Effective Python – 例14 在排序時使用key參數

例如list之類有序的容器可以用sort這個方法來做排序,但若是其中的物件沒辨法比較時(沒有實作< operator)會產生Error,這時用用key傳入一個function回傳可比較的物件來代替。

class Tool:
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight

    def __repr__(self):
        return f'Tool({self.name!r}, {self.weight})'


tools = [
    Tool('level', 3.5),
    Tool('hammer', 1.25),
    Tool('screwdriver', 0.5),
]

tools.sort()

TypeError: ‘<‘ not supported between instances of ‘Tool’ and ‘Tool’

我們可以用一個lamda function來讓Tool物件以name元素來做排序。

tools.sort(key=lamda x: x.name)
print(tools)

[Tool(‘hammer’, 1.25), Tool(‘level’, 3.5), Tool(‘screwdriver’, 0.5)]

或是回傳一個tuple,sort會依照順序來做比較。

tools = [
    Tool('sander', 4),
    Tool('drill', 4),
    Tool('circular saw', 0.5),
]

tools.sort(key=lambda x: (x.weight, x.name))
print(tools)

Tool(‘circular saw’, 0.5), Tool(‘drill’, 4), Tool(‘sander’, 4)]

另外可以用reverse參數或是負號來做反向排序

tools.sort(key=lambda x: (x.weight, x.name), reverse=True)
print(tools)

[Tool(‘sander’, 4), Tool(‘drill’, 4), Tool(‘circular saw’, 0.5)]

tools.sort(key=lambda x: (-x.weight, x.name), reverse=True)
print(tools)

[Tool(‘circular saw’, 0.5), Tool(‘sander’, 4), Tool(‘drill’, 4)]

Effective PYTHON – 例16: 檢查dictionary key值存在時,使用get而非KeyError

Effective PYTHON 2rd

在使用dictionary時,若key值不存在時會產生KeyError,我們有四種方式可以處理。

counters = {
    'key1': 1,
    'key2': 2
}

key = 'key0'


#法一:
#先檢查key值是否存在
if key in counters:
    count = counters[key]
else:
    count = 0

counters[key] = count + 1


#法二:
#用try/except處理KeyError
try:
    count = counters[key]
except KeyError:
    count = 0

counters[key] = count+1


#法三:
#使用get
count = counters.get(key, 0)
counters[key] = count + 1


#法四:
#使用setdefault
counters.setdefault(key, 0)
counters[key] += 1

get會把第一個引數當作key回傳對應的value,若key不存在不會丟出KeyError而是會回傳第一個引數的值,在此例中就會回傳0。若是沒有第二個引數會回傳None,在此例中應該比較推薦用get的用法。

而setdefault則會把value直接用第二個引數修改。通常是適合用在value是container的狀況,但書中建議這種情況可能要考慮用defaultdic來代替一般的dictionary。

key = 'key0'
votes = {
    'key1': ['Bob', 'Alice'],
    'key2': ['Coco']
}

names = votes.get(key)
if names is None:
    votes[key] = names = []

#或是用 := (Walrus Operator, assignment expression)
if (names := votes.get(key)) is None:
    votes[key] = names = []

#這種情況用setdefault最簡潔
names = votes.setdefault(key, [])

FIRE-工作10年就退休且財富自由

FIRE是Financial Independence Retire Early的縮寫,是在美國流行的一種理財概念。目標在工作10年存到足夠的退休金,並用這些資產進行被動投資,只要平均年報酬能等於一年的花費就可以達到提早退休的目標。

這篇主要的參考資料包括兩本書的中文譯本:

財務自由與足夠的退休金這兩點可能很抽象。FIRE認為在美國大概一個家庭需要100萬美元的資產,這些資產可帶來每年40000美元的收入。當然每個人想過/能過的生活不一樣,書中所舉的範例每年32000-60000美元。

100萬美元約是3000萬新台幣,而40000美元的年消費約是120萬新台幣。但在台灣實行FIRE,需要計算台灣與美國的物價,我參考Numbo [1,2],約以70%物價來計算。也就是說在台灣約要2000萬新台幣才能退休,大概全家每年可以消費80萬新台幣。若換算32000~60000美元的年支出,在台灣是70萬至130萬新台幣。

在台灣實行FIRE的家庭,目標月支出是5.5萬至10萬

退休所需資產是1700萬~3100萬

對於被動收入的理解各流派差異相當大,但對被動投資者來說就是「4%法則」,也就認為每100萬的資產扣除通膨後平均可帶來4萬元的年收入。這是一個不卑不亢的數字,雖然景氣有好有壞,各公司的經營也不同。但被動投資將投資拉長至30年以上,並分散投資上百上千家公司,在分散風險後可帶來相當穩定的投資報酬。

被動投資的原理不是三言兩語可以道盡,有問題的人應詳閱這兩本書。我另外推薦「漫步華爾街」。

使用4%法則計算會發現要在工作10年後退休需要將⅔的收入存下來。也就一個人年收百萬,一年也只能花33萬,一個月能花的錢不超過二萬八,這是窮學生過的生活。但你一年可以存下66萬元,十年後就可以存下666萬,加上每年4%投資報酬會變成830萬,830萬的4%就是33萬。接下來你就可以拿每年33萬的收入過財富自由的生活。

在台灣要實行FIRE最低需要家庭年收200萬,且將每月消費壓低至5.5萬

FIRE提早退休的核心就是減少不必要的花費,並不是教你什麼神奇的投資法。

當然有100萬的年收我不會選擇過每月二萬八的窮學生生活。FIRE告訴我早早退休並不是辦不到的事情,只是我選擇了更好的物質生活,所以才要這麼努力工作。

附註

[1] 全球物價指數排名出爐!台灣物價其實很低?-依這篇文章記錄,台北的物價約是紐約的75%
[2] Numbeo – 在這寫這篇文章時所計算的台北物價是紐約的65%
既然是退休時的花費,就不應該用各國最大城市來計算物價,但台灣小城市的物價資料不足,如果大家覺得70%計算不合理,在60-80%左右的區間調整應該還算合理。

要不要買房在這兩本FIRE的書中沒有一致見解。其中一本建議盡早買房,因為提早投資不動產就是加大投資的時間以及報酬,但要買郊區便宜的二手房子。另一本書的範例中有人買房也有租房,甚至是住拖車的例子。一般來說租金或不動產應該是支出或是總資產的30%以下,再怎麼多也不應該超過40%。

雖然其中一本書說打工族也可以FIRE,但若在台灣月收3萬要實行FIRE,一個月只能花一萬。我認為還是有些困難,FIRE在台灣的最低標可能還是要月收5萬以上才辦得到。

這兩本書所採用的被動投資都是以美國股市為主,美國與非美國的比例約是8:2,考量到這些作者都是在美國退休這個數字是合理的。另外股債比約是8:2,因為這兩本書都建議在財富自由後還是要繼續工作,所以要選100%股市也是合理的。

財富自由不代表完全不工作,而是讓你可以不用在意薪水去選擇你喜歡的工作與生活

軟體工程師必讀的經典書籍

下面是我整理一些有名的軟體或CS相關書籍,不過多少會有其他的書籍被遺漏。

粗體是我個人推薦的書籍

ZONE 1

Refactoring
Clean code
Design Patterns: Elements of Reusable Object-Oriented Software
Head first design pattern
The Mythical Man-Month
Domain-Driven Design: Tackling Complexity in the Heart of Software
The Phoenix Project: A Novel about IT, DevOps, and Helping Your Business Win

ZONE 2

The pragmatic programmer
Programming pearls
Code complete
Don’t Make Me Think, Revisited: A Common Sense Approach to Web Usability
Peopleware
Designing Data-Intensive Applications
Working Effectively with Legacy Code
Building Microservices
程式設計師的自我修養-連結、載入、程式庫

DevOps Handbook中文版|打造世界級技術組織的實踐指南

這本書不如“鳳凰計畫”有名,但我認為就算看過“鳳凰計畫”的人也還是很值得一讀。這本書會把“鳳凰計畫”裡面提到的「三步工作法」詳盡說明,但這本書所提的devops並沒有明確指出要用的流程或是工具,比較偏概念還有各公司採用的devops元素作簡介。

再對本書內容介紹前,我先以自己的解讀做總結。

  1. 自動化開發——bug, feature, 需求的自動化管理。並非只有coding的流程,所有高層主管以及客戶提出的需求都要有自動化的紀錄與追蹤。這樣才能統計所有的意見實行的狀況與成果。
  2. 自動化測試與部署——這是大部分人所以為的devops,但只有這個部分是沒有辦法達成devops的精神
  3. 自動化監控——除了監控以外,還要能提供客觀的方式來做評估產品。
  4. 部署後自動化測試——這也可算是監控的一部分,但自動化的測試可以提供更可靠且客觀的評估。更激烈的手段如“搗亂猴”,甚至主動內部攻擊來做測試。
  5. 將上述步驟以程式化自動執行,反覆循環執行並改進。
  6. 創造由上而下的devops文化,而非只是任命或雇用devops工程師。

目前大部份的devops可能都只關注在第二點,但實際上要從一到五點重覆循環改進才是真正的devops精神。

三步工作法其實是有很多抽象的概念與文化,自動化也只是手段之一。所以我認為最最重要的點還是第六點,要達成的最好方法就是推薦你的同事或主管來閱讀這本書。

長期投資的目標是十年後買房

有的人使用長期投資是為了存頭期款,目標在五年或十年後買房。

這並不是”被動投資”的目標,真正符合”被動投資“的長期投資應該是三十年以上的計畫。也許會認三十年太長,等到存完自己就老了。但這就是被動投資的目標,被動投資要你在可以工作的年紀就定下計畫,讓自己老到無法工作退休時也能有足夠且穩定的收入。

被動投資不是讓你二三十歲出社會,工作十幾年發大財買房,四十歲退休的計畫。

大部分的“被動投資”書籍,例如我推薦的“漫步華爾街”,作者認為大部分的人都應該買房,只是買房要在自己可負擔的範圍內。以我的話來解讀作者的意思,作者認為買房的錢是在原本的資產配置計劃之外,也就是說除了要存下足夠錢來完成資產配置所需的金額之外,也要存頭期款以及繳房貸,不能因為房貸而減少被動投資的金額或停止被動投資計劃。

股票報酬受景氣周期的影響,但景氣的周期又難以預測。雖然歷史告訴我們若能將投資拉長超過到十年以上大多能度過整個景氣循環而獲得正報酬,但很多投資需要在十年內變現。例如結婚、出國旅遊、留學、買車等等的花費,這一類預備的花費都不應該買股票型基金,因為我們無法預測是否會在正好需要支出時碰上股災。若打算要在十年內買房,這十年之中存下來的買房基金不應該買股票型基金。應該將預備買房的錢先定存,直到存夠時再來買房。

個人建議,在存預備購屋基金時可以台灣的REITs來替代部份的定存 。因為被動投資原則要求“分時分批投入”,但房屋的金額太大且無法分批買入。雖然REITs價格不完全與房價連動,但畢竟REITs標的為不動產,故”分時分批購買REITs”還是有類似”分時分批購買房屋”的效果。可惜台灣的REITs規模很小而且標的不多,大多是台北市的辦公大樓,所以要買多少比例台灣REIT還是需要各種衡量。

在我早先的文章裡建議先完成股票的資產配置部份再來存錢買房,但在台灣所有出社會的人都有很大的買房壓力,不管來自自身、同事、另一半或是長輩。若照我原先的建議可能要出社會工作20年才能達到買房的階段性目標,這對很多台灣人來說是難以接受的計劃。也許有買房壓力的台灣人在執行被動投資計劃時可以先一半投資股票型基金,另一半存下來預備買房。如果我原先的建議,將收入的1/3存下來投入被動投資。夫妻若年收入150萬就要每年存50萬。也就是每年存下25萬的買房預備金,大約8年可以存到200萬頭期款。也許200萬頭期款買不到什好的房子,但活在台灣也沒辦法。

被動投資的最終資產目標大概是年支出的25倍,所以每年花費100萬退休時要存2500萬資產,其中不超過一半為自住住宅,故大約為1200萬左右。推論合理的房價所得比不超過8倍,不然其他的被動收入會不夠退休後的支出。節論只能說台灣目前的房價偏高。呼應最前面所提,被動投資不是教你賺大錢買房然後提早退休。如果覺得錢不夠,應專注在本業上,提升自己的薪水才是正解。

長期投資台灣50 長期投資ETF

我推薦“被動”或“指數型”投資,但ETF既不是其充分條件也不是必要條件,不管是0050或00692以及其他大部分的ETF亦然。

關於“被動”投資或是“指數型投資”我找不到一個明確定義,在國外這兩個詞也沒有被廣泛使用。但我個人認為“被動投資”比“指數型投資”來得好,因為“指數型”會讓人錯誤連結“指數型ETF”,所以我會統一使用“被動投資”來描述我的投資理念。

台灣很多人會把這種投資方法稱為“綠角派”,實際方向與觀念大體是一樣的。雖然我文章不時有些特別說法,但實際上“綠角”的觀念我99%贊同,只是寫文章時會特別強調那1%的相異處。

“綠角派”應該改為“伯格派”或是“伯格頭”更好,在美國這一類人自稱“ BogleHeads”,表示他們尊崇Vangaurd創辦人”John Bogle”。

用我的話語來定義,包括下列幾點:

  1. 分散投資標的
  2. 分散投入時間
  3. 長期持有
  4. 使用低成本的工具

“分散投資標的”這件事依照伯格先生的建議只要分散投資整個美國股市已足夠,但我認為分散全球股市才是最佳解。伯格先生的建議是針對美國人,因為美國股市市值超過全球一半,而且美國上市大公司大多為跨國企業,所以分散買美國股市可能跟分散全球已有八分相似。另外一個原因是因為美國經濟與物價與美股相關,所以針對生活在美國大陸的美國人來說加重投資美股是很合理的。

但對於台灣人不建議只買VTI這類的美股ETF,除非已經下定決心要移民美國。但比起只買VTI,我更不建議只買0050或00692之類的台股ETF,因為台股佔全球股市只有一小點。雖然台灣股市與台灣經濟還有物價相關聯,在分散投資全球之後加碼台股我認為是合理的。但至少一半股票配置應為全球分散,所以台股不應超過50%的股票配置,但若只想買VT不想另外買台股也是合理的選擇。重點是台股的比例在投資計劃開始執行後就不應更動,不然就違背“長期持有”的原則。

關於“低成本工具”,最早出現的理想工具應該是Vanguard的指數型共同基金,這些指數基金有極低的管理費且追蹤良好。但這些基金後來不讓非美國人購買,故台灣投資人多使用“VT”這類低成本的全球股市型ETF來分散投資。

被動投資並沒有特別推崇ETF,實際上適合被動投資的ETF只是眾多ETF裡面的極少數。0050或00692我認為是尚可接受但並不優良的工具。為了分散投資臺灣,從一堆爛頻果中選這兩個堪用的工具。

至於5G之類的ETF絕對不是良好工具,單投資某些產業的ETF違反“分散”原則。

創新的公司文化與結構(一)

這是一篇與標題不符的文章。這個標題是我的目標,但目前還沒有完整的計畫。暫且先提出我認為目前公司架構所碰到的問題。

現在的公司大部分都還是使用科層制度,類似老闆/股東—CEO—高階主管—主管……—小主管—基層員工。針對這個制度許多人提出不同的問題,但我認為最大的問題就是現在風行的“向上管理”與”向下管理”。

大部分員工都是用上下交相賊的方式工作,而不是做對公司與社會有貢獻的事。大部分高層都會有脫離現實的發想,而下層的人為了滿足高層都會採用畫大餅的方式來獲取注意,而不會去確認計畫是否合理。因為公司賺錢並不會讓自己獲得太大的利益,造成大部分的人只會追求升遷。層層下來計畫越來越扭曲且脫離現實,但不論計畫是否成功,都只有會畫餅的人能升遷,因為不受管理的下屬對主管不利。真正想要解決問題的人反而會受到公司概有的系統與制度壓制,而上位者正是概得利益者。

少部分的人不求升遷,轉而追求CP值來滿足工作外的生活,不管是其他興趣還是副業。但他們也不會把公司或是社會的利益擺在前位。

因為科層制度讓公司利益與個人脫鉤。雖然資本主義告訴我們個人追求自己的利益可以讓整體的利益最大化,但代理人問題越來越嚴重,為了追求個人利益高階主管會讓公司去冒過度風險或是追求短期利益。大部分的公司都在COST DOWN或當COPY CAT,而不是創新或是提升技術。

另外我認為當公司越來越龐大,貧富差距拉大後,老闆也會去冒過度的風險,因為他們的資產與權利讓他們不害怕失業或失敗。有權有勢的有錢人並不擔心破產,因為他們很容易靠”競租”等方式東山再起,反而是沒有背景的員工因為公司破產而失去了未來。

想升遷的人與老闆讓公司追求扭曲的目標,而放棄升遷轉而追求CP值的員工也不會追求公司利益,進而讓現在的公司制度失衡。

追求個人利益是社會成長的動力,所以資本主義在現代的社會勝過了貴族制度與社會主義。但資本主義的歷史約三百年,與人類歷史相較還相當短。為了讓資本主義能穩定發票,我們需要讓個人的利益與社會利益趨同,這是創新的公司架構的目標。

核子醫學-甲狀腺

  • I-131
    • 有beta射線,可用於治療
    • 也可用於RAIU (Radiation iodine update)
    • γ-ray 364KeV可用於Whole body scan,但radiation dose較高易造成star artifact,且易造成thyroid stunning (>2-4mCi)
    • 不適合thyroid scan,因為有beta射線,易thyroid stunning
    • 半衰期8天
    • 較易偵substernal goiter,有的地方先做I-123 scan看不到subternal goiter再做I-131 scan(50μCi)
    • Whole body scan 2(1.5-4) mCi
    • 治療Graves’ disease 5-15mCi,toxic nodule 20-30 mCi, ablation 30-150 mCi(>30需隔離)
    • RAIU 5-10 μCi
  • I-123
    • Thyroid scan+RAIU 200-400μCi
    • Whole body scan 1.5-2 mCi
  • Tc-99m sodium pertechnetate
    • 替代選擇
    • 因radiation dose較低,常用在小孩
    • 亦用在診斷Mechkel’s diverticulum, salivary gland
    • thyroid scan 6mCi (2-10)
  • Thyrotoxicosis
    • RAIU ↑: Hashimoto, Graves’ disease
    • RAIU -: Antithyroid drugs: propylthiouracil, Methimazole
    • RAIU ↓: Subacute thyroiditis: thyrotoxic phase, 人工 (Thyrotoxicosis Factitia), Antihyroid drugs, Struma ovarii
  • Hypothyroid
    • RAIU ↑: Hashimoto
    • RAIU -: Hashimoto, subacute thyroiditis (recovery phase)
    • RAIU ↓: hypothyroidism
  • Euthyroid
    • RAIU ↑: Rebound after antithyroid drug withdrawal , Compensated dyshormonogenesis
    • RAIU ↓: Decompensated dyshormonogenesis

Health Literacy健康識能

  • 中譯為健康識能或健康素養,或較不常見譯為健康知能、健康認知
  • 定義
    • Set of skills/abilities needed to gain access to, understand, & use health-related info。
    • 獲取並理解與健康相關的說明文件或資訊。
  • 33%美國人閱讀能力不足小學5年級
  • 55%對於基礎數學運算有困難
  • 36% have basic or below-basic health literacy
    • 無法經由查表計算BMI,無法正確解讀處方EX飯前OR飯後
    • Poor Literacy對健康的不良影響比低教育程度和種族還大
  • 測試工具
  • Managment
    • 減慢說明速度
    • 使用易懂的話說,避免術語(ex: positive test)
    • 畫圖或用圖片輔助
    • 減少資訊量,只提供重點
    • Teach-back
      • 不要問「你是否了解」,應該請患者自行說明一次
      • 例「請表演一次如何使用」「您會如何跟你的同伴說明」
    • Encourage questions
      • 若患者沒有任何問題,通常也沒有完全了解
      • 不要問「Do you have any question?(有沒有任何問題)」,要問「What questions or concerns do you have?(有任何疑慮或問題請提出討論/還有什麼需要詢問)」
  • Medication adherence
    • 提供藥盒
    • 簡化回診方式(90天)
    • 請患者帶他們使用的藥物來,並請他們自己示範使用方式
  • Discussing risk
    • Frequency比percentages容易了解
      • 十人裡面會有兩人產生副作用
    • 強化影響力
      • 「這個藥物每治療100位患者,其中94位都不會有副作用」
      • 「Six of 100 patients using drug A will expirience hair loss」
    • 使用絕對與相對風險
      • 10年內每100人會有五人死於X疾病,若這100人每年接受篩檢會有兩人免於X疾病造成的死亡
    • 使用視覺化的幫助

Ref: Pocket Primary Care 2nd ed