From f32da5dc1231513cf43411bb5a4e5cf9c297e14a Mon Sep 17 00:00:00 2001 From: Thibaud Szymczak Date: Sun, 7 Aug 2022 14:28:55 +0200 Subject: [PATCH] Add answers to week 3 QA --- .../1-objects-and-arrays/traffic-light-1.js | 7 +- Week2/QA.md | 203 ++++++++++++++- Week3/QA-answers.md | 231 ++++++++++++++++++ .../1-traffic-light/traffic-light.js | 27 +- Week3/prep-exercises/2-experiments/index.js | 37 ++- 5 files changed, 484 insertions(+), 21 deletions(-) create mode 100644 Week3/QA-answers.md diff --git a/Week1/prep-exercises/1-objects-and-arrays/traffic-light-1.js b/Week1/prep-exercises/1-objects-and-arrays/traffic-light-1.js index 8db87fe..34d9cbc 100644 --- a/Week1/prep-exercises/1-objects-and-arrays/traffic-light-1.js +++ b/Week1/prep-exercises/1-objects-and-arrays/traffic-light-1.js @@ -1,10 +1,13 @@ -"use strict"; +'use strict'; /** * The `state` property says what the traffic light's state (i.e. colour) is at * that moment. */ + const trafficLight = { - state: "red", + state: 'red', }; +const trafficLightColour = 'red'; + const currentState = trafficLight.state; diff --git a/Week2/QA.md b/Week2/QA.md index 94fdec5..8ad65c8 100644 --- a/Week2/QA.md +++ b/Week2/QA.md @@ -1,10 +1,199 @@ -# Q & A Session +## Question -The first 2 weeks of JavaScript we do not have homework and we encourage students to follow all the material at their own pace. So students can ask questions about any week. Expect questions about: +what the difference between `if` and `switch`? And when should I use `if` ? and when should I use `switch` ? -- Basic JavaScript blocks (let/const, operators, loops, if/else, functions) -- The Debugger (both browser/vscode) and how to debug -- Naming conventions -- DRY principle +## Question -In these first weeks we want to get the students to create the right mental model for JavaScript constructs, so try to go back to basics as much as possible. However easy it comes to the mentors, this is the first time students encounter all the syntax of a programming language. So try to go slowly and use the debugger / [JSTutor](http://pythontutor.com/javascript.html#mode=edit) as much as possible. +what is the diffrence please ? + +```html + + + +``` + +### Answer + +[See the MDN documentation here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#usage_notes). Short answer: + +> Browsers don't all support the same video formats; you can provide multiple sources inside nested elements, and the browser will then use the first one it understands. + +## Question + +What is the difference between for and while loops ? + +## Question + +How can I clean the following text and find the most frequent word ? + +``` + const sentence = '%I $am@% a %tea@cher%, &and& I lo%#ve %te@a@ching%;. The@re $is no@th@ing; &as& mo@re rewarding as educa@ting &and& @emp%o@weri@ng peo@ple. ;I found tea@ching m%o@re interesting tha@n any ot#her %jo@bs. %Do@es thi%s mo@tiv#ate yo@u to be a tea@cher!? %Th#is 30#Days&OfJavaScript &is al@so $the $resu@lt of &love& of tea&ching' +``` + +### Answer + +[Answer here](https://codepen.io/thibaudszy/pen/BarpJKm?editors=0010). You can see the output of the console.logs in the browser console. +You can visualize the execution of this code [here](https://pythontutor.com/render.html#code=%20const%20sentence%20%3D%20'%25I%20%24am%40%25%20a%20%25tea%40cher%25,%20%26and%26%20I%20lo%25%23ve%20%25te%40a%40ching%25%3B.'%0A%20%0A%20const%20cleanSentence%20%3D%20sentence.replace%28/%5B%5EAa-zZ%7C%5Cs%5D/gi,%20''%29.toLowerCase%28%29%3B%0A%0Aconsole.log%28%7BcleanSentence%7D%29%3B%0A%0Aconst%20sentenceArray%20%3D%20cleanSentence.split%28'%20'%29%3B%0A%0Aconsole.log%28%7BsentenceArray%7D%29%0A%0Aconst%20repeatedWords%20%3D%20%7BmostCommonWord%3A%20null%7D%0A%0AsentenceArray.forEach%28word%20%3D%3E%20%7B%0A%20%20if%28repeatedWords%5Bword%5D%29%7B%0A%20%20%20%20repeatedWords%5Bword%5D%2B%3D1%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20repeatedWords%5Bword%5D%3D1%3B%0A%20%20%7D%0A%20%20%0A%20%20if%28!repeatedWords.mostCommonWord%29%7B%0A%20%20%20%20repeatedWords.mostCommonWord%20%3D%20word%3B%0A%20%20%20%20return%3B%0A%20%20%7D%20%0A%20%20if%28repeatedWords%5Bword%5D%20%3E%20repeatedWords%5BrepeatedWords.mostCommonWord%5D%29%7B%0A%20%20%20%20repeatedWords.mostCommonWord%20%3D%20word%3B%0A%20%20%7D%0A%7D%29%0Aconsole.log%28%20repeatedWords%29%0Aconsole.log%28'The%20most%20common%20word%20is%3A',%20repeatedWords.mostCommonWord%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D&textReferences=falsey). + +## Question + +What is pass-by-reference? and What are the differences between pass-by-value and pass-by-reference? + +### Answer + +View an example of both [here](https://pythontutor.com/render.html#code=//%20pass%20by%20value%0Aconst%20add%20%3D%20%28a,b%29%3D%3Ea%2Bb%3B%0Aconst%20myVar%20%3D%201%3B%0Aconst%20sum%20%3D%20add%28myVar,%201%29%3B%0A%0Aconsole.log%28'myVar%3A',%20myVar,%20'%3B%20sum%3A',%20sum%29%3B%0A%0A//%20pass%20by%20reference%0A%0Aconst%20addOneToFirstElement%20%3D%20%28arr%29%20%3D%3E%20%7B%0A%20%20arr%5B0%5D%20%3D%201%3B%0A%20%20return%20arr%3B%0A%7D%0A%0Aconst%20myArr%20%3D%20%5B0,%201,%202%5D%3B%0Aconst%20newArr%20%3D%20addOneToFirstElement%28myArr%29%3B%0Aconsole.log%28'myArr%3A',%20myArr,%20'%3B%20newArr%3A',%20newArr%29%3B&cumulative=false&curInstr=13&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false). + +Learn more in [this article](https://www.javascripttutorial.net/javascript-pass-by-value/#:~:text=JavaScript%20pass%2Dby%2Dvalue%20or%20pass%2Dby%2Dreference&text=It%20means%20that%20JavaScript%20copies,variables%20outside%20of%20the%20function.) + +**In short:** when passing a primitive value to a function, that value will be copied and any change to it's value will not affect the variable it passed to the function's arguments. When passing an object to a function, you are passing the reference of that object, not the actual object. Therefore, the function can modify the properties of the object via its reference. + +## Question + +The thing that confuses me is that the first output is as an array as it should be, but the second output is as a string. Why is this output not an array? + +```js +const myRecipe = { ingredients: ['4 eggs', '2 strips of bacon', '1 tsp salt/pepper'] }; + +console.log(myRecipe['ingredients']); + +//Output:[ '4 eggs', '2 strips of bacon', '1 tsp salt/pepper' ] + +for (let key in myRecipe) { + console.log(key + ': ' + myRecipe[key]); +} +//Output:ingredients: 4 eggs,2 strips of bacon,1 tsp salt/pepper +``` + +### Answer + +This is due to _type coercion_ when adding an array to a string. To do this, JS will convert the Array to a string using the [toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) method. You can learn more [here](https://github.com/weiqinl/You-Dont-Know-JS-CN/blob/master/types%20%26%20grammar/ch4.md#tostring). + +If you want to print: + +`ingredients: [ '4 eggs', '2 strips of bacon', '1 tsp salt/pepper' ]` + +you should use: + +```js +console.log(`${key}:`, myRecipe[key]); +``` + +## Question + +Can we use the `break`, `continue` and `label` statements with all loops types? and what the best usage for each ? + +## Question + +What is the difference between contains() and includes()? + +### Answer + +- `contains`: + + > The contains() method of the Node interface returns a boolean value indicating whether a node is a descendant of a given node, that is the node itself, one of its direct children (childNodes), one of the children's direct children, and so on. [learn more](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains) + + [What is a DOM node](https://dmitripavlutin.com/dom-node-element/) + + This method can only be used in the browser, as NodeJs does not have DOM nodes. + +- `includes`: + > The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate. [learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) + +## Question + +I have some questions about Prototype? What is a prototype of object and array and etc.? And how does it work? + +### Answer + +Prototypes are the mechanism by which JavaScript objects inherit features from one another. In this article, we explain what a prototype is, how prototype chains work, and how a prototype for an object can be set. + +[A good overview on MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes). + +Why do primitive values have methods like objects. Because of [autoboxing](https://dev.to/benjaminmock/do-you-know-what-autoboxing-in-js-is-enl). + +## Question + +what is the differences between are global scope and local scope ? + +## Question + +```js +const car = { + model: 'audi', + year: '2020', + gear: [1, 2, 3, 4, 5, 6], +}; +for (let feature in car) { + console.log(feature); +} +``` + + When I run this code I can see the output is: + + ``` + model + year + car + ``` + + When I write: + `console.log(feature.model)` + the result is `undefined`! + Also when I write : `console.log(feature.gear[0])` + It gives me error! + Why the first one's result is undefined and why it gives me error in second one? + Also can I access "audi" use "feature" in for loop instead car.model? + +### Answer + +The `for...in statement` iterates over all enumerable properties of an object that are keyed by strings (ignoring ones keyed by Symbols), including inherited enumerable properties. [learn more about `for...in`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in). + +As you can see from your `console.log`, `feature` will take the value of the properties of the Object, not the values. There isn't a way to directly iterate over the values of an object. However, you can access the car property using your iterator: + +```js +const car = { + model: 'audi', + year: '2020', + gear: [1, 2, 3, 4, 5, 6], +}; + +for (let feature in car) { + console.log(car[feature]); +} +``` + +## Question + +When I run this code const `a = [8]`; +const `b = [10]`; +`console.log(a < b);` the result is false + +### Answer + +This is because JS compares arrays and objects by _reference_ and not by value. The reference is the object's location in the heap. To compare the values of two arrays, you have to compare the primitive values that are contained within them. Which can be complicated depending on the structure of your array. + +## Question + +Why their outputs are different? + +```js +const arr = [1, 2, 3, 4, 5]; +delete arr[0]; +console.log(arr.length); + +//Output: 5; + +const arr = [1, 2, 3, 4, 5]; +arr.splice(0, 1); +console.log(arr.length); + +// Output: 4; +``` + +### Answer + +[Let's see the answer in JStutor](https://pythontutor.com/render.html#code=const%20arr1%20%3D%20%5B1,%202,%203,%204,%205%5D%3B%0Adelete%20arr1%5B0%5D%3B%0Aconsole.log%28arr1.length%29%3B%0A%0A//Output%3A%205%3B%0A%0Aconst%20arr2%20%3D%20%5B1,%202,%203,%204,%205%5D%3B%0Aarr2.splice%280,%201%29%3B%0Aconsole.log%28arr2.length%29%3B&cumulative=false&curInstr=6&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=js&rawInputLstJSON=%5B%5D&textReferences=false). + +Although you _can_ use `delete` on arrays, you should avoid it as it can lead to unexpected results. diff --git a/Week3/QA-answers.md b/Week3/QA-answers.md new file mode 100644 index 0000000..2bdf3a7 --- /dev/null +++ b/Week3/QA-answers.md @@ -0,0 +1,231 @@ +## Alex + +--- + +**For function getActiveClasses() I’ve made this solution first** + +```js +const getActiveClasses = () => { + const activeClasses = {}; + classes.forEach((instance) => { + if (instance.active) { + activeClasses[instance.name] = getPeopleOfClass(instance.name); + } + }); + return activeClasses; +}; +``` + +**but suddenly it doesn’t work, it return only one class instead of 3 as expected, so I’ve changed to** + +```js +const activeClasses = {}; +classes.forEach((instance) => { + if (instance.active) { + activeClasses[instance.name] = 1; + } +}); +for (let instance in activeClasses) { + activeClasses[instance] = getPeopleOfClass(instance); +} +return activeClasses; +``` + +and it works for me. So my question is: could someone explain me what I’ve done wrong? + +## Hikmet + +--- + +Hi, There are test-reports in the homework section of Week3. In the files, there is a warning:’This test has not been run.' How can we run this test? + +Go in the unit-tests directory and run: + +### Answer + +Run `npm run test` + +## Mohamed Belal + +--- + +"Is there any modern website made only with vanilla js without framework" is that possible ?, and if not how big websites like face book coded before inventing frameworks + +### Answer + +Booking is an example of a big, interactive website that works without a framework. Then it depends what yo mean by framework. A lot of websites are _server side generated_, meaning the html and css are created in the backend before being sent to the users. This is still done via frameworks, but they are not always JavaScript frameworks. In general, dynamic, interactive websites are often made with frameworks, static ones less so because it is not necessary. + +## Sultan + +--- + +What is the difference between named function and undefined function? +How to avoid from undefined value in function? + +## Answer + +Functions with no name are called anonymous functions. They work like regular functions but can't be reused. + +## Mohanad AL Hasan + +--- + +My question about `this` keyword , can I use this with all functions or just with functions as a method or property of an object? + +### Answer + +You can't use it in [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). + +In functions declared with the `function` keyword and when in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode), it depends how the function is called. + +## Nuha Saleh + +--- + +Is there any other way to check `if (something !== undefined)` inside function? + +### Answer + +Not if you only want to check if the value is specifically not `undefined`. However if you write `if(!something)`, this will check that the value is not [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) + +## Basheer Ghaleb + +--- + +is there any limits to use parameters in functions ?? + +### Answer + +Not really, but don't go crazy ;) + +## Mostafa Abdullah + +--- + +As I knew the arrow function has given to us by ECMAScript and it's a replacement of the regular function, but the question is if will compare them together which one is the easiest and the much used from the programmers? + +### Answer + +The arrow function is not a replacement but an alternative. Both have their advantages and disadvantages. From [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) + +> An arrow function expression is a compact alternative to a traditional function expression, but is limited and can't be used in all situations. + +I would say arrow functions are prefered to traditional functions when their limitations are not an issue. They also have the added benefit that when declared with the `const` keyword, they cannot be redeclared. + +## Basheer Ghaleb + +--- + +Is it necessary to specify let or const for a new variable inside a function? + +```js +const array = ['item1', 'item2']; +function addToArray(arr, items) { + newArray = [...array]; +} +``` + +## Elif + +--- + +Hi, how many nested functions can be used? Is there a limitation? + +### Answer + +Unless you start using [recursive functions](https://www.javascripttutorial.net/javascript-recursive-function/) (a function that calls itself), you won't run into this issue. + +The limit depends on the environment. From a [quick search](https://stackoverflow.com/questions/7826992/browser-javascript-stack-size-limit), modern versions of chrome allow more than 13'903 calls. If you exceed it, you will run into a stack overflow error. + +## Asiye Gokalp + +--- + +```js +const myFunc=function(num){ + return function toDouble(){ + console.log(num\*2); + } +} +console.log(myFunc(8)()); +``` + +The above function can be invoked using two double brackets. +Invoking with two double brackets did not work for the following function. +what's the reason? + +```js +function myName() { + const name = 'Melisa'; + console.log(name); + function sayHi() { + console.log('Hello!'); + } +} +myName()(); +``` + +### Answer + +That's because you are not returning the function in the second example. So the `sayHi` function will be destroyed once the `myName` function finishes being executed. + +## Badi + +--- + +What is module scope? + +Let's say you have two files: + +`index.js` + +```js +import getNumberPlusOne from `./getNumberPlusOne.js` + +console.log(getNumberPlusOne(5)); +``` + +`getNumberPlusOne.js` + +```js +const moduleScopeVariable = 1; + +export default (num) => num + moduleScopeVariable; +``` + +You are importing the function `getNumberPlusOne` in `index.js`, but for this function to run properly, it needs the value held in its module scope. However, even though you import the `getNumberPlusOne` module in `index.js`, you don't have access to the module's scoped variable outside of the `getNumberPlusOne` function. + +## yusuf demir + +--- + +Hello, + +```js +const sendCongratulationsMessage = (name) => { + console.log(`Congratulations ${name}, you passed the test. Well done!`); +}; + +const sendConsolidationMessage = (name) => { + console.log( + `Sorry ${name}, unfortunately you did not pass your test. Let's see what we can do to get you back on track` + ); +}; + +const sendResultMessage = (grade, ...rest) => { + if (grade < 6) { + sendConsolidationMessage(...rest); + } else { + sendCongratulationsMessage(...rest); + } +}; + +sendResultMessage(5, 'John'); +sendResultMessage(9, 'Deedee'); +``` + +In this example, we have one parameter which called "name" and this is not an array. Why a spread operator was used for only one parameter? + +## Answer + +Because it is in an array. Learn more about the [function argument's object here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments) diff --git a/Week3/prep-exercises/1-traffic-light/traffic-light.js b/Week3/prep-exercises/1-traffic-light/traffic-light.js index f4a5c1a..0be5ca1 100644 --- a/Week3/prep-exercises/1-traffic-light/traffic-light.js +++ b/Week3/prep-exercises/1-traffic-light/traffic-light.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; /** * The `trafficLight` object is now no longer a global variable. Instead, * it is defined in function `main()` and passed as a parameter to other @@ -6,17 +6,19 @@ */ function getCurrentState(trafficLight) { - // TODO - // Should return the current state (i.e. colour) of the `trafficLight` - // object passed as a parameter. + return trafficLight.possibleStates[trafficLight.stateIndex]; } function getNextStateIndex(trafficLight) { - // TODO - // Return the index of the next state of the `trafficLight` such that: - // - if the color is green, it will turn to orange - // - if the color is orange, it will turn to red - // - if the color is red, it will turn to green + // const { possibleStates, stateIndex } = trafficLight; + // return stateIndex < possibleStates.length - 1 ? stateIndex + 1 : 0; + + if (trafficLight.stateIndex < trafficLight.possibleStates.length - 1) { + trafficLight.stateIndex++; + } else { + trafficLight.stateIndex = 0; + } + return trafficLight.stateIndex; } // This function loops for the number of seconds specified by the `secs` @@ -33,15 +35,18 @@ function waitSync(secs) { function main() { const trafficLight = { - possibleStates: ["green", "orange", "red"], + possibleStates: ['green', 'orange', 'red'], stateIndex: 0, }; for (let cycle = 0; cycle < 6; cycle++) { const currentState = getCurrentState(trafficLight); - console.log(cycle, "The traffic light is now", currentState); + console.log(cycle, 'The traffic light is now', currentState); waitSync(1); // Wait a second before going to the next state + if (getNextStateIndex(trafficLight) === 0) { + console.log('resetting'); + } trafficLight.stateIndex = getNextStateIndex(trafficLight); } } diff --git a/Week3/prep-exercises/2-experiments/index.js b/Week3/prep-exercises/2-experiments/index.js index 7e5aa92..9cfa2cd 100644 --- a/Week3/prep-exercises/2-experiments/index.js +++ b/Week3/prep-exercises/2-experiments/index.js @@ -1,4 +1,20 @@ -"use strict"; +'use strict'; + +const generateRandomNumber = (min, max) => { + // Let's generate a random number between 0 and 1. For example 0.5532 + let num = Math.random(); + + // Multiply by the max value minus 1. Now the num value is a floating point number between the min value and max-1 + // For example, if max = 6: 3.3192000000000004 + num *= max - 1; + + // Add the min value to ensure this number is never less than it + // For example, if min = 1: 4.3192000000000004 + num += min; + + // Return the rounded value, in this example: 4 + return Math.round(num); +}; function runExperiment(sampleSize) { const valueCounts = [0, 0, 0, 0, 0, 0]; @@ -13,6 +29,14 @@ function runExperiment(sampleSize) { // for keeping a count how many times the value 1 is thrown, the second // element for value 2, etc. + for (let i = 0; i < sampleSize; i++) { + //This is what would be used in practice. Here I wrote down a step by step function to explain the process + // const randomNumber = Math.round(Math.random() * 5 + 1); + + const randomNumber = generateRandomNumber(1, 6); + valueCounts[randomNumber - 1] += 1; + } + const results = []; // TODO @@ -25,12 +49,23 @@ function runExperiment(sampleSize) { // two decimals, e.g. '14.60'. // 3. Then push that string onto the `results` array. + let i = 0; + + for (const count of valueCounts) { + results[i] = ((count * 100) / sampleSize).toFixed(2); + i++; + } + return results; } function main() { const sampleSizes = [100, 1000, 1000000]; + for (const size of sampleSizes) { + console.log(runExperiment(size), size); + } + // TODO // Write a for..of loop that calls the `runExperiment()` function for each // value of the `sampleSizes` array.