2016年11月28日 星期一

2016 年第 46 周記事

時序已過了 46 周了, 再過五周這一年就要過去, 如果不是有認真在寫周記還真的搞不清楚日子是怎樣過去的. 本周比較重要的是周二去上了兩天 Python 進階的課程, 把我的注意力從 Arduino 導回 Python 以及 GAE, 主要是從課堂上得知兩本 Python 在資料擷取方面的好書, 我就想說應該可以用樹莓派 Linux 裡的 cron table 來抓資料經過分析後存在 MySQL 資料庫裡, 然後將分析結果以 Email 傳給手機. 等有空再次玩樹莓派時再來試試看.

這次去上課巧遇了兩個人, 一個是同棟不同單位但已調職他處多年的美智, 我們彼此都忘了對方名字了; 另外一位是以前跟我一起奉派去美國舊金山研習的三元兄, 算算這竟然已經是 11 年前的事了, 日子怎麼過得這麼快呀! 可不是嗎? 當時二哥才上中班呢! 轉眼已經上了高中. 我覺得五十歲之後, 對時光越來越來越敏感, 恨不得時間的巨輪能轉慢一些, 對於人生的得失也較了然, 比較不想去計較了.

很久沒在管菜園, 上週日鋤了一小塊地來種玉米, 玉米用的是年初小舅給我的一支玉米棒, 但是沒把握會順利發芽, 所以旁邊與重新栽植了地瓜葉. 一周過去了, 似乎沒看到發芽跡象, 周日一整天都在下雨, 我看再不發芽可能都要爛掉了, 下周乾脆去買玉米苗來種算了.

另外就是 11/23 向英國 Hostinger 以美金 27 元租用其 Premium 虛擬主機三年 (到 2019/11/23), 這幾天陸續將專案上傳部署後, 設定 Advanced Cron Jobs 功能去觸發指定之 PHP 網路爬蟲程式擷取資訊後進行分析, 平均執行時間約在 30~40 秒完成, 我對此 Advanced Cron Jobs 功能相當滿意, 因為它最快可以設定每分鐘觸發一次.


本周菁菁與二哥本來要跟我一起回鄉下, 但理化家教黃老師周六下午有事, 問說可否改為周日下午; 而二哥則補習班臨時要補課, 所以仍是我一人回鄉下. 以後上大學或就業, 全家一起回鄉下的機會想必是越來越少了. 從二哥國二去全晟補習理化開始, 大家坐 QRV 回鄉下的情景就變成我跟姊姊與菁菁三人而已. 然後今年七月姐姐也為了準備明年的學測開始週日要去補習班, 就變成我跟菁菁兩人了. 接下來呢, 菁菁也要面臨會考了, 小舅媽說得沒錯, 以後會變成只有我一個人回去了. 雖然明白這是離巢期將近的訊息, 但 ... 孤寂總是需要些時間來調適 ... Good old days.


2016年11月26日 星期六

Hostinger 的 Advanced Cron Jobs 設定

昨天終於有空將我的 PHP 專案上傳到 Hostinger 虛擬主機, 安裝好應用程式後馬上就來測試它的 "Advanced Cron Jobs" 功能, 如果好用的話就可以自行觸發 PHP 程式的執行, 不用再依靠 GAE 的 Cron  Jobs 從外部查詢觸發了.

首先登入後台管理頁面, 往下移到 "Advance" 區塊按 "Advanced Cron Jobs" 鈕 :



最上面 "Command to run" 框是填入要執行的 PHP 程式, 裡面有提示預設格式如下 :

/usr/bin/php /home/u123456789/public_html/cron.php

注意喔, php 與後面的 / 之間必須空一格, 我第一次輸入就忽略這個, 雖然可以順利建立一個 cron, 但是在 View Output 時就會看到下列 "Not a directory" 的錯誤訊息 :

/bin/sh: /usr/bin/php/home/u123456789/public_html/cron/fetch_twse_daily_close.php: Not a directory

我猜這是 Hostinger 當初在 /user/bin 下建立 php 目錄時多敲了一個空格所致, 可能用戶多了之後才發現, 只好將錯就錯了. 我的 cron jobs 檔都放在根目錄的 cron 資料夾下面, 所以正確的路徑應該是 :

/usr/bin/php /home/u123456789/public_html/cron/fetch_twse_daily_close.php



這樣 cron tables 便設定完成, 按 "View Output" 可看到最近一次執行結果 (如果沒有的話, 可能是被瀏覽器擋掉了, 檢查網址列是否有顯示自動阻擋彈出式選單的統計, 將其取消阻擋即可). 與 "Cron Jobs" (Simple) 比較, "Advanced Cron Jobs" 最快執行頻率可設到每分鐘跑一次, 設定選項比較細比較多; 而 "Cron Jobs" 則最快是一小時跑一次, 而且只能在整點時跑 (即 0 分時), 選項也比較少.


"Cron Jobs" (Simple) 的 command to run 欄位已經預先固定路徑到我的帳號底下, 因此不會碰到 "Advanced Cron Jobs" 中 php 後面須有一空格問題.

不過, 不論是 "Advanced Cron Jobs" 或 "Cron Jobs", 同一個程式只能設一次, 但如果分別在兩邊各設一次則可以, 亦即兩者是各自獨立的. 要解決此問題也很簡單, 就是把要在不同時間執行的程式複製為另一個檔案, 例如 fetch_twse_daily_1.php 與 fetch_twse_daily_2.php 即可, 或者乾脆就每個小時執行一次也不為過, 有些意天只能產生一筆的資料就在程式中用日期欄位來判斷即可.

當然我還是可以從外部用 GAE 來觸發執行, 但先看看內部觸發跑的情況如何, 優的話就不必用到 GAE 了.

2016-11-29 補充 :

觀察 Cron jobs 運轉兩天的報告, 我發現指定時間執行的程式都比預期時間晚 8 個小時執行, 例如指定 16:00:00 執行, 實際上卻是到 00:00:00 才真的跑. 我猜這是因為台灣與英國有 8 小時時差的關係, 我們是 GMT+8, 所以若指定下午四點執行, 我們下午四點時英國才當日早上 8 點, 而英國下午 4 點時我們已是晚上 12 點. 我已寫信詢問 Hostinger 是否有地方可以設定 Cron Jobs 時區的? 不過我相信是沒有, 這部分可能得自己換算, 反正就是將我們預定要執行的時間減 8 即可, 要不然就改為每小時或每兩小時執行一次, 然後在程式中依據日期欄位判斷是否已經執行過了, 是的話跳過即可.


河堤公園單車行

早上載菁菁去圖書館回來後, 看到我的小白已經兩個禮拜沒騎了 (太忙了), 還好手機有帶, 就直接換小白騎出去, 今天主要是想測量沿河堤公園騎到博愛二路與三路兩端來回路程與時間. 路線圖如下 :


我從明誠路出發經大順路到博愛二路的愛河之心折返, 再騎回明誠路往前過新莊仔路, 自由路, 再到博愛三路折返明誠路, 這樣總計是 7.38 公里, 耗時約 40 分鐘 :


這樣單程應該是 3.6 公里. 每周都要這樣鍛鍊 1~2 次, 加上慢跑與游泳, 希望在冬季結束前完成南迴段, 可能的話也把 20 多年前停下來的彰化~嘉義段, 嘉義~高雄段補齊, 這樣就只剩下花東段了.

2016年11月25日 星期五

下載備份 Google App Engine 應用程式檔案的新方式

之前我在 Hostinger 上申請的免費網站由於進行了大量運算被認為濫用免費資源而遭到停權 (我哪知道免費用戶的 CPU 使用量是多少啊), 結果促使我在前天向 Hostinger 購買了 Premium 虛擬主機服務. 但是我發現原先的免費帳號還是不斷地被之前設定的 GAE cron jobs 進行 query, 因此在寫信向 Hostinger 解釋之前必須先停止 GAE 上的 cron jobs 才行.

我參考了之前的文章去下載 GAE 應用程式以便檢查看看到底是哪一個應用程式在 trigger 我的 Hostinger 免費主機, 因為太久忘記了, 所以就從最接近的 appfog-twstockbot 開始查起 :

# 下載備份 Google App Engine 應用程式檔案的方法

但是照原先的方法下載卻發現不像以前那樣會在 DOS 命令列中直接詢問 Google 帳號密碼, 而是顯示如下訊息 :

Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation. 著作權所有,並保留一切權利。

E:\>appcfg.py download_app -A appfog-twstockbot -V 1 E:\gae\appfog-twstockbot
09:35 PM Host: appengine.google.com
09:35 PM Fetching file list...
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id=550516889913.apps.googleusercontent.com&access_type=offline

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

這時 DOS 就僵在那邊無法動彈 (其實就是在等待我們使用瀏覽器進行 Google 帳號認證), 同時冒出一個視窗詢問要用哪一個瀏覽器認證, 選好後就會開啟瀏覽器連線到 Google 進行認證, 我的 Google 帳號採用兩階段認證, 因此必須用登記的手機接收認證碼, 驗證成功後會顯示要求授權存取 GAE 與 Google Cloud 頁面 :


按允許後結束認證, DOS 畫面即回應開始下載 :

Authentication successful. (認證通過)
09:36 PM Fetching files...
09:36 PM [1/10] main.py (這個檔案就是我要檢查的 cron table 觸發對象)
09:36 PM [2/10] extjs.htm
09:36 PM [3/10] jquery.htm
09:36 PM [4/10] index.yaml
09:36 PM [5/10] static/dataTables.zh-tw.txt
09:36 PM [6/10] html5.htm
09:36 PM [7/10] app.yaml
09:36 PM [8/10] cron.yaml (這是 cron table)
09:36 PM [9/10] default.htm
09:36 PM [10/10] favicon.ico

打開 main.py (此為 MTV 架構中的 View, 或 MCV 架構中的 Controller, 負責 routing) 檢查, 果然就是去觸發我在 Hostinger 申請的免費的 16mb.com 網址, 抓到了. 以前如果佈署完應用程式就馬上做紀錄的話, 現在也不會這麼費事去調查.

接著檢查其中的 cron.yaml, 其內容就是 cron table :

cron:
- description: fetch_twse_daily_close
  url: /fetch_twse_daily_close
  schedule: every day 16:00
  timezone: Asia/Taipei
- description: fetch_twse_daily_institutes
  url: /fetch_twse_daily_institutes
  schedule: every day 16:02
  timezone: Asia/Taipei
- description: technical_analysis
  url: /technical_analysis
  schedule: every day 16:04
  timezone: Asia/Taipei
- description: create_daily_report
  url: /create_daily_report
  schedule: every day 16:08
  timezone: Asia/Taipei
- description: fetch_daily_report
  url: /fetch_daily_report
  schedule: every day 16:10
  timezone: Asia/Taipei
- description: fetch_twse_daily_debit
  url: /fetch_twse_daily_debit
  schedule: every day 21:00
  timezone: Asia/Taipei
- description: fetch_2330_tw_basic
  url: /fetch_2330_tw_basic
  schedule: every 11 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_dividend
  url: /fetch_2330_tw_dividend
  schedule: every 22 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_analysis
  url: /fetch_2330_tw_analysis
  schedule: every 12 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_balance
  url: /fetch_2330_tw_balance
  schedule: every 13 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_cash
  url: /fetch_2330_tw_cash
  schedule: every 14 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_income
  url: /fetch_2330_tw_income
  schedule: every 15 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_profit
  url: /fetch_2330_tw_profit
  schedule: every 16 minutes
  timezone: Asia/Taipei
- description: fetch_2330_tw_owner
  url: /fetch_2330_tw_owner
  schedule: every 21 minutes
  timezone: Asia/Taipei
- description: fetch_yahoo_company
  url: /fetch_yahoo_company
  schedule: every 60 minutes
  timezone: Asia/Taipei
- description: fetch_yahoo_dealing
  url: /fetch_yahoo_dealing
  schedule: every 9 minutes
  timezone: Asia/Taipei
- description: fetch_yahoo_credit
  url: /fetch_yahoo_credit
  schedule: every 10 minutes
  timezone: Asia/Taipei
- description: fetch_yahoo_major
  url: /fetch_yahoo_major
  schedule: every 10 minutes
  timezone: Asia/Taipei
- description: fetch_yahoo_earning
  url: /fetch_yahoo_earning
  schedule: every 20 minutes
  timezone: Asia/Taipei

把第二行以下全部刪除, 只留第一行的 cron: 然後更新 cron table 即可終止 cron jobs 了. 參考 :

# 停止 GAE 的 cron jobs 的方法

接下來下達更新 cron 的指令 :

E:\>cd gae

E:\GAE>appcfg.py update_cron appfog-twstockbot
11:14 PM Host: appengine.google.com
11:14 PM Uploading cron entries.

E:\GAE>

註 : 加上 --oauth2 透過瀏覽器認證 (新版的 GAE SDK 已預設不須加, 較舊的則需要)

E:\GAE>appcfg.py --oauth2 update_cron appfog-twstockbot


注意, 不論是下載/上傳應用程式, 或者更新 cron 必須在應用程式 (此處為 appfog-twstockbot) 的上一層目錄 (此處為 GAE) 下執行, 參考 :

# GAE 的 Cron Job

所以上面下載應用程式應該在 E:\GAE 下比較一致 :

E:\cd GAE
E:\GAE>appcfg.py download_app -A appfog-twstockbot -V 1 appfog-twstockbot

最後補充一點, 如果不要用瀏覽器認證, 要像以前那樣直接在 DOS 輸入帳號密碼, 只要加上一些參數即可 :

appcfg.py download_app -A appfog-twstockbot -V 1 E:\gae\appfog-twstockbot --noauth_local_webserver

不過因為我的 Google 已經採用兩階段認證, 因此不能輸入 Google 密碼, 而是要輸入機器認證專用密碼, 我覺得還是用目前以瀏覽器進行認證較方便.

2016-12-26 補充 :

昨晚停掉 GAE 上的 appfog-twstockbot 應用的 cron 後, 果然就靜下來了 :


這樣就可以寫信給 Hostinger 說我的 16mb.com 免費主機只是做實驗用途, 不會再進行大量運算了, 希望他們可以恢復運作. 其實既然已經購買了 Premium 服務, 我是不需要這個免費主機, 但看到帳號底下有個 abuse 字樣總是不舒服, 而且無效的 cron 不斷運作也是耗損能源, 一切無效的動作都必須停止.

# https://cloud.google.com/appengine/docs/python/download

2016-11-27 補充 :

今天在鄉下老家電腦上用較舊版的 GAE SDK 照上面程序下載, 發現它還是跟以前一樣在 DOS 中詢問 Email 與密碼, 因為我的 Google 帳號已申請兩階段認證, 所以這密碼可不是 Google 帳號的密碼, 而是在 Google 帳號設定中授權 GAE 存取的另一組密碼, 我之前有特別記下來, 但是輸入後卻無法通過認證, 真是傷腦筋, 還要回去找之前所寫的紀錄, 很浪費時間. 我直接在 Google 搜尋, 馬上就找到結果了, 參考這篇 :

# 使用Google App Engine上傳程式, 一直要求輸入帳號密碼, 如何解決?

原來只要加上 --oauth2 就會透過瀏覽器進行 Google 帳號認證了, 例如 :

appcfg.py --oauth2 download_app -A appfog-twstockbot -V 1 E:\GAE\appfog-twstockbot



辦公室的新電腦

周一來了一批新電腦, 我辦公室的那台也在汰換之列. Something new is always good, but~~ 一堆資安要求與軟體重安裝很麻煩. 由於我 D 碟累積了一大堆工作資料, 周一下班前負責幫我調校系統的年輕人說資料搬移至少需要兩小時, 只好丟在那邊讓它跑. 受訓兩天回來才著手安裝軟體, 昨天花了半天才能開始用.

今天開始安裝軟體, Java 還是用 JDK7, 因為之前寫的程式都在此環境跑, 而且我不認為我會用到 Java 8 的那些奇怪的新功能, 也不打算在 Java 上花額外的心力, 我大概只要用 Java 來擷取與分析營運資料即可. 去上兩天 Pyhton 進階班課成後, 我決定專注在 Python 的學習.

安裝完 JDK 7 後要到 "控制台/系統" 下設定環境變數 :

JAVA_HOME=C:\Program Files (x86)\Java\jdk1.7.0_79
PATH= ~ ;%JAVA_HOME%\bin;

這樣在任何目錄下便能順利執行 Java 程式了.


好書 : 系統程式

這本書是從鄉下的市圖分館借來的, 此書寫得極好, 以作者設計的一個簡易 32 位元處理器 CPU0 為對象來說明如何實作其組譯器, 編譯器, 作業系統等系統程式. 看了前面一點便沒有時間看, 還是先歸還, 等以後有空再借, 這裡做個紀錄以便後續追蹤.

# 系統程式 System Software (旗標, 陳鍾誠)


作者陳鍾誠係金門大學教授, 涉獵廣泛著作頗豐, 參考 :

# http://ccckmit.wikidot.com


2016年11月24日 星期四

如何取消手機未應答轉接

二哥前陣子問我說他的手機會接到打給我的電話, 我以為是之前在 3G 時代申請的雙號同振沒取消掉, 今天打電話問中華行動客服是否可取消, 結果竟然我沒有申請同振, 客服認為可能是我手機有設定未應答轉接之故, 可以在撥號盤輸入下列號碼後按撥號 :

##002#

按完後再試真的就不會有這現象了, 證實是未應答轉接. 如果要設定未應答轉接到某個號碼例如 0933000000 (假設號碼), 則要輸入如下號碼 :

**61*0933000000#

注意, 藍色部分要換成你要轉去的號碼.


購買 Hostinger Premium 虛擬主機服務

昨晚寫完 Python 學習筆記正想關機睡覺, 突然想到上周評估虛擬主機時有打算以每月 1.99 歐元租用英國 Hostinger 的 Premium 主機, 現在是否還有這個價格? 結果連線過去發現竟然有更好的折扣優惠, 租三年只要 27 歐元, 並贈送 .xyz 域名一年 !



點進去看發現只有租三年才有最高 15 折, 每月 0.75 歐元優惠, 租四年可沒這麼好哩 !


於是我當機立斷, 擇期不如撞期, 就給他下單了 :


可知 Hostinger 雖是 UK 公司, 但卻在塞普路斯註冊. 右上角還註明必須 11/23 日結束前付款, 我下單時雖已過 12 點為 11 月 24 日, 但在塞普路斯還是 11/23. 我使用信用卡付款後馬上收到銀行簡訊通知信用卡消費約 1027 元, 推算匯率是 1027/27=38 元, 哇咧, 比今天台銀收盤價 34 元高出 4 元, 這是手續費嗎? 這個價格以我上周我評估時四年 3333 元來算, 換成三年是 3333*3/4=2500, 則1027 相當於是上周的 41 折 : 1027/2500=0.41.

付款後網頁出現兩項訂單需要設定, 一是虛擬主機, 一是免費一年的域名 :


主機設定主要是輸入域名, 密碼, 以及選擇主機位置, 我選北美 :


而域名設定部分則是輸入姓名住址與電話而已 :


以現有 Hostinger 帳號登入系統後果然出現了這個新的主機, 租期三年到 2019-11-23 :


如果不是這麼湊巧, 我還不知道要猶豫多久才會下決定哩! 

2016-11-24 補充 :

早上登入 Hostinger 時出現下列告示 :

"Your domain is not pointing to our nameservers at the moment, so services such as FTP, File Manager, E-mail (and others) will not work correctly. You can find our nameservers at the "Accounts -> Details" section. Please mind that DNS might take up to 24 hours to propagate when the change is submitted."

好像是說我申請的一年免費 .xyz 域名尚未指到 Hostinger 的域名伺服器, 這要在哪裡指定呢? 還是說因為要 24 小時才會綁定, 所以這只是通知而已? 我已寫信詢問客服了解 (線上客服時間是英國當地 03:00~22:00, 相當於台灣時間 11:00~24:00). Hostinger 的域名伺服器如下 :


Business 主機也有打折優惠 (同樣租三年 15 折), 但我比較了 Premium 與 Business 的差別, 發現兩者只有資料庫備份週期與是否提供 SSL 這兩項不同而已 :


這兩項對我而言並非很重要, 而兩者價格卻差兩倍, 所以我覺得還是 Premium 價划算.

2016-11-24 晚上補充 :

晚上吃過飯後收信發現 Hostinger 通知我的一年免費域名已經開通, 實際連線果然顯示預設內容了, 可見域名啟用大約要花將近一天. 另外登入系統後在管理網頁右下角會顯示線上諮詢按鈕 :


按此按鈕會出現線上對談框, 可以向客服人員提出疑問. 我今天主要是問, 我的免費 .xyz 域名明年到期後若不續用, 可否切換為 Hostinger 提供的免費域名 (例如 16mb.com 的) ?


答案是可以的, 但不是在哪裡設定切換, 而是要按 Home/Hosting 底下的 New Hosting Account 鈕新增一個帳戶, 然後建立一個免費域名來連結虛擬主機即可.

2016-11-25 補充 :

我第一次申請 Hostinger 帳號是在 2016-2-16 日, 所寄 Email 資訊如下 :

Nameserver 1: ns1.hostinger.co.uk 31.170.163.241
Nameserver 2: ns2.hostinger.co.uk 31.220.23.1
Nameserver 3: ns3.hostinger.co.uk 173.192.183.247
Nameserver 4: ns4.hostinger.co.uk 31.170.164.249

Uploading Your Website

You may use one of the addresses given below manage your web site:

Temporary FTP Hostname: 31.220.16.247
Full FTP Hostname: ftp.yourAccount
FTP Username: uxxxxxxxxx
FTP Password: yyyyyyy

You must upload files to the public_html folder!

Email Settings

For email accounts that you setup, you should use the following connection details in your email program:

POP3 Host Address: mx1.hostinger.co.uk
Username: The email address you are checking email for
Password: As specified when setting up the email account

Thank you for choosing us.

Hostinger United Kingdom
http://www.hostinger.co.uk

那時為了 Hostinger 不再支援 mysql 函式庫, 我還特別為此將 mysql.php 改為 mysqli.php, 參考 :

# EasyuiCMS 改版為 v2 (mysqli)


2016-12-05 補充 :

這幾天測試 PHP 專案, 發現有時候會出現如下結果 :

Resource Limit Exceeded

The website is temporarily unable to service your request as it exceeded resource limit. Please try again later.

我想這可能是 Premium 只保證 99.9% 穩定度的關係吧.

2016年11月23日 星期三

Python 學習筆記 : 安裝執行環境與 IDLE 基本操作

這兩天被派去受 "Python 進階班" 的訓, 有一段時間沒接觸 Python 了, 趁這個機會溫習一下也好. 老師使用的是 Python 3, 而我以前在 GAE 用的是 Pyhton 2, 但其實差異沒有很多啦. 以下就這兩天的 Python 3 學習做個摘要整理.

Python 是一種跨平台的指令碼語言 (Scripting language), 乃 Python 之父 Guido van Rossum 為了發展 Amoeba 分散式處理作業系統, 於 1989 年以其先前發展之 ABC 教學語言為基礎, 揉合了 modula-3, UNIX shell, Icon, SmallTalk 與 C 語言的風格於荷蘭阿姆斯特丹大學發展而成. Python 語言的基本哲學是 : 做事時應該只有一種明確的方式, 這使得 Python 程式較簡潔易學.

Python 虛擬機器可在多種 OS 上運作, 但最先是在 Mac 機器上實作的. Python 的圖騰是一隻蟒蛇, 但其名稱的由來卻與蟒蛇一點關係也沒有, 而是源自英國 BBC 著名的喜劇影集 "Monty Python’s Flying Circus" 來的. 而其整合開發環境叫做 IDLE 而非 IDE 的原因是 Monty Python 開發小組的一個成員名為 Eric Idle 的緣故.

Python 在 2000-10-16 發布了 Python 2.0, 支援垃圾回收與 Unicode, 此版本是 Python 大受歡迎的開始. 2008-12-03 又發布了 Python 3.0, 但與舊版本不完全相容 (not backward-compatible), 這在程式語言演進上較為罕見. 關於 Python 2 與 Python 3 的差異可參考這篇 :

# Python 2.x 或 3.x?

Python 語言的特色整理如下 :
  1. Python 是物件導向的直譯式語言 (Interpreter language), 與 Java/C++ 等編譯語言比起來, 省掉了編譯與連結步驟, 簡化了開發流程, 但事實上是把中介碼 byte code 的編譯動作隱藏起來了.
  2. Python 與 Javascript, PHP 等語言一樣均屬於腳本語言 (Scripting language), 其與系統語言 (C/C++) 之差異是 : 系統語言目標是節省系統資源, 提高執行效能 (資訊家電需求), 而腳本語言之目標是節省程式員時間, 提高開發速度 (應用程式需求).
  3. Python 是動態語言 (Dynamic language), 在執行時期才確定資料型別, 這與 Javascript, VBscript, Ruby 等語言是相同的.
  4. Python 是強型別語言 (Strong-typed language), 資料型別須透過顯式型別轉換才能混合運算, 如同 Java.
  5. Python 不是格式自由語言, 採用強制縮排定義程式區塊, 以換行表示敘述結束. 縮排是語法的一部分, 違反縮排規則將無法執行.
  6. Python 是跨平台語言, 早期本身是用 ANSI C 語言撰寫的, 可以在 Unix/Linux/DOS/Windows/Macintosh 等作業系統上執行. Python 程式執行時會編譯成 pycode 中介碼, 與 Java 的 bytecode 類似.
  7. Python 是開放源碼 (Open source) 的.
  8. Python 內建比 Java/C/C++ 還豐富的資料型別, 從而有效地減少程式碼長度.
  9. Python 內建複數型別, 支援複數運算.
  10. Python 是完全物件導向的語言, 不論資料, 字串, 函式, 模組全部都是物件. 完全支援多重繼承, 多型, 過載, 衍生, 與泛型, 使程式碼可重複使用. 同時也有例外處理機制, 具備垃圾回收功能, 自動管理記憶體之使用. 
  11. 利用 py2exe, pypy, pyinstaller 可將 Python 原始碼轉成脫離編譯器執行環境的獨立執行程式.
  12. Pyhton 的設計哲學 : 優雅, 明確, 簡單. 希望 "用一種方法, 最好是只有一種方法來做一件事", 而非像 Perl 那樣 "有多種方法來做同一件事", 盡量避免歧義, 因此 Python 原始碼具有高度的可讀性.
  13. Python 雖然被歸類為 "指令碼/描述語言 (Scripting language)", 但其功能遠比 Shell script, Javascript, VBscript 等僅能處理簡單工作之指令碼語言強大, Python 開發者稱其為一種 "高階動態語言".
  14. Python 也被稱為 Glue language (膠合語言), 能夠將其他語言編寫的程式進行整合與封裝.
  15. 大多數 Linux 發行版本都已整合了 Python, 可以在終端機下直接執行 Python.
  16. Python 語言的架構是可延伸的, 並非所有的功能與特性都整合到核心, 而是歸類於其強大的標準函式庫中, 從而避免像 VBscript 那樣臃腫. Python 輕巧的語言核心只包括數字, 字串, 串列, 字典, 檔案等資料型別與函式, 其他額外功能如系統管理, 網路通訊, 文字處理, 資料庫, 圖形介面, XML 等全部由標準函式庫提供. 另外社群還提供豐富的套件, 如 Web 開發, 科學計算等等.
  17. Python 標準函式庫包含多個作業系統功能呼叫函式庫, 透過 pywin32 套件可以存取 Windows API 與 COM 服務; 而透過 IronPython 則可直接呼叫 .Net Framework.
  18. 以 Python 編寫系統管理指令在可讀性, 效能, 重覆使用, 擴充性方面都優於 shell 指令.
  19. Python 已有的實作 : CPython (C), JPython (Java), PyPy (Python), IronPyhon (.Net).
以上都是關於 Python 的背景知識, 現在 Python 越來越受歡迎, 不僅在科學計算領域被廣泛使用, 許多大學如 MIT 與柏克萊等校之資訊科學系也改用 Python 作為學生必修語言, 目前 Python 在 TIOBE 排行已經穩定在前五名 :


自 Python 1.0 於 1994 年問世以來, 過去 22 年來 Pyhton 的排名從 26 名穩定上升到目前的第五名, 其受歡迎的程度可見一斑 :


此外在嵌入式系統應用中, Python 也是樹莓派 Raspberry Pi 的預設作業系統 Raspbian 的內建程式語言, 樹莓派也因為 Python 龐大的第三方套件而展現驚人的功能, 廣泛應用在無人機, 機器人, 影像辨識, 自然語言處理等領域. Python 的厲害在於其豐富的第三方套件, 在 PyPi 網站上已登錄超過 9 萬個套件, 各種應用應有盡有, 參考 :

# https://pypi.python.org/pypi

學習 Python 要先安裝其執行環境, 首先到官網下載 Python :

# https://www.python.org/downloads/

如果要安裝 64 位元版本, 到下列網址尋找 x86-64 exceutable 版的 :

# https://www.python.org/downloads/windows/

目前最新版是 3.5.2, 如果是用在 GAE 的話要下載 2.7 版, 因為 GAE 尚未支援 Python 3.  Python 2.7 版也是 Python 2 的最後版本.

安裝 Python 時要注意更改安裝路徑以及勾選 "Add Python 3.5 to PATH" :


注意, 這裡要選 "Customerized installation", 這樣才能更改安裝路徑 :


這個只要按 Next 即可 :


這裡就是修改安裝路徑的地方, 將原先又臭又長的路徑改為 C:\Python35 即可. 這樣安裝完後在 DOS 視窗的任何目錄下打 Python 都能執行 Python 程式.



直接輸入 Python 指令馬上即輸出結果. 例如 :

>>> 2+3
5
>>> print(2+3)
5

如果要跳出 Python 直譯器, 可輸入 exit() 或 quit() 或按 Ctrl+C 即回到 DOS 命令列.

此外也可以使用 Python 內建的 IDLE 交談式介面來執行 Python 程式, 其功能比由 DOS 進入 Python 執意環境要多, 例如可以編輯 Python 程式後點選 Run Module 來執行檔案.

當下了一些指令後, IDLE 視窗就會塞滿指令與回應, 能不能像在 DOS 一樣下個 CLS 指令就清除畫面呢? 很遺憾的是 IDLE 並沒有這樣的單一指令. 不過可以照下列文章介紹的方法為 IDLE 添加清除畫面快捷鍵 :

# IDLE如何清屏?

先下載 ClearWindow.py 程式, 將其放在 Python 3 安裝目錄的 C:\Python35\Lib\idlelib 下, 然後用記事本編輯此目錄下的 config-extensions.def 檔, 將下列指令複製到檔尾後存檔, 將 IDLE 重開即可在 Option 下看到新增的 "Clear Shell Window" 功能選項了, 按此可清除畫面 :



這次受訓從老師那邊發現一本 Python 好書 :

# Python 程式設計 : 從初學到活用 Python 開發技巧的 16 堂課 (何敏煌, 博碩)

Source : 天瓏

今天晚上就跑去明儀買回來, 打算好好研讀一番.

參考 :

# Python 2.x或3.x?
# Python Tutorial 第二堂(1)數值與字串型態

Python 3 與 Python 2 主要的差異如下 :

1. Input 輸入 :

在 Python 2 時可以使用 raw_input() 函數與 input() 函數讀取標準輸入, input() 事實上是透過 raw_input() 實作的, 兩者的傳回值型態不同, raw_input() 傳回值一律是字串, 且字串輸入時不用加引號, 例如 :

>>> raw_input("Name:")
Name:tony     (字串不須加引號)
'tony'
>>> raw_input("Age:")
Age:50
'50'                 (傳回字串)

可見 raw_input() 輸入時都不用加引號. 而 input() 則字串須加引號 :

>>> input("Name:")
Name:tony    (字串須加引號)

Traceback (most recent call last):
  File "    input("Name:")
  File "NameError: name 'tony' is not defined
>>> input("Name:")
Name:"tony"   (字串須加引號)
'tony'
>>> input("Name:")
Name:"tony"
'tony'
>>> input("Age:")
Age:50   (數字不須加引號)
50

可見 input() 只有數字不須加引號.

不過在 Python 3.2.3 版後已經不能用 raw_input() 了, 只能使用 input().

參考 :

# python 研究-raw_input 和 input 差異比較

2. Print 輸出 :

在 Python 2 時 print 是一個敘述 (指令), 列入關鍵字裡面, 使用方式如下 :

print "Hello World"

但是到了 Python 3 時 print 變成函數, 輸出資訊必須放在小括號內 :

print ("Hello World")

3. 中文支援 :

Python 2 雖然也支援中文, 但必須在第一行指定 UTF-8 字元編碼 :

# -*- coding:UTF-8 -*-

同時 .py 檔存檔時必須另存為 UTF-8 編碼格式.

但是在 Python 3 已經全面支援中文了 (預設使用 UTF-8 編碼), 連變數名稱也可以使用中文, 例如 :

>>> 哈囉世界="Hello World"
>>> 哈囉世界
'Hello World'

第一行不用再加 encoding 註記, 但仍要存成 UTF-8 格式.


另外, Python 支援大整數也是一個亮點, 在 C/Java 等語言裡, 整數 int 使用 4 個 bytes 儲存, 資料範圍 -2147483648~2147483647, 超出此範圍即發生溢位錯誤而無法儲存. 在 Python 無此問題, 再大的整數都可以處理. 在 Python 2 版還有分整數 int 與長整數 long, 大整數可以在後面加個 L 標示為長整數. 而且 2.2 版後若發生溢位會自動轉換成長整數, 不會出現執行錯誤. 到 Python 3 之後已經沒有 long 這種資料類型, 整數就只有 int 這個類型, 這個 int 其實就是 2 版的 long, 亦即在 Python 3 裡全部都是長整數.

不過, Python 對大整數的支援無上限指的是直到機器的極限, 看 CPU 是 32/64 位元而定. 而浮點數也是有機器限制的, 32 位元電腦只能表示到小數點後 12 位; 64 位元則至 16 位,  例如 :

>>> 1.0/3.0     (64 位元機器)
0.3333333333333333

而科學表示法可以處理到 1.7e308, 到 1.8e308 就變成 inf (無限大) 了 :

>>> 1.8e308
inf
>>> 1.7e308
1.7e+308
>>>

2017-04-11 補充 :

Python 3 與 Python 2 到底有哪些不同? 參見 :

# https://docs.python.org/3/whatsnew/3.0.html

2018-02-26 補充 :

在下面這篇文章中建議安裝 32 位元的版本, 參考 :

# https://stackoverflow.com/questions/3117626/should-i-use-python-32bit-or-python-64bit

其理由是 :
  1. 通常不會用到很多記憶體, 32 位元就夠了.
  2. 比較不會遇到 COM 的問題.
  3. 大部分 DLL 是 32 位元的, 64 位元的 Python 通常無法載入 32 位元 DLL.
不過隨著 Python 版本更新, 這些已不是問題, 而且機器學習框架如 TensorFlow 要求 Python 64 位元版本, 因此我現在都改安裝 64 位元版本. 參考 :

# Windows 安裝深度學習框架 TensorFlow 與 Keras


2018-06-23 補充 :

最近在 "超圖解 Python 物聯網實作入門 (旗標, 趙英傑)" 這本書發現愛沙尼亞 TARTU 大學開發的 Thonny 編輯器非常好用, 此 Python 專用編輯器自帶 Python 3.6.4 開發環境, 因此只要安裝 Thonny 即可編輯與執行 Python 程式, 不需在編輯器與命令提示字元視窗來回切換, 可說是超迷你版的 Anaconda, 主要差別是 Thonny 原生只帶了 pip 與 setuptools 這兩個外掛模組, 使用者可視需要利用其方便的安裝工具自行安裝自己用得到的外掛模組, 而 Ananconda 則幾乎是包山包海內建了大多數外掛模組因而顯得擁腫龐大. 參考這篇 :

# 好用的 Python 編輯器 Thonny

如果電腦中還沒安裝 Python, 那就直接安裝 Thonny 就好, 不需要另外在安裝 Python 了. 如果電腦裡已經有 Python 也沒關係, Thonny 自帶的 Python 與電腦原先安裝的 Python 井水不犯河水, 兩邊所安裝的外掛模組也是毫無關係的平行線. Thonny 唯一的問題是其自帶的 Python 是 32 位元且為 3.6.4 版, 而 TensorFlow 框架目前只支援到 3.5 且必須在 64 位元 Python 上跑, 因此無法安裝 TensorFlow. 

高應大圖書調借方式

因為這兩天去上 Python 進階班的關係, 到我的第一母校高應大圖書館找 Python 的書, 發現燕巢校區有一本江良志翻譯的 Google App Engine 的書 :

# 雲端網頁程式設計 : Google App Engine使用Python / Massimiliano Pippi著 ; 江良志譯
# http://www.books.com.tw/products/0010676446

因為 GAE 納入 Google Cloud Platform 後感覺有點陌生了, 所以想借回來看看.


但是跨校區必須用借調方式, 不能點預約或 Request1 超連結. 首先到圖書館首頁右下角點圖書借調服務系統 :


先點一下 "個人專區", 輸入帳號密碼登入系統 :


搜尋要找的書 :


按 "申請借調" 即可 :


每次都會忘記還要打電話問櫃台學妹很麻煩, 所以做一下紀錄.

2016-11-24 補充 :

今晚去圖書館取回這本書了, 果然是本難得的好書, 有專家指引可以省掉不少摸索的時間. 等有心得再做紀錄.