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