---
# System prepended metadata

title: C_Q16-Q17 code review
tags: [CodeReview]

---

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