2016年12月29日 星期四

electron 上手筆記

electron 上手筆記

這裡 electron 是說 github 推的跨平台桌面應用程式開發工具,使用 html, css, javascript 開發。

文件、範例哪兒找?

有無簡易模板?

請參閱 quick-start 那份文件,我這裡也略述之。

專案目錄檔案結構

專案名稱/
– package.json
– main.js
– index.html

package.json

package.json 的內容如下:

{
    "name":"專案名稱",
    "version":"0.1.0",
    "main":"main.js"
}

如果沒有 main 這欄,electron 會去找 index.js 來用。

main.js

main.js 的工作是建立 window 以及處理系統事件。(這裡的系統事件指的是 electron 裡的 app 物件事件)

以下是範例:

const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win

function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({width: 800, height: 600})

  // and load the index.html of the app.
  win.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  // Open the DevTools.
  win.webContents.openDevTools()

  // Emitted when the window is closed.
  win.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    win = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

index.html

index.html 就等於是畫面定義。範例如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using node <script>document.write(process.versions.node)</script>,
    Chrome <script>document.write(process.versions.chrome)</script>,
    and Electron <script>document.write(process.versions.electron)</script>.
  </body>
</html>

開發時如何執行程式?

electron 安裝在 global

在專案目錄裡的命令列執行

electron .

electron 安裝在 local

在專案目錄裡的命令列執行

macOS/Linux

$ ./node_modules/.bin/electron .

Windows

$ .\node_modules\.bin\electron .

electron 是來自 binary download

Windows

$ .\electron\electron.exe your-app\

Linux

$ ./electron/electron your-app/

macOS

$ ./Electron.app/Contents/MacOS/Electron your-app/

有沒有現成的範例檔下載?

用 npm 來做:

# Clone the repository
$ git clone https://github.com/electron/electron-quick-start
# Go into the repository
$ cd electron-quick-start
# Install dependencies
$ npm install
# Run the app
$ npm start

2016年12月4日 星期日

[vscode]開發 extension 的豆知識

前置作業

開發 vscode 的 extension,要先知道的是:
* 開發語言是 TypeScript or JavaScript
* 開發電腦要裝 node.js,還有 Yeoman and the Yeoman VS Code Extension generator

npm install -g yo generator-code
yo code

產生起始開發專案

執行命令列 yo code 之後,會讓你選擇使用何種語言開發。
然後回答幾個問題,它就會產生一個目錄,再進去那個目錄裡執行 code .,就開始寫程式。需要一點時間,因為它需要下載相依套件,準備文件內容再啟動 vscode 編輯器。

debug

按 F5。會需要一點時間,它需要編譯相關檔案後,啟動 vscode 測試用編輯器。它的標題會寫[擴充功能開發主機],以標記為它實際是用來測試你寫的程式的。如果你有改程式,建議是在[擴充功能開發主機]按 ctrl-r 會比較快。如果是關掉它再按 F5 就會比較慢。至於文件上說直接按 F5 這招我就試不出來了。但是在[擴充功能開發主機]開著的情況下,有個 ctrl-shift-F5 是重新啟動,也很快速。

文件中有說,直接按 ctrl-r 重載入 會有用是因為 vscode 有為 .ts 的檔案註冊事件,只要有改變就會重新編譯,所以對於開發主機那裡只要重載入(ctrl-r)就行了。

vscode 的擴充功能的 API 也都有連帶放在 yo 所產生的檔案裡。就是 node_modules\vscode\vscode.d.ts

deploy

FileSystemWatcher

  • 一定要裝 .Net 4.5
  • 要監控的 path 那裡,請記得是它是 glob 的字串。要監控目錄,就是目錄再加 *.*

showInformationMessage

目前沒辦法自動消失

String.format

這個東西不在標配裡。在 typescript 也沒有。用幾個網路上找節的目前都無解。正在嘗試組合技。

參考

2016年9月23日 星期五

[vscode]extension 裡的 FileSystemWatcher 壞掉了?

Why is vs code’s FileSystemWatcher not working on my Windows 7?
You need .NET 4.5.

前言

這篇其實就是個一拳就解決的事情。但是為了要演滿20分鐘,所以傑諾斯一定要撐很久的情況。不能打贏對手,也不能一拳就躺下來休息。(我在講什麼?)

環境

出問題的環境多是 windows 7,其他的環境像是 windows 8, windows 10, mac os, linux 幾乎都沒人中招。

問題描述

這樣也可以撐三段,可以了。簡單來說,像是 Package-Watcher 這種會看某個檔案是否會被外部程式改變的。它需要一個 FileSystemWatcher 的實體,由 workspace.createFileSystemWatcher 產生,然後處理它的 onDidChage。
// 這是 TypeScript,微軟主推在 javascript 世界的前置語言,它會被編譯成合於 ES5、ES6、或 ES7 再交由 node.js 或瀏覽器執行。

let path = vscode.workspace.rootPath + "/package.json";
let watcher = vscode.workspace.createFileSystemWatcher(path);
watcher.onDidChange((e) => {
    console.log('package.json change')
})
但是!!這就是在我的 windows 7 裡不能執行。花了我快十個小時,弄到凌晨四、五點不得不去睡覺,但還是沒解。
今天上午去查 issue,看到這一句:
This issue is that Electron requires .NET 4.5 since it uses System.Threading.Tasks.Task.Delay(Int32) which came with .NET 4.5
來源:https://github.com/Microsoft/vscode/issues/5083
就是說,因為 windows 7 常常有人忘了要裝到 4.5,沒注意到的話,通常都留在 4.0。而其他版本,要嘛因為不能裝,要嘛太低使用者會自己裝,要嘛內建就 4.5,所以中招的就是 windows 7 最多!

解法

請裝 .NET 4.5。
一拳。

[atom]開啟多個視窗

前言

在使用上,如果已經開啟一個 atom 視窗。之後若是再開啟其他位置的檔案,會通通擠在一起視窗裡,在 tree view 也都放在同一個 project folder 裡。在我自己使用上,因為會在不同的位置開一些檔案做參考,不屬於同一個專案,全部擠在一起不方便。有時檔名一樣,很容易搞錯。

對手怎麼做?

我把vscode 視為 atom 的對手,它的行為就是不同目錄開起來就是會不同視窗。搞錯機會很低。

解決方法

網路上是有說用命令列參數 -n--new-window,例如 atom -n ~/file。但是在 windows 下,其實習慣的是右鍵來處理。可惜沒找到。

另一個方法則是開啟之後,對不同目錄的檔案的頁籤,按右鍵,會出現「open in new window」,按下去就會再開一個視窗。只是它會把原先那個目錄留在 tree view 裡,這樣就是兩個 project folder。像我比較龜毛就會去把它移掉。對著目錄按右鍵,選擇「remove project folder」這樣就比較乾淨一點。

更新: 我找到更簡單的方法。如果在其他目錄也要開檔案,不要直接開啟那個檔案,而是開啟那個目錄,這樣就會再開一個 atom 視窗。這就正合我意。‧‧‧‧‧

2016年9月20日 星期二

[sozi]大改版

[sozi]大改變

sozi 16 的大改變

前言

除了 inkscape 版本快速之外,sozi 從 15 開始的大變動我沒跟上,今天才知道,那就是它脫離了 inkscape 而獨立了。

主要變動

說是獨立,應該也可以說它換到一個新環境,叫做 nw.js,據說是 intel 主導的一個開發專案。軟體堆疊是 node.js 與 Chromium engine。開發時使用 html , css, javascript,平台移植性相當好。

因為它現在不在是個外掛,所以,直接下載 zip 檔,解開之後,執行裡面的執行檔就行了。

下載地方:https://github.com/senshu/Sozi/releases/tag/16.02-fix344

操作流程大改變

在執行 sozi 之前,請先看一下教程,免得浪費時間瞎摸。 http://sozi.baierouge.fr/pages/tutorial-first.html

操作流程大改變,因為它本身只做簡報編輯動作,所以必須要先把 svg 檔準備好,這是第一個大不同的地方。

在選好 svg 檔之後,第一個動作是建立新的 frame。那個「+」按鈕在視窗下方。按下去之後,調整 frame 的 title 在右方欄,改一個文字框,記得要按 enter。

調整 carema 的方法,用滑鼠:
* 移動:滑鼠左鍵按住、拖動
* zoom:滑鼠左鍵、鍵盤 alt 鍵按住、拖動
* 旋轉:滑鼠左鍵、鍵盤 shift 鍵按住、拖動

存檔基本上不用擔心,它會自動存,也有按鈕可以按。原始的 svg 不會動到,你要播放的所有東西都放在 {檔名.sozi.html} 那個檔案裡了。

結語

這樣的改變還喜歡嗎?第一個優點是不用再擔心安裝的問題、再來不擔心平台的問題、之前跟 inkscape 整合有點不順手的問題也沒了。缺點我個人認為是要先把 svg 準備好。有愛就繼續支持囉!

[超譯]設定vscode markdown 環境

[超譯]VS code 的 markdown

譯序

參考文件是 https://code.visualstudio.com/docs/languages/markdown
內建支援 preview (預覽),也可多裝 extension 加強能力。
本來是想寫心得的,不小心就變超譯了。既然是超譯,就代表有些地方我會增減。有興趣還請看原文。

前言

在 Visual Studio Code 裡使用 markdown 可以非常有趣,也有很多 markdown 的特色讓你更有生產力。

markdown extension

內建的功能之外,還有一些 extension 增加功能。

譯註:這段在文章裡是動態產生一組 markdown 相關的 extension 列表,所以會是什麼會隨時間演進。

開啟預覽

要開一個預覽是用 ctrl-shift-v,會多開一個 tab (頁籤) 顯示。這個我覺得不好用,我喜歡 side by side (也就是視窗並列)的方式。按鍵是 ctrl-k v (先按 ctrl-k,然後放開,再按 v,這個不能在中文輸入法裡,如果卡在輸入法中,會抓不到 v 這個鍵) 叫出視窗並列的預覽。

使用自己的 css

可以改變預覽的樣子,當然,對於後續的編譯成 html 也有用途。要更新 "markdown.styles": [] 的設定。

例如我有一個 css 長這樣:

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

h1 {
    color: cornflowerblue;
}

用 File > Preferences > Workspace Settings 開啟設定 settings.json 更新裡面的內容為:

// Place your settings in this file to overwrite default and user settings.
{
    "markdown.styles": [
        "Style.css"
    ]
}

## snippets for markdown
有幾個內建的 snippets,用 ctrl-space 來驅動,這就會依語境提供一串建議。

譯註:ctrl-space 在中文輸入法啟用的時候,悲劇。

編譯成 html

VS code 整進一個 task runner 可以用它與 markdown 編譯器合作完成編譯工作。可以把 .md 檔變成 .html 檔。

  1. 背後是使用 node.js 來處理,所以要安裝 node.js 之外,再加上 marked。用 npm 安裝 npm install -g marked
  2. 建立一個 md 檔。記得開啟一個「目錄」再開一個新檔案 sample.md (多餘的我不想翻…) 把底下的文字放進去:

    Hello Markdown in VS Code!
    ====================
    
    This is a simple introduction to compiling Markdown in VS Code.
    
    Things you'll need:
    
    * [node](https://nodejs.org)
    * [marked](https://www.npmjs.com/package/marked)
    * [tasks.json](/docs/editor/tasks)
    
    ## Section Title
    
    > This block quote is here for your information.
    
  3. 建立 task.json。打開 Command Palette (用 ctrl-shift-p),然後在裡打字 Configure Task Runner,然後按 enter。它會列出可能的 tasks.json 模板,選 Others,因為我們要執行外部命令。這會在你的 Workspace 的 .vscode 目錄裡產生一個 tasks.json 檔案,長成這樣:

    {
        // See http://go.microsoft.com/fwlink/?LinkId=733558
        // for the documentation about the tasks.json format
        "version": "0.1.0",
        "command": "echo",
        "isShellCommand": true,
        "args": ["Hello World"],
        "showOutput": "always"
    }
    

    因為我們要使用 marked 編譯 markdown 檔,所以要改成以下這樣:

    {
    // See http://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "marked",
    "isShellCommand": true,
    "args": ["sample.md", "-o", "sample.html"],
    "showOutput": "always"
    

    }

    這設定的意思是把 marked 當成一個外部任務執行者,只執行一項任務,把 markdown 檔編譯成 html 檔,它的命令是 marked sample.md -o sample.html

  4. 執行建立任務。以上只是在檔案裡設定,要執行它可以按 ctrl-shift-b (Run Build Task)。此時,你應該可以看到一個增加的 sample.html 檔案出現在檔案列表裡。

    這個範例不會出現什麼問題所以執行任務完會有對應的 sample.html 被建立。

自動編譯

再進一步,想要自動編譯的話,需要多做些事。

  1. 加裝 gulp npm install -g gulp gulp-markdown。多裝 gulp-markdown 會讓事情簡單一點。

  2. 建立 gulp task。在 simple.md 那個目錄開新檔案 gulpfile.js。把以下內容放進去:

    var gulp = require('gulp');
    var markdown = require('gulp-markdown');
    
    gulp.task('markdown', function() {
        return gulp.src('**/*.md')
            .pipe(markdown())
            .pipe(gulp.dest(function(f) {
                return f.base;
            }));
    });
    
    gulp.task('default', function() {
        gulp.watch('**/*.md', ['markdown']);
    });
    

    以上程式會做這些事:

    1. 在 Workspace 裡看哪些檔案有變動。
    2. 把有改變的 markdown 檔案們,用 markdown 編譯器處理一遍。(gulp-markdown)
    3. 這樣我們就會有一堆名字對應的 markdown 檔與 html 檔在同一目錄裡。
  3. 修改 tasks.json 以完成監視。要完整把任務整合進 VS code,還需要修改任務設定。改成以下的樣子:

    {
        "version": "0.1.0",
        "command": "gulp",
        "isShellCommand": true,
        "tasks": [
            {
                "taskName": "default",
                "isBuildCommand": true,
                "showOutput": "always",
                "isWatching": true
            }
        ]
    }
    
  4. 執行 gulp Build Task。以上仍是一個檔案內的設定,要執行它要按 ctrl-shift-b (Run Build Task)。但這次我們是設定一個監視,所以 Status Bar 應該會在左手邊指示。

    現在,如果建立或改變其他的 markdown 檔,你會看到對應的 html 被產生出來或是存檔時反應改變。你也可以啟用 Auto Save 讓事情更流暢。

    如果你要停止監視,你可以按 ctrl-shift-b,然後在 message box 裡點 Terminate Running Task。或者你可以用 Command Palette (用 ctrl-shift-p 叫出來),然後找到 terminate command。

接下來

你可以往下看的是:

幾個常見問答

  • 有無拼字檢查?
    • 內建沒有,但是可以加裝 spell checking extension
  • 有無支援 github 風格的 markdown?
    • 沒有,VS code 以支援 CommonMark 為目標,使用 markdown-it 函式庫(它實作 CommonMark 標準)。
  • 上面的過程裡我在 Command Palette 找不到 Configure Task Runner 命令?
    • 你應該是一開始選擇開啟檔案,而不是開啟目錄。你可以用 File > Open Folder…開啟目錄,或是用命令列 cd 到目的地,再執行 code . 開啟目錄。

2016年9月12日 星期一

[atom]設定 python 開發環境

前言

要知道好不好用,就得用心體會,就拿來試試開發 python 程式吧。

材料

谷歌到一系列 youtube ,就照本宣科試試。

https://www.youtube.com/watch?v=uve1tjVIQ6c

步驟:格式設定

  1. 顯示縮排的尺 (Show Indent Guide)。 在 1.10.2 的版本是放在 Settings > Editor 這裡。
  2. 使用 Soft Tabs
  3. Tabs length 設成 4

步驟:套件安裝

  1. 啟用 autosave。對 Settings 也要啟用。
  2. 安裝 atom-runner。這個可執行 python。如果你是 apple 系統,要在 config 加東西,請參照影片。

步驟:執行

  1. 寫一段程式

    import random
    
    for i in range(5):
        print(random.random())
    
  2. 執行請按(我是用 windows) alt-r

還有 autocomplete 與 debugger

autocomplete 與 refactor

照那個 youtube 設定只有能執行 python。但是沒有加裝 autocomplete-python 這個套件的話,基本上它所提示的只是你已經輸入過的關鍵字,當然不夠用。「跳到定義去 go-to-definition 」這個 IDLE 沒有的夢幻功能就可以用 ctrl-alt-g 來使用。因為一次按三個按鍵太糟,請安裝 hyperclick 套件,這樣就可以按住 ctrl 用滑鼠去點你想找定義的關鍵字。

https://atom.io/packages/autocomplete-python

為了寫程式 refactor 方便,Python Tools 加進來是最好的。

https://atom.io/packages/python-tools

debugger

debugger 目前有兩個套件,我選擇 https://atom.io/packages/python-debugger 。我不選 https://atom.io/packages/atom-python-debugger 的原因是不想多改 code 插 trace。

python-debugger 它使用的 alt-r 與 atom-runner 重覆,所以必須要使用選單 Packages > python-debugger > Toggle 來開啟執行視窗。這是要注意的地方。如果直接按 alt-r 會直接執行 python code。

[atom]編輯器體驗

起因

之前網路上看到有人把 sublime 跟 atom 比,才知道 github 出了一個 atom editor。但還沒有想要用看看。但是後來遇到朋友已開始用了,所以也來試試看,主要想要看看它能否當做 python IDE 與 markdown 編輯器。

背景

因為我會常常在 windows, linux, mac 環境跑來跑去。所以會需要一個通用的編輯器。我現在是在 windows 裡裝 notepad++,在 linux 用 pico/vi/gedit,在 mac 則是用 python IDLE 來暫用。目前來說,我在 mac 開文章的機會非常少,多是開來寫 python 所以就是用 python IDLE 就好了。原本有考慮 sublime,但是要讓我碰到的電腦都要裝 sublime 的話又好像太過份。而且 sublime 在討論上、套件上又好像比較少,也許是因為它屬於專有軟體的關係。所以,先試試 atom。他的用戶多,套件也會比較多一點。將來若是有自己開發套件,要連同主體一起散佈的話,也比較不會被說話。當然,應該也可以開發 sublime 套件,要賣給別人的時候請客戶再多付 sublime 的錢。這個方面我要再多些時間考慮。

擴充性

以擴充性來說,我當然還是喜歡 sublime 的 python api。atom 是用 node.js,對我來說還是不如 python 習慣。尤其 javascript 的非同步特性是不是合適套件開發,這不試過真不知道。

markdown 支援

最近喜歡使用 markdown 來寫文章,atom 上有官方內建的 markdown preview,也有社群加強版的 markdown preview plus。而 sublime 就要找看看。這也就是我會選擇多數人用的原因,這樣比較容易 google 到套件及使用方法。少人用的就會難找及難學。從 markdown 的角度來看,現在是有免費線上的 StackEdit 可用,但是若要固定下來,的確還是選執行檔編輯器會比較好。

ps. 其實 sublime 的 markdown preview 用 google 一下就出來了。https://www.youtube.com/watch?v=XnPkdcBGBlw 。但是它的 preview 不是即時,也不是在 sublime 裡,而是讓你指定轉成 html ,再用瀏覽器開啟。(也可以換成其他格式再用其他程式開啟。)這樣就不如 atom 的好了。

小發現

現在使用上有幾個感覺:
* 啟動比 notepad++ 慢很多,跟 jedit 有得拼了(比慢)。
* 一開始中文字型怪怪的。也許用到大陸字體,「置」這個字裡面是一豎而不是兩個橫。
於是按照以下連結,改成 Noto Sans CJK TC。
http://lsymind.blogspot.tw/2015/06/atom_22.html

官方說明文件

https://atom.io/docs

2016年9月11日 星期日

[js]打造自己的開發環境閱讀心得

前言

因為有點不知道除了 visual studio 之外的開發環境會長怎樣,所以研究了一下以下的文章,稍微了解一下現在的世界長怎樣了。 http://larry850806.github.io/2016/09/04/es7-environment/

我這篇算是心得報告,只有把我不會的地方加一些描述。要了解全部還請記得去原來的地方看。記得一定要感謝原作者 Larry Lu http://larry850806.github.io/about/
https://github.com/Larry850806/nodejs-ES7-template

了解生字

  • babel
    它看來是一個編譯器,把你寫的 javascript 轉成另一種寫法的 javascript。這大概就是目前 javascript 最有趣的地方吧…。 https://babeljs.io/
    類似的有:TypeScript, CoffeeScript

  • gulp
    這個看起來像是 gcc make 的系統,依照你寫的設定標,自動把編譯、複製、散佈等工作做完的系統。是 node.js 的套件之一。
    http://gulpjs.com/ http://abgne.tw/web/gulp/gulp-tuts-install-gulp-js.html

目錄安排

文章中的建議是因為有用了 gulp 做自動處理,所以會把檔案很乖地很分散在各個不同的目錄裡。

package.json
node_modules
gulpfile.js
index.js
src
    index.js
    utils.js
build
    index.js
    utils.js

package.json 與 node_modules 是 node.js 需要的。
gulpfile.js 是 gulp 的設定
最外面的 index.js 是程式執行的起點。但它只是轉一手讓 build/index.js 來執行。為了不要讓人太傷腦筋。
src 裡,原文是放 ES7 的程式,build 是被轉成 ES5 的程式。

註:ES7 與 ES5 是指 ECMA Script 7 與 ECMA Script 5。是 Javasript 目前的正式學名。兩個在語法上有不同,所以必須要分兩個名字來講。目前可以靠程式把新語法轉成舊語法,以利舊瀏覽器/舊環境執行,減少大家開發上轉換的痛苦。這一點也是獨特之處。

開發流程

開發時只動 src 裡的東西,其他的動作靠 gulp 來幫忙。
真正執行的起點是 ./index.js,而它會去執行 build/index.js。

gulp 設定

因為是靠 gulp 來處理轉譯與搬檔案,所以要了解一下它的用法。https://github.com/nimojs/gulp-book

文章內使用的設定是:

// gulpfile.js

var gulp = require('gulp');
var babel = require('gulp-babel');

gulp.task('babelify', function(){
    return gulp.src('src/**/*.js')
        .pipe(babel({
            presets: ['es2015', 'es2016', 'es2017'],
            plugins: [
                [
                    "transform-runtime", {
                        "polyfill": false, 
                        "regenerator": true
                    }
                ]
            ]
        }))
        .pipe(gulp.dest(build))
});

使用方法是在命令列輸入 gulp babelify,gulp 就會把 src 裡所有的 js 用 babel 轉成 ES5 的程式碼,丟到 build 裡去。所需要的模組是:

{
    "babel-plugin-transform-runtime": "^6.12.0",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-es2016": "^6.11.3",
    "babel-preset-es2017": "^6.14.0",
    "gulp-babel": "^6.1.2"
}

babel 轉譯錯誤的輸出

若是在 babel 轉譯的時候有錯誤,要把錯誤寫出來,需要在 .pipe(babel({…}) 後面加上 on error 的處理函式

.on('error', function(err){
    console.log(err.stack);
    this.emit('end');
})

debug 用的 source map

在轉譯之後,有 exception 發生時,會 dump 出來的是已轉譯的程式碼(也就是 build/index.js),但是那個我們人類很難看,所以可借用所謂的 source map 來讓錯誤對應到 src/index.js 我們比較好修正。(本來設計也只能在 src 那裡動程式碼。)所以在 on(‘error’, … )的後面加上:

.pipe(sourcemaps.write({
            includeContent: false,
            sourceRoot: 'src'
}))  

要讓 node 知道要採用 source map 來對應錯誤行號與內容,要在執行的 index.js 加上:

require('source-map-support').install();

要做到如此,source map 需要兩個模組:

{
    "gulp-sourcemaps": "^1.6.0",
    "source-map-support": "^0.4.2"
}

程式碼變動自動轉譯

這個功能原作者是用 gulp 來監視檔案有無變動,有的話就自動轉譯。要在 gulpfile.js 加上一段:

gulp.task('watch', function(){
    return gulp.watch(['src/**/*.js'], ['babelify']);
});

gulp.task('default', ['babelify', 'watch']);

最後

還可以多看一篇 http://larry850806.github.io/2016/07/25/react-optimization/ 這裡大概就可以知道為什麼 python 會有 mutable、immutable 的東西跑出來。

2016年9月6日 星期二

[python]改用 requests

源起

最近發現一些程式都不正常結束。查看了一下,有幾個是 http 已經不提供了,被導去 https,所以讓 urllib 的呼叫失敗。目前來看,可以用 requests 來解決這問題。

過程

在安裝 requests 之後,的確程式碼少了一些。只是有個警告一直出現:

InsecurePlatformWarning: A true SSLContext object is not available.

雖然還是正常執行,只是 console 視窗一直被洗很討厭。有人說換到 python 2.7.9 就可以或是 pip install requests[security] ,我換到 2.7.12 也 pip install requests[security] 但只是換了一個訊息,但是還是洗畫面。

InsecureRequestWarning: Unverified HTTPS request is being made.

結局

首先參考 https://urllib3.readthedocs.io/en/latest/security.html

正規解法應該參考 https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl 來解決問題。

但是我使用裡面偷懶的做法,在程式一開始加入

import requests.packages.urllib3

requests.packages.urllib3.disable_warnings()

2016年8月8日 星期一

[mqtt]在 XP 上安裝 mosquitto

[mqtt]在 XP 上安裝 mosquitto

在 XP 上安裝 mosquitto,與在 windows 7 以上不一樣。

在 XP 上,需要使用標有 cygwin 的安裝檔。如果直接使用標注 win32 的安裝檔來裝,在執行時會出現 mosquitto.exe 不是正確的 win32 應用程式的錯誤。
下載 mosquitto-1.4.9-install-cygwin.exe 之後,安裝。一樣的,需要依說明下載 Win32OpenSSL_Light-1_0_2h.exe 與 pthreads-w32-2-9-1-release.zip 然後把需要的 dll 放到 mosquitto.exe 旁邊。
再來則必須要安裝 cygwin,到 cygwin 官網下載 setup-x86.exe,然後執行。只需要安裝基本 (base) 就好了,我們只要是複製幾個檔案。安裝好之後,就點 mosquitto.exe,它會告知少什麼 dll,然後就去 cygwin 安裝的地方 copy 過來。我記得是以下幾個:
* cygcrypto-1.0.0.dll
* cyggcc_s-1.dll
* cygssl-1.0.0.dll
* cygwin1.dll
* cygz.dll
這樣,mosquitto.exe 就正常可用。如果希望它變成一個服務,那最簡單是再執行一次安裝檔,選擇服務選項。如此就會在開機的時候自動啟動。
但是,這個安裝檔裡的 mosquitto_pub.exe 與 mosquitto_sub.exe 仍出現不是正確的 win32 應用程式的錯誤。我想也許是打包錯了,報了 issue 結果負責人說他沒有 XP,所以要我們自己 compile 試試。其實在他回覆之前,我就下載舊的安裝檔來試,裝在另一個目錄,中間有很多不同的錯誤,像是找不到 entry point 的、getTickCount64 不在 KERNEL32.DLL 的。最後終於在 mosquitto-1.2-install-cygwin.exe 找到一個說缺 msvcr100.dll 的。
msvcr100.dll 我找到有兩個,一個在 C:\windows\system32,一個則在 anaconda\Library\bin 裡面。結果是後面這個放到 mosquitto_sub/pub 旁邊才成功。但是 mosquitto-1.2-install-cygwin.exe 裡面的 mosquitto.exe 會出現 無法找到程序輸入點 inet_ntop (在動態連結函式庫 WS2_32.dll) 的錯誤。所以就安裝兩版來解決問題吧 XD
目前只有用到最簡單的連結,其他功能沒有用到(例如 ssl、帳號密碼),所以不知道是不是全功能完整無蟲。可以確定的是 服務正常、pub/sub 正常。私用應該沒問題。

[超譯]Node.js 加 MQTT 入門

https://blog.risingstack.com/getting-started-with-nodejs-and-mqtt/

Node.js 加 MQTT 入門

這篇貼文由 Charlie Key 提供,他是 Structure 的 CEO 與 Co-Founder。Structure 是一個 IoT 的平台,讓你能輕鬆建立相連的經驗與解決方案。Charlie 已經用 Node.js 於工作幾年,現在用它來為 IoT 的世界充能。
Javascript 的世界持續地開發新彊界,像 Node.js 的技術可讓伺服端快速擴展,而現在達到 IoT 的世界。Node.js 現在可在許多嵌入式裝置內,像是 Intel Edison。與嵌入式裝置的溝通一向都可行的,但使用 Node.js 與 MQTT 這類協定讓溝通前所未有的簡單。
在這貼文,我們會看一下如何利用兩個技術(Node.js 與 MQTT)來傳送訊息,建立一個簡易的車庫開門應用程式。這只是此類通訊的其中的一個可能的應用。
MQTT 本身是個非常簡單的 publish / subscribe (出版/訂閱)協定。它讓你在一個主題上送訊息(你可以想像那些是頻道),經由一個中央管理的 message broker。整個協定故意非常輕量。這會讓它能輕易地在嵌入式裝置上執行。幾乎所有的微處理器都有函式庫可用讓它能收送 MQTT 的訊息。以下可以看到 MQTT 溝通的基本概念。
這裡一張架構圖
現在,想像一下我們要打造一個遠端控制的車庫開門系統,使用 MQTT。第一件事我們需要計畫車庫門與遠端遙控器要傳送什麼訊息。為了要讓這範例簡單,我們只打算能夠開門與關門就好。真實的架構圖會長成這樣:
又一張架構圖
門會有幾個狀態,已開、已關、開門中、關門中。真的門也許會有其他狀態,如 暫停。但我們今天暫不考慮。
我們的應用程式會分開兩個檔案,一個是給車庫用另一個給控制器用。我會在每個程式的上頭標名檔名。首先,我們會需要用 npm 安裝 mqtt 函式庫,然後設定我們要用的 broker。現在有很多開放的 broker 可用於測試,我會使用 broker.hivemq.com。再次強調,這只是測試用,不要在正式產品還用這個。以下是兩個檔案一開始都要的程式碼:
// contoller.js and garage.js
const mqtt = require('mqtt')  
const client = mqtt.connect('mqtt://broker.hivemq.com') 
接下來,我們要加一些程式碼來連上 broker。一定連上,我們會建立一個主題(頻道),這在車庫門連上時的溝通用的。在門這邊,是 publish(出版)訊息到這個主題,而控制器這邊則是subscribe(訂閱)。同樣,在這個時間點,我們會加一個區域變數,追蹤車庫門現在的狀態。你會發現我們的主題加了前綴 “garage/”,這是為了組織目的的簡化,你也可以隨自己喜歡來命名。
// garage.js
const mqtt = require('mqtt')  
const client = mqtt.connect('mqtt://broker.hivemq.com')

/**
* The state of the garage, defaults to closed
* Possible states : closed, opening, open, closing
*/

var state = 'closed'

client.on('connect', () => {  
  // Inform controllers that garage is connected
  client.publish('garage/connected', 'true')
})
在控制器端,我們不只是要訂閱這主題,我們也需要加上訊息接聽者,對訊息出版時採取動作。一但訊息收到,我們會使用一個變數,檢查變數的值且追蹤是否門還連在系統上。
// controller.js
const mqtt = require('mqtt')  
const client = mqtt.connect('mqtt://broker.hivemq.com')

var garageState = ''  
var connected = false

client.on('connect', () => {  
  client.subscribe('garage/connected')
})

client.on('message', (topic, message) => {  
  if(topic === 'garage/connected') {
    connected = (message.toString() === 'true');
  }
})
目前為止,門與控制器只知道,門是否連在系統上,我們還不能採取什麼動作。為了要讓控憲器知道門發生什麼事,我們再加上一個函式,送出現在門的狀態,函式長這樣:
// added to end of garage.js
function sendStateUpdate () {  
  console.log('sending state %s', state)
  client.publish('garage/state', state)
}
要使用這個函式,我們會加在車庫連上的呼叫裡:
// updated garage.js connect
client.on('connect', () => {  
  // Inform controllers that garage is connected
  client.publish('garage/connected', 'true')
  sendStateUpdate()
})
現在車庫門可以更新,告訴每個人它現在的狀態。現在控制器需要更新自己的門狀態的變數。然而在這個時間點,先更新訊息處理函式,對應不同的主題呼叫不同的函式。這會增加一點程式的結構性。整個更新完如下:
// updated controller.js
const mqtt = require('mqtt')  
const client = mqtt.connect('mqtt://broker.hivemq.com')

var garageState = ''  
var connected = false

client.on('connect', () => {  
  client.subscribe('garage/connected')
  client.subscribe('garage/state')
})

client.on('message', (topic, message) => {  
  switch (topic) {
    case 'garage/connected':
      return handleGarageConnected(message)
    case 'garage/state':
      return handleGarageState(message)
  }
  console.log('No handler for topic %s', topic)
})

function handleGarageConnected (message) {  
  console.log('garage connected status %s', message)
  connected = (message.toString() === 'true')
}

function handleGarageState (message) {  
  garageState = message
  console.log('garage state update to %s', message)
}
在這裡,我們的控制器可以跟上車庫門的狀態與連線狀態。現在可以加一些功能來控制我們的門。第一件事是讓車庫開始接聽一些訊息,告訴它開或關。
// updated garage.js connect call
client.on('connect', () => {  
  client.subscribe('garage/open')
  client.subscribe('garage/close')

  // Inform controllers that garage is connected
  client.publish('garage/connected', 'true')
  sendStateUpdate()
})
我們現在需要在車庫門這裡加個訊息接聽者:
// added to garage.js
client.on('message', (topic, message) => {  
  console.log('received message %s %s', topic, message)
})
在控制器這裡,我們也會加上傳送開門或關門訊息的能力。這有兩個簡單的函式。在一個真實的應用程式中,這會由外部輸入來呼叫(像是 web 應用程式,手機 app…等)。在這個範例中,我們會用個計時器來呼叫,只是測試這個系統而已。新增的程式碼如下:
// added to controller.js
function openGarageDoor () {  
  // can only open door if we're connected to mqtt and door isn't already open
  if (connected && garageState !== 'open') {
    // Ask the door to open
    client.publish('garage/open', 'true')
  }
}

function closeGarageDoor () {  
  // can only close door if we're connected to mqtt and door isn't already closed
  if (connected && garageState !== 'closed') {
    // Ask the door to close
    client.publish('garage/close', 'true')
  }
}

//--- For Demo Purposes Only ----//

// simulate opening garage door
setTimeout(() => {  
  console.log('open door')
  openGarageDoor()
}, 5000)

// simulate closing garage door
setTimeout(() => {  
  console.log('close door')
  closeGarageDoor()
}, 20000)
以上的程式碼包含開與關的功能。它們確認車庫已經連上系統而且不在已要求的狀態中。我們的控制器最後版本的程式碼如下:
// controller.js
const mqtt = require('mqtt')  
const client = mqtt.connect('mqtt://broker.hivemq.com')

var garageState = ''  
var connected = false

client.on('connect', () => {  
  client.subscribe('garage/connected')
  client.subscribe('garage/state')
})

client.on('message', (topic, message) => {  
  switch (topic) {
    case 'garage/connected':
      return handleGarageConnected(message)
    case 'garage/state':
      return handleGarageState(message)
  }
  console.log('No handler for topic %s', topic)
})

function handleGarageConnected (message) {  
  console.log('garage connected status %s', message)
  connected = (message.toString() === 'true')
}

function handleGarageState (message) {  
  garageState = message
  console.log('garage state update to %s', message)
}

function openGarageDoor () {  
  // can only open door if we're connected to mqtt and door isn't already open
  if (connected && garageState !== 'open') {
    // Ask the door to open
    client.publish('garage/open', 'true')
  }
}

function closeGarageDoor () {  
  // can only close door if we're connected to mqtt and door isn't already closed
  if (connected && garageState !== 'closed') {
    // Ask the door to close
    client.publish('garage/close', 'true')
  }
}

// --- For Demo Purposes Only ----//

// simulate opening garage door
setTimeout(() => {  
  console.log('open door')
  openGarageDoor()
}, 5000)

// simulate closing garage door
setTimeout(() => {  
  console.log('close door')
  closeGarageDoor()
}, 20000)
現在,車庫門必須對應這些訊息做反應。再一次,我們使用 switch 引導不同的主題。一但訊息被收到,門會試著處理它且確認它能到那狀態才動作。然後它會進入轉移狀態(開門中、關門中),送出更新訊息,最後到達持續狀態(已開、已關)。為了測試的目的,最後一個部份是用計時器來完成。在真實情況中,系統應該等待硬體訊號通知它已完成。
// updated garage.js message handler
client.on('message', (topic, message) => {  
  console.log('received message %s %s', topic, message)
  switch (topic) {
    case 'garage/open':
      return handleOpenRequest(message)
    case 'garage/close':
      return handleCloseRequest(message)
  }
})
開門與關門的處理函式可以加到檔案的最後。
// added to garage.js
function handleOpenRequest (message) {  
  if (state !== 'open' && state !== 'opening') {
    console.log('opening garage door')
    state = 'opening'
    sendStateUpdate()

    // simulate door open after 5 seconds (would be listening to hardware)
    setTimeout(() => {
      state = 'open'
      sendStateUpdate()
    }, 5000)
  }
}

function handleCloseRequest (message) {  
  if (state !== 'closed' && state !== 'closing') {
    state = 'closing'
    sendStateUpdate()

    // simulate door closed after 5 seconds (would be listening to hardware)
    setTimeout(() => {
      state = 'closed'
      sendStateUpdate()
    }, 5000)
  }
}
有了這些函式,我們現在有個完整功能的車庫系統。為了測試你可以開啟控制器程式然後再開車庫門程式。控制器會在開啟後 5 秒送開門指令,20 秒送關門指令。
最後我要建議的事是讓我們的車庫門更新自己的連線狀態,當我們的程式因為任何原因被關掉的時候。這個離開的乾淨程式碼是依照 stackoverflow answer 建議,然後改用 mqtt 訊息傳送。這可在放在車庫檔案的最後。所有的東西組合起來就得到最後的車庫檔案。
// garage.js
const mqtt = require('mqtt')  
const client = mqtt.connect('mqtt://broker.hivemq.com')

/**
 * The state of the garage, defaults to closed
 * Possible states : closed, opening, open, closing
 */
var state = 'closed'

client.on('connect', () => {  
  client.subscribe('garage/open')
  client.subscribe('garage/close')

  // Inform controllers that garage is connected
  client.publish('garage/connected', 'true')
  sendStateUpdate()
})

client.on('message', (topic, message) => {  
  console.log('received message %s %s', topic, message)
  switch (topic) {
    case 'garage/open':
      return handleOpenRequest(message)
    case 'garage/close':
      return handleCloseRequest(message)
  }
})

function sendStateUpdate () {  
  console.log('sending state %s', state)
  client.publish('garage/state', state)
}

function handleOpenRequest (message) {  
  if (state !== 'open' && state !== 'opening') {
    console.log('opening garage door')
    state = 'opening'
    sendStateUpdate()

    // simulate door open after 5 seconds (would be listening to hardware)
    setTimeout(() => {
      state = 'open'
      sendStateUpdate()
    }, 5000)
  }
}

function handleCloseRequest (message) {  
  if (state !== 'closed' && state !== 'closing') {
    state = 'closing'
    sendStateUpdate()

    // simulate door closed after 5 seconds (would be listening to hardware)
    setTimeout(() => {
      state = 'closed'
      sendStateUpdate()
    }, 5000)
  }
}

/**
 * Want to notify controller that garage is disconnected before shutting down
 */
function handleAppExit (options, err) {  
  if (err) {
    console.log(err.stack)
  }

  if (options.cleanup) {
    client.publish('garage/connected', 'false')
  }

  if (options.exit) {
    process.exit()
  }
}

/**
 * Handle the different ways an application can shutdown
 */
process.on('exit', handleAppExit.bind(null, {  
  cleanup: true
}))
process.on('SIGINT', handleAppExit.bind(null, {  
  exit: true
}))
process.on('uncaughtException', handleAppExit.bind(null, {  
  exit: true
}))
這了那些,我們完成了我們的車庫門控制器。我希望你能挑戰下一級。一些修改與一個 Intel Edison 會讓你建立一個完整的遠端車庫開門系統。此範例完整的原始碼也會放在 Github。
這只是一個開始。還有一些 MQTT 的新選項與能力,包含使用 SSL、使用者/密碼 認證來增加安全性。
如果你喜歡這篇貼文且想知道 Node.js 能到什麼程度,這有個超讚會議會來到:Node Community Convention。將會有許多偉大的演講,主題包含 IoT、系統放大……等等。

作者
Gabor Nagy
在 Marketing 是個全端。在 web 開發正在從零到英雄的路上。

2016年7月28日 星期四

[超譯] 核心版控演義

linux 核心的版本控制管理系統,曾經有經歷過一段動盪,linus 自己曾經在郵件列表裡回過一段文章,提出自己的看法。郵件標題是 「Kernel SCM saga..」
原文連結:
http://lkml.iu.edu/hypermail/linux/kernel/0504.0/1540.html

好,有很多人已經發現(有些人已經知道好幾個星期),我們正努力解決這一兩個月與 BK [譯註:BitKeeper] 之間的衝突。但,我們沒有成功,所以,核心組正在尋找替代方案。
(顯然這訊息會到 slashdot,所以應該 每個人都知道 )
我選了 BK 就讓能衝突消失的期待,似乎沒有成功 ( “你沒看見這幾G又幾G 的火熖嗎?”)。所以,在某種意義上是無法避免的。但我確信我曾希望能有合理的開源替代能選擇,為此,我們將必須忙和一陣子。
題外話,別怪 BitMover,就算這是一個常見的反應。Larry 真的是想把事情做好,但事情到了我不想要的地步,想要把兩塊湊在一起需要的膠水越多越好。
我們已經使用 BK 三年了,事實上,現在最大的問題是有許多人用過最好的工具之後,變得非常挑剔。包含我自己,我們都因為 BitKeeper 的幫助,在 merging 我的 tree,或把他們的 tree 傳給我的時候變得比較輕鬆。
當然,也許更大多數的人只是把 BK 當成更好(也更快)的「匿名 CVS」的客端。眼前的問題是我花了許多時間試圖找到最好的協作方案。
注意,BitKeeper 不是消失了。只是現在最真切的事情是,我決定不再使用 BK,主要因為我需要找到替代,而不是「讓東西持續正常」。我決定硬著頭皮,看看沒有 BK 的生活會是怎樣。到目前為止,是個黑白的世界。
不要過度解釋,我會用個星期閉關,(想做是 linus 只是去放假的正常事件),我也正在找人負責維護 BK tree,至少是能夠傳給我(單獨)補丁,我會自己 想辦法 merge。
所謂「單獨補丁 individual patches」是個關鍵字。題外話,BK 一個做得很好的事,許多人就算沒用 BK 也喜歡的,就是它對於改變的視圖很棒。這個不會消失。
事實上,BK 讓我們做事的方法有了根本的改變。像是 changeset 的視圖、讓我能相信子維護者能做更大的事、不用按順序上補丁…等。所以三年的 BK 使用不是浪費。我相信這會讓我們用更好的方式做事。我會尋找讓這些事情繼續的方法。
所以,我只是要說,我個人與 BK 相處愉快,與 Larry 也是。合作沒有成功讓核心開發有了巨大的困難。一個暫時性的問題,要產出在 BK 允許的範圍內使用的工具,這一點我們會繼續努力。
讓火開始燒吧。
Linus
PS. 不要再跟我說 subversion。如果你一定要,去研究 “monotone”,那看來是最可行的。但不要再煩開發者讓他們無法把事情做完。他們已經要煩惱我的問題了。

[閒聊]超簡單回答 - 什麼是 github?

github 是一個程式碼代管網站,它讓你可以放程式碼供大家下載。由於它使用 git 版本控制程式,所以名字 github 裡面有個 git。

git 是由 linus 開發出來的(第一版)。是為了因應分散式開發的特性而另外開發的。在他開發的時候,同時間也有其他的分散式開的版本控制系統已經出現,BitKeeper,或是 Mercurial。Mercurial 開發時間只有晚 git 一些些而已。但是 linus 覺得都不合他的意,所以就自幹一套,然後把 linux kernel 的版本控制系統換成了 git。

另外一提,Mercurial,俗稱 hg,這一套版本控制系統是用 python 寫的,Mozilla 與 python 都將程式碼轉移到 hg 的系統之中。

我想,如果有人問我要選哪一個?因為現在使用 git 的人多,也許學用 git 會比較好。至於我自己個人,已經用了 hg,現在還不想隨便換。

參考:
https://zh.wikipedia.org/wiki/Git
https://git-scm.com/book/zh-tw/v1/%E9%96%8B%E5%A7%8B-%E9%97%9C%E6%96%BC%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6
http://lkml.iu.edu/hypermail/linux/kernel/0504.0/1540.html

2016年7月27日 星期三

[閒聊] arduino 也算是個語言?

IEEE 2016 程式排行榜 裡把 arduino 算是一個語言,引起一些討論。
我個人是可以理解為什麼會列為另一種語言。
也許它被認為”足夠”降低開發門檻成功給一般人使用,而且其生態系也大到一個程度。它的前處理,著實也做了很多事,從使用者的角度,根本看不到 C/C++ 要的 ..h, .c or .cpp。在簡化的程度上,已經讓只會寫 arduino 的人,一定不會用 C/C++ 的環境寫程式。
IEEE 官網也很多人質疑,說 arduino 不過是個開發環境,應該要算在 C 上面。但是就如同 C 與 C++ 一樣會有論戰,為什麼 C 要跟 C++ 算一起?或反過來說,C 與 C++ 要算一種語言嗎?如果算一種語言,為什麼要寫 C/C++ 而不乾脆說 C? 如果算兩種語言,但是算人頭的時候又要一起算呢?
曾經在閱讀 cython 的時候,看到他們寫的 「The Cython language is a superset of the Python language that additionally supports calling C functions and declaring C types on variables and class attributes.」他們做的事情,就是讓使用者可以用一般的 python 寫程式,也可以用 cython 新增加的語法指定與 c 合作的宣告與功能。他們也是先經過自己的「前處理器」,把程式轉換過。他們自稱是 cython language。而且還是 superset 。我曾經想了很久。後來又看到 TypeScript,CoffeeScript。如果這些努力可以說是新增了一個新語言,那麼,arduino 被稱做一個語言,我是可以理解的。
我自己的臉書備份

2016年6月15日 星期三

[windows] usb碟在 windows 與 mac 之間插來插去然後就不能用了。

為了交換資料,用 mac 把一個 usb碟做成 FAT32,剛開始還正常,幾次之後發現,中文字都亂碼了。再用個幾次連容量都不對。回到 windows 看裡面有兩個分割區,比較大的那個 windows 就看不見,想用 windows 來清掉分割區又點不到那個指令,卡住了怎辦?這時候 diskpart 是救星。

有很大的資料要交換,例如影片,用網路來傳還是比較慢,家裡的 wifi 就是沒辦法每秒 25 或 50 MB 來傳。所以一個 FAT32 的 usb碟一直是我的方式。但是這次就遇到檔名亂碼的問題,隨後發生分割區看不到的問題。從 windows 這邊來看,用 mac 來割 FAT32 會弄出兩個主分割區,讓 windows 搞不懂。要救回這個 usb碟的方法,應該是用 windows 自己來切分割區了。打開磁碟管理,對著分割區按下右鍵,清除分割區的選項居然是灰色不能選,這下無解了。至少這條路不能走。難道 windows 真的無招了嗎?
還好,這問題不是只有我發生,外國人也發生,解決方法就是 diskpart.exe 這個內建程式。
我只需要做到清除分割,建立分割區還是用原來的圖形格式化工具。
步驟:
(1) 進到命令列
(2) 輸入 diskpart 之後按 <enter>
(3) 輸入 list disk,看清楚第幾個是你的 usb碟,沒看清楚會非常悲劇,一定要算對。然後用 select disk n 選到你的 usb碟,n 是列表上第幾個磁碟。選完之後,再用 detail disk 確認一下。
(4) 接下來輸入 clean 指令,清除整個分割區。
(5) 離開程式,輸入 exit。
接下來的建立分割區,就照一般的格式化做法就行了。

參考:
http://superuser.com/questions/274687/how-do-i-format-a-usb-drive-on-a-pc-that-was-formatted-on-a-mac

[python] try except raise,為什麼會需要 raise ?

在 python 裡,對於有可能錯誤的地方,就是用 try 去包住它,然後針對可能的錯誤去處理它。像是:

try:
    f = open('x','r')
except IOError:
    raise
except Exception:
    print 'other error'
    raise

有天某個人問我,為什麼,既然已經是抓到問題了,為什麼還要 raise,把它丟出去呢?也許有很多理由,但我有兩個簡單的理由:(1)我想直接讓程式被停掉,(2)我想讓執行我寫的程式的程式也知道有問題,讓它自己決定該怎麼辦。這在寫程式給別的程式用的時候很重要。

在 raise exception 的時候,我以前是寫成以下這樣:
try:
    f = open('x','r')
except Exception, ex:
    print 'other error'
    raise ex

這樣在文句上好像很正常,但是就會出現困擾的地方,就是 traceback 所指的 exception 行號是在 raise 的地上,而不是真正發生的地方。

IOError                                   Traceback (most recent call last)
 in ()
      3 except Exception, ex:
      4     print 'other error'
----> 5     raise ex

IOError: [Errno 2] No such file or directory: 'x'
後來才發現,應該直接 raise 後面不加參數,才會如下指到對的行數去。

IOError                                   Traceback (most recent call last)
 in ()
      1 try:
----> 2     f = open('x','r')
      3 except IOError:
      4     raise
      5 except Exception:

IOError: [Errno 2] No such file or directory: 'x'

2016年4月2日 星期六

[windows] 要找個執行檔在哪裡,像 linux 的 whereis 的指令?

我不知道為何可以用 curl。用著用著就習慣了。
但是突然發現不能用 request。
想要去更新又不知道到哪兒去更新。

在 linux  有 whereis 指令,但是 windows 就是不叫 whereis。
它就要叫

    where

就這樣,解決。

http://superuser.com/questions/21067/windows-equivalent-of-whereis

2016年3月16日 星期三

[windows] 殺掉佔住某個 port 的程序

今天在測試的時候,一個程式畫面死掉被關掉,但是程序(process)沒有被關掉,一直佔著。
總不能每次發生這種事的時候就重開電腦吧?
於是找了一下,有解!
救星就是 netstat。

使用以下指令:
netstat -a -n -o
會列出所有本機正在開啟的 port,還有 PID。
接下來就是用 task manager,找到那個程序,殺掉它。搞定!

參考:
http://stackoverflow.com/questions/8688949/how-to-close-tcp-and-udp-ports-via-windows-command-line

2016年3月15日 星期二

[python] django-cms 在 pythonanywhere 的安裝

django-cms 是基於 django 的 CMS (Content Management System,內容管理系統),可以快速建立可上線的網站、部落格…等等。它也是去年(2015 年)被選為最佳 CMS 的系統。(http://www.cmscritic.com/announcing-the-2015-winner-for-best-open-source-cms/)

PythonAnyWhere 則是一個服務商,可以提供以 python 為基礎的許多 web framework,例如 django。所以,在 PythonAnyWhere 上要提供一個 Django 網站是內建功能之一。其他的像 flask 或是 bottle 等 web framework 現在也支援。一般人可以申請免費服務試用,可以有 512 MB 的硬碟空間與 100 秒 cpu 時間。如果 100 秒 cpu 時間用完,其實還是可以正常運作,只是慢一點而已,拿來試用非常剛好。

把 django-cms 與 PythonAnyWhere 結合在一起是很簡單的。PythonAnyWhere 官方似乎沒有比較正式的說明,不過在經過測試之後,在 virtualenv 的環境上來做,應該會是比較好的選擇。

第一步,建立 virtualenv 環境
source virtualenvwrapper.sh
mkvirtualenv djangocms --python=python3 
在 PythonAnyWhere 上必須使用已經提供好 環境設定,所以要使用他們提供的 virtualenvwrapper.sh 與 mkvirtualenv 進入 virtualenv 的環境中。
如果要在 virtualenv 裡用到 python3,所以加上 --python=python3

如果要使用官方已經裝好的 numpy, scipy 的話,要加上這個參數 --system-site-packages。

執行完之後,就會停在 virtualenv 的環境裡:
(djangocms) 12:24 ~ $

第二步,安裝 djangocms-installer
現在 django-cms 是使用 djangocms-installer 來安裝,所以要先用 pip 安裝這個。
pip install djangocms-installer
第三步, 建立 djangocms 專案
這裡建議照我說的做,不然不小心會把自己的家目錄裡的東西砍光光。
首先,開一個目錄叫 project_name,然後進去。

(djangocms) 12:32 ~ $ mkdir project_name(djangocms) 12:33 ~ $ cd project_name/(djangocms) 12:34 ~/project_name $

然後使用以下指令建立專案:
(djangocms) 12:34 ~/project_name $ djangocms -p . my_demo

會開始問一些問題,基本上就一路按 enter,不然就照我的來選:
Database configuration (in URL format) [default sqlite://localhost/project.db]:
django CMS version (choices: 2.4, 3.0, 3.1, 3.2, stable, develop) [default stable]:
Django version (choices: 1.5, 1.6, 1.7, 1.8, 1.9, stable) [default stable]:
Activate Django I18N / L10N setting (choices: yes, no) [default yes]:
Install and configure reversion support (choices: yes, no) [default yes]:
Languages to enable. Option can be provided multiple times, or as a comma separated list. Only language codes supported by Django can be used here: en
Optional default time zone [default Etc/UTC]:
Activate Django timezone support (choices: yes, no) [default yes]:
Activate CMS permission management (choices: yes, no) [default yes]:
Use Twitter Bootstrap Theme (choices: yes, no) [default no]:
Use custom template set [default no]:
Load a starting page with examples after installation (english language only). Choose "no" if you use a custom template set. (choices: yes, no) [default no]: yes



然後就開始安裝到停下來。會要你輸入管理員的帳號、信箱、密碼。
Creating admin userUsername (leave blank to use 'ironman'): Email address: 在這裡輸入信箱Password: Password (again): Superuser created successfully.All done!


第四步,建立 web app
到 web 頁籤按下建立 web app 的按鈕,選擇 manual configuration。
設定 virtualenv 路徑設定到 /home/yourusername/.virtualenvs/djangocms。

import os
import sys
# add project folder to path
path = '/home/ironman/project_name'
if path not in sys.path:
    sys.path.append(path)
# Remove any references to your home folder (this can break Mezzanine)
while "." in sys.path:
    sys.path.remove(".")
while "" in sys.path:
    sys.path.remove("")
# specify django settings
os.environ['DJANGO_SETTINGS_MODULE'] = 'my_demo.settings'

# load default django wsgi app for Django >= 1.4
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
到 Static files 那裡設定:
Url: /static/
Path: /home/yourusername/project_name/static
第五步,修改 db 位置設定
因為用安裝器裝的設定,有一點不一樣,所以 db 位置它指錯了。
請到 project_name/my_demo/settings.py 裡,找到這裡:
DATABASES = {
    'default': {
        'CONN_MAX_AGE': 0,
        'ENGINE': 'django.db.backends.sqlite3',
        'HOST': 'localhost',
        'NAME': 'project.db',
        'PASSWORD': '',
        'PORT': '',
        'USER': ''
    }
}

把 'NAME': 'project.db' 改成 'NAME': 'project_name/project.db'

不改會出現錯誤:no such table: cms_urlconfrevision

再按下web app 的 Reload 按鈕。
瀏覽結果,這是有選範例首頁的樣子:

這是沒選範例首頁的樣子:


接下來就是怎麼使用它的問題了。這裡有「使用者」的說明文件。http://docs.django-cms.org/en/3.2.3/user/index.html

[python] mezzanine 在 pythonanywhere 的安裝

Mezzanine 是基於 django 的 CMS (Content Management System,內容管理系統),可以快速建立可上線的網站、部落格…等等。

PythonAnyWhere 則是一個服務商,可以提供以 python 為基礎的許多 web framework,例如 django。所以,在 PythonAnyWhere 上要提供一個 Django 網站是內建功能之一。其他的像 flask 或是 bottle 等 web framework 現在也支援。一般人可以申請免費服務試用,可以有 512 MB 的硬碟空間與 100 秒 cpu 時間。如果 100 秒 cpu 時間用完,其實還是可以正常運作,只是慢一點而已,拿來試用非常剛好。

把 Mezzanie 與 PythonAnyWhere 結合在一起是很簡單的。PythonAnyWhere 官方建議在 virtualenv 的環境上來做,也給了範例如下:

第一步,建立 virtualenv 環境

source virtualenvwrapper.sh
mkvirtualenv mezzanine
在 PythonAnyWhere 上必須使用已經提供好 環境設定,所以要使用他們提供的 virtualenvwrapper.sh 與 mkvirtualenv 進入 virtualenv 的環境中。
如果要在 virtualenv 裡用到 python3,要使用以下的指令替代上面第二行指令

mkvirtualenv mezzanine --python=python3
如果要使用官方已經裝好的 numpy, scipy 的話,要加上這個參數 --system-site-packages

執行完之後,就會停在 virtualenv 的環境裡:
(mezzanine)13:12 ~ $
第二步,安裝 mezzanine
接下來就是使用 pip install mezzanine 安裝。

第三步,建立網站專案
在經過一連串下載後,就是開始第一個專案來試用一下了。開第一個專案的指令是:
mezzanine-project project_name
cd project_name
接下來的動作是設定時區與建立資料庫內容。
首先在 settings.py 找到TIME_ZONE, 改成我們這裡的TIME_ZONE='Asia/Taipei'
然後執行以下指令:
python manage.py createdb --noinput
會在資料庫裡建立所需要的 table。預設使用的是 sqlite3 的資料庫。眼睛利一點的會看到管理者預設帳號密碼是 admin/default。等一下要用,真的要上線一定要去改密碼

第四步,設定 wsgi
PythonAnyWhere 與 mezzanine 的連結是靠 wsgi,請到 web 頁籤


建立一個按下建立 web app 的按鈕,選擇 manual configuration。
然後把 virtualenv 路徑設定到 /home/yourusername/.virtualenvs/mezzanine 。


找到 WSGI configuration file 所指的檔案連結按下去,改成以下這樣:
import os
import sys

# add project folder to path
path = '/home/yourusername/project_name':
if path not in sys.path:
    sys.path.append(path)

# Remove any references to your home folder (this can break Mezzanine)
while "." in sys.path:
    sys.path.remove(".")
while "" in sys.path:
    sys.path.remove("")

# specify django settings
os.environ['DJANGO_SETTINGS_MODULE'] = 'project_name.settings'

# load default django wsgi app for Django >= 1.4
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
然後按下web app 的 Reload 按鈕,接下來要處理 static 檔案。

第五步,設定 static 檔案
在 web 頁籤,到 Static files 那裡設定:

Url: /static/
Path: /home/yourusername/project_name/static

然後執行以下指令:
python manage.py collectstatic
這樣會把 static 的檔案搬到對的地方去。再按下web app 的 Reload 按鈕。

現在就可以瀏覽一下剛才的成果。

接下來,使用的方法就又是另一個問題了。

2016年2月27日 星期六

[超譯] 機器學習介紹

原文連結http://opensourceforu.efytimes.com/2016/02/an-introduction-to-machine-learning/


機器學習介紹

機器學習是計算機科學的一個領域,它探索「學習」與演算法的建構,從資料中學習,並依此做預測。機器學習涵蓋了模式辨認(pattern recognition)以及人工智慧中的計算式學習理論。它被用在許多應用中,像是自動駕駛車,有效率網頁搜尋,語音辨識…等。

編程(programming)基本上是告訴電腦要做什麼。傳統的編程習會假設寫程式的人已經理解問題,而且用這個理解,寫出一串清楚的指令來解決 某特定問題或完成特定任務。這類的例子非常多,事實上,絕大多數的程式都是這樣寫的,有著清楚可預期的輸入、輸出,與優美的演算法處理。例如,排序數字, 在文檔中移除某個字串,複製檔案…等等。
然而,有某些種類的問題,傳統編程或問題解決定方法不是這麼好使。例好,假設你有 50,000 個文件,必須分類成運動、商業、娛樂,又不能人工一個個處理。又例如,在上千個圖片裡找到特定的物件。在後面這個例子,物件可能是不同角度的相片,或是在 不同光線的條件下。你要如何分辨哪些相片有這個物件?另一個非常有用的例子是建立一個線上付款通道(online payment gateway)且希望防止詐欺交易。其中一個方法是辨認出潛在詐欺交易的跡象,在交易完成前啟動警報。這樣,你要如何準確預測而避免不必要的警報?
你可以簡單地說,這是不可能寫出非常準確的演算法來對付上述每個問題。我們能做的是,建立一個系統像人類專家一樣地工作。一個醫生可以檢驗報告看出病人生了什麼病。醫生的準確率不會是 100%,他多數時間會是正確的。沒人用程式寫出一個醫生,他這些知識來自學習與經驗。
我們需要的是一個系統能從經驗中學習,就算我們無法編程它叫它做特定的任務。我們做的是,給它看大量的範例,電腦是被編程為從大量的資訊中學習。在 它完成學習之後,就可以預測或做一些任務。這就是機器學習。醫生的例子有一點點與真正的機器學習不一樣,機器學習的核心思想是機器學習會有大量資料中學 習,而且會從經驗中改進。


機器學習與數學

許多機器學習演算法基本上企圖逼近一個未知的數學函數,而且絕大多數這些演算法本質上就是數學。因為資料有隨機性與不確定性,我們必須應用來自機率 與統計的概念。事實上,機器學習演算法非常依賴統計的概念,以致許多人認為機器學習該叫統計學習。離開統計,另一個被用到重要的數學分支是線性代數。矩陣 的概念,系統方程組的解,演算法的優化,都在機器學習中佔有重要地位。


機器學習與大數據

近來,機器學習與大數據走得很近。大數據指的是巨量的已存資料,而且是有意義地被使用。看一些例子來了解我說的。假設你已在交易平台上收集顧客交易 資料,這資料的量可以輕易地到達被認為是大數據的量,還有一些其他你存下的資料。現在,這些資料的用途是檢查顧客定單的狀態,計算商務會計上的盈虧,以及 其他技術或操作上的日常業務。除了這些,商業上也常想以獨特的方式利用這些資料。有些人對這分析使用特定的字。雖然直接地計算可以得到盈虧、總支出、總庫 存等答案,但稍進一步的資料操作會切片與切塊讓訊息顯現。我們依然會追求基本報表的背後訊息,辨認出不顯見的模式。我們也會想要建立預測模型。


不同的機器學習演算法

現在有兩種不同種類的演算法,受監督學習與無監督學習。受監督學習指的是,資料給序標籤,如下例所示:
中午12點時溫度 風速 風向 下午是否下雨
1 30度C 3 m/s
2 35度C 10 m/s 西
3 37度C 7 m/s 東北
4 34度C 8 m/s
假設我們必須預測下午是否下雨,使用溫度及風的資料。是否下雨記錄在「下午是否下雨」那一行,那就是標籤。這裡的溫度,風速、風向是預測子(predictor)或說是輸入變數,下午是否下雨則是輸出變數。
演算法從這樣的資料學習,叫做受監督學習演算法。有些資料是自動萃取/自動產生的,例如機器的日誌,多數需要人工加標籤,這樣增加資料獲得的成本。
受監督學習演算法的例子有「線性回歸演算法 linear regression algorithms」、「貝氏演算法 Naïve-Bayesan algorithms」「K近鄰演算法 k-nearest neighbour」…等等。
如果資料沒有標籤,它變成一個無監督學習演算法。例如:「K平均分群 k-means clustering」、「主成份分析 principal component analysis」…等等。
我們也可以用另一個邏輯來分類機器學習演算法,分成回歸演算法或是分類演算法。回歸演算法是指演算法真的預測一個數字,像是接下來幾天的溫度,股市收盤指數…等等。
分類演算法則是把輸入分類,例如是否下雨、股市漲還是跌、它是疾病 x、疾病 y 還是疾病 z……等等。


機器學習的工作

要理解與讚嘆的是,機器學習演算法基本上是數學演算法,我們可以用任何喜歡的電腦語言來實作。例如 C、PHP、Java、Python 甚至是 JavaScript。但我個人喜歡的是統計語言 R。在不同的語言有許多熱門的機器學習模組或函式庫,Weka 是強大的機器學習與資料採礦的軟體,它用 Java 寫的,而且很熱門。Scikit-learn 在 python 開發者中很熱門。Orange Machine Learning Toolbox 也是 pyhon 可用的工具。R 語言有許多非常基本的統計套件與模組,也有很多不同的套件像 e1071、Randomforest、Ann、…等依賴在不同的機器學習演算法上。Apache Mahout 是可拓展的機器學習演算法,通常用在大數據習統。Weka 非常強大,但它在商業使用上有授權問題,你可以用 Java-ML (Java machine learning algorithm)。雖然開發活動看起來停子了,它的函式庫仍值得一試,它擁有足夠的文件與教學讓人易於上手。我會建議有進一步需要的人可探索「深度學習演算法 deep learning algorithm」


原文作者

Mahesha Hiremath
The author is an independent data analytics consultant from Bengaluru. He is building a platform for electric vehicles-Project Vidyut. Project Vidyut is a not-for-profit initiative for promoting electric vehicles, and also to build open source electric vehicles. He can be reached at mahesha-at-projectvidyut-dot-org and tweets with handle@MaheshaHiremath.
Connect with him: Website

超譯系列是練習翻譯的技巧,順便分享給大家參考的資訊相關的資訊。
Exercise to translation. Give advise to me if something wrong.
譯者/translator: Ricky Teng
聯絡/contact: ricky-dot-teng-at-gmail-dot-com

2016年2月26日 星期五

[python]numpy array 的 reshape 練習

這裡收集 reshape 的練習。有時真的很常忘記。
import numpy as np
t1 = np.ndarray((10, 3,3), dtype=np.float32)
t2 = np.ndarray((10, 3 * 3), dtype=np.float32)

q = 0
for i in t1:
    t2[q]=i.reshape(9)
    q +=1
t3 = t1.reshape(10,-1)
t1
array([[[ 0., 0., 0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]]], dtype=float32)
t2
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]], dtype=float32)
t3
 array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]], dtype=float32)

2016年2月13日 星期六

[opensource]作業系統革命觀後筆記

#作業系統革命觀後筆記

2016.02.13


  1. 什麼是作業系統 -2:29
  2. Linus 說「他們把 Richard Stallman 當做哲學家,把我當成工程師。」(這兩個似乎是互看不爽) -3:47
  3. 開始實際由 FSF(GNU) 開始,但現在大家會想到 linux -4:02
  4. 自由的消失,因為密碼的出現。 -5:12
  5. open source 的點子其實電腦一開始就有。直到後來才變得不能看原始碼,也許 M$ 要負一些責任 -6:41
  6. 比爾蓋茲對於軟體所有權的公開信 -7:33
  7. 80 年代的作業系統授權讓 Stallman 很難過,然後成立自由軟體基金會 -9:25
  8. 1984 年 1 月,Stallman 開始 GNU 作業系統開發 -11:35
  9. GNU 的關鍵點就在於 free,指的是 freedom 而不是 free beer。是說擁有修改的權利。 -15:12
  10. 自由軟體還是有著作權的,只是作者給你自由散佈複製修改的權力,但是使用者也要一樣地對待別人 -17:01
  11. 1990年,整個 GNU 系統的核心,現在才要開始。而此時,Linus 的核心出現補上了缺的一塊 -23:12
  12. GNU/Linux system? -30:23
  13. Apache 是 linux 的殺手級應用 -32:05
  14. 作業系統套件散佈商的出現 -34:58
  15. 兩種軟體開發的模式 -38:58
  16. Netscape 是下一棒的抵抗專利軟體的軟體 -40:04
  17. "Netscape Source Code as Netscape Product"「Nestscape 的原始碼也是產品」-43:15
  18. 從 free software 到 open source -46:01
  19. free software 名稱是個問題,人們第一個想到的是免費而不是自由 -46:49
  20. 用 open source 取代 free software 的起源 -47:38
  21. open source 與 free software 的不同。理查史托曼 -48:10
  22. debian 的 open source 定義 -50:32
    1. 自由散佈
    2. 原始碼
    3. 可延伸 寫作(Derived Works Permitted)
    4. Integrity of the Author's Source Code (作者完整的原始碼)
    5. No Discrimination Against Persons or Groups (對任何個人或團體沒有歧視)
    6. No Discrimination Against Fields of Endeavor (不歧視任何領域)
    7. Distribution of License (散佈授權證)
    8. License Must Not be Specific to a Product (授權證不受產品限制)
    9. License Must Not Contaminate Other Software (授權證不污染其他軟體)
  23. database 軟體跟進 -53:28
  24. 主機哥很正常啊?你看滿滿都是。 -57:06
  25. windows 退貨日 -59:22
  26. 我真的很愛看兩個針鋒相對 -1:12:23
  27. 泡沫 -1:20:45
  28. 翻譯 WiDE (wide@edirect168.com) 2004.09.07 修訂/jserv 2015.03.11

2016年2月4日 星期四

[RPI]rpi-raspbian-設定網路增強版

因為我換個 ap 之後就連不上,研究之後發現除了之前提到的招數之外,還有一個很重要的,就是因為 wpa/wpa2 的關係,在 /etc/network/interface 裡無法處理,必須要用 wpa_supplicant 來處理(wep 可以直接在 interface 裡處理),所以,設定的方式就得要改變。

要注意的重點是
(1) wpa2 不支援 iface wlan0 inet static,要指定 ip 就一定要改成 iface wlan0 inet manual。(這是說 /etc/network/interface)
(2) 如果你的密碼不是 hex,就要在把密碼用雙引號夾起來。(這是指 /etc/wpa_supplicant/wpa_supplicant.conf)
(3) 要使用 wpa2,/etc/wpa_supplicant/wpa_supplicant.conf 裡,proto=RSN 與 key_mgmt=WPA-PSK 要設定。
(4) scan_ssid=1 照 參考[2] 的說法很好用。會自動連到可用的 ap。但是從 參考[5]、參考[6] 來看好像又是另外一回事。讓我日後再確認吧。

參考:
[1] https://www.raspberrypi.com.tw/2152/setting-up-wifi-with-the-command-line/

[2] http://www.algissalys.com/how-to/how-to-raspberry-pi-multiple-wifi-setup-through-the-command-line

[3] http://stackoverflow.com/questions/14119446/iwconfig-connect-network-via-wifi-on-terminal

[4] http://weworkweplay.com/play/automatically-connect-a-raspberry-pi-to-a-wifi-network/

[5] http://lynn770707.pixnet.net/blog/post/334312943-%5Blinux%5D-wifi-wpa_supplicant%E8%A8%AD%E5%AE%9A%E6%AA%94

[6] https://www.daemon-systems.org/man/wpa_supplicant.conf.5.html

2016年1月31日 星期日

[ipython] jupyter 數學公式的寫法(還有顯示 $ 錢字號 dollar sign)

目前查到的有兩種方法。一種是用 ipython.display 的功能,一個是使用 mathjax。

使用 ipython.display
ipython.display 提供非常豐富的顯示方式,這種方式是靠 code cell 執行程式處理。
像是:
來源[1]

來源[1]





使用 mathjax
基本上 jupyter 已經是使用 mathjax 處理數學公式。而且它整合在 markdown cell 裡。
所以只要把建立一個 markdown cell,把 latex 的表示的前後加上 $ 這個符號,像這樣:
$c = \sqrt{a^2 + b^2}$

再按下 cell 的執行按鈕,就會畫出公式了。
來源[2]

因為錢字號現在被視為語言關鍵字,在文章中要顯示 $ 的方法,可以看以下文章:http://codebeta.blogspot.tw/2016/01/blogspot-blogger-latex.html


參考:
[1]http://nbviewer.jupyter.org/github/ipython/ipython/blob/1.x/examples/notebooks/Part%205%20-%20Rich%20Display%20System.ipynb

[2]http://jupyter-notebook.readthedocs.org/en/latest/notebook.html#markdown-cells

[mathjax]在 blogspot / blogger 網誌裡顯示 latex

要在網頁上顯示公式,現在查到的主流方法是用 latex 語法,函式庫是用 Mathjax。總之時代進步了,就這個樣子。

查到的方式是,在網頁範本裡的 head 區加入定義好的 script。有人已經好心處理好了。

blogspot 的範本是在這裡開啟:



按下去之後就是:



在 </head> 之上插入以下的程式碼:

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js">
MathJax.Hub.Config({
 extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js"],
 jax: ["input/TeX", "output/HTML-CSS"],
 tex2jax: {
     inlineMath: [ ['$','$'], ["\\(","\\)"] ],
     displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
 },
 "HTML-CSS": { availableFonts: ["TeX"] }
});
</script> 
存檔,然後寫個網誌來試試,像這樣:$$ \sum_a^b x^2 $$ $$ \sum_a^b x^2 $$

現在要顯示錢字號,就要包在 <span class="tex2jax_ignore">$</span> 裡面。有沒有更方便的方式,我暫時不知道。

參考:
http://tex.stackexchange.com/questions/13865/how-to-use-latex-on-blogspot

https://blogueun.wordpress.com/2014/01/04/escaping-in-mathjax/

[ipython] ipython notebook / jupyter 介紹--為什麼我要用

其實我的目的是,利用 ipython notebook / jupyter 當做多功能編輯器,取代 notepad++ 或是 word。

在安裝 anaconda 之後,不論在命令列是執行 ipython notebook,或是執行 jupyter notebook,都會成出現同一個畫面:
已經是 jupyter 了。所以原來的 ipython notebook 畫面,我現在用不出來。
圖片來自 http://ipython.org/notebook.html

但是,由以下的 demo 還是可以體會到 ipython notebook / jupyter notebook的魅力。


與 jupyter notebook 的畫面比較,似乎沒有太大差別。

要提一下的是,ipython 是一件事,ipython notebook 是另外一件事。ipython 是提升 python 的互動性的介面,所以叫 ipython (interactive python)。而 ipython notebook 則是一個 web app 讓使用 python介紹、呈現資料、計算更為活潑即時,而它的確建立在 ipython 之上。

jupyter 與 jupyter notebook 也差不多是兩件事,jupyter 有他偉大的計劃, 希望能讓其他的語言也能 ipython notebook 達到的效果。而 jupyter notebook 則是目前執行出這個 web app 的指令。

而目前,我剛好就只需要用到 ipython notebook 的功能,而現在它屬於 jupyter notebook 其中一個項目之中。為什麼還要換 ipython notebook 呢?因為網路上用 ipython notebook 當關鍵字搜尋到的非官方資源還是佔多數,若是要自己多學就還是要知道 ipython notebook 與 jupyter notebook 的關係。
例如:在 google 輸入 jupyter notebook latex,出來第一個還是:

連 google 都知道要用 ipython notebook 會是比較對的結果,當我們知道它們的關係,就不會直接跳過它,而會點進去看。

如果說想深一點了解我想做什麼的話,我用一個網頁來代表:http://hplgit.github.io/doconce/doc/pub/slides/scientific_writing-1.html
雖然文章主打不是 ipython notebook。

參考:
http://ipython.org/notebook.html

2016年1月29日 星期五

[ipython] anaconda 一個方便的 ipython notebook 安裝

有許多網誌教導,「安裝 ipython 會遇到許多麻煩,所以新手最簡單的就是下載 anaconda 來裝,一切沒煩惱。接下來我們來下載……。」於是,我就來試毒,看看有什麼麻煩,先從安裝 anaconda 開始。

首先從 https://www.continuum.io/downloads 選擇安裝器。我選的是紅框那個 windows python 2.7 32bit


下載完之後,點兩下就執行,一開始都按下一步,但很快遇到第一個選項要決定:

如果選了 Just Me,安裝目錄就會被選在使用者的家底下,例如 C:\User|xxx\Anaconda2。這個樣子我不太喜歡。所以我選了第二個,因為我希望它被放在 C 槽根目錄底下跟 C:\python27 這樣。

再來一些 Yes 與下一步之後,又遇到一個要決定的事情:

如果選擇上面的選項,在 Anaconda 環境上,就是靠 PATH 的設定來決定誰被先選到。如果不選,那就是只能用 anaconda 提供的命令列視窗使用 anaconda 的環境。

如果選擇下面的選項,那系統要求 python 的時候,就會去找 anaconda 提供的 python 環境。如果有混搭如他所說的 IDE,就要選擇這個會比較方便。

因為我本身已經安了一堆東西在 C:\Python27 底下,也習慣了,所以第二個選項就不勾了,只勾第一個選項。

按下 Install 之後,就是等待,然後就安裝完畢了。

因為我是 win10,我按下視窗鍵用眼睛要找 "Anaconda (32-bit)",找不到…。


看不到不代表沒有,反正東西就在那裡了。在命令列直接打 ipython。我原本沒裝的 ipython,現在有反應了。



我為什麼要用 anaconda 呢?是為了要裝 IPython Notebook,後來進級叫做 Jupyter。(官方說法是 ipython notebook 移到 jupyter。)改篇再說。

參考:
https://www.continuum.io/why-anaconda