From 738f3a473fc1f9241b00ff30e48dc306503b04b4 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Sun, 18 Sep 2022 20:40:14 -0500 Subject: [PATCH 01/37] slides --- 2-slides.html | 8 +++++++- 3-slides.html | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/2-slides.html b/2-slides.html index d0b63d7..3efbfe6 100644 --- a/2-slides.html +++ b/2-slides.html @@ -23,7 +23,13 @@
- +
+ +
+
-
+
-
+
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
+
-
+
+
From 3a960688c950bcad998563c4d9043f23b1587771 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Sun, 18 Sep 2022 23:35:37 -0500 Subject: [PATCH 07/37] jsquiz --- 2-jsquiz-complete.html | 19 ++--- 2-jsquiz-starter.html | 175 +++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 3 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 2-jsquiz-starter.html diff --git a/2-jsquiz-complete.html b/2-jsquiz-complete.html index 2998c1e..301b003 100644 --- a/2-jsquiz-complete.html +++ b/2-jsquiz-complete.html @@ -75,7 +75,7 @@

Quiz.js

- + @@ -134,16 +134,18 @@

Quiz.js

let fact; - const optionButtons = document.getElementById("options").children; const explanation = document.getElementById("explanation"); const nextButton = document.getElementById("next-question"); + const optionButtons = document.getElementById("options").children; function getNextFact() { - fact = facts.shift(); // get the next fact in our array (shortening the array) + fact = facts.shift(); // get the first fact in our array (shortening the array) - // set the question text & clear any previous explanation + // set the question text to the current fact's statement document.getElementById("statement").textContent = fact.statement; - hide(document.getElementById("explanation")); + + // hide any previous explanation + hide(explanation); for (let option of optionButtons) { // clear any previous classes @@ -153,9 +155,8 @@

Quiz.js

enable(option); } - // disable & hide next-question button + // disable next-question button disable(nextButton); - hide(nextButton); } @@ -164,13 +165,13 @@

Quiz.js

for (let option of optionButtons) { option.addEventListener("click", e => { // When this option is clicked... - // disable all other option buttons + + // disable all the option buttons for (let button of optionButtons) { disable(button); } // enable the 'next question' button, if we still have facts left - show(nextButton); if (facts.length > 0) { enable(nextButton); } else { diff --git a/2-jsquiz-starter.html b/2-jsquiz-starter.html new file mode 100644 index 0000000..6a6fea7 --- /dev/null +++ b/2-jsquiz-starter.html @@ -0,0 +1,175 @@ + + + + + Quiz.js + + + +
+

Quiz.js

+

Do you know JS? Find out!

+
+ Score: 0 / 0 +
+
+ +
+
+ +
+
+ + +
+ + + +
+ + + + + diff --git a/README.md b/README.md index 037e3ac..9a9fa98 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Prerequisites: - Day 2 - 0930: Day 2 Intro & project overview - 1000: Working with a code editor - - 1030: Functions & Scope + - 1015: Functions & Scope - 1130: Event Handlers - 1200: Lunch - 1300: Conditionals From d659d79fa6f60090fbfe6993fa6752bfce5772f7 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Sun, 18 Sep 2022 23:42:51 -0500 Subject: [PATCH 08/37] slides --- 2-slides.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/2-slides.html b/2-slides.html index 0294d4c..4afd4ef 100644 --- a/2-slides.html +++ b/2-slides.html @@ -307,6 +307,9 @@
From 579d79344f4c3cafe4a078db3642f63473916b18 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Sun, 18 Sep 2022 23:51:49 -0500 Subject: [PATCH 09/37] slides --- 2-slides.html | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/2-slides.html b/2-slides.html index 4afd4ef..968a9a4 100644 --- a/2-slides.html +++ b/2-slides.html @@ -309,7 +309,7 @@ Gif from Schitt's Creek of David saying 'There are so many variables still in play' - +
@@ -318,6 +318,14 @@ Let's make our web page *interactive*! + -- + + +
From 4aedc56b90b0bd7236cfcdfda92af533bdcc7fc8 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Mon, 19 Sep 2022 00:22:41 -0500 Subject: [PATCH 10/37] fixes --- 1-slides.html | 111 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 35 deletions(-) diff --git a/1-slides.html b/1-slides.html index 7423268..494af91 100644 --- a/1-slides.html +++ b/1-slides.html @@ -236,25 +236,33 @@ -- - ### `document` + ```js + document + ```

the entire HTML document

-- - ### `document.title` + ```js + document.title + ```

the page (document) title

-- - ### `document.body` + ```js + document.body + ```

the body element

-- - ### `document.body.children` + ```js + document.body.children + ```

all the elements within the body

@@ -262,39 +270,45 @@ -- - #### `document.getElementById("board")` + ```js + document.getElementById("board") + ``` -

document.querySelector("#board")

+
document.querySelector("#board")

the (first) element with id="board"

-- - #### `document.getElementsByTagName("h1")` + ```js + document.getElementsByTagName("h1") + ``` -

document.querySelectorAll("h1")

+
 document.querySelectorAll("h1")

all the h1 elements

-- - #### `document.getElementsByClassName("player")` + ```js + document.getElementsByClassName("player") + ``` -

document.querySelectorAll(".player")

+
document.querySelectorAll(".player")

all the elements with class="player"

-- -

document.getElementsByClassName("player").length

+
document.getElementsByClassName("player").length
-

document.querySelectorAll(".player").length

+
 document.querySelectorAll(".player").length

the number of elements with class="player"

-- - document.getElementById("p1-name").textContent +
document.getElementById("p1-name").textContent

the text inside the element with id="p1-name"

@@ -331,21 +345,23 @@

document.querySelectorAll(".player").lengthchange the page title

note the double-quotes

-- - document.getElementById("p1-name").textContent = "Sofia" +
document.getElementById("p1-name").textContent = "Sofia"

replace the text of the #p1-name element

-- - document.getElementById("p1-name").append(" & friends") +
document.getElementById("p1-name").append(" & friends")

add to the end of the element's current text

@@ -425,8 +441,14 @@

document.querySelectorAll(".player").lengthcharacters

Variables let us **remember** values - ``` + ```js let remember = "Sept. 21"; ``` @@ -816,7 +838,7 @@

characters

Gif from 'The Office' of Michael Scott yelling 'I declare... bankruptcy!' - ``` + ```js let bankruptcy; ``` @@ -826,7 +848,7 @@

characters

### Assigning a variable - ``` + ```js let myDeclaredVariable; myDeclaredVariable = "so value, much wow"; ``` @@ -835,7 +857,7 @@

characters

### Declaring & assigning at once - ``` + ```js let myAssignedVariable = "such efficient, amaze"; ``` @@ -847,7 +869,7 @@

characters

aka a variable that can't be changed - ``` + ```js const myUnchangeableVariable = "Never gonna give you up"; ``` @@ -910,7 +932,7 @@

characters

What happens when this code runs? - ``` + ```js let answerToLife = ((4 + 1) * 2 * 4) + 2; ``` @@ -990,7 +1012,7 @@

characters

Arrays let us keep multiple values together in a single collection - ``` + ```js let synonyms = ["plethora", "array", "cornucopia"]; ``` @@ -1056,11 +1078,15 @@

characters

What do you think each of these does? (Try it!) - `["c", "a", "d", "b"].sort()` + ```js + ["c", "a", "d", "b"].sort() + ``` - ["lions", "tigers", "bears oh my!"].join(" & ") +
["lions", "tigers", "bears oh my!"].join(" & ")
- `[1, 2, 3].concat([4, 5, 6])` + ```js + [1, 2, 3].concat([4, 5, 6]) + ``` -- @@ -1086,11 +1112,13 @@

characters

```js let abcArray = ["a", "b", "c"]; abcArray[1] = "d"; + abcArray; ``` ```js let abcString = "abc"; abcString[1] = "d"; + abcString; ``` -- @@ -1108,11 +1136,13 @@

characters

```js let numbers1 = [1, 2, 3]; let result1 = numbers1.push(4); + numbers1; ``` ```js let numbers2 = [1, 2, 3]; let result2 = numbers2.concat([4]); + numbers2; ``` -- @@ -1139,7 +1169,7 @@

characters

```js const constVariable = "original value"; constVariable = "new Value"; - + ``` -- @@ -1196,17 +1226,27 @@

characters

### Getting property values - `js.name` + ```js + js.name + ``` + + + ```js + js.isAwesome + ``` - `js.isAwesome` -- ### Using property values - `js.name.startsWith("Java")` + ```js + js.name.startsWith("Java") + ``` - `let age = 2022 - js.birthYear;` + ```js + let age = 2022 - js.birthYear; + ``` -- @@ -1221,7 +1261,7 @@

characters

indecisive.snack = "chips"; ``` - --- + -- ### Exercise @@ -1240,7 +1280,7 @@

characters

}; ``` - --- + -- ### Nested objects @@ -1355,6 +1395,7 @@

characters

console.log(hello.length); const yello = hello.toUpperCase(); ``` + [✨MDN✨ JS > Standard built-in objects > String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) -- From 373a2a71bd54447f3e05d6bd1dcbf97c9d935922 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Mon, 19 Sep 2022 17:42:45 -0500 Subject: [PATCH 11/37] merge fix --- 1-slides.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-slides.html b/1-slides.html index 494af91..cabd775 100644 --- a/1-slides.html +++ b/1-slides.html @@ -538,7 +538,7 @@ - `false` - `"true"` - `document.title` - - `document.getElementById("board").children.length` + - `"some string".length` - `null` (guess first, then use `typeof` to check!) From f3b6dfb27d481f4a74f8a5d302df6b856058c594 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Mon, 19 Sep 2022 19:15:46 -0500 Subject: [PATCH 12/37] slides --- 2-slides.html | 540 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 537 insertions(+), 3 deletions(-) diff --git a/2-slides.html b/2-slides.html index 968a9a4..1b5c6ad 100644 --- a/2-slides.html +++ b/2-slides.html @@ -30,6 +30,436 @@ [anjana.dev/javascript-first-steps](https://anjana.dev/javascript-first-steps)
+
+ +
+
+ +
+ +
+ +
+
+ +
@@ -310,6 +740,105 @@ Gif from Schitt's Creek of David saying 'There are so many variables still in play' + -- + + In JS it doesn't just matter *what* variables we declare + + It also matters *where* we declare them + + *Scope* determines where variables are "in play" + + -- + + + + ```js + + function declareBankruptcy() { + let bankruptcy = true; + } + + declareBankruptcy(); + console.log(bankruptcy); + + ``` + -- + + Scopes are *nested* within the program + + The widest scope is the **global** scope + + Each function gets its own new scope within the scope where it was declared + + + + -- + + + ```js + + let planet = "Jupiter"; + + function scopeOut() { + let planet = "Mars"; + console.log("Inner planet:", planet); + } + + scopeOut(); + console.log("Outer planet:", planet); + + ``` + + + + -- + + Within each scope, you can access variables declared in a *wider* scope (e.g. global scope) + + But not those declared in a *narrower* scope (e.g. function scope) + + + -- + + ```js + + let globalVariable = "I live in global scope"; + + function narrowerScope() { + console.log(globalVariable); + let localVariable = "I live in the function scope"; + } + + narrowerScope(); + console.log(localVariable); + + ``` + + + + -- + + Variables declared with `let` can be modified from within a narrower scope + + This can be useful, but also dangerous! + + -- + + ```js + let feeling = "free"; + + function trap() { + feeling = "boxedIn"; + } + + trap(); + console.log(feeling); + + ``` + + + +
@@ -327,6 +856,11 @@ + + -- + + +
@@ -723,13 +724,105 @@ - `yell`: given a lowercase string, log it in all caps to the console - `longerThan`: given 2 arrays, return whether the first is longer than the second + -- + + ## Arrow functions + + Gif of Katniss Everdeen drawing a bow + + -- + + The `=>` "fat arrow" lets us create an unnamed function without much code + + ```js + (x, y) => x + y + ``` + + aka an *arrow function* + + -- + + Since arrow functions are expressions, we can assign them to a variable + + ```js + const add = (x, y) => x + y; + ``` + + is equivalent to + + ```js + function add(x, y) { + return x + y; + } + ``` + + -- + + Arrow functions are great when we just want to return a value + + ```js + function square(x) { + return x*x; + } + ``` + + vs. + + ```js + const square = (x) => x*x; + ``` + + -- + + For one-parameter functions, parentheses are optional + + ```js + x => x*x + ``` + ```js + (x) => x*x + ``` + -- + + For multiple parameters, parentheses are required + + ```js + (firstName, lastName) => firstName + " " + lastName + ``` + + -- + + If we need to do more than just return a value, + + we can use curly braces for a "normal" function body + + In that case, we still need a `return` + + ```js + const addAndLog = (x, y) => { + let sum = x + y; + console.log('The sum is', sum); + return sum; + } + ``` + + -- + + ### Exercise + + In the console, declare the following functions *using arrow functions*: + - `divide`: given 2 numbers, return the first divided by the second + - `whisper`: given an uppercase string, log it in all lowercase to the console + - `shorterThan`: given 2 arrays, return whether the first is shorter than the second + + -- ### Exercise - In the JSQuiz starter, follow the next TODOs to: - - Fill in the `hide` and `show` functions - - Declare the functions called `disable` and `enable` + In the JSQuiz starter, follow TODOs 4 & 5 to + - declare functions to disable or enable a button + - declare `isCorrect(guess)` function that compares a guess string to your fact's answer string @@ -849,6 +942,20 @@ -- + Our page right now... + + Gif of MC Hammer dancing with text 'cant touch this' + + -- + + The web browser fires *events* when certain things happen on the page + + For example, when the user clicks somewhere on the page, a `click` event is fired + + -- + + + - -- + JS passes an `event` object to the handler function with information about the event + If we accept this as a parameter, we can use it to get details + + + ```js + document.addEventListener("click", (event) => { + console.log(event); + }); + ``` + + + -- + + `event.target` is the element the event fired on + + (in this case, which element was clicked) + + ```js + document.addEventListener("click", (event) => { + console.log(event.target); + }); + ``` + -- + + ["click"](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event) isn't the only type of event we can handle + + - ["dblclick"](https://developer.mozilla.org/en-US/docs/Web/API/Element/dblclick_event) + - ["mouseover"](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseover_event) + - ["mouseout"](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseout_event) + + ...and *lots* [more](https://developer.mozilla.org/en-US/docs/Web/Events)! + + -- + + ### Exercise + + In the console, on our quiz add event listeners to: + - Capitalize the text of the "true" button when it is clicked + - Change the `h1` text to "hovering" when the mouse moves into the element + - Change the `h1` text to "Quiz.js" when the mouse moves out of the element + + -- + + Gif from Scandal of Kerry Washington saying 'It's handled' + + + +
@@ -1090,9 +1249,162 @@ + +
+
- From 4c12fec1a5c0bef58df3d7c8c09a130b59b6dc48 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 00:34:23 -0500 Subject: [PATCH 18/37] jsquiz --- 2-jsquiz-starter.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/2-jsquiz-starter.html b/2-jsquiz-starter.html index deaeb11..ce5c87c 100644 --- a/2-jsquiz-starter.html +++ b/2-jsquiz-starter.html @@ -106,14 +106,14 @@

Quiz.js

// TODO 6A: Use a for loop to add a click event listener to each of the optionButtons - // TODO 6B: Within the event listener function, display the fact's explanation by setting the text of the explanation element + // TODO 6B: Within the event handler function, display the fact's explanation by setting the text of the explanation element - // TODO 7: Within the event listener function, + // TODO 7: Within the event handler function, // Use a for loop to disable all the option buttons - // TODO 8: Within the event listener function, + // TODO 8: Within the event handler function, // Get the guessed value from the clicked button // Use a conditional to compare the guess to the fact's answer // and add the "correct"/"incorrect" class as appropriate From e4d94c702c8b869b93a6c2f91a8943ea42a5666b Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 00:43:55 -0500 Subject: [PATCH 19/37] slides --- 2-slides.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/2-slides.html b/2-slides.html index f3e8714..be36e63 100644 --- a/2-slides.html +++ b/2-slides.html @@ -1402,6 +1402,11 @@ TODO 8: - Use a conditional to compare the guessed value to the real answer and add the appropriate class to the clicked button + -- + + ### Great job!! + + Gif from Schitt's Creek of David saying 'Look at you go' From 1e5be0af09b2fcd9adbda7fca7dac02e8958f008 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 00:48:59 -0500 Subject: [PATCH 20/37] jsquiz --- 2-jsquiz-complete.html | 147 --------------- 2-jsquiz-8.html => 2-jsquiz-finished.html | 0 2-jsquiz-multi.html | 206 ++++++++++++++++++++++ 3 files changed, 206 insertions(+), 147 deletions(-) delete mode 100644 2-jsquiz-complete.html rename 2-jsquiz-8.html => 2-jsquiz-finished.html (100%) create mode 100644 2-jsquiz-multi.html diff --git a/2-jsquiz-complete.html b/2-jsquiz-complete.html deleted file mode 100644 index 6f3ea53..0000000 --- a/2-jsquiz-complete.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Quiz.js - - - -
-

Quiz.js

-

Do you know JS? Find out!

-
- -
-
- -
- -
- - -
- -
- -
- -
- - - - - diff --git a/2-jsquiz-8.html b/2-jsquiz-finished.html similarity index 100% rename from 2-jsquiz-8.html rename to 2-jsquiz-finished.html diff --git a/2-jsquiz-multi.html b/2-jsquiz-multi.html new file mode 100644 index 0000000..301b003 --- /dev/null +++ b/2-jsquiz-multi.html @@ -0,0 +1,206 @@ + + + + + Quiz.js + + + +
+

Quiz.js

+

Do you know JS? Find out!

+
+ Score: 0 / 0 +
+
+ +
+
+ +
+
+ + +
+ + + +
+ + + + + From 4850727210b52c4a1c65a5c42338b60d1d8962c0 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 08:29:32 -0500 Subject: [PATCH 21/37] jsquiz --- 2-jsquiz-multi.html => 2-jsquiz-fancy.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename 2-jsquiz-multi.html => 2-jsquiz-fancy.html (99%) diff --git a/2-jsquiz-multi.html b/2-jsquiz-fancy.html similarity index 99% rename from 2-jsquiz-multi.html rename to 2-jsquiz-fancy.html index 301b003..3a05346 100644 --- a/2-jsquiz-multi.html +++ b/2-jsquiz-fancy.html @@ -87,7 +87,7 @@

Quiz.js

{ "statement": "JavaScript was invented in 1995", "answer": "true", - "explanation": "Brendan Eich created JS at Netscape in 1995. The initial version of the language was written in just10 days." + "explanation": "Brendan Eich created JS at Netscape in 1995. The initial version of the language was written in just 10 days." }, { "statement": "Strings in JS are editable values", From cfed1aa5f40bcee882a2fef70ef948fc8806d7c0 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 08:31:09 -0500 Subject: [PATCH 22/37] jsquiz --- 2-jsquiz-1.html => jsquiz-wip/2-jsquiz-1.html | 0 2-jsquiz-2.html => jsquiz-wip/2-jsquiz-2.html | 0 2-jsquiz-3.html => jsquiz-wip/2-jsquiz-3.html | 0 2-jsquiz-4.html => jsquiz-wip/2-jsquiz-4.html | 0 2-jsquiz-5.html => jsquiz-wip/2-jsquiz-5.html | 0 2-jsquiz-6.html => jsquiz-wip/2-jsquiz-6.html | 0 2-jsquiz-7.html => jsquiz-wip/2-jsquiz-7.html | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename 2-jsquiz-1.html => jsquiz-wip/2-jsquiz-1.html (100%) rename 2-jsquiz-2.html => jsquiz-wip/2-jsquiz-2.html (100%) rename 2-jsquiz-3.html => jsquiz-wip/2-jsquiz-3.html (100%) rename 2-jsquiz-4.html => jsquiz-wip/2-jsquiz-4.html (100%) rename 2-jsquiz-5.html => jsquiz-wip/2-jsquiz-5.html (100%) rename 2-jsquiz-6.html => jsquiz-wip/2-jsquiz-6.html (100%) rename 2-jsquiz-7.html => jsquiz-wip/2-jsquiz-7.html (100%) diff --git a/2-jsquiz-1.html b/jsquiz-wip/2-jsquiz-1.html similarity index 100% rename from 2-jsquiz-1.html rename to jsquiz-wip/2-jsquiz-1.html diff --git a/2-jsquiz-2.html b/jsquiz-wip/2-jsquiz-2.html similarity index 100% rename from 2-jsquiz-2.html rename to jsquiz-wip/2-jsquiz-2.html diff --git a/2-jsquiz-3.html b/jsquiz-wip/2-jsquiz-3.html similarity index 100% rename from 2-jsquiz-3.html rename to jsquiz-wip/2-jsquiz-3.html diff --git a/2-jsquiz-4.html b/jsquiz-wip/2-jsquiz-4.html similarity index 100% rename from 2-jsquiz-4.html rename to jsquiz-wip/2-jsquiz-4.html diff --git a/2-jsquiz-5.html b/jsquiz-wip/2-jsquiz-5.html similarity index 100% rename from 2-jsquiz-5.html rename to jsquiz-wip/2-jsquiz-5.html diff --git a/2-jsquiz-6.html b/jsquiz-wip/2-jsquiz-6.html similarity index 100% rename from 2-jsquiz-6.html rename to jsquiz-wip/2-jsquiz-6.html diff --git a/2-jsquiz-7.html b/jsquiz-wip/2-jsquiz-7.html similarity index 100% rename from 2-jsquiz-7.html rename to jsquiz-wip/2-jsquiz-7.html From bb5012e1bd4c15ca7cc9425100192d3b993c5de8 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 08:31:47 -0500 Subject: [PATCH 23/37] readme --- README.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 9a9fa98..96377b8 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ Contents: - Day 1: - [Slides](./1-slides.html) - [Tic Tac Toe](./1-tictactoe.html) -- Day 2: *No spoilers!* - - Slides - - JS Quiz +- Day 2: + - [Slides](./2-slides.html) + - JS Quiz ([starter](./2-jsquiz-starter.html), [finished](./2-jsquiz-finished.html), [fancy](./2-jsquiz-fancy)) - Day 3: *No spoilers!* - Slides - Doggo Fetch @@ -53,27 +53,26 @@ Prerequisites: - 1000: JavaScript: What? Why? How? - 1015: Working with the DOM (HTML) - 1115: Data Types - - 1130: Working with Strings - 1200: Lunch - - 1300: Operators & Expressions - - 1330: Variables - - 1400: Working with Objects & Arrays - - 1530: Day 1 project review + - 1300: Working with Strings + - 1330: Operators & Expressions + - 1500: Variables - 1600: End of Day 1 - Day 2 - - 0930: Day 2 Intro & project overview - - 1000: Working with a code editor - - 1015: Functions & Scope - - 1130: Event Handlers + - 0930: Working with Objects & Arrays + - 1100: Day 1 project review + - 1130: Day 2 project overview + - 1145: Working with a code editor - 1200: Lunch - - 1300: Conditionals - - 1330: Loops - - 1430: Map & Filter - - 1530: Day 2 project review + - 1300: Functions & Scope + - 1415: Event Handlers + - 1500: Conditionals + - 1530: Loops - 1600: End of Day 2 - Day 3 - 0930: Day 3 Intro & project overview - 1000: Fetch, Promises, Async/Await + - 1100: Map & Filter - 1130: Destructuring & spread syntax - 1200: Lunch - 1300: Debugging & error handling From 2860b10f0e081df39decdd7e5c67d8e9155966f2 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 08:32:16 -0500 Subject: [PATCH 24/37] fetch --- 3-doggofetch.html | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/3-doggofetch.html b/3-doggofetch.html index 459b25e..dcd6c19 100644 --- a/3-doggofetch.html +++ b/3-doggofetch.html @@ -79,6 +79,17 @@

Guess the Doggo

const breedsEndpoint = "https://dog.ceo/api/breeds/list/all"; const randomImgEndpoint = "https://dog.ceo/api/breeds/image/random"; + + function getRandomElement(array) { + const i = Math.floor(Math.random() * array.length); + return array[i]; + } + + function shuffleArray(array) { + // randomly shuffles elements in an array in-place + return array.sort((a,b) => Math.random() - 0.5); + } + async function fetchMessage(url) { // Fetch the resource at the given URL, parse & return the "message" property of its body @@ -115,17 +126,7 @@

Guess the Doggo

return `${subtype ? subtype + " " : ""}${breed}`; } - - function getRandomElement(array) { - const i = Math.floor(Math.random() * array.length); - return array[i]; - } - - function shuffleArray(array) { - // randomly shuffles elements in an array in-place - return array.sort((a,b) => Math.random() - 0.5); - } - + function getChoices(n, correctAnswer, array) { // Generate a list of n choices including the correct answer and others from the array const choices = [correctAnswer]; From 61621385b8591794be5e35fb090eeab7ae1bfc53 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 17:02:52 -0500 Subject: [PATCH 25/37] merge slides fixes --- 2-slides.html | 89 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/2-slides.html b/2-slides.html index be36e63..d8c56b7 100644 --- a/2-slides.html +++ b/2-slides.html @@ -30,6 +30,34 @@ [anjana.dev/javascript-first-steps](https://anjana.dev/javascript-first-steps) +
+ +
+
+ +
+
+ +
-
- -
+
-
-
- -
-
-
+
+
@@ -69,29 +217,153 @@ + +
From e789de40c2d9519f9aeed4f02addb88e6e7d6310 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 20 Sep 2022 21:41:42 -0500 Subject: [PATCH 31/37] doggos --- ...tch-new.html => 3-doggofetch-finished.html | 0 3-doggofetch-old.html | 200 ----------------- 3-doggofetch-starter.html | 202 ++++++++++++++++++ 3 files changed, 202 insertions(+), 200 deletions(-) rename 3-doggofetch-new.html => 3-doggofetch-finished.html (100%) delete mode 100644 3-doggofetch-old.html create mode 100644 3-doggofetch-starter.html diff --git a/3-doggofetch-new.html b/3-doggofetch-finished.html similarity index 100% rename from 3-doggofetch-new.html rename to 3-doggofetch-finished.html diff --git a/3-doggofetch-old.html b/3-doggofetch-old.html deleted file mode 100644 index dcd6c19..0000000 --- a/3-doggofetch-old.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - Doggo Fetch - - - -
-

Guess the Doggo

-

What breed is the dog in this image?

- -
- -
-
- Fetching doggo... -
-
-
- -
- - - - - - - - - diff --git a/3-doggofetch-starter.html b/3-doggofetch-starter.html new file mode 100644 index 0000000..c04624b --- /dev/null +++ b/3-doggofetch-starter.html @@ -0,0 +1,202 @@ + + + + + Doggo Fetch + + + +
+

Guess the Doggo

+

What breed is the dog in this image?

+ +
+ +
+
+
+
+
+ +
+ + + + + + From 737827ec4b27231135169966b158e7674ce097e7 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Wed, 21 Sep 2022 01:09:59 -0500 Subject: [PATCH 32/37] slides --- 2-slides.html | 364 +++++++++++++++++++++++++++----------------------- 3-slides.html | 338 +++++++++++++++++++++++++++++++--------------- 2 files changed, 425 insertions(+), 277 deletions(-) diff --git a/2-slides.html b/2-slides.html index 5dae3f0..ef8c4e4 100644 --- a/2-slides.html +++ b/2-slides.html @@ -1079,10 +1079,9 @@ ### Exercise - In the console, on our quiz add event listeners to: - - Capitalize the text of the "true" button when it is clicked - - Change the `h1` text to "hovering" when the mouse moves into the element - - Change the `h1` text to "Quiz.js" when the mouse moves out of the element + In the console, on our quiz add event listeners to the buttons so that: + - When the "true" button is clicked, the button's text becomes "clicked true" + - When the "false" button is clicked, the "explanation" div text becomes "clicked false" -- @@ -1090,6 +1089,194 @@ + + + +
+
@@ -1274,178 +1461,23 @@ mood = "sad"; } ``` - -- ### Exercise - - In the console: - - Assign two variables `iLikeDogs` and `iLikeCats` to describe your feelings about them - - Use a logical operator to assign a variable `iLikeBoth` based on the values of the first 2 - - Use a ternary operator to assign a variable `bark` whose value is either `"woof"` if you like dogs, or `"shh"` if you don't - - -
-
-
-
-
- +
+
+
@@ -121,6 +99,8 @@ @@ -243,34 +242,11 @@ JS adds the task to the TODO list and keeps running our program - Gif of Spice Girls singing 'Stop' + Gif from Friends of Joey saying 'I wanna gooooo' But our program needs the data, we want JS to stop and wait for the Promise to resolve - - @@ -278,13 +254,13 @@
-
-
-
+
+
+
+
@@ -502,11 +561,54 @@ Gif from Clueless of Cher standing in front of a chalkboard saying 'I was like totally buggin' + -- + + A certainty of coding (especially in JS): + + Gif of Rachael Kay Albers saying 'Spectacular failure is part of the game' + + Stuff. Will. Go. Wrong! + + -- + + `console.log()` (or `.warn()` or `.error()`) is one way to understand what's happening when your program runs + + ```js + function whyIsntThisWorking(input) { + console.log("Well at least we got this far"); + console.log(input); + return thingThatDoesntWork(input); + } + ``` + + -- + + You can also use the browser's debugger to *pause* JS and inspect what's happening + + ```js + function whyIsntThisWorking(input) { + debugger; + return thingThatDoesntWork(input); + } + ``` + + The `debugger` statement creates a *breakpoint* where JS will pause and let you look around + + -- + + Different browsers' debuggers work differently + + - [Firefox](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools#the_javascript_debugger) + - [Chrome](https://developer.chrome.com/docs/devtools/javascript/) + - [Safari](https://support.apple.com/guide/safari-developer/debugging-overview-devd24689f72/mac) +
From 6844c5761559f1511bae04adeff5d660821bdeb1 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Wed, 21 Sep 2022 01:44:43 -0500 Subject: [PATCH 34/37] doggos --- 3-doggofetch-finished.html | 56 ++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/3-doggofetch-finished.html b/3-doggofetch-finished.html index c04624b..706a2b0 100644 --- a/3-doggofetch-finished.html +++ b/3-doggofetch-finished.html @@ -77,37 +77,25 @@

Guess the Doggo

const BREEDS = ["affenpinscher", "african", "airedale", "akita", "appenzeller", "shepherd australian", "basenji", "beagle", "bluetick", "borzoi", "bouvier", "boxer", "brabancon", "briard", "norwegian buhund", "boston bulldog", "english bulldog", "french bulldog", "staffordshire bullterrier", "australian cattledog", "chihuahua", "chow", "clumber", "cockapoo", "border collie", "coonhound", "cardigan corgi", "cotondetulear", "dachshund", "dalmatian", "great dane", "scottish deerhound", "dhole", "dingo", "doberman", "norwegian elkhound", "entlebucher", "eskimo", "lapphund finnish", "bichon frise", "germanshepherd", "italian greyhound", "groenendael", "havanese", "afghan hound", "basset hound", "blood hound", "english hound", "ibizan hound", "plott hound", "walker hound", "husky", "keeshond", "kelpie", "komondor", "kuvasz", "labradoodle", "labrador", "leonberg", "lhasa", "malamute", "malinois", "maltese", "bull mastiff", "english mastiff", "tibetan mastiff", "mexicanhairless", "mix", "bernese mountain", "swiss mountain", "newfoundland", "otterhound", "caucasian ovcharka", "papillon", "pekinese", "pembroke", "miniature pinscher", "pitbull", "german pointer", "germanlonghair pointer", "pomeranian", "medium poodle", "miniature poodle", "standard poodle", "toy poodle", "pug", "puggle", "pyrenees", "redbone", "chesapeake retriever", "curly retriever", "flatcoated retriever", "golden retriever", "rhodesian ridgeback", "rottweiler", "saluki", "samoyed", "schipperke", "giant schnauzer", "miniature schnauzer", "english setter", "gordon setter", "irish setter", "sharpei", "english sheepdog", "shetland sheepdog", "shiba", "shihtzu", "blenheim spaniel", "brittany spaniel", "cocker spaniel", "irish spaniel", "japanese spaniel", "sussex spaniel", "welsh spaniel", "english springer", "stbernard", "american terrier", "australian terrier", "bedlington terrier", "border terrier", "cairn terrier", "dandie terrier", "fox terrier", "irish terrier", "kerryblue terrier", "lakeland terrier", "norfolk terrier", "norwich terrier", "patterdale terrier", "russell terrier", "scottish terrier", "sealyham terrier", "silky terrier", "tibetan terrier", "toy terrier", "welsh terrier", "westhighland terrier", "wheaten terrier", "yorkshire terrier", "tervuren", "vizsla", "spanish waterdog", "weimaraner", "whippet", "irish wolfhound"]; - // TODO 1 - // Given an array, return a randomly selected value from the array - // (this should NOT modify the original array) + // Utility function to get a randomly selected item from an array function getRandomElement(array) { const i = Math.floor(Math.random() * array.length); return array[i]; } - // TODO 2 - // Given an array, shuffle the order of its elements in-place - // (this SHOULD modify the original array) + // Utility function to shuffle the order of items in an array in-place function shuffleArray(array) { return array.sort((a,b) => Math.random() - 0.5); } - // TODO 3 - // Given a URL such as "https://images.dog.ceo/breeds/poodle-standard/n02113799_2280.jpg" - // return the breed name string as formatted in the breed list, e.g. "standard poodle" - function getBreedFromURL(url) { - const path = url.replace("https://images.dog.ceo/breeds/", ""); - const breedID = path.split("/")[0]; - const [breed, subtype] = breedID.split("-"); - return `${subtype ? subtype + " " : ""}${breed}`; - } - - // TODO 4 + // TODO 1 // Given an array of possible answers, a correct answer value, and a number of choices to get, // return a list of that many choices, including the correct answer and others from the array function getMultipleChoices(n, correctAnswer, array) { + // Use a while loop and the getRandomElement() function + // Make sure there are no duplicates in the array const choices = [correctAnswer]; while (choices.length < n) { let candidate = getRandomElement(array); @@ -118,20 +106,33 @@

Guess the Doggo

return shuffleArray(choices); } + + // TODO 2 + // Given a URL such as "https://images.dog.ceo/breeds/poodle-standard/n02113799_2280.jpg" + // return the breed name string as formatted in the breed list, e.g. "standard poodle" + function getBreedFromURL(url) { + // The string method .split(char) may come in handy + // Try to use destructuring as much as you can + const [,path] = url.split("/breeds/"); + const [breedID] = path.split("/"); + const [breed, subtype] = breedID.split("-"); + // return `${subtype ? subtype + " " : ""}${breed}`; + return [subtype, breed].join(" "); + } - // TODO 5 + + + // TODO 3 // Given a URL, fetch the resource at that URL, // then parse the response as a JSON object, // finally return the "message" property of its body async function fetchMessage(url) { const response = await fetch(url); // Fetch the resource at the given URL - const json = await response.json(); // Parse the response as JSON - const {message} = json; // Extract the value of the "message" property + const {message} = await response.json(); // Parse the response as JSON & remember its 'message' value return message; // Return the message } - // Function to add the multiple-choice buttons to the page function renderButtons(choicesArray, correctAnswer) { @@ -148,7 +149,7 @@

Guess the Doggo

const options = document.getElementById("options"); // Container for the multiple-choice buttons - // TODO 6 + // TODO 4 // For each of the choices in choicesArray, // Create a button element whose name, value, and textContent properties are the value of that choice, // attach a "click" event listener with the buttonHandler function, @@ -168,10 +169,6 @@

Guess the Doggo

image.setAttribute("src", imgUrl); const frame = document.getElementById("image-frame"); - // TODO 7 - // Attach an event listener to the "load" event on the image element, and in the handler function, - // replace any existing children elements of the frame element with the image element, - // then call renderButtons() with the choices and correctAnswer image.addEventListener("load", () => { // Wait until the image has finished loading before trying to add elements to the page frame.replaceChildren(image); @@ -191,10 +188,11 @@

Guess the Doggo

return [doggoImgUrl, correctBreed, breedChoices]; } - // TODO 8 + // TODO 5 // Asynchronously call the loadQuizData() function, - // Then call renderQuiz() the imageUrl, correctAnswer, and choices it returns - renderQuiz(...(await loadQuizData())); + // Then call renderQuiz() with the returned imageUrl, correctAnswer, and choices + const [imageUrl, correctAnswer, choices] = await loadQuizData(); + renderQuiz(imageUrl, correctAnswer, choices); From 46a001ca2c223e515ee55d4606ef12aadae403be Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Wed, 21 Sep 2022 02:36:11 -0500 Subject: [PATCH 35/37] slides --- 3-slides.html | 100 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/3-slides.html b/3-slides.html index acdfc8b..e17d3b4 100644 --- a/3-slides.html +++ b/3-slides.html @@ -52,6 +52,9 @@ - In Day 3, go to the [starter](./3-doggofetch-starter.html) file - Save & open in your text editor + -- + + Gif from Clueless of Cher excitedly saying 'Project!' @@ -170,6 +173,8 @@ @@ -617,6 +664,51 @@
@@ -624,8 +716,8 @@ ## Next steps - Dig deeper with more FrontendMasters courses - - Refine your mental model with [Just JavaScript]() by Dan Abramov and Maggie Appleton - - Explore & investigate on [MDN](developer.mozilla.org) + - Refine your mental model with [Just JavaScript](https://justjavascript.com/) by Dan Abramov and Maggie Appleton + - Explore & investigate on [MDN](developer.mozilla.org) & elsewhere - Keep tinkering!
From 679e07814b49fbc3e551cbd8bed5c64fde0144a7 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Wed, 21 Sep 2022 02:39:15 -0500 Subject: [PATCH 36/37] doggos --- 3-doggofetch-finished.html | 1 - 3-doggofetch-starter.html | 69 +++++++++++++------------------------- 2 files changed, 24 insertions(+), 46 deletions(-) diff --git a/3-doggofetch-finished.html b/3-doggofetch-finished.html index 706a2b0..7a64c5e 100644 --- a/3-doggofetch-finished.html +++ b/3-doggofetch-finished.html @@ -116,7 +116,6 @@

Guess the Doggo

const [,path] = url.split("/breeds/"); const [breedID] = path.split("/"); const [breed, subtype] = breedID.split("-"); - // return `${subtype ? subtype + " " : ""}${breed}`; return [subtype, breed].join(" "); } diff --git a/3-doggofetch-starter.html b/3-doggofetch-starter.html index c04624b..96b31b4 100644 --- a/3-doggofetch-starter.html +++ b/3-doggofetch-starter.html @@ -77,61 +77,49 @@

Guess the Doggo

const BREEDS = ["affenpinscher", "african", "airedale", "akita", "appenzeller", "shepherd australian", "basenji", "beagle", "bluetick", "borzoi", "bouvier", "boxer", "brabancon", "briard", "norwegian buhund", "boston bulldog", "english bulldog", "french bulldog", "staffordshire bullterrier", "australian cattledog", "chihuahua", "chow", "clumber", "cockapoo", "border collie", "coonhound", "cardigan corgi", "cotondetulear", "dachshund", "dalmatian", "great dane", "scottish deerhound", "dhole", "dingo", "doberman", "norwegian elkhound", "entlebucher", "eskimo", "lapphund finnish", "bichon frise", "germanshepherd", "italian greyhound", "groenendael", "havanese", "afghan hound", "basset hound", "blood hound", "english hound", "ibizan hound", "plott hound", "walker hound", "husky", "keeshond", "kelpie", "komondor", "kuvasz", "labradoodle", "labrador", "leonberg", "lhasa", "malamute", "malinois", "maltese", "bull mastiff", "english mastiff", "tibetan mastiff", "mexicanhairless", "mix", "bernese mountain", "swiss mountain", "newfoundland", "otterhound", "caucasian ovcharka", "papillon", "pekinese", "pembroke", "miniature pinscher", "pitbull", "german pointer", "germanlonghair pointer", "pomeranian", "medium poodle", "miniature poodle", "standard poodle", "toy poodle", "pug", "puggle", "pyrenees", "redbone", "chesapeake retriever", "curly retriever", "flatcoated retriever", "golden retriever", "rhodesian ridgeback", "rottweiler", "saluki", "samoyed", "schipperke", "giant schnauzer", "miniature schnauzer", "english setter", "gordon setter", "irish setter", "sharpei", "english sheepdog", "shetland sheepdog", "shiba", "shihtzu", "blenheim spaniel", "brittany spaniel", "cocker spaniel", "irish spaniel", "japanese spaniel", "sussex spaniel", "welsh spaniel", "english springer", "stbernard", "american terrier", "australian terrier", "bedlington terrier", "border terrier", "cairn terrier", "dandie terrier", "fox terrier", "irish terrier", "kerryblue terrier", "lakeland terrier", "norfolk terrier", "norwich terrier", "patterdale terrier", "russell terrier", "scottish terrier", "sealyham terrier", "silky terrier", "tibetan terrier", "toy terrier", "welsh terrier", "westhighland terrier", "wheaten terrier", "yorkshire terrier", "tervuren", "vizsla", "spanish waterdog", "weimaraner", "whippet", "irish wolfhound"]; - // TODO 1 - // Given an array, return a randomly selected value from the array - // (this should NOT modify the original array) + // Utility function to get a randomly selected item from an array function getRandomElement(array) { const i = Math.floor(Math.random() * array.length); return array[i]; } - // TODO 2 - // Given an array, shuffle the order of its elements in-place - // (this SHOULD modify the original array) + // Utility function to shuffle the order of items in an array in-place function shuffleArray(array) { return array.sort((a,b) => Math.random() - 0.5); } - // TODO 3 - // Given a URL such as "https://images.dog.ceo/breeds/poodle-standard/n02113799_2280.jpg" - // return the breed name string as formatted in the breed list, e.g. "standard poodle" - function getBreedFromURL(url) { - const path = url.replace("https://images.dog.ceo/breeds/", ""); - const breedID = path.split("/")[0]; - const [breed, subtype] = breedID.split("-"); - return `${subtype ? subtype + " " : ""}${breed}`; - } - - // TODO 4 + // TODO 1 // Given an array of possible answers, a correct answer value, and a number of choices to get, // return a list of that many choices, including the correct answer and others from the array function getMultipleChoices(n, correctAnswer, array) { - const choices = [correctAnswer]; - while (choices.length < n) { - let candidate = getRandomElement(array); - if (choices.indexOf(candidate) < 0) { // check if this is already in the array - choices.push(candidate); // if not, add it - } - } - return shuffleArray(choices); + // Use a while loop and the getRandomElement() function + // Make sure there are no duplicates in the array + } + + // TODO 2 + // Given a URL such as "https://images.dog.ceo/breeds/poodle-standard/n02113799_2280.jpg" + // return the breed name string as formatted in the breed list, e.g. "standard poodle" + function getBreedFromURL(url) { + // The string method .split(char) may come in handy + // Try to use destructuring as much as you can + + } - // TODO 5 + + + // TODO 3 // Given a URL, fetch the resource at that URL, // then parse the response as a JSON object, // finally return the "message" property of its body async function fetchMessage(url) { - const response = await fetch(url); // Fetch the resource at the given URL - const json = await response.json(); // Parse the response as JSON - const {message} = json; // Extract the value of the "message" property - return message; // Return the message + } - // Function to add the multiple-choice buttons to the page function renderButtons(choicesArray, correctAnswer) { @@ -148,17 +136,12 @@

Guess the Doggo

const options = document.getElementById("options"); // Container for the multiple-choice buttons - // TODO 6 + // TODO 4 // For each of the choices in choicesArray, // Create a button element whose name, value, and textContent properties are the value of that choice, // attach a "click" event listener with the buttonHandler function, // and append the button as a child of the options element - choicesArray.map(choice => { - let button = document.createElement("button"); - button.value = button.name = button.textContent = choice; - button.addEventListener("click", buttonHandler); - options.appendChild(button); - }) + } @@ -168,10 +151,6 @@

Guess the Doggo

image.setAttribute("src", imgUrl); const frame = document.getElementById("image-frame"); - // TODO 7 - // Attach an event listener to the "load" event on the image element, and in the handler function, - // replace any existing children elements of the frame element with the image element, - // then call renderButtons() with the choices and correctAnswer image.addEventListener("load", () => { // Wait until the image has finished loading before trying to add elements to the page frame.replaceChildren(image); @@ -191,10 +170,10 @@

Guess the Doggo

return [doggoImgUrl, correctBreed, breedChoices]; } - // TODO 8 + // TODO 5 // Asynchronously call the loadQuizData() function, - // Then call renderQuiz() the imageUrl, correctAnswer, and choices it returns - renderQuiz(...(await loadQuizData())); + // Then call renderQuiz() with the returned imageUrl, correctAnswer, and choices + From 0e0c07093ffdd2757d1420958f01fcfdc138695f Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Wed, 21 Sep 2022 08:55:43 -0500 Subject: [PATCH 37/37] slides --- 2-slides.html | 2 ++ 3-slides.html | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/2-slides.html b/2-slides.html index ef8c4e4..a3702b7 100644 --- a/2-slides.html +++ b/2-slides.html @@ -1181,6 +1181,8 @@ The `map` & `filter` methods also let us process all the items in an array + Illustration of filter, map, reduce to make a sandwich + -- `map` calls a function on each item in an array to create a new array diff --git a/3-slides.html b/3-slides.html index e17d3b4..c1630a2 100644 --- a/3-slides.html +++ b/3-slides.html @@ -101,7 +101,7 @@