# JS直播班-BMI kata練習_書豪經驗分享 ## 1. 用了哪些軟體錄製跟記錄倒數 ※ 我的電腦是WIN10環境,以下軟體皆是以WIN10的環境進行。 ### 。錄影軟體:[ActivePresenter](https://atomisystems.com/download/) 8.3.2版       這是老師的google表單中推薦的軟體,[使用教學](https://hackmd.io/@Albertnotes/HJEOF92dI)在此。       我在錄製時是選擇沒有錄聲音,所以不會把一邊聽的音樂錄進去。       為了公正無爭議,所以我錄全螢幕,右下角可以看到WINDOWS的時間    ![](https://i.imgur.com/L5sNQeu.png) 跟教學文中比較不一樣的地方是「導出」的地方沒有Youtube這個選項, 所以我是導出成「視頻」(就是影片啦),再另外上傳到Youtube去的。 ![](https://i.imgur.com/mJGZQJB.png) *** ### 。記錄倒數:鬧鐘與時鐘(WIN10內建的)       點左下角的WINDOWS圖案,然後直接打字「鬧鐘」就會出現囉! ![](https://i.imgur.com/20husrH.png) 一開始練習時,我訂了3個計時器:5分鐘 & 10分鐘 & 1小時 5分鐘、10分鐘:想知道5分鐘、10分鐘時我大約可以寫到哪裡 1小時:先瞭解自己第一次大概要花多久時間,所以訂長一點 然後隨著速度變快,就只留下目標的計時器 ![](https://i.imgur.com/rMkCuM8.png) *** ### 。寫Code軟體:[VSCode(Visual Studio Code)](https://code.visualstudio.com/) 插件:Live Server 這個插件,可以在存檔時,就自動重新整理網頁內容,所以console.log也會自動重整成最新的,可以省下跳到網頁視窗重整的時間。 ![](https://i.imgur.com/0bj1HfK.png) 使用時,按右下角的「Go Live」就會開啟網頁,每當存檔時,就能直接在那個網頁上即時重整囉! ![](https://i.imgur.com/QAgiUL1.png) 另外提醒一下,如果想要讓人知道自己按了什麼按鍵,就要開啟「Toggle Screencast Mode」模式 像這樣: ![](https://i.imgur.com/RAaf9lq.png) 以下講解開啟此模式的步驟: 左上角功能列:檢視 → 命令選擇區 (會在中間出現命令選擇區介面) ![](https://i.imgur.com/JipwtZc.png) 在命令選擇區裡,輸入「Toggle Screencast Mode」 ![](https://i.imgur.com/vHDDbak.png) 點擊搜尋出來的「Toggle Screencast Mode」模式,就開啟完成 ![](https://i.imgur.com/nm45ZWy.png) *** ## 2. 如何做前置作業,以及安排視窗切割 ### 。視窗安排:如下圖   - 左邊用來寫Code   - 為了能即時看到Console.log的結果,所以我把網頁開在右邊   - 另一個網頁準備好Google翻譯,需要時可以查   - 又另一個視窗,那是計時器 ![](https://i.imgur.com/2pwckfc.png) *** ### 。前置作業 & 練習過程: (1) 先看清楚題目要求、此程式的目標要做什麼 (2) 查清楚BMI規則、初步整理需要的規則 (3) 把Code寫出來,看是否達成題目要求 (4) 開始優化Code,把Code改成自己覺得好的樣子 (5) 按照寫好的Code,整理自己的邏輯思緒,記得大致上要寫哪些東西 (6) 開始重寫,提升流暢度,優化哪邊該先寫等流程 (7) 評估哪些地方讓我用滑鼠來回滾動查找的,把資訊整理在一起方便看 (8) 繼續重寫,提升流暢度,優化流程 (9) 達到自己當前的極限 (10) 評估要怎樣改Code才有辦法達成時間目標(10分鐘、5分鐘),或沒有辦法達成(?) (11) 參考別人寫的Code有什麼優點可以借鏡、自己花很多時間的操作有沒有快速鍵可幫忙? (12) 為了極速特化而精簡Code (13) 繼續重寫,提升流暢度,優化流程 (14) 知道自己有沒有辦法達成:可行 → 再更快;不可行 → 先這樣就好 *** ## 3. 編輯器熱鍵分享 我...我好像沒怎麼用熱鍵(遮臉) 存檔:Ctrl + s 複製:Ctrl + c 貼上:Ctrl + v 還原:Ctrl + z 跳到那行最後面:End 跳到那行最前面:Home 選取一段文字:滑鼠連點兩下 有一些打過的指令,會在打的過程中出現,可以按Tab省打幾個字 *** ## 4. BMI kata 的程式碼分享 ### 。程式碼:亦可在[codepen](https://codepen.io/zshao1031/pen/qBqMXWz)上看 ```scss= // 【預先整理的資料】 // BMI值計算公式: BMI = 體重(公斤) / 身高(公尺)平方 // overThin 過輕 BMI < 18.5 您的體重過輕,健康指數為藍色 // normal 正常 18.5 <= BMI < 24  您的體重正常,健康指數為紅色 // overWeight 過重 24 <= BMI < 27 您的體重過重,健康指數為澄色 // mildFat 輕度肥胖 27 <= BMI < 30 您的體重輕度肥胖,健康指數為黃色 // moderateFat 中度肥胖 30 <= BMI < 35 您的體重中度肥胖,健康指數為黑色 // severeFat 重度肥胖 35 <= BMI 您的體重重度肥胖,健康指數為綠色 // 【第二階段題目附的程式碼】 const bmiStatesData = { "overThin": { "state": "過輕", "color": "藍色" }, "normal": { "state": "正常", "color": "紅色" }, "overWeight": { "state": "過重", "color": "澄色" }, "mildFat": { "state": "輕度肥胖", "color": "黃色" }, "moderateFat": { "state": "中度肥胖", "color": "黑色" }, "severeFat": { "state": "重度肥胖", "color": "綠色" } } // 【以下是自己寫的程式碼】 let bmiHistoryData = []; // 第三階段用 function printBmi(cm,kg){ let bmi = (kg/((cm/100)**2)).toFixed(2); // 算出BMI let state; // 若輸入的是文字,或是讓bmi變成0或負數,就是資料有誤 if(bmi == "NaN" || bmi <= 0){ console.log("您的數值輸入錯誤,請重新輸入"); return;                   // 輸入資料有誤,就不需要進行後面的行動了,所以直接return跳出 } else if( bmi < 18.5) state = "overThin"; // 過輕 else if( bmi < 24) state = "normal"; // 正常 else if( bmi < 27) state = "overWeight"; // 過重 else if( bmi < 30) state = "mildFat"; // 輕度肥胖 else if( bmi < 35) state = "moderateFat"; // 中度肥胖 else state = "severeFat"; // 重度肥胖 // 印出第一階段、第二階段結果用 console.log(`您的體重${bmiStatesData[state].state},健康指數為${bmiStatesData[state].color}`); // 以物件的形式,將此次的bmi、state結果存入bmiHistoryData陣列裡 bmiHistoryData.push({bmi,state}); } // 第三階段,印出最終結果 function showHistoryData(){ console.log(`您總共計算 ${bmiHistoryData.length} 次 BMI 紀錄,最後一次 BMI 指數為 ${bmiHistoryData[bmiHistoryData.length-1].bmi},體重${bmiStatesData[bmiHistoryData[bmiHistoryData.length-1].state].state}!健康指數為${bmiStatesData[bmiHistoryData[bmiHistoryData.length-1].state].color}!`); } printBmi(178, 20); printBmi(178, 70); printBmi(178, 85); // printBmi(178, 90); // printBmi(178, 110); // printBmi(178, 130); printBmi("身高","體重"); showHistoryData(); ``` *** ### 題目:按照第一階段、第二階段、第三階段的順序寫出符合題目要求的程式碼 ### 【第一階段】 ```scss= 【第一階段】請寫 printBmi 函式,並印出對應狀態 printBmi(178, 20) >> 印出 console.log 文字為「您的體重過輕」 printBmi(178, 70) >> 印出 console.log 文字為「您的體重正常」 printBmi(178, 85)>> 印出 console.log 文字為「您的體重過重」 printBmi(178, 90)>> 印出 console.log 文字為「您的體重輕度肥胖」 printBmi(178, 110)>> 印出 console.log 文字為「您的體重中度肥胖」 printBmi(178, 130)>> 印出 console.log 文字為「您的體重重度肥胖」 printBmi("身高","體重")>> 印出 console.log 文字為「您的數值輸入錯誤,請重新輸入」 ```   。我的解題流程:   1. 題目要求要印出查BMI的結果,所以先查BMI的規則    公式是要輸入身高、體重來計算出一個數值,再用此數值落在哪個區間判斷此人體態狀況   2. 題目給的 printBmi(178, 70); 看起來是輸入身高178公分、體重70公斤    而 printBmi 這個函式,必須要能印出題目指定的體態結果    (※ 提醒:公式中的身高是用「公尺」來計算,資料要是用公分必須要先換算)   3. 用題目給的數值試算BMI,確定體態的評估結果與題目要求的結果一致,確定理解題目無誤   4. 寫出BMI的計算公式,確認算出的數字正確   5. 寫出BMI各區間的if else判斷式,確認體態評估的結果正確   6. 思考輸入怎樣的內容會無法計算(輸入非數字)、或被判定為錯誤資料(BMI為0或負數 )   7. 將錯誤資料的判斷式加入原本的判斷式中(修改Code)   8. 確認結果與題目要求的相符 ※ 我所用的程式碼,基本上都是老師教過的,但格式簡化的部分~有些是老師沒提過的 (A) if(判斷式)後面如果只有一條指令,就可以省略 {} 而直接接在後面寫。 ```scss= 像是這樣:if( bmi < 24) state = "normal"; 跟這樣是相同的:if( bmi < 24){ state = "normal"; } 也跟這樣是相同的: if( bmi < 24){  state = "normal"; } ``` (B) bmi狀態的if判斷式,若輸入的是非數字,數學公式會無法計算,所以結果會是NaN 而這個NaN是字串,所以判斷式中要用""括起來 ```scss= if(bmi == "NaN" || bmi <= 0) ``` (C ) 上課沒直接教到的還有算「n次方」的寫法,還有取小數點以下x位的寫法 ```scss= 例如,要計算 a 的 b次方,寫成: a ** b; 這邊要算的是平方,所以寫成 ** 2 BMI公式 = 體重(公斤) / 身高(公尺)的平方 bmi = kg / ((cm / 100) ** 2) 而除法算出來常常小數點會有非常多位,這邊只要顯示到小數點以下第二位就好了 所以加上 .toFixed(2) bmi = (kg / ((cm / 100) ** 2)).toFixed(2); ``` *** ### 【第二階段】 ```scss= 【第二階段】請程式碼裡加入此(bmiStatesData)變數,並嘗試運用此變數裡的資訊。 printBmi(178, 20) >> 印出 console.log 文字為「您的體重過輕,健康指數為藍色」 printBmi(178, 70) >> 印出 console.log 文字為「您的體重正常,健康指數為紅色」 printBmi(178, 85)>> 印出 console.log 文字為「您的體重過重,健康指數為澄色」 printBmi(178, 90)>> 印出 console.log 文字為「您的體重輕度肥胖,健康指數為黃色」 printBmi(178, 110)>> 印出 console.log 文字為「您的體重中度肥胖,健康指數為黑色」 printBmi(178, 130)>> 印出 console.log 文字為「您的體重重度肥胖,健康指數為綠色」 printBmi("身高","體重")>> 印出 console.log 文字為「您的數值輸入錯誤,請重新輸入」 ``` 。我的解題流程:   1. 跟第一階段比起來,要求印出的內容只多了要印出顏色的後半句   2. 題目要求必須使用bmiStatesData裡的資料,這些資料包含了結果文字中要的體態跟顏色   3. 在第一階段的判斷式中,修改Code為記錄bmiStatesData裡分類用的英文(屬性)   4. 將印出結果的文字改為第二階段要求的那些文字   5. 憑第3點中記錄的英文(屬性),將文字中的體態與顏色,換成吃bmiStatesData的資料 ※ 使用的語法,沒有超出上課所教內容 *** ### 【第三階段】 ```scss= 【第三階段】儲存每筆計算資料,多一個變數為 bmiHistoryData,並賦予空陣列來儲存計算物件資料,若數值輸入錯誤,則不儲存。 printBmi(178, 20) >> 印出 console.log 文字為「您的體重過輕,健康指數為藍色」 printBmi(178, 70) >> 印出 console.log 文字為「您的體重正常,健康指數為紅色」 printBmi(178, 85)>> 印出 console.log 文字為「您的體重過重,健康指數為澄色」 showHistoryData() >> 印出 console.log 文字為「您總共計算 3 次 BMI 紀錄,最後一次 BMI 指數為 26.83,體重過重!健康指數為澄色!」 ```  。我的解題流程:   1. 要求要將BMI查詢結果記錄在陣列中、且輸入錯誤的資料不儲存   2. 要求要有一個showHistoryData()函式來印出一段不同的文字   3. 要求包括「計算了幾次(有幾筆資料)」、最後一筆資料的「BMI數值」、「體態」、「顏色」   4. 在printBmi函式裡,增加將資料記入(push)陣列的程式碼   5. 在showHistoryData函式哩,去讀陣列的資料,來印出題目要求的結果 ※ 經老師提點,記資料到陣列時,應該只要記錄關鍵的內容 ※ 我原本寫的還會記錄一些重複的描述文字,這樣要是想要用別的文字內容來顯示 BMI 結果,這樣的記錄就會因為寫太死而做不到,而且還會浪費記憶體,確實應該精簡 ※ 後來再看一次老師錄的影片,裡面是用物件去記關鍵內容,我已改為用物件去記錄   但這邊是用簡寫的方法寫的,比較如下: ```scss= 原本的寫法: bmiHistoryData.push(`BMI 指數為 ${bmi},體重${bmiStatesData[state].state}!健康指數為${bmiStatesData[state].color}!`); 新的寫法:用物件去記關鍵內容 bmiHistoryData.push({bmi,state}); 該物件完整寫法是這樣: {  bmi: bmi,  state: state } 若左邊的名稱跟右邊的變數名稱相同的話,可以簡寫成這樣: {  bmi,  state } 而若再把這個物件縮在一行內寫,就變成 {bmi, state} 了 把這個物件push到陣列裡,就變成 bmiHistoryData.push({bmi,state}); 了 ``` *** ## 5. 如何安排時間與頻率來進行訓練 其實我沒特別安排...這週末剛好沒啥事,而且外面又下大雨,是個適合專心練習的日子 在上課老師講解主線任務時~我就躍躍欲試了,所以一下課我就立刻開始寫第一遍,因為我打字速度還算可以,印象中花了18分鐘左右完成第一次。 然後覺得不滿意的地方有點多,就又想立刻動手改起來 結果,調整了一下就能接近10分鐘了,就開始準備起錄影 就順著一股想一直做下去的心情一直又改又寫又錄的,達到了7分多的速度 那時評估這樣下去,就算手順再更順,頂多也只能6分多近7分,於是就決定休息了 隔天,看到有人回報他的影片,於是參考了一下後有了靈感 又開始改code,發現這樣的寫法很可以! 然後開始拚5分內,練習到達標! 過程大概就是這樣...憑心情XD