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, [])

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

下面是我整理一些有名的軟體或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精神。

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

[Python] 讓Jupyter notebook可以從遠端連線

請參考jupyter官網說明
為了安全第一步請設定jupyter密碼

$ jupyter notebook password
Enter password:  ****
Verify password: ****
[NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json

有可能會回說jupyter_notebook_config不存在之類的錯誤
代表你需要config檔 使用以下指令即可

$ jupyter notebook --generate-config

接下來修改config檔

$ vi ~/.jupyter/jupyter_notebook_config.py

新增下面資料或是將原本的註解(#)刪除即可

c.NotebookApp.ip = '*'

ip改成星號讓遠端電腦可以透過本機ip連上jupyter_note
若本機的ip為固定ip直接填上對應ip也行
現在啟動jupyter notebook應該就可以從遠端連線了
另外建議要用https加密連線 以免密碼被偷取

c.NotebookApp.certfile = u'/absolute/path/to/your/certificate/fullchain.pem'
c.NotebookApp.keyfile = u'/absolute/path/to/your/certificate/privkey.pem'

把路徑改成金鑰的位置即可 至於金鑰如何取得請自己google

[Python] 讓Jupyter notebook可以從遠端連線

請參考jupyter官網說明

為了安全第一步請設定jupyter密碼

$ jupyter notebook password
Enter password:  ****
Verify password: ****
[NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json

有可能會回說jupyter_notebook_config不存在之類的錯誤
代表你需要config檔 使用以下指令即可

$ jupyter notebook --generate-config

接下來修改config檔

$ vi ~/.jupyter/jupyter_notebook_config.py

新增下面資料或是將原本的註解(#)刪除即可

c.NotebookApp.ip = '*'

ip改成星號讓遠端電腦可以透過本機ip連上jupyter_note
若本機的ip為固定ip直接填上對應ip也行
現在啟動jupyter notebook應該就可以從遠端連線了

另外建議要用https加密連線 以免密碼被偷取

c.NotebookApp.certfile = u'/absolute/path/to/your/certificate/fullchain.pem'
c.NotebookApp.keyfile = u'/absolute/path/to/your/certificate/privkey.pem'

把路徑改成金鑰的位置即可 至於金鑰如何取得請自己google

在ubuntu 17.10下使用Anaconda安裝Tensorflow與Keras

此篇參考

Tensorflow + keras 深度學習人工智慧實務應用-林大貴

至Anaconda官網下載Python3版的Anaconda for Linux

Downloads

請用bash介面下載

#wget https://repo.continuum.io/archive/Anaconda3-5.1.0-Linux-x86_64.sh

安裝Anaconda, -b代表批次安裝並省略條款閱款

#bash Anaconda3-5.1.0-Linux-x86_64.sh -b

將Anaconda的路徑加到PATH

#vi ~/.bashrc

在檔案內新增

# add by Anaconda
export PATH="/home/username/anaconda3/bin:$PATH"

若是用root安裝要改成

export PATH="/root/anaconda3/bin:$PATH"

套用新的PATH

source ~/.bashrc

確認Python版本

# python3 --version
Python 3.6.4 :: Anaconda, Inc.

安裝tensorflow and keras

python -m pip install tensorflow
python -m pip install keras

建立工作目錄

mkdir -p ~/pywork
cd ~/pywork

開啟jupytor

jupytor notebook

在windows10下使用Anaconda安裝Tensorflow與Keras

此篇參考

Tensorflow + keras 深度學習人工智慧實務應用-林大貴

至Anaconda官網下載Python3版的Anaconda for windows

Downloads

依照指示安裝,安裝過程中會出現「Add Anaconda to my PATH evironment variable」這個選項必須要勾選。

安裝後請啟動cmd「命令提示字元」

建立一個工作目錄

md \pythonwork

cd \pythonwork

使用Anaconda建立給tensorflow使用的虛擬環境

conda create --name tensorflow python=3.5 anaconda
activate tensorflow

安裝tensorflow and keras

pip install tensorflow
pip install keras

啟動jupyter notebook

jupyter notebook

瀏覽器應會自動開敵jupyter notebook
要關閉jupyter請在cmd按下ctrl+c
離開虛擬環境請

deactivate tensorflow

[Python] 單底線與雙底線

[code lang=”python”]#single_double.py
class Parent(object):
def _single(self):
print("Parent single underscore")
def __double(self):
print("Parent double underscore")

class Child(Parent):
pass

c = Child()
c._single() #Parent single underscore
#Python並沒有類似C的protected member
#單底線的member在執行行並沒有實際差異
#但單底線的member表示此member不應該被其他人或是Child使用

print(dir(c))
#[‘_Parent__double’, ‘__class__’, … ‘__weakref__’, ‘_single’]

#c.__double() AttributeError: ‘Child’ object has no attribute ‘__double’
c._Parent__double()
#雙底線的member在child是沒辦法被直接存取
#Python並沒有所謂的private function,但可以用雙底線達到類似的效果
[/code]

閱讀全文

[Python] multiple import

[code lang=”python”]#a.py
print("in a.py berfore import b")
import b
print("in a.py after import b")
[/code]
[code lang=”python”]#b.py
print ("in b.py")
[/code]
[code lang=”python”]#c.py
print("in c.py berfore import b")
import b
print("in c.py after import b")
[/code]
[code lang=”python”]#d.py
print("in d.py berfore import a")
import a
print("in d.py after import a")

print("in d.py berfore import c")
import c
print("in d.py after import c")
[/code]

in d.py berfore import a
in a.py berfore import b
in b.py
in a.py after import b
in d.py after import a
in d.py berfore import c
in c.py berfore import b
in c.py after import b
in d.py after import c
>>> a.b.x = 1
>>> c.b.x
1
>>> a.b

>>> c.b

>>> 

重複import會被視為同一個物件