├── htm ├── license.html ├── video1.html ├── video2.html ├── message3.html ├── people1.html ├── message2.html ├── message1.html ├── home.html ├── people2.html ├── info.html ├── message4.html ├── article1.html ├── article2.html ├── article4.html └── article3.html ├── home.html ├── index.html └── css └── pmag.css /htm/license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

## 授權聲明

17 |

本雜誌採用 創作共用:姓名標示、相同方式分享 授權,若您想要修改本書產生衍生著作時,至少應該遵守下列授權條件:

18 |
    19 |
  1. 標示原作者姓名
  2. 20 |
  3. 採用 創作共用:姓名標示、相同方式分享 的方式公開衍生著作。
  4. 21 |
22 |

另外、當本雜誌中有文章或素材並非採用 姓名標示、相同方式分享 時,將會在該文章或素材後面標示其授權,此時該文章將以該標示的方式授權釋出,請修改者注意這些授權標示,以避免產生侵權糾紛。

23 |

例如有些文章可能不希望被作為「商業性使用」,此時就可能會採用創作共用:姓名標示、非商業性、相同方式分享 的授權,此時您就不應當將該文章用於商業用途上。

24 |

最後、懇請勿移除公益捐贈的相關描述,以便讓愛心得以持續散播!

25 |
26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /htm/video1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

看影片學 markdown 編輯出版流程

17 |

在本期的短訊中,我們介紹了 markdown, pandoc, calibre ebook-convert, make 等工具,這些文章列表如下:

18 | 24 |

當您閱讀了以上文章之後,就可以瞭解「程式人雜誌」的編輯方法,並且知道如何用 markdown 格式出版電子書了。

25 |

為了讓讀者能有更「真實」的體認,筆者將這些編輯流程錄影下來,放到了 YouTube 上,請點選下列連結以觀賞該影片。

26 | 29 |

透過這種方式,我們可以採用非常「程式人的方法」,同時出版各種格式的電子書,讓您的身份從程式人轉變為作家。 【本文由陳鍾誠撰寫】

30 |
31 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /htm/video2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

看影片學 C# 遊戲程式-使用 Window Forms

17 |

從本月開始,Gary Lin 將幫我們錄製一系列的影片,從簡單的 Window Forms 程式開始,逐步帶我們進入 遊戲設計的領域,目前這系列的影片已經有四集了,編輯將其列表如下:

18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
影片名稱網址說明
C# 遊戲程式設計 (00)http://youtu.be/U8muJ8k1S-U兩球互相追逐
C# 遊戲程式設計 (01)http://youtu.be/0zkJLEp0sYY很多紅球追一個籃球
C# 遊戲程式設計 (02)http://youtu.be/0HzjzIYYiR4碰撞處理
C# 遊戲程式設計 (03)http://youtu.be/U8muJ8k1S-U多個籃球與紅球
49 |

(本文中的影片與教學由 Gary Lin 主講與提供,編輯者為陳鍾誠)

50 |
51 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /htm/message3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

軟體短訊-Calibre 電子書管理轉換系統

17 |

Calibre 是一個用來管理並且轉換電子書格式的系統,您可以匯入電子書到 Calibre 當中進行管理與閱讀, 也可以將電子書轉換成其他格式,以便放到某些平台上去閱讀。

18 |

Calibre 具有視窗型的介面,但是筆者並不常使用,筆者較常用的是 Calibre 當中所附的一個命令列程式, 稱為 ebook-convert,下圖顯示了筆者電腦中這個程式所在的位置。

19 |
20 | 21 |
22 |

Ebook-convert 可以將電子書的格式轉來轉去,例如將 epub 轉換為 pdf 檔案輸出,以下是該程式支援的 輸出入檔案格式:

23 |
24 |

Input Formats: CBZ, CBR, CBC, CHM, DJVU, EPUB, FB2, HTML, HTMLZ, LIT, LRF, MOBI, ODT, PDF, PRC, PDB, PML, RB, RTF, SNB, TCR, TXT, TXTZ

25 |

Output Formats: AZW3, EPUB, FB2, OEB, LIT, LRF, MOBI, HTMLZ, PDB, PML, RB, PDF, RTF, SNB, TCR, TXT, TXTZ

26 |
27 |

您可以看到 ebook-convert 所支援的電子書格式真的非常完整,請進一步閱讀以下網頁以瞭解其用法。

28 | 31 |

事實上、程式人雜誌自從第二期之後,就是使用 pandoc 將 markdown 轉換為 html 與 epub 格式,然後 再用 Calibre 的 ebook-convert 程式,將 epub 電子書轉換為 PDF 格式,以便讓讀者能方便的閱讀。

32 |

或許有些曾經用過 pandoc 的讀者會有疑問,為何不用 pandoc 直接將 markdown 轉換為 pdf 呢?

33 |

原本、筆者曾經這樣做過,但是這樣作在英文上沒有問題,但在中文上就無法成功轉換了。為了解決 pandoc 中文轉換的問題,筆者也曾經撰寫過 latex 樣版,讓 pandoc 順利的將 markdown 轉換為 latex 之後再用 MiKTeX 將 latex 轉換為 pdf 文件。雖然最後可以運作,但是仍然有些無法令人滿意的問題,所以後來 筆者才找到了 Calibre 中的 ebook-convert,來完成 epub 轉為 pdf 的動作。

34 |

Calibre 官方網站的網址為 http://calibre-ebook.com/ ,您可以從網站中取得進一步的資訊。【本文由陳鍾誠撰寫】

35 |
36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /htm/people1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

Linux 創建者-Linus Torvalds

17 |

Linus Torvalds 這位仁兄我想不用介紹,大家都知道他做了甚麼事,因為有一個作業系統幾乎就是用他名字命名的,Linu-X,簡稱 Linux。

18 |
19 | 20 |
21 |

Linus Benedict Torvalds 於 1969年12月28日出生於芬蘭赫爾辛基市,擁有美國國籍。他除了創造並主導 Linux 核心 的開發之外,還發展出 Git 這個廣為世人使用的版本管理系統。如果諾貝爾獎設立程式領域的項目,那他肯定是得獎者之一。

22 |

Torvalds 畢業於赫爾辛基大學計算機科學系,1997年至2003年在美國加州矽谷任職於全美達公司(Transmeta Corporation)參與該公司晶片的code morph技術研發。後受聘於開源碼發展實驗室(OSDL : Open Source Development Labs, Inc),全力開發 Linux 核心,並任職於 Linux 基金會。

23 |

托瓦茲與妻子托芙(Tove,一位六次芬蘭前女子空手道冠軍)育有三名孩子。

24 |

Torvalds 在大學時代,由於想在 x86 個人電腦上使用類似 UNIX 的系統,但是卻找不到這樣的作業系統。只看到一個由 Andrew Stuart Tanenbaum 這位「荷蘭阿姆斯特丹自由大學的計算機科學教授」所寫的小型 MINIX 作業系統可用,於是他在 研究了 MINIX 之後,於 1991 年開始就逐步改造了 MINIX,最後全部換成了自己的程式碼,並將相關訊息放到 Usenet 新聞群組comp.os.minix 上,標題如下所示:

25 |
26 |

Linus Benedict Torvalds (5 October 1991). "Free minix-like kernel sources for 386-AT".

27 |
28 |

從那時候開始,Linux 就迅速發展,Linux 站在 GNU gcc 這樣的開發工具上,逐步壯大起來,並且吸引了越來越多的程式人員 為此平台開發程式。

29 |

Torvalds 開發的是 Linux Kernel,也就式作業系統的核心部分,然後許多人將此核心連同一大群軟體,包裝成許多的分支,像是 RedHat, Ubuntu, Fedora, CentOS, Debian 等等。

30 |

後來、連商業公司也開始進來了,基於 Linux 的 Android 作業系統在手機上取得了重大的成功,這讓 Google 這樣的公司 進入了作業系統的領域,並結合整個電子產業的硬體公司,像是 HTC、三星、Motorola、ASUS 等,占領了智慧型手機 的大部分市場。

31 |

Linux 改造了整個電腦工業,其創造者 Torvalds 扮演著重要且關鍵的角色。

32 |

Torvalds 的另一個重要貢獻是創造並主導了 Git 這個版本管理系統的開發,現在 Git 已經凌駕 CVS , SVN 與 Mercurial,成為 程式人員最常使用的版本管理系統,著名的 github 網站就提供了這樣一個平台,讓全世界的人可以將原始碼上傳並且透過 git 進行開發與合作,連這本「程式人雜誌」也是透過 github 發行並提供給讀者下載的。

33 |

Torvalds 的驚人貢獻,來自學生時代的一個想法,並將這個想法付諸行動,成就了不凡的一生。

34 |

參考文獻

35 | 40 |

【本文由陳鍾誠取材並修改自維基百科】

41 |
42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /htm/message2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

軟體短訊-Pandoc 格式轉換系統

17 |

在 Web 盛行之後,使用簡易文字的方式撰寫網頁的需求就一直存在,於是產生了像 wiki 這樣的格式, 相對的也就需要一些工具將這些格式轉換成網頁。

18 |

維基百科就是這樣一個例子,他們透過 Mediawiki 這樣的格式撰寫文章,然後維基百科的網站就會用 程式將這種簡易的格式轉換成網頁,呈現給使用者看。

19 |

Wiki 類型的簡易書寫格式,除了 Mediawiki 之外,還有越來越多從 markdown 衍生出來的語法,像是 ReStructureText (RST), Textile 等等。

20 |

在上一篇短訊中,我們介紹了 Markdown 這種很容易撰寫與閱讀的格式,當然我們也就需要一種程式, 可以將 markdown 文件轉換成網頁,pandoc 正是這樣的一個工具程式。

21 |

Pandoc 不只可以將 Markdown 轉換成網頁,還可以轉換成 epub, latex, doc, odt 等格式的電子書, 也可以在各種簡易書寫格式之間轉換 (例如 markdown 轉 mediawiki),因此 pandoc 也被稱為文件格式 轉換的瑞士萬用刀。

22 |

Pandoc 的使用很容易,以下是一些 pandoc 的使用範例,其參數的用法與 c 語言編譯器 gcc 很像。

23 |
pandoc input.md -o output.html               # markdown 轉 html
24 | 
25 | pandoc -s input.md -o output.tex             # markdown 轉 latex
26 | 
27 | pandoc -s --webtex input.md -o output.html   # 有數學式可加上 --webtex, --mathml 或 --mathjax 等參數
28 | 
29 | pandoc -s --toc -c ../css/pmag.css -B header.htm -A footer.htm input.md -o output.htm
30 |

Pandoc 會自動根據輸入輸出檔的附檔名進行辨認,因此不需要特別指定輸入輸出檔的格式 (當然也可以強制指定格式)。

31 |

參數 -s 代表 --standalone,也就是要產生獨立可顯示的輸出檔時使用的,像是單獨的網頁 html,或者 epub 等都會 加上這個選項。

32 |

Pandoc 也支援一些 markdown 的延伸語法,像是 latex 數學式可用 $ ... $ 這樣的方式包裹住, 例如 $\int_0^{\infty} f(x) dx$ 的呈現結果會是 \int_0^{\infty} f(x) dx,但是要用數學式必須加上 --webtex, --mathml 或 --mathjax 等參數,以便選擇數學式要用哪種顯示方式呈現。

33 |

在上述範例中的最後一句,--toc 代表要產生目錄 (Table Of Content, TOC),而 -c ../css/pmag.css 則是要套用 該 CSS 樣式,-B header.htm 代表要在輸出檔案前補上 header.htm 作為檔頭,而 -A footer.htm 則代表 要在輸出檔案尾端補上檔尾 footer.htm。

34 |

Pandoc 的官方網站的網址如下:

35 | 38 |

您可以從其中的 README 取得詳細的 使用說明,或者直接參考 demos, 以範例的方式學習 pandoc 的用法。【本文由陳鍾誠撰寫】

39 |
40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /htm/message1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

出版短訊-Markdown 寫作格式

17 |

Markdown 是一種由 John GruberAaron Swartz 所創造的超簡單型標記語言,目前在網路越來越多的人使用這種格式進行寫作,其用途有點像維基百科 所使用的 mediawiki 格式,但是設計理念卻有很大的不同。

18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
John GruberAaron Swartz
32 |

Markdown 的設計理念有點像文書排版軟體 (例如 MS. Word, LibreOffice Writer) 這種「所視即所得」的想法,但卻是純文字形式的寫法,也就是讓你寫出來的文字檔就與呈現時的畫面 差不多,這樣的設計讓您在寫作時就很容易感受排版出來的結果,這種作法正是 Markdown 令人愛不釋手 的原因。

33 |

為了讓讀者 實際體會 Markdown 的所視即所得效果,我們將本文的部分原始碼列於此處,這樣讀者應該 就可以很容易的透過對照看出這些標記的效果了

34 |
## 出版短訊:markdown 寫作格式
35 | 
36 | [Markdown] 是一種由 [John Gruber] 和 
37 | [Aaron Swartz](http://zh.wikipedia.org/wiki/Aaron_Swartz)
38 | 所創造的超簡單型標記語言,目前在網路越來越多的人
39 | 使用這種格式進行寫作,其用途有點像維基百科
40 | 所使用的 mediawiki 格式,但是設計理念卻有很大的不同。
41 | 
42 | John Gruber                      Aaron Swartz
43 | ----------------------------     -------------------------------
44 | ![](../img/JohnGruber.jpg)       ![](../img/AaronSwartz.jpg)
45 | 
46 | ...
47 | 
48 | 為了讓讀者 *實際體會* Markdown 的所視即所得效果,
49 | 我們將本文的原始碼列於此處,這樣讀者應該就可
50 | 以很容易的透過對照看出這些標記的效果了。
51 | 
52 | ...
53 | 
54 | 如果您想要進一步瞭解 markdown 的語法,
55 | 請參考 <http://markdown.tw/> 這個寫得很好的 markdown 語法介紹。
56 | 
57 | [John Gruber]:http://en.wikipedia.org/wiki/John_Gruber
58 | [Markdown]:http://zh.wikipedia.org/wiki/Markdown
59 |

如果您想要進一步瞭解 markdown 的語法,請參考 http://markdown.tw/ 這個寫得很好的 markdown 語法介紹。

60 |

說明:必須注意的是,Markdown 當中並沒有設計表格的語法,所以本文中的表格語法是 pandoc 軟體採用 「所視即所得」精神所自行延伸的語法。

61 |

(本文由陳鍾誠修改自維基百科,來源為 http://zh.wikipedia.org/wiki/Markdown)

62 |
63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

關於程式人雜誌

17 |

程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌。

18 |

雜誌下載

19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
出刊年月epubipad:PDFA4:PDF單頁 HTM原始碼全部下載
2013年4月epubipad.pdfA4.pdfpmag.htmlcode.zip201304.zip
43 |

本期內容

44 | 72 |

雜誌訂閱

73 |

想訂閱程式人雜誌請按 雜誌訂閱 連結並填寫表單。

74 |

連絡我們

75 |

竭誠歡迎程式人投稿,或者成為本雜誌的專欄作家,現在就可以加入 程式人雜誌社團 一同共襄盛舉。

76 |

本雜誌編輯為「陳鍾誠 (@ccckmit)」,若要聯絡編輯,請寄信到

82 |
83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /htm/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

關於程式人雜誌

17 |

程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌。

18 |

雜誌下載

19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
出刊年月epubipad:PDFA4:PDF單頁 HTM原始碼全部下載
2013年4月epubipad.pdfA4.pdfpmag.htmlcode.zip201304.zip
43 |

本期內容

44 | 72 |

雜誌訂閱

73 |

想訂閱程式人雜誌請按 雜誌訂閱 連結並填寫表單。

74 |

連絡我們

75 |

竭誠歡迎程式人投稿,或者成為本雜誌的專欄作家,現在就可以加入 程式人雜誌社團 一同共襄盛舉。

76 |

本雜誌編輯為「陳鍾誠 (@ccckmit)」,若要聯絡編輯,請寄信到

82 |
83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

關於程式人雜誌

17 |

程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌。

18 |

雜誌下載

19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
出刊年月epubipad:PDFA4:PDF單頁 HTM原始碼全部下載
2013年4月epubipad.pdfA4.pdfpmag.htmlcode.zip201304.zip
43 |

本期內容

44 | 72 |

雜誌訂閱

73 |

想訂閱程式人雜誌請按 雜誌訂閱 連結並填寫表單。

74 |

連絡我們

75 |

竭誠歡迎程式人投稿,或者成為本雜誌的專欄作家,現在就可以加入 程式人雜誌社團 一同共襄盛舉。

76 |

本雜誌編輯為「陳鍾誠 (@ccckmit)」,若要聯絡編輯,請寄信到

82 |
83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /htm/people2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

Markdown 與 RSS 的創造者-Aaron Swartz

17 |
18 | 圖、Aaron Swartz 2008 年 12 月 13 日在 Creative Commons event 的照片

圖、Aaron Swartz 2008 年 12 月 13 日在 Creative Commons event 的照片

19 |
20 |

Aaron Swartz 是個程式領域的天才,但是他的人生,卻以悲劇收場。

21 |

Aaron Swartz 於 1986 年 11 月 8 日出生美國芝加哥的伊利諾伊州一個猶太家庭。他的父親本身就是程式領域的創業者, 這讓他從很小就開始接觸程式與網路,並於13歲時就贏的了 ArsDigita Prize 比賽的冠軍。

22 |

14 歲時,斯沃茨加入了 RSS-DEV 組織,與夥伴們一同創造出了 RSS 規格,後來他積極參與各種網路規格制定組織,像是為 W3C 撰寫 RFC 以定義 RDF 及 XML 等規格,以及參與創作共用 Creative Commons (CC) 組織,並成為了 CC 創辦人 Lawrence Lessig 指導的研究員。

23 |

如果您仔細觀察 Aaron Swartz 的程式、文章與經歷,您會發現他的生命幾乎完全投入在數位出版領域,而且有非常大個貢獻。

24 |

舉例而言、除了參與 RSS, RDF, XML 規格的制定,並參與 CC 組織之外,Aaron Swartz 還與 John Gruber 共同創造了 Markdown 這個影響深遠的文件格式,這個格式已成為 github, stackoverflow 等網站的主要書寫格式,並且有眾多工具 pandoc, kitabu 被創造出來將 markdown 用在出版領域,而且也有像 leanpub 這樣的出版網站使用此種格式進行出版。

25 |

另外、他還創造出 web.py 這個以 Python 語言寫成的網站框架,用來作為出版平台。並且改寫了 Reddit.com 這個訊息分享網站的程式,用程式讓訊息的分享更為容易。

26 |

正是因為對數位出版的熱愛,讓 Aaron Swartz 更感覺到當今商業公司把持了大量的出版利益,並且透過法律體系抑制版權開放的運動,因此他寫下了「游擊隊開放存取宣言」 (Guerrilla Open Access Manifesto),並於 2010 年成立了 DemandProgress.org 網站,反對 SOPA/PIPA 這些網際網路審查法案。

27 |

接著、他更在 2010 年 9 月,在 MIT 校園內透過網路自動大量下載了 480 萬份 JSTOR 的期刊論文與相關文件,期望讓這些學術論文公開自由的被存取。接著在 2011 年 1 月 6 日時,他被聯邦調查局逮捕了,並控以「電信詐欺 (wire fraud)、電腦詐欺 (computer fraud)、從受保護電腦非法取得資訊、故意毀壞受保護電腦」等四項罪名。

28 |

後來這些罪名陸續增加,從 4 項變為 13 項,並且檢察官威脅他要以刑事罪起訴,這讓他非常沮喪。

29 |

2013 年 1 月 11 日時,他在住處自殺身亡。

30 |

Aaron 死了,年僅 26 歲!

31 |

參考文獻

32 | 39 |

後記

40 |

按理說,那些學者寫的論文,應該是全人類共有的文明資產才對,但是為何會變成幾家出版商所控制的私有資產呢? 非學術界的人通常無法理解此種情況,而學術界的人,則是理解之後仍然將論文交給出版商,繼續為他們創造私有資產。

41 |

目前的情況是、學者們所寫的論文投稿到期刊之後,商業權將移轉到期刊公司,於是那些未付費就下載這些論文的行為 就都成了侵害私有財產權的行為。

42 |

更糟糕的是,連那篇論文的作者,也不能再出版自己的論文,有時連將自己的論文放上網路都成了非法行為。

43 |

對這個問題有興趣的朋友可以參看以下的幾篇文章。

44 | 50 |

【本文由陳鍾誠取材並修改自維基百科】

51 |
52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /htm/info.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

雜誌訊息

17 |

讀者訂閱

18 |

程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌,如果您願意成為本雜誌的專欄作家,請加入 程式人雜誌社團 一同共襄盛舉。

19 |

我們透過發行這本雜誌,希望讓大家可以讀到想讀的書,學到想學的技術,同時也讓寫作的朋友的作品能產生良好價值 – 那就是讓讀者根據雜誌的價值捐款給慈善團體。 讀雜誌做公益也不需要有壓力,您不需要每讀一本就急著去捐款,您可以讀了十本再捐,或者使用固定的月捐款方式,當成是雜誌訂閱費,或者是季捐款、一年捐一次等都 OK ! 甚至是單純當個讀者我們也都很歡迎! 本雜誌每期參考價:NT 50 元,如果您喜歡本雜誌,請將書款捐贈公益團體。例如可捐贈給「羅慧夫顱顏基金會 彰化銀行(009) 帳號:5234-01-41778-800」。(若匯款要加註可用「程式人雜誌」五個字)

20 |

想訂閱本雜誌的讀者,請按 雜誌訂閱 連結並填寫表單,我們會在每一期雜誌出刊時寄送通知與下載網址到您的信箱。

21 |

投稿須知

22 |

給專欄寫作者: 做公益不需要有壓力。如果您願意撰寫專欄,您可以輕鬆的寫,如果當月的稿件出不來,我們會安排其他稿件上場。

23 |

給網誌捐贈者: 如果您沒時間寫專欄或投稿,沒關係,只要將您的網誌以 [創作共用的「姓名標示、非商業性、相同方式分享」授權] 並通知我們,我們會自動從中選取需要的文章進行編輯,放入適當的雜誌當中出刊。

24 |

給文章投稿者: 程式人雜誌非常歡迎您加入作者的行列,如果您想撰寫任何文章或投稿,請用 markdown 或 LibreOffice 編輯好您的稿件,並於每個月 25 日前投稿到程式人雜誌社團 的檔案區,我們會盡可能將稿件編入隔月1號出版程式人雜誌當中,也歡迎您到社團中與我們一同討論。

25 |

如果您要投稿給程式人雜誌,我們最希望的格式是採用 markdown 的格式撰寫,然後將所有檔按壓縮為 zip 上傳到社團檔案區給我們, 如您想學習 markdown 的撰寫出版方式,可以參考 看影片學 markdown 編輯出版流程 一文。

26 |

如果您無法採用 markdown 的方式撰寫,也可以直接給我們您的稿件,像是 MS. Word 的 doc 檔或 LibreOffice 的 odt 檔都可以,我們 會將這些稿件改寫為 markdown 之後編入雜誌當中。

27 |

參與編輯

28 |

您也可以擔任程式人雜誌的編輯,甚至創造一個全新的公益雜誌,我們誠摯的邀請您加入「開放公益出版」的行列,如果您想擔任編輯或創造新雜誌,也歡迎到 程式人雜誌社團 來與我們討論相關事宜。

29 |

公益資訊

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 |
公益團體聯絡資訊服務對象捐款帳號
財團法人羅慧夫顱顏基金會http://www.nncf.org/

02-27190408分機 232
顱顏患者 (如唇顎裂、小耳症或其他罕見顱顏缺陷)銀行:009彰化銀行民生分行
帳號:5234-01-41778-800
社團法人台灣省兒童少年成長協會http://www.cyga.org/

04-23058005
單親、隔代教養.弱勢及一般家庭之兒童青少年銀行:新光銀行
戶名:台灣省兒童少年成長協會
帳號:103-0912-10-000212-0
68 |
69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /css/pmag.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | b, u, i, center, 7 | dl, dt, dd, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td, 10 | article, aside, canvas, details, embed, 11 | figure, figcaption, footer, header, hgroup, 12 | menu, nav, output, ruby, section, summary, 13 | time, mark, audio, video { 14 | margin: 0; 15 | padding: 0; 16 | border: 0; 17 | font: inherit; 18 | vertical-align: baseline; 19 | line-height:160%; 20 | } 21 | 22 | #cover-image { 23 | width:100%; 24 | } 25 | 26 | h1, h2, h3, h4, h5, h6, p { 27 | color:#353535; 28 | } 29 | 30 | h1, h2, h3, h4, h5, h6 { 31 | margin: 0; 32 | font-family: 'Times New Roman', '標楷體'; 33 | font-weight: bold; 34 | } 35 | 36 | blockquote { 37 | margin: 10px; 38 | padding-left: 10px; 39 | padding-right: 10px; 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | border: 1px solid #373737; 43 | background-color: #efefef; 44 | } 45 | 46 | h1 { font-size: xx-large; text-align:center; margin:30px; } 47 | 48 | h2 { font-size: x-large; margin-top:30px; margin-bottom:30px; } 49 | 50 | h3 { font-size: large; } 51 | 52 | h4 { font-size: medium; } 53 | 54 | h5 { font-size: small } 55 | 56 | h6 { font-size: x-small; } 57 | 58 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight:bold; } 59 | 60 | h1, h1 a { color:#191970; } 61 | h2, h2 a { color:#050505; } 62 | h3, h3 a { color:#000066; } 63 | h4, h4 a { color:#000000; } 64 | h5, h5 a { color:#708090; } 65 | h6, h6 a { color:#000080; } 66 | 67 | p { 68 | margin: 10px 0 15px 0; 69 | font-size:100%; 70 | } 71 | 72 | li { 73 | font-size:100%; 74 | } 75 | 76 | footer p { 77 | color: #f2f2f2; 78 | } 79 | 80 | a { 81 | text-decoration: none; 82 | color: #007edf; 83 | text-shadow: none; 84 | 85 | transition: color 0.5s ease; 86 | transition: text-shadow 0.5s ease; 87 | -webkit-transition: color 0.5s ease; 88 | -webkit-transition: text-shadow 0.5s ease; 89 | -moz-transition: color 0.5s ease; 90 | -moz-transition: text-shadow 0.5s ease; 91 | -o-transition: color 0.5s ease; 92 | -o-transition: text-shadow 0.5s ease; 93 | -ms-transition: color 0.5s ease; 94 | -ms-transition: text-shadow 0.5s ease; 95 | } 96 | 97 | table { 98 | border-collapse: collapse; 99 | border-spacing: 0; 100 | border: 1px solid #373737; 101 | margin-bottom: 20px; 102 | text-align: left; 103 | margin-left:auto; 104 | margin-right:auto; 105 | } 106 | 107 | th { 108 | padding: 10px; 109 | background-color:black; 110 | color:white; 111 | } 112 | 113 | td { 114 | padding: 10px; 115 | vertical-align: middle; 116 | border: 1px solid #373737; 117 | } 118 | 119 | em { 120 | font-weight:bold; 121 | } 122 | 123 | #header_wrap { 124 | margin: 0; 125 | padding: 16px; 126 | border: 0; 127 | font: inherit; 128 | vertical-align: baseline; 129 | background-color:black; 130 | color:white; 131 | } 132 | 133 | #header_wrap h1, h1 sub, h1 a { 134 | color:white; 135 | } 136 | 137 | h2 { 138 | color:black; 139 | } 140 | 141 | #header_wrap sub { 142 | color:white; 143 | font-size:60%; 144 | } 145 | 146 | .title, .author, .date { 147 | color:#333333; 148 | text-align:center; 149 | font-family: 'Times New Roman', '標楷體'; 150 | } 151 | 152 | .title { font-size:xx-large; line-height:800%; } 153 | 154 | .author { font-size:large; line-height:300%; } 155 | 156 | .date { font-size:large; line-height:300%; } 157 | 158 | 159 | #content { 160 | margin:10px; 161 | padding:10px; 162 | } 163 | 164 | pre { 165 | border: 1px solid #373737; 166 | background-color:#efefef; 167 | color:#3f3f3f; 168 | font-size:medium; 169 | width:95%; 170 | padding:10px; 171 | } 172 | 173 | code { 174 | font-family: '細明體'; 175 | } 176 | 177 | .figure { 178 | margin:10px; 179 | padding:10px; 180 | margin-left: auto; 181 | margin-right: auto; 182 | display: block; 183 | } 184 | 185 | .figure img { 186 | border: 1px solid #373737; 187 | margin-left: auto; 188 | margin-right: auto; 189 | display: block; 190 | } 191 | 192 | .figure .caption { 193 | text-align:center; 194 | } 195 | 196 | #TOC { 197 | } 198 | 199 | #footer { 200 | text-align:center; 201 | font-size:small; 202 | color:#6f6f6f; 203 | margin: 10px; 204 | padding: 10px; 205 | } 206 | 207 | /* JavaScript Style */ 208 | table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { 209 | margin: 0; padding: 0; vertical-align: baseline; border: none; } 210 | table.sourceCode { width: 100%; } 211 | td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #afafaf; border-right: 1px solid #aaaaaa; } 212 | td.sourceCode { padding-left: 5px; } 213 | code > span.kw { color: #007020; font-weight: bold; } 214 | code > span.dt { color: #902000; } 215 | code > span.dv { color: #40a070; } 216 | code > span.bn { color: #40a070; } 217 | code > span.fl { color: #40a070; } 218 | code > span.ch { color: #4070a0; } 219 | code > span.st { color: #4070a0; } 220 | code > span.co { color: #60a0b0; font-style: italic; } 221 | code > span.ot { color: #007020; } 222 | code > span.al { color: #ff0000; font-weight: bold; } 223 | code > span.fu { color: #06287e; } 224 | code > span.er { color: #ff0000; font-weight: bold; } 225 | 226 | -------------------------------------------------------------------------------- /htm/message4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

14 |
15 |
16 |

軟體短訊-Make 專案建置工具

17 |

Make 是 GNU 組織所釋出的老牌專案建置工具,通常會與 gcc 一同安裝,用來建置 c 語言的專案, 但是後來很多人也用 Make 來管理其他語言的專案,甚至有很多語言也發展出類似 make 的專案建置工具, 像是 Java 的 Maven 與 Ruby 的 Rake 等等。

18 |

Make 的預設建置對像為該資料夾下名稱為 Makefile 的檔案,因此您只要撰寫好 Makefile,然後執行指令 make 就可以開始建置整個專案了。

19 |

由於 Makefile 當中可以呼叫任何的命令列程式,因此並不受限於 C 語言編譯建置時使用,您可以把 Make 當成是更好用的批次檔來用。

20 |

事實上、程式人雜誌從第二期以後就是用 make 建置整本電子書的,以下是程式人雜誌的專案建置檔。

21 |
PANDOC = pandoc -s --webtex 
 22 | HTML  = home.html license.html message1.html message2.html message3.html \
 23 | message4.html people1.html people2.html video1.html article1.html \
 24 | article2.html article3.html article4.html info.html
 25 | MD   = license.md message.md message1.md  message2.md  message3.md message4.md \
 26 | people.md people1.md  people2.md video.md video1.md article.md article1.md \
 27 | article2.md article3.md article4.md info.md reflink.md
 28 | PARG = -c ../css/pmag.css -B header.htm -A footer.htm 
 29 | PEPUB = --toc --epub-metadata=metadata.xml --epub-stylesheet=../css/pmag.css 
 30 | EARG = --margin-top=16 --margin-bottom=16 --margin-left=20 --margin-right=20 \
 31 | --pretty-print --base-font-size=9 --font-size-mapping="7, 8, 9, 12, 14, 16, 20, 24" 
 32 | RM = rm -f
 33 | 
 34 | .PHONY: all epubipad pdfipad pdfA4
 35 | 
 36 | all: $(HTML)
 37 | 
 38 | epubA4:
 39 |     $(PANDOC) $(PEPUB) --epub-cover-image=../img/coverA4.png toc.md $(MD) -o ../book/A4.epub
 40 | 
 41 | pdfA4: epubA4
 42 |     ebook-convert ../book/A4.epub ../book/A4.pdf $(EARG) --paper-size=a4
 43 |     
 44 | epubipad:
 45 |     $(PANDOC) $(PEPUB) --epub-cover-image=../img/cover.jpg toc.md $(MD) -o ../book/ipad.epub
 46 | 
 47 | pdfipad: epubipad
 48 |     ebook-convert ../book/ipad.epub ../book/ipad.pdf $(EARG) --output-profile=ipad3
 49 |     
 50 | html: $(HTML)
 51 | 
 52 | shtm: 
 53 |     $(PANDOC) --toc $(MD) -o ../book/pmag.html $(PARG)
 54 | 
 55 | %.html: %.md
 56 |     $(PANDOC) $< reflink.md -o ../htm/$@ $(PARG)
 57 |     
 58 | clean: 
 59 |     ${RM} ../htm/*.*
60 |

在以上的專案建置檔中,我們使用了以下 pandoc 指令將 markdown 轉換為一頁一頁的 HTML,以建立網頁版的程式人雜誌。

61 |
%.html: %.md
 62 |     $(PANDOC) $< reflink.md -o ../htm/$@ $(FLAGS)
63 |

然後、我們也使用了以下指令呼叫 pandoc 將所有檔案合併轉換為 epub 電子書。

64 |
epubipad:
 65 |     $(PANDOC) $(PEPUB) --epub-cover-image=../img/cover.jpg toc.md $(MD) -o ../book/ipad.epub
66 |

最後、我們使用了 calibre 的 ebook-convert 將 epub 電子出轉換為 pdf 檔案,

67 |
pdfipad: epubipad
 68 |     ebook-convert ../book/ipad.epub ../book/ipad.pdf $(EARG) --output-profile=ipad3
69 |

以下是我們程式人雜誌 2013 年 4 月號的建置過程。

70 |
D:\Dropbox\Public\pmag\201304\source>make html
 71 | pandoc -s --webtex  home.md reflink.md -o ../htm/home.html -c ../css/pmag.css -B
 72 |  header.htm -A footer.htm
 73 | pandoc -s --webtex  license.md reflink.md -o ../htm/license.html -c ../css/pmag.
 74 | css -B header.htm -A footer.htm
 75 | pandoc -s --webtex  message1.md reflink.md -o ../htm/message1.html -c ../css/pma
 76 | g.css -B header.htm -A footer.htm
 77 | pandoc -s --webtex  message2.md reflink.md -o ../htm/message2.html -c ../css/pma
 78 | g.css -B header.htm -A footer.htm
 79 | pandoc -s --webtex  message3.md reflink.md -o ../htm/message3.html -c ../css/pma
 80 | g.css -B header.htm -A footer.htm
 81 | pandoc -s --webtex  message4.md reflink.md -o ../htm/message4.html -c ../css/pma
 82 | g.css -B header.htm -A footer.htm
 83 | pandoc -s --webtex  people1.md reflink.md -o ../htm/people1.html -c ../css/pmag.
 84 | css -B header.htm -A footer.htm
 85 | pandoc -s --webtex  people2.md reflink.md -o ../htm/people2.html -c ../css/pmag.
 86 | css -B header.htm -A footer.htm
 87 | pandoc -s --webtex  video1.md reflink.md -o ../htm/video1.html -c ../css/pmag.cs
 88 | s -B header.htm -A footer.htm
 89 | pandoc -s --webtex  video2.md reflink.md -o ../htm/video2.html -c ../css/pmag.cs
 90 | s -B header.htm -A footer.htm
 91 | pandoc -s --webtex  article1.md reflink.md -o ../htm/article1.html -c ../css/pma
 92 | g.css -B header.htm -A footer.htm
 93 | pandoc -s --webtex  article2.md reflink.md -o ../htm/article2.html -c ../css/pma
 94 | g.css -B header.htm -A footer.htm
 95 | pandoc -s --webtex  article3.md reflink.md -o ../htm/article3.html -c ../css/pma
 96 | g.css -B header.htm -A footer.htm
 97 | pandoc -s --webtex  article4.md reflink.md -o ../htm/article4.html -c ../css/pma
 98 | g.css -B header.htm -A footer.htm
 99 | pandoc -s --webtex  info.md reflink.md -o ../htm/info.html -c ../css/pmag.css -B
100 |  header.htm -A footer.htm
101 | 
102 | pandoc -s --webtex  --toc --epub-metadata=metadata.xml --epub-stylesheet=../css/pmag.css
103 |   --epub-cover-image=../img/cover.jpg toc.md license.md message.md message1.md  message2.md 
104 |   message3.md message4.md people.md people1.md  people2.md video.md video1.md video2.md \
105 |   article.md article1.md article2.md article3.md article4.md info.md reflink.md -o ../book/ipad.epub
106 | ebook-convert ../book/ipad.epub ../book/ipad.pdf --margin-top=16 --margin-bottom=16 
107 | --margin-left=20 --margin-right=20 --pretty-print --base-font-size=9 
108 | --font-size-mapping="7, 8, 9, 12, 14, 16, 20, 24"  --output-profile=ipad3
109 | 1% 將輸入轉換為HTML格式...
110 | InputFormatPlugin: EPUB Input running
111 | on D:\Dropbox\Public\pmag\201304\book\ipad.epub
112 | Parsing all content...
113 | COLOR_VALUE: No match in Choice(HEX color, Named Color, Sequence(FUNCTION, Choice(unary +-, 
114 | number, percentage), Sequence(comma, Choice(unary +-, number, percentage)), end FUNC ")"), 
115 | Sequence(FUNCTION, Choice(unary +-, number, percentage), Sequence(comma, Choice(unary +-, 
116 | number, percentage)), end FUNC ")")): ('HASH', u'#\ufeff\ufeff000080', 66, 18)
117 | COLOR_VALUE: No match in Choice(HEX color, Named Color, Sequence(FUNCTION, Choice(unary +-, 
118 | number, percentage), Sequence(comma, Choice(unary +-, number, percentage)), end FUNC ")"), 
119 | Sequence(FUNCTION, Choice(unary +-, number, percentage), Sequence(comma, Choice(unary +-, 
120 | number, percentage)), end FUNC ")"))
121 | 34% 正在對電子書籍進行轉換...
122 | Merging user specified metadata...
123 | Detecting structure...
124 | Flattening CSS and remapping font sizes...
125 | Source base font size is 12.00000pt
126 | Removing fake margins...
127 | Cleaning up manifest...
128 | Trimming unused files from manifest...
129 | Creating PDF Output...
130 | 67% 執行 PDF Output 外掛程式
131 | 71% Rendered cover.xhtml
132 | 75% Rendered title_page.xhtml
133 | 79% Rendered ch1.xhtml
134 | 83% Rendered ch2.xhtml
135 | 87% Rendered ch3.xhtml
136 | 91% Rendered ch4.xhtml
137 | 95% Rendered ch5.xhtml
138 | 100% Rendered ch6.xhtml
139 | Rendered PDF in 4.316 seconds:
140 | PDF output written to D:\Dropbox\Public\pmag\201304\book\ipad.pdf
141 | 將輸出儲存到   D:\Dropbox\Public\pmag\201304\book\ipad.pdf
142 | 
143 |

透過這樣的方式,我們用很「程式人」的方法,編輯了一份雜誌。【本文由陳鍾誠撰寫】

144 |
145 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /htm/article1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 28 | 29 | 30 | 31 |
32 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

33 |
34 |
35 |

Arduino入門教學(4) – 控制 LED 燈光亮度 (作者:Copper Maa)

36 |

Arduino 筆記 - Lab3 控制 LED 燈光亮度

37 |

實驗目的

38 |

利用 PWM (Pulse Width Modulation, 脈衝寬度調變) 控制 LED 燈光亮度。

39 |

材料

40 | 46 |

接線

47 | 50 |
51 | 52 |
53 |

電路圖

54 |
55 | 56 |
57 |

程式碼:Fading.pde

58 |
int brightness = 0;    // how bright the LED is
 59 | int fadeAmount = 5;    // how many points to fade the LED by
 60 | 
 61 | void setup()  { 
 62 |   // declare pin 9 to be an output:
 63 |   pinMode(9, OUTPUT);
 64 | } 
 65 | 
 66 | void loop()  { 
 67 |   // set the brightness of pin 9:
 68 |   analogWrite(9, brightness);    
 69 | 
 70 |   // change the brightness for next time through the loop:
 71 |   brightness = brightness + fadeAmount;
 72 | 
 73 |   // reverse the direction of the fading at the ends of the fade: 
 74 |   if (brightness == 0 || brightness == 255) {
 75 |     fadeAmount = -fadeAmount ; 
 76 |   }     
 77 |   // wait for 30 milliseconds to see the dimming effect    
 78 |   delay(30);                            
 79 | }
80 |

編譯這支程式,然後上傳到 Arduino 板子上,過數秒後,就會看到 LED 燈光不斷地改變亮度,一下子漸亮,一下漸暗。

81 |

說明:

82 | 91 |

範例照片/影片

92 |

Youtube 上正好有段示範利用 PWM 控制 LED 燈光亮度的影片,我們來看看他的示範:

93 | 96 |

PWM 原理簡介

97 |

數位輸出可以控制訊號的開跟關,開意味著通電,關意味著斷電,如果我們能夠進一步通電的時間比例,就能讓類比輸出產生變化,例如 LED 燈光通電時間為 50%,就可以控制 LED 讓它只有 50% 的亮度,如果把通電時間比例改為 25%,就可以控制 LED 讓它只有 25% 的亮度。這個方法稱為 PWM (Pulse Width Modulation)脈衝寬度調變,PWM 是一個利用數位訊號來控制類比輸出的技術,常用於蜂鳴器、電熱器、馬達或風扇轉速、燈光亮度等的控制。

98 |

下圖中,垂直的綠線代表一個規律的時間週期,在 Arduino 中,每個週期是 2ms (PWM 頻率為 500Hz)。analogWrite() 的參數值範圍介於 0 到 255 之間,analogWrite(255) 代表產生 100% duty cyle 的輸出(一直通電),而 analogWrite(127) 則是產生 50% duty cycle 的輸出(一半的時間通電,一半的時間斷電)。

99 |

Duty Cycle 為每一個週期通電(on) 的時間比例。

100 |

數位輸出可以控制訊號的開跟關,開意味著通電,關意味著斷電,如果我們能夠進一步通電的時間比例,就能讓類比輸出產生變化,例如 LED 燈光通電時間為 50%,就可以控制 LED 讓它只有 50% 的亮度,如果把通電時間比例改為 25%,就可以控制 LED 讓它只有 25% 的亮度。這個方法稱為 PWM (Pulse Width Modulation)脈衝寬度調變,PWM 是一個利用數位訊號來控制類比輸出的技術,常用於蜂鳴器、電熱器、馬達或風扇轉速、燈光亮度等的控制。

101 |

下圖中,垂直的綠線代表一個規律的時間週期,在 Arduino 中,每個週期是 2ms (PWM 頻率為 500Hz)。analogWrite() 的參數值範圍介於 0 到 255 之間,analogWrite(255) 代表產生 100% duty cyle 的輸出(一直通電),而 analogWrite(127) 則是產生 50% duty cycle 的輸出(一半的時間通電,一半的時間斷電)。

102 |

Duty Cycle 為每一個週期通電(on) 的時間比例。

103 |
104 | 105 |
106 |

你可能會納悶,一直開開關關的 ,LED 會不會閃爍讓眼睛不舒服?答案是不會的,因為開關的頻率很快,肉眼是看不出 LED 有在閃爍的。

107 |

動動腦

108 |
    109 |
  1. 如何加快或放慢 LED 亮度變化的速度?(提示:delay() 函式)
  2. 110 |
  3. 改用 pin9 以外的其它 PWM 腳位
  4. 111 |
  5. 多接幾顆 LED,讓每顆 LED 使用不同的速率改變亮度
  6. 112 |
113 |

參考資料

114 | 117 |

Arduino 筆記 - Lab4 使用可變電阻調光

118 |

實驗目的

119 |

使用可變電阻 (potentiometer) 控制 LED 的燈光亮度,達到調光的目的。

120 |

材料

121 | 129 |

接線

130 |

LED 接到 pin9 和 GND,長腳(陽極)串接一顆 220 ohm 電阻到 pin9,短腳(陰極)直接接到 GND 可變電阻中間腳位接到類比輸入(Analog Input) pin3,剩下的兩支腳位,一支接到 5V,另外一支接到 GND

131 |
132 | 133 |
134 |

電路圖

135 |
136 | 137 |
138 |

程式碼:potentiometer.pde

139 |

140 | int potPin = 3; // select the input pin for the potentiometer
141 | int ledPin = 9; // select the pin for the LED
142 | 
143 | void setup() {
144 |   Serial.begin(9600);
145 | }
146 | 
147 | void loop() {
148 |   int sensorValue = analogRead(potPin);
149 |   Serial.println(sensorValue, DEC);
150 |   
151 |   sensorValue = sensorValue/4; // convert from 0-1024 to 0-255
152 |   analogWrite(ledPin, sensorValue);
153 |   delay(150);
154 | }
155 |

說明:

156 | 164 |

範例照片/影片

165 |

編譯好程式,上傳到 Arduino 後,按下 Serial Monitor 這個按鈕,就會看到 COM Port 不斷收到一串範圍介於 0 到 1023 的數值,這些數值與可變電阻是相關聯的。如果旋轉可變電阻,對應的數值也會跟著改變,而且 LED 燈號的亮度也會跟著改變。

166 |

Youtube 上正好有段示範利用可變電阻控制 LED 燈光亮度的影片,我們來看看他的示範:

167 | 170 |
171 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /htm/article2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 28 | 29 | 30 | 31 |
32 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

33 |
34 |
35 |

JavaScript (4) – 在互動網頁中的應用:以功能表為例 (作者:陳鍾誠)

36 |

JavaScript 是唯一被各家瀏覽器所共同支援的程式語言,因此在設計網站的時候,我們如果不採用像 Flash 或 Silverlight 這樣的外掛技術,就必須採用 JavaScript 來設計互動式網頁。

37 |

在 node.js 這樣的伺服端 JavaScript 開發平台推出之後,我們就能夠採用 JavaScript 同時設計 Client 端與 Server 端的程式,這樣的模式相當的吸引人,我們會在後續的文章中介紹這樣的網站設計方法。

38 |

在本文當中,我們將透過 JavaScript 設計一個互動網頁的功能表,以便展示瀏覽器中的 JavaScript 程式是如何運作的。

39 |

功能表程式

40 |

以下是一個功能表的程式的執行結果,當我們的滑鼠移到功能項上時,就會浮現子功能表,而當我們點下子功能表中的項目時,就會出現一個 alert 視窗,顯示該功能子項被點選的訊息。

41 |
42 | 功能表程式的執行畫面

功能表程式的執行畫面

43 |
44 |

以下是這個網頁的原始 HTML 程式碼,其中 <style>...</style> 部分是 CSS 原始碼,而 <script ...</script> 部分則是 JavaScript 程式碼。

45 |
<html>
 46 | <head>
 47 | <title>範例 -- 功能表實作</title>
 48 | <style>
 49 | .menu   { background-color:black; color:white; padding:10px; 
 50 |           vertical-align:top; width:100px; list-style-type:none; }
 51 | .menu a { color:white; text-decoration:none; }
 52 | </style>
 53 | <script type="text/javascript">
 54 | function show(id) {
 55 |   document.getElementById(id).style.visibility='visible';
 56 | }
 57 |  
 58 | function hide(id) {
 59 |   document.getElementById(id).style.visibility='hidden';
 60 | }
 61 | </script>    
 62 |   </head>
 63 |   <body onload="JavaScript:hide('popup1');hide('popup2');">
 64 |       <ul onmouseover="show('popup1');"  onmouseout="hide('popup1')" 
 65 |           style="position:absolute; left:100px; top:20px">
 66 |         <li id="menu1" class="menu">menu1</li>
 67 |         <ul id="popup1" class="menu">
 68 |           <li><a href="JavaScript:alert('1.1');">menu 1.1</a></li>
 69 |           <li><a href="JavaScript:alert('1.2');">menu 1.2</a></li>
 70 |         </ul> 
 71 |       </ul>
 72 |       <ul onmouseover="show('popup2');" onmouseout="hide('popup2')" 
 73 |           style="position:absolute; left:220px; top:20px">
 74 |         <li id="menu2" class="menu">menu2</li>
 75 |         <ul id="popup2" class="menu">
 76 |           <li><a href="JavaScript:alert('2.1');">menu 2.1</a></li>
 77 |           <li><a href="JavaScript:alert('2.2');">menu 2.2</a></li>
 78 |           <li><a href="JavaScript:alert('2.3');">menu 2.3</a></li>
 79 |         </ul>
 80 |       </ul>
 81 |   </body>
 82 | </html>
83 |

雖然以上程式只是一個小小的功能表程式碼,但是要能夠讀懂,而且寫得出來,卻要懂相當多的技術才行,這些技術包含 HTML, CSS , JavaScript 與 Document Object Model (DOM)。

84 |

程式解析

85 |

在 HTML 的一開始,我們用以下語法描述了功能表所需要的 CSS 樣式,當我們套用在像 <li id="menu2" class="menu">menu2</li> 這樣的 HTML 項目上時,就會呈現比較好看的功能表排版格式,而這正是 CSS 樣式的功用。

86 |
<style>
 87 | .menu   { background-color:black; color:white; padding:10px; 
 88 |           vertical-align:top; width:100px; list-style-type:none; }
 89 | .menu a { color:white; text-decoration:none; }
 90 | </style>
91 |

以上的 CSS 語法中,要求功能表要以黑底白字的方式 (background-color:black; color:white;) 顯示,邊緣補上 10 點的空白(padding:10px;),而且是以向上靠攏 (vertical-align:top;) 的方式,每個功能表的寬度都是 100 點 (width:100px;),然後不要顯示項目前面的點符號 (list-style-type:none;)。

92 |

接著是一段 JavaScript 程式碼的語法,定義了 show(id) 與 hide(id) 這兩個函數,我們可以用這兩個函數在適當的時候讓功能表顯示出來或者是隱藏掉,這樣才能做到「浮現」的功能。

93 |
<script type="text/javascript">
 94 | function show(id) {
 95 |   document.getElementById(id).style.visibility='visible';
 96 | }
 97 |  
 98 | function hide(id) {
 99 |   document.getElementById(id).style.visibility='hidden';
100 | }
101 | </script>    
102 |

然後,開始進入 HTML 的 body 區塊,其中定義了兩組功能表,第一組的內容如下:

103 |
      <ul onmouseover="show('popup1');"  onmouseout="hide('popup1')" 
104 |           style="position:absolute; left:100px; top:20px">
105 |         <li id="menu1" class="menu">menu1</li>
106 |         <ul id="popup1" class="menu">
107 |           <li><a href="JavaScript:alert('1.1');">menu 1.1</a></li>
108 |           <li><a href="JavaScript:alert('1.2');">menu 1.2</a></li>
109 |         </ul> 
110 |       </ul>
111 |

上述區塊最外層的 <ul>...</ul> 定義了整個功能表的結構,是由功能母項 <li id="menu1" class="menu">menu1</li> 與子功能表 <ul id="popup1" class="menu">...</ul> 所組合而成的,而 <ul onmouseover="show('popup1');" onmouseout="hide('popup1')" style="position:absolute; left:100px; top:20px"> 這一段除了定義了該功能表要顯示在絕對位置 (100,20) 的地方之外,還定義了 onmouseover 與 onmouseout 的事件,這兩個事件讓功能表可以在滑鼠移入時顯示出來,然後在滑鼠移出時隱藏起來,因而做到了浮現式功能表所要求的條件。

112 |

由於我們在 <li>...</li> 內的超連結 <a href="JavaScript:alert('2.1');">menu 2.1</a> 使用了 JavaScript 語法,因此在該超連結被點選時,就會有警告視窗顯示 2.1 的訊息,這個訊息僅僅是讓我們知道該功能項被點選了而已,沒有真實的功能。

113 |

同樣的、第二個功能表的程式碼也是非常類似的,請讀者看看是否能夠讀者其內容。

114 |
      <ul onmouseover="show('popup2');" onmouseout="hide('popup2')" 
115 |           style="position:absolute; left:220px; top:20px">
116 |         <li id="menu2" class="menu">menu2</li>
117 |         <ul id="popup2" class="menu">
118 |           <li><a href="JavaScript:alert('2.1');">menu 2.1</a></li>
119 |           <li><a href="JavaScript:alert('2.2');">menu 2.2</a></li>
120 |           <li><a href="JavaScript:alert('2.3');">menu 2.3</a></li>
121 |         </ul>
122 |       </ul>
123 |

看到這裡,讀者應該大致理解了上述功能表網頁的運作原理,但事實上、我們還漏掉了一行重要的程式碼,那就是 <body onload="JavaScript:hide('popup1');hide('popup2');"> 這一行,這一行讓浮現功能表能在一開始就處於隱藏狀態,才不會一進來就看到兩個功能表都浮現出來的錯誤情況。

124 |

結語

125 |

從上述範例中,您可以看到瀏覽器中的 JavaScript ,通常是透過調整網頁某些項目的 CSS 屬性,以達成互動性的功能,這種互動網頁技術,事實上是結合了 HTML+CSS+JavaScript 等技術才能達成的功能,因此這三項技術在瀏覽器當中幾乎是合為一體、可以說是缺一不可的。

126 |

在本期中我們說明了互動式網頁的設計方式,但這樣的設計方式非常冗長,對程式人員而言是很大的負擔,因此在互動網頁興起之後,就逐漸出現了各式各樣的互動性 JavaScript 框架,也就是現成的 JavaScript 函式庫,讓我們可以輕易做出很好的互動性,像是 jQuery, ExtJS, YUI, Prototype, Dojo 等互動性函式庫,以便減輕 JavaScript 程式人員的負擔,增加程式員的生產力,在下一期當中,我們將使用最常被使用的 jQuery 框架,再度說明互動網頁的寫法,我們下期見!

127 |
128 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /htm/article4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 28 | 29 | 30 | 31 |
32 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

33 |
34 |
35 |

從 C# 看作業系統-(2) 競爭情況、鎖定與生產者/消費者問題 (作者:陳鍾誠)

36 |

競爭情況 (Race Condition)

37 |

至此,我們已經用 C# 實作了作業系統中的 Thread 與 Deadlock 這兩種慨念,但事實上、這兩個概念之間是有關係的,要理解 Thread 與死結之間的關係,就必須從 Race Condition (競爭情況) 這個問題談起。

38 |

在多 Thread (或多 CPU) 的情況之下,兩個 thread 可以共用某些變數,但是共用變數可能造成一個嚴重的問題,那就是當兩個 thread 同時修改一個變數時,這種修改會造成變數的值可能錯誤的情況,以下是一個範例。

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
Thread 1Thread 2Thread1+2 (第 1 種情況)Thread1+2 (第 2 種情況)
counter = 0
...
R1 = counterR1 = counterT1:R1 = counterT1:R1 = counter
R1 = R1 + 1R1 = R1 - 1T2:R1 = counterT1:R1 = R1+1
counter = R1counter = R1T2:R1 = R1-1T2:R1 = counter
T2:counter=R1T2:R1 = R1-1
T1:R1 = R1+1T2:counter = R1
T1:counter = R1T1:counter = R1
......
執行結果 : counter = 0執行結果 : counter = -1
111 |

這種情況並非只在多 CPU 的系統裡會發生,在單 CPU 的多線程系統裡也會發生,因為一個高階語言指令在翻譯成機器碼時,通常會變成很多個指令,這讓修改的動作無法在單一指令內完成,如果這些修改動作執行到一半的時候,線程被切換了,就會造成上述的競爭情況。

112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 |
高階語言組合語言對應動作
counter ++LD R1, counterR1 = counter
ADD R1, R1, 1R1 = R1 + 1
ST R1, countercounter = R1
138 |

這種競爭情況對程式設計者而言是無法接受的,如果程式的執行結果無法確保,那所有的程式都將陷入一團混亂,連 counter++ 這樣的動作都有問題的話,那任何多線程的程式都將無法正確運作。

139 |

為了避免這樣的問題產生,一個可能的解決方法是採用鎖定 (lock) 的方式,當我們執行共用變數的修改時,先進行鎖定,讓其他的線程無法同時修改該變數,等到修改完畢後解索後,其他的線程才能修改該變數,這樣就能避免掉競爭情況的問題了。

140 |

但是、一但我們能夠進行鎖定的動作,那就可能會造成上述的死結情況,這也正是 Thread 與死結之間的關係,讓我們用一句話總結如下:

141 |
因為多線程的程式會有競爭情況,為了避免該情況而引入了鎖定機制,
142 | 但是鎖定機制用得不好就會造成死結。
143 |

讓我們先用程式來驗證競爭情況的存在,以下是一個 C# 的競爭情況範例 (當然這種競爭情況是我們刻意造成的)。

144 |

檔案:RaceConditon.cs

145 |
using System;
146 | using System.Threading;
147 | using System.Collections.Generic;
148 | 
149 | class RaceCondition
150 | {
151 |     static int counter = 0, R1 = 0;
152 |     static void Main(string[] args)
153 |     {
154 |         Thread thread1 = new Thread(inc);
155 |         Thread thread2 = new Thread(dec);
156 |         thread1.Start();
157 |         thread2.Start();
158 |         thread1.Join();
159 |         thread2.Join();
160 |     }
161 | 
162 |     static Random random = new Random();
163 | 
164 |     static void waitAndSee(String msg)
165 |     {
166 |         Thread.Sleep(random.Next(0, 10));
167 |         Console.WriteLine(msg+"     R1:"+R1+" counter:"+counter);
168 |     }
169 | 
170 |     static void inc()
171 |     {
172 |         R1 = counter;
173 |         waitAndSee("inc:R1 = counter");
174 |         R1 = R1 + 1;
175 |         waitAndSee("inc:R1 = R1 + 1 ");
176 |         counter = R1;
177 |         waitAndSee("inc:counter = R1");
178 |     }
179 | 
180 |     static void dec()
181 |     {
182 |         R1 = counter;
183 |         waitAndSee("dec:R1 = counter");
184 |         R1 = R1 - 1;
185 |         waitAndSee("dec:R1 = R1 - 1 ");
186 |         counter = R1;
187 |         waitAndSee("dec:counter = R1");
188 |     }
189 | }
190 |

執行結果

191 |
D:\Dropbox\Public\cs\code>RaceCondition
192 | inc:R1 = counter     R1:0 counter:0
193 | dec:R1 = counter     R1:0 counter:0
194 | inc:R1 = R1 + 1      R1:0 counter:0
195 | inc:counter = R1     R1:0 counter:0
196 | dec:R1 = R1 - 1      R1:0 counter:0
197 | dec:counter = R1     R1:0 counter:0
198 | 
199 | D:\Dropbox\Public\cs\code>RaceCondition
200 | inc:R1 = counter     R1:0 counter:0
201 | inc:R1 = R1 + 1      R1:0 counter:0
202 | dec:R1 = counter     R1:0 counter:0
203 | inc:counter = R1     R1:-1 counter:0
204 | dec:R1 = R1 - 1      R1:-1 counter:0
205 | dec:counter = R1     R1:-1 counter:-1
206 |

要解決以上的競爭情況,必須採用一些協調 (Cooperation) 方法,C# 當中所提供的主要協調方法是 lock 這個語句。簡單來說,C# 的 lock 的實作方式就是採用作業系統教科書中所說的 Monitor 之方法,只是在 lock 的開始加入 Monitor.Enter() 語句,然後在 lock 的結束加入 Monitor.Exit() 語句而已,其方法如下所示。

207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 |
C# lockMonitor 語句
lock (_locker) {Monitor.Enter(_locker);
......
critical();critical();
......
}Monitor.Exit(_locker);
237 |

使用 lock 的方式,我們可以很輕易的解決上述程式的競爭情況,以下是該程式加入 lock 機制後的程式碼與執行結果。

238 |

檔案:RaceConditonLock.cs

239 |
using System;
240 | using System.Threading;
241 | using System.Collections.Generic;
242 | 
243 | class RaceConditionLock
244 | {
245 |     static int counter = 0, R1 = 0;
246 |     static String counterLocker = "counterLocker";
247 |     
248 |     static void Main(string[] args)
249 |     {
250 |         Thread thread1 = new Thread(inc);
251 |         Thread thread2 = new Thread(dec);
252 |         thread1.Start();
253 |         thread2.Start();
254 |         thread1.Join();
255 |         thread2.Join();
256 |     }
257 | 
258 |     static Random random = new Random();
259 | 
260 |     static void waitAndSee(String msg)
261 |     {
262 |         Thread.Sleep(random.Next(0, 10));
263 |         Console.WriteLine(msg+"     R1:"+R1+" counter:"+counter);
264 |     }
265 | 
266 |     static void inc()
267 |     {
268 |         lock (counterLocker) {
269 |             R1 = counter;
270 |             waitAndSee("inc:R1 = counter");
271 |             R1 = R1 + 1;
272 |             waitAndSee("inc:R1 = R1 + 1 ");
273 |             counter = R1;
274 |             waitAndSee("inc:counter = R1");
275 |         }
276 |     }
277 | 
278 |     static void dec()
279 |     {
280 |         lock (counterLocker) {
281 |             R1 = counter;
282 |             waitAndSee("dec:R1 = counter");
283 |             R1 = R1 - 1;
284 |             waitAndSee("dec:R1 = R1 - 1 ");
285 |             counter = R1;
286 |             waitAndSee("dec:counter = R1");
287 |         }
288 |     }
289 | }
290 |

執行結果

291 |
D:\Dropbox\Public\cs\code>csc RaceConditionLock.cs
292 | 適用於 Microsoft (R) .NET Framework 4.5 的
293 | Microsoft (R) Visual C# 編譯器版本 4.0.30319.17929
294 | Copyright (C) Microsoft Corporation. 著作權所有,並保留一切權利。
295 | 
296 | 
297 | D:\Dropbox\Public\cs\code>RaceConditionLock
298 | inc:R1 = counter     R1:0 counter:0
299 | inc:R1 = R1 + 1      R1:1 counter:0
300 | inc:counter = R1     R1:1 counter:1
301 | dec:R1 = counter     R1:1 counter:1
302 | dec:R1 = R1 - 1      R1:0 counter:1
303 | dec:counter = R1     R1:0 counter:0
304 | 
305 | D:\Dropbox\Public\cs\code>RaceConditionLock
306 | inc:R1 = counter     R1:0 counter:0
307 | inc:R1 = R1 + 1      R1:1 counter:0
308 | inc:counter = R1     R1:1 counter:1
309 | dec:R1 = counter     R1:1 counter:1
310 | dec:R1 = R1 - 1      R1:0 counter:1
311 | dec:counter = R1     R1:0 counter:0
312 | 
313 | D:\Dropbox\Public\cs\code>RaceConditionLock
314 | inc:R1 = counter     R1:0 counter:0
315 | inc:R1 = R1 + 1      R1:1 counter:0
316 | inc:counter = R1     R1:1 counter:1
317 | dec:R1 = counter     R1:1 counter:1
318 | dec:R1 = R1 - 1      R1:0 counter:1
319 | dec:counter = R1     R1:0 counter:0
320 |

號誌 (Semaphore) 與生產者/消費者問題

321 |
using System;
322 | using System.Threading;
323 | using System.Collections.Generic;
324 | 
325 | class ProducerConsumer
326 | {
327 |     static readonly int BUFFER_SIZE = 3;
328 |     static Queue<int> queue = new Queue<int>(BUFFER_SIZE);
329 |     static Semaphore filled = new Semaphore(0, BUFFER_SIZE);
330 |     static Semaphore unfilled = new Semaphore(BUFFER_SIZE, BUFFER_SIZE);
331 |     static Mutex mutex = new Mutex(false);
332 | 
333 |     static void Main(string[] args)
334 |     {
335 |         Thread producer = new Thread(new ThreadStart(produce));
336 |         Thread consumer = new Thread(new ThreadStart(consume));
337 |         producer.Start();
338 |         consumer.Start();
339 |         producer.Join();
340 |         consumer.Join();
341 |     }
342 | 
343 |     static Random random = new Random();
344 | 
345 |     private static void produce()
346 |     {
347 |         while (true)
348 |         {
349 |             Thread.Sleep(random.Next(0, 500));
350 |             int produceNumber = random.Next(0, 20);
351 |             Console.WriteLine("Produce: {0}", produceNumber);
352 | 
353 |             unfilled.WaitOne();     // wait(unfilled)
354 |             mutex.WaitOne();                // wait(mutex)
355 |             
356 |             queue.Enqueue(produceNumber);
357 | 
358 |             mutex.ReleaseMutex();           // signal(mutex)
359 |             filled.Release();       // signal(filled)
360 | 
361 |             if (produceNumber == 0)
362 |                 break;
363 |         }
364 |     }
365 | 
366 |     private static void consume()
367 |     {
368 |         while (true)
369 |         {
370 |             filled.WaitOne();       // wait(filled)
371 |             mutex.WaitOne();                // wait(mutex)
372 |             int number = queue.Dequeue();
373 |             Console.WriteLine("Consume: {0}", number);
374 | 
375 |             mutex.ReleaseMutex();           // signal(mutex)
376 |             unfilled.Release(); // signal(unfilled)
377 |             if (number == 0)
378 |                 break;
379 |             Thread.Sleep(random.Next(0, 1000));
380 |         }
381 |     }
382 | }
383 |

執行結果

384 |
D:\Dropbox\Public\pmag\201304\code>ProducerConsumer
385 | Produce: 7
386 | Consume: 7
387 | Produce: 4
388 | Produce: 12
389 | Consume: 4
390 | Produce: 16
391 | Produce: 1
392 | Consume: 12
393 | Produce: 8
394 | Consume: 16
395 | Produce: 15
396 | Produce: 7
397 | Consume: 1
398 | Produce: 18
399 | Consume: 8
400 | Produce: 0
401 | Consume: 15
402 | Consume: 7
403 | Consume: 18
404 | Consume: 0
405 |

另外、在作業系統中有個多行程的經典問題稱為 Dining Philospher (哲學家用餐) 問題,也可以採用 lock 的方法解決,由於這個問題實務上比較不那麼常用,本文中就不再詳細探討此一問題,有興趣的朋友可以看看網路上的解決方法,像是以下這篇 java2s 當中的程式就用 C# 實作解決了此一問題。

406 | 409 |

在本章中,我們購過透過實作的方式,讓讀者感受作業系統當中的 Thread、Deadlock、Race Condition、與 Semaphore 等概念,希望這樣的說明方式對讀者會有所幫助。

410 |

參考文獻

411 | 421 |
422 | 425 | 426 | 427 | -------------------------------------------------------------------------------- /htm/article3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 28 | 29 | 30 | 31 |
32 |

程式人雜誌 -- 2013 年 4 月號 (開放公益出版品)

33 |
34 |
35 |

R 統計軟體(2)-抽樣與敘述統計 (作者:陳鍾誠)

36 |

隨機抽樣

37 |

統計的基礎是抽樣,所謂的抽樣就是從母體 (一大群樣本) 當中抽出一些樣本,而在抽樣的時候,我們通常會盡可能的確保樣本的隨機性,以避免抽到的樣本有所偏差。

38 |

簡單來說,抽樣是從一群東西(母體) 當中隨機抽取出 x1, x2, ...., xn 等 n 個觀察值的過程,表示如下:

39 |
母體 => (獨立性) X1, X2, .... , Xn 等 n 個隨機變數相互獨立 => 取出 x1, x2, ...., xn 等 n 個觀察值。
40 |

在電腦上,我們可以很容易的模擬隨機抽樣,以下是一個使用 R 軟體模擬隨機抽樣的範例,其中指令 sample(1:100, 10) 代表從 1 到 100 的整數當中取出 10 個樣本出來。

41 |
> x = sample(1:100, 10)
 42 | > x
 43 |  [1] 12 17 50 33 98 77 39 79  7 26
44 |

sample 函數的原型是 sample(x, size, replace = FALSE, prob = NULL),如果 replace 設定為 FALSE,代表已經取過就會被去除,不能重複出現;反之則可以重複出現。

45 |

在統計學中,有一些常用的機率模型,都有對應的 R 抽樣函數,以下是一些最常用的機率模型之整理。

46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
機率模型密度函數R 函數名稱說明
二項分布{n \choose x} p^x (1-p)^{n-x}binom(n:size, p:prob)n:樣本數, p:正面機率,
n 次試驗中有 x 個成功的機率
布瓦松分布\frac{e^{-\lambda s} {\lambda s}^x}{x!}pois(lambda)k:期望值, \lambda = \frac{k}{s},
在 s 時間內,事件出現平均 k 次
均勻分布 (Uniform)\frac{1}{b-a}unif(a:min, b:max)a:範圍下限, b: 上限
出現機會均等
常態分布(Normal)\frac{1}{\sqrt{2\pi} \sigma} e^{- \frac{1}{2} [(x-\mu)/\sigma]^2}norm(mean, sd)中央極限定理:x1+x2+...+xk; 當 k 越大就越接近常態分布
指數分布 (Exponential)\frac{1}{b} e^{-x/b}exp(rate)伽瑪分布(a=1, b=\frac{1}{\lambda})
布瓦松過程中,第一次事件出現的時間 W
88 |

對於每個機率模型,您只要在該函數前若加入 r 這個字,就可以用來產生隨機樣本,以下是一些隨機樣本的產生範例。

89 |
> rbinom(20, 5, 0.5)
 90 |  [1] 4 3 3 4 2 4 3 1 2 3 4 3 2 2 2 4 2 3 1 1
 91 | > rpois(20, 3.5)
 92 |  [1] 2 1 4 2 1 6 3 6 1 3 3 6 6 0 4 2 6 4 6 2
 93 | > runif(20, min = 3, max = 8)
 94 |  [1] 3.933526 3.201883 7.592147 5.207603 4.897806 3.848298 4.521461 4.437873
 95 |  [9] 3.655640 5.633540 6.557995 5.430671 6.502675 5.637283 7.713699 5.841052
 96 | [17] 6.859493 5.987991 3.752924 7.480678
 97 | > rnorm(20, mean = 5.0, sd = 2.0)
 98 |  [1] 6.150209 4.743013 3.328734 5.096294 4.922795 6.272768 4.862825 8.036376
 99 |  [9] 4.198432 5.467984 2.046450 6.452511 2.088256 5.349187 3.074408 3.628072
100 | [17] 3.421388 7.242598 3.125895 9.865341
101 | > rexp(20, rate=2.0)
102 |  [1] 0.17667426 0.49729383 0.12786107 0.13983412 0.44683515 1.30482842
103 |  [7] 0.28512544 1.61472266 0.23220649 0.39089780 0.05947224 1.42892610
104 | [13] 0.02555552 0.69409186 0.68228242 0.22542362 0.33590791 0.14684937
105 | [19] 0.34995146 0.80595369
106 |

為了讓讀者能確認這些指令所產生的圖形確實符合分布,讓我們用這些隨機抽樣函數各產生 100,000 個樣本, 然後用 hist() 這個函數繪製統計圖,就能看出這些抽樣函數的效果了,以下是我們的抽樣指令與結果圖形。

107 |
> x = rbinom(100000, 5, 0.5)
108 | > hist(x)
109 |
110 | rbinom(100000, 5, 0.5) 的統計圖

rbinom(100000, 5, 0.5) 的統計圖

111 |
112 |
> y = rpois(100000, 3.5)
113 | > hist(y)
114 |
115 | rpois(100000, 3.5) 的統計圖

rpois(100000, 3.5) 的統計圖

116 |
117 |
> z = runif(100000, min=3, max=8)
118 | > hist(z)
119 |
120 | runif(100000, min=3, max=8) 的統計圖

runif(100000, min=3, max=8) 的統計圖

121 |
122 |
> w = rnorm(100000, mean=5.0, sd=2.0)
123 | > hist(w)
124 |
125 | rnorm(100000, mean=5.0, sd=2.0) 的統計圖

rnorm(100000, mean=5.0, sd=2.0) 的統計圖

126 |
127 |
> v = rexp(100000, rate=2.0)
128 | > hist(v)
129 |
130 | rexp(100000, rate=2.0) 的統計圖

rexp(100000, rate=2.0) 的統計圖

131 |
132 |

敘述統計:單組樣本的統計

133 |

敘述統計乃是隨機抽樣的樣本集合,進行某些計算與繪圖,以便忠實的呈現出樣本的某些特性。這些計算出的數值,以及呈現出來的圖形,可以反映出樣本的某些統計特性,讓統計者能透過數值或圖形,大致了解樣本的統計特徵。

134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
中文名稱英文名稱數學公式 / 說明
樣本平均數Mean\bar{X} = \frac{\sum_{i=1}^n X_i}{n}
樣本中位數Median樣本排序後最中間位置的數值
樣本變異數Sample VarianceS^2 = \sum_{i=1}^n \frac{(X_i - \bar{X})^2}{n-1} = \frac{n \sum_{i=1}^n X_i^2 - (\sum_{i=1}^n Xi)^2}{n (n-1)}
樣本標準差Sample Standard Deviation樣本變異數中的 S 稱為樣本標準差,也就是 \sqrt{S^2}
樣本全距Range樣本中最大的觀察值減去最小的觀察值 \omega = X_H-X_L
離群值Outlier 或 Wild離其他樣本很遠,特別大或特別小的樣本值
樣本四分數間距InterQuartile Range, IQR第 3 四分位數減掉第 1 四分位數 IQR = q_3 - q_1
180 |

注意:變異數的定義為 \delta^2 = E[(X-\mu)^2],上述的樣本變異數必須除以 n-1 才是變異數的不偏估計量,而不是除以 n。

181 |

R 操作範例:敘述統計

182 |
> x = sample(1:100, 10)
183 | > x
184 |  [1] 12 17 50 33 98 77 39 79  7 26
185 | > mean(x)
186 | [1] 43.8
187 | > median(x)
188 | [1] 36
189 | > var(x)
190 | [1] 984.1778
191 | > sd(x)
192 | [1] 31.37161
193 | > range(x)
194 | [1]  7 98
195 | > max(x)
196 | [1] 98
197 | > min(x)
198 | [1] 7
199 | > max(x)-min(x)
200 | [1] 91
201 | > q1 = quantile(x, 0.25)
202 | > q1
203 |   25% 
204 | 19.25 
205 | > q3 = quantile(x, 0.75)
206 | > q3
207 |   75% 
208 | 70.25 
209 | > q3-q1
210 | 75% 
211 |  51 
212 | > iqr(x)
213 | 錯誤: 沒有這個函數 "iqr"
214 | > IQR(x)
215 | [1] 51
216 | > fivenum(x)
217 | [1]  7 17 36 77 98
218 | > summary(x)
219 |    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
220 |    7.00   19.25   36.00   43.80   70.25   98.00 
221 |

敘述統計:繪製統計圖

222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 |
中文名稱英文名稱說明
直方圖Histogram根據每個區間的樣本出現次數繪製的長條圖。
肩型圖 (累加分配圖)Relative Cumulative Frequency Ogive將累加次數繪製出來的圖形。
莖葉圖Stem-and-Leaf Diagram用主幹數字與分支數字表示分布情況的圖形。
盒型圖Boxplots由平均值、內籬笆與外籬笆所形成的盒型圖,可看出中心點與離散程度。
253 |

說明:盒型圖是由四分位數 q1, q3, 以及內籬笆 f1, f3 (inner fences), 連接值 a1, a3 與外籬笆 F1, F3 (outer fances) 所組成的圖形

254 | 259 |

R 操作範例 : 統計圖

260 |
> x = rnorm(100)
261 | > x
262 |   [1]  0.389381081 -0.274522826  1.492670583 -1.563228609  0.766405108
263 |   [6]  0.736573742  0.297407135 -1.324130406 -1.376598231  1.661727175
264 |  [11] -1.356590351  1.309122339 -1.193821085  0.365801091 -0.952034088
265 |  [16] -0.277610568 -0.599980091 -0.124105876 -1.107713162  0.560637570
266 |  [21]  0.714449138  0.111969057  0.505171739 -2.418297599  0.318797182
267 |  [26]  2.716646516  0.345289422  0.019434615  1.087758951  0.033917165
268 |  [31] -0.356786424 -1.284809066  1.580411327  0.552931291 -0.615928762
269 |  [36] -0.087069820 -0.814632197 -0.570882510 -0.107731447 -1.453838416
270 |  [41] -0.257115209  1.166866120  1.072692716 -0.022594852  0.441221144
271 |  [46]  1.053900960 -1.025193547 -1.119200587  0.264668203  1.409504515
272 |  [51]  0.241644132 -0.955407800  0.446297381  0.231887649  0.769308731
273 |  [56]  0.269624579  0.496109294  0.822638573 -0.904380789 -0.429527404
274 |  [61] -2.050582772 -0.586973281 -1.192753403  1.158321933 -0.151319360
275 |  [66]  0.558858868 -0.656174351 -2.858964403  0.366785049  0.896958092
276 |  [71]  0.369315063 -0.953560954 -0.762608370 -1.017449547 -0.127738562
277 |  [76] -1.922030980 -0.839897930  1.332972530 -0.001151104  0.104336360
278 |  [81] -0.208907813  1.401335798  0.019330593 -0.687559289  0.445371885
279 |  [86]  0.504532689  2.168626000 -1.742886230  0.831058071  2.011604088
280 |  [91]  1.676059594  1.132849957 -1.047073217 -0.912548540 -2.235854777
281 |  [96] -1.194104128  0.121106118 -1.178415224  0.214196778  0.280714044
282 | > stem(x)
283 | 
284 |   The decimal point is at the |
285 | 
286 |   -2 | 9421
287 |   -1 | 97654433222211000000
288 |   -0 | 998887766664433322111100
289 |    0 | 00011122233333344444445556667788889
290 |    1 | 11112233445677
291 |    2 | 027
292 | 
293 | > hist(x, main="Frequency Histogram of x")
294 | 
295 | > hist(x, main="Probability Histogram of x", freq=F)
296 | 
297 | > Fx = ecdf(x)
298 | 
299 | > plot(x)
300 | 
301 | > plot(Fx)
302 | 
303 | > boxplot(x)
304 |
305 | 統計圖

統計圖

306 |
307 |
308 | 盒狀圖

盒狀圖

309 |
310 |

以上都是對於單組樣本的統計數字與圖形,以下將討論兩組樣本的統計數字

311 |

敘述統計:共變異數、兩組樣本的相關度統計

312 |

兩組樣本的統計數字,最重要的就是共變異數 (covariance) 相關係數 (correlation) 與了。

313 |

共變異數是兩組樣本 X, Y 的樣本與期望值之間差的乘積之期望值,而相關係數則共變異數經過 正規化後的結果,用來表示兩組樣本相關程度,其數值介於 -1.0 到 1.0 之間。

314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 |
中文名稱英文名稱數學公式 / 說明
共變異數covariance\gamma_{XY} =E[ (X-E[X])\,(Y-E[Y])]
相關係數correlation\phi_{XY}  =E[ (X-E[X])(Y-E[Y])]/(\sigma_X \sigma_Y)
335 |

讓我們看看 R 軟體中的共變異數函數 cov() 與相關係數 cor() 的操作,如下所示:

336 |
 runif(10, 1, 5)
337 | > x
338 |  [1] 1.375135 1.863417 2.403693 2.639902 1.694610 4.419406 4.032262 2.147783
339 |  [9] 1.501733 1.497732
340 | > cov(x, x)
341 | [1] 1.144697
342 | > cov(x, x+1)
343 | [1] 1.144697
344 | > cor(x, x)
345 | [1] 1
346 | > cor(x, x+1)
347 | [1] 1
348 | > cov(x, -x)
349 | [1] -1.144697
350 | > cor(x, -x)
351 | [1] -1
352 | > cor(x, 0.5*x)
353 | [1] 1
354 | > y = runif(10, 1, 5)
355 | > y
356 |  [1] 1.114662 2.358270 2.089179 4.581484 4.170922 2.630044 1.450336 1.320637
357 |  [9] 1.705649 3.506064
358 | > cor(x, y)
359 | [1] -0.04560485
360 | > cor(y, y)
361 | [1] 1
362 | > 
363 |

以上敘述統計所計算出來的數值,都有很直覺的意義,我們就不對這些數值進行詳細的數學說明了,有興趣的讀者請參考統計學的書籍。

364 |

在下一期當中,我們將介紹一個重要的機率統計法則:「中央極限定理」,並用 R 軟體進行驗證, 這個法則是理解後續的推論統計程式,像是「信賴區間與檢定的基礎」,我們下期見!

365 |
366 | 369 | 370 | 371 | --------------------------------------------------------------------------------