[TOC] ## Code review #1 by Angela ### Q16 * 可以把題目設定的數字都寫得更彈性,讓程式可以額外設定 ```javascript // 例如我目前就把偏移量宣告一個變數,所以在跑messageOfQ16的時候就可以先調整shift的值 const shift = 3; console.log(messageOfQ16(answer, shift)); // 所以,也可以把5個字母的5設定出來 ``` * readline使用reject的情境可以是:如果使用者超過某個時間沒有輸入的話就會reject ## Code review #2 by Eva ### Q17 * 可以思考完全符合業主的需求就好,還是做點彈性 * 但17題目標還是先把需求做出來就好 * 我目前的寫法是以候選人的角度,可以和以選票的角度去寫的方法比較優缺點 * 比較票數的function可以寫在另一個class裡 * 但我不會寫orz ```javascript class Candidates { constructor({ candidatesScores }) { this.candidatesScores = candidatesScores || [0, 0, 0, 0]; } get sameHighestSCoreCandidates() { const rawScores = [ new Candidate(1).score, new Candidate(2).score, new Candidate(3).score, new Candidate(4).score, ]; return rawScores.sort().filter(); } } ``` * 命名不要怕字數很多很長,寫清楚比較重要!! * 找出最大值可以用Math.max ```javascript // 原本用排序來找最大值 const sortedCandidates = candidates.toSorted((candidate1, candidate2) => { return candidate2.score - candidate1.score; }); //使用Math.max const scoresOfCandidates = candidates.map((candidate) => candidate.score); const maxScore = Math.max(...scoresOfCandidates); ``` ## Code review #final by Chris ### Q17 * Q17預設要練習的是什麼? * 練習實作演算法,照別人的邏輯把code寫出來 * 資料整理也要寫成code,不然怎麼知道人工有沒有key錯 ```javascript // 我原本的寫法是一個一個把資料key進去 const candidate1 = new Candidate(1); candidate1.setVotes("firstOrderVotes", 51); candidate1.setVotes("fourthOrderVotes", 5, 23, 21); const candidate2 = new Candidate(2); candidate2.setVotes("firstOrderVotes", 23); candidate2.setVotes("secondOrderVotes", 5); candidate2.setVotes("thirdOrderVotes", 51, 21); const candidate3 = new Candidate(3); candidate3.setVotes("firstOrderVotes", 5); candidate3.setVotes("secondOrderVotes", 51, 23, 21); const candidate4 = new Candidate(4); candidate4.setVotes("firstOrderVotes", 21); candidate4.setVotes("thirdOrderVotes", 5, 23); candidate4.setVotes("fourthOrderVotes", 51); --- // 應該要能直接從表格中整理資料 // | # | 51票 | 5票 | 23票 | 21票 | // | 第一順位 | 1 | 3 | 2 | 4 | // | 第二順位 | 3 | 2 | 3 | 3 | // | 第三順位 | 2 | 4 | 4 | 2 | // | 第四順位 | 4 | 1 | 1 | 1 | // 假設資料以csv傳入 const data = `51,5,23,21 1,3,2,4 3,2,3,3 2,4,4,2 4,1,1,1`; function processData(allText) { var allTextLines = allText.split("\n"); var headers = allTextLines[0].split(","); const lines = allTextLines.map((strLine, index) => { const arrLine = strLine.split(","); const result = new Map(); // 做成Map物件是為了要迭代 headers.forEach((header, headerIndex) => { result.set(header, arrLine[headerIndex]); }); return result; }); return lines.slice(1); } console.log(processData(data)); // [ // Map(4) { '51' => '1', '5' => '3', '23' => '2', '21' => '4' }, // Map(4) { '51' => '3', '5' => '2', '23' => '3', '21' => '3' }, // Map(4) { '51' => '2', '5' => '4', '23' => '4', '21' => '2' }, // Map(4) { '51' => '4', '5' => '1', '23' => '1', '21' => '1' } // ] ``` > Map物件[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach) * 盡量不要用寫死的名稱來表示有順序的東西 * 把這些order改成array,用index來代表order ```javascript // 原本寫的 this.firstOrderVotes = [23]; this.secondOrderVotes = [5]; this.thirdOrderVotes = [51, 21]; this.fourthOrderVotes = [0]; // 改成 votes = [ [23], [5], [51, 21], [0] ] ``` * 直接用整份資料的角度去寫 ```javascript // 橫列為一陣列 const votes = [51, 5, 23, 21]; const orders = [ [1, 3, 2, 4], [3, 2, 3, 3], [2, 4, 4, 2], [4, 1, 1, 1], ]; // 直排為一陣列 // [總票數, 順位1, 順位2, 順位3, 順位4] // 順位剛好等同於index const votingCompositions = [ [51, 1, 3, 2, 4], [5, 3, 2, 4, 1], [23, 2, 3, 4, 1], [21, 4, 3, 2, 1], ] ``` ### 其他補充 #### 軟體工程的本質性及附屬性 from 人月神話 > 軟體的本質相當抽象,由許多概念組合而成,但無論有多少種呈現方式,其基本構造都是不變的,可區分為本質性及附屬性 * 本質性問題:不可消滅的複雜度 * 例如我最後一定要印出一行字,那`console.log`就是不可消滅的程式碼 * 附屬性問題:怎麼去解決本質性問題。我們要學習的是控制附屬性問題的厚度適當,小但足以形容問題。 * 厚度不要太小:例如要適當的命名,讓問題得以被理解 * 厚度不要太大:用了一堆花俏的技術來解決簡單的問題,殺雞焉用牛刀🔪 #### 了解JavaScript的3大方向:new, this, 繼承 * 先去了解new這個運算子在做什麼,試著實作看看 > [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new#description) #### OOP * 三大要素:封裝、繼承、動態連結 * Date這個物件可以幫助理解OOP的封裝,以及get, set的運作 * 永遠無法得知Date裡面到底存了什麼,只能用各種method去取得格式化後的值 ![image](https://hackmd.io/_uploads/Sk8z_Zzu0.png)