diff --git a/week-1/README.md b/week-1/README.md index 062bb4d..b56b2db 100644 --- a/week-1/README.md +++ b/week-1/README.md @@ -14,7 +14,7 @@ --- - + ## submission instructions | emoji | who uses it | meaning | diff --git a/week-1/fcc-basic-js-pt-1.md b/week-1/fcc-basic-js-pt-1.md index 6ca5118..ea1ef1f 100644 --- a/week-1/fcc-basic-js-pt-1.md +++ b/week-1/fcc-basic-js-pt-1.md @@ -1,3 +1,11 @@ > complete [the basic JS exercises](https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript) through _Counting Cards_ & paste each of your solutions into this file. This will allow you to use your FCC exercises as a study reference later on > [completed example](https://github.com/AlfiYusrina/hyf-javascript1/blob/master/week1/freecode_camp_solutions.MD) +[PHY] (http://www.pythontutor.com/javascript.html#code=//%20this%20is%20an%20in-line%20comment%20%3B%29%0A/*%20This%20is%20a%20%0Amulti-line%20coment%20%3A%29%20*/%0A&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +2 types of comment line + +```js +// this is an in-line comment ;) +/* This is a +multi-line coment :) */ +``` diff --git a/week-1/jl-errors-formatting.md b/week-1/jl-errors-formatting.md index 66627fb..fc3ecff 100644 --- a/week-1/jl-errors-formatting.md +++ b/week-1/jl-errors-formatting.md @@ -1,3 +1,40 @@ > paste [this markdown](https://raw.githubusercontent.com/janke-learning/error-exercises/master/formatting.md) into this file and fix the errors! > [completed example](https://github.com/AlfiYusrina/hyf-javascript1/blob/master/week1/errors_solutions.MD) (of the old version) -> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) \ No newline at end of file +> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) + +# Formatting Errors + +It's easy to miss the little things, even when you're an experienced programmer! Using a linter will help enormously avoiding simple formatting errors, but it's still great practice to learn how to spot them yourself. This skill build your confidence writing code from a blank page and is important for those times when you're coding outside of your normal editor. + +### exercises +* [improper end of statement](#improper-end-of-statement) + +--- + +## improper end of statement +broken code: +```js +let a = 1: +``` +error message: +``` +this is a error message +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +let a = 1; +``` + +your notes: + +:+1: +[TOP](#formatting-errors) + + +___ +___ +### Janke Learning diff --git a/week-1/jl-functions.md b/week-1/jl-functions.md index d24d0e7..2cc6070 100644 --- a/week-1/jl-functions.md +++ b/week-1/jl-functions.md @@ -1,2 +1,221 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/function-exercises/master/functions.md) into this file and complete the exercises! -> references: [javascript.info functions](https://javascript.info/function-basics), [function examples to study](https://github.com/janke-learning/function-exercises/blob/master/examples-to-study.md) \ No newline at end of file +> references: [javascript.info functions](https://javascript.info/function-basics), [function examples to study](https://github.com/janke-learning/function-exercises/blob/master/examples-to-study.md) +# Functions + +some exercises to help you understand functions: +* Defining vs. Calling functions + * Defining: when you write the funciton -> function name() {}. This creates the function in memory + * Calling: using the function to compute new values -> name(). This creates a new frame and returns a new value +* Arguments +* Lexical Scope +* Return Values +* tracing values through function calls. + 1. stored in a variable + 1. passed as argument to a function call + 1. available as a parameter in the new frame + 1. returned from the frame as a return value + 1. captured in a variable + +### Index +* [completed example](#completed-example) +* exercises + * [number 1](#1) + * [number 2](#2) + * [number 3](#3) + * [number 4](#4) + * [number 5](#5) + * [number 6](#6) + * [number 7](#7) + * [number 8](#8) +* [resources](#resources) + +--- + +## Completed Example + +[on pytut](http://www.pythontutor.com/javascript.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20result%20%3D%20param_2%20%2B%20param_3%20%2B%20param_1%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22x%22,%20arg_2%20%3D%20%22z%22,%20arg_3%20%3D%20%22y%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22zyx%22,%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&curInstr=0&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20result%20%3D%20param_2%20%2B%20param_3%20%2B%20param_1%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22x%22,%20arg_2%20%3D%20%22z%22,%20arg_3%20%3D%20%22y%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22zyx%22,%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // completed example + function f(param_1, param_2, param_3) { + var result = param_2 + param_3 + param_1; + return result; + }; + + // set values in the args to pass the assert + let arg_1 = "x", arg_2 = "z", arg_3 = "y"; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "zyx", "example: return_val === " + return_val); +} +``` + +[TOP](#functions) + +--- + +## Exercises + +### 1 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22,%20arg_2%20%3D%20%22%22,%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22zyx%22,%20%221%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=6&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22,%20arg_2%20%3D%20%22%22,%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22zyx%22,%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 1 + function f(param_1, param_2, param_3) { + var result = param_3 + param_1 + param_2; + return result; + }; + + // set values in the args to pass the assert + let arg_1 = "", arg_2 = "", arg_3 = ""; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "zyx", "1: return_val === " + return_val); +} +``` + +### 2 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22,%20arg_2%20%3D%20%22%22,%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22yxz%22,%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=6&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A%2F%2F%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22%2C%20arg_2%20%3D%20%22%22%2C%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1%2C%20arg_2%2C%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22yxz%22%2C%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 2 + function f(param_1, param_2, param_3) { + var result = param_3 + param_1 + param_2; + return result; + }; + + // set values in the args to pass the assert + let arg_1 = "", arg_2 = "", arg_3 = ""; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "yxz", "2: return_val === " + return_val); +} +``` + +### 3 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20_%20%3D%20param_2%3B%0A%20%20param_2%20%3D%20param_1%3B%0A%20%20param_1%20%3D%20_%3B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22,%20arg_2%20%3D%20%22%22,%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22yxz%22,%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=9&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20%20var%20_%20%3D%20param_2%3B%0A%20%20param_2%20%3D%20param_1%3B%0A%20%20param_1%20%3D%20_%3B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A%2F%2F%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22%2C%20arg_2%20%3D%20%22%22%2C%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1%2C%20arg_2%2C%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22yxz%22%2C%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 3 + function f(param_1, param_2, param_3) { + var _ = param_2; + param_2 = param_1; + param_1 = _; + var result = param_3 + param_1 + param_2; + return result; + }; + + // set values in the args to pass the assert + let arg_1 = "", arg_2 = "", arg_3 = ""; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "yxz", "3: return_val === " + return_val); +} +``` + +### 4 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20_%20%3D%20param_2%3B%0A%20%20param_2%20%3D%20param_3%3B%0A%20%20param_3%20%3D%20_%3B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A//%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22,%20arg_2%20%3D%20%22%22,%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xyz%22,%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=9&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20%20var%20_%20%3D%20param_2%3B%0A%20%20param_2%20%3D%20param_3%3B%0A%20%20param_3%20%3D%20_%3B%0A%20%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20%20return%20result%3B%0A%7D%3B%0A%0A%2F%2F%20set%20values%20in%20the%20args%20to%20pass%20the%20assert%0Alet%20arg_1%20%3D%20%22%22%2C%20arg_2%20%3D%20%22%22%2C%20arg_3%20%3D%20%22%22%3B%0Alet%20return_val%20%3D%20f%28arg_1%2C%20arg_2%2C%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xyz%22%2C%20%22return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 4 + function f(param_1, param_2, param_3) { + var _ = param_2; + param_2 = param_3; + param_3 = _; + var result = param_3 + param_1 + param_2; + return result; + }; + + // set values in the args to pass the assert + let arg_1 = "", arg_2 = "", arg_3 = ""; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "xyz", "4: return_val === " + return_val); +} +``` + +### 5 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20x%20%3D%20%22x%22,%20y%20%3D%20%22y%22,%20z%20%3D%20%22z%22%3B%0Alet%20return_val%20%3D%20f%28/*%20pass%20x,%20y%20%26%20z%20in%20the%20right%20order%20*/%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xyz%22,%20%225%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=6&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20var%20result%20%3D%20param_3%20%2B%20param_1%20%2B%20param_2%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20x%20%3D%20%22x%22%2C%20y%20%3D%20%22y%22%2C%20z%20%3D%20%22z%22%3B%0Alet%20return_val%20%3D%20f%28%2F*%20pass%20x%2C%20y%20%26%20z%20in%20the%20right%20order%20*%2F%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xyz%22%2C%20%225%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 5 + function f(param_1, param_2, param_3) { + var result = param_3 + param_1 + param_2; + return result; + }; + + let x = "x", y = "y", z = "z"; + let return_val = f(/* pass x, y & z in the right order */); + + console.assert(return_val === "xyz", "5: return_val === " + return_val); +} +``` + +### 6 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20var%20result%20%3D%20param_2%20%2B%20param_1%20%2B%20param_3%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20x%20%3D%20%22x%22,%20y%20%3D%20%22y%22,%20z%20%3D%20%22z%22%3B%0Alet%20return_val%20%3D%20f%28/*%20pass%20x,%20y%20%26%20z%20in%20the%20right%20order%20*/%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xzy%22,%20%226%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=6&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20var%20result%20%3D%20param_2%20%2B%20param_1%20%2B%20param_3%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20x%20%3D%20%22x%22%2C%20y%20%3D%20%22y%22%2C%20z%20%3D%20%22z%22%3B%0Alet%20return_val%20%3D%20f%28%2F*%20pass%20x%2C%20y%20%26%20z%20in%20the%20right%20order%20*%2F%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xzy%22%2C%20%226%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 6 + function f(param_1, param_2, param_3) { + var result = param_2 + param_1 + param_3; + return result; + }; + + let x = "x", y = "y", z = "z"; + let return_val = f(/* pass x, y & z in the right order */); + + console.assert(return_val === "xzy", "6: return_val === " + return_val); +} +``` + +### 7 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20var%20result%20%3D%20/*%20arrange%20the%20params%20to%20pass%20the%20assert%20*/%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20arg_1%20%3D%20%22z%22,%20arg_2%20%3D%20%22y%22,%20arg_3%20%3D%20%22x%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xzy%22,%20%227%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20var%20result%20%3D%20%2F*%20arrange%20the%20params%20to%20pass%20the%20assert%20*%2F%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20arg_1%20%3D%20%22z%22%2C%20arg_2%20%3D%20%22y%22%2C%20arg_3%20%3D%20%22x%22%3B%0Alet%20return_val%20%3D%20f%28arg_1%2C%20arg_2%2C%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22xzy%22%2C%20%227%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 7 + function f(param_1, param_2, param_3) { + var result = /* arrange the params to pass the assert */; + return result; + }; + + let arg_1 = "z", arg_2 = "y", arg_3 = "x"; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "xzy", "7: return_val === " + return_val); +} +``` + +### 8 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20f%28param_1,%20param_2,%20param_3%29%20%7B%0A%20var%20result%20%3D%20/*%20arrange%20the%20params%20to%20pass%20the%20assert%20*/%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20arg_1%20%3D%20%22z%22,%20arg_2%20%3D%20%22y%22,%20arg_3%20%3D%20%22x%22%3B%0Alet%20return_val%20%3D%20f%28arg_1,%20arg_2,%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22yxz%22,%20%228%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized](http://janke-learning.github.io/parsonizer/?snippet=function%20f%28param_1%2C%20param_2%2C%20param_3%29%20%7B%0A%20var%20result%20%3D%20%2F*%20arrange%20the%20params%20to%20pass%20the%20assert%20*%2F%3B%0A%20return%20result%3B%0A%7D%3B%0A%0Alet%20arg_1%20%3D%20%22z%22%2C%20arg_2%20%3D%20%22y%22%2C%20arg_3%20%3D%20%22x%22%3B%0Alet%20return_val%20%3D%20f%28arg_1%2C%20arg_2%2C%20arg_3%29%3B%0A%0Aconsole.assert%28return_val%20%3D%3D%3D%20%22yxz%22%2C%20%228%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B) +```js +{ // 8 + function f(param_1, param_2, param_3) { + var result = /* arrange the params to pass the assert */; + return result; + }; + + let arg_1 = "z", arg_2 = "y", arg_3 = "x"; + let return_val = f(arg_1, arg_2, arg_3); + + console.assert(return_val === "yxz", "8: return_val === " + return_val); +} +``` + +--- + +## Resources + +* [pythontutor video](https://www.youtube.com/watch?v=bJUmxDsaduY&list=PLzV58Zm8FuBJFfQN5il3ujx6FDAY8Ds3u&index=6) + +___ +___ +### Janke Learning diff --git a/week-1/jl-variables-multiple.md b/week-1/jl-variables-multiple.md index b8bc5f5..300bbc8 100644 --- a/week-1/jl-variables-multiple.md +++ b/week-1/jl-variables-multiple.md @@ -1,2 +1,38 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/variable-exercises/master/swaps.md) into this file and complete the exercises! -> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) \ No newline at end of file +> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) +# Swaps + +You'll be given a bunch of variables with the wrong value assigned and a temporary variable you can use for storing values. Your task is to get the right values into each variable in as few steps as possible by shuffling them around. + +### example solutions +1. the first: [pytut](https://goo.gl/mk9xd3), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22b%22%2C%20b%20%3D%20%22a%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20b%3B%0Ab%20%3D%20a%3B%0Aa%20%3D%20_%3B) +1. the second: [pytut](https://goo.gl/BWKuGm), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22c%22%2C%20b%20%3D%20%22a%22%2C%20c%20%3D%20%22b%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20c%3B%0Ac%20%3D%20a%3B%0Aa%20%3D%20b%3B%0Ab%20%3D%20_%3B%0A) +1. the third: [pytut](https://goo.gl/jeBHWU), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22d%22%2C%20b%20%3D%20%22a%22%2C%20c%20%3D%20%22b%22%2C%20d%20%3D%20%22c%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20a%3B%0Aa%20%3D%20b%3B%0Ab%20%3D%20c%3B%0Ac%20%3D%20d%3B%0Ad%20%3D%20_%3B%0A) +1. the fourth: [pytut](https://goo.gl/C8t81i), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22z%22%2C%20b%20%3D%20%22y%22%2C%20c%20%3D%20%22x%22%2C%20d%20%3D%20%22w%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20a%3B%0Aa%20%3D%20d%3B%0Ad%20%3D%20_%3B%0A_%20%3D%20b%3B%0Ab%20%3D%20c%3B%0Ac%20%3D%20_%3B%0A) +1. the fifth: [pytut](https://goo.gl/KokxwL), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22z%22%2C%20b%20%3D%20%22y%22%2C%20c%20%3D%20%22x%22%2C%20d%20%3D%20%22w%22%2C%20e%20%3D%20%22v%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20a%3B%0Aa%20%3D%20e%3B%0Ae%20%3D%20_%3B%0A_%20%3D%20b%3B%0Ab%20%3D%20d%3B%0Ad%20%3D%20_%3B%0A) + +### challenges +1. [the first](https://goo.gl/k9jdZy) +```js +// your solution here +``` +1. [the second](https://goo.gl/KvayUU) +```js +// your solution here +``` +1. [the third](https://goo.gl/WXXtV7) +```js +// your solution here +``` +1. [the fourth](https://goo.gl/nTA1DG) +```js +// your solution here +``` +1. [the fifth](https://goo.gl/gDaKNi) +```js +// your solution here +``` + +___ +___ +### Janke Learning diff --git a/week-1/jl-variables-swaps.md b/week-1/jl-variables-swaps.md index 50ccca2..f10005d 100644 --- a/week-1/jl-variables-swaps.md +++ b/week-1/jl-variables-swaps.md @@ -1,2 +1,38 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/variable-exercises/master/multiple-assignments.md) into this file and complete the exercises! -> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) \ No newline at end of file +> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) +# Swaps + +You'll be given a bunch of variables with the wrong value assigned and a temporary variable you can use for storing values. Your task is to get the right values into each variable in as few steps as possible by shuffling them around. + +### example solutions +1. the first: [pytut](https://goo.gl/mk9xd3), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22b%22%2C%20b%20%3D%20%22a%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20b%3B%0Ab%20%3D%20a%3B%0Aa%20%3D%20_%3B) +1. the second: [pytut](https://goo.gl/BWKuGm), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22c%22%2C%20b%20%3D%20%22a%22%2C%20c%20%3D%20%22b%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20c%3B%0Ac%20%3D%20a%3B%0Aa%20%3D%20b%3B%0Ab%20%3D%20_%3B%0A) +1. the third: [pytut](https://goo.gl/jeBHWU), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22d%22%2C%20b%20%3D%20%22a%22%2C%20c%20%3D%20%22b%22%2C%20d%20%3D%20%22c%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20a%3B%0Aa%20%3D%20b%3B%0Ab%20%3D%20c%3B%0Ac%20%3D%20d%3B%0Ad%20%3D%20_%3B%0A) +1. the fourth: [pytut](https://goo.gl/C8t81i), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22z%22%2C%20b%20%3D%20%22y%22%2C%20c%20%3D%20%22x%22%2C%20d%20%3D%20%22w%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20a%3B%0Aa%20%3D%20d%3B%0Ad%20%3D%20_%3B%0A_%20%3D%20b%3B%0Ab%20%3D%20c%3B%0Ac%20%3D%20_%3B%0A) +1. the fifth: [pytut](https://goo.gl/KokxwL), [parsons](https://janke-learning.github.io/parsonizer/?snippet=let%20a%20%3D%20%22z%22%2C%20b%20%3D%20%22y%22%2C%20c%20%3D%20%22x%22%2C%20d%20%3D%20%22w%22%2C%20e%20%3D%20%22v%22%3B%0Alet%20_%20%3D%20'%20'%3B%0A%0A_%20%3D%20a%3B%0Aa%20%3D%20e%3B%0Ae%20%3D%20_%3B%0A_%20%3D%20b%3B%0Ab%20%3D%20d%3B%0Ad%20%3D%20_%3B%0A) + +### challenges +1. [the first](https://goo.gl/k9jdZy) +```js +// your solution here +``` +1. [the second](https://goo.gl/KvayUU) +```js +// your solution here +``` +1. [the third](https://goo.gl/WXXtV7) +```js +// your solution here +``` +1. [the fourth](https://goo.gl/nTA1DG) +```js +// your solution here +``` +1. [the fifth](https://goo.gl/gDaKNi) +```js +// your solution here +``` + +___ +___ +### Janke Learning diff --git a/week-2/README.md b/week-2/README.md index 4b2a67b..b775d8f 100644 --- a/week-2/README.md +++ b/week-2/README.md @@ -2,19 +2,19 @@ | | your Emoji | your comments | coach emoji | coach comments | | --- | --- | --- | --- | --- | -| :seedling: __[fcc: finish js basics](./fcc-basic-js-pt-2.md) | | | | | -| :dash: __[janke: tracing conditionals](./jl-tracing-conditionals.md) | | | | | -| :seedling: __[javascript.info: loops](./jsinfo-loops.md) | | | | | -| :dash: __[janke: loop refactors](./jl-loop-refactors.md) | | | | | -| :seedling: __[fcc: data structures](./fcc-data-structures.md) | | | | | -| :seedling: __[janke: errors const](./jl-errors-const.md) | | | | | -| :seedling: __[janke: errors arrays](./jl-errors-arrays.md) | | | | | -| :seedling: __[janke: errors objects](./jl-errors-objects.md) | | | | | -| :seedling: __[javascript.info: objects](./jsinfo-objects.md) | | | | | -| :dash: __[janke: reference types](./jl-reference-types.md) | | | | | -| :fire: __[janke: ref-type arguments](./jl-functions-ref-type-args.md) | | | | | -| :dash: __[janke: sentences w/o temps](./jl-variables-sentences-1.md) | | | | | -| :fire: __[janke: sentences w/ temps](./jl-variables-sentences-2.md) | | | | | +| :seedling: __[fcc: finish js basics](./fcc-basic-js-pt-2.md) |:seedling:| | | | +| :dash: __[janke: tracing conditionals](./js-tracing-conditionals.md) | :+1: | | | | +| :seedling: __[javascript.info: loops](./jsinfo-loops.md) |:seedling:| | | | +| :dash: __[janke: loop refactors](./jl-loop-refactors.md) |:+1: | | | | +| :seedling: __[fcc: data structures](./fcc-data-structures.md) |:seedling:| | | | +| :seedling: __[janke: errors const](./jl-errors-const.md) |:seedling:| | | | +| :seedling: __[janke: errors arrays](./jl-errors-arrays.md) |:seedling:| | | | +| :seedling: __[janke: errors objects](./jl-errors-objects.md) |:seedling:| | | | +| :seedling: __[javascript.info: objects](./jsinfo-objects.md) |:seedling:| | | | +| :dash: __[janke: reference types](./jl-reference-types.md) |:+1: | | | | +| :fire: __[janke: ref-type arguments](./jl-functions-ref-type-args.md) |:+1: | | | | +| :dash: __[janke: sentences w/o temps](./jl-variables-sentences-1.md) |:+1: | | | | +| :fire: __[janke: sentences w/ temps](./jl-variables-sentences-2.md) |:+1: | | | | diff --git a/week-2/jl-errors-arrays.md b/week-2/jl-errors-arrays.md index c86374f..7b8ac6c 100644 --- a/week-2/jl-errors-arrays.md +++ b/week-2/jl-errors-arrays.md @@ -1,3 +1,94 @@ > paste [this markdown](https://raw.githubusercontent.com/janke-learning/error-exercises/master/arrays.md) into this file and fix the errors! > [completed example](https://github.com/AlfiYusrina/hyf-javascript1/blob/master/week1/errors_solutions.MD) (of the old version) -> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) \ No newline at end of file +> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) +# Array Errors + + +* [missing closing bracket](#missing-closing-bracket) +* [missing comma](#missing-comma) +* [poorly nested](#poorly-nested) + +--- + +## missing closing bracket + +broken code: +```js +let myArray = [1, 2, 3; +``` +error message: +``` js +alert("Unexpected token!"); +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +let myArray = [1, 2, 3]; +``` +your notes: + +[TOP](#array-errors) + +--- + +## missing comma + +broken code: +```js +let myArray = [1, 2 3]; +``` +error message: +``` js +alert("Unexpected number!"); +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +let myArray = [1, 2, 3]; +``` +your notes: + +[TOP](#array-errors) + +--- + +## poorly nested + +broken code: +```js +let myArray = [ + [1, 2, 3] + [4, 5, 6] + [7, 8, 9] + ]; +``` +error message: +```js +alert("Cannot read property '9' of undefined!"); +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +let myArray = [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ]; +``` +your notes: + +[TOP](#array-errors) + + +___ +___ +### Janke Learning diff --git a/week-2/jl-errors-const.md b/week-2/jl-errors-const.md index 82a6984..f438a6e 100644 --- a/week-2/jl-errors-const.md +++ b/week-2/jl-errors-const.md @@ -1,2 +1,91 @@ > paste [this markdown](https://raw.githubusercontent.com/janke-learning/error-exercises/master/const.md) into this file and fix the errors! -> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) \ No newline at end of file +> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) +# Variable Errors + + +### exercises +* [missing variable name](#missing-variable-name) +* [reassigning to constant](#reassigning-to-constant) +* [unassigned const declaration](#unassigned-const-declaration) + +--- + +### missing variable name + +broken code: +```js +const = 5; +``` +error message: +```js +Unexpected token = +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +const x = 5; +``` +your notes: + +[TOP](#variable-errors) + +--- + + +## reassigning to constant + +broken code: +```js +const a = 9; +a = 0; +``` +error message: +```js +Assignment to constant variable. +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +const a = 9; +const b = 0; +``` +your notes: + +[TOP](#variable-errors) + +--- + + +## unassigned const declaration + +broken code: +```js +const a; +a = 0; +``` +error message: +```js +Missing initializer in const declaration +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +const a = 0; +``` +your notes: + +[TOP](#variable-errors) + +___ +___ +### Janke Learning + diff --git a/week-2/jl-errors-objects.md b/week-2/jl-errors-objects.md index 73f2eee..0647379 100644 --- a/week-2/jl-errors-objects.md +++ b/week-2/jl-errors-objects.md @@ -1,3 +1,62 @@ > paste [this markdown](https://raw.githubusercontent.com/janke-learning/error-exercises/master/objects.md) into this file and fix the errors! > [completed example](https://github.com/AlfiYusrina/hyf-javascript1/blob/master/week1/errors_solutions.MD) (of the old version) -> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) \ No newline at end of file +> references: [errors & life-cycle](https://github.com/janke-learning/errors-and-life-cycle), [exercise repo](https://github.com/janke-learning/errors) +# Object Errors + +* [too-far object access](#too-far-object-access) +* [access property directly](#access-property-directly) + +--- + +## too-far object access + +broken code: +```js +let a = {b:3}; +let b = a.b.3 +``` +error message: +```Unexpected number +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +let a = {b:3}; +let b = a.b +``` +your notes: + +[TOP](#object-errors) + +--- + +## access property directly +broken code: +```js +let x = {b:'e'}; +let y = b.e; +``` +error message: +```js +ReferenceError: b is not defined +``` +classification: +* creation phase or execution phase ? +* syntax or semanitc ? + +the fix: +```js +let x = {b:'e'}; +let y = x.b +``` +your notes: + +[TOP](#object-errors) + + +___ +___ +### Janke Learning diff --git a/week-2/jl-functions-ref-type-args.md b/week-2/jl-functions-ref-type-args.md index 3d1522f..a7ff8f0 100644 --- a/week-2/jl-functions-ref-type-args.md +++ b/week-2/jl-functions-ref-type-args.md @@ -1 +1,261 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/function-exercises/master/reference-type-arguments.md) into this file and complete the exercises! +# Reference Type Arguments + +When reference types (ie. arrays, objects) are passed as arguments to a function JavaScript simply passes a pointer to the thing in memory. If you modify a data structure that was passed as an argument, the changes will remain in the global scope after the frame has closed. This is a _side effect_. + +These examples and exercises will help you understand _side effects_ and how to avoid them. + +### Index: +* examples to study + * [side effects with return value](#with-return-value) + * [side effects without return value](#without-return-value) + * [comparing objects & arrays](#comparing-objects-and-arrays) + * [avoid S.E.'s by starting a new one](#by-starting-a-new-one) + * [avoid S.E.'s by making a copy](#by-making-a-copy) +* exercises + * [copy an array](#copy-an-array) + * [start a new array](#start-a-new-array) + * [copy an object](#copy-an-object) + * [start a new object](#start-a-new-object) + + +--- + +## Examples to Study + +## Side Effects + +### with return value +[on pytut](http://www.pythontutor.com/live.html#code=function%20no_side_effects%28param%29%20%7B%0A%20%20return%20%22%22%20%2B%20param%3B%0A%7D%0A%0Aconst%20arg%20%3D%203%3B%0Aconst%20ret_val%20%3D%20no_side_effects%28arg%29%3B%0A%0A//%20----%0A%0Afunction%20side_effector%28ref_type,%20key%29%20%7B%0A%20%20ref_type%5Bkey%5D%20%3D%20'side%20effect!'%3B%0A%20%20return%20ref_type%3B%0A%7D%0A%0Aconst%20arr%20%3D%20%5B'a'%5D%3B%0Aconst%20arr_ret_val%20%3D%20side_effector%28arr,%201%29%3B%0Aconsole.assert%28arr%5B1%5D%20%3D%3D%3D%20arr_ret_val%5B1%5D%29%3B%0A%0A%0Aconst%20obj%20%3D%20%7Ba%3A%201%7D%3B%0Aconst%20obj_ret_val%20%3D%20side_effector%28obj,%20'b'%29%3B%0Aconsole.assert%28obj.b%20%3D%3D%3D%20obj_ret_val.b%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function no_side_effects(param) { + return "" + param; + } + + const arg = 3; + const ret_val = no_side_effects(arg); + + // ---- + + function side_effector(ref_type, key) { + ref_type[key] = 'side effect!'; + return ref_type; + } + + const arr = ['a']; + const arr_ret_val = side_effector(arr, 1); + console.assert(arr[1] === arr_ret_val[1]); + + + const obj = {a: 1}; + const obj_ret_val = side_effector(obj, 'b'); + console.assert(obj.b === obj_ret_val.b); +} +``` + + +### without return value +[on pytut](http://www.pythontutor.com/live.html#code=function%20no_side_effects%28param%29%20%7B%0A%20%20const%20result%20%3D%20%22%22%20%2B%20param%3B%0A%7D%0A%0Aconst%20arg%20%3D%203%3B%0Ano_side_effects%28arg%29%3B%0A%0A%0A//%20---%0A%0Afunction%20side_effector%28ref_type,%20key%29%20%7B%0A%20%20ref_type%5Bkey%5D%20%3D%20'side%20effect!'%3B%0A%7D%0A%0Aconst%20arr%20%3D%20%5B'a'%5D%3B%0Aside_effector%28arr,%201%29%3B%0Aconsole.assert%28arr%5B1%5D%20%3D%3D%3D%20'side%20effect!'%29%3B%0A%0A%0Aconst%20obj%20%3D%20%7Ba%3A%201%7D%3B%0Aside_effector%28obj,%20'b'%29%3B%0Aconsole.assert%28obj.b%20%3D%3D%3D%20'side%20effect!'%29%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function no_side_effects(param) { + const result = "" + param; + } + + const arg = 3; + no_side_effects(arg); + + + // --- + + function side_effector(ref_type, key) { + ref_type[key] = 'side effect!'; + } + + const arr = ['a']; + side_effector(arr, 1); + console.assert(arr[1] === 'side effect!'); + + + const obj = {a: 1}; + side_effector(obj, 'b'); + console.assert(obj.b === 'side effect!'); +} +``` + +## Comparing Objects and Arrays + +[on pytut](http://www.pythontutor.com/live.html#code=const%20arr_1%20%3D%20%5B3,2,1%5D%3B%0Aconst%20arr_2%20%3D%20%5B3,2,1%5D%3B%0A%0Aconst%20arr_1_stringified%20%3D%20JSON.stringify%28arr_1%29%3B%0Aconst%20arr_2_stringified%20%3D%20JSON.stringify%28arr_2%29%3B%0A%0Aconsole.assert%28arr_1%20%3D%3D%3D%20arr_2%29%3B%0Aconsole.assert%28arr_1_stringified%20%3D%3D%3D%20arr_2_stringified%29%3B%0A%0A%0Aconst%20obj_1%20%3D%20%7Ba%3A3,b%3A2,c%3A1%7D%3B%0Aconst%20obj_2%20%3D%20%7Ba%3A3,b%3A2,c%3A1%7D%3B%0A%0Aconst%20obj_1_stringified%20%3D%20JSON.stringify%28obj_1%29%3B%0Aconst%20obj_2_stringified%20%3D%20JSON.stringify%28obj_2%29%3B%0A%0Aconsole.assert%28obj_1%20%3D%3D%3D%20obj_2%29%3B%0Aconsole.assert%28obj_1_stringified%20%3D%3D%3D%20obj_2_stringified%29%3B&cumulative=false&curInstr=5&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + const arr_1 = [3,2,1]; + const arr_2 = [3,2,1]; + + const arr_1_stringified = JSON.stringify(arr_1); + const arr_2_stringified = JSON.stringify(arr_2); + + console.assert(arr_1 === arr_2); + console.assert(arr_1_stringified === arr_2_stringified); + + + const obj_1 = {a:3,b:2,c:1}; + const obj_2 = {a:3,b:2,c:1}; + + const obj_1_stringified = JSON.stringify(obj_1); + const obj_2_stringified = JSON.stringify(obj_2); + + console.assert(obj_1 === obj_2); + console.assert(obj_1_stringified === obj_2_stringified); +} +``` + +[TOP](#reference-type-arguments) + +--- + +## Avoid Side Effects + +### by starting a new one + +preferred method, the logic is usually much simpler to follow. +[on pytut](http://www.pythontutor.com/live.html#code=//%20make%20a%20new%20empty%20array%0A//%20fill%20it%20with%20the%20new,%20correct,%20values%0Afunction%20reverse_a_new_one%28arr%29%20%7B%0A%20%20var%20new_arr%20%3D%20%5B%5D%3B%0A%20%20for%20%28let%20i%20%3D%20arr.length%20-%201%3B%20i%20%3E%3D%200%3B%20i--%29%20%7B%0A%20%20%20%20new_arr.push%28arr%5Bi%5D%29%3B%0A%20%20%7D%0A%20%20return%20new_arr%3B%0A%7D%0A%0Aconst%20backwards%20%3D%20%5B3,%202,%201%5D%3B%0Aconst%20reversed%20%3D%20reverse_a_new_one%28backwards%29%3B%0A%0Aconst%20reversed_strified%20%3D%20JSON.stringify%28reversed%29%3B%0Aconsole.assert%28reversed_strified%20%3D%3D%3D%20'%5B1,2,3%5D'%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + // make a new empty array + // fill it with the new, correct, values + function reverse_a_new_one(arr) { + var new_arr = []; + for (let i = arr.length - 1; i >= 0; i--) { + new_arr.push(arr[i]); + } + return new_arr; + } + + const backwards = [3, 2, 1]; + const reversed = reverse_a_new_one(backwards); + + const reversed_strified = JSON.stringify(reversed); + console.assert(reversed_strified === '[1,2,3]'); +} +``` + +### by making a copy + +not the best choice, it can be much more difficult to think about and debug. +[on pytut](http://www.pythontutor.com/live.html#code=//%20make%20a%20copy%20of%20the%20argument%0A//%20modify%20it%20direclty%0Afunction%20reverse_a_new_one%28arr%29%20%7B%0A%20%20var%20arr_strified%20%3D%20JSON.stringify%28arr%29%3B%0A%20%20var%20copy%20%3D%20JSON.parse%28arr_strified%29%3B%0A%20%20var%20last_index%20%3D%20copy.length%20-%201%0A%20%20for%20%28let%20i%20%3D%20last_index%3B%20i%20%3E%3D%20last_index%20/%202%3B%20i--%29%20%7B%0A%20%20%20%20const%20temp%20%3D%20copy%5Bi%5D%3B%0A%20%20%20%20copy%5Bi%5D%20%3D%20copy%5Blast_index%20-%20i%5D%3B%0A%20%20%20%20copy%5Blast_index%20-%20i%5D%20%3D%20temp%3B%0A%20%20%7D%0A%20%20return%20copy%3B%0A%7D%0A%0Aconst%20backwards%20%3D%20%5B5,%204,%203,%202,%201%5D%3B%0Aconst%20reversed%20%3D%20reverse_a_new_one%28backwards%29%3B%0A%0Aconst%20reversed_strified%20%3D%20JSON.stringify%28reversed%29%3B%0Aconsole.assert%28reversed_strified%20%3D%3D%3D%20'%5B1,2,3,4,5%5D'%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + // make a copy of the argument + // modify it direclty + function reverse_a_new_one(arr) { + var arr_strified = JSON.stringify(arr); + var copy = JSON.parse(arr_strified); + var last_index = copy.length - 1 + for (let i = last_index; i >= last_index / 2; i--) { + const temp = copy[i]; + copy[i] = copy[last_index - i]; + copy[last_index - i] = temp; + } + return copy; + } + + const backwards = [5, 4, 3, 2, 1]; + const reversed = reverse_a_new_one(backwards); + + const reversed_strified = JSON.stringify(reversed); + console.assert(reversed_strified === '[1,2,3,4,5]'); +} +``` + +[TOP](#reference-type-arguments) + +--- + +## Exercises + +### copy an array + +[on pytut](http://www.pythontutor.com/live.html#code=function%20copy_array%28arr%29%20%7B%0A%20%20//%20write%20this%20using%20JSON.stringify%20%26%20.parse%0A%7D%0A%0Aconst%20array%20%3D%20%5B'a',%20'b'%5D%3B%0Aconst%20by_copy%20%3D%20copy_array%28array%29%3B%0A%0Aconsole.assert%28array%5B0%5D%20%3D%3D%3D%20by_copy%5B0%5D%29%3B%0Aconsole.assert%28array%5B1%5D%20%3D%3D%3D%20by_copy%5B1%5D%29%3B%0Aconsole.assert%28array%20!%3D%3D%20by_copy%29%3B&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function copy_array(arr) { + // write this using JSON.stringify & .parse + } + + const array = ['a', 'b']; + const by_copy = copy_array(array); + + console.assert(array[0] === by_copy[0]); + console.assert(array[1] === by_copy[1]); + console.assert(array !== by_copy); +} +``` + + +### start a new array + +[on pytut](http://www.pythontutor.com/live.html#code=function%20start_new_array%28arr%29%20%7B%0A%20%20//%20write%20this%20by%20building%20a%20new%20array%20from%20scratch%0A%7D%0A%0Aconst%20array%20%3D%20%5B'a',%20'b'%5D%3B%0Aconst%20by_new_start%20%3D%20start_new_array%28array%29%3B%0A%0Aconsole.assert%28array%5B0%5D%20%3D%3D%3D%20by_new_start%5B0%5D%29%3B%0Aconsole.assert%28array%5B1%5D%20%3D%3D%3D%20by_new_start%5B1%5D%29%3B%0Aconsole.assert%28array%20!%3D%3D%20by_new_start%29%3B&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function start_new_array(arr) { + // write this by building a new array from scratch + // the paramenter should only be used on the right side of = + // the new one should only be used on the left side of = + } + + const array = ['a', 'b']; + const by_new_start = start_new_array(array); + + console.assert(array[0] === by_new_start[0]); + console.assert(array[1] === by_new_start[1]); + console.assert(array !== by_new_start); +} +``` + +### copy an object + +[on pytut](http://www.pythontutor.com/live.html#code=function%20copy_object%28obj%29%20%7B%0A%20%20//%20write%20this%20using%20JSON.stringify%20%26%20.parse%0A%7D%0A%0Aconst%20object%20%3D%20%7Ba%3A%201,%20b%3A%202%7D%3B%0Aconst%20by_copy%20%3D%20copy_object%28object%29%3B%0A%0Aconsole.assert%28object.a%20%3D%3D%3D%20by_copy.a%29%3B%0Aconsole.assert%28object%5B'b'%5D%20%3D%3D%3D%20by_copy%5B'b'%5D%29%3B%0Aconsole.assert%28object%20!%3D%3D%20by_copy%29%3B&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function copy_object(obj) { + // write this using JSON.stringify & .parse + } + + const object = {a: 1, b: 2}; + const by_copy = copy_object(object); + + console.assert(object.a === by_copy.a); + console.assert(object['b'] === by_copy['b']); + console.assert(object !== by_copy); +} +``` + + +### start a new object + +[on pytut](http://www.pythontutor.com/live.html#code=function%20start_new_object%28obj%29%20%7B%0A%20%20//%20write%20this%20by%20building%20a%20new%20object%20from%20scratch%0A%7D%0A%0Aconst%20object%20%3D%20%7Ba%3A%201,%20b%3A%202%7D%3B%0Aconst%20by_new_start%20%3D%20start_new_object%28object%29%3B%0A%0Aconsole.assert%28object.a%20%3D%3D%3D%20by_new_start.a%29%3B%0Aconsole.assert%28object%5B'b'%5D%20%3D%3D%3D%20by_new_start%5B'b'%5D%29%3B%0Aconsole.assert%28object%20!%3D%3D%20by_new_start%29%3B&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function start_new_object(obj) { + // write this by building a new object from scratch + // the paramenter should only be used on the right side of = + // the new one should only be used on the left side of = + } + + const object = {a: 1, b: 2}; + const by_new_start = start_new_object(object); + + console.assert(object.a === by_new_start.a); + console.assert(object['b'] === by_new_start['b']); + console.assert(object !== by_new_start); +} +``` + + + +[TOP](#reference-type-arguments) + +___ +___ +### Janke Learning diff --git a/week-2/jl-loop-refactors.md b/week-2/jl-loop-refactors.md index d55b4e5..6cd6689 100644 --- a/week-2/jl-loop-refactors.md +++ b/week-2/jl-loop-refactors.md @@ -1 +1,532 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/colevandersWands/loop-refactors/master/README.md) into this file and complete the exercises! +# Loop Refactors + +At it's simplist _refactoring_ is rewriting code while keeping it's original behavior. In the exercises and examples below you can test your refactors by pasting & running the original code in the console, then pasting & running your refactor in console. If both snippets log the exact same messages you have successfully completed the exercise! + +Learning to refactor loops is one of the best ways to learn how they work without struggling to solve code challenges. As you practice shifting between ```while``` and ```for``` loops you'll begin to recognize the general principles of iteration: +1. initial value +1. advancing operation +1. end condition + +Learning to identify these steps and rewrite loops in different ways will help you with debugging, problem solving & understanding other people's code. + +### INDEX +* [learning objectives](#learning-objectives) +* completed examples + * [for](#for) + * [while](#while) + * [do-while](#do-while) +* exercises + * [for to while (4)](#for-to-while) + * [while to for (4)](#while-to-for) +* [for or while?](#for-or-while) +* [resources](#resources) + + +--- + +## Learning Objectives + +* mastering JS loop syntax +* identifying the 3 key components of an iteration +* shifting easily between loop types +* separating the __structure__ of written code from the __behavior__ of program data + +[TOP](#loop-refactors) + +--- + +## Completed Examples + +### For + + +__[From w3schools](https://www.w3schools.com/js/js_loop_for.asp)__: +> The for loop has the following syntax: +``` +for (statement 1; statement 2; statement 3) { + code block to be executed +} +``` +> Statement 1 is executed (one time) before the execution of the code block. +> Statement 2 defines the condition for executing the code block. +> Statement 3 is executed (every time) after the code block has been executed. + +* [study ```for``` on pytut](http://www.pythontutor.com/live.html#code=//%20for%20loop%0Afor%20%28%20let%20stepper%20%3D%200%3B%20stepper%20%3C%204%3B%20stepper%2B%2B%20%29%20%7B%0A%20%20//%20body%0A%7D%0A%0A%0A&cumulative=false&curInstr=9&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +* [```for``` loop parsonized](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20for%20loop%0Afor%20%28%20let%20stepper%20%3D%200%3B%20stepper%20%3C%204%3B%20stepper%2B%2B%20%29%20%7B%0A%20%20%2F%2F%20body%0A%7D%0A%0A%0A) +* [block scope in for loops](http://www.pythontutor.com/live.html#code=for%20%28var%20x%20%3D%200%3B%20x%20%3C%202%3B%20x%2B%2B%29%20%7B%0A%20%20console.log%28%22x%3A%20%22,%20x%29%3B%0A%7D%0A%0Afor%20%28let%20y%20%3D%200%3B%20y%20%3C%202%3B%20y%2B%2B%29%20%7B%0A%20%20console.log%28%22y%3A%20%22,%20y%29%3B%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) - JS does an unexpected thing by creating 2 blocks while stepping through the loop. for now just know that this happens, you can understand why later when you learn about closure. + +_original for loop_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + for ( let stepper = 0; stepper < 3; stepper++ ) { + result += stepper; + console.log(result); + } + + console.log("final result: ", result); +} +``` + +_refactored to while_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + let stepper = 0; + while ( stepper < 3 ) { + result += stepper; + console.log(result); + stepper++; + } + + console.log("final result: ", result); +} +``` + +_refactored to do-while_ +```js +/* + it is not possible to refactor for loops into do-while loops + for loops might never execute their body + do-while loops will always execute their body at least once +*/ +``` + + +[TOP](#loop-refactors) + +--- + +### While + +* [```while``` on pytut](http://www.pythontutor.com/live.html#code=//%20while%20loop%0Alet%20stepper%20%3D%200%3B%0Awhile%20%28%20%20stepper%20%3C%204%20%29%20%7B%0A%20%20//%20body%0A%20%20stepper%2B%2B%3B%3B%0A%7D%0A%0A%0A&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +* [```while``` parsonized](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20while%20loop%0Alet%20stepper%20%3D%200%3B%0Awhile%20%28stepper%20%3C%204%29%20%7B%0A%20%20%2F%2F%20body%0A%20%20stepper%2B%2B%3B%0A%7D%0A%0A%0A) + +_original while loop_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + let stepper = 0; + while ( stepper < 3 ) { + result += stepper; + console.log(result); + stepper++; + } + + console.log("final result: ", result); +} +``` + +_refactored to for loop_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + for ( let stepper = 0; stepper < 3; stepper++ ) { + result += stepper; + console.log(result); + } + + console.log("final result: ", result); +} +``` + +_refactored to do-while_ +```js +/* + it is not possible to refactor while loops into do-while loops + while loops might never execute their body + do-while loops will always execute their body at least once +*/ +``` + + +[TOP](#loop-refactors) + +--- + +### Do-While + +* [```do-while``` on pytut](http://www.pythontutor.com/live.html#code=//%20do-while%20loop%0Alet%20stepper%20%3D%200%3B%0Ado%20%7B%0A%20%20//%20body%0A%20%20stepper%2B%2B%3B%0A%7D%20while%20%28stepper%20%3C%204%29%3B%0A%0A%0A&cumulative=false&curInstr=9&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +* [```do-while``` parsonized](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20do-while%20loop%0Alet%20stepper%20%3D%200%3B%0Ado%20%7B%0A%20%20%2F%2F%20body%0A%20%20stepper%2B%2B%3B%0A%7D%20while%20%28stepper%20%3C%204%29%3B%0A%0A%0A) + +_original do-while_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + let stepper = 0; + do { + result += stepper; + console.log(result); + stepper++; + } while (stepper < 3); + + console.log("final result: ", result); +} +``` + +_refactored to while_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + let stepper = 0; + + // do + result += stepper; + console.log(result); + stepper++; + + while (stepper < 3) { + result += stepper; + console.log(result); + stepper++; + } + + console.log("final result: ", result); +} +``` + +_refactored to for_ +```js +{ + let result = ''; + console.log("initial result: ", result); + + let stepper = 0; + + // do + result += stepper; + console.log(result); + + for ( stepper = 1; stepper < 3; stepper++ ) { + result += stepper; + console.log(result); + } + + console.log("final result: ", result); +} +``` + + +[TOP](#loop-refactors) + +--- + + +## Exercises + + +### For to While + +### for -> while 1 + +[practice on pytut](http://www.pythontutor.com/live.html#code=%7B%0A%20%20let%20result%20%3D%200%3B%0A%20%20for%20%28let%20i%20%3D%201%3B%20i%20%3C%2010%3B%20i%20%2B%3D%20result%29%20%7B%0A%20%20%20%20result%20%2B%3D%20i%3B%0A%20%20%20%20console.log%28i%29%3B%0A%20%20%7D%0A%7D%0A//%20refactor%20to%20while%20loop%0A%0Awhile%20%28%29%20%7B%0A%20%20%0A%7D&cumulative=false&curInstr=15&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +_original for loop_ +```js +{ + let result = 0; + for (let i = 1; i < 10; i += result) { + result += i; + console.log(i); + } +} +``` + +_refactor to while_ +```js +{ + while () { + + } +} +``` + +[parsonized solution](https://janke-learning.github.io/parsonizer/?snippet=let%20result%20%3D%200%3B%0Alet%20i%20%3D%201%3B%0Awhile%20%28%20i%20%3C%2010%20%29%20%7B%0A%20%20result%20%2B%3D%20i%3B%0A%20%20console.log%28i%29%3B%0A%20%20i%20%2B%3D%20result%3B%0A%7D) + +--- + +### for -> while 2 + +[practice on pytut](http://www.pythontutor.com/live.html#code=for%20%28let%20i%20%3D%20-3%3B%20i%20%3D%3D%3D%2010%20%7C%7C%20i%20%3C%2020%3B%20i%20*%3D%20-1.5%29%20%7B%0A%20%20console.log%28i%29%3B%0A%7D%0A%0A//%20refactor%20to%20while%20loop%0A%0Awhile%20%28%29%20%7B%0A%20%20%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +_original for loop_ +```js +{ + for (let i = -3; i === 10 || i < 20; i *= -1.5) { + console.log(i); + } +} +``` + +_refactor to while_ +```js +{ + while () { + + } +} +``` + +[parsonized solution](https://janke-learning.github.io/parsonizer/?snippet=let%20i%20%3D%20-3%3B%0Awhile%20%28i%20%3D%3D%3D%2010%20%7C%7C%20i%20%3C%2020%29%20%7B%0A%20%20console.log%28i%29%3B%0A%20%20i%20*%3D%20-1.5%3B%0A%7D) + +--- + +### for -> while 3 + +[practice on pytut](http://www.pythontutor.com/live.html#code=%7B%0A%20%20for%20%28let%20i%20%3D%200,%20j%20%3D%2010%3B%20i%20!%3D%3D%20j%3B%20i%2B%2B,%20j--%29%20%7B%0A%20%20%20%20console.log%28%22i%3A%20%22,%20i%29%3B%0A%20%20%20%20console.log%28%22j%3A%20%22,%20j%29%3B%0A%20%20%20%20console.log%28%22i%20%2B%20j%3A%20%22,%20i%20%2B%20j%29%3B%0A%20%20%7D%0A%7D%0A%0A//%20refactor%20to%20while%20loop%0A%0Awhile%20%28%29%20%7B%0A%20%20%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +_original for loop_ +```js +{ + for (let i = 0, j = 10; i !== j; i++, j--) { + console.log("i: ", i); + console.log("j: ", j); + console.log("i + j: ", i + j); + } +} +``` + +_refactor to while_ +```js +{ + while () { + + } +} +``` + +[parsonized solution](https://janke-learning.github.io/parsonizer/?snippet=let%20i%20%3D%200%2C%20j%20%3D%2010%3B%0Awhile%20%28%20i%20!%3D%3D%20j%20%29%20%7B%0A%20%20console.log%28%22i%3A%20%22%2C%20i%29%3B%0A%20%20console.log%28%22j%3A%20%22%2C%20j%29%3B%0A%20%20console.log%28%22i%20%2B%20j%3A%20%22%2C%20i%20%2B%20j%29%3B%0A%20%20i%2B%2B%2C%20j--%3B%0A%7D) + +--- + + +### for -> while 4 + +> The logic in this loop is difficult to understand; The goal of these refactors is to recognize the __form__ of your code without worrying about the content. You can easily complete this exercise without understanding what's happening! This is the power of learning reliable refactoring patterns + +[practice on pytut](http://www.pythontutor.com/live.html#code=%7B%0A%20%20const%20mixitup%20%3D%20false%3B%0A%20%20let%20val%3B%0A%20%20for%20%28let%20i%20%3D%20''%3B%20!!i%20!%3D%3D%20true%20%3B%20i%20%3D%20%2Bval%29%20%7B%0A%20%20%20%20val%20%3D%20!i%20%7C%7C%20mixitup%20*%20i%3B%0A%20%20%20%20console.log%28!!val%29%3B%0A%20%20%7D%0A%7D%0A%0A//%20refactor%20to%20while%20loop%0A%0Awhile%20%28%29%20%7B%0A%20%20%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +_original for loop_ +```js +{ + const mixitup = false; + let val; + for (let i = ''; !!i !== true ; i = +val) { + val = !i || mixitup * i; + console.log(!!val); + } +} +``` + +_refactor to while_ +```js +{ + while () { + + } +} +``` + +[parsonized solution](https://janke-learning.github.io/parsonizer/?snippet=const%20mixitup%20%3D%20false%3B%0Alet%20val%3B%0Alet%20i%20%3D%20''%3B%0Awhile%20%28%20!!i%20!%3D%3D%20true%20%29%20%7B%0A%20%20val%20%3D%20!i%20%7C%7C%20mixitup%20*%20i%3B%0A%20%20console.log%28!!val%29%3B%0A%20%20i%20%3D%20%2Bval%3B%0A%7D) + + + +[TOP](#loop-refactors) + +--- + +### While to For + +### while -> for 1 + +[practice on pytut](http://www.pythontutor.com/live.html#code=let%20x%20%3D%209%3B%0Awhile%20%28x%20%3E%202%29%20%7B%0A%20%20console.log%28x%20*%203%29%3B%0A%20%20x--%3B%0A%7D%0A%0A//%20refactor%20to%20for%20loop%0A%0Afor%20%28%20%3B%20%3B%20%29%20%7B%0A%20%20%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +[parsonized while loop](https://janke-learning.github.io/parsonizer/?snippet=let%20x%20%3D%209%3B%0Awhile%20%28x%20%3E%202%29%20%7B%0A%20%20console.log%28x%20*%203%29%3B%0A%20%20x--%3B%0A%7D) + +_original while loop_ +```js +{ + let x = 9; + while (x > 2) { + console.log(x * 3); + x--; + } +} +``` + +_refactor to for_ +```js +{ + for ( ; ; ) { + + } +} +``` + +--- + +### while -> for 2 + +> the [```++``` operator](https://github.com/janke-learning/expanding/blob/master/worked-in-place-operators.md) does two things in one step, it increments it's variable and returns a value. When used in a while loop condition it does the work of the second & third parts of a for loop statement. + +[practice on pytut](http://www.pythontutor.com/live.html#code=let%20x%20%3D%209%3B%0Awhile%20%28x%2B%2B%20%3C%2020%29%20%7B%0A%20%20console.log%28x%29%3B%0A%7D%0A%0A//%20refactor%20to%20for%20loop%0A%0Afor%20%28%20%3B%20%3B%20/*%20nothing%20goes%20here%20*/%20%29%20%7B%0A%20%20%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + + +_original while loop_ +```js +{ + let x = 9; + while (x++ < 20) { + console.log(x); + } +} +``` + +_refactor to for_ +```js +{ + for ( ; ; /* nothing goes here */ ) { + + } +} +``` + + +--- + +### while -> for 3 + +> for this refactor, write your for loop without using [```++``` operator](https://github.com/janke-learning/expanding/blob/master/worked-in-place-operators.md) in the condition check. we've started the refactor so you can get the idea + +[practice on pytut](http://www.pythontutor.com/live.html#code=/*%20%0Afor%20this%20refactor,%20write%20your%20for%20loop%20without%20using%20%0A%20%20%60%60%60%2B%2B%60%60%60%20in%20the%20condition%20check.%20%0A%20%20we've%20started%20the%20refactor%20so%20you%20can%20get%20the%20idea%0A*/%0A%0Alet%20x%20%3D%209%3B%0Awhile%20%28x%2B%2B%20%3C%2020%29%20%7B%0A%20%20console.log%28x%29%3B%0A%7D%0A%0A//%20refactor%20to%20for%20loop%0A%0Afor%20%28%20%3B%20x%20%3C%20%3B%20x%20%2B%3D%201%20%29%20%7B%0A%20%20%0A%7D&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + + +_original while loop_ +```js +{ + let x = 9; + while (x++ < 20) { + console.log(x); + } +} +``` + +_refactor to for_ +```js +{ + for ( ; x < ; x += 1 ) { + + } +} +``` + +--- + +### while -> for 4 + +> for this refactor, write your for loop without using [```++``` operator](https://github.com/janke-learning/expanding/blob/master/worked-in-place-operators.md) in the condition check. we're not starting this one for you + +[practice on pytut](http://www.pythontutor.com/live.html#code=/*%20%0Afor%20this%20refactor,%20write%20your%20for%20loop%20without%20using%20%0A%20%20%60%60%60%2B%2B%60%60%60%20in%20the%20condition%20check.%20%0A%20%20we're%20not%20starting%20this%20one%20for%20you%0A*/%0A%0Alet%20x%20%3D%209%3B%0Awhile%20%28%2B%2Bx%20%3C%2020%29%20%7B%0A%20%20console.log%28x%29%3B%0A%7D%0A%0A//%20refactor%20to%20for%20loop%0A%0Afor%20%28%20%3B%20%3B%20%29%20%7B%0A%20%20%0A%7D&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + + +_original while loop_ +```js +{ + let x = 9; + while (++x < 20) { + console.log(x); + } +} +``` + +_refactor to for_ +```js +{ + for ( ; ; ) { + + } +} +``` + +[TOP](#loop-refactors) + +--- + +## For or While + + +__[From StackOverflow](https://stackoverflow.com/questions/8109509/in-which-situations-should-i-use-while-loops-instead-for-loops-in-javascript#)__ +> (This will soon get closed as too subjective, or moved to another forum, but anyway...) +> Obviously any for loop can easily be rewritten using "while". But given the syntax of: + +``` +for ([initialization]; [condition]; [final-expression]) +``` +> that is used by the for loop it is obviously very well suited to situations where there is some simple initialisation and a simple end-of-iteration update or counter increment. Putting all of the loop control logic right there in the loop's opening statement makes it easy to see at a glance what makes the loop tick. +> With a while loop the end-of-iteration processing generally has to happen at the bottom of the loop's body, so it's harder to see at a glance how the loop works, but also that is much more suited to the situation where you have to perform a number of calculations to decide whether to keep the loop going. +> Of course you can shove multiple statements in a for loop initialisation or final-expression by separating them with commas, but if that is anything more complicated than i++, j++, k-- it quickly gets too messy for my taste and a while loop would be a better choice. +> +> -- nnnnnn + +__For__ loops in JavaScript could be considered [syntactic sugar](https://www.quora.com/What-is-syntactic-sugar-in-programming-languages), meaning you can replicate their exact behavior using simpler language features. + +--- + + +## Resources + + +__study tools__ +* [python tutor for JS](http://www.pythontutor.com/live.html#code=&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +* [parsonizer](https://janke-learning.org/parsonizer) + +__control-flow visualization__ +* (neither of these tools are perfect. if you find them confusing that's just fine, if they help you all the better!) +* [code2flow](https://code2flow.com/app) +* [flowviz](https://janke-learning.org/flowviz) + +__while loops__ +* [javascript.info](https://javascript.info/while-for#the-while-loop) +* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while) +* [Video](https://www.youtube.com/watch?v=PpbFyLTtpWI) +* [use while instead of for](https://teamtreehouse.com/community/why-use-while-loop-instead-of-for) + +__for loops__ +* [MDN on For Loops](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) +* [Video + Article](https://www.kirupa.com/html5/loops_in_javascript.htm) +* [StackOverflow](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript) +* [block scope in for loops](http://www.pythontutor.com/live.html#code=for%20%28var%20x%20%3D%200%3B%20x%20%3C%202%3B%20x%2B%2B%29%20%7B%0A%20%20console.log%28%22x%3A%20%22,%20x%29%3B%0A%7D%0A%0Afor%20%28let%20y%20%3D%200%3B%20y%20%3C%202%3B%20y%2B%2B%29%20%7B%0A%20%20console.log%28%22y%3A%20%22,%20y%29%3B%0A%7D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) - JS does an unexpected thing by creating 2 blocks while stepping through the loop. for now just know that this happens, you can understand why later when you learn about closure. + +__do-while loops__ +* [javascript.info](https://javascript.info/while-for#the-do-while-loop) +* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while) +* [do vs. while: Tutorial GateWay](https://www.tutorialgateway.org/difference-between-javascript-while-and-do-while-loop/) +* [do vs. while: Digital Ocean](https://www.digitalocean.com/community/tutorials/using-while-and-do-while-loops-in-javascript) + + +__loops__ +* [So many of them!](https://www.hackreactor.com/blog/javascript-loops-difference-between-types-while-for-in) +* [interactive examples](http://www.dofactory.com/tutorial/javascript-loops) + + + + + + +[TOP](#loop-refactors) + +___ +___ +### Janke Learning diff --git a/week-2/jl-reference-types.md b/week-2/jl-reference-types.md index 328ffa9..790ea9a 100644 --- a/week-2/jl-reference-types.md +++ b/week-2/jl-reference-types.md @@ -1 +1,478 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/reference-type-exercises/master/README.md) into this file and complete the exercises! +# Reference Type Exercises + +A series of examples and exercises to help you understand: +* reference vs. value (two ways variables can store values) +* arrays +* objects +* comparing arrays & objects +* nesting data structures + +### Index +* [examples to study](#examples-to-study) +* [reference exercises](#reference-exercises) +* [array exercises](#array-exercises) +* [object exercises](#object-exercises) +* [arrays vs objects](#arrays-vs-objects) +* nesting + * [arrays](#nesting-arrays) + * [objects](#nesting-objects) + * [both](#nesting-arrays-and-objects) + +--- + +## Examples to Study + +__Swapping with Arrays__ +[on pytut](http://www.pythontutor.com/javascript.html#code=let%20a%20%3D%20%5B%22b%22%5D%3B%0Alet%20b%20%3D%20%5B%22a%22%5D%3B%0Alet%20_%20%3D%20null%3B%0A%0A//%20swap%20the%20arrays%20to%20which%20each%20variable%20points%0A_%20%3D%20a%3B%0Aa%20%3D%20b%3B%0Ab%20%3D%20_%3B%0A%0A//%20------%0A%0A_%20%3D%20null%3B%0Alet%20x%20%3D%20%5B%22y%22%5D%3B%0Alet%20y%20%3D%20%5B%22x%22%5D%3B%0A%0A//%20swap%20the%20value%20each%20array%20contains%0A_%20%3D%20x%5B0%5D%3B%0Ax%5B0%5D%20%3D%20y%5B0%5D%3B%0Ay%5B0%5D%20%3D%20_%3B&curInstr=0&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let a = ["b"]; + let b = ["a"]; + let _ = null; + + // swap the arrays to which each variable points + _ = a; + a = b; + b = _; + + // ------ + + _ = null; + let x = ["y"]; + let y = ["x"]; + + // swap the value each array contains + _ = x[0]; + x[0] = y[0]; + y[0] = _; +} +``` + +__Comparing Reference Types__ +[on pytut](http://www.pythontutor.com/live.html#code=let%20a%20%3D%20%5B%5D%3B%0Alet%20b%20%3D%20%5B%5D%3B%0Aconsole.assert%28a%20!%3D%3D%20b%29%3B%0Aconsole.assert%28a%20%3D%3D%3D%20b%29%3B%0A%0Ab%20%3D%20a%3B%0Aconsole.assert%28a%20%3D%3D%3D%20b%29%3B%0Aconsole.assert%28a%20!%3D%3D%20b%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + let a = []; + let b = []; + console.assert(a !== b); + console.assert(a === b); + + b = a; + console.assert(a === b); + console.assert(a !== b); +} +``` + + +__Swapping with Objects__ (dot notation) +[on pytut](http://www.pythontutor.com/live.html#code=let%20a%20%3D%20%7By_prop%3A%20%22y%22%7D%3B%0Alet%20b%20%3D%20%7Bx_prop%3A%20%22x%22%7D%3B%0Alet%20_%20%3D%20null%3B%0A%0A//%20swap%20the%20object%20in%20which%20each%20value%20is%20stored%0A_%20%3D%20a%3B%0Aa%20%3D%20b%3B%0Ab%20%3D%20_%3B%0A%0A//%20------%0A%0A_%20%3D%20null%3B%0Alet%20x%20%3D%20%7Ba_prop%3A%20%22b%22%7D%3B%0Alet%20y%20%3D%20%7Bb_prop%3A%20%22a%22%7D%3B%0A%0A//%20swap%20the%20value%20each%20object%20contains%0A_%20%3D%20x.a_prop%3B%0Ax.a_prop%20%3D%20y.b_prop%3B%0Ay.b_prop%20%3D%20_%3B&cumulative=false&curInstr=12&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + let a = {y_prop: "y"}; + let b = {x_prop: "x"}; + let _ = null; + + // swap the object in which each value is stored + _ = a; + a = b; + b = _; + + // ------ + + _ = null; + let x = {a_prop: "b"}; + let y = {b_prop: "a"}; + + // swap the value each object contains + _ = x.a_prop; + x.a_prop = y.b_prop; + y.b_prop = _; +} +``` + +__Swapping with Objects__ (bracket notation) +[(read this first)](https://github.com/janke-learning/dots-vs-brackets) +[on pytut](http://www.pythontutor.com/live.html#code=let%20a%20%3D%20%7Bx_prop%3A%20%22y%22%7D%3B%0Alet%20b%20%3D%20%7By_prop%3A%20%22x%22%7D%3B%0Alet%20_%20%3D%20null%3B%0A%0A//%20swap%20the%20object%20in%20which%20each%20value%20is%20stored%0A//%20%20with%20dots%0A_%20%3D%20a.x_prop%3B%0Aa.x_prop%20%3D%20b.y_prop%3B%0Ab.y_prop%20%3D%20_%3B%0A%0A//%20------%0A%0A_%20%3D%20null%3B%0Alet%20x%20%3D%20%7Ba_prop%3A%20%22b%22%7D%3B%0Alet%20y%20%3D%20%7Bb_prop%3A%20%22a%22%7D%3B%0A%0A//%20swap%20the%20object%20in%20which%20each%20value%20is%20stored%0A//%20%20with%20brackets%0Aconst%20a_key%20%3D%20%22a_prop%22%3B%0Aconst%20b_key%20%3D%20%22b_prop%22%3B%0A_%20%3D%20x%5Ba_key%5D%3B%0Ax%5Ba_key%5D%20%3D%20y%5Bb_key%5D%3B%0Ay%5Bb_key%5D%20%3D%20_%3B&cumulative=false&curInstr=14&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + let a = {x_prop: "y"}; + let b = {y_prop: "x"}; + let _ = null; + + // swap the object in which each value is stored + // with dots + _ = a.x_prop; + a.x_prop = b.y_prop; + b.y_prop = _; + + // ------ + + _ = null; + let x = {a_prop: "b"}; + let y = {b_prop: "a"}; + + // swap the object in which each value is stored + // with brackets + const a_key = "a_prop"; + const b_key = "b_prop"; + _ = x[a_key]; + x[a_key] = y[b_key]; + y[b_key] = _; +} +``` + +[TOP](#reference-type-exercises) + +--- + +## Reference Exercises + +__Swap the Object & the Array__ +[on pytut](http://www.pythontutor.com/javascript.html#code=let%20obj%20%3D%20%5B%5D%3B%0Alet%20arr%20%3D%20%7B%7D%3B%0Alet%20_%20%3D%20null%3B%0A%0A//%20swap%20the%20object%20and%20the%20array&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let obj = []; + let arr = {}; + let _ = null; + + // --- swap below here --- + +} +``` + +__Complete this code__ +[(read this first)](https://github.com/janke-learning/reference-vs-value) +[on pytut](http://www.pythontutor.com/javascript.html#code=%20%20let%20value_1%20%3D%205%3B%0A%20%20let%20reference_1%20%3D%20%5B%5D%3B%0A%0A%20%20let%20value_2%20%3D%20value_1%3B%0A%20%20console.assert%28value_2%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20value_1%29%3B%0A%0A%20%20let%20reference_2%20%3D%20reference_1%3B%0A%20%20console.assert%28reference_2%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20reference_1%29%3B%0A%0A%20%20%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20console.assert%28value_1%20!%3D%3D%20value_2%29%3B%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20console.assert%28reference_1%5B0%5D%20%3D%3D%3D%20reference_2%5B0%5D%29%3B%0A%0A%20%20//%20remove%20the%20array%20from%20memory%0A%20%20%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%20%20%3B%20//%20write%20this%20line&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let value_1 = 5; + let reference_1 = []; + + let value_2 = value_1; + console.assert(value_2 /* === or !== ? */ value_1); + + let reference_2 = reference_1; + console.assert(reference_2 /* === or !== ? */ reference_1); + + ; // write this line + console.assert(value_1 !== value_2); + + ; // write this line + console.assert(reference_1[0] === reference_2[0]); + + // remove the array from memory + ; // write this line + ; // write this line +} +``` + +[TOP](#reference-type-exercises) + +--- + +## Array Exercises + +__Complete the Assertions__ +[on pytut](http://www.pythontutor.com/javascript.html#code=let%20a_1%20%3D%20%5B%5D%3B%0Alet%20a_2%20%3D%20a_1%3B%0Aconsole.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0Alet%20b_1%20%3D%20%5B%5D%3B%0Alet%20b_2%20%3D%20%5B%5D%3B%0Aconsole.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A%0A//%20---%0A%0Alet%20a_1.push%283%29%3B%0Alet%20a_2.push%283%29%3B%0Aconsole.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0Alet%20b_1.push%285%29%3B%0Alet%20b_2.push%285%29%3B%0Aconsole.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A%0A&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let a_1 = []; + let a_2 = a_1; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1 = []; + let b_2 = []; + console.assert(b_1 /* === or !== ? */ b_2); + + // --- + + let a_1.push(3); + let a_2.push(3); + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1.push(5); + let b_2.push(5); + console.assert(b_1 /* === or !== ? */ b_2); +} +``` + +__Complete the Assertions__ +[on pytut](http://www.pythontutor.com/javascript.html#code=let%20a_1%20%3D%20%5B%5D%3B%0Alet%20a_2%20%3D%20a_1%3B%0Aconsole.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0Alet%20b_1%20%3D%20%5B%5D%3B%0Alet%20b_2%20%3D%20%5B%5D%3B%0Aconsole.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A%0A//%20---%0A%0Aconst%20key%20%3D%200%3B%0A%0Alet%20a_1%5Bkey%5D%20%3D%203%3B%0Alet%20a_2%5Bkey%5D%20%3D%203%3B%0Aconsole.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0Alet%20b_1%5Bkey%5D%20%3D%205%3B%0Alet%20b_2%5Bkey%5D%20%3D%205%3B%0Aconsole.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let a_1 = []; + let a_2 = a_1; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1 = []; + let b_2 = []; + console.assert(b_1 /* === or !== ? */ b_2); + + // --- + + const index = 0; + + let a_1[index] = 3; + let a_2[index] = 3; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1[index] = 5; + let b_2[index] = 5; + console.assert(b_1 /* === or !== ? */ b_2); +} +``` + +__Fill in the Blanks__ +[on pytut](http://www.pythontutor.com/live.html#code=%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28arr_1%20!%3D%3D%20arr_2%29%3B%0Aconsole.assert%28arr_1%5B1%5D%20%3D%3D%3D%20arr_2%5B1%5D%29%3B%0Aconsole.assert%28arr_1%5B1%5D%20%3D%3D%3D%20'B'%29%0A%0Alet%20key%20%3D%200%3B%0Aconsole.assert%28arr_1%5Bkey%5D%20%3D%3D%3D%20arr_2%5Bkey%5D%29%3B%0Aconsole.assert%28arr_1%5Bkey%5D%20%3D%3D%3D%20'A'%29%3B%0A%0A%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28arr_1%5Barr_2%5B2%5D%5D%20%3D%3D%3D%20arr_2%5Barr_1%5B2%5D%5D%29%3B%0Aconsole.assert%28arr_1%5Barr_2%5B2%5D%5D%20%3D%3D%3D%20'B'%29%3B%0A%0A%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28arr_1%20%3D%3D%3D%20arr_2%29%3B%0Aconsole.assert%28arr_3%20!%3D%3D%20arr_1%29%3B%0Aconsole.assert%28arr_3%20!%3D%3D%20arr_2%29%3B%0Aconsole.assert%28arr_3%5Bkey%5D%20%3D%3D%3D%20arr_1%5B0%5D%29%3B%0A%0A%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28obj_3%5B1%5D%20%3D%3D%3D%20obj_2%5Bkey%5D%29%3B&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + ; // write this line + ; // write this line + console.assert(arr_1 !== arr_2); + console.assert(arr_1[1] === arr_2[1]); + console.assert(arr_1[1] === 'B') + + let key = 0; + console.assert(arr_1[key] === arr_2[key]); + console.assert(arr_1[key] === 'A'); + + ; // write this line + ; // write this line + console.assert(arr_1[arr_2[2]] === arr_2[arr_1[2]]); + console.assert(arr_1[arr_2[2]] === 'B'); + + ; // write this line + ; // write this line + console.assert(arr_1 === arr_2); + console.assert(arr_3 !== arr_1); + console.assert(arr_3 !== arr_2); + console.assert(arr_3[key] === arr_1[0]); + + ; // write this line + console.assert(obj_3[1] === obj_2[key]); +} +``` + +[TOP](#reference-type-exercises) + +--- + +## Object Exercises + +__Complete the Assertions__ +[on pytut](http://www.pythontutor.com/javascript.html#code=let%20a_1%20%3D%20%7B%7D%3B%0Alet%20a_2%20%3D%20a_1%3B%0Aconsole.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0Alet%20b_1%20%3D%20%7B%7D%3B%0Alet%20b_2%20%3D%20%7B%7D%3B%0Aconsole.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A%0A//%20---%0A%0Alet%20a_1.x%20%3D%203%3B%0Alet%20a_2.x%20%3D%203%3B%0Aconsole.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0Alet%20b_1.x%20%3D%205%3B%0Alet%20b_2.x%20%3D%205%3B%0Aconsole.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A%0A&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let a_1 = {}; + let a_2 = a_1; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1 = {}; + let b_2 = {}; + console.assert(b_1 /* === or !== ? */ b_2); + + // --- + + let a_1.x = 3; + let a_2.x = 3; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1.x = 5; + let b_2.x = 5; + console.assert(b_1 /* === or !== ? */ b_2); +} +``` + +__Complete the Assertions__ +[on pytut](http://www.pythontutor.com/javascript.html#code=%20%20let%20a_1%20%3D%20%7B%7D%3B%0A%20%20let%20a_2%20%3D%20a_1%3B%0A%20%20console.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0A%20%20let%20b_1%20%3D%20%7B%7D%3B%0A%20%20let%20b_2%20%3D%20%7B%7D%3B%0A%20%20console.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B%0A%0A%20%20//%20---%0A%20%20%0A%20%20const%20key%20%3D%20%22x%22%3B%0A%0A%20%20let%20a_1%5Bkey%5D%20%3D%203%3B%0A%20%20let%20a_2%5Bkey%5D%20%3D%203%3B%0A%20%20console.assert%28a_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20a_2%29%3B%0A%0A%20%20let%20b_1%5Bkey%5D%20%3D%205%3B%0A%20%20let%20b_2%5Bkey%5D%20%3D%205%3B%0A%20%20console.assert%28b_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20b_2%29%3B&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + let a_1 = {}; + let a_2 = a_1; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1 = {}; + let b_2 = {}; + console.assert(b_1 /* === or !== ? */ b_2); + + // --- + + const key = "x"; + + let a_1[key] = 3; + let a_2[key] = 3; + console.assert(a_1 /* === or !== ? */ a_2); + + let b_1[key] = 5; + let b_2[key] = 5; + console.assert(b_1 /* === or !== ? */ b_2); +} +``` + +__Fill in the Blanks__ +[on pytut](http://www.pythontutor.com/live.html#code=%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%3B%20//%20write%20this%20line%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28obj_1%20!%3D%3D%20obj_2%29%3B%0Aconsole.assert%28obj_1.x%20%3D%3D%3D%20obj_2.x%29%3B%0Aconsole.assert%28obj_1.x%20%3D%3D%3D%20%22a%22%29%3B%0A%0Alet%20key%20%3D%20%22y%22%3B%0Aconsole.assert%28obj_1%5Bkey%5D%20%3D%3D%3D%20obj_2%5Bkey%5D%29%3B%0Aconsole.assert%28obj_1%5Bkey%5D%20%3D%3D%3D%20'x'%29%3B%0A%0A%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28obj_1%5Bobj_2.y%5D%20%3D%3D%3D%20obj_2%5Bobj_1.y%5D%29%3B%0Aconsole.assert%28obj_1%5Bobj_2.y%5D%20%3D%3D%3D%20obj_1%5B'x'%5D%29%3B%0A%0A%20%20%20%20%3B%20//%20write%20this%20line%0A%20%20%20%20%3B%20//%20write%20this%20line%0Aconsole.assert%28obj_1%20%3D%3D%3D%20obj_2%29%3B%0Aconsole.assert%28obj_3%20!%3D%3D%20obj_1%29%3B%0Aconsole.assert%28obj_3%20!%3D%3D%20obj_2%29%3B%0Aconsole.assert%28obj_3%5Bkey%5D%20%3D%3D%3D%20obj_1.y%29%3B%0Aconsole.assert%28obj_3%5B'x'%5D%20%3D%3D%3D%20key%29%3B&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + ; // write this line + ; // write this line ; // write this line + console.assert(obj_1 !== obj_2); + console.assert(obj_1.x === obj_2.x); + console.assert(obj_1.x === "a"); + + let key = "y"; + console.assert(obj_1[key] === obj_2[key]); + console.assert(obj_1[key] === 'x'); + + ; // write this line + ; // write this line + console.assert(obj_1[obj_2.y] === obj_2[obj_1.y]); + console.assert(obj_1[obj_2.y] === obj_1['x']); + + ; // write this line + ; // write this line + console.assert(obj_1 === obj_2); + console.assert(obj_3 !== obj_1); + console.assert(obj_3 !== obj_2); + console.assert(obj_3[key] === obj_1.y); + console.assert(obj_3['x'] === key); +} +``` + +[TOP](#reference-type-exercises) + +--- + +## Comparison Exercises + +__Swap 'em__ +[on pytut](http://www.pythontutor.com/javascript.html#code=const%20obj%20%3D%20%7Bprop%3A%20%22array%22%7D%3B%0Aconst%20arr%20%3D%20%5B%22object%22%5D%3B%0Alet%20_%20%3D%20null%3B%0A%0A//%20swap%20the%20values%20stored%20in%20each%20structure%0A//%20%20using%20dot%20notation%20for%20the%20object%0A//%20%20using%20direct%20access%20for%20the%20array&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + const obj = {prop: "array"}; + const arr = ["object"]; + let _ = null; + + // swap the values stored in each structure + // using dot notation for the object + // using direct access for the array +} +``` + +__Swap 'em__ +[on pytut](http://www.pythontutor.com/live.html#code=const%20obj%20%3D%20%7Bprop%3A%20%22array%22%7D%3B%0Aconst%20arr%20%3D%20%5B%22object%22%5D%3B%0Alet%20_%20%3D%20null%3B%0A%0A//%20fill%20in%20these%20blanks%0Aconst%20obj_key%20%3D%20%3B%0Aconst%20arr_index%20%3D%20%3B%0A%0A_%20%3D%20arr%5Barr_index%5D%3B%0Aarr%5Barr_index%5D%20%3D%20obj%5Bobj_key%5D%3B%0Aobj%5Bobj_key%5D%20%3D%20_%3B%0A%0Aconsole.assert%28arr%5Barr_index%5D%20%3D%3D%3D%20%22object%22,%20%22first%20assert%22%29%3B%0Aconsole.assert%28obj%5Bobj_key%5D%20%3D%3D%3D%20%22array%22,%20%22second%20assert%22%29%3B&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + const obj = {prop: "array"}; + const arr = ["object"]; + let _ = null; + + // fill in these blanks + const obj_key = ; + const arr_index = ; + + _ = arr[arr_index]; + arr[arr_index] = obj[obj_key]; + obj[obj_key] = _; + + console.assert(arr[arr_index] === "object", "first assert"); + console.assert(obj[obj_key] === "array", "second assert"); +} +``` + +__Relative vs Absolute__ +[on pytut](http://www.pythontutor.com/javascript.html#code=//%20array%20indices%20are%20relative%0Aconst%20arr%20%3D%20%5B%22a%22,%20%22b%22%5D%3B%0Aconst%20index%20%3D%200%3B%0A%0Aconst%20read_arr_1%20%3D%20arr%5Bindex%5D%3B%0Aarr.shift%28%29%3B%20//%20removes%20the%20first%20item%0Aconst%20read_arr_2%20%3D%20arr%5Bindex%5D%3B%0A%0Aconsole.assert%28read_arr_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20read_arr_2%29%3B%0A%0A//%20object%20keys%20are%20absolute%0Aconst%20obj%20%3D%20%7Bx%3A%20%22a%22,%20y%3A%20%22b%22%7D%3B%0Aconst%20key%20%3D%20%22y%22%3B%0A%0Aconst%20read_obj_1%20%3D%20obj%5Bkey%5D%3B%0Adelete%20obj.x%3B%0Aconst%20read_obj_2%20%3D%20obj%5Bkey%5D%3B%0A%0Aconsole.assert%28read_obj_1%20/*%20%3D%3D%3D%20or%20!%3D%3D%20%3F%20*/%20read_obj_2%29%3B&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ + // array indices are relative + const arr = ["a", "b"]; + const index = 0; + + const read_arr_1 = arr[index]; + arr.shift(); // removes the first item + const read_arr_2 = arr[index]; + + console.assert(read_arr_1 /* === or !== ? */ read_arr_2); + + // object keys are absolute + const obj = {x: "a", y: "b"}; + const key = "y"; + + const read_obj_1 = obj[key]; + delete obj.x; + const read_obj_2 = obj[key]; + + console.assert(read_obj_1 /* === or !== ? */ read_obj_2); +} +``` + +[TOP](#reference-type-exercises) + +--- + +## Nesting Reference Types + +### Nesting Arrays + +__complete the asserts__ +[on pytut](http://www.pythontutor.com/live.html#code=let%20arr_1%20%3D%20%5B%5D%3B%0Alet%20arr_2%20%3D%20%5B%5D%3B%0A%0Aarr_1.push%28arr_2%29%3B%0Aarr_2.push%28arr_1%29%3B%0Aconsole.assert%28arr_1%5B0%5D%20/*%20%3D%3D%3D%20or%20!%3D%3D%20*/%20arr_2%29%3B%0Aconsole.assert%28arr_2%5B0%5D%20/*%20%3D%3D%3D%20or%20!%3D%3D%20*/%20arr_1%29%3B%0A%0Aarr_1.push%28%5B%5D%29%3B%0Aarr_2.push%28%5B%5D%29%3B%0Aconsole.assert%28arr_1%5B1%5D%20/*%20%3D%3D%3D%20or%20!%3D%3D%20*/%20arr_2%5B1%5D%29%3B%0A%0Aarr_1%5B0%5D.push%28'A'%29%3B%0Aconsole.assert%28arr_1%5B0%5D%5B2%5D%20/*%20%3D%3D%3D%20or%20!%3D%3D%20*/%20arr_2%5B2%5D%29%3B%0A%0Aarr_2%5B0%5D.push%28'B'%29%3B%0Aconsole.assert%28arr_2%5B0%5D%5B2%5D%20/*%20%3D%3D%3D%20or%20!%3D%3D%20*/%20arr_1%5B2%5D%29%3B%0A%0Aarr_1%5B1%5D.push%28'X'%29%3B%0Aarr_2%5B1%5D.push%28'X'%29%3B%0Aconsole.assert%28arr_1%5B1%5D%5B0%5D%20/*%20%3D%3D%3D%20or%20!%3D%3D%20*/%20arr_2%5B1%5D%5B0%5D%29&cumulative=false&curInstr=9&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + let arr_1 = []; + let arr_2 = []; + + arr_1.push(arr_2); + arr_2.push(arr_1); + console.assert(arr_1[0] /* === or !== */ arr_2); + console.assert(arr_2[0] /* === or !== */ arr_1); + + arr_1.push([]); + arr_2.push([]); + console.assert(arr_1[1] /* === or !== */ arr_2[1]); + + arr_1[0].push('A'); + console.assert(arr_1[0][2] /* === or !== */ arr_2[2]); + + arr_2[0].push('B'); + console.assert(arr_2[0][2] /* === or !== */ arr_1[2]); + + arr_1[1].push('X'); + arr_2[1].push('X'); + console.assert(arr_1[1][0] /* === or !== */ arr_2[1][0]) +} +``` + +__fill in the blanks__ +```js +{ + let arr_1 = []; + let arr_2 = []; + + arr_1.push(arr_2); + arr_2.push(arr_1); + console.assert(arr_1[0] /* === or !== */ arr_2); + console.assert(arr_2[0] /* === or !== */ arr_1); + + arr_1.push([]); + arr_2.push([]); + console.assert(arr_1[1] /* === or !== */ arr_2[1]); + + arr_1[0].push('A'); + console.assert(arr_1[0][2] /* === or !== */ arr_2[2]); + + arr_2[0].push('B'); + console.assert(arr_2[0][2] /* === or !== */ arr_1[2]); + + arr_1[1].push('X'); + arr_2[1].push('X'); + console.assert(arr_1[1][0] /* === or !== */ arr_2[1][0]) +} +``` + +### Nesting Objects + +### Nesting Arrays and Objects + +___ +___ +### Janke Learning diff --git a/week-2/jl-variables-sentences-1.md b/week-2/jl-variables-sentences-1.md index 9d47c67..b5e2144 100644 --- a/week-2/jl-variables-sentences-1.md +++ b/week-2/jl-variables-sentences-1.md @@ -1,2 +1,73 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/variable-exercises/master/sentences-without-temps.md) into this file and complete the exercises! -> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) \ No newline at end of file +> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) +# Sentences without temp variables + +These exercises ask you to reassign variables so that at each step of execution the variables spell out the next word in a sentence. See how few reassignments you can use per step! + +You'll have to practice looking ahead of and behind the line you are writing to strategize how you will store and reuse data from earlier in your program. This is one of the fundamental challenges in development. + + +### example solutions: +1. the toad reads me: [pytut](https://goo.gl/pmpkJZ), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20the%20toad%20reads%20me%0Alet%20_1%20%3D%20%22%20%22%2C%20_2%20%3D%20%22%20%22%2C%20_3%20%3D%20%22%20%22%2C%20_4%20%3D%20%22%20%22%2C%20_5%20%3D%20%22%20%22%3B%0A%2F%2F%20the%0A_1%20%3D%20%22t%22%2C%20_2%20%3D%20%22h%22%2C%20_3%20%3D%20%22e%22%3B%0A%2F%2F%20toad%0A_2%20%3D%20%22o%22%2C%20_3%20%3D%20%22a%22%2C%20_4%20%3D%20%22d%22%3B%0A%2F%2F%20reads%0A_1%20%3D%20%22r%22%2C%20_2%20%3D%20%22e%22%2C%20_5%20%3D%20%22s%22%3B%0A%2F%2F%20me%0A_1%20%3D%20%22m%22%2C%20_3%20%3D%20%22%20%22%2C%20_4%20%3D%20%22%20%22%2C%20_5%20%3D%20%22%20%22%3B) +1. eating meat every meal: [pytut](https://goo.gl/bDVjKL), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20eating%20meat%20every%20meal%0Alet%20_1%20%3D%20'%20'%2C%20_2%20%3D%20'%20'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%2C%20_5%20%3D%20'%20'%2C%20_6%3D%20'%20'%3B%0A%2F%2F%20eating%0A_1%20%3D%20%22e%22%2C%20_2%20%3D%20%22a%22%2C%20_3%20%3D%20%22t%22%2C%20_4%20%3D%20%22i%22%2C%20_5%20%3D%20%22n%22%2C%20_6%3D%20%22g%22%3B%0A%2F%2F%20meat%0A_4%20%3D%20_3%2C%20_3%20%3D%20_2%2C%20_2%20%3D%20_1%2C%20_1%20%3D%20%22m%22%2C%20_5%20%3D%20%22%20%22%2C%20_6%20%3D%20%22%20%22%3B%0A%2F%2F%20every%0A_1%20%3D%20_2%2C%20_3%20%3D%20_2%2C%20_2%20%3D%20%22v%22%2C%20_4%20%3D%20%22r%22%2C%20_5%20%3D%20%22y%22%3B%0A%2F%2F%20meal%0A_1%20%3D%20%22m%22%2C%20_2%20%3D%20_3%2C%20_3%20%3D%20%22a%22%2C%20_4%20%3D%20%22l%22%2C%20_5%20%3D%20%22%20%22%3B) +1. many men may melt my mind: [pytut](https://goo.gl/Gh8mCu), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20many%20men%20may%20melt%20my%20mind%0A%0Alet%20_1%20%3D%20'%20'%2C%20_2%20%3D%20'%20'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%3B%0A%0A%2F%2F%20many%0A_1%20%3D%20'm'%2C%20_2%20%3D%20'a'%2C%20_3%20%3D%20'n'%2C%20_4%20%3D%20'y'%3B%0A%2F%2F%20men%0A_2%20%3D%20'e'%2C%20_4%20%3D%20'%20'%3B%0A%2F%2F%20may%0A_2%20%3D%20'a'%2C%20_3%20%3D%20'y'%3B%0A%2F%2F%20melt%0A_2%20%3D%20'e'%2C%20_3%20%3D%20'l'%2C%20_4%20%3D%20't'%3B%0A%2F%2F%20my%0A_2%20%3D%20'y'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%3B%0A%2F%2F%20mind%0A_2%20%3D%20'i'%2C%20_3%20%3D%20'n'%2C%20_4%20%3D%20'd'%3B) +1. if fir trees ever fall: [pytut](https://goo.gl/tdJQwW), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20if%20fir%20trees%20ever%20fall%0A%0Alet%20_1%20%3D%20'%20'%2C%20_2%20%3D%20'%20'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%2C%20_5%20%3D%20'%20'%3B%0A%0A%2F%2F%20if%0A_1%20%3D%20'i'%2C%20_2%20%3D%20'f'%3B%0A%2F%2F%20fir%0A_1%20%3D%20_2%2C%20_2%20%3D%20'i'%2C%20_3%20%3D%20'r'%3B%0A%2F%2F%20trees%0A_1%20%3D%20't'%2C%20_2%20%3D%20_3%2C%20_3%20%3D%20'e'%2C%20_4%20%3D%20_3%2C%20_5%20%3D%20's'%3B%0A%2F%2F%20ever%0A_1%20%3D%20_3%2C%20_2%20%3D%20'v'%2C%20_4%20%3D%20'r'%2C%20_5%20%3D%20'r'%3B%0A%2F%2F%20fall%0A_1%20%3D%20'f'%2C%20_2%20%3D%20'a'%2C%20_3%20%3D%20'l'%2C%20_4%20%3D%20_3%2C%20_5%20%3D%20'%20'%3B) + +### challenges: +1. [the toad reads me](https://goo.gl/imKwgj) +```js +// the +_1 = "t", _2 = "h", _3 = "e"; +// toad +_2 = "o", _3 = "a", _4 = "d"; +// reads +_1 = "r", _2 = "e", _5 = "s"; +// me +_1 = "m", _3 = " ", _4 = " ", _5 = " "; +``` +. [eating meat every meal](https://goo.gl/cwZijk) +```js +// eating + _1 = "e", _2 = "a", _3 = "t", _4 = "i", _5 = "n", _6= "g"; +// meat +_4 = _3, _3 = _2, _2 = _1, _1 = "m", _5 = " ", _6 = " "; +// every +_1 = _2, _3 = _2, _2 = "v", _4 = "r", _5 = "y"; +// meal +_1 = "m", _2 = _3, _3 = "a", _4 = "l", _5 = " "; +``` +. [many men may melt my mind](https://goo.gl/16C62t) +```js +// many +_1 = 'm', _2 = 'a', _3 = 'n', _4 = 'y'; +// men +_2 = 'e', _4 = ' '; +// may +_2 = 'a', _3 = 'y'; +// melt +_2 = 'e', _3 = 'l', _4 = 't'; +// my +_2 = 'y', _3 = ' ', _4 = ' '; +// mind +_2 = 'i', _3 = 'n', _4 = 'd'; +``` +1. [if fir trees ever fall](https://goo.gl/8y5Lh2) +```js +// if +_1 = 'i', _2 = 'f'; +// fir +_1 = _2, _2 = 'i', _3 = 'r'; +// trees +_1 = 't', _2 = _3, _3 = 'e', _4 = _3, _5 = 's'; +// ever +_1 = _3, _2 = 'v', _4 = 'r', _5 = 'r'; +// fall +_1 = 'f', _2 = 'a', _3 = 'l', _4 = _3, _5 = ' ' +``` + + + + +___ +___ +### Janke Learning diff --git a/week-2/jl-variables-sentences-2.md b/week-2/jl-variables-sentences-2.md index 65feb7d..3d69947 100644 --- a/week-2/jl-variables-sentences-2.md +++ b/week-2/jl-variables-sentences-2.md @@ -1,2 +1,29 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/variable-exercises/master/sentences-with-temps.md) into this file and complete the exercises! -> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) \ No newline at end of file +> references: [javascript.info variables](https://javascript.info/variables), [variables and hoisting](https://github.com/janke-learning/variables-and-hoisting) +# Sentences with Temp Variables + +These exercises ask you to reassign variables so that at each step of execution the variables spell out the next word in a sentence. + +You'll have to practice looking ahead of and behind the line you are writing to strategize how you will store and reuse data from earlier in your program. This is one of the fundamental challenges in development. + +They're just like the [sentences without temps](./3-sentences-without-temps.md) exercises, but with a couple extra variables like you saw in [swaps](./1-swaps.md). Pay attention to how your planning and solution changes when you can save values for later + +See how few reassignments you can use per step! + +### example solutions: +1. the toad reads me: [pytut](https://goo.gl/WrWMid), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20the%20toad%20reads%20me%0A%0Alet%20_1%20%3D%20%22%20%22%2C%20_2%20%3D%20%22%20%22%2C%20_3%20%3D%20%22%20%22%2C%20_4%20%3D%20%22%20%22%2C%20_5%20%3D%20%22%20%22%3B%0Alet%20x%20%3D%20'%20'%2C%20y%20%3D%20'%20'%3B%0A%0A%2F%2F%20the%0A_1%20%3D%20%22t%22%2C%20_2%20%3D%20%22h%22%2C%20_3%20%3D%20%22e%22%3B%0A%2F%2F%20toad%0Ax%20%3D%20_3%3B%0A_2%20%3D%20%22o%22%2C%20_3%20%3D%20%22a%22%2C%20_4%20%3D%20%22d%22%3B%0A%2F%2F%20reads%0A_1%20%3D%20%22r%22%2C%20_2%20%3D%20x%2C%20_5%20%3D%20%22s%22%3B%0A%2F%2F%20me%0A_1%20%3D%20%22m%22%2C%20_3%20%3D%20%22%20%22%2C%20_4%20%3D%20%22%20%22%2C%20_5%20%3D%20%22%20%22%3B) +1. eating meat every meal: [pytut](https://goo.gl/ioTN8v), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20eating%20meat%20every%20meal%0A%0Alet%20_1%20%3D%20'%20'%2C%20_2%20%3D%20'%20'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%2C%20_5%20%3D%20'%20'%2C%20_6%3D%20'%20'%3B%0Alet%20x%20%3D%20'%20'%2C%20y%20%3D%20'%20'%3B%0A%0A%2F%2F%20eating%0A_1%20%3D%20%22e%22%2C%20_2%20%3D%20%22a%22%2C%20_3%20%3D%20%22t%22%2C%20_4%20%3D%20%22i%22%2C%20_5%20%3D%20%22n%22%2C%20_6%3D%20%22g%22%3B%0A%2F%2F%20meat%0Ax%20%3D%20_2%3B%0A_4%20%3D%20_3%2C%20_3%20%3D%20_2%2C%20_2%20%3D%20_1%2C%20_1%20%3D%20%22m%22%2C%20_5%20%3D%20%22%20%22%2C%20_6%20%3D%20%22%20%22%3B%0A%2F%2F%20every%0Ay%20%3D%20_1%3B%0A_1%20%3D%20_2%2C%20_3%20%3D%20_2%2C%20_2%20%3D%20%22v%22%2C%20_4%20%3D%20%22r%22%2C%20_5%20%3D%20%22y%22%3B%0A%2F%2F%20meal%0A_1%20%3D%20y%2C%20_2%20%3D%20_3%2C%20_3%20%3D%20x%2C%20_4%20%3D%20%22l%22%2C%20_5%20%3D%20%22%20%22%3B) +1. many men may melt my mind: [pytut](https://goo.gl/Q8LtiR), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20many%20men%20may%20melt%20my%20mind%0A%0Alet%20_1%20%3D%20'%20'%2C%20_2%20%3D%20'%20'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%3B%0Alet%20x%20%3D%20'%20'%2C%20y%20%3D%20'%20'%3B%0A%0A%2F%2F%20many%0A_1%20%3D%20'm'%2C%20%20_2%20%3D%20'a'%2C%20_3%20%3D%20'n'%2C%20_4%20%3D%20'y'%3B%0A%2F%2F%20men%0Ax%20%3D%20_2%2C%20y%20%3D%20_4%3B%0A_2%20%3D%20'e'%2C%20_4%20%3D%20'%20'%3B%0A%2F%2F%20may%0A_3%20%3D%20y%2C%20y%20%3D%20_2%2C%20_2%20%3D%20x%3B%0A%2F%2F%20melt%0Ax%20%3D%20_3%3B%0A_2%20%3D%20y%2C%20_3%20%3D%20'l'%2C%20_4%20%3D%20't'%3B%0A%2F%2F%20my%0A_2%20%3D%20x%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%3B%0A%2F%2F%20mind%0A_2%20%3D%20'i'%2C%20_3%20%3D%20'n'%2C%20_4%20%3D%20'd'%3B) +1. if fir trees ever fall: [pytut](https://goo.gl/SpjB6t), [parsons](https://janke-learning.github.io/parsonizer/?snippet=%2F%2F%20if%20fir%20trees%20ever%20fall%0A%0Alet%20_1%20%3D%20'%20'%2C%20_2%20%3D%20'%20'%2C%20_3%20%3D%20'%20'%2C%20_4%20%3D%20'%20'%2C%20_5%20%3D%20'%20'%3B%0Alet%20x%20%3D%20'%20'%2C%20y%20%3D%20'%20'%3B%20%2F%2F%20to%20save%20extra%20values%20for%20later%0A%0A%2F%2F%20if%0A_1%20%3D%20'i'%2C%20_2%20%3D%20'f'%3B%0A%2F%2F%20fir%0Ax%20%3D%20_2%3B%0A_2%20%3D%20_1%2C%20_1%20%3D%20x%2C%20_3%20%3D%20'r'%3B%0A%2F%2F%20trees%0A_1%20%3D%20't'%2C%20_2%20%3D%20_3%2C%20_3%20%3D%20'e'%2C%20_4%20%3D%20_3%2C%20_5%20%3D%20's'%3B%0A%2F%2F%20ever%0Ay%20%3D%20_2%3B%0A_1%20%3D%20_3%2C%20_2%20%3D%20'v'%2C%20_4%20%3D%20y%2C%20_5%20%3D%20'%20'%3B%0A%2F%2F%20fall%0A_1%20%3D%20x%2C%20_2%20%3D%20'a'%2C%20_3%20%3D%20'l'%2C%20_4%20%3D%20_3%2C%20_5%20%3D%20'%20'%3B) + + +### challenges: +1. [the toad reads me](https://goo.gl/4eqhLb) +1. [eating meat every meal](https://goo.gl/F9Njwp) +1. [many men may melt my mind](http://www.pythontutor.com/javascript.html#code=//%20many%20men%20may%20melt%20my%20mind%0A%0A//%20we%20give%20you%20this%0Alet%20_1%20%3D%20'%20',%20_2%20%3D%20'%20',%20_3%20%3D%20'%20',%20_4%20%3D%20'%20'%3B%0Alet%20x,%20y%3B%0A//%20--%20you%20write%20this%20--%0A%0A//%20many%0A%0A//%20men%0A%0A//%20may%0A%0A//%20melt%0A%0A//%20my%0A%0A//%20mind&mode=edit&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +1. [if fir trees ever fall](https://goo.gl/BCC6pz) + + +___ +___ +### Janke Learning diff --git a/week-2/js-tracing-conditionals.md b/week-2/js-tracing-conditionals.md index ffac81e..509911e 100644 --- a/week-2/js-tracing-conditionals.md +++ b/week-2/js-tracing-conditionals.md @@ -1,2 +1,1135 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/colevandersWands/conditional-exercises/master/tracing-paths.md) into this file and complete the exercises! -> references: [js.info conditionals](https://javascript.info/ifelse), [js.info logical operators](https://javascript.info/logical-operators), [js.info comparisons](https://javascript.info/comparison) [jl truthiness](https://github.com/janke-learning/truthiness) \ No newline at end of file +> references: [js.info conditionals](https://javascript.info/ifelse), [js.info logical operators](https://javascript.info/logical-operators), [js.info comparisons](https://javascript.info/comparison) [jl truthiness](https://github.com/janke-learning/truthiness) +# Tracing Paths + +Tracing is when you can point to the lines of code that were executed in the order they were executed, tracking values as you go for understanding and debugging. These exercises ask you to refactor and log conditional statements for a dynamic trace of what happened as the code was executed. + +Learn this well, your debugging & problem solving future self will thank you! + +> PS. In these exercises and examples you will be dealing with some difficult expressions. Don't worry about understanding them perfectly, one of the goals for these exercises is to learn how to work with code you don't fully understand! Don't hesitate using some trial and error to find your tracing values. + +### Index +* tracings to study + * [if else](#if-else) + * [if else if else](#if-else-if-else) + * [nested if else](#nested-if-else) +* tracing exercises + * [one](#one) + * [two](#two) + * [three](#three) + * [four](#four) + * [five](#five) + * [six](#six) + * [seven](#seven) + * [eight](#eight) + +--- + +## if else + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20test%20out%20a%20bunch%20of%20values%0A%0Aconst%20expression%20%3D%20!x%20%26%26%20y%3B%0Alet%20truthiness%20%3D%20Boolean%28expression%29%3B%0A%0Alet%20path%3B%0A%0Aif%20%28%20truthiness%20%29%20%7B%0A%20%20path%20%3D%20%22if%22%3B%0A%7D%20else%20%7B%0A%20%20path%20%3D%20%22else%22%3B%0A%7D%0A%0Atruthiness%20%2B%3D%20%22y%22%3B&cumulative=false&curInstr=7&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // test out different values + + if (!x && y) { + // if body + } else { + // else body + } + +} +``` + +__refactored and traced__ +```js +{ + const x = , y = ; // test out a bunch of values + + const expression = !x && y; + const truthiness = Boolean(expression); + + let path; + + if ( truthiness ) { + path = "if"; + } else { + path = "else"; + } + + console.log("x: " + typeof x + ", " + x); + console.log("y: " + typeof y + ", " + y); + console.log("EXP: ", typeof expression+", "+expression+", "+truthiness+"y"); + console.log("PATH: ", path); +} +``` + + +__some tracings__ +```js +x: 1, y: 1, path: "else" +x: 0, y: 1, path: "if" +x: 1, y: 0, path: "else" +x: 0, y: 0, path: "else" +x: null, y: true, path: "if" +x: NaN, y: Infinity, path: "if" +x: undefined, y: "", path: "else" +``` + + + +[TOP](#conditional-exercises) + +--- + +## if else if else + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20test%20out%20a%20bunch%20of%20values%0A%0Aconst%20expression_1%20%3D%20x%20%7C%7C%20y%3B%0Alet%20truthiness_1%20%3D%20Boolean%28expression_1%29%3B%0A%0Aconst%20expression_2%20%3D%20x%20!%3D%20y%3B%0Alet%20truthiness_2%20%3D%20Boolean%28expression_2%29%3B%0A%0Alet%20path%3B%0A%0Aif%20%28%20truthiness_1%20%29%20%7B%0A%20%20path%20%3D%20%22first%20if%22%3B%0A%7D%20else%20if%20%28%20truthiness_2%20%29%20%7B%0A%20%20path%20%3D%20%22second%20if%22%3B%0A%7D%20else%20%7B%0A%20%20path%20%3D%20%22else%22%3B%0A%7D%0A%0Atruthiness_1%20%2B%3D%20%22y%22%3B%0Atruthiness_2%20%2B%3D%20%22y%22%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // test out different values + + if (x || y) { + // first if body + } else if (x != y) { + // second if body + } else { + // else body + } + +} +``` + +__refactored and traced__ +```js +{ + const x = , y = ; // test out a bunch of values + + const expression_1 = x || y; + const truthiness_1 = Boolean(expression_1); + + const expression_2 = x != y; + const truthiness_2 = Boolean(expression_2); + + let path; + + if ( truthiness_1 ) { + path = "first if"; + } else if ( truthiness_2 ) { + path = "second if"; + } else { + path = "else"; + } + + console.log("x: " + typeof x + ", " + x); + console.log("y: " + typeof y + ", " + y); + console.log("FIRST EXP: ", typeof expression_1+", "+expression_1+", "+truthiness_1+"y"); + console.log("SECOND EXP: ", typeof expression_2+", "+expression_2+", "+truthiness_2+"y"); + console.log("PATH: ", path); +} +``` + +__some tracings__ +```js +x: true, y: true, path: "first if" +x: true, y: false, path: "first if" +x: false, y: true, path: "first if" +x: false, y: false, path: "else" +x: null, y: undefined, path: "else" +x: NaN, y: undefined, path: "second if" +x: NaN, y: null, path: "second if" +``` + + +[TOP](#conditional-exercises) + +--- + + +## nested if else + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20test%20out%20a%20bunch%20of%20values%0A%0Aconst%20expression_1%20%3D%20!x%20%26%26%20y%3B%0Alet%20truthiness_1%20%3D%20Boolean%28expression_1%29%3B%0A%0Aconst%20expression_2%20%3D%20!!y%20%7C%7C%20%2Bx%3B%0Alet%20truthiness_2%20%3D%20Boolean%28expression_2%29%3B%0A%0Aconst%20third_expression%20%3D%20x%20-%20y%20%7C%7C%20y%20-%20x%3B%0Alet%20truthiness_3%20%3D%20Boolean%28third_expression%29%3B%0A%0Alet%20path%3B%0A%0Aif%20%28%20truthiness_1%20%29%20%7B%0A%20%20if%20%28%20truthiness_2%20%29%20%7B%0A%20%20%20%20path%20%3D%20%22if%20if%22%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20path%20%3D%20%22if%20else%22%3B%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28%20truthiness_3%20%29%20%7B%0A%20%20%20%20path%20%3D%20%22else%20if%22%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20path%20%3D%20%22else%20else%22%3B%0A%20%20%7D%0A%7D%0A%0Atruthiness_1%20%2B%3D%20%22y%22%3B%0Atruthiness_2%20%2B%3D%20%22y%22%3B%0Atruthiness_3%20%2B%3D%20%22y%22%3B&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // test out different values + + if (!x && y) { + if (!!y || +x) { + // if if body + } else { + // if else body + } + } else { + if (x - y || y - x) { + // else if body + } else { + // else else body + } + } + +} +``` + +__refactored and traced__ +```js +{ + const x = , y = ; // test out a bunch of values + + const expression_1 = !x && y; + const truthiness_1 = Boolean(expression_1); + + const expression_2 = !!y || +x; + const truthiness_2 = Boolean(expression_2); + + const expression_3 = x - y || y - x; + const truthiness_3 = Boolean(expression_3); + + let path; + + if ( truthiness_1 ) { + if ( truthiness_2 ) { + path = "if if"; + } else { + path = "if else"; + } + } else { + if ( truthiness_3 ) { + path = "else if"; + } else { + path = "else else"; + } + } + + console.log("x: " + typeof x + ", " + x); + console.log("y: " + typeof y + ", " + y); + console.log("FIRST EXP: ", typeof expression_1+", "+expression_1+", "+truthiness_1+"y"); + console.log("SECOND EXP: ", typeof expression_2+", "+expression_2+", "+truthiness_2+"y"); + console.log("THIRD EXP: ", typeof expression_3+", "+expression_3+", "+truthiness_3+"y"); + console.log("PATH: ", path); +} +``` + + +__some tracings__ +```js +x: null, y: null, path: "else else" +x: false, y: null, path: "else else" +x: false, y: true, path: "if if" +x: NaN, y: 1, path: "if if" +x: Infinity, y: "", path: "else if" +x: 1, y: "", path: "else if" +// I think "if else" is unreachable! +``` + + + +[TOP](#conditional-exercises) + +--- +--- + +## One + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%3D%3D%3D%20%2Bx%20%7C%7C%20x%20%3D%3D%3D%20!x%29%20%7B%0A%0A%7D%20else%20%7B%0A%0A%7D&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = ; // try a bunch of values! + + if (x === +x || x === !x) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Two + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%3D%3D%3D%20%2Bx%29%20%7B%0A%0A%7D%20else%20if%20%28x%20%3D%3D%3D%20!x%29%20%7B%0A%0A%7D%20else%20%7B%0A%0A%7D&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = ; // try a bunch of values! + + if (x === +x) { + + } else if (x === !x) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Three + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%3D%3D%20%2Bx%29%20%7B%0A%0A%7D%20%0Aif%20%28x%20%3D%3D%20!!x%29%20%7B%0A%0A%7D%20else%20%7B%0A%0A%7D%0A&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x == +x) { + + } + if (x == !!x) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Four + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%29%20%7B%0A%20%20if%20%28y%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28y%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%0A&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x) { + if (y) { + + } else { + + } + } else { + if (y) { + + } else { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Five + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28%20!x%20%7C%7C%20!y%20%29%20%7B%0A%0A%7D%20else%20if%20%28%20!%28x%20%26%26%20y%29%20%29%20%7B%0A%0A%7D%20else%20%7B%20%0A%0A%7D&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if ( !x || !y ) { + + } else if ( !(x && y) ) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + +> [De Morgan's Law](https://www.youtube.com/watch?v=tKnS3s8fOu4) + + + +[TOP](#tracing-paths) + +--- + +## Six + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%29%20%7B%0A%20%20if%20%28y%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28x%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20%20&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x) { + if (y) { + + } else { + + } + } else { + if (x) { + + } else { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + // can you remove on conditional statement without changing the bahavior? +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Seven + + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%7C%7C%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%0A%20%20%7D%0A%7D%20else%20if%20%28x%20%26%26%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x || y) { + if (x !== y) { + + } + } else if (x && y) { + if (x !== y) { + + } + } else { + if (x !== y) { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + + +## Eight + + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%7C%7C%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%0A%20%20%7D%0A%7D%20else%20if%20%28x%20%26%26%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x !== y) { + if (x || y) { + + } else if (x && y) { + + } else { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + + +___ +___ +### Janke Learning +heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // test out different values + + if (!x && y) { + // if body + } else { + // else body + } + +} +``` + +__refactored and traced__ +```js +{ + const x = , y = ; // test out a bunch of values + + const expression = !x && y; + const truthiness = Boolean(expression); + + let path; + + if ( truthiness ) { + path = "if"; + } else { + path = "else"; + } + + console.log("x: " + typeof x + ", " + x); + console.log("y: " + typeof y + ", " + y); + console.log("EXP: ", typeof expression+", "+expression+", "+truthiness+"y"); + console.log("PATH: ", path); +} +``` + + +__some tracings__ +```js +x: 1, y: 1, path: "else" +x: 0, y: 1, path: "if" +x: 1, y: 0, path: "else" +x: 0, y: 0, path: "else" +x: null, y: true, path: "if" +x: NaN, y: Infinity, path: "if" +x: undefined, y: "", path: "else" +``` + + + +[TOP](#conditional-exercises) + +--- + +## if else if else + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20test%20out%20a%20bunch%20of%20values%0A%0Aconst%20expression_1%20%3D%20x%20%7C%7C%20y%3B%0Alet%20truthiness_1%20%3D%20Boolean%28expression_1%29%3B%0A%0Aconst%20expression_2%20%3D%20x%20!%3D%20y%3B%0Alet%20truthiness_2%20%3D%20Boolean%28expression_2%29%3B%0A%0Alet%20path%3B%0A%0Aif%20%28%20truthiness_1%20%29%20%7B%0A%20%20path%20%3D%20%22first%20if%22%3B%0A%7D%20else%20if%20%28%20truthiness_2%20%29%20%7B%0A%20%20path%20%3D%20%22second%20if%22%3B%0A%7D%20else%20%7B%0A%20%20path%20%3D%20%22else%22%3B%0A%7D%0A%0Atruthiness_1%20%2B%3D%20%22y%22%3B%0Atruthiness_2%20%2B%3D%20%22y%22%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // test out different values + + if (x || y) { + // first if body + } else if (x != y) { + // second if body + } else { + // else body + } + +} +``` + +__refactored and traced__ +```js +{ + const x = , y = ; // test out a bunch of values + + const expression_1 = x || y; + const truthiness_1 = Boolean(expression_1); + + const expression_2 = x != y; + const truthiness_2 = Boolean(expression_2); + + let path; + + if ( truthiness_1 ) { + path = "first if"; + } else if ( truthiness_2 ) { + path = "second if"; + } else { + path = "else"; + } + + console.log("x: " + typeof x + ", " + x); + console.log("y: " + typeof y + ", " + y); + console.log("FIRST EXP: ", typeof expression_1+", "+expression_1+", "+truthiness_1+"y"); + console.log("SECOND EXP: ", typeof expression_2+", "+expression_2+", "+truthiness_2+"y"); + console.log("PATH: ", path); +} +``` + +__some tracings__ +```js +x: true, y: true, path: "first if" +x: true, y: false, path: "first if" +x: false, y: true, path: "first if" +x: false, y: false, path: "else" +x: null, y: undefined, path: "else" +x: NaN, y: undefined, path: "second if" +x: NaN, y: null, path: "second if" +``` + + +[TOP](#conditional-exercises) + +--- + + +## nested if else + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20test%20out%20a%20bunch%20of%20values%0A%0Aconst%20expression_1%20%3D%20!x%20%26%26%20y%3B%0Alet%20truthiness_1%20%3D%20Boolean%28expression_1%29%3B%0A%0Aconst%20expression_2%20%3D%20!!y%20%7C%7C%20%2Bx%3B%0Alet%20truthiness_2%20%3D%20Boolean%28expression_2%29%3B%0A%0Aconst%20third_expression%20%3D%20x%20-%20y%20%7C%7C%20y%20-%20x%3B%0Alet%20truthiness_3%20%3D%20Boolean%28third_expression%29%3B%0A%0Alet%20path%3B%0A%0Aif%20%28%20truthiness_1%20%29%20%7B%0A%20%20if%20%28%20truthiness_2%20%29%20%7B%0A%20%20%20%20path%20%3D%20%22if%20if%22%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20path%20%3D%20%22if%20else%22%3B%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28%20truthiness_3%20%29%20%7B%0A%20%20%20%20path%20%3D%20%22else%20if%22%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20path%20%3D%20%22else%20else%22%3B%0A%20%20%7D%0A%7D%0A%0Atruthiness_1%20%2B%3D%20%22y%22%3B%0Atruthiness_2%20%2B%3D%20%22y%22%3B%0Atruthiness_3%20%2B%3D%20%22y%22%3B&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // test out different values + + if (!x && y) { + if (!!y || +x) { + // if if body + } else { + // if else body + } + } else { + if (x - y || y - x) { + // else if body + } else { + // else else body + } + } + +} +``` + +__refactored and traced__ +```js +{ + const x = , y = ; // test out a bunch of values + + const expression_1 = !x && y; + const truthiness_1 = Boolean(expression_1); + + const expression_2 = !!y || +x; + const truthiness_2 = Boolean(expression_2); + + const expression_3 = x - y || y - x; + const truthiness_3 = Boolean(expression_3); + + let path; + + if ( truthiness_1 ) { + if ( truthiness_2 ) { + path = "if if"; + } else { + path = "if else"; + } + } else { + if ( truthiness_3 ) { + path = "else if"; + } else { + path = "else else"; + } + } + + console.log("x: " + typeof x + ", " + x); + console.log("y: " + typeof y + ", " + y); + console.log("FIRST EXP: ", typeof expression_1+", "+expression_1+", "+truthiness_1+"y"); + console.log("SECOND EXP: ", typeof expression_2+", "+expression_2+", "+truthiness_2+"y"); + console.log("THIRD EXP: ", typeof expression_3+", "+expression_3+", "+truthiness_3+"y"); + console.log("PATH: ", path); +} +``` + + +__some tracings__ +```js +x: null, y: null, path: "else else" +x: false, y: null, path: "else else" +x: false, y: true, path: "if if" +x: NaN, y: 1, path: "if if" +x: Infinity, y: "", path: "else if" +x: 1, y: "", path: "else if" +// I think "if else" is unreachable! +``` + + + +[TOP](#conditional-exercises) + +--- +--- + +## One + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%3D%3D%3D%20%2Bx%20%7C%7C%20x%20%3D%3D%3D%20!x%29%20%7B%0A%0A%7D%20else%20%7B%0A%0A%7D&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = ; // try a bunch of values! + + if (x === +x || x === !x) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Two + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%3D%3D%3D%20%2Bx%29%20%7B%0A%0A%7D%20else%20if%20%28x%20%3D%3D%3D%20!x%29%20%7B%0A%0A%7D%20else%20%7B%0A%0A%7D&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = ; // try a bunch of values! + + if (x === +x) { + + } else if (x === !x) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Three + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%3D%3D%20%2Bx%29%20%7B%0A%0A%7D%20%0Aif%20%28x%20%3D%3D%20!!x%29%20%7B%0A%0A%7D%20else%20%7B%0A%0A%7D%0A&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x == +x) { + + } + if (x == !!x) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Four + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%29%20%7B%0A%20%20if%20%28y%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28y%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%0A&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x) { + if (y) { + + } else { + + } + } else { + if (y) { + + } else { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Five + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28%20!x%20%7C%7C%20!y%20%29%20%7B%0A%0A%7D%20else%20if%20%28%20!%28x%20%26%26%20y%29%20%29%20%7B%0A%0A%7D%20else%20%7B%20%0A%0A%7D&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if ( !x || !y ) { + + } else if ( !(x && y) ) { + + } else { + + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + +> [De Morgan's Law](https://www.youtube.com/watch?v=tKnS3s8fOu4) + + + +[TOP](#tracing-paths) + +--- + +## Six + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%29%20%7B%0A%20%20if%20%28y%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28x%29%20%7B%0A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20%20&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x) { + if (y) { + + } else { + + } + } else { + if (x) { + + } else { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + // can you remove on conditional statement without changing the bahavior? +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + +## Seven + + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%7C%7C%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%0A%20%20%7D%0A%7D%20else%20if%20%28x%20%26%26%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x || y) { + if (x !== y) { + + } + } else if (x && y) { + if (x !== y) { + + } + } else { + if (x !== y) { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + +--- + + +## Eight + + + +[on pytut](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20,%20y%20%3D%20%3B%20//%20try%20a%20bunch%20of%20values!%0A%0Aif%20%28x%20%7C%7C%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%0A%20%20%7D%0A%7D%20else%20if%20%28x%20%26%26%20y%29%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D%20else%20%7B%0A%20%20if%20%28x%20!%3D%3D%20y%29%20%7B%0A%20%20%20%20%0A%20%20%7D%0A%7D&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +__original code__ +```js +{ + const x = , y = ; // try a bunch of values! + + if (x !== y) { + if (x || y) { + + } else if (x && y) { + + } else { + + } + } + +} +``` + +__refactored and traced__ +```js +{ + +} +``` + +__some tracings__ +```js +// find 6+ tracing values +// try to find at least 1 set for each path +// or can you? some paths are unreachable! +``` + + +[TOP](#tracing-paths) + + +___ +___ +### Janke Learning diff --git a/week-3/README.md b/week-3/README.md index dd8c6c1..4f408d1 100644 --- a/week-3/README.md +++ b/week-3/README.md @@ -2,16 +2,16 @@ | | your Emoji | your comments | coach emoji | coach comments | | --- | --- | --- | --- | --- | -| :dash: __[janke: truthiness](./jl-truthiness.md) | | | | | -| :seedling: __[javascript.info: logical operators](./jsinfo-logical-operators.md) | | | | | -| :seedling: __[javascript.info: conditionals](./jsinfo-conditionals.md) | | | | | -| :seedling: __[janke: test cases](./jl-test-cases.md) | | | | | -| :fire: __[janke: replicate ```==```](./jl-replicate-loose-equality.md) | | | | | -| :dash: __[janke: operator precedence](./jl-operator-precedence.md) | | | | | -| :fire: __[janke: expanding expressions](./jl-expanding-expressions.md) | | | | | -| :dash: __[FCC: basic algorithms](./fcc-algorithms-1.md) | | | | | -| :dash: __[janke: functions as arguments](./jl-functions-as-arguments.md) | | | | | -| :fire: __[janke: callstack](./jl-callstack.md) | | | | | +| :dash: __[janke: truthiness](./jl-truthiness.md) |:+1: | | | | +| :seedling: __[javascript.info: logical operators](./jsinfo-logical-operators.md) |:+1: | | | | +| :seedling: __[javascript.info: conditionals](./jsinfo-conditionals.md) |:+1: | | | | +| :seedling: __[janke: test cases](./jl-test-cases.md) |:+1:| | | | +| :fire: __[janke: replicate ```==```](./jl-replicate-loose-equality.md) |:+1: | | | | +| :dash: __[janke: operator precedence](./jl-operator-precedence.md) |:+1: | | | | +| :fire: __[janke: expanding expressions](./jl-expanding-expressions.md) |:+1: | | | | +| :dash: __[FCC: basic algorithms](./fcc-algorithms-1.md) |:+1: | | | | +| :dash: __[janke: functions as arguments](./jl-functions-as-arguments.md) |:+1: | | | | +| :fire: __[janke: callstack](./jl-callstack.md) |:+1: | | | | diff --git a/week-3/jl-callstack.md b/week-3/jl-callstack.md index 2ea8e78..abf398c 100644 --- a/week-3/jl-callstack.md +++ b/week-3/jl-callstack.md @@ -1 +1,322 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/function-exercises/master/callstack.md) into this file and complete the exercises! +# Sentences + +defining and calling functions from _within_ functions! no. way. + +yups. You can! that's how the __callstack__ is made, you stack up function calls. + +It sounds complicated at first, but after some practice you'll find it's not so bad. calling a function from inside another function (inside a new _lexical scope_) is no different than calling one from the global scope. + +### Index +* completed examples + * [tailor](#tailor) + * [space capes](#space-capes) +* warm-ups + * [tour 1](#tour-1) + * [tour 2](#tour-2) +* exercises + * [eat ate tea 1](#1) + * [eat ate tea 2](#2) + * [space capes 1](#3) + * [space capes 2](#4) + * [cruel ulcer 1](#5) + * [cruel ulcer 2](#6) + * [cruel ulcer 3](#7) + +--- + +## Completed Examples + +### Tailor + +[on pytut](http://www.pythontutor.com/javascript.html#code=function%20a_word%28_1,%20_2,%20_3,%20_4,%20_5,%20_6%29%20%7B%20%0A%20%20%0A%20%20function%20tailor%28_a,%20_b,%20_c,%20_d,%20_e,%20_f%29%20%7B%0A%20%20%20%20return%20_a%20%2B%20_c%20%2B%20_b%20%2B%20_d%20%2B%20_f%20%2B%20_e%3B%0A%20%20%7D%0A%20%20var%20word%20%3D%20tailor%28_2,%20_6,%20_1,%20_5,%20_4,%20_3%29%3B%0A%0A%20%20var%20result%20%3D%20word%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20a_word%28%22a%22,%20%22t%22,%20%22o%22,%20%22r%22,%20%22l%22,%20%22i%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'tailor',%20%22example%201%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&curInstr=0&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ // completed example 1 + function a_word(_1, _2, _3, _4, _5, _6) { + + function tailor(_a, _b, _c, _d, _e, _f) { + return _a + _c + _b + _d + _f + _e; + } + var word = tailor(_2, _6, _1, _5, _4, _3); + + var result = word; + return result; + } + const return_val = a_word("a", "t", "o", "r", "l", "i"); + console.assert(return_val === 'tailor', "example 1: return_val === " + return_val); +}; +``` + +### Space Capes + +[on pytut](http://www.pythontutor.com/javascript.html#code=function%20sentence%28_1,%20_2,%20_3,%20_4,%20_5%29%20%7B%20%0A%20%20%0A%20%20function%20space%28_a,%20_b,%20_c,%20_d,%20_e%29%20%7B%0A%20%20%20%20return%20_a%20%2B%20_b%20%2B%20_c%20%2B%20_d%20%2B%20_e%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20space%28_5,%20_4,%20_2,%20_3,%20_1%29%3B%0A%0A%20%20function%20capes%28_a,%20_b,%20_c,%20_d,%20_e%29%20%7B%0A%20%20%20%20return%20_a%20%2B%20_b%20%2B%20_c%20%2B%20_d%20%2B%20_e%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20capes%28_3,%20_2,%20_4,%20_1,%20_5%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28%22e%22,%20%22a%22,%20%22c%22,%20%22p%22,%20%22s%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'space%20capes',%20%22example%202%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&curInstr=0&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ // completed example 2 + function sentence(_1, _2, _3, _4, _5) { + + function space(_a, _b, _c, _d, _e) { + return _a + _b + _c + _d + _e; + } + var word_1 = space(_5, _4, _2, _3, _1); + + function capes(_a, _b, _c, _d, _e) { + return _a + _b + _c + _d + _e; + } + var word_2 = capes(_3, _2, _4, _1, _5); + + var result = word_1 + " " + word_2; + return result; + } + const return_val = sentence("e", "a", "c", "p", "s"); + console.assert(return_val === 'space capes', "example 2: return_val === " + return_val); +}; +``` + +[TOP](#sentences) + +--- + +## Warm Ups + +### Tour 1 + +[on pytut](http://www.pythontutor.com/javascript.html#code=function%20a_word%28_1,%20_2,%20_3,%20_4%29%20%7B%20%0A%20%20%0A%20%20function%20tour%28_a,%20_b,%20_c,%20_d%29%20%7B%0A%20%20%20%20return%20_b%20%2B%20_a%20%2B%20_c%20%2B%20_d%3B%0A%20%20%7D%0A%20%20var%20word%20%3D%20tour%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20a_word%28%22o%22,%20%22t%22,%20%22u%22,%20%22r%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'tour',%20%22wu-1%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&curInstr=0&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D) +```js +{ // warmup 1 + function a_word(_1, _2, _3, _4) { + + function tour(_a, _b, _c, _d) { + return _b + _a + _c + _d; + } + var word = tour(/* fill this in */); + + var result = word; + return result; + } + const return_val = a_word("o", "t", "u", "r"); + console.assert(return_val === 'tour', "wu-1: return_val === " + return_val); +}; +``` + +### Tour 2 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20a_word%28_1,%20_2,%20_3,%20_4%29%20%7B%20%0A%20%20%0A%20%20function%20tour%28_a,%20_b,%20_c,%20_d%29%20%7B%0A%20%20%20%20return%20_c%20%2B%20_a%20%2B%20_d%20%2B%20_b%3B%0A%20%20%7D%0A%20%20var%20word%20%3D%20tour%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20a_word%28%22u%22,%20/*%20fill%20this%20in%20*/%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'tour',%20%22wu-2%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // warmup 2 + function a_word(_1, _2, _3, _4) { + + function tour(_a, _b, _c, _d) { + return _c + _a + _d + _b; + } + var word = tour(/* fill this in */); + + var result = word; + return result; + } + const return_val = a_word("u", /* fill this in */); + console.assert(return_val === 'tour', "wu-2: return_val === " + return_val); +}; +``` + +[TOP](#sentences) + +--- + +## Exercises + +### 1 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3%29%20%7B%20%0A%20%20%0A%20%20function%20eat%28_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20eat%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20function%20ate%28_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20ate%28_1,%20_2,%20_3%29%3B%0A%0A%20%20function%20tea%28_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_x%20%2B%20_y%20%2B%20_3%3B%0A%20%20%7D%0A%20%20var%20word_3%20%3D%20tea%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%20%2B%20%22%20%22%20%2B%20word_3%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28%22a%22,%20%22e%22,%20%22t%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'eat%20ate%20tea',%20%221%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=14&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 1 -> eat ate tea. + function sentence(_1, _2, _3) { + + function eat(_x, _y, _z) { + return _x + _y + _z; + } + var word_1 = eat(_2, _1, _3); + + function ate(_x, _y, _z) { + return _x + _y + _z; + } + var word_2 = ate(_1, _3, _2); + + function tea(_x, _y, _z) { + return _x + _y + _3; + } + var word_3 = tea(_3, _2, _3=1); + + var result = word_1 + " " + word_2 + " " + word_3; + return result; + } + const return_val = sentence("a", "e", "t"); + console.assert(return_val === 'eat ate tea', "1: return_val === " + return_val); +}; +``` + +### 2 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3%29%20%7B%20%0A%20%20%0A%20%20function%20eat%28_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_z%20%2B%20_y%20%2B%20_x%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20eat%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20function%20ate%28_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_y%20%2B%20_x%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20ate%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20function%20tea%28_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_x%20%2B%20_z%20%2B%20_y%3B%0A%20%20%7D%0A%20%20var%20word_3%20%3D%20tea%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%20%2B%20%22%20%22%20%2B%20word_3%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28%22a%22,%20%22e%22,%20%22t%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'eat%20ate%20tea',%20%222%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=14&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 2 -> eat ate tea. 2 + function sentence(_1, _2, _3) { + + function eat(_x, _y, _z) { + return _z + _y + _x; + } + var word_1 = eat(/* fill this in */); + + function ate(_x, _y, _z) { + return _y + _x + _z; + } + var word_2 = ate(/* fill this in */); + + function tea(_x, _y, _z) { + return _x + _z + _y; + } + var word_3 = tea(/* fill this in */); + + var result = word_1 + " " + word_2 + " " + word_3; + return result; + } + const return_val = sentence("a", "e", "t"); + console.assert(return_val === 'eat ate tea', "2: return_val === " + return_val); +}; +``` + +### 3 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3,%20_4,%20_5%29%20%7B%20%0A%0A%20%20function%20space%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20space%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20function%20capes%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20capes%28_4,%20_3,%20_2,%20_5,%20_1%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28/*%20fill%20this%20in%20*/%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'space%20capes',%20%223%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 3 -> space capes + function sentence(_1, _2, _3, _4, _5) { + + function space(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_1 = space(/* fill this in */); + + function capes(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_2 = capes(_4, _3, _2, _5, _1); + + var result = word_1 + " " + word_2; + return result; + } + const return_val = sentence(/* fill this in */); + console.assert(return_val === 'space capes', "3: return_val === " + return_val); +}; +``` + +### 4 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3,%20_4,%20_5%29%20%7B%20%0A%0A%20%20function%20space%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20space%28_3,%20_4,%20_1,%20_5,%20_2%29%3B%0A%0A%20%20function%20capes%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20capes%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28/*%20fill%20this%20in%20*/%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'space%20capes',%20%224%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 4 -> space capes + function sentence(_1, _2, _3, _4, _5) { + + function space(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_1 = space(_3, _4, _1, _5, _2); + + function capes(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_2 = capes(/* fill this in */); + + var result = word_1 + " " + word_2; + return result; + } + const return_val = sentence(/* fill this in */); + console.assert(return_val === 'space capes', "4: return_val === " + return_val); +}; +``` + +### 5 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3,%20_4,%20_5%29%20%7B%20%0A%0A%20%20function%20cruel%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20cruel%28_3,%20_1,%20_4,%20_5,%20_2%29%3B%0A%0A%20%20function%20ulcer%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20ulcer%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28/*%20fill%20this%20in%20*/%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'cruel%20ulcer',%20%225%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 5 -> cruel ulcer + function sentence(_1, _2, _3, _4, _5) { + + function cruel(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_1 = cruel(_3, _1, _4, _5, _2); + + function ulcer(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_2 = ulcer(/* fill this in */); + + var result = word_1 + " " + word_2; + return result; + } + const return_val = sentence(/* fill this in */); + console.assert(return_val === 'cruel ulcer', "5: return_val === " + return_val); +}; +``` + +### 6 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3,%20_4,%20_5%29%20%7B%20%0A%0A%20%20function%20cruel%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20cruel%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20function%20ulcer%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_v%20%2B%20_w%20%2B%20_x%20%2B%20_y%20%2B%20_z%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20ulcer%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28%22e%22,%20%22l%22,%20%22u%22,%20%22c%22,%20%22r%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'cruel%20ulcer',%20%226%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 6 -> cruel ulcer + function sentence(_1, _2, _3, _4, _5) { + + function cruel(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_1 = cruel(/* fill this in */); + + function ulcer(_v, _w, _x, _y, _z) { + return _v + _w + _x + _y + _z; + } + var word_2 = ulcer(/* fill this in */); + + var result = word_1 + " " + word_2; + return result; + } + const return_val = sentence("e", "l", "u", "c", "r"); + console.assert(return_val === 'cruel ulcer', "6: return_val === " + return_val); +}; +``` + +### 7 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28_1,%20_2,%20_3,%20_4,%20_5%29%20%7B%20%0A%0A%20%20function%20cruel%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_x%20%2B%20_z%20%2B%20_w%20%2B%20_v%20%2B%20_y%3B%0A%20%20%7D%0A%20%20var%20word_1%20%3D%20cruel%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20function%20ulcer%28_v,%20_w,%20_x,%20_y,%20_z%29%20%7B%0A%20%20%20%20return%20_z%20%2B%20_w%20%2B%20_y%20%2B%20_x%20%2B%20_v%3B%0A%20%20%7D%0A%20%20var%20word_2%20%3D%20ulcer%28/*%20fill%20this%20in%20*/%29%3B%0A%0A%20%20var%20result%20%3D%20word_1%20%2B%20%22%20%22%20%2B%20word_2%3B%0A%20%20return%20result%3B%0A%7D%0Aconst%20return_val%20%3D%20sentence%28%22e%22,%20%22l%22,%20%22u%22,%20%22c%22,%20%22r%22%29%3B%0Aconsole.assert%28return_val%20%3D%3D%3D%20'cruel%20ulcer',%20%227%3A%20return_val%20%3D%3D%3D%20%22%20%2B%20return_val%29%3B&cumulative=false&curInstr=11&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ // 7 -> cruel ulcer + function sentence(_1, _2, _3, _4, _5) { + + function cruel(_v, _w, _x, _y, _z) { + return _x + _z + _w + _v + _y; + } + var word_1 = cruel(/* fill this in */); + + function ulcer(_v, _w, _x, _y, _z) { + return _z + _w + _y + _x + _v; + } + var word_2 = ulcer(/* fill this in */); + + var result = word_1 + " " + word_2; + return result; + } + const return_val = sentence("e", "l", "u", "c", "r"); + console.assert(return_val === 'cruel ulcer', "7: return_val === " + return_val); +}; +``` + + + + + + + +[TOP](#sentences) + +___ +___ +### Janke Learning diff --git a/week-3/jl-expanding-expressions.md b/week-3/jl-expanding-expressions.md index 5cf539c..7e5d31f 100644 --- a/week-3/jl-expanding-expressions.md +++ b/week-3/jl-expanding-expressions.md @@ -1 +1,578 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/expanding/master/exercises-operators-only.md) into this file and complete the exercises! +# Operator-Only Exercises + +Some single-line expressions to expand with only operators. + +Be sure to practice _incremental refactoring_ by running your tests every time you expand an operator, like you see in [these worked examples](./worked-expressions.md). + +You'll be presented with a single line expression. your task is to write enough test cases to begin understanding it, refactor it into steps according to operator precedence, then study your test cases in more detail. + +The main objective for these exercises is that you become comfortable stepping through and working with complex JS expressions, not that your learn everything about how all operators work. Understanding implicit coercion is very important but will be covered in depth later on. + + +### Index +* [learning objectives](#learning-objectives) +* Testing Tools + * [test case format](#test-case-format) + * [run\_tests function](#run-tests-function) +* completed examples + * [one](#one) + * [two](#two) + * [three](#three) + * [four](#four) + * [five](#five) +* exercises + * [types & casting (3)](#types-and-casting) + * [logical operators (3)](#logical-operators) + * [arithmetic operators (3)](#arithmetic-operators) + * [all primitive operators (3)](#all-primitive-operators) +* [resources](#resources) + +--- + +## learning objectives + + +* which operators exist in JS +* reading this [operator precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) +* breaking down long expressions (super helpful for debugging, reading & writing code) +* statements vs. expressions + +[TOP](#operator-only-exercises) + +--- + +## Testing Tools + +### Test Case Format + +```js +const test_cases = [ + {name:'meaningful name', args:['the inputs', 'for this snippet'], expected: 'what it should output'}, + {name:'another test case', args:['different', 'inputs'], expected: 'the expected output'}, + ... + ]; +``` + +### Run Tests Function + +__paste this into your console before moving on__ +```js +function run_tests(_target, _cases) { + console.groupCollapsed('<- click this arrow to see the function') + console.log(_target.toString()); + console.groupEnd(); + + for (let t_case of _cases) { + + // create variables for readability + const expected = t_case.expected; + const args = t_case.args; + + // run function with test case + const actual = _target(...args); + + // compare + let pass; + if (typeof expected === 'object' && expected !== null) { + const _actual = JSON.stringify(actual); + const _expected = JSON.stringify(expected); + pass = _actual === _expected; + } else if ( expected !== expected ) { + pass = actual !== actual; + } else { + pass = actual === expected; + }; + + // communicate result to developer + if (pass) { + console.groupCollapsed(`%cPASS: ${t_case.name}`, 'color:green'); + } else { + console.groupCollapsed(`%c: ${t_case.name}`, 'color:red'); + console.log("%cactual: ", 'color:orange', typeof actual +", "+ actual); + }; + + for (let i = 0; i < args.length; i++) { + console.log(`arg ${i+1}: ${typeof args[i]},`, args[i]); + } + console.log("%cexpected: ", 'color:blue', typeof expected +", "+ expected); + console.groupEnd(); + }; +} +``` + +[TOP](#operator-only-exercises) + +--- + +## Completed Examples + +### One + +uncomment the refactors one at a time to see that they all pass the same tests. + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=Number%28Boolean%28String%28a%29%29%29%0AString%28_%29%0ABoolean%28_%29%0ANumber%28_%29) +```js +test_cases = [ + {name: 'false', args: [false], expected: 1}, + {name: 'NaN', args: [NaN], expected: 1}, + {name: '""', args: [""], expected: 0}, + {name: 'null', args: [null], expected: 1}, + {name: 'undefined', args: [undefined], expected: 1}, + {name: '0', args: [0], expected: 1}, +]; +/* // original challenge +function expression(a) { + return Number(Boolean(String(a))); +} */ +/* // first refactor +function expression(a) { + const op_1 = String(a); + return Number(Boolean(op_1)); +} */ +/* // second refactor +function expression(a) { + const op_1 = String(a); + const op_2 = Boolean(op_1); + return Number(op_2); +} */ + +// fully expanded +function expression(a) { + const op_1 = String(a); + const op_2 = Boolean(op_1); + const op_3 = Number(op_2); + return op_3; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +--- + +### Two + +uncomment the refactors one at a time to see that they all pass the same tests. + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=%28a%20%2B%20b%29%20%3D%3D%20%28a%20%3C%20c%29%0A_%20%2B%20_%0A_%20%3C%20_%0A_%20%3D%3D%20_%0A%0A%0A%0A) +```js +test_cases = [ + {name: 'false, true, false', args: [false, true, false], expected: false}, + {name: '0, 1, 0', args: [0, 1, 0], expected: false}, + {name: '"", " ", ""', args: ["", " ", ""], expected: true}, + {name: '2, -1, 3', args: [2, -1, 3], expected: true}, + {name: 'null, undefined, NaN', args: [null, undefined, NaN], expected: false}, +]; +/* // original challenge +function expression(a, b, c) { + return (a + b) == (a < c); +} */ +/* // first refactor +function expression(a, b, c) { + const op_1 = a + b; + return op_1 == (a < c); +} */ +/* // second refactor +function expression(a, b, c) { + const op_1 = a + b; + const op_2 = a < c; + return op_1 == op_2; +} */ + +// fully expanded +function expression(a, b, c) { + const op_1 = a + b; + const op_2 = a < c; + const op_3 = op_1 == op_2; + return op_3; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +--- + +### Three + +uncomment the refactors one at a time to see that they all pass the same tests. + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=b%20%26%26%20typeof%20a%20%3D%3D%3D%20'string'%0Atypeof%20_%0A_%20%3D%3D%3D%20'string'%0A_%20%26%26%20_) +```js +test_cases = [ + {name: 'false, true', args: [false, true], expected: false}, + {name: 'false, "true"', args: [false, "true"], expected: false}, + {name: 'true, 0', args: [true, 0], expected: 0}, + {name: 'true, Æ’alse', args: [true, false], expected: false}, + {name: 'true, "Æ’alse"', args: [true, "false"], expected: false}, + {name: '"", ""', args: ["", ""], expected: ""}, + {name: '"", " "', args: ["", " "], expected: true}, +]; +/* // original challenge +function expression(a, b) { + return b && typeof a === 'string'; +} */ +/* // first refactor +function expression(a, b) { + const op_1 = typeof a; + return b && op_1 === 'string'; +} */ +/* // second refactor +function expression(a, b) { + const op_1 = typeof a; + const op_2 = op_1 === 'string'; + return b && op_2; +} */ + +// expanded expression +function expression(a, b) { + const op_1 = typeof a; + const op_2 = op_1 === 'string'; + const op_3 = b && op_2; + return op_3; +} +run_tests(expression, test_cases); +``` + +> short-circuiting with ```||``` and ```&&```, an advanced gotcha: [worked expansion](./worked-short-circuiting.md), [codeburst: using || cleverly](https://codeburst.io/javascript-what-is-short-circuit-evaluation-ff22b2f5608c) +> The examples on this page do not replicate short-circuiting, and you don't have to either in the assignments + +[TOP](#operator-only-exercises) + +--- + + +### Four + +uncomment the refactors one at a time to see that they all pass the same tests. + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=%28b%20%26%26%20typeof%20a%29%20%3D%3D%3D%20'string'%0Atypeof%20_%0A_%20%26%26%20_%0A_%20%3D%3D%3D%20'string') + +```js +test_cases = [ + {name: '"", NaN', args: ["", NaN], expected: false}, + {name: 'NaN, ""', args: [NaN, ""], expected: false}, + {name: '" ", NaN', args: ["", NaN], expected: false}, + {name: 'NaN, " "', args: [NaN, " "], expected: false}, + {name: '"string", NaN', args: ["string", NaN], expected: false}, + {name: 'NaN, "string"', args: [NaN, "string"], expected: false}, + {name: '"string", true', args: ["", NaN], expected: false}, +]; +/* // original challenge +function expression(a, b) { + return (b && typeof a) === 'string'; +} */ +/* // first refactor +function expression(a, b) { + const op_1 = typeof a; + return (b && op_1) === 'string'; +} */ +/* // second refactor +function expression(a, b) { + const op_1 = typeof a; + const op_2 = b && op_1; + return op_2 === 'string'; +} */ + +// final expansion +function expression(a, b) { + const op_1 = typeof a; + const op_2 = b && op_1; + const op_3 = op_2 === 'string' + return op_3; +} +run_tests(expression, test_cases); +``` + +> __challenge question:__ can this function ever return true? +> Either explain why it's impossible, or write a test case that will return true. + +[TOP](#operator-only-exercises) + +--- + +### Five + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=%28%20a%20%3E%20Number%28b%29%20%29%20%7C%7C%20String%28c%29%0ANumber%28_%29%0A_%20%3E%20_%0AString%28_%29%0A_%20%7C%7C%20_) + +```js +test_cases = [ + {name: '0, 1, null', args:[0, 1, null], expected: "null"}, + {name: '1, 0, null', args:[1, 0, null], expected: true}, + {name: '1, "e", null', args:[1, 'e', null], expected: "null"}, + {name: '"e", "e", null', args:['e', 'e', null], expected: "null"}, + {name: '3, "2", null', args:[3, '2', null], expected: true}, + {name: '"2", "2", undefined', args:['2', '2', undefined], expected: 'undefined'}, +]; +/* // original challenge +function expression(a, b, c) { + return ( a > Number(b) ) || String(c); +} */ +/* // first refactor +function expression(a, b, c) { + const op_1 = Number(b); + return ( a > op_1 ) || String(c); +} */ +/* // second refactor +function expression(a, b, c) { + const op_1 = Number(b); + const op_2 = a > op_1; + return op_2 || String(c); +} */ +/* // third refactor +function expression(a, b, c) { + const op_1 = Number(b); + const op_2 = a > op_1; + const op_3 = String(c); + return op_2 || op_3; +} */ + +// final expansion +function expression(a, b, c) { + const op_1 = Number(b); + const op_2 = a > op_1; + const op_3 = String(c); + const op_4 = op_2 || op_3; + return op_4; +} +run_tests(expression, test_cases); +``` + +> short-circuiting with ```||``` and ```&&```, an advanced gotcha: [worked expansion](./worked-short-circuiting.md), [codeburst: using || cleverly](https://codeburst.io/javascript-what-is-short-circuit-evaluation-ff22b2f5608c) +> The examples on this page do not replicate short-circuiting, and you don't have to either in the assignments + + +[TOP](#operator-only-exercises) + +--- + +## Types and Casting + +### types & casting 1 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=typeof%20a%20%3D%3D%3D%20typeof%20b%0Atypeof%20a%0Atypeof%20b%0A_%20%3D%3D%3D%20_) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return typeof a === typeof b; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +### types & casting 2 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=Boolean%28a%29%20!%3D%3D%20Boolean%28b%29%0ABoolean%28a%29%0ABoolean%28b%29%0A_%20!%3D%3D%20_) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return Boolean(a) !== Boolean(b); +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +### types & casting 3 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=Boolean%28b%29%20%3D%3D%3D%20Boolean%28Number%28a%29%29%0ABoolean%28b%29%0ANumber%28a%29%0ABoolean%28_%29%0A_%20%3D%3D%3D%20_) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return Boolean(b) === Boolean(Number(a)); +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +--- + + +## Logical Operators + + +### logical operators 1 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=!%28a%20%26%26%20!b%29%0A!_%0A_%20%26%26%20_%0A!%28_%29%0A%0A) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return !(a && !b); +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + + +### logical operators 2 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=!!a%20%7C%7C%20!!b%0A!a%0A!_%0A!b%0A!_%0A_%20%7C%7C%20_) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return !!a || !!b; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + + +### logical operators 3 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=!!a%20%7C%7C%20!!b%0A!a%0A!_%0A!b%0A!_%0A_%20%7C%7C%20_) +```js +test_cases = [ + {name: 'null, null, null', args: [null, null, null], expected: null}, +]; +function expression(a, b, c) { + return a || b && c || a; +} +run_tests(expression, test_cases); +``` + + +[TOP](#operator-only-exercises) + +--- + +## Arithmetic Operators + +### arithmetic operators 1 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=-%28a%20%2B%20b%29%20*%20c%0A_%20%2B%20_%0A-%28_%29%0A_%20*%20_) +```js +test_cases = [ + {name: 'null, null, null', args: [null, null, null], expected: null}, +]; +function expression(a, b, c) { + return -(a + b) * c; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + + +### arithmetic operators 2 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=a%20**%20b%20%2F%20%2Bc%0A%2B_%0A_%20**%20_%0A_%20%2F%20_) +```js +test_cases = [ + {name: 'null, null, null', args: [null, null, null], expected: null}, +]; +function expression(a, b, c) { + return a ** b / +c; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + + + +### arithmetic operators 3 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=b%20%25%20c%20-%20a%20**%20c%20%2F%20b%0A_%20**%20_%0A_%20%2F%20_%0A_%20%25%20_%0A_%20-%20_) +```js +test_cases = [ + {name: 'null, null, null', args: [null, null, null], expected: null}, +]; +function expression(a, b, c) { + return b % c - a ** c / b; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +--- + +## All Primitive Operators + + +### all primitive operators 1 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=a%20%25%20b%20%7C%7C%20!!a%0A_%20%25%20_%0A!a%0A!_%0A_%20%7C%7C%20_) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return a % b || !!a; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + + + +### all primitive operators 2 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=typeof%20a%20%3D%3D%3D%20'number'%20%2B%20a%0Atypeof%20_%0A_%20%3D%3D%3D%20_%0A_%20%2B%20_) +```js +test_cases = [ + {name: 'null, null', args: [null, null], expected: null}, +]; +function expression(a, b) { + return typeof a === 'number' + a; +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +### all primitive operators 3 + +[parsonized operators](https://janke-learning.github.io/parsonizer/?snippet=!!%2Ba%20%3D%3D%3D%20Boolean%28a%29%0A%2B_%0A!_%0A!_%0ABoolean%28_%29%0A_%20%3D%3D%3D%20_) +```js +test_cases = [ + {name: 'null', args: [null], expected: null}, +]; +function expression(a) { + return !!+a === Boolean(a); +} +run_tests(expression, test_cases); +``` + +[TOP](#operator-only-exercises) + +--- + +## Resources + +* [test cases](https://github.com/janke-learning/test-cases) +* [worked examples to study](./worked-expressions.md) +* [operator precedence: mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) +* [operator precedence: janke](https://github.com/janke-learning/operator-precedence) +* [operator precedence: scripting master](http://www.scriptingmaster.com/javascript/operator-precedence.asp) +* [operator precedence: dummies](https://www.dummies.com/web-design-development/javascript-operator-precedence/) +* [ast visualizer](https://astexplorer.net/) + * explore how JS parses your code and represents operator precedence + * select to hide everything just above the collapsible tree, makes it readable + * this tool will be very helpful figuring out order of operations when expanding expressions + * the deepest operators are executed first, then their parents, ... + * using this for anything but just expressions will likely be more confusing than helpful + * this tool doesn't check for syntax errors and doesn't run code, so keep it simple and just copy in the expression. no need for variable declarations + + +[TOP](#operator-only-exercises) + +___ +___ +### Janke Learning diff --git a/week-3/jl-functions-as-arguments.md b/week-3/jl-functions-as-arguments.md index 9cc630b..6fcaec3 100644 --- a/week-3/jl-functions-as-arguments.md +++ b/week-3/jl-functions-as-arguments.md @@ -1 +1,167 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/function-exercises/master/functions-as-arguments.md) into this file and complete the exercises! +# Functions as Arguments + +In JavaScript you can pass functions as arguments. Since functions are reference types, they will behave a lot like arrays and objects when passed as arguments. And since they are still functions being called from inside an execution frame, they will still make a callstack like in exercises 3. + +### Index: +* [completed example](#completed-example) +* exercises + * [number 1](#number-1) + * [number 2](#number-2) + * [number 3](#number-3) + * [number 4](#number-4) + +--- + +## completed example + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28param_1,%20param_2%29%20%7B%0A%20%20var%20word_1%20%3D%20param_1%28't',%20'e',%20'a'%29%3B%0A%20%20var%20word_2%20%3D%20param_2%28'e',%20'a',%20't'%29%3B%0A%20%20return%20word_1%20%2B%20'%20'%20%2B%20word_2%3B%0A%7D%0A%0Afunction%20first%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_2%20%2B%20_3%20%2B%20_1%3B%0A%7D%0A%0Afunction%20second%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_3%20%2B%20_1%20%2B%20_2%3B%0A%7D%0A%0Aconst%20result%20%3D%20sentence%28first,%20second%29%3B%0A%0Aconsole.assert%28result%20%3D%3D%3D%20'eat%20tea',%20'result%20%3D%3D%3D%20'%20%2B%20result%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function sentence(param_1, param_2) { + var word_1 = param_1('t', 'e', 'a'); + var word_2 = param_2('e', 'a', 't'); + return word_1 + ' ' + word_2; + } + + function first(_1, _2, _3) { + return _2 + _3 + _1; + } + + function second(_1, _2, _3) { + return _3 + _1 + _2; + } + + const result = sentence(first, second); + + console.assert(result === 'eat tea', 'result === ' + result); +} +``` + +[TOP](#functions-as-arguments) + +--- + +## number 1 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28param_1%29%20%7B%0A%20%20var%20word_1%20%3D%20param_1%28/*%20fill%20this%20*/%29%3B%0A%20%20var%20word_2%20%3D%20param_1%28/*%20fill%20this%20*/%29%3B%0A%20%20var%20word_3%20%3D%20param_1%28/*%20fill%20this%20*/%29%3B%0A%20%20return%20word_1%20%2B%20word_2%20%2B%20word_3%3B%0A%7D%0A%0Afunction%20first%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_2%20%2B%20_3%20%2B%20_1%3B%0A%7D%0A%0Aconst%20result%20%3D%20sentence%28first%29%3B%0A%0Aconsole.assert%28result%20%3D%3D%3D%20'eat%20ate%20tea',%20'result%20%3D%3D%3D%20'%20%2B%20result%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function sentence(param_1) { + var word_1 = param_1(/* fill this */); + var word_2 = param_1(/* fill this */); + var word_3 = param_1(/* fill this */); + return word_1 + word_2 + word_3; + } + + function first(_1, _2, _3) { + return _2 + _3 + _1; + } + + const result = sentence(first); + + console.assert(result === 'eat ate tea', 'result === ' + result); +} +``` + +[TOP](#functions-as-arguments) + +--- + +## number 2 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20word_1%20%3D%20param_1%28/*%20fill%20this%20*/%29%3B%0A%20%20var%20word_2%20%3D%20param_2%28/*%20fill%20this%20*/%29%3B%0A%20%20var%20word_3%20%3D%20param_3%28/*%20fill%20this%20*/%29%3B%0A%20%20return%20word_1%20%2B%20word_2%20%2B%20word_3%3B%0A%7D%0A%0Afunction%20first%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_2%20%2B%20_3%20%2B%20_1%20%2B%20'%20'%3B%0A%7D%0Afunction%20second%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_3%20%2B%20_1%20%2B%20_2%20%2B%20'%20'%3B%0A%7D%0Afunction%20third%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_1%20%2B%20_3%20%2B%20_2%3B%0A%7D%0A%0Aconst%20result%20%3D%20sentence%28first,%20second,%20third%29%3B%0A%0Aconsole.assert%28result%20%3D%3D%3D%20'eat%20ate%20tea',%20'result%20%3D%3D%3D%20'%20%2B%20result%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function sentence(param_1, param_2, param_3) { + var word_1 = param_1(/* fill this */); + var word_2 = param_2(/* fill this */); + var word_3 = param_3(/* fill this */); + return word_1 + word_2 + word_3; + } + + function first(_1, _2, _3) { + return _2 + _3 + _1 + ' '; + } + function second(_1, _2, _3) { + return _3 + _1 + _2 + ' '; + } + function third(_1, _2, _3) { + return _1 + _3 + _2; + } + + const result = sentence(first, second, third); + + console.assert(result === 'eat ate tea', 'result === ' + result); +} +``` + +[TOP](#functions-as-arguments) + +--- + +## number 3 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20word_1%20%3D%20param_1%28't',%20'a',%20'e'%29%3B%0A%20%20var%20word_2%20%3D%20param_2%28'e',%20't',%20'a'%29%3B%0A%20%20var%20word_3%20%3D%20param_3%28'a',%20't',%20'e'%29%3B%0A%20%20return%20word_1%20%2B%20word_2%20%2B%20word_3%3B%0A%7D%0A%0Afunction%20first%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20/*%20fill%20this%20*/%3B%0A%7D%0Afunction%20second%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20/*%20fill%20this%20*/%3B%0A%7D%0Afunction%20third%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20/*%20fill%20this%20*/%3B%0A%7D%0A%0Aconst%20result%20%3D%20sentence%28first,%20second,%20third%29%3B%0A%0Aconsole.assert%28result%20%3D%3D%3D%20'eat%20ate%20tea',%20'result%20%3D%3D%3D%20'%20%2B%20result%29%3B&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function sentence(param_1, param_2, param_3) { + var word_1 = param_1('t', 'a', 'e'); + var word_2 = param_2('e', 't', 'a'); + var word_3 = param_3('a', 't', 'e'); + return word_1 + word_2 + word_3; + } + + function first(_1, _2, _3) { + return /* fill this */; + } + function second(_1, _2, _3) { + return /* fill this */; + } + function third(_1, _2, _3) { + return /* fill this */; + } + + const result = sentence(first, second, third); + + console.assert(result === 'eat ate tea', 'result === ' + result); +} +``` + +[TOP](#functions-as-arguments) + +--- + +## number 4 + +[on pytut](http://www.pythontutor.com/live.html#code=function%20sentence%28param_1,%20param_2,%20param_3%29%20%7B%0A%20%20var%20word_1%20%3D%20param_1%28't',%20'a',%20'e'%29%3B%0A%20%20var%20word_2%20%3D%20param_2%28'e',%20't',%20'a'%29%3B%0A%20%20var%20word_3%20%3D%20param_3%28'a',%20't',%20'e'%29%3B%0A%20%20return%20word_1%20%2B%20word_2%20%2B%20word_3%3B%0A%7D%0A%0Afunction%20first%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_2%20%2B%20_3%20%2B%20_1%3B%0A%7D%0Afunction%20second%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_3%20%2B%20_2%20%2B%20_1%3B%0A%7D%0Afunction%20third%28_1,%20_2,%20_3%29%20%7B%0A%20%20return%20_3%20%2B%20_2%20%2B%20_1%3B%0A%7D%0A%0Aconst%20result%20%3D%20sentence%28/*%20fill%20this%20*/%29%3B%0A%0Aconsole.assert%28result%20%3D%3D%3D%20'eat%20ate%20tea',%20'result%20%3D%3D%3D%20'%20%2B%20result%29%3B&cumulative=false&curInstr=2&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + function sentence(param_1, param_2, param_3) { + var word_1 = param_1('t', 'a', 'e'); + var word_2 = param_2('e', 't', 'a'); + var word_3 = param_3('a', 't', 'e'); + return word_1 + word_2 + word_3; + } + + function first(_1, _2, _3) { + return _2 + _3 + _1; + } + function second(_1, _2, _3) { + return _3 + _2 + _1; + } + function third(_1, _2, _3) { + return _3 + _2 + _1; + } + + const result = sentence(/* fill this */); + + console.assert(result === 'eat ate tea', 'result === ' + result); +} +``` + +[TOP](#functions-as-arguments) + +___ +___ +### Janke Learning diff --git a/week-3/jl-operator-precedence.md b/week-3/jl-operator-precedence.md index 03f0377..d1ce1b5 100644 --- a/week-3/jl-operator-precedence.md +++ b/week-3/jl-operator-precedence.md @@ -1 +1,535 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/operator-precedence/master/README.md) into this file and complete the exercises! +# Operator Precedence + +you'll be presented with a single line expression. your task is to break it into steps according to operator precedence. The main objective for these exercises is that you become comfortable stepping through and working with complex JS expressions, not that your learn everything about how all operators work. + +Once you become familiar with these exercises you'll find that you're able to complete them just as easily no matter what values you set. +After mastering them you'll find that you can complete them without even caring what values are going through the expressions! + +This is because programming languages are _formal systems_, meaning their text is constructed based on a set of rules. Once you learn how to manipulate code thinking not about _what it does_ but _how it's structured_ as a text, then you'll be ready to rock and roll. + +__learning objectives__ +* which operators exist in JS +* reading this [operator precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) +* breaking down long expressions (super helpful for debugging, reading & writing code) +* stepping through expressions +* building nasty debugging skillls +* statements vs. expressions + + + +### Index +* [completed examples](#completed-examples) + * [one](#1) + * [two](#2) + * [three](#3) + * [four](#4) + * [five](#5) +* exercises + * [types & casting](#types-and-casting) + * [logical operators](#logical-operators) + * [arithmetic operators](#arithmetic-operators) + * [all primitive operators](#all-primitive-operators) +* [resources](#resources) + +--- + +## Completed Examples + +### 1 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=Number%28Boolean%28String%28a%29%29%29%0AString%28_%29%0ABoolean%28_%29%0ANumber%28_%29) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20Number%28Boolean%28String%28a%29%29%29%3B%0A%0Aconst%20op_1%20%3D%20String%28a%29%3B%0Aconst%20step_1%20%3D%20Number%28Boolean%28op_1%29%29%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20Boolean%28op_1%29%3B%0Aconst%20step_2%20%3D%20Number%28op_2%29%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20Number%28op_2%29%3B%0Aconst%20step_3%20%3D%20op_3%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = ; + + const expected = Number(Boolean(String(a))); + + const op_1 = String(a); + const step_1 = Number(Boolean(op_1)); + console.assert(step_1 === expected, "step_1"); + + const op_2 = Boolean(op_1); + const step_2 = Number(op_2); + console.assert(step_2 === expected, "step_2"); + + const op_3 = Number(op_2); + const step_3 = op_3; + console.assert(step_3 === expected, "step_3"); +} +``` + +### 2 + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=%28a%20%2B%20b%29%20%3D%3D%20%28a%20%3C%20c%29%0A_%20%2B%20_%0A_%20%3C%20_%0A_%20%3D%3D%20_%0A%0A%0A%0A) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20,%20c%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20%28a%20%2B%20b%29%20%3D%3D%20%28a%20%3C%20c%29%3B%0A%0Aconst%20op_1%20%3D%20a%20%2B%20b%3B%0Aconst%20step_1%20%3D%20op_1%20%3D%3D%20%28a%20%3C%20c%29%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20a%20%3C%20c%3B%0Aconst%20step_2%20%3D%20op_1%20%3D%3D%20op_2%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20op_1%20%3D%3D%20op_2%3B%0Aconst%20step_3%20%3D%20op_3%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) + +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = , c = ; + + const expected = (a + b) == (a < c); + + const op_1 = a + b; + const step_1 = op_1 == (a < c); + console.assert(step_1 === expected, "step_1"); + + const op_2 = a < c; + const step_2 = op_1 == op_2; + console.assert(step_2 === expected, "step_2"); + + const op_3 = op_1 == op_2; + const step_3 = op_3; + console.assert(step_3 === expected, "step_3"); +} +``` + +### 3 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=b%20%26%26%20typeof%20a%20%3D%3D%3D%20'string'%0Atypeof%20_%0A_%20%3D%3D%3D%20'string'%0A_%20%26%26%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20b%20%26%26%20typeof%20a%20%3D%3D%3D%20'string'%3B%0A%0Aconst%20op_1%20%3D%20typeof%20a%3B%0Aconst%20step_1%20%3D%20b%20%26%26%20op_1%20%3D%3D%3D%20'string'%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20op_1%20%3D%3D%3D%20'string'%3B%0Aconst%20step_2%20%3D%20b%20%26%26%20op_2%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20b%20%26%26%20op_2%3B%0Aconst%20step_3%20%3D%20op_3%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B&cumulative=false&curInstr=1&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = b && typeof a === 'string'; + + const op_1 = typeof a; + const step_1 = b && op_1 === 'string'; + console.assert(step_1 === expected, "step_1"); + + const op_2 = op_1 === 'string'; + const step_2 = b && op_2; + console.assert(step_2 === expected, "step_2"); + + const op_3 = b && op_2; + const step_3 = op_3; + console.assert(step_3 === expected, "step_3"); +} +``` +[short-circuiting - an advanced gotcha](https://github.com/janke-learning/expanding/blob/master/worked-short-circuiting.md) + +### 4 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=%28b%20%26%26%20typeof%20a%29%20%3D%3D%3D%20'string'%0Atypeof%20_%0A_%20%26%26%20_%0A_%20%3D%3D%3D%20'string') +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20%28b%20%26%26%20typeof%20a%29%20%3D%3D%3D%20'string'%3B%0A%0Aconst%20op_1%20%3D%20typeof%20a%3B%0Aconst%20step_1%20%3D%20op_1%20%3D%3D%3D%20'string'%20%26%26%20b%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20b%20%26%26%20op_1%3B%0Aconst%20step_2%20%3D%20op_2%20%3D%3D%3D%20'string'%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20op_2%20%3D%3D%3D%20'string'%3B%0Aconst%20step_3%20%3D%20op_3%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = (b && typeof a) === 'string'; + + const op_1 = typeof a; + const step_1 = (b && op_1) === 'string' ; + console.assert(step_1 === expected, "step_1"); + + const op_2 = b && op_1; + const step_2 = op_2 === 'string'; + console.assert(step_2 === expected, "step_2"); + + const op_3 = op_2 === 'string'; + const step_3 = op_3; + console.assert(step_3 === expected, "step_3"); +} +``` + + +### 5 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=%28%20a%20%3E%20Number%28b%29%20%29%20%7C%7C%20String%28c%29%0ANumber%28_%29%0A_%20%3E%20_%0AString%28_%29%0A_%20%7C%7C%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20,%20c%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20%28%20a%20%3E%20Number%28b%29%20%29%20%7C%7C%20String%28c%29%3B%0A%0Aconst%20op_1%20%3D%20Number%28b%29%3B%0Aconst%20step_1%20%3D%20%28%20a%20%3E%20op_1%20%29%20%7C%7C%20String%28c%29%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20a%20%3E%20op_1%3B%0Aconst%20step_2%20%3D%20%28%20op_2%20%29%20%7C%7C%20String%28c%29%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20String%28c%29%3B%0Aconst%20step_3%20%3D%20op_2%20%7C%7C%20op_3%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B%0A%0Aconst%20op_4%20%3D%20op_2%20%7C%7C%20op_3%3B%0Aconst%20step_4%20%3D%20op_4%3B%0Aconsole.assert%28step_4%20%3D%3D%3D%20expected,%20%22step_4%22%29%3B&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = , c = ; + + const expected = ( a > Number(b) ) || String(c); + + const op_1 = Number(b); + const step_1 = ( a > op_1 ) || String(c); + console.assert(step_1 === expected, "step_1"); + + const op_2 = a > op_1; + const step_2 = ( op_2 ) || String(c); + console.assert(step_2 === expected, "step_2"); + + const op_3 = String(c); + const step_3 = op_2 || op_3; + console.assert(step_3 === expected, "step_3"); + + const op_4 = op_2 || op_3; + const step_4 = op_4; + console.assert(step_4 === expected, "step_4"); +} +``` +[short-circuiting - an advanced gotcha](https://codeburst.io/javascript-what-is-short-circuit-evaluation-ff22b2f5608c) + + + +[TOP](#operator-precedence) + +--- +--- + +# Exercises + +--- + +## Types and Casting + +### types & casting 1 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=typeof%20a%20%3D%3D%3D%20typeof%20b%0Atypeof%20a%0Atypeof%20b%0A_%20%3D%3D%3D%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20typeof%20a%20%3D%3D%3D%20typeof%20b%3B%0A%0Aconst%20op_1%20%3D%20%3B%0Aconst%20step_1%20%3D%20%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20%3B%0Aconst%20step_2%20%3D%20%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20%3B%0Aconst%20step_3%20%3D%20%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = typeof a === typeof b; + + let op_1; + let step_1; + console.assert(step_1 === expected, "step_1"); + + let op_2; + let step_2; + console.assert(step_2 === expected, "step_2"); + + let op_3; + let step_3; + console.assert(step_3 === expected, "step_3"); +} +``` + +### types & casting 2 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=Boolean%28a%29%20!%3D%3D%20Boolean%28b%29%0ABoolean%28a%29%0ABoolean%28b%29%0A_%20!%3D%3D%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20Boolean%28a%29%20!%3D%3D%20Boolean%28b%29%3B%0A%0Aconst%20op_1%20%3D%20%3B%0Aconst%20step_1%20%3D%20%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20%3B%0Aconst%20step_2%20%3D%20%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20%3B%0Aconst%20step_3%20%3D%20%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B%20&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = Boolean(a) !== Boolean(b); + + let op_1; + let step_1; + console.assert(step_1 === expected, "step_1"); + + let op_2; + let step_2; + console.assert(step_2 === expected, "step_2"); + + let op_3; + let step_3; + console.assert(step_3 === expected, "step_3"); +} +``` + +## types & casting 3 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=Boolean%28b%29%20%3D%3D%3D%20Boolean%28Number%28a%29%29%0ABoolean%28b%29%0ANumber%28a%29%0ABoolean%28_%29%0A_%20%3D%3D%3D%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20Boolean%28b%29%20%3D%3D%3D%20Boolean%28Number%28a%29%29%3B%0A%0Aconst%20op_1%20%3D%20%3B%0Aconst%20step_1%20%3D%20%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20%3B%0Aconst%20step_2%20%3D%20%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20%3B%0Aconst%20step_3%20%3D%20%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B%0A%0Aconst%20op_4%20%3D%20%3B%0Aconst%20step_4%20%3D%20%3B%0Aconsole.assert%28step_4%20%3D%3D%3D%20expected,%20%22step_4%22%29%3B&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = Boolean(b) === Boolean(Number(a)); + + let op_1; + let step_1; + console.assert(step_1 === expected, "step_1"); + + let op_2; + let step_2; + console.assert(step_2 === expected, "step_2"); + + let op_3; + let step_3; + console.assert(step_3 === expected, "step_3"); + + let op_4; + let step_4; + console.assert(step_4 === expected, "step_4"); +} +``` + +[TOP](#operator-precedence) + +--- + +## Logical Operators + +### logical operators 1 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=!%28a%20%26%26%20!b%29%0A!_%0A_%20%26%26%20_%0A!%28_%29%0A%0A) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20!%28a%20%26%26%20!b%29%3B%0A%0Aconst%20op_1%20%3D%20%3B%0Aconst%20step_1%20%3D%20%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20%3B%0Aconst%20step_2%20%3D%20%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20%3B%0Aconst%20step_3%20%3D%20%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B%20&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = !(a && !b); + + let op_1; + let step_1; + console.assert(step_1 === expected, "step_1"); + + let op_2; + let step_2; + console.assert(step_2 === expected, "step_2"); + + let op_3; + let step_3; + console.assert(step_3 === expected, "step_3"); +} +``` + +### logical operators 2 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=!!a%20%7C%7C%20!!b%0A!a%0A!_%0A!b%0A!_%0A_%20%7C%7C%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20!!a%20%7C%7C%20!!b%3B%0A%0Aconst%20op_1%20%3D%20%3B%0Aconst%20step_1%20%3D%20%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20%3B%0Aconst%20step_2%20%3D%20%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20%3B%0Aconst%20step_3%20%3D%20%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B%20%0A%0Aconst%20op_4%20%3D%20%3B%0Aconst%20step_4%20%3D%20%3B%0Aconsole.assert%28step_4%20%3D%3D%3D%20expected,%20%22step_4%22%29%3B%0A%0Aconst%20op_5%20%3D%20%3B%0Aconst%20step_5%20%3D%20%3B%0Aconsole.assert%28step_5%20%3D%3D%3D%20expected,%20%22step_5%22%29%3B%20&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = ; + + const expected = !!a || !!b; + + let op_1; + let step_1; + console.assert(step_1 === expected, "step_1"); + + let op_2; + let step_2; + console.assert(step_2 === expected, "step_2"); + + let op_3; + let step_3; + console.assert(step_3 === expected, "step_3"); + + let op_4; + let step_4; + console.assert(step_4 === expected, "step_4"); + + let op_5; + let step_5; + console.assert(step_5 === expected, "step_5"); +} +``` + +### logical operators 3 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=a%20%7C%7C%20b%20%26%26%20c%20%7C%7C%20a%0A_%20%26%26%20_%0Aa%20%7C%7C%20_%0A_%20%7C%7C%20a) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20,%20c%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20a%20%7C%7C%20b%20%26%26%20c%20%7C%7C%20a%3B%0A%0A//%20break%20down%20this%20expression&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = , b = , c = ; + + const expected = a || b && c || a; + + // break down this expression +} +``` +[ast explorer](https://astexplorer.net/#/gist/bc0bac0e8559bf97071c9129a05a28f9/e5fcaa5df8317fb1a45ba1a7866733d96768c463) + + +[TOP](#operator-precedence) + +--- + +## Arithmetic Operators + +### arithmetic operators 1 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=-%28a%20%2B%20b%29%20*%20c%0A_%20%2B%20_%0A-%28_%29%0A_%20*%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%200,%201,%20-1,%20NaN,%20Infinity,%20.5,%20-0.0,%201e3,%201e-3,%20999e305,%20999e306%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20,%20c%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20-%28a%20%2B%20b%29%20*%20c%3B%0A%0Aconst%20op_1%20%3D%20%3B%0Aconst%20step_1%20%3D%20%3B%0Aconsole.assert%28step_1%20%3D%3D%3D%20expected,%20%22step_1%22%29%3B%0A%0Aconst%20op_2%20%3D%20%3B%0Aconst%20step_2%20%3D%20%3B%0Aconsole.assert%28step_2%20%3D%3D%3D%20expected,%20%22step_2%22%29%3B%0A%0Aconst%20op_3%20%3D%20%3B%0Aconst%20step_3%20%3D%20%3B%0Aconsole.assert%28step_3%20%3D%3D%3D%20expected,%20%22step_3%22%29%3B%20&cumulative=false&curInstr=10&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ +/* values to try + 0, 1, -1, NaN, Infinity, .5, -0.0, 1e3, 1e-3, 999e305, 999e306 +*/ +const a = , b = , c = ; + +const expected = -(a + b) * c; + +let op_1; +let step_1; +console.assert(step_1 === expected, "step_1"); + +let op_2; +let step_2; +console.assert(step_2 === expected, "step_2"); + +let op_3; +let step_3; +console.assert(step_3 === expected, "step_3"); +} +``` +[scientific notation](http://www.java2s.com/Tutorials/Javascript/Javascript_Tutorial/Data_Type/How_to_write_Scientific_notation_literal_in_Javascript.htm) + +### arithmetic operators 2 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=a%20**%20b%20%2F%20%2Bc%0A%2B_%0A_%20**%20_%0A_%20%2F%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%200,%201,%20-1,%20NaN,%20Infinity,%20.5,%20-0.0,%201e3,%201e-3,%20999e305,%20999e306%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20,%20c%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20a%20**%20b%20/%20%2Bc%3B%0A%0A//%20break%20down%20this%20expression%20&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + 0, 1, -1, NaN, Infinity, .5, -0.0, 1e3, 1e-3, 999e305, 999e306 + */ + const a = , b = , c = ; + + const expected = a ** b / +c; + + // break down this expression +} +``` + +### arithmetic operators 3 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=b%20%25%20c%20-%20a%20**%20c%20%2F%20b%0A_%20**%20_%0A_%20%2F%20_%0A_%20%25%20_%0A_%20-%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%200,%201,%20-1,%20NaN,%20Infinity,%20.5,%20-0.0,%201e3,%201e-3,%20999e305,%20999e306%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20,%20c%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20b%20%25%20c%20-%20a%20**%20c%20/%20b%3B%0A%0A//%20break%20down%20this%20expression&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + 0, 1, -1, NaN, Infinity, .5, -0.0, 1e3, 1e-3, 999e305, 999e306 + */ + const a = , b = , c = ; + + const expected = b % c - a ** c / b; + + // break down this expression +} +``` + +[TOP](#operator-precedence) + +--- + +## All Primitive Operators + +### all primitive operators 1 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=a%20%25%20b%20%7C%7C%20!!a%0A_%20%25%20_%0A!a%0A!_%0A_%20%7C%7C%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%200,%201,%20-1,%20NaN,%20Infinity,%20.5,%20-0.0,%201e3,%201e-3,%20999e305,%20999e306%0A%20%200,%203%0A%20%201,%203%0A%20%202,%203%0A%20%203,%203%0A%20%204,%203%0A*/%0Aconst%20a%20%3D%20,%20b%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20a%20%25%20b%20%7C%7C%20!!a%3B%0A%0A//%20break%20down%20this%20expression&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + 0, 1, -1, NaN, Infinity, .5, -0.0, 1e3, 1e-3, 999e305, 999e306 + 0, 3 + 1, 3 + 2, 3 + 3, 3 + 4, 3 + */ + const a = , b = ; + + const expected = a % b || !!a; + + // break down this expression +} +``` + +### all primitive operators 2 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=typeof%20a%20%3D%3D%3D%20'number'%20%2B%20a%0Atypeof%20_%0A_%20%3D%3D%3D%20_%0A_%20%2B%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%200,%201,%20-1,%20NaN,%20Infinity,%20.5,%20-0.0,%201e3,%201e-3,%20999e305,%20999e306%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20typeof%20a%20%3D%3D%3D%20'number'%20%2B%20a%3B%0A%0A//%20break%20down%20this%20expression&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + 0, 1, -1, NaN, Infinity, .5, -0.0, 1e3, 1e-3, 999e305, 999e306 + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = ; + + const expected = typeof a === 'number' + a; + + // break down this expression +} +``` + +### all primitive operators 3 + + +[parsonized](https://janke-learning.github.io/parsonizer/?snippet=!!%2Ba%20%3D%3D%3D%20Boolean%28a%29%0A%2B_%0A!_%0A!_%0ABoolean%28_%29%0A_%20%3D%3D%3D%20_) +[on pytut](http://www.pythontutor.com/live.html#code=/*%20values%20to%20try%0A%20%20%22%22,%20%22%20%22,%20true,%20false,%20undefined,%20null,%200,%201,%20-1,%20NaN,%20Infinity%0A*/%0Aconst%20a%20%3D%20%3B%0A%0Aconst%20expected%20%3D%20!!%2Ba%20%3D%3D%3D%20Boolean%28a%29%3B%0A%0A//%20break%20down%20this%20expression&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +```js +{ + /* values to try + "", " ", true, false, undefined, null, 0, 1, -1, NaN, Infinity + */ + const a = ; + + const expected = !!+a === Boolean(a); + + // break down this expression +} +``` + + +[TOP](#operator-precedence) + +--- + +## Resources + +* [operator precedence: mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) +* [operator precedence: scripting master](http://www.scriptingmaster.com/javascript/operator-precedence.asp) +* [operator precedence: dummies](https://www.dummies.com/web-design-development/javascript-operator-precedence/) +* [ast visualizer](https://astexplorer.net/) + * explore how JS parses your code and represents operator precedence + * select to hide everything just above the collapsible tree, makes it readable + * this tool will be very helpful figuring out order of operations when expanding expressions + * the deepest operators are executed first, then their parents, ... + * using this for anything but just expressions will likely be more confusing than helpful + * this tool doesn't check for syntax errors and doesn't run code, so keep it simple and just copy in the expression. no need for variable declarations + + +___ +___ +### Janke Learning diff --git a/week-3/jl-replicate-loose-equality.md b/week-3/jl-replicate-loose-equality.md index 9db11da..a33fa75 100644 --- a/week-3/jl-replicate-loose-equality.md +++ b/week-3/jl-replicate-loose-equality.md @@ -1,2 +1,186 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/implicit-coercion/master/replicate-loose-equality.md) into this file and complete the exercises! +# Replicate Loose Equality + + +["What I cannot create, I do not understand."](https://blog.codinghorror.com/when-understanding-means-rewriting/) + +Gain a deeper understanding of implicit coercion and the tricky ```==``` operator by developing your own replication for primitive values onlu using a [TDD methodology](https://github.com/janke-learning/tdd). + + +### Index +* [describing behavior](#describing-behavior) +* [run\_tests function](#run--tests-function) +* [test driven development](#test-driven-development) +* [study ```==```](#study-it) +* [replicate ```==```](#replicate-it) + +--- + +## Describing Behavior + +Code's behavior is what has changed in your program _after_ the code has executed, implementation is the lines of text that make up the code. This exercise will introduce how to understand behavior using __test cases__. + +Practically speaking you can think of test cases as just inputs and outputs. What values went into the function, and what values come out of the function? The test case will contain the input-output pairs that your function _should_ implement, a test case fails if the function returns something else. + +Test cases may be relatively easy to read and use, but writing good ones can be tricky. You have to think about all possible strange combinations and fringe cases. So don't worry about writing the perfect test cases yet, just do your best and compare with a friend to help each other understand how you thought of your test cases. + +For this exercise you will write test cases in this format: +```js +test_cases = [ + {name:'meaningful name', args:['the inputs', 'for this snippet'], expected: 'what it should output'}, + {name:'another test case', args:['different', 'inputs'], expected: 'the expected output'}, + ]; +``` + +[TOP](#replicate-loose-equality) + +--- + +## run\_tests Function + +To check if your function passes all of it's test cases, we'll be using this function. It takes two arguments (the function to test, and the test cases), and console.log's a message for every test case that fails. + +Study it for a minute then paste it in the console, the exercises below won't work otherwise. If you don't understand entirely how this function works that's okay. The main objective for this exercise is to write & use test cases, understand JS operators. + +```js +function run_tests(_target, _cases) { + console.groupCollapsed('<- click this arrow to see the function') + console.log(_target.toString()); + console.groupEnd(); + + for (let t_case of _cases) { + + // create variables for readability + const expected = t_case.expected; + const args = t_case.args; + + // run function with test case + const actual = _target(...args); + + // compare + let pass; + if (typeof expected === 'object' && expected !== null) { + const _actual = JSON.stringify(actual); + const _expected = JSON.stringify(expected); + pass = _actual === _expected; + } else if ( expected !== expected ) { + pass = actual !== actual; + } else { + pass = actual === expected; + }; + + // communicate result to developer + if (pass) { + console.groupCollapsed(`%cPASS: ${t_case.name}`, 'color:green'); + } else { + console.groupCollapsed(`%c: ${t_case.name}`, 'color:red'); + console.log("%cactual: ", 'color:orange', typeof actual +", "+ actual); + }; + + for (let i = 0; i < args.length; i++) { + console.log(`arg ${i+1}: ${typeof args[i]},`, args[i]); + } + console.log("%cexpected: ", 'color:blue', typeof expected +", "+ expected); + console.groupEnd(); + }; +} +``` + +[TOP](#replicate-loose-equality) + +--- + +## Test Driven Development + +Very briefly this is a development philosophy that says to write all the tests your code should pass, then write the code to pass the tests. + +In the following exercise you will be practicing TDD by starting with the ```test_cases```, and then writing the ```==``` replication to pass the tests. + +For more info and TDD exercises [check this out](https://github.com/janke-learning/tdd). + +[TOP](#replicate-loose-equality) + +--- + +### Study It + +Study [this comparison table](https://dorey.github.io/JavaScript-Equality-Table/). +Play around with this [interactive table](https://janke-learning.org/equalities-coercion/). +Then test yourself with [this quiz](https://eqeq.js.org). + + +[TOP](#replicate-loose-equality) + +--- + +### Replicate It + +It's your turn. In this exercise you'll write your own replication of the == operator for primitive values 'number', 'string', 'boolean', 'null' and 'undefined'. We've provided you with a whole bunch of test cases and a commented starter function. It's up to you to do the rest! (hint: try focusing on one comment at a time, pass it then, move on to pass the next. also, the test cases are organized to match up with the three sections of the function) + +__Passing Test Cases:__ you will use these tests to develop your replication of ```==```. Copy-paste them into the console and hit enter. to make sure they are loaded type ```test_cases``` into the console. Feel free to add more passing test cases before moving on the replication! +```js +test_cases = [ + { name: 'null, undefined', args: [null, undefined], expected: true}, + { name: 'undefined, null', args: [undefined, null], expected: true}, + { name: 'null, null', args: [null, null], expected: true}, + { name: 'undefined, undefined', args: [undefined, undefined], expected: true}, + { name: 'null, "anything else"', args: [null, "anything else"], expected: false}, + { name: 'undefined, "anything else"', args: [undefined, "anything else"], expected: false}, + { name: 'true, false', args: [true, false], expected: false}, + { name: 'false, false', args: [false, false], expected: true}, + { name: '3, 3', args: [3, 3], expected: true}, + { name: '3.0, 3', args: [3.0, 3], expected: true}, + { name: '+0, -0', args: [+0, -0], expected: true}, + { name: '"\t", "\t"', args: ["\t", '\t'], expected: true}, + { name: '-3, +3', args: [-3, +3], expected: false}, + { name: '3, "3"', args: [3, "3"], expected: true}, + { name: '"3", 3', args: ["3", 3], expected: true}, + { name: '"3", "3"', args: ["3", "3"], expected: true}, + { name: 'true, 1', args: [true, 1], expected: true}, + { name: 'false, 0', args: [false, 0], expected: true}, + { name: 'false, ""', args: [false, ""], expected: true}, + { name: '0, ""', args: [0, ""], expected: true}, + { name: '"e", true', args: ["e", true], expected: false}, + { name: 'undefined, ""', args: [undefined, ""], expected: false} +]; +``` + +__Native Operation:__ Before moving on, copy-paste this code into the console and hit enter. Study the test results to build a first understanding of how ```==``` works. (if there are any red test cases, something went wrong!) +```js +{ + function loose_equality(a, b) { + return a == b; + } + run_tests(loose_equality, test_cases); +} +``` + +__Your Replication:__ Your turn! Paste the code below into the console and begin developing your own replication of the ```==``` operator. Write little bits of code at once and run the code frequently. Try perhaps implementing one comment at a time or to pass one test case at a time. +Once you've passed all the tests, paste your code back into this markdown for studying later! +```js +{ + function loose_replication(a, b) { + // if both a and b are null or undefined, return true + // if only one is null or undefined, return false + + // if both arguments are the same type (num, string, or bool) + // compare them with === and return the result + + // if both are not the same type + // make sure both are type 'number' + // compare them with ===, and return the result + } + run_tests(loose_replication, test_cases); +} +``` + +[TOP](#replicate-loose-equality) + +--- + +> [a complete replication of ```==```](https://gist.github.com/qntm/d899c00aa1ac2c663ac6db23bcffcaba), not just for primitives + +___ +___ +### Janke Learning diff --git a/week-3/jl-test-cases.md b/week-3/jl-test-cases.md index b4dda8e..4c1885e 100644 --- a/week-3/jl-test-cases.md +++ b/week-3/jl-test-cases.md @@ -1 +1,443 @@ -> paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/test-cases/master/README.md) into this file and complete the exercises! \ No newline at end of file +> paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/test-cases/master/README.md) into this file and complete the exercises! +# Test Cases + +Learn about test cases, a great way to understand code. And learn a bit out JS operators while you're at it. + +### Index: +* [describing behavior](#describing-behavior) +* [run\_tests function](#run-tests-function) +* [examples to study](#examples-to-study) + * [failing test cases](#failing-test-cases) + * [plus](#plus) + * [loose equality](#loose-equality) +* [exercises](#exercises) + * [strict equality](#strict-equality) + * [typeof](#typeof) + * [boolean](#boolean) + * [number](#number) + * [or](#or) + * [and](#and) + * [not](#not) + * [ternary](#ternary) + * [less than](#less-than) + * [greater than](#greater-than) + * [subtraction](#subtraction) +* [resources](#resources) + +--- + +## Describing Behavior + +Code's behavior is what has changed in your program _after_ the code has executed, implementation is the lines of text that make up the code. This exercise will introduce how to understand behavior using __test cases__. + +Practically speaking you can think of test cases as just inputs and outputs. What values went into the function, and what values come out of the function? The test case will contain the input-output pairs that your function _should_ implement, a test case fails if the function returns something else. + +Test cases may be relatively easy to read and use, but writing good ones can be tricky. You have to think about all possible strange combinations and fringe cases. So don't worry about writing the perfect test cases yet, just do your best and compare with a friend to help each other understand how you thought of your test cases. + +For this exercise you will write test cases in this format: +```js +test_cases = [ + {name:'meaningful name', args:['the inputs', 'for this snippet'], expected: 'what it should output'}, + {name:'another test case', args:['different', 'inputs'], expected: 'the expected output'}, + ]; +``` + +> DISCLAIMER: +> * In this exercise you are learning to write test cases for existing code. The code is always right. If your test fails, change it. +> * In the real world it will usually be the oposite. The tests should descibe the code. If the tests fail, change the code. + +[TOP](#test-cases) + +--- + +## run\_tests Function + +To check if your function passes all of it's test cases, we'll be using this function. It takes two arguments (the function to test, and the test cases), and console.log's a message for every test case that fails. + +Study it for a minute then paste it in the console, the exercises below won't work otherwise. If you don't understand entirely how this function works that's okay. The main objective for this exercise is to write & use test cases, understand JS operators. + +```js +function run_tests(_target, _cases) { + console.groupCollapsed('<- click this arrow to see the function') + console.log(_target.toString()); + console.groupEnd(); + + for (let t_case of _cases) { + + // create variables for readability + const expected = t_case.expected; + const args = t_case.args; + + // run function with test case + const actual = _target(...args); + + // compare + let pass; + if (typeof expected === 'object' && expected !== null) { + const _actual = JSON.stringify(actual); + const _expected = JSON.stringify(expected); + pass = _actual === _expected; + } else if ( expected !== expected ) { + pass = actual !== actual; + } else { + pass = actual === expected; + }; + + // communicate result to developer + if (pass) { + console.groupCollapsed(`%cPASS: ${t_case.name}`, 'color:green'); + } else { + console.groupCollapsed(`%c: ${t_case.name}`, 'color:red'); + console.log("%cactual: ", 'color:orange', typeof actual +", "+ actual); + }; + + for (let i = 0; i < args.length; i++) { + console.log(`arg ${i+1}: ${typeof args[i]},`, args[i]); + } + console.log("%cexpected: ", 'color:blue', typeof expected +", "+ expected); + console.groupEnd(); + }; +} +``` + +[TOP](#test-cases) + +--- + +## Examples to Study + +### Failing Test Cases + +notice: in all of these exercises it is your test cases that need to change if they fail. JS operators are always right, you must change your expectations until they match the actual behavior. +```js +{ + const test_cases = [ + {name: '3', args: [3], expected: 3}, + {name: 'null', args: [null], expected: 'object'}, + {name: 'true', args: [true], expected: '1'}, + {name: 'false', args: [false], expected: '0'}, + ]; + function to_string(a) { + return String(a); + } + run_tests(to_string, test_cases); +} +``` + + +### Plus + +```js +{ + const test_cases = [ + {name: 'string, number', args: ['e', 1], expected: 'e1'}, + {name: 'string, null', args: ['e', null], expected: 'enull'}, + {name: 'string, undefined', args: ['e', undefined], expected: 'eundefined'}, + {name: 'string, boolean', args: ['e', false], expected: 'efalse'}, + {name: 'number, number', args: [1, -1], expected: 0}, + {name: 'true, number', args: [true, 1], expected: 2}, + {name: 'false, number', args: [false, 1], expected: 1}, + {name: 'null, number', args: [null, 1], expected: 1}, + {name: 'undefined, number', args: [undefined, 1], expected: NaN}, + ]; + function plus(a, b) { + return a + b; + } + run_tests(plus, test_cases); +} +``` + +### Loose Equality + +```js +{ + const test_cases = [ + {name: 'null, undefined', args: [null, undefined], expected: true}, + {name: 'null, null', args: [null, null], expected: true}, + {name: 'undefined, undefined', args: [undefined, undefined], expected: true}, + {name: 'null, ""', args: [null, ""], expected: false}, + {name: 'null, 0', args: [null, 0], expected: false}, + {name: 'null, false', args: [null, false], expected: false}, + {name: 'undefined, ""', args: [undefined, ""], expected: false}, + {name: 'undefined, 0', args: [undefined, 0], expected: false}, + {name: 'undefined, false', args: [undefined, false], expected: false}, + {name: 'true, false', args: [true, false], expected: false}, + {name: 'true, true', args: [true, true], expected: true}, + {name: 'false, false', args: [false, false], expected: true}, + {name: '3, "3"', args: [3, "3"], expected: true}, + {name: 'true, 1', args: [true, 1], expected: true}, + {name: 'false, 0', args: [false, 0], expected: true}, + {name: 'true, " "', args: [true, " "], expected: false}, + {name: 'false, "', args: [false, ""], expected: true}, + {name: '0, ""', args: [0, ""], expected: true} + ]; + function loose_equality(a, b) { + return a == b; + } + run_tests(loose_equality, test_cases); +} +``` + +[TOP](#test-cases) + +--- + +## Exercises + +These exercises are a bit backwards, usually as a developer you will write complete test cases then make sure your code passes them. To complete these exercises you will be writing test cases that pass functions we give you. If a test case fails it's the the test case that is wrong, go back to that case and fix it. + +Writing test cases just happens to be the other best way to understand how code works. The first best way is to [rewrite it yourself](https://blog.codinghorror.com/when-understanding-means-rewriting/) like in the Implicit Coercion exercises. + +(test cases for these exercises should be limited to primitive types - Number, Boolean, String, Null, Undefined) + + +### strict equality + +```js +{ + const test_cases = [ + {name: '3, 3', args: [3, 3], expected: true}, + {name: '3, "3"', args: [3, "3"], expected: false}, + /* write 8 more passing test cases */ + ]; + function strict_equality(a, b) { + return a === b; + } + run_tests(strict_equality, test_cases); +} +``` + +[TOP](#test-cases) + +### typeof + +```js +{ + const test_cases = [ + {name: 'null', args: [null], expected: 'object'}, + {name: 'undefined', args: [undefined], expected: 'undefined'}, + /* write 6 more passing test cases */ + ]; + function _typeof(a) { + return typeof a; + } + run_tests(_typeof, test_cases); +} +``` + +[TOP](#test-cases) + +### Boolean + +```js +{ + const test_cases = [ + {name: 'null', args: [null], expected: false}, + {name: 'undefined', args: [undefined], expected: false}, + /* write 10 more passing test cases */ + ]; + function to_boolean(a) { + return Boolean(a); + } + run_tests(to_boolean, test_cases); +} +``` + +[TOP](#test-cases) + +### Number + +```js +{ + const test_cases = [ + {name: 'null', args: [null], expected: 0}, + {name: 'undefined', args: [undefined], expected: NaN}, + /* write 10 more passing test cases */ + ]; + function to_number(a) { + return Number(a); + } + run_tests(to_number, test_cases); +} +``` + +[TOP](#test-cases) + +### or + +[replication](https://github.com/janke-learning/truthiness#or-operator) +```js +{ + const test_cases = [ + {name: '1, 1', args: [1, 1], expected: 1}, + {name: '0, 1', args: [0, 1], expected: 1}, + {name: '1, 0', args: [1, 0], expected: 1}, + {name: '0, 0', args: [0, 0], expected: 0}, + /* write 10 more passing test cases */ + ]; + function or(a, b) { + return a || b; + } + run_tests(or, test_cases); +} +``` + +[TOP](#test-cases) + +### and + +[replication](https://github.com/janke-learning/truthiness#and-operator) +```js +{ + const test_cases = [ + {name: '1, 1', args: [1, 1], expected: 1}, + {name: '0, 1', args: [0, 1], expected: 0}, + {name: '1, 0', args: [1, 0], expected: 0}, + {name: '0, 0', args: [0, 0], expected: 0}, + /* write 10 more passing test cases */ + ]; + function and(a, b) { + return a && b; + } + run_tests(and, test_cases); +} +``` + +[TOP](#test-cases) + +### not + +[replication](https://github.com/janke-learning/truthiness#not-operator) +```js +{ + const test_cases = [ + {name: '1', args: [1], expected: false}, + {name: '0', args: [0], expected: true}, + /* write 10 more passing test cases */ + ]; + function not(a) { + return !a; + } + run_tests(not, test_cases); +} +``` + +[TOP](#test-cases) + +### ternary + +[replication](https://github.com/janke-learning/truthiness#not-operator) +```js +{ + const test_cases = [ + {name: '1, "x", "y"', args: [1, 'x', 'y'], expected: 'x'}, + {name: '0, "x", "y"', args: [0, 'x', 'y'], expected: 'y'}, + /* write 10 more passing test cases */ + ]; + function ternary(a, b, c) { + return a ? b : c ; + } + run_tests(ternary, test_cases); +} +``` + +[TOP](#test-cases) + + +### greater than + +rules for implicit coercion: +* If both operands are numbers, perform a numeric comparison. +* If both operands are strings, compare the [character codes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) for each. sort of like alphabetical order. +* If one operand is a number, convert the other operand to a number and perform a numeric comparison. +* careful of NaN and values that convert to NaN. +```js +{ + const test_cases = [ + {name: 'true, 0', args: [true, 0], expected: true}, + {name: 'true, 1', args: [true, 1], expected: false}, + {name: 'false, 0', args: [false, 0], expected: false}, + {name: 'false, 1', args: [false, 1], expected: false}, + /* write 4 more passing test cases with only strings */ + /* write 6 more passing test cases without NaN values */ + /* write 4 more passing test cases with NaN values */ + ]; + function greater_than(a, b) { + return a > b; + } + run_tests(greater_than, test_cases); +} +``` + +[TOP](#test-cases) + + +### less than + +rules for implicit coercion: +* If both operands are numbers, perform a numeric comparison. +* If both operands are strings, compare the [character codes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) for each. sort of like alphabetical order. +* If one operand is a number, convert the other operand to a number and perform a numeric comparison. +* careful of NaN and values that cast to NaN. +```js +{ + const test_cases = [ + {name: 'true, 0', args: [true, 0], expected: false}, + {name: 'true, 1', args: [true, 1], expected: false}, + {name: 'false, 0', args: [false, 0], expected: false}, + {name: 'false, 1', args: [false, 1], expected: true}, + /* write 4 more passing test cases with only strings */ + /* write 6 more passing test cases without NaN values*/ + /* write 4 more passing test cases with NaN values*/ + ]; + function less_than(a, b) { + return a < b; + } + run_tests(less_than, test_cases); +} +``` + +[TOP](#test-cases) + + + +### subtraction + +implicit coercion with all mathematical operators (except for +) is pretty simple: +* convert everything to a number, then do math on them +* be aware of NaN values! +```js +{ + const test_cases = [ + {name: 'true, 0', args: [true, 0], expected: 1}, + {name: 'true, 1', args: [true, 1], expected: 0}, + {name: 'false, 0', args: [false, 0], expected: 0}, + {name: 'false, 1', args: [false, 1], expected: -1}, + /* write 5 more passing test cases without NaN values*/ + /* write 5 more passing test cases with NaN values*/ + ]; + function subtraction(a, b) { + return a - b; + } + run_tests(subtraction, test_cases); +} +``` + +[TOP](#test-cases) + + + +--- + +## Resources + +* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators) +* [javascript.info](https://javascript.info/operators) + + + +[TOP](#test-cases) + +___ +___ +### Janke Learning diff --git a/week-3/jl-truthiness.md b/week-3/jl-truthiness.md index 0bb9fe1..7113881 100644 --- a/week-3/jl-truthiness.md +++ b/week-3/jl-truthiness.md @@ -1 +1,131 @@ > paste [this markdown of exercises](https://raw.githubusercontent.com/janke-learning/truthiness/master/README.md) into this file and complete the exercises! +# Truthiness + +Truthiness is relatively simple to understand. Does a value convert to _true_ or _false_ when cast to boolean? + +This repo covers several key language features who's behavior is dependant on the __truthiness__ of their arguments. + +### Index +* [determining truthiness](#determining-truthiness) +* [falsey values](#falsey-values) +* [operators of truhiness](./operators-of-truthiness.md) +* [statements of truhiness](./statements-of-truthiness.md) +* [resources](#resources) + +--- +--- + +## Determining Truthiness + + +Paste this in the console to learn about truthiness, or study it [on python tutor](http://www.pythontutor.com/live.html#code=const%20x%20%3D%20%3B%20//%20experiment%20with%20different%20values%20%0A%0Aconst%20coerced_to_bool%20%3D%20Boolean%28x%29%3B%0A%0Aconsole.log%28%22x%3A%20%22%20%2B%20typeof%20x%20%2B%20%22,%20%22%20%2B%20x%29%3B%0Aconsole.log%28%22coerced_to_bool%3A%20%22%20%2B%20typeof%20coerced_to_bool%20%2B%20%22,%20%22%20%2B%20coerced_to_bool%29%3B%0Aconsole.log%28coerced_to_bool%20%2B%20%22y%3A%20%22%20%2B%20typeof%20x%20%2B%20%22,%20%22%20%2B%20x%29%3B&cumulative=false&curInstr=9&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false): +```js +{ + const x = ; // experiment with different values + + const coerced_to_bool = Boolean(x); + + console.log("x: " + typeof x + ", " + x); + console.log("coerced_to_bool: " + typeof coerced_to_bool + ", " + coerced_to_bool); + console.log(coerced_to_bool + "y: " + typeof x + ", " + x); +}; +``` +values to try: +```js +a: true --> ? +a: false --> ? +a: 0 --> ? +a: 1 --> ? +a: null --> ? +a: undefined --> ? +a: '' --> ? +a: ' ' --> ? +a: 'tiil' --> ? +a: 2 --> ? +a: 345 --> ? +a: NaN --> ? +a: Infinity --> ? +a: -Infinity --> ? +a: -3 --> ? +a: -0.0 --> ? +``` + +--- + +## Falsey Values + +JavaScript has only 6 falsey primitive values. All other values are truthy. + +[on pytut](https://goo.gl/urDfWG) + +```js +{ + const x = ; + + const coerced_to_bool = Boolean(x); + + console.log("x: " + typeof x + ", " + x); + console.log("coerced_to_bool: " + typeof coerced_to_bool + ", " + coerced_to_bool); + console.log(coerced_to_bool + "y: " + typeof x + ", " + x); +}; +``` +the values: +```js +1: false --> ? + +2: null --> ? + +3: undefined --> ? + +4: '' --> ? +4: "" --> ? +4: `` --> ? + +5: NaN --> ? + +6: 0 --> ? +6: 0.0 --> ? +6: +0 --> ? +6: -0 --> ? +``` + + +[TOP](#truthiness) + +--- + + +## Resources + +__study tools__: +* [PythonTutor for JavaScript](http://www.pythontutor.com/live.html#code=&cumulative=false&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false) +* [the Parsonizer](https://janke-learning.github.io/parsonizer/) + +__helpful links__: +* pytut snippets: + * [truthy & falsey values](https://goo.gl/jBTLFD) + * [&& vs. ||](https://goo.gl/BBXea6) +* javascript.info + * [data types](https://javascript.info/types) + * [type conversions](https://javascript.info/type-conversions) + * [conditionals](https://javascript.info/ifelse) + * [logical operators](http://javascript.info/logical-operators) + * [loops](https://javascript.info/while-for) +* mdn: [logicals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators), [ternary](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) +* [truthiness & comparisons](https://dorey.github.io/JavaScript-Equality-Table/) - click on the "if()" tab for truthiness +* from __boolean by example__: + * [truthiness for the console](https://github.com/janke-learning/boolean-by-example/blob/master/README.md#truthiness) + * [&&, || for the console](https://github.com/janke-learning/boolean-by-example#and-or-operators) + * [! for the console](https://github.com/janke-learning/boolean-by-example#not) + * [live in devtools](https://janke-learning.github.io/boolean-by-example/) +* mdn: + * [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean) + * [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) + * [falsey](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) +* [a codepen](https://codepen.io/philipwalton/pen/nufrk) + +[TOP](#truthiness) + +___ +___ +### Janke Learning