# 專案實作--松鼠人 - 先備知識: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>