# 專案實作--松鼠人
- 先備知識:array, function, object
<hr>
某天,Johnny發現自己時不時會變成一隻毛茸茸的松鼠,這個現象一直困擾著他。因此,Johnny想藉由寫下日誌以記錄當天發生的事件,並觀測自己是否有變成松鼠人的情形

於是,他請教822的同學,我們簡單把他的要求拆成以下步驟:
1. 利用一個function把日誌包裹至大的陣列
2. 寫出相關係數的function
3. 將一段時間所記錄的日誌進行分析
那麼,開始解決Johnny的問題之前,我們先recall一下之前上過的內容
## Recall
#### Properties(屬性)
`Array.length` `Math.max`
- 上述等表達式以獲取該**物件**的某種屬性
#### Method(方法)
`dog.toUpperCase()` `sequence.push(5)`
- 使用method可以不需要參數,而是從methods of the value(屬性值)中取得該物件的值
- 當然,有參數也是可以的
#### Object(物件)
- a collection of any properties
- key-value pair
- for the case of day 1, we think of the style of diary wewant to write.
```htmlembedded=
<script>
let day1={
squirrel:false,
events:["work","touched tree","pizza","running"]
};
console.log(day1.squirrel);
console.log(day1.events);
</script>
```
try to think what is the "property", and what is the "value"?
- notice: `{}` `:`
- `key-value pair` looks like tentacles, which grasp the value. (像是變數)
簡單複習過後,可以開始解決問題了!!
## How to push the events into an array
```htmlembedded=
<script>
let journal=[];
function addEntry(events,squirrel){
journal.push({events,squirrel});
}
addEntry(["work", "touched tree", "pizza", "running",
"television"], false);
addEntry(["work", "ice cream", "cauliflower", "lasagna",
"touched tree", "brushed teeth"], false);
addEntry(["weekend", "cycling", "break", "peanuts",
"beer"], true);
console.log(journal);
</script>
```
- 注意parameter的形式
### 經共大概三個月的紀錄後,這是Johnny的日誌
```htmlembedded=
const JOURNAL = [
{"events":["carrot","exercise","weekend"],"squirrel":false},
{"events":["bread","pudding","brushed teeth","weekend","touched tree"],"squirrel":false},
{"events":["carrot","nachos","brushed teeth","cycling","weekend"],"squirrel":false},
{"events":["brussel sprouts","ice cream","brushed teeth","computer","weekend"],"squirrel":false},
{"events":["potatoes","candy","brushed teeth","exercise","weekend","dentist"],"squirrel":false},
{"events":["brussel sprouts","pudding","brushed teeth","running","weekend"],"squirrel":false},
{"events":["pizza","brushed teeth","computer","work","touched tree"],"squirrel":false},
{"events":["bread","beer","brushed teeth","cycling","work"],"squirrel":false},
{"events":["cauliflower","brushed teeth","work"],"squirrel":false},
{"events":["pizza","brushed teeth","cycling","work"],"squirrel":false},
{"events":["lasagna","nachos","brushed teeth","work"],"squirrel":false},
{"events":["brushed teeth","weekend","touched tree"],"squirrel":false},
{"events":["lettuce","brushed teeth","television","weekend"],"squirrel":false},
{"events":["spaghetti","brushed teeth","work"],"squirrel":false},
{"events":["brushed teeth","computer","work"],"squirrel":false},
{"events":["lettuce","nachos","brushed teeth","work"],"squirrel":false},
{"events":["carrot","brushed teeth","running","work"],"squirrel":false},
{"events":["brushed teeth","work"],"squirrel":false},
{"events":["cauliflower","reading","weekend"],"squirrel":false},
{"events":["bread","brushed teeth","weekend"],"squirrel":false},
{"events":["lasagna","brushed teeth","exercise","work"],"squirrel":false},
{"events":["spaghetti","brushed teeth","reading","work"],"squirrel":false},
{"events":["carrot","ice cream","brushed teeth","television","work"],"squirrel":false},
{"events":["spaghetti","nachos","work"],"squirrel":false},
{"events":["cauliflower","ice cream","brushed teeth","cycling","work"],"squirrel":false},
{"events":["spaghetti","peanuts","computer","weekend"],"squirrel":true},
{"events":["potatoes","ice cream","brushed teeth","computer","weekend"],"squirrel":false},
{"events":["potatoes","ice cream","brushed teeth","work"],"squirrel":false},
{"events":["peanuts","brushed teeth","running","work"],"squirrel":false},
{"events":["potatoes","exercise","work"],"squirrel":false},
{"events":["pizza","ice cream","computer","work"],"squirrel":false},
{"events":["lasagna","ice cream","work"],"squirrel":false},
{"events":["cauliflower","candy","reading","weekend"],"squirrel":false},
{"events":["lasagna","nachos","brushed teeth","running","weekend"],"squirrel":false},
{"events":["potatoes","brushed teeth","work"],"squirrel":false},
{"events":["carrot","work"],"squirrel":false},
{"events":["pizza","beer","work","dentist"],"squirrel":false},
{"events":["lasagna","pudding","cycling","work"],"squirrel":false},
{"events":["spaghetti","brushed teeth","reading","work"],"squirrel":false},
{"events":["spaghetti","pudding","television","weekend"],"squirrel":false},
{"events":["bread","brushed teeth","exercise","weekend"],"squirrel":false},
{"events":["lasagna","peanuts","work"],"squirrel":true},
{"events":["pizza","work"],"squirrel":false},
{"events":["potatoes","exercise","work"],"squirrel":false},
{"events":["brushed teeth","exercise","work"],"squirrel":false},
{"events":["spaghetti","brushed teeth","television","work"],"squirrel":false},
{"events":["pizza","cycling","weekend"],"squirrel":false},
{"events":["carrot","brushed teeth","weekend"],"squirrel":false},
{"events":["carrot","beer","brushed teeth","work"],"squirrel":false},
{"events":["pizza","peanuts","candy","work"],"squirrel":true},
{"events":["carrot","peanuts","brushed teeth","reading","work"],"squirrel":false},
{"events":["potatoes","peanuts","brushed teeth","work"],"squirrel":false},
{"events":["carrot","nachos","brushed teeth","exercise","work"],"squirrel":false},
{"events":["pizza","peanuts","brushed teeth","television","weekend"],"squirrel":false},
{"events":["lasagna","brushed teeth","cycling","weekend"],"squirrel":false},
{"events":["cauliflower","peanuts","brushed teeth","computer","work","touched tree"],"squirrel":false},
{"events":["lettuce","brushed teeth","television","work"],"squirrel":false},
{"events":["potatoes","brushed teeth","computer","work"],"squirrel":false},
{"events":["bread","candy","work"],"squirrel":false},
{"events":["potatoes","nachos","work"],"squirrel":false},
{"events":["carrot","pudding","brushed teeth","weekend"],"squirrel":false},
{"events":["carrot","brushed teeth","exercise","weekend","touched tree"],"squirrel":false},
{"events":["brussel sprouts","running","work"],"squirrel":false},
{"events":["brushed teeth","work"],"squirrel":false},
{"events":["lettuce","brushed teeth","running","work"],"squirrel":false},
{"events":["candy","brushed teeth","work"],"squirrel":false},
{"events":["brussel sprouts","brushed teeth","computer","work"],"squirrel":false},
{"events":["bread","brushed teeth","weekend"],"squirrel":false},
{"events":["cauliflower","brushed teeth","weekend"],"squirrel":false},
{"events":["spaghetti","candy","television","work","touched tree"],"squirrel":false},
{"events":["carrot","pudding","brushed teeth","work"],"squirrel":false},
{"events":["lettuce","brushed teeth","work"],"squirrel":false},
{"events":["carrot","ice cream","brushed teeth","cycling","work"],"squirrel":false},
{"events":["pizza","brushed teeth","work"],"squirrel":false},
{"events":["spaghetti","peanuts","exercise","weekend"],"squirrel":true},
{"events":["bread","beer","computer","weekend","touched tree"],"squirrel":false},
{"events":["brushed teeth","running","work"],"squirrel":false},
{"events":["lettuce","peanuts","brushed teeth","work","touched tree"],"squirrel":false},
{"events":["lasagna","brushed teeth","television","work"],"squirrel":false},
{"events":["cauliflower","brushed teeth","running","work"],"squirrel":false},
{"events":["carrot","brushed teeth","running","work"],"squirrel":false},
{"events":["carrot","reading","weekend"],"squirrel":false},
{"events":["carrot","peanuts","reading","weekend"],"squirrel":true},
{"events":["potatoes","brushed teeth","running","work"],"squirrel":false},
{"events":["lasagna","ice cream","work","touched tree"],"squirrel":false},
{"events":["cauliflower","peanuts","brushed teeth","cycling","work"],"squirrel":false},
{"events":["pizza","brushed teeth","running","work"],"squirrel":false},
{"events":["lettuce","brushed teeth","work"],"squirrel":false},
{"events":["bread","brushed teeth","television","weekend"],"squirrel":false},
{"events":["cauliflower","peanuts","brushed teeth","weekend"],"squirrel":false}
];
```
直接放入現在的`<script>`中即可
## Correlation function
- expressed as a value that ranges from -1 to 1
- use phi coefficient (ϕ)
- suppose we have done something dubbed "x"
<pre>
<div class="box">
<h1 class="item1"> x is false <br> not squirrel<br> n00 / table[0] </h1>
<h1 class="item2"> x is true <br> not squirrel <br> n01 / table[1] </h1>
<h1 class="item3"> x is false <br> squrriel <br> n10 / table[2] </h1>
<h1 class="item4"> x is true <br> squirrel <br> n11 / table[3] </h1>
</div>
<style>
.box{
width:400px;
height:400px;
display:grid;
grid-template-rows:[first] 1fr [second] 1fr [third];
grid-template-rows:[one] 1fr [two] 1fr [three];
}
.item1{
background-color:red;
grid-row:1/2;
grid-column:1/2;
}
.item2{
background-color:white;
grid-row:1/2;
grid-column:2/3;
}
.item3{
background-color:green;
grid-row:2/3;
grid-column:1/2;
}
.item4{
background-color:yellow;
grid-row:2/3;
grid-column:2/3;
}
</style>
</pre>
### first, we should find the number of the case
```htmlembedded=
function tableFor(event, journal) {
let table = [0, 0, 0, 0];
//table[0][1][2][3] 分別表示xx xo ox oo
//第一位是有無變身,第二位是有無發生events
for(let entry of journal){
index=0;
if(entry.events.includes(event)) index+=1;
if(entry.squirrel) index+=2;
table[index] += 1;
}
return table;
}
console.log(tableFor("pizza", JOURNAL));
```
### Now, let's come across the function

```htmlembedded=
function phi(table) {
return (table[3] * table[0] - table[2] * table[1]) /
Math.sqrt((table[2] + table[3]) *
(table[0] + table[1]) *
(table[1] + table[3]) *
(table[0] + table[2]));
}
console.log(phi(tableFor("pizza", JOURNAL)));
```
### Then, we try to find the correlation about each events
```htmlembedded=
const show_events = (journal)=>{
let events = [];
for(let entry of journal){
for(let event of entry.events){
if(!events.includes(event)){
events.push(event);
}
}
}
return events;
}
console.log(show_events(JOURNAL));
for(let event of show_events(JOURNAL)){
console.log(event+":"+phi(tableFor(event,JOURNAL)));
}
```
## Well, there are a lot of numbers. How to make a filter to them.
```htmlembedded=
for(let event of show_events(JOURNAL)){
let correlation = phi(tableFor(event,JOURNAL));
if(correlation > 0.1 || correlation < -0.1){
console.log(event+":"+correlation);
}
}
```
- There are two factors with a correlation that’s clearly stronger than the others -- "peanuts" and "brushed teeth"
- we try to jump into the conclusion of squirrelman's phenomenon
```htmlembedded=
for(let entry of JOURNAL){
if(entry.events.includes("peanuts")&&
!entry.events.includes("brushed teeth")){
entry.events.push("peanut teeth");
}
}
console.log(phi(tableFor("peanut teeth", JOURNAL))); //that is the result
```
## Exercise
### identity
- write an object contained four properties,"name","major","hobby","score",and their's type are string,string,array,array
respectively
- write a function which inverses the order to the array, and let the score be pamaraters. Observe the result.
(not to use Array.unshift method)
```htmlembedded=
const Duncan={
name:"Duncan",
major:"EE",
hobby:["reading","swimming"],
score:[60,70,75]
}
Duncan.score.push(34);
console.log(Duncan.score);
const inverse = (array) =>{
let newarray = [];
for(let i=array.length-1;i>=0;i--){
newarray.push(array[i]);
}
return newarray;
}
console.log(inverse(Duncan.score));
```
### 其他寫法
```htmlembedded=
const inverse_2=(array)=>{
let j=0;
let i=array.length-1;
let ne=[];
while(i>=0){
ne.push(array[i]);
i--;
}
return ne;
}
function reverseArrayInPlace(array) {
for (let i = 0; i < Math.floor(array.length / 2); i++) {
let old = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = old;
}
return array;
}
console.log(inverse_2(Duncan.score));
console.log(reverseArrayInPlace(Duncan.score));
```
### Data structure -- List

- the first object should hold the reference to the second object's information
- create a function **todoList**, which creates this kind of list structure
- add a helper function **prepend**, which takes an element and a list and creates a new list that adds the element to the front of the input list
- we also create a function **nth**, which takes a list and a number and returns the element at the given position in the list (with zero referring to the first element) or undefined when there is no such element.
```htmlembedded=
<script>
const todoList=(array)=>{
let list = null;
for(let i = array.length-1;i>=0;i--){
list = {value:array[i], rest:list};
}
return list;
}
let li = todoList([1,2,3]);
console.log(li);
const prepend=(element,list)=>{
return {value:element, rest:list};
}
console.log(prepend(0,li));
function nth(list, n) {
if (list==null) return undefined;
else if (n == 0) return list.value;
else return nth(list.rest, n - 1);
}
console.log(nth(li,3));
console.log(nth(li,2));
console.log(nth(li,1));
console.log(nth(li,0));
</script>
```
## Reference
<a href="https://eloquentjavascript.net/"> Eloquent JavaScript </a>