PageRank



轉移公告

計劃把 http://blog.hoamon.info/ 文章全部轉移至 http://www.hoamon.info/blog/ 這裡,而本 Blogger 站台的文章近 500 篇,我預計在 2014-12-31 前移轉完畢,完成後 http://blog.hoamon.info/ 將只作代轉服務,一律把舊連結如 http://blog.hoamon.info/index.html 轉成 http://www.hoamon.info/blog/index.html ,敬請舊雨新知互相走告。

新文章只發佈在 http://www.hoamon.info/blog/

何岳峰 敬上

2011年12月25日 星期日

19 公里花了 149 分

昨天(12/24),許多人準備過耶誕夜的時候,我完成了 19 公里的慢跑,每公里平均 7 分 50 秒的速度,換算成全馬後,在身體沒發生異狀(抽筋、脫水…)的條件下,這種速率應該也是在及格邊緣( 6 小時完賽)。

昨天本來是想跑到 21 公里的,剛好是半馬的長度。但在 19 公里時,已經是下午 6 點 10 分了,入夜的埔里有點冷,我有點受不了,而且小腿肌肉也有些緊繃。擔心受傷,也就結束我的挑戰。

再過一個禮拜,就是我人生中第一場馬拉松了,老婆叫我『盡力而為就好』,我回答她:「我這個人最不喜歡拼命了,放心吧」。

2011年12月22日 星期四

莫名奇妙的一封信


今天(12/22)在我家門口地上發現一封不屬於我們的信,它的投遞門牌跟我家差了 10 號。第一個念頭是它寄錯了。但仔細看看,才發現這個未貼郵票,非由郵差寄送的信件是有問題的。

因為它的收信人不是我,理論上,我該在信件上註明「投遞錯誤」,然後丟入郵筒讓郵局去處理。但因為它沒有貼郵票,這不屬於「郵件」,不關郵局的事,何況它上面沒寫寄件人地址,也沒得退回。

那我應該幫忙把這封信拿到隔壁 5 間房的收件人手上嗎? 仔細看看上面文句,寄信人應該與收信人是朋友關係,但他(她)卻搞錯住址! 這不合理。

所以我認為寄信人就是要我幫忙轉遞的,而會這麼作的原因,在於「這封信」的內容有「違法」的可能性。或許它是恐嚇信。

那我應該拆開這封信,看看裡面是什麼嗎? 反正它沒貼郵票,不是郵件,不受郵政法的限制。但「妨害秘密罪」就不曉得了,這封信算「封緘信函」嗎? 我不是很清楚。而且也有可能寄信人搞了這一大圈就是要我自行拆開信件,然後發現奇怪的事。我不喜歡這種被騙的感覺。

所以我的解決之道是放在我家門口的資源回收箱,它是個公開場所(有些資源回收阿伯會去那找東西),而且我寫了這篇 blog 公告周知。這樣一來,我鐵定不算「隱匿他人之封緘信函」了。

另外還提供各位觀眾滿足好奇心的機會,去看看今晚的 33 台倒底要講什麼!

2011年12月17日 星期六

請惠予捐款綠黨



上面是捐款給綠黨的收據,距離投票日不到 30 天了,我的捐款流水號還只是 44 號而已,這其中還得扣除「未完成捐款流程」的部份,實際上在網路捐款的人可能不到 40 人。

為什麼我會知道有「未完成捐款」的紀錄,因為在作 ATM 轉帳前,我是選擇 WebATM 轉帳的,結果發現被導到綠界去,所以我想綠黨應該會被抽比較多的手續費,所以我才改成 ATM 轉帳,而當時的 WebATM 轉帳交易編號就是 43 。

說實在話,我不完全贊同綠黨主張,像是核四案,我是傾向拿它來取代核一、二、三的,不過,除了核四外,以後就不再接受核五了。

會支持綠黨,主要有幾個原則:

  1. 多樣性: 只問藍綠太無聊了
  2. 理想性: 他們的參選人及黨員是有中心思想,也具備實現的勇氣。不像某個黨的白皮書撰寫人們,在主角當選後,居然說他們不戀棧權位,所以不入閣,那這樣你寫的東西誰要負責實作,果然到後來,主角就只好說那是選戰口號,是目標,但不一定能實現 。
  3. 愛地球: 誰不愛地球呢! 只是程度差別,看起來,他們是比一般人更愛地球的。
另外先預告,這次 2012 立委的政黨票,我一定是投給綠黨的



2011年12月13日 星期二

關於居住正義及實價登錄,我的看法是狗屎(bull shit)

讀「實價登錄闖關 增設 2 但書」新聞。為了要實現「居住正義」,所以立委們要通過幾項法律。其中之一是房屋價格採實價登錄。
我不懂得的是「什麼是居住正義?」是讓每個人有屋子住嗎? 現在也沒通過這些法案,但全臺灣有多少人沒房子住,以遊民數來說:「http://blog.xuite.net/wellsli/003/44107047 、http://www.lihpao.com/?action-viewnews-itemid-62099」,大約在 1 萬 5 千人左右。就他媽的為了這佔臺灣人口千分之六點五的族群,搞這麼大的事,說不過去吧!

所以我想政客們的重點是在『有房子住,但沒有房子的人』身上。那這些人有多少呢:「http://www.libertytimes.com.tw/2010/new/nov/12/today-e9.htm」,大約是三成。

原來民主國家也是會為少數人謀福利的。我一直認為民主國家就應該是個多數暴力國家,因為真正的民主國家才不會強調自己是個民主國家,在他們心中,國家的成份比較少,個人的成份比較多。

話說回來。好啦! 您們說搞了「實價登錄」,那這些沒房子想要買房子的人,就不會被建商、仲介欺騙導致買到價格高於市價的屋子,能讓他們買得起房子。也就是可以用公開透明的「銷售價」讓買房子的人有個「定錨點」,用來證明價格是否合理,以利決定買下房屋。但問題是這想買房子的人,卻也有可能是個有房子但還想繼續買房子的人,因為「實價登錄」沒說「有房子的人不准看」。所以其實這功能不是只為了三成百姓,連其他七成也受惠了。那這樣子又跟「居住正義」有什麼關係? 我以為政客們講的居住正義是讓沒房子的人有房子。這樣看來也不是囉~

所以說「居住正義」是要讓人不要買到過高的價格,因為有了前幾手的實質銷售價,所以新買家就可以相信自己花了錢買房子比較踏實,因為新的買價與舊的賣價差不多,也因為差不多,所以沒人會覺得自己被賣家給騙了。問題是用 565 元買盈正的人,他前一天看到的價格是 100 元嗎? 也是 500 元左右,價格兩者是差不多呀! 那現在它的價格是 56 元,您會覺得他被騙了嗎? 所以公開透明的價格也不見得讓買家在日後相信他的買價是公正合理的,那作這件事幹什麼!

我惟一想到的是為未來「實價課稅」作好打底工作。可是內政部長又說「沒有配套措施前,它不會作為課稅基礎」。這樣我就不知道這種「緩兵之計」到底有沒有用。

基本上,我贊成「實價課稅」,然而這是為了「租稅正義」,而不是「居住正義」,講到這裡,我還是不懂「居住正義」是用來幹麼的? 要保障每個人有房子住嗎? 人民公社就是啦! 怎麼不用? 美國也是「實價登錄」、「實價課稅」的,然而還不是有次貸,那些買了房子的人會說:「當初我就是靠實價才買到好房子的」嗎?  拿「實價登錄」、「實價課稅」來求「居住正義」,那真是笨蛋作的事。而我不懂的是臺灣怎麼那麼多笨蛋,讓我也跟著變笨了。

擁有房子不見得是每個國民的目標,政府也不應該強求每個人民要擁有房屋,只要作到「第十條 人民有居住及遷徙之自由」就夠了,但政府該強迫人民履行義務:
  • 第十九條 人民有依法律納稅之義務。
  • 第二十條 人民有依法律服兵役之義務。
  • 第二十一條 人民有受國民教育之權利與義務。
因為國民教育、兵役我都盡過義務了,所以我未來的重點是在納稅,公平合理的稅制是我關心政府事務的重要指標。

之前我在「政治文」:政府如何因應房地產價格急速上漲問題中,提到林英彥教授認為可將土增稅的課稅依據從公告地價改為交易實價,這樣可收到「土地交易所得稅」的效果,又避免修改稅法的冗長。

之前我也認為此法可行,但仔細看過土增稅相關條例後,我發現它並沒有資本利損的機制,也就是說,如果當年度我在股票利得、薪資上大有斬獲,但房產交易卻大賠的情況下,我無法使用房產損失來減免股票利得、薪資上的收入。那這種租稅制度就不合理了。

解鈴還需繫鈴人,法是立委們殺的,就得由他們救。

奇怪,為什麼我從一開始討論土地交易利得稅跳到證券交易所得稅呢? 這不會跳很大嗎? 原因就在於自中華民國建國以來,我們從未有過「土地交易利得稅」,你說土地增值稅不是嗎? 我說當然不是,因為它沒有「資本利損」的概念,自然就不是完整的「資本利得稅」,如果我們要把土增稅改成照實價課稅且具有「資本利得稅」的概念,我認為這一步很難。但「證所稅」是我們本來有的,只是後來被立委們殺了,所以如果能先復原「證所稅」,再把「課徵證所稅」這種具「資本利得稅」的經驗套用在「土地交易所得稅」上,會比較不動搖國本。

最後我想說的是:『中文真是博大精深呀! 文章標題的『狗屎』到底指的是「居住正義與實價登錄」,還是「我的看法」。請自己想著辦,我絕不會跟您說答案。』

2011年12月1日 星期四

人才,真是人才呀!


低收入者不宜進入股市」這一番話雖沒有一百分,也有九十八分了。

差了兩分是什麼? 那就是對低收入者而言,根本的重點不在金融投資,而是人力資本投資,所以不管風險有多低的投資工具,都不適合「低收入者」。

他個人的「納財瓶頸」是在自身的工作能力上,那怎麼有人還會想要去外求別的「理想投資工具」呢! 改善自己的工作能力才是第一重要的。

相較之下,其他人只會說台灣股市本益比很低,股價很委屈,只知道宣傳好投資標的,卻沒有提醒大家,一檔好股票不是對每個人來說都是好股票,要先考慮自身條件作好資產配置後,才可以決定要買那些委屈的股票。

這我覺得對岸的人才,真的是有學過「投資」。

2011年11月25日 星期五

請捐錢給維基百科(2011年)

除了熱情人士貢獻詞條外,也需要有人貢獻「頻寬」、「伺服器」、「審查詞條編輯」的資源。與「詞條」一樣,資源不會憑空產生。總要有人拿錢去拉專線、組裝伺服器,處理法律問題…

以往,我都是捐 $5 塊美金。今年他們有新的捐款管道,提供永豐銀行的帳戶,所以可以直接捐新台幣。為慶祝新管道(這又是一個要花人力的地方,總要有人去談新台幣款項與 wikipedia 組識的出入方法吧!),所以今年我捐了 NT $600 ,是用 WebATM 轉的。用銀行轉帳的方式,對 wikipedia 最好,它們不會被扣手續費。

前往捐款

使用 bank transfer 時,它會給你一組代碼,是讓你去轉帳時(臨櫃、 WebATM 都行)填到附註欄用的。

另外,捐款後有一個附加好處,它們不知道是用 cookie 還是 IP 方式? 讓有捐過錢的人,看不到「捐款呼籲」。

2011年11月19日 星期六

相較於「不動產現貨投資」,我個人更偏好「REIT」或「REAT」

REAT(Real Estate Asset Trust)的本質像債券,買入後是有固定收益的。但投資金檻高,單筆須有幾百萬,這個我買不起,就此打住,待我以後每秒幾十萬上下再說。

REIT(Real Estate Investment Trust)的本質像股票,REIT的管理機構就像是一家物業管理公司,它的營收就是來自大樓的租金收入。在扣除管理費用後,剩下的就分配給收益人。

2011年11月6日 星期日

難怪公司可以搞到快倒了!!!

自從去年比完台東之美鐵人三項後,到現在沒去游過泳。所以今年也就沒參加台東之美鐵人三項了。

雖然對游泳還有些餘悸,但跑步可是沒放下。難得今年南投縣為慶祝建國一百年(或是刺激觀光)辦了 2011 中潭馬拉松。我住南投,當然是要助陣一下。順便也拖了老婆一起去,只是她報的是健康 5 K。
2011 中潭馬拉松報名網頁
但這個報名網站寫得 2266 。不過是個填寫資料的 PHP 網頁,也限定要用 IE 瀏覽器,茂德( ProMOS )真是沒人才了。本來我還以為是這個網站的金流用了 WebATM ,所以不限定 IE 不行,等我真的用了 IE 報完名後,才發現還是得自己去 ATM/臨櫃/WebATM 轉帳,那你他媽的限我用 IE 幹麼!!!

看了網頁中的 javascript 程式碼,發現都是原始 javascript 碼,沒用任何高級函式庫,我這才發現原來茂德的 PHP 工程師喜歡手工打造,或許這還是他們的企業文化 => 純手工打造。

這難怪茂德作到下櫃了。他們的 DRAM 說不定是用人工焊接的呢?

可笑、可笑,虧我還是茂德股東,真想把它賣了,但它下櫃了,沒得賣。神呀! 為什麼不讓我早發現他們的網頁設計技巧呀!

2011年10月7日 星期五

jobs dead,而賈伯斯是英雄嗎?

很多人說他是英雄、領袖、偉大發明家… ,昨晚看新聞時,大約有五分之四的內容與他有關,雖然還輸給蔣故總統經國先生,但對不是美國人的我們來說,算很多了。

jobs 是不是英雄? 在我年紀小的時候當然是,但現在我可不確定了。

手邊拿起一本 2000 年出版的「 i蘋果」,書末結尾停留在 Apple Computer Inc. 發表 iMac 的年代,它的結語:「無論結局如何,這個世界都應該感謝蘋果的貢獻。它是資訊時代勇敢、或可說莽撞的開路先鋒。它驕傲地扛著這個破曉時代的旗幟,如此嶄新、如此令人興奮,為今日我們視為理所當然的科技革新鋪平了道路。蘋果的故事正在頹敗,將成為美國企業界中最奇特、也最悲哀的故事之一。但無論蘋果的主管有多麼拙劣,都無法磨滅蘋果在歷史上的地位。」

我記得某一年跟舅舅聊股票時,講到:「未來搞不好是蘋果打敗微軟,人們對科技的需求不見得一直是相同的,微軟靠軟體起家,但將來或許軟硬一體成型的產品才是大家想要的。」那時,我記得蘋果股價才 3 塊。

剛剛查了 Google Finance :



3 塊多的股價大概是在 1997 年,也差不多是我大學時代的事。與我開始買股票的經驗相仿,不過 i蘋果一書,卻說 1997 左右,它的股價在 16 塊附近,這我就不懂了。不知道是誰對。

其實經過 10 多年,記憶這檔事就不見得準確了,尤其我的記憶力不好(PS 理解力超棒)。舊記憶在新事件發生後可能被遺忘、可能被重設。搞不好,當年我對舅舅講的可能只是:「現在蘋果這麼便宜,只要 3 塊,但它早期是比微軟好的,或許將來它也能再次比微軟貴。」

不管真相是那種,但我知道就算當年有能力去美國買蘋果電腦股票,我也沒機會賺到這近 100 倍的報酬率。因為 3 塊錢買,我 5 塊錢賣掉它就非常非常高興,那有可能放了 14 年等它賺到這 100 倍的報酬率。會這麼作的人,只有被動投資人

而 jobs 到底是不是英雄? 從 2000 年左右的觀點看來,是跟現在差很大地。所以英雄得靠緣份,沒那機遇,就沒那表現。這也得倚賴他現在就結束傳奇的一生,如果再過 15 年,會不會他就跟 bill 一樣跑去玩基金會,不管 M$ 了?

年輕時我欣賞 jobs ,完全是因為我不喜歡跟風,當時大家都喜歡 bill gates ,那我偏不要,我就愛 jobs 。這風格不只表現在股票選購上,也表現在就讀科系上,也表現在書藉選讀上,太多地方我是不愛跟多數人選擇相同的。

而年紀小時,覺得這個世界的運轉一定是由某些大人物主導的,沒這些人地球就不會動了。長大後,才慢慢體會一日之所需,百工斯為備不只發生在日常生活中,這些大人物的決策也少不了其他小人物的準備,所謂的「英雄」不過是「你懶得記住所有人的名字,挑大頭名字來記得較輕鬆簡單」的替代品。

我相信 iOS 的程式碼沒一行是 jobs 寫的(或許我講得太死了,搞不好,他的確寫了一行 hello world! ),我相信 iPhone 觸控螢幕的面板沒有任何一片是 jobs 裝的、他從沒作過任何一部 iXXX 廣告片美編... ,是的,雖然他也作了不少事,但整個 i 系列產品應是很多人的功勞。

現在他過逝了, iPhone 4S 還不是照出貨,我相信 iPhone 5 也是,但 iPhone 6 就不見得了。時代在變,另一組人馬可能就崛起了。這不過是另一個生存者誤差的故事。

想想 IBM ,想想 Apple Computer,想想 Microsoft ,又想想 Apple 就知道了,或許以後你們想的是 Ho600 。

== 後記 ==

蘋果在 1997 年的股價的確應在 16 塊左右。因為 AAPL 作了兩次股票分割, 1 股變 4 股,而 Google Finance 會依權值重算舊價格,所以原本應該是 16 塊的東西,就變成 4 塊錢了。那表示我現在所記得 3 塊多可能就是被 Google finance 給重設了。

2011年10月1日 星期六

另一種解鋼筋切割組合問題(無界背包問題)的方法(改自 thinker 所提觀念)


#!/usr/bin/env python
# -*- coding: utf8 -*-
""" cut(10, [7, 5, 3, 2]) = cut(3, [7, 5, 3, 2]) + cut(10, [5, 3, 2])
"""
def _plus1(a):
a[0] += 1
return a


def _cache(my_function):
CACHE = {}
def inner_function(*args):
key = str(args[:])
if not CACHE.get(key, None):
CACHE[key] = my_function(*args)
return CACHE[key]

return inner_function


@_cache
def cut(total, sizes):
propers = tuple([sz for sz in sizes if sz <= total])
if len(propers) == 1:
return [[0,]*(len(sizes)-len(propers))+[total/propers[0],],]
elif not propers:
if total < 0:
return []
else:
return [[0,]*len(sizes),]

result1 = [_plus1(a) for a in cut(total-sizes[0], sizes)]
result2 = [[0, ]+a for a in cut(total, sizes[1:])]
return result1 + result2


if __name__ == '__main__':
from time import time

bar = 10
sizes = [7, 5, 3, 2]

t0 = time()
answer = cut(bar, sizes)
print time() - t0

print 'count: %s'%len(answer)
#for a in answer:
# print a, sum([j*sizes[i] for i, j in enumerate(a)])


其計算邏輯是 cut(10, [7, 5, 3, 2]) = cut(3, [7, 5, 3, 2]) + cut(10, [5, 3, 2]) ,這觀念從 Thinker 那邊學來的,它用在計算 cut(10, [7, 5, 3, 2]) 的組合數有多少時,非常非常快,不過,我在擴充至求組合數有那些時,這方法的速度就比不上 cut(10, [7, 5, 3, 2]) = (cut(10, [5, 3, 2]) 的結果,其元素 0 插入 0) + (cut(3, [5, 3, 2]) 的結果,其元素 0 插入 1) 了。

不曉得是不是我在運算過程中,那裡少了優化?

2011 被動投資回顧

這麼 2011 年還沒結束,我就在作回顧呢?

因為配息已經告一個尾聲了,今年就算再買股票,也拿不到利息了。

從我 2008 年建立 56 支股票投資名單後,到現在 2011 年了,名單也增加到近 200 支股票(當然還沒買全),每年所拿到現金利息(含扣抵稅額)除以總投資本金後,大約如下:

2009: 3%
2010: 3.6%
2011: 5%(以 17% 扣抵稅率試算)

而平均購買成本約在 6378 點左右。回想起 4 年前,馬總統當選,我花了 4 萬 5 買了合庫、日月光、雷虎。從 9300 點開始一路買到 4000 點,再買到 9100 點,到現在的 7200 點。這平均持股成本在 6378 ,實在讓我非常滿意。

事實上,我有印象以來的持股成本應該是在 6700 左右才是,怎麼我在 7000 點以上繼續買進,這平均成本反而下降了呢?

原因就是除權、除息,就像開發工銀手上擁有的聯電,每股不到 3 元一樣,經過時間的發酵,聯電公司馬不停蹄的賺錢後,讓開發工銀手上握有的成本愈來愈低。

而且我覺得我運氣很好(真的嗎? 沒把年化報酬率算出來跟大盤比,這都只是感覺而已),手上不小心有了宏達電、統一超(當然都是零股啦),一個有 300%+ ,一個有 250%+ 的報酬率,而踩到的地雷也只有力晶(-66%)、茂德(-90%)、盈正(-75%),還好它們的投資比率都不高。

經過這 3 年多來施行被動投資策略的成果來看,我十分滿意。當股票漲,我高興,當股票跌,我也高興(當然是有錢買才高興,還好我年輕有工作作,能賺錢買股票),無處不怡然自得呀!

你被動了嗎?

2011年9月16日 星期五

再改寫「背包問題」的求解程式碼

之前的作法是將 cut 函式所計算的 list 結果直接 append 到全域變數 tmps 中,這樣的 cut 函式是無法作 decorator 的。

新方法則是把 cut 函式的 input, output 重新規劃,讓答案就是 return 值,這樣 input 就能對應到單一 output ,透過這個特性,我們就能加上一個 @cache decorator ,去作快取。因為在求解的過程中,勢必會遇到重覆的 input ,有了快取,可以少算一次。

其中的 _no_cache_count 值指的是第一次遇到的 input 值,而 _cache_count 值則是利用 dictionary 找到答案的次數。

要怎麼建構出 cut 函式的樣貌? 我們一開始先抽象地想像這個 cut 函式要作到的事就是 answer = cut(bar, sizes)

answer 是我們要的答案,結構是 list of list( [[ , , , ..], [ , , , ..], ..] )。而 bar 是原長度, sizes 則是需求尺寸的 list 。

假設我們帶 bar = 10, sizes = [7, 5, 3, 2] ,那麼經過 cut 運算,就能得到一個 list of list 的 answer,那到底 answer 是多少? 我們先不管。但我們可以知道 10 拿給 7 去切,可以得到 0, 1 兩種組合。

所以 cut(10, [7, 5, 3, 2]) 一定會等於 cut(10, [5, 3, 2]) 的結果其解全部在元素 0 的位置插入 0 + cut(3, [5, 3, 2]) 的結果其解全部在元素 0 的位置插入 1 。

一樣地, cut(10, [5, 3, 2]) 也會等於 cut(10, [3, 2]) 的結果其解全部在元素 0 的位置插入 0 + cut(5, [3, 2]) 的結果其解全部在元素 0 的位置插入 1 + cut(0, [3, 2]) 的結果其解全部在元素 0 的位置插入 2 。

直到 cut(10, [2]) 時,我們知道它的結果就是 ([5], ) ,為什麼是一個 tuple of list ? 因為之前我們就定義 cut 一定要回傳 list of list ,而因為這次的 cut 回傳值本身並不會被修改,所以傳個 tuple 回去,可以少用一滴滴的記憶體(應該是一滴滴而已)。

當開始有 answer 被回傳後,我們就開始作合併的工作(就是把前一個需求尺寸的用量插入 answer 內的 list)。合併後再回傳。

程式碼如下,不過在實際跑的時候,有二件事我不能理解,為了比較 cut 與 cache_cut 的效率差別,我在同一個行程上分別跑了兩次 cut, 兩次 cache_cut ,而順序是 cache_cut, cut, cut, cache_cut ,cache_cut 比 cut 快,這很容易理解,但第二次的 cut 居然會比第一次的 cut 還慢,這我就不懂了。

另外,我每次跑 cut 之前,都是用 cs = CutSteel(bar, sizes) 創建新的物件,為什麼第二次跑的 cache_cut ,它還是可以找到第一次 cache_cut 所儲存的 CACHE 呢?

最後,我還得到一個結論,當解答組合數不多時,用 cut 會比 cache_cut 快。因為小題目,遇到重覆 input 少,但如果還是全部的 input 要儲存 CACHE ,那所花費的時間還不夠重覆 input 所節省的時間了。


1 #!/usr/bin/env python
2 # -*- coding: utf8 -*-
3 import types
4
5
6
7 class CutSteel:
8 u""" 目的:解鋼筋切割的組合問題(也就是背包問題),但不只是求組合數,
9 也要把所有的組合列出。
10 例: 10 公尺長的鋼筋,要切成 7, 5, 3, 2 公尺等,有多少種組合。
11 解:
12 7 5 3 2
13 [1, 0, 1, 0]
14 [1, 0, 0, 1]
15 [0, 2, 0, 0]
16 [0, 1, 1, 1]
17 [0, 1, 0, 2]
18 [0, 0, 3, 0]
19 [0, 0, 2, 2]
20 [0, 0, 1, 3]
21 [0, 0, 0, 5]
22 """
23 def __init__(self, bar, sizes):
24 if type(bar) != types.IntType or bar <= 0:
25 raise ValueError(u'只接受正整數')
26 for s in sizes:
27 if type(s) != types.IntType or s <= 0:
28 raise ValueError(u'只接受正整數')
29
30 self._no_cache_count = 0
31 self._cache_count = 0
32
33
34 def cache(my_function):
35 CACHE = {}
36 def inner_function(*args):
37 key = str(args[1:])
38
39 # try:
40 # #INFO 用 try 的會比 if 慢一點點。只慢一點點。
41 # CACHE[key]
42 # args[0]._cache_count += 1
43 # except KeyError:
44 # args[0]._no_cache_count += 1
45 # CACHE[key] = my_function(*args)
46
47 if not CACHE.get(key, None):
48 CACHE[key] = my_function(*args)
49 args[0]._no_cache_count += 1
50 else:
51 args[0]._cache_count += 1
52 return CACHE[key]
53
54 return inner_function
55
56
57 @cache
58 def bag(self, total, sizes):
59 u""" 只計算組合數 from thinker"""
60 propers = tuple([sz for sz in sizes if sz <= total])
61 if not propers:
62 if total >= self._minsize: return 0
63 else: return 1
64
65 num = self.bag(total - propers[0], propers) + self.bag(total, propers[1:])
66 return num
67
68
69 def cut(self, total, sizes):
70 u""" 本函式的 input 為「被切割長度」及「欲切割的種數」。
71
72 output 為該 input 的所有組合。
73 """
74 if len(sizes) == 1:
75 return (
76 [(total / sizes[0]), ],
77 )
78 elif total < sizes[-1]:
79 return (
80 [0,] * len(sizes),
81 )
82
83 return [
84 [j] + tr
85 for j in xrange(0, total / sizes[0] + 1)
86 for tr in self.cut(total - sizes[0] * j, sizes[1:])
87 ]
88
89
90 @cache
91 def cache_cut(self, total, sizes):
92 u""" 因為 cache_cut 函式本身是具有固定 input 就會產生固定 output ,
93 它們具有一對一或多對一的關係,所以我把 input,
94 output 放在一個 dictionary 中,若程式計算到相同的 input 時,
95 可免計算,直接從 dictionary 拿答案。
96
97 其實本函式就是複製 cut 函式後,
98 將函式內程式碼中的 self.cut 改成 self.cache_cut ,
99 並在函式名前加上 @cache 而已。
100 """
101 if len(sizes) == 1:
102 return (
103 [(total / sizes[0]), ],
104 )
105 # elif total < sizes[-1]:
106 # #INFO 多這個判斷式反而變慢了。因為已經用 cache 了,
107 # #所以那些 total < sizes[-1] 情況會變成比較少,
108 # #然而在一個 cache_cut 函式中多加一個 if ,則判斷時間會多一倍,
109 # #加速效果反而不如預期。
110 # return (
111 # [0,] * len(sizes),
112 # )
113
114 return [
115 [j] + tr
116 for j in xrange(0, total / sizes[0] + 1)
117 for tr in self.cache_cut(total - sizes[0] * j, sizes[1:])
118 ]
119
120
121
122 from time import time
123 import sys
124 if __name__ == '__main__':
125 #bar = sys.argv[1:]
126 #sizes = sys.argv[2:]
127 bar = 10
128 sizes = [7, 5, 3, 2]
129 sizes.sort(reverse=True)
130 sizes = tuple(sizes)
131
132 cs = CutSteel(bar, sizes)
133 cs._minsize = min(sizes)
134 print 'Total count: %s' % cs.bag(bar, tuple(sizes))
135
136 cs = CutSteel(bar, sizes)
137 time0 = time()
138 result = cs.cache_cut(bar, sizes)
139 print 'cache_cut spend time: %s' % (time() - time0)
140 print len(result)
141 print('\tno cache count: %s, cache count: %s'%(cs._no_cache_count, cs._cache_count))
142
143 # cs = CutSteel(bar, sizes)
144 # time0 = time()
145 # result = cs.cut(bar, sizes[:])
146 # print 'cut spend time: %s' % (time() - time0)
147 # print len(result)
148 # print('\tno cache count: %s, cache count: %s'%(cs._no_cache_count, cs._cache_count))
149 #
150 # cs = CutSteel(bar, sizes)
151 # time0 = time()
152 # result = cs.cut(bar, sizes[:])
153 # print 'cut spend time: %s' % (time() - time0)
154 # print len(result)
155 # print('\tno cache count: %s, cache count: %s'%(cs._no_cache_count, cs._cache_count))
156 #
157 # cs1 = CutSteel(bar, sizes)
158 # time0 = time()
159 # result = cs1.cache_cut(bar, sizes[:])
160 # print 'cache_cut spend time: %s' % (time() - time0)
161 # print len(result)
162 # print('\tno cache count: %s, cache count: %s'%(cs._no_cache_count, cs._cache_count))
163
164 for i in xrange(0, len(result)):
165 print(result[len(result)-i-1])

2011年9月12日 星期一

賽德克‧巴萊觀前感 - 談第一、二次霧社事件及抗日那些事

聲明: 既然是觀前感,就表示我還沒看過電影,所以本文不是談魏導演的手法及電影優劣,只是要談談它的背景故事,請不要拿本篇文章結論來當作該看或不看電影的論點。我是一定會去看「賽德克‧巴萊」,為的不是「莫那‧魯道是個英雄,能發揮臺灣人精神」? 而是為了一部花費 7 億打破臺灣電影史紀錄的電影。常看電影的人應該都知道,不是花大錢的電影就比較好看,使錢也是一種門道,我就想看看臺灣導演會不會使錢。

筆者在國史館臺灣文獻館當了二年的替代役,在這個地方工作所得到的好處之一,是打破了我過去對歷史資料來源的迷思。

原來在歷史課本上所看到的內容,是有人在機關公文中尋尋覓覓拼湊出來的,或者是說史料內容除了口述、古籍、文獻、紀要、遺跡…這些外,居然也可以是從前朝機關往來文書中汲取而來,而這種地方來的史料,是很花費功夫的,可能看了涵蓋 2 年期間的數千份公文,卻只找到 2 張圖:「太魯閣族的衣著、紋面情形。」。

從這兩張圖中,我們才知道要重演 1900 年左右的故事時,裡面的人該穿什麼樣的衣服、紋什麼樣的面。當然這是考據史實的拍法,如果不講究,拿塊黑黑紅紅花花的布套上去,我想臺灣也沒多少人會知道這是錯的,或許連現今太魯閣族人也不見得認得出來。因為這是 110 年前的事,服飾花樣會進步,尤其在這 110 年之間,臺灣經歷了兩個統治者,他們無不想抹去大家對前朝的記憶。

既然執政者能依優勢抹去大家對前朝的記憶,所以他們所留下的檔案公文,有些也不盡然是真的,那些公務員擬公文時,也知道這將來會成為證據,所以不該寫的,就不會寫了。我們要研究歷史的話,也得有這份體認,要從多方管道得來資訊,並作交叉驗證。

好了,我總要進入正題了。

在臺灣有讀過書的人,都知道莫那‧魯道是抗日英雄,與他最相關的歷史就是第一次霧社事件。不過,課本沒講的是:「有其他原住民部落帶著日本人一起打賽德克族的德固達雅分支(備份)、之前莫那‧魯道也幫著日本人打泰雅族(備份)以及第二次霧社事件是原住民族彼此相殺」。

為什麼在我們印象中,乃原住民族不滿日本政府的欺壓,起而反抗而來? 怎麼也有其他原住民是站在日本那一邊,甚至連莫那‧魯道也曾跟日本站同一邊。到底他還是不是抗日英雄呢?

他是抗日英雄這件事,其實並不重要,重要的是我們政府希望我們相信這件事,而且起而效尤,這樣才能延續執政權的正當性,是他們讓我們遠離日本暴政,請詳閱這篇格文

要讓人民效尤抗日,就得找個偉人,述說他的事蹟,去除枝節得到純正連貫易消化的故事,讓人民好吸收。這像不像置入性行銷呀! 原來我們政府幾十年前就在作了。

但是撥開那些政治實體的詞語,我們把焦點放在人身上,從這些歷史中,我只看到一群人為了資源,而必須從別人那邊奪取。

像是:「日本在明治維新後,需支應日本社會生活水準提升而效法大英帝國所採取的殖民帝國主義」、「中國越族被中原漢族趕到海峽另一邊而與臺灣平埔族融合」、「原住民服從日本以換取其他原住民族的獵場」。

歷史重覆上演著人類在地球上巧取豪奪資源後,再分配給某一部份人享用的故事。而且結局往往是產業層次較高的社群贏了。

從「槍炮、病菌與鋼鐵」一書得來的觀念:「地理能決定人類社會的優劣(而不是人類基因決定優劣)」,所以在一塊土地上,如果它養成一個國家實體,具有法治、軍隊、領袖的話,那表示其他人種來這塊地,在假以時日後,也同樣發展的了。這個論點,告訴我們如果給 1683 年的臺灣平埔族人、 1930 年的臺灣原住民人更多時間,他們也能同樣發展至現在的產業層次。但是中國越族、漢族來了、日本也人來了,他們被迫學習別人的文化、語言。而現在呢?

現今的臺灣人身上的血液多半都有越族、漢族、平埔族、高山族甚至日本人的血液,你如果把自己定位在「被欺壓的平埔族或是高山族」上,那你如何忽視「越族、漢族」的血源,就像你支持「莫那‧魯道抗日是體現臺灣人精神一樣」,你如何看待那些協助日本的原住民族,而且他們的後代目前多半還住在霧社,是真真實實地存在,難道他們就不是臺灣人嗎? 我不這麼認為。只要是住在臺灣(含澎湖、金門、馬祖、綠島、蘭嶼、小琉球),他就應該是個臺灣人,不須宣誓、不用驗血,簡單講,我採屬地主義。

從資源的角度來看莫那‧魯道,我們就可以了解他之前服從日本但後來卻反抗日本的源由,其實就是讓他的族人們過得好(雖然不是他親口說的,是我以同理心猜想的)。他一開始也知道日本的產業層次高、人數多,反抗只是以卵擊石,豪無勝算,直到後來得罪了日本人,只好用生命來賭一把,不過結果你知道的:「他輸了」。歷史沒法重來,所以我們不知道,如果他當時忍下了,是否還是會被滅族? 很多時候,領袖也不知道該不該作,他只能賭。

如果我們人類社會能朝向與棲地均衝發展,資源有多少就用多少,不用擴張領地來掠奪資源,應該會少了很多殘酷的戰爭。只是這目標作不到,因為「全球化」及「氣候變遷」讓我們很難作到「與棲地均衝發展」。

所以,我想有生之年可能還是會面臨到資源分配不足的事情,唉~ 那該怎麼因應呢? 我還沒想到。還是去看電影吧! 它應該沒那麼難讓人懂。

2011年9月10日 星期六

終於能在臺灣看到 NFL 例行賽轉播

筆者從小就是個不愛運動的小孩,一直覺得這是不動大腦、四肢發達的人才作的事,這個信念一直維持到大一時期。

我在唸大學時,已經是個只愛待在家裡鬼混的小孩,因為高中時大多把該玩的都玩過了。於是,我大學花在第四台的時間還不少,一開始看得當然是電影而已,而 ESPN 很少轉到,直到某天轉到舊金山淘金者的美式足球季後賽。過去只在電影中大略見識過,對其比賽規則當然是不懂,也因筆者對於不懂的事,就愛搞懂,也不管 EPSN 只有原音轉播,反正我就是一邊看一邊猜。看著看著也略知一二,就這樣一路看到 Brett Favre 帶著 Green Bay 拿下 '96 超級盃。

等到美式足球季結束後,我開始另尋它種運動比賽節目,而台灣大聯盟正巧於 '97 正式開打,一開始都是袁定文當球評的,而他剛開始作球評時,花了不少時間在解釋棒球比賽的門道,不像我以前看國際賽時,只專注在國家隊有沒有安打、有沒有得分上。於是,我開始對「運動比賽」改觀了,它不像我所認為的是「四肢發達」的人才搞的玩意,沒有腦袋還真是混不出局面。當時,我對棒球可是深深地著迷,不但看直播,也看重播,有時一場比賽我看了三遍。是的,你猜到了,我大學很少在唸書的。

對「運動」改觀後,我就百無禁忌了,冰球(Hockey)、足球(Soccer)、板球(Cricket)都看,就是不看籃球,因為我不喜歡跟風。甚至,我還買了 '97 NHL 的電腦遊戲,那個老闆還說:「真沒想到,這遊戲會有人買。」

因為袁博士當時也在年代台的 Catch the fever 節目擔任球評轉播美國大聯盟,所以我後來對美國棒球的了解反而比美式足球還深了。

然而,因為袁博士及王建民所帶來的美國職棒熱潮間接地讓 EPSN 臺灣台壓縮了其他球類比賽的預算,使得我看洋基比賽看到吐,也沒什麼機會再看到美式足球例行賽了。

直到今年(2011), ASN 運動台作到了「直播 NFL 例行賽」的服務,使用中華電信 MOD 只要多花 11 塊,就能升級到豪華特餐,這其中包含了 ASN 運動台。

剛剛我在 MOD 上看了 2011 NFL Kickoff 綠灣包裝工 V.S 紐奧良聖徒,喚起了十幾年前的記憶。我想我一定是又老了。

2011年8月18日 星期四

超 MAN 的玩具



它的輪子直徑為 2 公尺,比我還高,可惜我不能貼著它的車輪拍照,會違反他們的工作規則。這台是 Caterpillar 的 773F OFF-HIGHWAY TRUCK,可承載 61 噸的物品,比起國內一般的砂石車承載 20 噸來說,足足有 3 倍之多。

湖山水庫主體是土石壩,需要用到非常多的土石填方,如果用國內最大的砂石車來作運輸,司機得多請 2 倍,或是工期得多出 2 倍,但基地環境不見得能容納 3 倍的運輸車輛,所以會選擇這種重機具。

據管理人員解說,工作人員不得在其後跟車,不然它倒車壓過你後,司機也不見得會發現異樣。

2011年8月5日 星期五

今天(2011-08-05)我有 5.84% 的損失

今天大盤跌了 5.58% ,而我有 5.84% 的損失。多那 0.26% ,當然會不高興。

凱因斯:「投資者有責任週期性地承受損失且不能有絲毫怨言」。大師說的話,那我當然是得吞下來囉,不過得去跑個三圈,流流汗、出出氣。

對長期的被動投資者而已,市場下跌沒什麼了不起,它不跌你怎麼用便宜的價格買股票呢!

我知道有很多朋友,今天心情真的不好。寫這篇文章只是想說:「如果今天的事,讓你吃不下飯、睡不著覺、工作沒擋頭,那請試試『指數投資被動投資』吧!」

過去,我還曾有一天負 7% 的績效,還連了好幾天哩。那是我們的李前總統:「臺灣、中國,一邊一國」的時候,當時,我手上只有巨大,湊巧它還是很紅的中概股,不到一個月,我就被融資斷頭了,那時候,我真的沒睡好覺,也沒讀好書呀!

Google Call +1

現在用 Google Call 就能用網路撥號給市內電話及手機了。

費率目前是市話 0.02美金/分,手機 0.09美金/分,換算台幣大約是 0.6/分 、 2.7/分。其實市話費率與中華電信費率差不多,而長途電話方面,有一點優勢,在手機費率方面則有明顯優勢。

剛剛,我已刷卡儲值 10 美元了。話質感覺不出是網路電話,效果還不錯。

建議各位使用。

=== 後記 ===
今天很驚訝地發現, Google Call 的發話地居然是「中國大陸 - 上海」,奇怪它們不是退出中國了嗎? 還是那個只是合作的電信業者。不過從這點看來,臺灣電信公司的通話費率應該是頗高的,竟然從上海打來的電話,還能收得比中華電信網內互打還便宜。

2011年8月4日 星期四

Connect MS SQL Server with python-pymssql

Two years ago, i writed a blog: "How to connect MS SQL Server with Python in the Linux OS?". I used freetds + python-sybase in this Howto. Now i have to upgrade the linux server to x86_64 architecture(original in i386), then the old python-sybase package have always been failured. The newest version released at 2010 DEC, but i tried all the 39, 38, 36 versions that no one can compile accurately.

Fortunately, my underclassman talked to me about python-pymssql. And it has been packaged in the Ubuntu, so i just use the magic command:

$ sudo apt-get install python-pymssql

My Linux server takes the power back!!!

The usage likes python-sybase, below is the example:


1 #!/usr/bin/env python
2 import sys, datetime, pymssql
3 from types import IntType
4
5 DB = {
6 'ip': '127.0.0.1',
7 'port': '1433',
8 'user': 'user',
9 'password': 'password',
10 'database': 'database',
11 }
12
13 try:
14 Database = pymssql.connect(host=':'.join([DB['ip'], DB['port']]), user=DB['user'], password=DB['password'], database=DB['database'], as_dict=True)
15 except pymssql.OperationalError, msg:
16 print "Could not Connection SQL Server"
17 sys.exit()
18 else:
19 DBCursor = Database.cursor()
20
21 sql = "select * from data_table"
22 print('sql: %s' % sql)
23 DBCursor.execute(sql)
24
25 while 1:
26 row = DBCursor.fetchone()
27 if not row: break
28
29 for k, v in row.items():
30 if type(k) == IntType: continue
31
32 if k.lower() in ('some_date_field', ):
33 # change field type
34 if type(v) == datetime.date:
35 value = v
36 else:
37 try:
38 value = datetime.date(*time.strptime(v, '%Y/%m/%d')[:3])
39 except:
40 value = None
41 else:
42 value = unicode(str(v), 'cp950')
43
44 print('%s => %s'%(k, v))

2011年8月2日 星期二

提高最低工資來強迫企業辭退「工作沒有效率」的勞工

最近股市漲了不少,物價也漲了不少,公務員薪水也漲了不少,所以勞工朋友們也希望「最低工資」能調漲不少

不過,我想不透的是:「明明最低工資調高,應該是對比較弱勢的勞工(勞工們之間的比較)更加不利」,為什麼勞工團體會想出這種方案?

事實上,上面的觀念也不是我想出來的,石頭閒語:淺談基本工資最低工資爭議與個人芻議,這兩篇文章有詳細的介紹,就請各位移駕過去瞧瞧。

雖然石兄在分析模型時,未考慮資本家的利潤,而這部份也是勞工團體所希望的「最低工資差額」來源。不過就「提高基本工資」會「提高失業率」這件事,還是成立的。對老闆而言,當他覺得員工的工作能力不夠格領「最低工資」時,一定是把他們辭退的。屆時,非自願性失業多了,失業率也就高了。

這「最低工資提高」與「公務員加薪」兩者,一邊是企業被迫降低短期利潤,一邊是政府為增加公務員好感,這立足點是不同的,勞工團體拿兩者來比,實是拿芭樂比香蕉呀!

不過,在我看了「葛林斯班的騙局」一書後,有了些修正。

該書作者拉斐,在討論勞工薪資時,把國家稅收及企業利潤一併考慮,所以得到一個結論,當企業營收大部份歸入企業利潤中,而勞工薪資又被國家稅收剝奪一部份後,那麼勞工就比較沒有錢可以去購買其他公司所生產的商品,這樣其他公司的營收會下滑,間接影響其他公司的勞工薪資,所以當大部份的公司給的是比較少的勞工薪資,其實是傷害了自身的利潤。

拉斐也舉了過去美國的經濟數據來實證,當最低工資、企業稅率比較高而個人稅率比較低時,經濟成長率比較大。

所以我相信當全體企業將利潤多分給勞工,雖然營利率會下降,但總利潤值是會提升的。不過,這個結論我認為只適用「美國」,或是說「內需型的國家」。

在臺灣,企業生產的商品多半是外銷,提高國內勞工的最低工資,並不會讓外國人變得有錢,而多買臺灣出產的商品。所以在我們這種重外銷的國家中,「提高最低工資」的確對「經濟成長率」沒有幫助。不過,我還是贊成「提高最低工資」,誠如標題所言,較高的最低工資能間接迫使「工作效率不足(人力資本少)」的勞工沒有工作。

為什麼我這麼不喜歡「工作效率不足(人力資本少)」的勞工呢? 多一個人有工作,可以養活自己,有什麼不好? 我認為這些「工作效率不足(人力資本少)」的勞工對地球是不好的。因為作一樣的事,他們花的電費比較多,廢料率會比較高,出錯率也比較高,這些在在地浪費了地球的資源。所以該讓他們沒有工作。爾後,政府再透過社會教育來提升他們的工作效率。

2011年7月31日 星期日

社會問題根源於家庭、顯現於學校、惡化於社會

標題引自張春興教授在 1991 所著之「現代心理學」。社會問題範圍廣大,包含有:「失業率」、「貧富差距」、「暴力」、「毒品」、「犯罪」…等問題。

而社會問題,我們都可以歸究於「教育」沒作好。誠如標題所言,教育有三環: 家庭教育、學校教育及社會教育。究竟我們該期待什麼樣的教育,才能讓社會更好呢?

昨天看了「等待超人( waiting for Superman )」的紀錄片,片中聚焦於美國的公立學校教育問題,他們希望用好老師來塑造好學校,產生好學生。觀看當時,感覺或許美國公立學校有這樣的問題,但該片是談教育的,卻極少提及家庭、社會兩種層面,一味地猛攻「教師終生聘用制培養爛老師」的論點,不禁有「該片是 KIPP 宣導片」的想法。

果然,今天查了一下相關資訊,得到一篇新聞:「D.C. school official tied to test scores flap resigns」,一位特區學校的校長面臨「學生成績作弊」的指控,已提出辭呈。所以透過「浮動薪資」來提升學生學習成效變得不是那麼正相關。

以「錢」為誘因來鏈結學生成績,讓「學生成績進步」的結果,反應到教師薪資上,雖然附帶了「另一種的效果」。但我相信,為「錢」而作弊的老師是個案,就像在「教師終身聘用制」下,會產生「不會教學但能保有一份工作」的老師,也一樣是個案。

為錢而作弊的老師,也不是在特許學校政策產生下才有的事,從「蘋果橘子經濟學」的第一章:「小學老師與相撲選手有何共通點?」中,就知道芝加哥、加州的公立學校過去也發生這一類的事件。

為討論方便,接下來的學校教育只涉及中小學義務教育。

而我針對教師薪資的看法,則是傾向目前的「固定制」,因為在義務教育中,每個學生繳交的學費都是一樣的,讓教師薪資有所不同時,那他所收受的學生該繳不同等級的學費嗎? 這一點,很難突破觀念吧! 因為教師有教學等級的不同,勢必讓家長、學生有了差別心,那每個人都想選薪資高的老師時,又該如何分配?

義務教育就是得一視同仁,要享有差別的教育品質,請選擇私立學校。

義務教育的目的不在於培養高級知識份子,它只要求學生具備一定的生活知能即可。在這個目標下,只要教師能達成「讓學生具備一定的生活知能」,就能持續獲得工作。

事實上,我個人並不認為學校教育的問題很大,的確好學校、好老師對學生影響不小,但教育三環中,家庭與社會也很重要呀!

那些進 KIPP 學校的學生表現有所提升,有部份的原因就是家庭期待較高,既然家庭期待高,也就推動他們自我學習的動機,而「主動學習」是教育成功的第一要點。

我對父母將子女的學習成就建立在好學校、好老師身上,十分不以為然。從這次北北基二次分發事件,就可以知道大家十分在乎唸的是什麼學校。但好學校、好老師就能創造你的好人生嗎? 這麼說吧! 如果你的人生過得糟透了,你是該怪自己還是老師? 又如果你的人生過得美極了,你會感謝老師還是自己?

時常聽到有人抱怨企業或社會要的東西,學校老師卻不教。但說實在話,要當一個水果賣場服務生,遲早總會遇到客戶推了一車商品來結帳,如果老師上課只教過 3 顆 50 元的蘋果加上 12 顆 10 元等於 270 元的題目,那他的結帳金額會一直都是 270 元嗎? 這不可能吧! 所以當我聽到這種抱怨時,會直接認定抱怨的人是個笨蛋。

「如何閱讀一本書」中提到「閱讀越主動,效果越好」,而我喜歡把它改成「學習越主動,效果越好」,也因此你可以認定「學校老師」教得不好(未達到你的高標,但理論上都是符合大家的均標),教得不對,而選擇「自己學習」。這時,你有學校圖書館或社區圖書館能使用,可以參與知識性社團與別人互動。而不是坐而等待老師變好,我個人覺得只要是從師專、師院、師大、師資班畢業的老師,其教學能力不會連國中生都教不好,會教不好,通常是因為我們要音樂老師去教數學、國文老師去教自然或是美術老師去教英文所造成的。

主動學習除了可以是天生造成的,後天的話則需透過「家庭教育」、「學校教育」及「社會教育」來培養。父母有沒有讓孩子體會「主動學習」是件有意義的事,學校有沒有讓孩子發現「主動學習」的效果,社會有沒有讓孩子了解「主動學習」的必要

就家庭教育來說,「蘋果橘子經濟學」一書有提到什麼樣的父母對小孩的學習成就有影響:

1. 父母教育程度高(正相關)
2. 父母社經地位高(正相關)
3. 母親生第一胎時三十歲以上(正相關)
4. 小孩出生時體重偏低(負相關)
5. 父母在家中說英語(正相關)
6. 小孩為領養(負相關)
7. 父母與學校家長會(正相關)
8. 家裡有很多書(正相關)

其中, 1、2、3、7、8 多半與學習有關,像是父母自己的學習程度、因為受高等教育導致生育年齡高、關心學童的學習情形及願意投資在學習(買書)上面。

該書中也說明了父母會唸書給小孩子聽及常帶他們上圖書館、博物館是與孩子學習成就”“”無相關“”“的。

所以如果父母本身能表現出他對學習的看重及確實實踐學習,那麼小孩的學習成就高是可預見的。

我家的書櫃中,可看到我書不少,那個是 2009 的相片,現在應該又多了 30 ~ 40 本吧! 不過,我爸的書櫃可是我的 2~3 倍,那還是十幾年前的事。從小就常看他在看書,也很喜歡跟我講法律的話題,有次還得意洋洋跟我分享附近街道上多了紅綠燈是因為他寫公文給公所建議的。他總是跟我說:「法律是給懂的人用的」。

如果真心期待小孩的學習成就高,也請把自己的學習能力拿出來吧! 不要口頭上,一直叫小孩讀書、讀書,自己卻不翻書來看。

然而上面所說的方式卻無法協助弱勢族群脫貧,大部份是因為他們的父母教育程度低、社經地位低,也可能讀不太懂書,或是工時長無法花費心力在學習上。

這時社會教育就該出現了,一個人無法在有工作,能養活自己的情況下,還另外保有空閒時間來學習,這代表他的工作效率或是人力資本太低了,政府應該禁止這種人工作(也就是透過「提高基本工資」來強迫他們被辭退),並強迫他去上有薪給之訓練課程,提升他的人力資本。提高人力資本後,除了可養活自己外,還能有時間自我進修,這才真正有機會脫貧,也能給孩子建立主動學習的榜樣。

= 後記 =

原來比爾蓋茲大力宣傳「等待超人」,我果然跟他是不對盤。

2011年6月11日 星期六

Install Python2.5 on Ubuntu 11.04 x86_64 for Google App Engine

之前所提的「Install Python2.5 on Ubuntu 10.04 i386 for Google App Engine」,主要是在 i386 Ubuntu 的安裝方式。我這一次換了電腦,也裝了 Ubuntu 11.04 amd64 的版本,所以安裝方式有些許不同:

1. 系統內建的 sqlite 函式庫無法連結。
2. 某些 .so 檔不再放在 /usr/lib ,而是在 /usr/lib32, /usr/lib64, /usr/lib/x86_64-linux-gnu 等地。

另外在安裝 python2.5 時,也想順便套上 readline 及 ipython 。以下是安裝過程:

先裝上 Ubuntu 內建的函式庫:

$ apt-get install liblcms1-dev zlib1g-dev libfreetype6-dev libjpeg62-dev libsqlite3-dev libssl-dev tk-dev libreadline-dev

安裝 sqlite3:

$ cd sqlite-autoconf-3070603/
$ ./configure --prefix=/usr/local/sqlite3 --enable-readline --enable-threadsafe --enable-dynamic-extensions
$ make && sudo make install

安裝 Python2.5.6:

$ cd Python2.5.6/
$ ./configure --prefix=/usr/local/python25 --with-zlib -with-zlib-library=/usr/lib/x86_64-linux-gnu --with-zlib-include=/usr/include --with-tk --with-tk-library=/usr/lib32 --with-tk-include=/usr/include --with-tcl --with-tcl-library=/usr/lib32 --with-tcl-include=/usr/include --libdir=/usr/local/sqlite3/lib --includedir=/usr/local/sqlite3/include --with-freetype2 --with-jpeg --with-readline
$ make && sudo make install

安裝 ipython

$ cd ipython/
$ sudo /usr/local/python25/bin/python2.5 setup.py install

安裝 GAE 相依模組 ipaddr:

$ cd ipaddr-2.1.1/
$ sudo /usr/local/python25/bin/python2.5 setup.py install

安裝 GAE 相依模組 python-ssl:

$ cd python-ssl-1.15/
$ cp -rf ../Python2.5.6/Include/* /usr/local/python25/include/ # 需要 Python 源碼
$ sudo /usr/local/python25/bin/python2.5 setup.py install

安裝 PIL:

修改 Imaging-1.1.7/setup.py 中的參數如下:

TCL_ROOT = '/usr/lib32'
JPEG_ROOT = '/usr/lib32'
ZLIB_ROOT = '/usr/lib/x86_64-linux-gnu/'
TIFF_ROOT = '/usr/lib32'
FREETYPE_ROOT = '/usr/lib32'
LCMS_ROOT = '/usr/lib32'

檢查模組是否可使用

$ /usr/local/bin/python2.5 setup.py build_ext -i

測試模組

$ /usr/local/bin/python2.5 selftest.py

看到如下訊息,就代表模組皆有支援

 --- PIL CORE support ok
 --- TKINTER support ok
 --- JPEG support not installed
 --- ZLIB (PNG/ZIP) support not installed
 --- FREETYPE2 support ok
 --- LITTLECMS support ok

再執行

$ sudo /usr/local/python25/bin/python2.5 setup.py install

最後,再把 dev_appserver.py, appcfg.py 中的 #!/usr/bin/env python 改成 #!/usr/bin/env python2.5 即可(也不是必須的,只要你知道執行 GAE server 時是用 python2.5 就夠了)。

完成後就可以在 Ubuntu 11.04+ x86_64 中開發 GAE 程式了。

2011年6月10日 星期五

「股票隨便買然後長抱」是會賺錢? 就跟擲銅板的玩法一樣!

學弟一直不相信我說的:「現在有閒錢(也就是說別拿學費來買),就是買股票,買什麼? 0050 ! 因為他們現在只能存小錢,所以現在買 0050 的零股就夠了。等到湊成 20 萬以上,再來股票市場中隨便買(註1),好公司也買,爛公司也買,類別愈多,家數愈多,這人生的金融投資策略也就夠了。」

學弟為什麼不相信呢? 我想是這個方法太簡單了,不用分析公司基本面,不用知道它們是幹什麼的,不看技術線型,這對我們『愛研究』的研究生來說,太沒挑戰性了,而且這樣買股票都能賺錢,實在太沒天理了。

但是我在唸大學時,可是廢寢忘食地研究公司基本面,研究技術線型,搞到後來,自己覺得都可以去考證券/期貨營業員執照了,結果還是把錢賠光光,這難道有天理嗎?

2011年4月23日 星期六

使用「公認機構簽核公錀」所發生的不知名問題

How to get a free HTTPS web certification authority by StartSSL.com 一文中,我申請了 A.hoamon.info 的公錀簽核,也正確地跑在 https 上,在使用瀏覽器觀看時,完全沒有問題。然而在 hg 軟體上,卻會發生 SSL: Server certificate verify failed. 的錯誤訊息,從 Mercurial on Windows vs Linux, spot the problem 一文中,作者解釋是 Windows 的 ssl 版本太舊的原因,但照他的解決方案處理,我的 hg 軟體卻是報 URLError. 錯誤。

後來在檢查 apache.conf 時發現,這台機器有三個 https 站台,一個是用 A.hoamn.info 的公錀,另外兩個 B, C 站台卻都是用 whatever.hoamon.info 的公錀。而 B, C 站台的設定檔寫得比 A.hoamon.info 站台還前面。所以試著調動 A.hoamon.info 到 B, C 站台設定的前面,結果 hg 軟體就正常了。

問題是解決了,但我反而混亂了。印象中, https 協定中,公錀是在 IP 層(或表現層,我不確定)就發送至使用者的瀏覽器,既然沒到應用層,則網頁伺服器就不知道該拿那一個虛擬站台的公錀給使用者,於是它總是拿第一個看到的公錀(也就是寫在最前面的),所以這篇教學文章,才會寫到:「…一個 Apache ,也只能架一個 SSL 站,用一個站名。除非妳跑很多份 Apache ,各自跑在不 同的 IP 或不同的 TCP 埠上,才能在同一臺伺服 器上,跑好幾個 SSL 站。」

實際上,在 Windows XP 的 IE, Safari 上觀看 A, B, C 三個站台,也的確都是拿到 A.hoamon.info 的公錀。但在 Chrome, Firefox 上,卻是看到 A 用 A.hoamon.info ,但 B, C 用的是 whatever.hoamon.info 的公錀。

這我頭大了,為什麼跟基本原理不一樣??? 還是因為某些瀏覽器有「重拿公錀的機制」存在???

破了我個人的紀錄: 以 59 分 58 秒完成 10 公里路跑

今天(2011-04-23),第一次在 60 分鐘內跑完了 10 公里。

最大的不同在於使用小跨步的跑法,雖然步頻要加快,心跳數也比大跨步高(* 1)。不過,對肌肉而言比較輕鬆,所以在尾段時,還能用更快速度前進。

註1 使用 ALATECH 的心率計觀察每分鐘心跳數。

2011年4月17日 星期日

How to get a free HTTPS web certification authority by StartSSL.com

一般在上網時,所用的 Http 協定是明碼的,使用者與網站伺服器之間的任何網路結點(閘道器)都有方法可以看到網路連線所傳遞的訊息,所以如果網站所提供的服務關係到機密(隱私)資料時,我都會讓網站用 Https 加密協定服務。

使用 Https 服務時,有一個重要觀念: 如何拒絕「中間人攻擊」。

假想一個以 Https 加密協定服務的 A 網站,在它與使用者傳遞公錀(加密憑證)時,是被一個中間人接走,而中間人再把它自己的公錀傳遞給使用者,結果使用者傻傻地使用中間人的公錀加密,再把加密資訊傳到中間人,而中間人用自己的私錀解密後,再用 A 網站公錀加密傳回 A 網站,在這個模式,雖然使用的是 Https 協定,但資料還是被中間人看光光了。

所以要防止此類攻擊,就必須讓使用者能「確認」公錀真的是 A 網站的。方法是使用者自己手頭上要有一些公認機構所發行的公錀憑證(一般的瀏覽器都已經包入),然後在拿到 A 網站的公錀憑證時,用手頭上已有的公認機構公錀憑證去驗證這個 A 網站的公錀憑證是否被這些公認機構簽核過,如果有,則表示公錀的確就是 A 網站的,當使用者用這把公錀加密時,就只能被 A 網站解密。

本篇文章的目的是站在 A 網站的立場上,如何將 A 網站的公錀交給公認機構作簽核,這樣使用者在瀏覽 A 網站時,才不會跳出一個警示視窗告知使用者:「 A 網站有安全疑慮」。

一般將公錀交給公認機構去作簽核是要花錢的,像是國內最大的簽證公司(我猜的)網際威信最便宜的簽核年費是 18000 元。這筆費用不是每個人願意負擔的,像是我的 https 網站,主要是提供我們團隊作專案管理之用,也就不到 10 位的使用者,要我花 18000 元,去買一個「讓使用者在一年之內不會看到該網站有安全疑慮」的警告訊息,這我可花不下手。

所幸,有公認機構了解這種需求,它以「給非商業網站一年免費」作廣告宣傳,如果有更高級的簽核需求,它才額外收費。那麼以我上述所要的,其實就拿那個「一年免費」用用即可。

首先請使用 Firefox (它們目前不支援 Chrome)去瀏覽 http://www.startssl.com/ ,並點選右上角的錀匙圖示,如下圖:


就能看到 Sign-up 按鈕,如下圖:



按下 Sign-up 按鈕就開始註冊帳戶的流程,整個公錀簽核的程序分成三個階段:
  1. 註冊帳戶
  2. 驗證網址
  3. 公錀簽核
1. 註冊帳戶時, startssl 會給你的瀏覽器一個全新的公私錀檔,這個公私錀檔是專供你的帳戶使用的,這個公私錀檔要好好保管,搞丟了,你就不能再用這個帳戶申請簽核的動作,因為它的登入不是用帳號密碼作登入機制,而是用公私錀作登入機制。

2. 驗證網址,你必須證明要作簽核的網址是你所管理的。而這個驗證動作完成後,你也只有 30 天的期限去作簽核它的公錀,過期後,就必須再次驗證網址。

3. 針對已驗證過的網址,你可以申請簽核公錀的動作,主要分兩種作法,一是 startssl 完全生出一把全新的公私錀憑證; 二是我們自己生出私錀及公錀請求檔,再把公錀請求檔交給 startssl 去作出已簽核的公錀。本文是介紹第二種方法,因為私錀應該是自己處理會比較妥當,不要懶惰到連解密錀匙也委託他人製造,我個人認為這種人不只懶還不負責任。

原則上,公錀不過是一個文字檔,所以它在 Linux, Window$, Mac 作業系統下,都能處理,但我個人還是喜歡用 Linux 來作這件事

1. 註冊帳戶:


請填寫你的詳細資料,原則上,他們只採 web 審核,所以只要你的資料不要「太假」,他們都會通過。但如果你要為商業網站申請憑證的話,這就不能開玩笑了,因為你買憑證時,它會要你給護照及身份證、駕照的文件作審核。


請到註冊信箱接受具驗證碼的信。並注意「目前的這個視窗」是不允許關閉的,如果你關閉當下這個網頁,再用相同連結回來,這樣你填寫的驗證碼就算是對的,它也不會通過你的申請。


產生「帳戶」專用的公私錀檔,可選擇 Hign Grade 。


將公私錀檔安裝至瀏覽器上,這裡的公私錀檔是指你的帳戶與 startssl 網站溝通時,所用的公私錀檔,而不是你的網站要用的公錀。


建議你備份這份公私錀檔。


完成後,可見到帳戶頁面。

2. 驗證網址:


我是選擇 Domain Name Validation 方式。


填入網址。


startssl 會從 whois 資料中抓出管理員信箱,所以你必須確認該網址的 whois 內容是正確的。


請到信箱收取驗證碼。並填入上面的 Verification Code 中。


成功後,你只有 30 天的時間,去簽核該網站的公錀檔。

3. 簽核公錀:


公錀可以有很多種用途( Email/XMPP/Object Code ),但目前我只需要 Web 的,所以選擇 Web Server SSL/TLS certificate 。


要使用自己獨立生成的私錀來作簽核公錀的動作,請選擇 Skip 。

欲生成長度為 4096 bits 的私錀檔並使用 des3 格式作私錀加密(密碼長度要大於 4 個字元),請使用如下指令:

# openssl genrsa -des3 -out exmple.com.key 4096
Generating RSA private key, 4096 bit long modulus
................................................................................................................................................................++
...............................................++
e is 65537 (0x10001)
Enter pass phrase for exmple.com.key:
Verifying - Enter pass phrase for exmple.com.key:

從新增的私錀中,產生一個憑證請求檔,並在請求檔中,寫入「目標網址」(也就是你剛驗證過的那個網址)的所屬資料,如:所在地、單位名稱、負責人信箱等:

# openssl req -new -key exmple.com.key -out exmple.com.csr
Enter pass phrase for exmple.com.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:{{TW}}
State or Province Name (full name) [Some-State]:{{Taichung}}
Locality Name (eg, city) []:{{Taichung}}
Organization Name (eg, company) [Internet Widgits Pty Ltd]:{{EXAMPLE-Company}}
Organizational Unit Name (eg, section) []:{{EXAMPLE-Company}}
Common Name (eg, YOUR name) []:{{EXAMPLE Company}}
Email Address []:{{master@exmple.com}}

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

兩個 {{ }} 所包住的部份,請自己修改成正確資料。


在 Linux 完成 CSR 檔的製作後,你會得到 example.com.csr 檔案,請將檔案內容貼入上圖的文字框中。


CSR檔如無誤,它會出現上圖的訊息。


它要你選擇要生成簽核公錀的頂層網域。


請填入你所提供 https 服務的網址名稱。


確認要簽核公錀的網址。 startssl 簽核的公錀,預設會給你的目標網域及它的頂層網址兩個。如果你要簽核公錀的網址希望是 *.example.com ,也就是除頂層網域外,把它的下層網域一網打盡,也是可以,只要二年付 USD 49.9 即可,大約 1500 元的新台幣,而且這是 wild cards 網址,網際威信可沒這麼好康,一個就要 18000 元、二個就是要 36000 元。這時,我又感到「全球化」的愉悅。


接下來,請把文字框中的文字貼到 example.com.crt 中,這個內容即已被簽核過的公錀檔。另外,請順便下載上圖中的 intermediate 及 root 兩個 CA 檔案。


整個工作完成了。

然後在 Apache 設定檔中設定如下:
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM
SSLCertificateFile /etc/apache2/example.com.crt
SSLCertificateKeyFile /etc/apache2/example.com.key
SSLCertificateChainFile /etc/apache2/sub.class1.server.ca.pem
SSLCACertificateFile /etc/apache2/ca.pem
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
重新啟動 Apache 時,它會問你私錀密碼為何? 這個動作在管理員面前發生是沒有問題的,但在系統自動重開機時,會造成困惱,所以我們可移除私錀的加密,指令如下:

# openssl rsa -in exmple.com.key -out exmple.com.key.no_password

exmple.com.key.no_password 這個私錀檔就是沒加密的,將它寫入 apache 設定檔即可。

2011年4月16日 星期六

SSH 的公私錀生成說明

Linux/Mac:

請在命令列鍵入如下指令:

$ ssh-keygen -t rsa -b 4096

Generating public/private rsa key pair.
Enter file in which to save the key (/home/tmp/.ssh/id_rsa): <<按 Enter ,使用預設值>>
Enter passphrase (empty for no passphrase): <<設個私錀密碼,請大於 5 個字元>>
Enter same passphrase again: <<確認剛剛的私錀密碼>>

Your identification has been saved in /home/tmp/.ssh/id_rsa.
Your public key has been saved in /home/tmp/.ssh/id_rsa.pub.
The key fingerprint is:
72:fb:40:ba:8a:40:be:48:03:bd:20:13:6d:83:cb:d0 tmp@core2duo
The key's randomart image is:
+--[ RSA 4096]----+
| |
| + |
|+ A |
|o= . |
|*o. T . S |
|=o . = . |
|.-. . o |
|o.o. . o |
|... ... . |
+-----------------+


這樣,你的公錀就是 ~/.ssh/id_rsa.pub 而私錀就是 ~/.ssh/id_rsa 。

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEAz22m/azvKC7uk05/D6qvl5c+QR95jkiqEpnn3/co/zOGc4Gf7v1sc5H7Lf5CUOTxgfgAOZSmdr1OPaUYU1cvJTLTjKeVznifyTl3KabMH1Yy8wpSS1TjCTbS8896uXXYtrdIL5KEHnVADYdS4fHWtY7uAR+JWlbh9OjN3deU77656knwW0PO5ELMYKUicSZZZFoUFyDCflM61cNNP1i/rwa1pp8nFqyjzNOq5hKaEsssiJK4tPcm+5K8rwRXm3k7fprvoxYswebo9U85kvyWPqY0iMFE0P019Pbq5VWCaqfv9nzD7rZaKe+aLk/7n+E4HSSSLYNlhnQkZUVm40zGnhGEZvT0e+kmpJpXJKjAe3ZJkowc3o8xrBjD0ULP+jN1fHMUxllWOuxgNkqdD/UjXf5E777Zw+Fpoy2B1c/wRPpRfsFisfLg9xxj3MF+E3wkHROOtrSv+M2wLKVtDODF4zwO8dr5g9s5xBTlSJFsBCJGmX2+zQ6y2033amRnr/Xl0+KAqCOdO+BmQ+iw7X0DFCfxZtjx4RQXcGYw3HqSKP3I4Tft0IHD0g1HXuQhMezG6yVIVABgbo47+Xbdxx7vFb82Anv7DnmhbOovk3LDrzPzyNe7fS2Jla5T5Etb5jyEHE1qNfJNzKVgxjBMGKGk7L5GIx7pXUk= tmp@core2duo

把上面的公錀內容放到你想登入的 Linux/Mac 機器中的 ~/.ssh/authorized_keys2 (這個檔,其實是看系統管理員是怎麼設定的,只不過一般的 Linux 套件都是用這個作預設值)中,這樣你就能使用這一對公私錀登入遠端機器了。

Windows:

就比較麻煩了,請去下載 puttygen.exe 程式,執行它後如下圖:



選擇 SSH-2 RSA 及輸入 4096 的 Number of bits in a generated key 後,再按下 Generate 按鈕,讓滑鼠停留在綠色生成桿的下方空白處,並胡亂移動滑鼠遊標,讓 puttygen.exe 得到亂數種子,待進度達百分百後,可得到下圖:



選取的藍色文字即公錀內容,請貼到你欲登入的 Linux/Mac 機器中的 ~/.ssh/authorized_keys2 中,而私錀部份,請在設定密碼「Key passphrase」及確認密碼「Confirm passphrase」後,按下 Save private key 按鈕以存檔至系統硬碟。

最後,請保護好你的私錀檔(最好不要離開生成它的機器硬碟),遺失它或是被別人盜取後的代價相當大。 Good Luck!

2011年4月13日 星期三

CMClass: 簡述 libsvm(Support Vector Machine library) 使用方法

libsvm乃台大林智仁老師開發的 Open source 工具,其目的為實作 Support Vector Machine 分類器,使用語言主要是 C++ ,目前也有 JAVA 版本,也提供其他語言的 wrapper ,像是 Perl, Python, Ruby, Matlab, Hashkell, Lisp 等。

詳細數學就不介紹了,怕大家睡著(但其實是因為還沒看懂),各位可以看一下下面那段這個影片,大略了解 SVM 分類器如何區別不同資料。



本文章主要介紹的是用 Python 語言去操作 libsvm 函式庫。

先解壓縮 libsvm.tgz 檔,可以看到 python 及 windows 資料夾,如果要在 Linux 中使用的話,請在主目錄中作

$ make lib

這樣會得到 libsvm.so.2 檔,這是 libsvm 的主函式庫,而在 windows 中使用的話,它則是先幫你編譯好這個檔了,可在 windows/ 找到這個 libsvm.dll 檔。

在 Linux 中,請把 python/*py 放到 /usr/local/lib/python2.6/site-packages 中,而 libsvm.so.2 放到 /usr/local/lib/python2.6/ 。

在 windows 中,請把 python/*py 放到 C:\Python26\Lib\site-packages 中,而 libsvm.dll 請放到 C:\Python26\Lib\windows 資料夾中(因為 svmutil.py 寫死了它的相對路徑,所以務必依它的相對位置置放)。

請在 Python shell 中,鍵入下列指令,測試是否安裝成功。

>>> from svmutil import *
>>>

沒錯誤訊息,那就是安裝對了。

使用 svm ,主要就是兩個動作: 訓練及預測。

訓練:

svmutil.svm_train 函式的引數有「類別標籤」、「觀察值」、「參數」。

你的原始資料若是如下:

1. 3, 4, 5, 6 => 第二類
2. 3, 4, 5, 5 => 第一類
3. ....

前面的 #. 表第幾個觀察值,後面逗號分隔的數據為各維度的值,行末則是放置該觀察值為第幾類的說明。請把它轉成

>>> Y = [2, 1, ...]
>>> x = [(3, 4, 5, 6), (3, 4, 5, 5), ...]

類別標籤請獨立放置到一個 list 中,而觀察值維度則依序放置到另一個 list 中。接下來,就能使用 svm_train:

>>> from svmutil import *
>>> model = svm_train(Y, x, '-c 4')

所得到的 model 就是一個經過訓練的分類器。

預測

接下來,我們要拿訓練好的分類器去預測新的觀察值:

>>> p_label, p_acc, p_val = svm_predict([0]*len(new_x), new_x, model)

而 p_label 就是依 new_x 順序所對應的類別標籤 list 。

下圖是我隨機生成的 300 點,圓點為原始的觀察值,而以線相連的連續點則是預測點。



詳細程式碼請參照如下:

 1 #! /usr/bin/python
2 # -*- coding: utf8 -*-
3
4 __author__="hoamon"
5 __date__ =u"$2011/4/12 下午 05:52:31$"
6
7 from math import pi, sin, cos
8 from random import random
9 from matplotlib import pyplot as plt
10 from svmutil import *
11
12 def circleData(centre, radius, down_limit_percent=0, lens=100, range=[0, 100]):
13 points = []
14 while len(points) < lens:
15 _angle = 2 * pi * random()
16 radius_percent = random()
17 if radius_percent < down_limit_percent: continue
18 _radius = radius * radius_percent
19 x = centre[0] + cos(_angle) * _radius
20 y = centre[1] + sin(_angle) * _radius
21 if range[0] <= x <= range[1] and range[0] <= y <= range[1]:
22 points.append((x, y))
23 return points
24
25
26 def test():
27 u""" 製作三群的隨機資料,每群皆 100 個點,點位置的 x, y 限制在 0 ~ 100 之間
28
29 最後利用 matplotlib 繪製出來的圖,"單點"表原始資料,而連續點畫線的部份,
30 該點位的類別則是利用 svm_predict 計算出來的。
31
32 Y = [1, 1, 1, ..., 2, 2, 2, ..., 3, 3, 3, ...]
33 x = [(x1, y1), (x2, y2), ...]
34 """
35 Y = [1] * 100 + [2] * 100 + [3] * 100
36 x1, x2, x3 = (circleData((35, 40), 12),
37 circleData((35, 40), 48, down_limit_percent=0.25),
38 circleData((80, 80), 20)
39 )
40 x = x1 + x2 + x3
41
42 m = svm_train(Y, x, '-c 4')
43
44 #INFO 在 100x100 的畫布上,打出 40000 個點,拿這 4 萬個點去給 m 作預測,算出這 4 萬個點的類別
45 points = [(i*0.5, j*0.5) for j in xrange(0, 200) for i in xrange(0, 200)]
46 p_label, p_acc, p_val = svm_predict([0]*40000, points, m)
47
48 line_1, line_2, line_3, pre_label = [], [], [], p_label[0]
49 for i in xrange(0, 200):
50 for j in xrange(0, 200):
51 index = i * 200 + j
52 now_label = p_label[index]
53 if now_label == 1 :
54 line_1.append(points[index])
55 elif now_label == 2 :
56 line_2.append(points[index])
57 elif now_label == 3 :
58 line_3.append(points[index])
59
60 fig = plt.figure()
61 ax = fig.add_subplot(111)
62 ax.plot([p[0] for p in x1], [p[1] for p in x1], 'ro')
63 ax.plot([p[0] for p in x2], [p[1] for p in x2], 'go')
64 ax.plot([p[0] for p in x3], [p[1] for p in x3], 'bo')
65 ax.plot([p[0] for p in line_1], [p[1] for p in line_1], 'r-', alpha=0.5)
66 ax.plot([p[0] for p in line_3], [p[1] for p in line_3], 'b-', alpha=0.5)
67 ax.set_title('Points of three classes')
68 ax.set_xlabel('x')
69 ax.set_ylabel('y')
70 ax.set_xlim(0, 100)
71 ax.set_ylim(0, 100)
72 plt.show()
73 return m, p_label, p_acc, p_val
74
75
76 if __name__ == "__main__":
77 test()

2011年4月12日 星期二

無法在 Windows 上的 NetBeans 作中文註解

為了讓 Python 程式能容易在團隊之間快速流動,我們要求大家在程式編碼上一律使用 utf8 。只要在程式檔的第一行宣告 #-*- coding: utf8 -*- 以及使用 utf-8 編碼存檔即可。

不過,在 Windows 中執行時,因為它還活在 cp950 的時代,所以我們還要在 Python 主安裝目錄中的 Lib/site-packages/sitecustomize.py 中加入

import sys
sys.setdefaultencoding('utf8')

這樣 python 程式在執行時,才不會遇到 UnicodeEncodeError (其實偶爾還是會遇到,原因是搞混了 Unicode 編碼及 UTF-8 編碼)。

而在使用 NetBeans 時,我們也會在 /etc/netbeans.conf 中設定 -J-Dfile.encoding=utf8 來讓 NetBeans 正常顯示程式中的 UTF-8 編碼中文字。

不過,在 mercurial commit 時,卻無法使用中文作註解。這時候,只要在 netbeans.conf 加入 -J-Dmercurial.encoding=utf8 即可。


2011年4月8日 星期五

廣告:申辦壹網樂機上盒(免費收看壹電視新聞及多部電影)

利益揭露: 透過網頁連結申辦機上盒,能讓我參加抽獎,什麼獎呢? 我也不太曉得,請看倌自行查閱

之前在 PCHome 上買了台 X201i NB,結果貨到時,多送了一台壹網樂機上盒,之前有在壹電視網站上觀看五都選戰的節目,覺得他們真是幹得不錯,只不過我的 Ubuntu + Chrome + flash player 有時候看一看就會自動變灰畫面。

當然他們也有提供桌面程式 NXPlayer 安裝在電腦上看,可惜只有 Window$ 版。

使用壹網樂機上盒就沒這個問題啦! 而且這個機上盒內的作業系統可是 Open source 的 Linux ,有興趣可到下載,這讓人又更加地樂意為他們推廣。而且目前使用機上盒觀看電影、影集,有上百部片是免費的。

有興趣地免費申請一台吧! 只要有 Email 、手機號碼及真實地址(它才能寄機上盒給你呀!)就能申請。

2011年3月16日 星期三

該砍掉右腿嗎?

某天,老婆和我吵架。在爭執了一段時間後,我們進行了以下對話:

老婆:「我是不是你最愛的人?」

我:「我才是我這世界上最愛的人!」

…(大家沉默了一段時間)

老婆:「那你離開我之後,你不會難過囉~」

我:「我不知道。」

老婆:「你又有什麼好難過的,我又不是你最愛的人。」

我:「左腳是我的最愛,右腿第二,妳要我砍掉右腿嗎?」

老婆笑了。

我實在難以想通「女人的想法」,因為「到底是不是最愛的人?」這件事跟我們一開始爭執的問題根本沒有關係。

2011年3月13日 星期日

有幸一睹「槍炮、病菌與鋼鐵:人類社會的命運」

真是該死呀! 當初在大學時,就有機會讀讀這本書,只是當時對於這本書的書名:「槍炮、病菌與鋼鐵」實在沒啥興趣,也不曉得原來它談論的是人類歷史,根本就沒拿來翻翻。不若「歷史之終結與最後一人」來得響亮,結果這本「歷史之終結與最後一人」,我至今還沒看懂,冤枉了荷包。

讀著這本書,讓我想到許多過去想過但不一定有解的事情:「該不該撲殺外來種?」、「台灣抗日的意義在那裡? 個人的國家定位何在?」、「到底該不該吃素?」、「K策略與R策略那個好?」、「人的成功條件中,運氣重不重要?」、「為什麼有些植物比較好吃?其他則否!」、「宗教是用來更有效地統治人民?」。

且給我多一點時間再次細讀這本書,讓我把這些問題好好地整理才分享給大家。

今天發這篇文的目的,只是告訴大家:『「槍炮、病菌與鋼鐵:人類社會的命運」真是一本重要且有趣的書』。事實上,看完這本書後,我又去博客來買了該作者的另二本書:「第三種猩猩:人類的身世及未來」、「大崩壞」。

2011年2月26日 星期六

「投資人宣言」讀後感

這書裡講的概念,大概都在綠角投資筆記、約翰.柏格以及威廉.伯恩斯坦(同本書作者)的書中看過了,像是
  • 高報酬往往伴隨著高風險,但高風險不一定帶來高報酬

  • 分散式投資: 金錢投資的目的並不是獲取暴利,而是安穩、優雅地渡過退休生活

  • 好公司,大多是壞股票; 壞公司,整體而言,是好股票

  • 主動投資長期績效往往不如被動投資

  • 績效來來去去只有成本是固定的

  • 金融從業人員不一定是站在客戶的立場

  • 如何作好資產配置(股債比)

  • 掌握好個人的人力資本
所以一直以來,我愛當金融保險業者的股東勝於當他們的顧客,努力學習程式設計及其他學問提升個人人力資本,先投資自己才作金融投資,並且分散式地購買各種類股(不過,金融股還是佔了半數),達到「如何閱讀一本書」中所提之「贊同實用書之後,你應該實踐書中理論」(在第十三章)。

不過,我的實踐也還不到百分百,像是國內債券及國外股債這二項,我的資產比例還是 0% 。有鑑於此,我開始研究 006202寶富盈 ETF 。過陣子,再向大家報告。

另外,這本書帶給我惟一的新收獲就是「高經濟成長體,不見得是好投資對象」,但理由並不是「好公司,爛股票; 爛公司,好股票」。所謂的「好公司,爛股票」是因為投資人偏好好公司致使其股票的風險貼水減少所以實質報酬率降低。然則在本書中,作者實際提出中國、印尼、南韓、…台灣等亞洲新興市場國家與美國在 1988 ~ 2008 年之間的年化 GDP 、 年化名目股市報酬率比較表(表2.3),從表中,可看到美國以 2.77% 的 GDP 數字卻能提供股市投資人 8.8% 的股市報酬,但中國以 9.61% 的 GDP 卻只能帶來 -3.31% 的股市報酬,原因在於「股票稀釋和安全法規不足而發生的明目張膽竊取」

這現象帶給我相當大的震憾,原來法治國家的好處是這麼棒。中國股市的這種表現也才與我的日常經驗搭上線。因為一直以來,聽別人說:「在大陸作生意,給公務員的額外費用是明明白白、清清楚楚的規費」,而這些沒放到國家口袋,從公司股東口袋搬出來的錢,果然是有反應在股市報酬率上。

雖然台灣的數據是贏過中國大陸的,但這也沒什麼好高興的。至今,我們親愛的同胞: 王又曾、曾正仁、陳由豪、朱安雄同志都還在海外過著顛沛流離的生活,什麼時候才能盼著他們回到溫暖的故鄉:「台灣」呀!

2011年1月27日 星期四

近 250% 的報酬率,我前所未有的紀錄

這是繼 60% 的漲幅後,再一次突破我個人的紀錄。這一切要歸功於 HTC

當時外資紛紛看衰它,而我因為 HTC 幫 Google 代工自有品牌 Nexus One 手機這件事,對它非常有好感。也就在 330 元時,買了 80 股,而後又配了 4 股及幾千元的現金,成本也就降到 279 元。今天(2011-01-27)它股價收在 975 元,報酬率達 249% 。

千金難買早知道,如果當時我把手邊的錢全押在 HTC 上,總報酬率就是 249% ,而不是現在的 13% 。

然而我有這個屁股吃這種瀉藥嗎? 應該是沒有! 股票不會只漲不跌的。


如果手裡的股票只有宏達電,那它從 760 元下殺到 618 元時,我忍耐的住嗎? 就因為害怕所以在 730 元賣了 24 股。又或者能忍得住但我能睡得著嗎? 之前只擁有巨大時,就知道我的個性不是那種可以大而化之的人。

重壓宏達電勢必讓我沒有生活品質,而且這是我運氣好,如果重壓的是茂德,那故事就沒那麼有趣了。

有趣的是,因為現在擁有茂德、雷虎、台航…這些讓我賠錢的股票,反而我才睡得著覺。這就是被動投資呀!

2011年1月24日 星期一

使用 PayPal Express Checkout 作線上收款機制

若你不太了解什麼是金流系統,可以先去看「簡述金流系統」。

消費者在線上購買商品或勞務,所謂的付款其實只牽扯到兩件事:『身份驗證』及『確認額度』。但這兩件事都是特許公司如銀行或信用卡公司才能作的事。所以我們得透過中間人或中間人的中間人(金流公司)幫我們作到這兩件事,而我選的是 PayPal ,它是跨國的金流公司,我個人認為十分適合純網際網路公司使用。

從誰那裡匯多少錢到誰那裡? 有三個變數:『付款的人』、『付多少』及『收款人』。這『收款人』當然是我們自己的公司囉。在程式中設定收款帳戶只要設定『帳戶名稱(USERNAME)』、『密碼(PASSWORD)』及『簽名(SIGNATURE)」就行了,如何申請這三種資料請看我的另篇文章

而『付多少』的設定變數名則為 AMT 。但在消費者刷卡時,要讓他明確地了解買的東西到底有什麼? 價錢是多少? 要刷多少錢? 我們得另外設定訂單的顯示變數。有商品名稱(L_NAME0)、商品描述(L_DESC0)、商品編號(L_NUMBER0)、購買數量(L_QTY0)、商品單價(L_AMT0)、所有商品小計(ITEMAMT)、運送及處理費用(SHIPPINGAMT)、稅金(TAXAMT)等。

這些變數後有帶 0 的表示它可以是多值,如果該筆訂單有第二項商品的話,就設定 L_NAME1 、 L_DESC1 、 L_NUMBER1 、 L_QTY1 、 L_AMT1 ,以此類推。

這些訂單顯示變數有幾項原則:

  • ITEMAMT 必須等於 L_AMT0 * L_QTY0 + L_AMT1 * L_QTY1 + ... + L_AMTn * L_QTYn

  • AMT 必須等於 ITEMAMT + SHIPPINGAMT + TAXAMT


違反這兩個原則, PayPal 會報錯的。

而『付款的人』部份就不是我們程式設計師該處理的,這部份交由 PayPal 自己與消費者確認卡號是否正確、與發卡銀行確認是否允許消費者刷該筆訂單的金額。等到 PayPal 作完『身份確認』及『額度確認』後,PayPal 會回傳一個 TOKEN ,告知我們消費者有能力消費該筆訂單,如果我們接受該筆交易,就以這個 TOKEN 回覆給 PayPal ,那它就幫我們刷下消費者的卡片了。之後就能在 PayPal 的帳務管理介面中看到消費者的付款紀錄。

上面的觀念了解了,我們這就進行程式的實作吧!

PayPal 的付款程序要經過 3 次的 API 呼叫,分別是 SetExpressCheckout, GetExpressCheckoutDetails, DoExpressCheckoutPayment 。

  • SetExpressCheckout 是整理好一份訂單資訊供消費者瀏覽。

  • GetExpressCheckoutDetails 是抓取當次交易的詳細資訊,但不包含消費者的卡號。

  • DoExpressCheckoutPayment 要求 PayPal 對消費者進行刷卡動作,完成交易。


而消費者瀏覽網頁順序則是『我們的訂單頁面』=>『確定購買』=>『SetExpressCheckout』=>『PayPal 付款頁』=>『PayPal 確認頁』=>『GetExpressCheckoutDetails+DoExpressCheckoutPayment』=>『我們的購買成功頁面』。

我們自己所寫的『確定購買』程式中,會紀錄消費者的購買資訊,產生訂單編號,完成後執行 SetExpressCheckout API 呼叫動作。所謂的呼叫,其實不過就像是 html 中的 form submit 。很懶惰的作法是輸出一個如下的 html 表單,然後要求消費者自己手動按下送出鈕。


 1 <form method="POST" action="https://api-3t.paypal.com/nvp">
 2     <input type="hidden" name="USER" value="API_username_do_not_copy_me">
 3     <input type="hidden" name="PWD" value=" API_password_do_not_copy_me">
 4     <input type="hidden" name="SIGNATURE" value="API_signature_do_not_copy_me">
 5     <input type="hidden" name="L_NAME0" value="test_product_name">
 6     <input type="hidden" name="L_DESC0" value="test_description">
 7     <input type="hidden" name="L_NUMBER0" value="test1">
 8     <input type="hidden" name="L_QTY0" value="1">
 9     <input type="hidden" name="L_AMT0" value="85">
10     <input type="hidden" name="ITEMAMT" value="85">
11     <input type="hidden" name="SHIPPINGAMT" value="10">
12     <input type="hidden" name="TAXAMT" value="5">
13     <input type="hidden" name="AMT" value="100">
14     <input type="submit" name="METHOD" value="SetExpressCheckout">
15     <input type="hidden" name="VERSION" value="63.0">
16     <input type="hidden" name="CURRENCYCODE" value="TWD">
17     <input type="hidden" name="PAYMENTACTION" value="Sale">
18     <input type="hidden" name="CANCELURL" value="http://www.YourCancelURL.com">
19     <input type="hidden" name="RETURNURL" value="http://www.YourReturnURL.com">
20 </form>


這裡有幾個地方要注意, form method 一定是 POST , form action 一定是 https://api-3t.paypal.com/nvp ,input name="METHOD" 的 value 一定是 SetExpressCheckout 。

VERSION 代表你呼叫的 API 版本是多少,版本號太小的 API ,可能會有些參數不支援。不過,以我使用的經驗,上面的參數都能跑在 53 ~ 63 之間。但能設得愈大愈好。

而 CURRENCYCODE 代表收取的幣別, TWD 代表新台幣, USD 代表美金,其他貨幣請參閱這裡

PAYMENTACTION 的值有三種: Sale, Authorization, Order , Sale 表一般銷售,消費者要買,你一定賣; Authorization 表須確認的銷售,如消費者要買 Giant 的 TCR SL 3 車架,但貴公司沒建置庫存管理,所以消費者下單後,你得到大如足球場的倉庫去找,找得到就賣,找不到只好跟消費者 Say Sorry! Order 表須更長時間的確認銷售,像 Authorization 最多只會在帳務管理系統中等 3 天讓你按下請款鈕,但 Order 可以等到 29 天。

CANCELURL 是當消費者在 PayPal 付款頁中,反悔了,在他取消交易時, PayPal 會導引他回到你的網站。

RETURNURL 是當消費者在 PayPal 確認頁按下「立即付款」, PayPal 會導引他回到你的網站,理論上,這個網頁就是你執行 GetExpressCheckoutDetails + DoExpressCheckoutPayment 的地方。

從這個 html form 範例中,可以了解呼叫 SetExpressCheckout API 真的是非常簡單的事,只要把握正確的 name - value pair(nvp) 即可。

不過我們是 Python 程式設計師,怎麼能用 html form 這麼簡單的東西來呼叫 API ,當然要用 urllib 囉! 把下面的程式插到『確定購買』程式的最後面,這樣就不用消費者自己手動按送出鈕了。


 1 from google.appengine.api import urlfetch
 2 import urllib
 3
 4 string_hash = {
 5     "USER": "API_username_do_not_copy_me", "PWD": " API_password_do_not_copy_me",
 6     "SIGNATURE": "API_signature_do_not_copy_me", "L_NAME0": "test_product_name",
 7     "L_DESC0": "test_description", "L_NUMBER0": "test1", "L_QTY0": "1",
 8     "L_AMT0": "85", "ITEMAMT": "85", "SHIPPINGAMT": "10", "TAXAMT": "5",
 9     "AMT": "100", "METHOD": "SetExpressCheckout", "VERSION": "63.0",
10     "CURRENCYCODE": "TWD", "PAYMENTACTION": "Sale",
11     "CANCELURL": "http://www.YourCancelURL.com",
12     "RETURNURL": "http://www.YourReturnURL.com",
13 }
14 form_data = urllib.urlencode(string_hash)
15 result = urlfetch.fetch(url='https://api-3t.paypal.com/nvp',
16     payload=form_data,
17     method=urlfetch.POST,
18     headers={'Content-Type': 'application/x-www-form-urlencoded'},
19     deadline=10)
20
21 hash = {}
22 for i in result.content.split('&'):
23     k, v = i.split('=')
24     hash[k] = urllib.unquote(v)
25
26 redirect_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=%s' % hash['TOKEN']
27 return HttpResponseRedirect(redirect_url)


跑到 redirect_url 網址後,就是 PayPal 自己與消費者互動的網頁,等到消費者確定付款了,就會再轉回我們的 RETURNURL 程式。在 RETURNURL 頁面中,首先呼叫 GetExpressCheckoutDetails 得到該 token 所對應的付款資訊。然後再執行 DoExpressCheckoutPayment 即可完成信用卡刷卡動作。


 1 # exec GetExpressCheckoutDetails
 2 token = request.GET.get('token')
 3 string_hash = {
 4     "USER": "API_username_do_not_copy_me", "PWD": " API_password_do_not_copy_me",
 5     "SIGNATURE": "API_signature_do_not_copy_me", "METHOD": "GetExpressCheckoutDetails",
 6     "VERSION": "63.0", "TOKEN": token,
 7 }
 8 form_data = urllib.urlencode(string_hash)
 9 result = urlfetch.fetch(url='https://api-3t.paypal.com/nvp',
10     payload=form_data,
11     method=urlfetch.POST,
12     headers={'Content-Type': 'application/x-www-form-urlencoded'},
13     deadline=10)
14
15 hash = {}
16 for i in result.content.split('&'):
17     k, v = i.split('=')
18     hash[k] = urllib.unquote(v)
19
20 if hash['ACK'] != 'Success':
21     error_messages = []
22     for k, v in hash.items():
23         error_messages.append('%s: %s'%(k, v))
24     raise Exception(';\n'.join(error_messages))
25
26 # exec DoExpressCheckoutPayment
27 string_hash = {
28     "USER": "API_username_do_not_copy_me", "PWD": " API_password_do_not_copy_me",
29     "SIGNATURE": "API_signature_do_not_copy_me", "METHOD": "DoExpressCheckoutPayment",
30     "VERSION": "63.0", "TOKEN": token,
31     "AMT": "100", "CURRENCYCODE": "TWD",
32 }
33 form_data = urllib.urlencode(string_hash)
34 result = urlfetch.fetch(url='https://api-3t.paypal.com/nvp',
35     payload=form_data,
36     method=urlfetch.POST,
37     headers={'Content-Type': 'application/x-www-form-urlencoded'},
38     deadline=10)
39
40 hash = {}
41 for i in result.content.split('&'):
42     k, v = i.split('=')
43     hash[k] = urllib.unquote(v)
44
45 if hash['ACK'] != 'Success':
46     error_messages = []
47     for k, v in hash.items():
48         error_messages.append('%s: %s'%(k, v))
49     raise Exception(';\n'.join(error_messages))
50
51 return HttpResponseRedirect('http://www.YourThankURL.com/')


就這樣,你會在 PayPal 的帳務管理系統中,看到消費者的付款紀錄。
Related Posts Plugin for WordPress, Blogger...