# +_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

```javascript!
測試不應該出現 console.log
原因是因為我 q12 這隻 function 是從 main 來的,讀到 main 的時候會全部跑一次,main 裡面就有 console.log
```
### 測試是出貨檢驗報告
```javascript!
當品管收到檢驗報告的時候,他們會進行相同手法的測試,做一樣的事情看是否可以得到相同結果。
我現在的測試 1/ 的說明文字只有說要列出倍數,但是沒有說倍數是什麼,所以出錯了可能也看不出來。
所以可以:把範圍縮小,然後列出來 會比較好,很快的可以明確清楚知道是要檢驗哪些會比較好。
```

### 有 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
}
```

```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]
];
```