---
# System prepended metadata

title: 專案實作--松鼠人

---

# 專案實作--松鼠人

- 先備知識:array, function, object

<hr>

某天，Johnny發現自己時不時會變成一隻毛茸茸的松鼠，這個現象一直困擾著他。因此，Johnny想藉由寫下日誌以記錄當天發生的事件，並觀測自己是否有變成松鼠人的情形
![](https://i.imgur.com/zZwil0k.jpg =300x)

於是，他請教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
![](https://i.imgur.com/vWpY2Up.png)
```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
![](https://i.imgur.com/Zg6Uhix.png =300x300)
- 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>
