接下來這一篇算是收割前面幾個章節的章節小練習,基本上我是盡量規劃每過幾個章節就有一些小作業、小東西,最主要是希望這個系列不只是學習 Python 而是希望透過實際一些小練習來讓加深印象。
相信許多人在學習程式語言的時候,應該很常遇到 BMI 計算的小作業,不外乎這邊我也是一樣會使用 BMI 計算當作小練習,而接下來小作業的功能很小,剛剛好適合練習:
當然這邊為了完成條件製作,可能會使用到一些前面完全沒有聊過、講過的語法,畢竟作業在製作上都會有一定難度,所以這邊也是為了要訓練 Google 的技巧,透過 Google 去學習額外的許多知識。
廢話也差不多了,接下來先讓我們看一段可能、大概、或許、應該你已經看到膩的 BMI 公式:
BMI = 體重(公斤) / 身高2(公尺2)
很好,相信你看到這邊你已經非常興奮的知道怎麼做了。
所以這一篇就到這邊結束
前面開玩笑的,怎麼可能就這樣結束呢?所以一開始前面就先以平易近人的簡易 JavaScript BMI 計算來寫一遍,畢竟我們是從 JavaScript 角度學 Python 你說是吧?
(運作邏輯與程式碼這邊就不再著墨說明。)
// 身高 175 體重 68
((68 / ((175 ** 2) / 100)) * 100).toFixed(2); // 22.20
// 身高 178 體重 75
((75 / ((178 ** 2) / 100)) * 100).toFixed(2); // 23.67
// 身高 161 體重 45
((45 / ((161 ** 2) / 100)) * 100).toFixed(2); // 17.36
前幾個章節的函式有聊到可以將重複性的行為給包裝起來,上方我們可以注意到,除了 體重 與 身高 是會隨著使用者輸入而變化之外,其他參數都是固定的,因此我們就可以包裝成一個函式直接重複呼叫:
function bmi (kg, cm) {
console.log('BMI 計算:', ((kg / ((cm ** 2) / 100)) * 100).toFixed(2));
}
bmi(68, 175); // 22.2
bmi(75, 178); // 23.67
bmi(45, 161); // 17.36
看完平易近人的 JavaScript 後,讓我們回到我們這一次的目標 Python 吧!
那麼上面的 BMI 計算如果要改寫成 Python 的版本又該如何撰寫呢?一開始難度先不拉那麼高,讓我們一步一腳印慢慢打穩基礎之後再來挑戰更難的,所以一開始先試著撰寫跟 JavaScript 版本一樣還沒包裝成函式之前的方式:
# 身高 175 體重 68
print(68 / ((175 ** 2) / 100) * 100) # 22.20408163265306
# 身高 178 體重 75
print(75 / ((178 ** 2) / 100) * 100) # 23.671253629592226
# 身高 161 體重 45
print(45 / ((161 ** 2) / 100) * 100) # 17.36044134099765
基本上我們可以看到輸出的結果中小數點超級的多,但是在這邊我們只取小數點第二位。
那...只取小數點第二位的話我們這邊該怎麼做呢?在 Python 中有一個函式叫做 round()
可以幫助我們四捨五入取得特定小數點:
round(x, y)
x
要四捨五入的表達式y
要取得小數點第幾位的表達式因此接下來我們就直接套用 round
函式:
print(round(68 / ((175 ** 2) / 100) * 100, 2)) # 22.20
print(round(75 / ((178 ** 2) / 100) * 100, 2)) # 23.67
print(round(45 / ((161 ** 2) / 100) * 100, 2)) # 17.36
要注意 round
函式若是沒有傳入 y
參數的話,預設是會直接將小數點全部四捨五入:
print(round(68 / ((175 ** 2) / 100) * 100)) # 22
print(round(75 / ((178 ** 2) / 100) * 100)) # 24
print(round(45 / ((161 ** 2) / 100) * 100)) # 17
那麼透過上面程式碼我們也可以得知基本上也是除了 身高、體重 之外都不會有任何變動,所以搭配函式之後我們可以這樣寫:
def bmi (kg, cm):
print('BMI 計算結果:', round((kg / ((cm ** 2) / 100)) * 100, 2))
bmi(68, 175) # BMI 計算結果:22.2
bmi(75, 178) # BMI 計算結果:23.67
bmi(45, 161) # BMI 計算結果:17.36
除此之外你也可以試著挑戰使用前面所學的 lambda
改寫程式碼,讓整體程式碼更短更簡潔:
bmi = lambda kg, cm: print('BMI 計算結果:', round((kg / ((cm ** 2) / 100)) * 100, 2))
bmi(68, 175) # BMI 計算結果:22.2
bmi(75, 178) # BMI 計算結果:23.67
bmi(45, 161) # BMI 計算結果:17.36
嘗試使用 lambda
之後有沒有很想把全部程式碼改用 lambda
呢?
當然如果你不想使用 BMI 計算當作練習的話也可以考慮使用別的,例如:匯率、單位計算等等,假設你很沒有想法的話,我個人推薦 這個網站 的計算機,任何一個你都可以去撈出來試著研究製作練習看看。
這邊也額外聊一下關於字串相加的部分,為什麼會講到這個呢?主要原因是每個人製作作業呈現的方式不一定,而這邊可能會遇到一些小雷點,所以就順便聊一下關於字串組合的部分。
在前一篇我們已經遇到一個雷點是關於 整數 與 字串 相加的雷點,那麼在早期我們在寫 JavaScript 中主要都是使用加號運算子達到字串相加的需求,而這又稱之為字串連結 or 字串相加:
console.log('第'+ day +'天');
而在 ES6 之後出了一個非常非常方便的語法叫做樣板字面值 (Template literals) 的新語法,在開發上組合字串時是非常方便的,尤其是組合 DOM 的時候:
console.log(`第${day}天`);
那麼 Python 呢?前面我們已經嘗試過所謂的字串連結,如果傳入的不是相同型別,例如:整數 (int
) 那麼就必須做型別轉換:
day = 1
print('第'+ str(day) +'天')
而這種字串相加的方式其實非常麻煩,你必須一直輸入 '
、"
與 +
等符號,那...Python 也有跟 JavaScript 一樣類似的樣板字面值 (Template literals) 語法嗎?嚴格說起來是有的,只是在 Python 中稱之為「 字串格式化(String formatting) 」:
day = 1
print(f'第{day}天')
不知道你有沒有注意到一件事情,上面的字串格式化範例我並沒有使用 str()
做型別轉換,但是上面範例確實是不會出現錯誤的,因為字串格式化會自己幫你傳入的任何東西都轉換為 String 型別。
你有沒有感覺到字串格式化方便方便超多!
主要使用的方式是在字串最前方加上一個小寫 f
or 大寫 F
,接著使用 {}
插入要組合的表達式(expression),例如像是變數也可以:
day = 1
print(f'第{day}天')
剛剛也有提到 {}
內只接受表達式,所以 lambda
也是可以的,只是要記得用類似 IIFE 寫法:
print(f'我叫做{ (lambda name: name)("Ray") },你好')
所以上一篇函式的程式碼我們可以改成這樣:
def fn(day):
print(f'第{day}天')
print('起床')
print('刷牙')
print('運動')
print('中午吃飯')
print('午睡')
print('下午運動')
print('晚上吃飯')
print('晚上洗澡')
print('睡覺')
print('---------')
fn(1)
相較之下使用字串格式化會比使用字串連結較簡潔好寫而且也不用,最後也附上 JavaScript 與 Python 兩者都改成相同的 BMI 計算語法比較:
最後就讓我們使用迷因結束今天的回合吧:
最後的最後,算是簡單優化一下 BMI 計算功能而已,延續上方的 BMI 練習題目,我們可以試著在 BMI 中增加判斷式,例如:
def bmi (kg, cm):
if kg <= 0:
return print('體重輸入不正確')
if cm <= 0:
return print('身高輸入不正確')
bmiNum = round((kg / ((cm ** 2) / 100)) * 100, 2)
if bmiNum < 18.5:
print(f'你目前的 BMI 是:{bmiNum},介於過輕範圍內。')
elif 18.5 >= bmiNum < 24:
print(f'你目前的 BMI 是:{bmiNum},介於正常範圍內。')
elif 24 >= bmiNum < 27:
print(f'你目前的 BMI 是:{bmiNum},介於過重範圍內。')
elif 27 >= bmiNum < 30:
print(f'你目前的 BMI 是:{bmiNum},介於輕度範圍內。')
elif 30 >= bmiNum < 35:
print(f'你目前的 BMI 是:{bmiNum},介於中度範圍內。')
elif bmiNum >= 35:
print(f'你目前的 BMI 是:{bmiNum},介於中度範圍內。')
else:
print('計算錯誤。')
bmi(68, 175) # 你目前的 BMI 是: 22.2 介於過重範圍內。
bmi(95, 185) # 你目前的 BMI 是: 27.76 介於中度範圍內。
今天這一份程式碼將會放在這個儲存庫:https://github.com/hsiangfeng/javascript-to-python
OH!NO!今天本來要做最後一片花雕醉雞,結果打開之後發現雞肉已經臭掉了...事實證明千萬不要抓剛剛好過期那天處理全部的雞肉。