---
# System prepended metadata

title: +_q11~q17 code review
tags: [CodeReview]

---

# +_q11~q17 code review

# Chris q6~q10_code review
想看哪幾題：

## q12
#### if...else
目前這樣寫有點威脅感，如果(...)就這樣，不然就給你怎樣
```javascript!
if (rangeStart > 0 && rangeEnd > 0 && multipleLimit > 0) {
  const primeList = getPrimeListOfThisRange(rangeStart, rangeEnd);
  const multiplesList = getMultiplesList(primeList, multipleLimit);
  const allPrimeMultiples = getAllPrimeMultiples(primeList, multiplesList);
  return (`10~20 的質數有：${primeList}\n${showResult(primeList, allPrimeMultiples)}`)
} else {
  throw new Error(`請輸入正數`);
}
```
Chris 覺得比較好的寫法是：
區分正常和不正常部分，讓一看就知道正在處理哪個部分，所以通常會寫==如果是什麼條件，就拋錯誤==，正常情況就不會被包在 if...else 裏面，就是 early return 寫法
```javascript!
// 而且這邊可以很多條件(不用寫巢狀)，而這段 if 就算消失也不會怎樣，正常 code 都不會動到，就少了威脅感
  if (rangeStart <= 0 || rangeEnd <= 0 || multipleLimit <= 0) {
    throw new Error(`請輸入正數`);
  }

  const primeList = getPrimeListOfThisRange(rangeStart, rangeEnd);
  const multiplesList = getMultiplesList(primeList, multipleLimit);
  const allPrimeMultiples = getAllPrimeMultiples(primeList, multiplesList);
  return (`10~20 的質數有：${primeList}\n${showResult(primeList, allPrimeMultiples)}`)
```

### getMultiplesList 命名
```javascript!
命名遇到 number，要小心，number 對於問題的定義太模糊了
書上寫：遇到 number 去想它是 index 還是 total？
終究會有更貼近意義的命名，是級數的 number 嗎？還是什麼的 number，這些數字有關係嗎，一定有東西可以加進去
```

### fill 改寫(歐買尬)
```javascript!
function generateNumberList(rangeStart, rangeEnd) {
  return Array(rangeEnd - rangeStart + 1).fill().map((_, index) => {
    return rangeStart + index;
  });
}

// 改寫為
function generateNumberList(rangeStart, rangeEnd) {
  return Array(rangeEnd - rangeStart + 1).fill(rangeStart).map((init, index) => {
    return init + index;
  });
}
```

```javascript!
function generateNumberList(rangeStart, rangeEnd) {
  return Array(rangeEnd - rangeStart + 1).fill(rangeStart).map((init, index) => {
    return init + index;
  });
}

export function getMultiplesList(primeList, multipleLimit) {
  return primeList.map((prime) => {
    const multipleCount = Math.floor(multipleLimit / prime);

    return generateNumberList(1, multipleCount)
      .map(multiple => multiple * prime);
  })
  // [9, 7, 5, 5]
  // return Array(multipleCount).fill(0).map((_, numberIndex) => {
  //   return (numberIndex + 1)
  // });
  // [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
  // [ 1, 2, 3, 4, 5, 6, 7 ],
  // [ 1, 2, 3, 4, 5 ],
  // [ 1, 2, 3, 4, 5 ] 
  // ]
  // })
}
```

### 關於寫 code 的整理
```javascript!
現在自己看自己的 code 就是覺得還 ok 吧，但被 Chirs 整理過後就變成大改造，可以繼續練習思考重構和閱讀性這件事情 QQ 
像是有些東西是不是拿到就要馬上存起來做計算，或是要再跑下一次迴圈重新拿再做計算？

例如我 q12 先在一個 算倍數的 function 送 質數陣列和 100 的限制當參數，拿到 11 可以乘以 9 次 的 [1,2,3,4,5,6,7,8,9] 和其他的質數要乘以幾次
然後再做一個 function 放 這個倍數 function 和質數陣列進去算乘積
>> 啊我怎麼不在第一支 function 的時候就乘起來！就不用再用第二個 function 再跑一次迴圈了:) 尬電，不知道自己在想什麼，被一支 funciton 做一件事情蒙蔽了

最直接反應是效能，但如果沒有比較好讀，就會選擇分開寫
```
### q12.test
![image](https://hackmd.io/_uploads/Byxa5trj0.png)
```javascript!
測試不應該出現 console.log
原因是因為我 q12 這隻 function 是從 main 來的，讀到 main 的時候會全部跑一次，main 裡面就有 console.log 
```

### 測試是出貨檢驗報告
```javascript!
當品管收到檢驗報告的時候，他們會進行相同手法的測試，做一樣的事情看是否可以得到相同結果。

我現在的測試 1/ 的說明文字只有說要列出倍數，但是沒有說倍數是什麼，所以出錯了可能也看不出來。
所以可以：把範圍縮小，然後列出來 會比較好，很快的可以明確清楚知道是要檢驗哪些會比較好。
```
![image](https://hackmd.io/_uploads/rJZ04qHjR.png)

### 有 throw new Error 記得寫 try...catch 不然要 throw 去哪啦！直接噴錯！

## q15 
### 為什麼會覺得拿 index 來操作不好
```javascript!
Chris：index 是在寫程式的，是工程師會想到的事情，有時候寫程式會讓一切看起來像在"操作現實世界事物的感覺"。

< 寫 code 描述現實事物，會比拿來堆砌流程好很多 >
```

### 控制迴圈只有一個出口一個入口
```javascript!
function getTotalCargo(equipmentList, carWeightLimit) {
    const sport = Array(3).fill(0);
	
    let currentWeight = 0;
	
  while(currentWeight < carWeightLimit) {
    const currentItemIndex = getRandomItemIndex(equipmentList);
    let randomItemWeight = equipmentList[currenItemIndex].weight;
    if (currentWeight + randomItemWeight > carWeightLimit) {
      break;
    }
    currentWeight += randomItemWeight;
    sport[currentItemIndex] += 1;
  }
  return { sport, currenWeight };
}
```
改寫為
```javascript!
function getTotalCargo(equipmentList, carWeightLimit) {
  const sport = Array(3).fill(0);

  let currentWeight = 0;

  let currentItemIndex = getRandomItemIndex(equipmentList);
  let randomItemWeight = equipmentList[currentItemIndex].weight;

  do {
    currentWeight += randomItemWeight;
    sport[currentItemIndex]++;

    currentItemIndex = getRandomItemIndex(equipmentList);
    randomItemWeight = equipmentList[currentItemIndex].weight;

  } while (currentWeight + randomItemWeight < carWeightLimit);

  return { sport, currentWeight };
}
```
### 這樣是拿容器裏面的 code 來用
```javascript!
sport[currentItemIndex]++;
// 不用選，直接是 sport 這個容器隨機骰到哪個 index 就會幫我選好

// 不然我原本寫這樣哈哈哈哈哈哈
if(index === 0) {
  搬什麼
}
if(index === 1) {
  搬什麼
}
if(index === 2) {
  搬什麼
}
```
### 如果要用 constructor
```javascript!
車也要做出來喔，磅秤要有一個 is okay? okay 再放上車，建構物件的時候會很囉唆，很多細小行為都可以去定義它，呼叫他的時候很愉快，寫一個車滿了嗎，還沒繼續放，就目前這樣算是做一半，想像一個場景，有工人在把這些東西搬上車，步驟是怎麼樣？就真的要想好那些步驟器材物件，加上貨物重量也要定義好，要有磅秤、重量登記版等等等，不物件的寫法就很像在空氣中！就在你心中算而已！
```
## q17

### == null 就是 === null || === undefined
### 真心建議先跑一個迴圈做檢查，確定沒問題再開始做事
```javascript!
votingInfo.forEach(info => {
  if(info.votes !== undefined && info.rank !== undefined){
    info.rank.forEach((info.rank.forEach((candidate, index) => {
      totalScoresList[candidate - 1] += info.votes * scoreStandard[index];
    });
} else {
    throw new Error(`請輸入完整投票資訊`);
} 
    return totalScoresList
});
```
改為
```javascript!
votingInfo.forEach(info => {
  if (info.votes == null || info.rank == null) { 
    throw new Error(`請輸入完整投票資訊`);
    }
  });
  votingInfo.forEach((info) => {
    info.rank.forEach((candidate, index) => {
      totalScoresList[candidate] += info.votes * scoreStandard[index];
    });
  })
  return totalScoresList
```

#### votingInfo 這個 info 就是在切版的時候用 contianer . box 一樣道理
```javascript!
const votingInfo = [
  { votes: 51, rank: [1, 3, 2, 4] },
  { votes: 5, rank: [3, 2, 4, 1] },
  { votes: 23, rank: [2, 3, 4, 1] },
  { votes: 21, rank: [4, 3, 2, 1] }
];
// 一定有一個更好的詞可以用

result 是結果 但是還沒算而已
```
#### info 可以改成 item
```javascript!
item 就會隱喻這個東西是一個 Array/List

你就會知道，哇這是一個陣列，可以 forEach 嗎來看看裡面有什麼東西
```
```javascript!
votingInfo.forEach(info => {
  if (info.votes == null || info.rank == null) { 
    throw new Error(`請輸入完整投票資訊`);
    }
  });
```
#### 變工程師，思想上會有些模糊地帶需要釐清，學會精準用字
#### index 巧妙之處
```javascript!
export function getCandidateScoresList(votingInfo) {
  let totalScoresList = [0, 0, 0, 0]; 
  const scoreStandard = [4, 3, 2, 1];

  votingInfo.forEach(info => {
    if (info.votes == null || info.rank == null) { 
      throw new Error(`請輸入完整投票資訊`);
    }
  });
  votingInfo.forEach(info => {
    info.rank.forEach((candidate, index) => {
      totalScoresList[candidate - 1] += info.votes * scoreStandard[index];  ----> 這邊的 [candidate - 1] 可能會有點難讀
    });
  })
  return totalScoresList
}
```
```javascript!
export function getCandidateScoresList(votingInfo) {
  let totalScoresList = [0, 0, 0, 0, 0];  ----> 改這樣 
  const scoreStandard = [4, 3, 2, 1];

  votingInfo.forEach(info => {
    if (info.votes == null || info.rank == null) { 
      throw new Error(`請輸入完整投票資訊`);
    }
  });
  votingInfo.forEach(info => {
    info.rank.forEach((candidate, index) => {
      totalScoresList[candidate] += info.votes * scoreStandard[index]; ----> 這邊就真的是候選人1234了
    });
  })
  return totalScoresList
}
```
![image](https://hackmd.io/_uploads/ByG5yCrs0.png)
```javascript!
export function q17(votingInfo) {
  const totalScoresList = getCandidateScoresList(votingInfo);
  return totalScoresList.map((score, scoreIndex) => {
    if (scoreIndex === 0) return ''; ---> 回傳就會變成五個元素，再把第一個元素 Bang 掉，下方 return 就會 1234
    return `候選人${scoreIndex} 得 ${score} 分`;
  }).join('\n');
}
```
### 
```javascript!
  const votingInfo = [
    { votes: 51, rank: [1, 3, 2, 4] }, 
    { votes: 5, rank: [3, 2, 4, 1] },
    { votes: 23, rank: [2, 3, 4, 1] },
    { votes: 21, rank: [4, 3, 2, 1] }
  ];

// Chris 會想用成這樣來做事，這樣後面的東西直接可以用比較合乎邏輯的 index 來做事
  const votingInfo = [
  [51, 1, 3, 2, 4],
  [5, 3, 2, 4, 1],
  [23, 2, 3, 4, 1],
  [21, 4, 3, 2, 1]
];
```