From 71a2c0aafdd5f01486bb94a2c9023b7ac02bf51e Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 5 Oct 2022 21:03:58 -0400 Subject: [PATCH 001/105] Assignment 1: Variables --- exercises/01-variables/01-variables.js | 1 + exercises/01-variables/02-variables.js | 1 + exercises/01-variables/03-change-a-variable.js | 1 + exercises/01-variables/04-constants.js | 1 + exercises/01-variables/05-fix-error.js | 2 +- exercises/01-variables/06-fix-bug.html | 2 +- 6 files changed, 6 insertions(+), 2 deletions(-) diff --git a/exercises/01-variables/01-variables.js b/exercises/01-variables/01-variables.js index 3e741b4..3d8bcd2 100644 --- a/exercises/01-variables/01-variables.js +++ b/exercises/01-variables/01-variables.js @@ -4,3 +4,4 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +let myNumber = 9; diff --git a/exercises/01-variables/02-variables.js b/exercises/01-variables/02-variables.js index 4b4b262..9cc4359 100644 --- a/exercises/01-variables/02-variables.js +++ b/exercises/01-variables/02-variables.js @@ -4,3 +4,4 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +let year = "2022"; diff --git a/exercises/01-variables/03-change-a-variable.js b/exercises/01-variables/03-change-a-variable.js index 0e3b65d..e862389 100644 --- a/exercises/01-variables/03-change-a-variable.js +++ b/exercises/01-variables/03-change-a-variable.js @@ -6,3 +6,4 @@ let price = 5.99; */ // WRITE YOUR ANSWER BELOW THIS LINE +price = 10.0; diff --git a/exercises/01-variables/04-constants.js b/exercises/01-variables/04-constants.js index 649e49b..73450da 100644 --- a/exercises/01-variables/04-constants.js +++ b/exercises/01-variables/04-constants.js @@ -5,3 +5,4 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +const PIE = 3.14; diff --git a/exercises/01-variables/05-fix-error.js b/exercises/01-variables/05-fix-error.js index f051c9e..69941e8 100644 --- a/exercises/01-variables/05-fix-error.js +++ b/exercises/01-variables/05-fix-error.js @@ -5,7 +5,7 @@ // WRITE YOUR ANSWER BELOW THIS LINE // This is throwing an error. Do you know why? -const numberOfLikes = 57; // Change me +const numberOfLikes = 58; // Change me // DO NOT CHANGE THE CODE BELOW diff --git a/exercises/01-variables/06-fix-bug.html b/exercises/01-variables/06-fix-bug.html index bb31834..3f43a17 100644 --- a/exercises/01-variables/06-fix-bug.html +++ b/exercises/01-variables/06-fix-bug.html @@ -39,7 +39,7 @@ document.querySelector("#form").addEventListener("submit", (e) => { e.preventDefault(); - document.querySelector("#name").value; // Change this line only. Set me to a variable called "content". + let content = document.querySelector("#name").value; // Change this line only. Set me to a variable called "content". // Do not change this alert("Hello " + content); From 567cee1d9d6976539bb4245cd037870963e5e87a Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 5 Oct 2022 23:24:07 -0400 Subject: [PATCH 002/105] Hal's correction of Assignment 1, 02-variables. Removed quotation marks from 2022 to make it a number. --- exercises/01-variables/02-variables.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/01-variables/02-variables.js b/exercises/01-variables/02-variables.js index 9cc4359..b9b1a56 100644 --- a/exercises/01-variables/02-variables.js +++ b/exercises/01-variables/02-variables.js @@ -4,4 +4,4 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE -let year = "2022"; +let year = 2022; From a4f3d0ec4a5bdae29a92fc0c006e635d42f3c5a4 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 12 Oct 2022 17:31:36 -0400 Subject: [PATCH 003/105] Solutions to variables exercise --- .../01-variables/01-variables.solution.js | 8 +++ .../01-variables/02-variables.solution.js | 8 +++ .../03-change-a-variable.solution.js | 10 ++++ .../01-variables/04-constants.solution.js | 9 ++++ .../01-variables/05-fix-error.solution.js | 12 +++++ .../01-variables/06-fix-bug.solution.html | 50 +++++++++++++++++++ 6 files changed, 97 insertions(+) create mode 100644 solutions/01-variables/01-variables.solution.js create mode 100644 solutions/01-variables/02-variables.solution.js create mode 100644 solutions/01-variables/03-change-a-variable.solution.js create mode 100644 solutions/01-variables/04-constants.solution.js create mode 100644 solutions/01-variables/05-fix-error.solution.js create mode 100644 solutions/01-variables/06-fix-bug.solution.html diff --git a/solutions/01-variables/01-variables.solution.js b/solutions/01-variables/01-variables.solution.js new file mode 100644 index 0000000..7c30df0 --- /dev/null +++ b/solutions/01-variables/01-variables.solution.js @@ -0,0 +1,8 @@ +/** + * Create a new variable called "myNumber". It should be equal to your favorite number. + * (Do not use var.) + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let myNumber = 7; diff --git a/solutions/01-variables/02-variables.solution.js b/solutions/01-variables/02-variables.solution.js new file mode 100644 index 0000000..acc8509 --- /dev/null +++ b/solutions/01-variables/02-variables.solution.js @@ -0,0 +1,8 @@ +/** + * Create a new variable called "year" that is equal to this year. + * (Do not use var.) + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let year = 2022; diff --git a/solutions/01-variables/03-change-a-variable.solution.js b/solutions/01-variables/03-change-a-variable.solution.js new file mode 100644 index 0000000..4a5a9b3 --- /dev/null +++ b/solutions/01-variables/03-change-a-variable.solution.js @@ -0,0 +1,10 @@ +let price = 5.99; + +/** + * Hurray inflation. Without modifying the first line, + * change the variable "price" so that it is a value that is greater than 5.99. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +price = 1000.99; diff --git a/solutions/01-variables/04-constants.solution.js b/solutions/01-variables/04-constants.solution.js new file mode 100644 index 0000000..315ba9f --- /dev/null +++ b/solutions/01-variables/04-constants.solution.js @@ -0,0 +1,9 @@ +/** + * Create a constant called "PIE". + * It should be equal to the mathematical pie (3.14...), + * and it should have two or more digits after the decimal point. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const PIE = 3.14; diff --git a/solutions/01-variables/05-fix-error.solution.js b/solutions/01-variables/05-fix-error.solution.js new file mode 100644 index 0000000..59a9697 --- /dev/null +++ b/solutions/01-variables/05-fix-error.solution.js @@ -0,0 +1,12 @@ +/** + * There is an error with this code. Fix the error by changing the code where instructed below. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// This is throwing an error. Do you know why? +let numberOfLikes = 57; // Change me + +// DO NOT CHANGE THE CODE BELOW + +numberOfLikes = 58; diff --git a/solutions/01-variables/06-fix-bug.solution.html b/solutions/01-variables/06-fix-bug.solution.html new file mode 100644 index 0000000..3f43a17 --- /dev/null +++ b/solutions/01-variables/06-fix-bug.solution.html @@ -0,0 +1,50 @@ + + + + + + + + EXERCISE + + + +
+ + + +
+ + + From 13ef2d9d8a8d158a51c6591e169b8b42276cc796 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 12 Oct 2022 17:34:19 -0400 Subject: [PATCH 004/105] Include introductions for Quokka --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cbc895d..be04763 100644 --- a/README.md +++ b/README.md @@ -41,4 +41,4 @@ Whenever you are ready to submit your work, you will need to [commit your work, - Command Line: [NPM Guide](https://nodesource.com/blog/an-absolute-beginners-guide-to-using-npm/) | [Unix Crash Course](https://www.vikingcodeschool.com/web-development-basics/a-command-line-crash-course) | [Unix Cheat Sheet](http://www.mathcs.emory.edu/~valerie/courses/fall10/155/resources/unix_cheatsheet.html) - Command Line: [Unix Cheat Sheet](https://www.guru99.com/linux-commands-cheat-sheet.html) | [Unix Tutorial](http://www.ee.surrey.ac.uk/Teaching/Unix/) | [NPM Guide](https://nodesource.com/blog/an-absolute-beginners-guide-to-using-npm/) - Git: [Git Commands for Beginners](http://rogerdudler.github.io/git-guide/) | [First Contributions Tutorial](https://github.com/firstcontributions/first-contributions) -- Visual Studio Code: [Mac Keyboard Shortcuts](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf) | [Windows Keyboard Shortcuts](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf) | [Getting Started](https://code.visualstudio.com/docs/getstarted/introvideos) +- Visual Studio Code: [Mac Keyboard Shortcuts](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf) | [Windows Keyboard Shortcuts](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf) | [Getting Started](https://code.visualstudio.com/docs/getstarted/introvideos) | [How to use Quokka.js](https://debug.to/1441/quokka-js-extension-for-visual-studio-code) From 66b7c176383cfa31df8f8ede99072c6c3fe6b046 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 25 Sep 2022 13:11:35 -0400 Subject: [PATCH 005/105] Numbers exercises --- .vscode/launch.json | 13 ++++ exercises/02-numbers/01-add.js | 6 ++ exercises/02-numbers/02-subtract.js | 9 +++ .../02-numbers/03-multiply-and-divide.js | 8 +++ exercises/02-numbers/04-increment.js | 9 +++ exercises/02-numbers/05-decrement.js | 9 +++ .../02-numbers/06-order-of-operations.js | 8 +++ exercises/02-numbers/07-calcuator.html | 59 ++++++++++++++++ test/02-numbers/numbers-test-helper.js | 48 +++++++++++++ test/02-numbers/numbers.spec.js | 67 +++++++++++++++++++ 10 files changed, 236 insertions(+) create mode 100644 exercises/02-numbers/01-add.js create mode 100644 exercises/02-numbers/02-subtract.js create mode 100644 exercises/02-numbers/03-multiply-and-divide.js create mode 100644 exercises/02-numbers/04-increment.js create mode 100644 exercises/02-numbers/05-decrement.js create mode 100644 exercises/02-numbers/06-order-of-operations.js create mode 100644 exercises/02-numbers/07-calcuator.html create mode 100644 test/02-numbers/numbers-test-helper.js create mode 100644 test/02-numbers/numbers.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 8649ba4..5da72b6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -30,5 +30,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "2. Numbers", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/02-numbers/numbers.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/02-numbers/01-add.js b/exercises/02-numbers/01-add.js new file mode 100644 index 0000000..fec8186 --- /dev/null +++ b/exercises/02-numbers/01-add.js @@ -0,0 +1,6 @@ +/** + * Create a constant called "sum". + * On the right side of the "equals" sign, there should two numbers and a plus sign. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/02-numbers/02-subtract.js b/exercises/02-numbers/02-subtract.js new file mode 100644 index 0000000..9abdbe9 --- /dev/null +++ b/exercises/02-numbers/02-subtract.js @@ -0,0 +1,9 @@ +let a = 10; // e.g. +let b = 5; // e.g. + +/** + * Create a new variable called "difference". It should equal the "b" minus "a". + * This should still work when "a" and "b" are equal to different numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/02-numbers/03-multiply-and-divide.js b/exercises/02-numbers/03-multiply-and-divide.js new file mode 100644 index 0000000..f5951a5 --- /dev/null +++ b/exercises/02-numbers/03-multiply-and-divide.js @@ -0,0 +1,8 @@ +const ONE_HUNDRED = 100; + +/** + * Create a constant called "percentage". + * It should equal one number divided by another, and then multiplied by "ONE_HUNDRED". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/02-numbers/04-increment.js b/exercises/02-numbers/04-increment.js new file mode 100644 index 0000000..420b78f --- /dev/null +++ b/exercises/02-numbers/04-increment.js @@ -0,0 +1,9 @@ +let age = 90; // e.g. + +/** + * Increment the variable "age" by 1. (That is, add 1). + * Use the increment operator to solve this problem. + * This should still work when "age" is a different number. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/02-numbers/05-decrement.js b/exercises/02-numbers/05-decrement.js new file mode 100644 index 0000000..fce1657 --- /dev/null +++ b/exercises/02-numbers/05-decrement.js @@ -0,0 +1,9 @@ +let age = 90; // e.g. + +/** + * Decrement the variable "age" by 1. (That is, subtract 1). + * Use the decrement operator to solve this problem. + * This should still work when "age" is a different number. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/02-numbers/06-order-of-operations.js b/exercises/02-numbers/06-order-of-operations.js new file mode 100644 index 0000000..6736bf1 --- /dev/null +++ b/exercises/02-numbers/06-order-of-operations.js @@ -0,0 +1,8 @@ +/** + * Without changing the numbers themselves, + * change the syntax or order of operations so that result equals 800. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const result = 3 + 5 * 100; diff --git a/exercises/02-numbers/07-calcuator.html b/exercises/02-numbers/07-calcuator.html new file mode 100644 index 0000000..f311c7c --- /dev/null +++ b/exercises/02-numbers/07-calcuator.html @@ -0,0 +1,59 @@ + + + + + + + + EXERCISE + + + + +
+ + + + + = + 0 +
+ + + diff --git a/test/02-numbers/numbers-test-helper.js b/test/02-numbers/numbers-test-helper.js new file mode 100644 index 0000000..9dd60a0 --- /dev/null +++ b/test/02-numbers/numbers-test-helper.js @@ -0,0 +1,48 @@ +import { getAnswer } from "../getAnswer.js"; + +const addStr = getAnswer("../exercises/02-numbers/01-add.js"); + +const subtractStr = getAnswer("../exercises/02-numbers/02-subtract.js"); + +const multiplyDivideStr = getAnswer( + "../exercises/02-numbers/03-multiply-and-divide.js" +); + +const incrementStr = getAnswer("../exercises/02-numbers/04-increment.js"); + +const decrementStr = getAnswer("../exercises/02-numbers/05-decrement.js"); + +const orderOfOperationsStr = getAnswer( + "../exercises/02-numbers/06-order-of-operations.js" +); + +export const add = eval(`() => { + ${addStr} + return sum; +}`); + +export const subtract = eval(`(a, b) => { + ${subtractStr} + return difference; +}`); + +export const getPercentage = eval(`(a, b) => { + const ONE_HUNDRED = 100; + ${multiplyDivideStr} + return percentage; +}`); + +export const increment = eval(`(age) => { + ${incrementStr} + return age; +}`); + +export const decrement = eval(`(age) => { + ${decrementStr} + return age; +}`); + +export const getOrderOfOperations = eval(`() => { + ${orderOfOperationsStr} + return result; +}`); diff --git a/test/02-numbers/numbers.spec.js b/test/02-numbers/numbers.spec.js new file mode 100644 index 0000000..ee12bf7 --- /dev/null +++ b/test/02-numbers/numbers.spec.js @@ -0,0 +1,67 @@ +import { expect } from "chai"; +import { + add, + subtract, + getPercentage, + increment, + decrement, + getOrderOfOperations, +} from "./numbers-test-helper.js"; + +describe("2. Numbers", () => { + describe("01-add", () => { + it('should contain a constant called "sum" that should result in a number', () => { + const number = add(); + expect(number).to.be.a("number").to.not.equal(NaN); + }); + it('"sum" should equal to one number plus another', () => { + const str = add.toString(); + expect(str).to.match(/\=/).to.match(/\+/); + }); + }); + + describe("02-subtract", () => { + it('should contain a variable "difference" equal to the numbers "a" minus "b"', () => { + const difference = subtract(20, 3); + expect(difference).to.equal(17); + }); + }); + + describe("03-multiple-and-divide", () => { + it('should contain a constant called "percentage" that should result in a number', () => { + const number = getPercentage(); + expect(number).to.be.a("number").to.not.equal(NaN); + }); + it('"percentage" should equal to one number divided by another times the constant "ONE_HUNDRED"', () => { + const str = getPercentage.toString(); + expect(str).to.match(/\=/).to.match(/\//).to.match(/\*/); + const array = str.split("ONE_HUNDRED"); + expect(array).length.to.be.greaterThan(2); + }); + }); + + describe("04-increment", () => { + it('should use the increment operator to increment the variable "age" by 1', () => { + expect(increment.toString().includes("++")).equal(true); + expect(increment(19)).equal(20); + }); + }); + + describe("05-decrement", () => { + it('should use the decrement operator to decrement the variable "age" by 1', () => { + expect(decrement.toString().includes("--")).equal(true); + expect(decrement(18)).equal(17); + }); + }); + + describe("06-order-of-operations", () => { + it("should equal the number 800", () => { + const number = getOrderOfOperations(); + expect(number).to.be.a("number").to.equal(800); + }); + it("should still contain a plus (+) and multiple (*) sign", () => { + const str = getOrderOfOperations.toString(); + expect(str).to.match(/\=/).to.match(/\+/).to.match(/\*/); + }); + }); +}); From 4ce662cbc65ce4ce3c2e1bdf9155f922d8617784 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 12 Oct 2022 19:29:19 -0400 Subject: [PATCH 006/105] Assignment 2 --- exercises/02-numbers/01-add.js | 1 + exercises/02-numbers/02-subtract.js | 1 + exercises/02-numbers/03-multiply-and-divide.js | 1 + exercises/02-numbers/04-increment.js | 1 + exercises/02-numbers/05-decrement.js | 1 + exercises/02-numbers/06-order-of-operations.js | 2 +- exercises/02-numbers/07-calcuator.html | 2 +- 7 files changed, 7 insertions(+), 2 deletions(-) diff --git a/exercises/02-numbers/01-add.js b/exercises/02-numbers/01-add.js index fec8186..461346d 100644 --- a/exercises/02-numbers/01-add.js +++ b/exercises/02-numbers/01-add.js @@ -4,3 +4,4 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +const sum = 10 + 6; diff --git a/exercises/02-numbers/02-subtract.js b/exercises/02-numbers/02-subtract.js index 9abdbe9..c7cfcd0 100644 --- a/exercises/02-numbers/02-subtract.js +++ b/exercises/02-numbers/02-subtract.js @@ -7,3 +7,4 @@ let b = 5; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let difference = b - a; diff --git a/exercises/02-numbers/03-multiply-and-divide.js b/exercises/02-numbers/03-multiply-and-divide.js index f5951a5..9b45bde 100644 --- a/exercises/02-numbers/03-multiply-and-divide.js +++ b/exercises/02-numbers/03-multiply-and-divide.js @@ -6,3 +6,4 @@ const ONE_HUNDRED = 100; */ // WRITE YOUR ANSWER BELOW THIS LINE +const percentage = (60 - 40) / ONE_HUNDRED; diff --git a/exercises/02-numbers/04-increment.js b/exercises/02-numbers/04-increment.js index 420b78f..7064fe5 100644 --- a/exercises/02-numbers/04-increment.js +++ b/exercises/02-numbers/04-increment.js @@ -7,3 +7,4 @@ let age = 90; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +age++; diff --git a/exercises/02-numbers/05-decrement.js b/exercises/02-numbers/05-decrement.js index fce1657..9d1ea9f 100644 --- a/exercises/02-numbers/05-decrement.js +++ b/exercises/02-numbers/05-decrement.js @@ -7,3 +7,4 @@ let age = 90; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +age--; diff --git a/exercises/02-numbers/06-order-of-operations.js b/exercises/02-numbers/06-order-of-operations.js index 6736bf1..32f398c 100644 --- a/exercises/02-numbers/06-order-of-operations.js +++ b/exercises/02-numbers/06-order-of-operations.js @@ -5,4 +5,4 @@ // WRITE YOUR ANSWER BELOW THIS LINE -const result = 3 + 5 * 100; +const result = (3 + 5) * 100; diff --git a/exercises/02-numbers/07-calcuator.html b/exercises/02-numbers/07-calcuator.html index f311c7c..191d3eb 100644 --- a/exercises/02-numbers/07-calcuator.html +++ b/exercises/02-numbers/07-calcuator.html @@ -49,7 +49,7 @@ let b = parseInt(document.querySelector("#b").value || 0); // Create a variable called "sum" on the line below. It should be equal to a + b. - + let sum = a + b; document.querySelector("#answer").textContent = sum || "-"; }); }); From bac94a0752bdd898bc985adb66be5b3b4afbdb14 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 2 Oct 2022 15:03:20 -0400 Subject: [PATCH 007/105] Strings exercises --- .vscode/launch.json | 13 ++++++ exercises/03-strings/01-create-a-string.js | 5 +++ .../02-get-the-character-position.js | 21 +++++++++ exercises/03-strings/03-string-length.js | 11 +++++ exercises/03-strings/04-get-last-character.js | 11 +++++ .../05-get-last-word-in-place-name.js | 18 ++++++++ test/03-strings/strings-test-helper.js | 44 +++++++++++++++++++ test/03-strings/strings.spec.js | 41 +++++++++++++++++ 8 files changed, 164 insertions(+) create mode 100644 exercises/03-strings/01-create-a-string.js create mode 100644 exercises/03-strings/02-get-the-character-position.js create mode 100644 exercises/03-strings/03-string-length.js create mode 100644 exercises/03-strings/04-get-last-character.js create mode 100644 exercises/03-strings/05-get-last-word-in-place-name.js create mode 100644 test/03-strings/strings-test-helper.js create mode 100644 test/03-strings/strings.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 5da72b6..b0faac1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -43,5 +43,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "3. Strings", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/03-strings/strings.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/03-strings/01-create-a-string.js b/exercises/03-strings/01-create-a-string.js new file mode 100644 index 0000000..ded2b2d --- /dev/null +++ b/exercises/03-strings/01-create-a-string.js @@ -0,0 +1,5 @@ +/** + * Create a new variable called "myName". It should be equal to your name, which is a string. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/03-strings/02-get-the-character-position.js b/exercises/03-strings/02-get-the-character-position.js new file mode 100644 index 0000000..bbe345c --- /dev/null +++ b/exercises/03-strings/02-get-the-character-position.js @@ -0,0 +1,21 @@ +let firstName = "Bill"; // e.g. +let letter = "i"; // e.g. + +/** + * Create a variable called "characterPosition". + * It should be equal to the first index (position) of "letter" within the string "firstName". + * + * @example + * let firstName = "Bill"; + * let letter = "i"; // e.g. + * The answer should be 1. (JavaScript starts counting with 0). + * + * @example + * let firstName = "Briana"; + * let letter = "a"; // e.g. + * The answer should be 3. (JavaScript starts counting with 0). + * + * Your answer should still work when "firstName" and "letter" are equal to different values than they are above. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/03-strings/03-string-length.js b/exercises/03-strings/03-string-length.js new file mode 100644 index 0000000..795cef1 --- /dev/null +++ b/exercises/03-strings/03-string-length.js @@ -0,0 +1,11 @@ +const str = "bananas"; // e.g. + +/** + * Create a new constant called "strLength". It should be evaluate to the number of characters within the value of "str". + * @example + * - If "str" is "bananas", "strLength" should count the number of characters and result in 7. + * - If "str" is "chocolate", "strLength" should count the number of characters and result in 9. + * This should still work when "str" is equal to a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/03-strings/04-get-last-character.js b/exercises/03-strings/04-get-last-character.js new file mode 100644 index 0000000..3aee0c4 --- /dev/null +++ b/exercises/03-strings/04-get-last-character.js @@ -0,0 +1,11 @@ +let str = "Wes Craven"; // e.g. + +/*** + * Create a constant called "lastCharacter". It should be equal to the last character within "str". + * @example + * let str = "Wes Craven"; + * "lastCharacter" should equal "n" + * Your answer should still work when "str" is equal to something else. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/03-strings/05-get-last-word-in-place-name.js b/exercises/03-strings/05-get-last-word-in-place-name.js new file mode 100644 index 0000000..f240798 --- /dev/null +++ b/exercises/03-strings/05-get-last-word-in-place-name.js @@ -0,0 +1,18 @@ +const place = "New Jersey"; // e.g. + +/** + * Create a variable called "newPlace". It should use "place" above and it should be equal to the last part of a place name. + * This should still work when place is equal to a different city, like "New Mexico" or "San Diego". + * + * @example + * If "place" is equal to "New Jersey", + * "newPlace" should equal "York" + * + * If "place" is equal to "New Mexico", + * "newPlace" should equal "Mexico" + * + * If "place" is equal to "San Diego", + * "newPlace" should equal "Diego" + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/03-strings/strings-test-helper.js b/test/03-strings/strings-test-helper.js new file mode 100644 index 0000000..e434dbb --- /dev/null +++ b/test/03-strings/strings-test-helper.js @@ -0,0 +1,44 @@ +import { getAnswer } from "../getAnswer.js"; + +const getNameStr = getAnswer("../exercises/03-strings/01-create-a-string.js"); + +const getTheCharacterPositionAnswer = getAnswer( + "../exercises/03-strings/02-get-the-character-position.js" +); + +const stringLengthStr = getAnswer( + "../exercises/03-strings/03-string-length.js" +); + +const getLastCharacterAnswer = getAnswer( + "../exercises/03-strings/04-get-last-character.js" +); + +const getLastWordInPlaceNameStr = getAnswer( + "../exercises/03-strings/05-get-last-word-in-place-name.js" +); + +export const getName = eval(`() => { + ${getNameStr} + return myName; +}`); + +export const getTheCharacterPosition = eval(`(firstName, letter) => { + ${getTheCharacterPositionAnswer} + return characterPosition; +}`); + +export const stringLength = eval(`(str) => { + ${stringLengthStr} + return strLength; +}`); + +export const getLastCharacter = eval(`(str) => { + ${getLastCharacterAnswer} + return lastCharacter; +}`); + +export const getLastWordInPlaceName = eval(`(place) => { + ${getLastWordInPlaceNameStr} + return newPlace; +}`); diff --git a/test/03-strings/strings.spec.js b/test/03-strings/strings.spec.js new file mode 100644 index 0000000..89ab2b8 --- /dev/null +++ b/test/03-strings/strings.spec.js @@ -0,0 +1,41 @@ +import { expect } from "chai"; +import { + getName, + getTheCharacterPosition, + stringLength, + getLastCharacter, + getLastWordInPlaceName, +} from "./strings-test-helper.js"; + +describe("3. Strings", () => { + describe("01-create-a-string", () => { + it('should contain a variable called "myName" that is equal to your name', () => { + const name = getName(); + expect(name).to.be.a("string").to.have.length.greaterThan(1); + }); + }); + + describe("02-get-character-position", () => { + it('should contain a variable "characterPosition" and it should be equal to the index of "letter" within "firstName"', () => { + expect(getTheCharacterPosition("James", "a")).equal(1); + }); + }); + + describe("03-string-length", () => { + it('should contain a constant "strLength" and it should count the number of characters within a string "str"', () => { + expect(stringLength("Javascript")).equal(10); + }); + }); + + describe("04-get-last-character", () => { + it('should contain a constant called "lastCharacter" and it should equal lastCharacter the last character (or letter) within the string "str"', () => { + expect(getLastCharacter("Marvel")).equal("l"); + }); + }); + + describe("05-get-last-word-in-place-name", () => { + it('should contain a variable "newPlace" that is equal to the second word within a place name "place"', () => { + expect(getLastWordInPlaceName("Los Angeles")).equal("Angeles"); + }); + }); +}); From 79eb82d584115a7a8554abf3231c4ed7179f5e80 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 13 Oct 2022 10:12:26 -0400 Subject: [PATCH 008/105] Assignment 03 - Hal Katzman --- exercises/03-strings/01-create-a-string.js | 2 ++ exercises/03-strings/02-get-the-character-position.js | 2 ++ exercises/03-strings/03-string-length.js | 2 ++ exercises/03-strings/04-get-last-character.js | 2 ++ exercises/03-strings/05-get-last-word-in-place-name.js | 3 +++ 5 files changed, 11 insertions(+) diff --git a/exercises/03-strings/01-create-a-string.js b/exercises/03-strings/01-create-a-string.js index ded2b2d..f99aaf3 100644 --- a/exercises/03-strings/01-create-a-string.js +++ b/exercises/03-strings/01-create-a-string.js @@ -3,3 +3,5 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE + +let myName = "Hal"; diff --git a/exercises/03-strings/02-get-the-character-position.js b/exercises/03-strings/02-get-the-character-position.js index bbe345c..936e5de 100644 --- a/exercises/03-strings/02-get-the-character-position.js +++ b/exercises/03-strings/02-get-the-character-position.js @@ -19,3 +19,5 @@ let letter = "i"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE + +let characterPosition = 1; diff --git a/exercises/03-strings/03-string-length.js b/exercises/03-strings/03-string-length.js index 795cef1..4b201ae 100644 --- a/exercises/03-strings/03-string-length.js +++ b/exercises/03-strings/03-string-length.js @@ -9,3 +9,5 @@ const str = "bananas"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE + +let strLength = str.length; diff --git a/exercises/03-strings/04-get-last-character.js b/exercises/03-strings/04-get-last-character.js index 3aee0c4..89b862f 100644 --- a/exercises/03-strings/04-get-last-character.js +++ b/exercises/03-strings/04-get-last-character.js @@ -9,3 +9,5 @@ let str = "Wes Craven"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE + +const lastCharacter = str[str.length - 1]; diff --git a/exercises/03-strings/05-get-last-word-in-place-name.js b/exercises/03-strings/05-get-last-word-in-place-name.js index f240798..81aa39b 100644 --- a/exercises/03-strings/05-get-last-word-in-place-name.js +++ b/exercises/03-strings/05-get-last-word-in-place-name.js @@ -16,3 +16,6 @@ const place = "New Jersey"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE + +let index = place.indexOf(" "); +let newPlace = place.substring(index + 1); From 727771ce3168d51e479c730bfc74b9b2c43fbea2 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Thu, 13 Oct 2022 19:56:49 -0400 Subject: [PATCH 009/105] Fix bug with numbers test --- test/02-numbers/numbers.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/02-numbers/numbers.spec.js b/test/02-numbers/numbers.spec.js index ee12bf7..58d10e3 100644 --- a/test/02-numbers/numbers.spec.js +++ b/test/02-numbers/numbers.spec.js @@ -21,8 +21,8 @@ describe("2. Numbers", () => { }); describe("02-subtract", () => { - it('should contain a variable "difference" equal to the numbers "a" minus "b"', () => { - const difference = subtract(20, 3); + it('should contain a variable "difference" equal to the numbers "b" minus "a"', () => { + const difference = subtract(3, 20); expect(difference).to.equal(17); }); }); From b895c95c0c845286ca0d41984cdd8d8d2eccccad Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Mon, 17 Oct 2022 17:25:27 -0400 Subject: [PATCH 010/105] Solutions for the numbers and strings exercise --- solutions/02-numbers/01-add.solution.js | 8 +++ solutions/02-numbers/02-subtract.solution.js | 11 ++++ .../03-multiply-and-divide.solution.js | 10 ++++ solutions/02-numbers/04-increment.solution.js | 11 ++++ solutions/02-numbers/05-decrement.solution.js | 11 ++++ .../06-order-of-operations.solution.js | 8 +++ .../02-numbers/07-calcuator.solution.html | 60 +++++++++++++++++++ .../03-strings/01-create-a-string.solution.js | 7 +++ .../02-get-the-character-position.solution.js | 23 +++++++ .../03-strings/03-string-length.solution.js | 13 ++++ .../04-get-last-character.solution.js | 13 ++++ ...05-get-last-word-in-place-name.solution.js | 21 +++++++ 12 files changed, 196 insertions(+) create mode 100644 solutions/02-numbers/01-add.solution.js create mode 100644 solutions/02-numbers/02-subtract.solution.js create mode 100644 solutions/02-numbers/03-multiply-and-divide.solution.js create mode 100644 solutions/02-numbers/04-increment.solution.js create mode 100644 solutions/02-numbers/05-decrement.solution.js create mode 100644 solutions/02-numbers/06-order-of-operations.solution.js create mode 100644 solutions/02-numbers/07-calcuator.solution.html create mode 100644 solutions/03-strings/01-create-a-string.solution.js create mode 100644 solutions/03-strings/02-get-the-character-position.solution.js create mode 100644 solutions/03-strings/03-string-length.solution.js create mode 100644 solutions/03-strings/04-get-last-character.solution.js create mode 100644 solutions/03-strings/05-get-last-word-in-place-name.solution.js diff --git a/solutions/02-numbers/01-add.solution.js b/solutions/02-numbers/01-add.solution.js new file mode 100644 index 0000000..41f01aa --- /dev/null +++ b/solutions/02-numbers/01-add.solution.js @@ -0,0 +1,8 @@ +/** + * Create a constant called "sum". + * On the right side of the "equals" sign, there should two numbers and a plus sign. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const sum = 4 + 5; diff --git a/solutions/02-numbers/02-subtract.solution.js b/solutions/02-numbers/02-subtract.solution.js new file mode 100644 index 0000000..3a1195a --- /dev/null +++ b/solutions/02-numbers/02-subtract.solution.js @@ -0,0 +1,11 @@ +let a = 10; // e.g. +let b = 5; // e.g. + +/** + * Create a new variable called "difference". It should equal the "b" minus "a". + * This should still work when "a" and "b" are equal to different numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let difference = b - a; diff --git a/solutions/02-numbers/03-multiply-and-divide.solution.js b/solutions/02-numbers/03-multiply-and-divide.solution.js new file mode 100644 index 0000000..478e3d4 --- /dev/null +++ b/solutions/02-numbers/03-multiply-and-divide.solution.js @@ -0,0 +1,10 @@ +const ONE_HUNDRED = 100; + +/** + * Create a constant called "percentage". + * It should equal one number divided by another, and then multiplied by "ONE_HUNDRED". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const percentage = (4 / 5) * ONE_HUNDRED; diff --git a/solutions/02-numbers/04-increment.solution.js b/solutions/02-numbers/04-increment.solution.js new file mode 100644 index 0000000..2adf3f1 --- /dev/null +++ b/solutions/02-numbers/04-increment.solution.js @@ -0,0 +1,11 @@ +let age = 90; // e.g. + +/** + * Increment the variable "age" by 1. (That is, add 1). + * Use the increment operator to solve this problem. + * This should still work when "age" is a different number. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +age++; diff --git a/solutions/02-numbers/05-decrement.solution.js b/solutions/02-numbers/05-decrement.solution.js new file mode 100644 index 0000000..12117df --- /dev/null +++ b/solutions/02-numbers/05-decrement.solution.js @@ -0,0 +1,11 @@ +let age = 90; // e.g. + +/** + * Decrement the variable "age" by 1. (That is, subtract 1). + * Use the decrement operator to solve this problem. + * This should still work when "age" is a different number. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +age--; diff --git a/solutions/02-numbers/06-order-of-operations.solution.js b/solutions/02-numbers/06-order-of-operations.solution.js new file mode 100644 index 0000000..32f398c --- /dev/null +++ b/solutions/02-numbers/06-order-of-operations.solution.js @@ -0,0 +1,8 @@ +/** + * Without changing the numbers themselves, + * change the syntax or order of operations so that result equals 800. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const result = (3 + 5) * 100; diff --git a/solutions/02-numbers/07-calcuator.solution.html b/solutions/02-numbers/07-calcuator.solution.html new file mode 100644 index 0000000..3f7ff2e --- /dev/null +++ b/solutions/02-numbers/07-calcuator.solution.html @@ -0,0 +1,60 @@ + + + + + + + + EXERCISE + + + + +
+ + + + + = + 0 +
+ + + diff --git a/solutions/03-strings/01-create-a-string.solution.js b/solutions/03-strings/01-create-a-string.solution.js new file mode 100644 index 0000000..c136770 --- /dev/null +++ b/solutions/03-strings/01-create-a-string.solution.js @@ -0,0 +1,7 @@ +/** + * Create a new variable called "myName". It should be equal to your name, which is a string. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let myName = "Terrance"; diff --git a/solutions/03-strings/02-get-the-character-position.solution.js b/solutions/03-strings/02-get-the-character-position.solution.js new file mode 100644 index 0000000..2957a75 --- /dev/null +++ b/solutions/03-strings/02-get-the-character-position.solution.js @@ -0,0 +1,23 @@ +let firstName = "Bill"; // e.g. +let letter = "i"; // e.g. + +/** + * Create a variable called "characterPosition". + * It should be equal to the first index (position) of "letter" within the string "firstName". + * + * @example + * let firstName = "Bill"; + * let letter = "i"; // e.g. + * The answer should be 1. (JavaScript starts counting with 0). + * + * @example + * let firstName = "Briana"; + * let letter = "a"; // e.g. + * The answer should be 3. (JavaScript starts counting with 0). + * + * Your answer should still work when "firstName" and "letter" are equal to different values than they are above. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let characterPosition = firstName.indexOf(letter); diff --git a/solutions/03-strings/03-string-length.solution.js b/solutions/03-strings/03-string-length.solution.js new file mode 100644 index 0000000..3df7051 --- /dev/null +++ b/solutions/03-strings/03-string-length.solution.js @@ -0,0 +1,13 @@ +const str = "bananas"; // e.g. + +/** + * Create a new constant called "strLength". It should be evaluate to the number of characters within the value of "str". + * @example + * - If "str" is "bananas", "strLength" should count the number of characters and result in 7. + * - If "str" is "chocolate", "strLength" should count the number of characters and result in 9. + * This should still work when "str" is equal to a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const strLength = str.length; diff --git a/solutions/03-strings/04-get-last-character.solution.js b/solutions/03-strings/04-get-last-character.solution.js new file mode 100644 index 0000000..89b862f --- /dev/null +++ b/solutions/03-strings/04-get-last-character.solution.js @@ -0,0 +1,13 @@ +let str = "Wes Craven"; // e.g. + +/*** + * Create a constant called "lastCharacter". It should be equal to the last character within "str". + * @example + * let str = "Wes Craven"; + * "lastCharacter" should equal "n" + * Your answer should still work when "str" is equal to something else. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const lastCharacter = str[str.length - 1]; diff --git a/solutions/03-strings/05-get-last-word-in-place-name.solution.js b/solutions/03-strings/05-get-last-word-in-place-name.solution.js new file mode 100644 index 0000000..81aa39b --- /dev/null +++ b/solutions/03-strings/05-get-last-word-in-place-name.solution.js @@ -0,0 +1,21 @@ +const place = "New Jersey"; // e.g. + +/** + * Create a variable called "newPlace". It should use "place" above and it should be equal to the last part of a place name. + * This should still work when place is equal to a different city, like "New Mexico" or "San Diego". + * + * @example + * If "place" is equal to "New Jersey", + * "newPlace" should equal "York" + * + * If "place" is equal to "New Mexico", + * "newPlace" should equal "Mexico" + * + * If "place" is equal to "San Diego", + * "newPlace" should equal "Diego" + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let index = place.indexOf(" "); +let newPlace = place.substring(index + 1); From d4f42f3364f2c268892f56d4142dd5d28a534304 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 2 Oct 2022 15:29:14 -0400 Subject: [PATCH 011/105] Combine strings exercises --- .vscode/launch.json | 13 +++++ .../01-concatenate-operator.js | 18 ++++++ .../02-template-literals.js | 18 ++++++ .../03-replace-last-name.js | 18 ++++++ .../04-combine-strings/04-combine-text.html | 56 +++++++++++++++++++ .../combine-strings-helper.js | 28 ++++++++++ .../combine-strings.spec.js | 51 +++++++++++++++++ 7 files changed, 202 insertions(+) create mode 100644 exercises/04-combine-strings/01-concatenate-operator.js create mode 100644 exercises/04-combine-strings/02-template-literals.js create mode 100644 exercises/04-combine-strings/03-replace-last-name.js create mode 100644 exercises/04-combine-strings/04-combine-text.html create mode 100644 test/04-combine-strings/combine-strings-helper.js create mode 100644 test/04-combine-strings/combine-strings.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index b0faac1..e9578a5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -56,5 +56,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "4. Combine Strings", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/04-combine-strings/combine-strings.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/04-combine-strings/01-concatenate-operator.js b/exercises/04-combine-strings/01-concatenate-operator.js new file mode 100644 index 0000000..2154224 --- /dev/null +++ b/exercises/04-combine-strings/01-concatenate-operator.js @@ -0,0 +1,18 @@ +let bookTitle = "Harry Potter and the Sorcerer's Stone"; +let author = "J. K. Rowling"; + +/** + * Use the concatenation operator (the plus sign) to solve this problem. + * + * Create a variable called "bookInfo". It should combine the variables "bookTitle" and "author" together + * so that if I were to log "bookInfo", it would say: + * Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * @example + * // Declare "bookTitle" + * console.log(bookTitle); // Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * This should still work when "bookTitle" and "author" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/04-combine-strings/02-template-literals.js b/exercises/04-combine-strings/02-template-literals.js new file mode 100644 index 0000000..43d025e --- /dev/null +++ b/exercises/04-combine-strings/02-template-literals.js @@ -0,0 +1,18 @@ +let bookTitle = "Harry Potter and the Sorcerer's Stone"; +let author = "J. K. Rowling"; + +/** + * This exercise is the same as the previous, except you will use template literals to solve this problem. + * + * Create a variable called "bookInfo". It should combine the variables "bookTitle" and "author" together + * so that if I were to log "bookInfo", it would say: + * Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * @example + * // Declare "bookTitle" + * console.log(bookTitle); // Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * This should still work when "bookTitle" and "author" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/04-combine-strings/03-replace-last-name.js b/exercises/04-combine-strings/03-replace-last-name.js new file mode 100644 index 0000000..e1cb274 --- /dev/null +++ b/exercises/04-combine-strings/03-replace-last-name.js @@ -0,0 +1,18 @@ +let fullName = "Joe Washington"; // e.g. +let newLastName = "Fernandez"; // e.g. + +/** + * A person just got married and they need their last name replaced. You will change the value of "fullName" below. Replace the last name in "fullName" with "newLastName". + * + * @example + * let fullName = "Emily Rose"; + * let newLastName = "Smith"; + * The new value for "fullName" should result in "Emily Smith". + * + * @example + * let fullName = "Joe Washington"; + * let newLastName = "Fernandez"; + * The new value for "fullName" should result in "Joe Fernandez". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/04-combine-strings/04-combine-text.html b/exercises/04-combine-strings/04-combine-text.html new file mode 100644 index 0000000..9be95ee --- /dev/null +++ b/exercises/04-combine-strings/04-combine-text.html @@ -0,0 +1,56 @@ + + + + + + + + EXERCISE + + + +
+
+ + +
+
+ + +
+ +
+ + + diff --git a/test/04-combine-strings/combine-strings-helper.js b/test/04-combine-strings/combine-strings-helper.js new file mode 100644 index 0000000..cd0bd69 --- /dev/null +++ b/test/04-combine-strings/combine-strings-helper.js @@ -0,0 +1,28 @@ +import { getAnswer } from "../getAnswer.js"; + +const getBookTitleConcatStr = getAnswer( + "../exercises/04-combine-strings/01-concatenate-operator.js" +); + +const getBookTitleTemplateStr = getAnswer( + "../exercises/04-combine-strings/02-template-literals.js" +); + +const replaceLastNameAnswer = getAnswer( + "../exercises/04-combine-strings/03-replace-last-name.js" +); + +export const getBookTitleConcat = eval(`(bookTitle, author) => { + ${getBookTitleConcatStr} + return bookInfo; +}`); + +export const getBookTitleTemplate = eval(`(bookTitle, author) => { + ${getBookTitleTemplateStr} + return bookInfo; +}`); + +export const replaceLastName = eval(`(fullName, newLastName) => { + ${replaceLastNameAnswer} + return fullName; +}`); diff --git a/test/04-combine-strings/combine-strings.spec.js b/test/04-combine-strings/combine-strings.spec.js new file mode 100644 index 0000000..eccf326 --- /dev/null +++ b/test/04-combine-strings/combine-strings.spec.js @@ -0,0 +1,51 @@ +import { expect } from "chai"; +import { + getBookTitleConcat, + getBookTitleTemplate, + replaceLastName, +} from "./combine-strings-helper.js"; + +describe("4. Combine Strings", () => { + describe("01-concatenate-operator", () => { + it('should contain a variable "bookInfo" that is bookTitle + by + author (e.g. Harry Potter and the Sorcerer\'s Stone by J. K. Rowling)', () => { + const title = getBookTitleConcat( + "The Lord of the Rings", + "J.R.R. Tolkien" + ); + expect(title) + .to.be.a("string") + .to.equal("The Lord of the Rings by J.R.R. Tolkien"); + }); + it("should use the concatenation operator (the plus sign) to combine values into a string", () => { + const funcStr = getBookTitleConcat.toString(); + const parts = funcStr.split("+"); + expect(parts.length).to.be.greaterThanOrEqual(3); + }); + }); + + describe("02-template-literals", () => { + it('should contain a variable "bookInfo" that is bookTitle + by + author (e.g. Harry Potter and the Sorcerer\'s Stone by J. K. Rowling)', () => { + const title = getBookTitleTemplate( + "The Lord of the Rings", + "J.R.R. Tolkien" + ); + console.log(title); + expect(title) + .to.be.a("string") + .to.equal("The Lord of the Rings by J.R.R. Tolkien"); + }); + it("should use the concatenation operator (the plus sign) to combine values into a string", () => { + const funcStr = getBookTitleTemplate.toString(); + const parts = funcStr.split("`"); + expect(parts.length).to.be.greaterThanOrEqual(3); + const pieces = funcStr.split("$"); + expect(pieces.length).to.be.greaterThanOrEqual(3); + }); + }); + + describe("03-replace-last-name", () => { + it('"fullName" should be equal to a person\'s new name', () => { + expect(replaceLastName("Gordon Ramsey", "Smith")).equal("Gordon Smith"); + }); + }); +}); From fbf7fca4546f905bca0208a9ce0c40a01dc07718 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 2 Oct 2022 17:08:02 -0400 Subject: [PATCH 012/105] Coercion exercises --- .vscode/launch.json | 13 ++++ .../05-coercion/01-convert-string-to-int.js | 8 +++ .../05-coercion/02-fix-coercion-error.js | 12 ++++ .../05-coercion/03-fix-coercion-input.html | 60 +++++++++++++++++++ test/05-coercion/coercion-test-helper.js | 19 ++++++ test/05-coercion/coercion.spec.js | 19 ++++++ 6 files changed, 131 insertions(+) create mode 100644 exercises/05-coercion/01-convert-string-to-int.js create mode 100644 exercises/05-coercion/02-fix-coercion-error.js create mode 100644 exercises/05-coercion/03-fix-coercion-input.html create mode 100644 test/05-coercion/coercion-test-helper.js create mode 100644 test/05-coercion/coercion.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index e9578a5..19ba327 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -69,5 +69,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "5. Coercion", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/05-coercion/coercion.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/05-coercion/01-convert-string-to-int.js b/exercises/05-coercion/01-convert-string-to-int.js new file mode 100644 index 0000000..bd5e5ad --- /dev/null +++ b/exercises/05-coercion/01-convert-string-to-int.js @@ -0,0 +1,8 @@ +let answer = "55"; // e.g. + +/** + * You will change the value of "answer" below. Cast (convert) "answer", which is a string, so that it is an integer. + * This should still work when "answer" is a different numeric value (e.g. "105", "-5", "1.23") + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/05-coercion/02-fix-coercion-error.js b/exercises/05-coercion/02-fix-coercion-error.js new file mode 100644 index 0000000..eaa9b07 --- /dev/null +++ b/exercises/05-coercion/02-fix-coercion-error.js @@ -0,0 +1,12 @@ +let num1 = 2; // e.g. +let num2 = "7"; // e.g. + +/** + * If I were to log the code below, it does not print out what I would expect. + * For example, I expect "sum" to result in the number 7 instead of the string "27". + * This should still work when "num1" and "num2" are equal to different values that could be strings or numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let sum = num1 + num2; diff --git a/exercises/05-coercion/03-fix-coercion-input.html b/exercises/05-coercion/03-fix-coercion-input.html new file mode 100644 index 0000000..334d6ae --- /dev/null +++ b/exercises/05-coercion/03-fix-coercion-input.html @@ -0,0 +1,60 @@ + + + + + + + + EXERCISE + + + + +
+ + + + + = + 0 +
+ + + diff --git a/test/05-coercion/coercion-test-helper.js b/test/05-coercion/coercion-test-helper.js new file mode 100644 index 0000000..075ae1e --- /dev/null +++ b/test/05-coercion/coercion-test-helper.js @@ -0,0 +1,19 @@ +import { getAnswer } from "../getAnswer.js"; + +const convertStringToIntAnswer = getAnswer( + "../exercises/05-coercion/01-convert-string-to-int.js" +); + +const fixCoercionErrorAnswer = getAnswer( + "../exercises/05-coercion/02-fix-coercion-error.js" +); + +export const convertStringToInt = eval(`(answer) => { + ${convertStringToIntAnswer} + return answer; +}`); + +export const fixCoercionError = eval(`(num1, num2) => { + ${fixCoercionErrorAnswer} + return sum; +}`); diff --git a/test/05-coercion/coercion.spec.js b/test/05-coercion/coercion.spec.js new file mode 100644 index 0000000..0546422 --- /dev/null +++ b/test/05-coercion/coercion.spec.js @@ -0,0 +1,19 @@ +import { expect } from "chai"; +import { + convertStringToInt, + fixCoercionError, +} from "./coercion-test-helper.js"; + +describe("5. Coercion", () => { + describe("01-convert-string-to-int", () => { + it('"answer" should be cast as (converted to) an integer', () => { + expect(convertStringToInt("5")).to.be.a("number").equal(5); + }); + }); + + describe("02-fix-coercion-error", () => { + it('"sum" should be a number that is equal to "num1" plus "num2". It should not be a string.', () => { + expect(fixCoercionError("3", 5)).to.be.a("number").equal(8); + }); + }); +}); From e2897f9f7d2f25783dc9c52ba57b3902124e0427 Mon Sep 17 00:00:00 2001 From: Matina Patsos Date: Mon, 17 Oct 2022 20:28:47 -0400 Subject: [PATCH 013/105] Remove instructions on making a pull requests --- docs/SubmittingAssignments.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/docs/SubmittingAssignments.md b/docs/SubmittingAssignments.md index f2ef49a..df20b0a 100644 --- a/docs/SubmittingAssignments.md +++ b/docs/SubmittingAssignments.md @@ -20,21 +20,3 @@ In your terminal (in Visual Studio Code), type: ``` git push origin main ``` - -## Make A Pull Request - -You will then need to make pull request from Github. Here is how you will do that: - -1. Open a browser (Chrome, Edge, Safari, Firefox, etc) and go to https://github.com/ -2. If you are not signed in, signin -3. In the top right, click on your avatar and select "Your repositories" - -![Open your repositories in Github](img/git-your-repositories.png) - -4. Select _JSFunFall2022_ -5. Click on the "Contribute" dropdown and click on the "Open pull request" button - -![Opening a pull request](img/open-pull-request.png) - -6. Click on the "Create pull requests" button -7. Give your pull request a title if it does not have one and click on the "Create pull requests" button From 43142cbca3a99accbfd59a9506930f417310d67e Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 19 Oct 2022 17:29:05 -0400 Subject: [PATCH 014/105] Solutions for combine strings and coercion --- .../01-concatenate-operator.solution.js | 20 +++++++ .../02-template-literals.solution.js | 20 +++++++ .../03-replace-last-name.solution.js | 22 +++++++ .../04-combine-text.solution.html | 56 +++++++++++++++++ .../05-coercion/01-convert-string-to-int.js | 10 ++++ .../05-coercion/02-fix-coercion-error.js | 12 ++++ .../05-coercion/03-fix-coercion-input.html | 60 +++++++++++++++++++ 7 files changed, 200 insertions(+) create mode 100644 solutions/04-combine-strings/01-concatenate-operator.solution.js create mode 100644 solutions/04-combine-strings/02-template-literals.solution.js create mode 100644 solutions/04-combine-strings/03-replace-last-name.solution.js create mode 100644 solutions/04-combine-strings/04-combine-text.solution.html create mode 100644 solutions/05-coercion/01-convert-string-to-int.js create mode 100644 solutions/05-coercion/02-fix-coercion-error.js create mode 100644 solutions/05-coercion/03-fix-coercion-input.html diff --git a/solutions/04-combine-strings/01-concatenate-operator.solution.js b/solutions/04-combine-strings/01-concatenate-operator.solution.js new file mode 100644 index 0000000..c658654 --- /dev/null +++ b/solutions/04-combine-strings/01-concatenate-operator.solution.js @@ -0,0 +1,20 @@ +let bookTitle = "Harry Potter and the Sorcerer's Stone"; +let author = "J. K. Rowling"; + +/** + * Use the concatenation operator (the plus sign) to solve this problem. + * + * Create a variable called "bookInfo". It should combine the variables "bookTitle" and "author" together + * so that if I were to log "bookInfo", it would say: + * Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * @example + * // Declare "bookTitle" + * console.log(bookTitle); // Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * This should still work when "bookTitle" and "author" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let bookInfo = bookTitle + " by " + author; diff --git a/solutions/04-combine-strings/02-template-literals.solution.js b/solutions/04-combine-strings/02-template-literals.solution.js new file mode 100644 index 0000000..e4fc197 --- /dev/null +++ b/solutions/04-combine-strings/02-template-literals.solution.js @@ -0,0 +1,20 @@ +let bookTitle = "Harry Potter and the Sorcerer's Stone"; +let author = "J. K. Rowling"; + +/** + * This exercise is the same as the previous, except you will use template literals to solve this problem. + * + * Create a variable called "bookInfo". It should combine the variables "bookTitle" and "author" together + * so that if I were to log "bookInfo", it would say: + * Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * @example + * // Declare "bookTitle" + * console.log(bookTitle); // Harry Potter and the Sorcerer's Stone by J. K. Rowling + * + * This should still work when "bookTitle" and "author" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let bookInfo = `${bookTitle} by ${author}`; diff --git a/solutions/04-combine-strings/03-replace-last-name.solution.js b/solutions/04-combine-strings/03-replace-last-name.solution.js new file mode 100644 index 0000000..e57622c --- /dev/null +++ b/solutions/04-combine-strings/03-replace-last-name.solution.js @@ -0,0 +1,22 @@ +let fullName = "Joe Washington"; // e.g. +let newLastName = "Fernandez"; // e.g. + +/** + * A person just got married and they need their last name replaced. You will change the value of "fullName" below. Replace the last name in "fullName" with "newLastName". + * + * @example + * let fullName = "Emily Rose"; + * let newLastName = "Smith"; + * The new value for "fullName" should result in "Emily Smith". + * + * @example + * let fullName = "Joe Washington"; + * let newLastName = "Fernandez"; + * The new value for "fullName" should result in "Joe Fernandez". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let index = fullName.indexOf(" "); +fullName = fullName.substring(0, index); +fullName += newLastName; diff --git a/solutions/04-combine-strings/04-combine-text.solution.html b/solutions/04-combine-strings/04-combine-text.solution.html new file mode 100644 index 0000000..20e1831 --- /dev/null +++ b/solutions/04-combine-strings/04-combine-text.solution.html @@ -0,0 +1,56 @@ + + + + + + + + EXERCISE + + + +
+
+ + +
+
+ + +
+ +
+ + + diff --git a/solutions/05-coercion/01-convert-string-to-int.js b/solutions/05-coercion/01-convert-string-to-int.js new file mode 100644 index 0000000..d2476e1 --- /dev/null +++ b/solutions/05-coercion/01-convert-string-to-int.js @@ -0,0 +1,10 @@ +let answer = "55"; // e.g. + +/** + * You will change the value of "answer" below. Cast (convert) "answer", which is a string, so that it is an integer. + * This should still work when "answer" is a different numeric value (e.g. "105", "-5", "1.23") + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +answer = parseInt(answer); diff --git a/solutions/05-coercion/02-fix-coercion-error.js b/solutions/05-coercion/02-fix-coercion-error.js new file mode 100644 index 0000000..289e17c --- /dev/null +++ b/solutions/05-coercion/02-fix-coercion-error.js @@ -0,0 +1,12 @@ +let num1 = 2; // e.g. +let num2 = "7"; // e.g. + +/** + * If I were to log the code below, it does not print out what I would expect. + * For example, I expect "sum" to result in the number 7 instead of the string "27". + * This should still work when "num1" and "num2" are equal to different values that could be strings or numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let sum = parseFloat(num1) + parseFloat(num2); diff --git a/solutions/05-coercion/03-fix-coercion-input.html b/solutions/05-coercion/03-fix-coercion-input.html new file mode 100644 index 0000000..221e121 --- /dev/null +++ b/solutions/05-coercion/03-fix-coercion-input.html @@ -0,0 +1,60 @@ + + + + + + + + EXERCISE + + + + +
+ + + + + = + 0 +
+ + + From 977d040e540c1281bd483218ef59bc7540538a32 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 16 Oct 2022 15:01:20 -0400 Subject: [PATCH 015/105] Control flow exercises --- .vscode/launch.json | 13 +++ exercises/06-control-flow/01-if-statement.js | 19 ++++ exercises/06-control-flow/02-if-statement.js | 15 ++++ .../06-control-flow/03-if-statement.html | 87 +++++++++++++++++++ .../control-flow-test-helper.js | 19 ++++ .../control-flow-test-helper.spec.js | 24 +++++ 6 files changed, 177 insertions(+) create mode 100644 exercises/06-control-flow/01-if-statement.js create mode 100644 exercises/06-control-flow/02-if-statement.js create mode 100644 exercises/06-control-flow/03-if-statement.html create mode 100644 test/06-control-flow/control-flow-test-helper.js create mode 100644 test/06-control-flow/control-flow-test-helper.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 19ba327..1df13c5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -82,5 +82,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "6. Control Flow", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/06-control-flow/control-flow-test-helper.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/06-control-flow/01-if-statement.js b/exercises/06-control-flow/01-if-statement.js new file mode 100644 index 0000000..05773f5 --- /dev/null +++ b/exercises/06-control-flow/01-if-statement.js @@ -0,0 +1,19 @@ +const burger = 7.0; // e.g. +const drink = 1.99; // e.g. + +let total = burger; + +let isBuyingDrink = true; // e.g. + +/** + * At the "Happy Burger", you have two choices: + * - A burger ($7.00) + * - A burger ($7.00) and a drink ($1.99) + * + * If "isBuyingDrink" is true, add the cost of "drink" to the "total". + * If "isBuyingDrink" is false, do not change the cost. + * + * This should still work when "burger" and "drink" are equal to different numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/06-control-flow/02-if-statement.js b/exercises/06-control-flow/02-if-statement.js new file mode 100644 index 0000000..71aedd6 --- /dev/null +++ b/exercises/06-control-flow/02-if-statement.js @@ -0,0 +1,15 @@ +let subtotal = 50.0; // e.g. +let tip = 0.2; // e.g. + +let total; + +/** + * If a customer leaves a tip, change the variable "total" + * so that it is equal to the subtotal plus the subtotal times the tip. + * + * If a customer does not leave a tip (that is, "tip" equals 0), "total" should equal the "subtotal". + * + * This should still work when "subtotal" and "total" are equal to different numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/06-control-flow/03-if-statement.html b/exercises/06-control-flow/03-if-statement.html new file mode 100644 index 0000000..4cc95ed --- /dev/null +++ b/exercises/06-control-flow/03-if-statement.html @@ -0,0 +1,87 @@ + + + + + + + + EXERCISE + + + + +
+

+
+ + + + + +
+ +
+ + + diff --git a/test/06-control-flow/control-flow-test-helper.js b/test/06-control-flow/control-flow-test-helper.js new file mode 100644 index 0000000..f9d2474 --- /dev/null +++ b/test/06-control-flow/control-flow-test-helper.js @@ -0,0 +1,19 @@ +import { getAnswer } from "../getAnswer.js"; + +const addDrinkStr = getAnswer( + "../exercises/06-control-flow/01-if-statement.js" +); + +const addTipStr = getAnswer("../exercises/06-control-flow/02-if-statement.js"); + +export const addDrink = eval(`(burger, drink, isBuyingDrink) => { + let total = burger; + ${addDrinkStr} + return total; +}`); + +export const addTip = eval(`(subtotal, tip) => { + let total; + ${addTipStr} + return total; +}`); diff --git a/test/06-control-flow/control-flow-test-helper.spec.js b/test/06-control-flow/control-flow-test-helper.spec.js new file mode 100644 index 0000000..48453c1 --- /dev/null +++ b/test/06-control-flow/control-flow-test-helper.spec.js @@ -0,0 +1,24 @@ +import { expect } from "chai"; +import { addDrink, addTip } from "./control-flow-test-helper.js"; + +describe("6. Control Flow", () => { + describe("01-if-statement.js", () => { + it('should add "drink" to the variable "total" if "isBuyingDrink" is true"', () => { + expect(addDrink(6.95, 1.99, true)).to.be.a("number").to.equal(8.94); + }); + + it('should only change the value of "total" if "isBuyingDrink" is true', () => { + expect(addDrink(6.95, 1.99, false)).to.be.a("number").to.equal(6.95); + }); + }); + + describe("02-if-statement.js", () => { + it('"total" should equal to "subtotal" + ("subtotal" * "tip") if tip is greater than 0', () => { + expect(addTip(25, 0.1)).to.be.a("number").to.equal(27.5); + }); + + it('"total" should equal "subtotal" if "tip" is 0', () => { + expect(addTip(25.78, 0)).to.be.a("number").to.equal(25.78); + }); + }); +}); From 52764a3c5f4405dc3f035f399e47e9518ffca28e Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 16 Oct 2022 16:07:04 -0400 Subject: [PATCH 016/105] Comparisons exercise --- .vscode/launch.json | 13 +++ exercises/07-comparisons/01-is-equal.js | 14 +++ exercises/07-comparisons/02-is-not-equal.js | 13 +++ .../07-comparisons/03-is-larger-number.js | 12 ++ exercises/07-comparisons/04-is-teenager.js | 11 ++ exercises/07-comparisons/05-is-weekend.js | 11 ++ exercises/07-comparisons/06-is-even.js | 10 ++ .../07-comparisons/comparisons-test-helper.js | 51 +++++++++ test/07-comparisons/comparisons.spec.js | 106 ++++++++++++++++++ 9 files changed, 241 insertions(+) create mode 100644 exercises/07-comparisons/01-is-equal.js create mode 100644 exercises/07-comparisons/02-is-not-equal.js create mode 100644 exercises/07-comparisons/03-is-larger-number.js create mode 100644 exercises/07-comparisons/04-is-teenager.js create mode 100644 exercises/07-comparisons/05-is-weekend.js create mode 100644 exercises/07-comparisons/06-is-even.js create mode 100644 test/07-comparisons/comparisons-test-helper.js create mode 100644 test/07-comparisons/comparisons.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 1df13c5..8e51b0f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -95,5 +95,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "7. Comparisons", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/07-comparisons/comparisons.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/07-comparisons/01-is-equal.js b/exercises/07-comparisons/01-is-equal.js new file mode 100644 index 0000000..99304e4 --- /dev/null +++ b/exercises/07-comparisons/01-is-equal.js @@ -0,0 +1,14 @@ +let isEqual; + +let userInput1 = 39; // e,g, +let userInput2 = "39"; // e,g, + +/** + * You will be changing the value of "isEqual" below. + * If "userInput1" strictly equals "userInput2", "isEqual" should be true. + * Otherwise, it should be false. + * Hint: What does strictly mean? + * Your answer should still work when "userInput1" and "userInput2" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/07-comparisons/02-is-not-equal.js b/exercises/07-comparisons/02-is-not-equal.js new file mode 100644 index 0000000..0bb48c1 --- /dev/null +++ b/exercises/07-comparisons/02-is-not-equal.js @@ -0,0 +1,13 @@ +let isNotAtGoalWeight; + +let targetBMI = 24; // e.g. +let actualBMI = 27; // e.g. + +/** + * You will be changing the value of "isNotAtGoalWeight" below. + * If "targetBMI" equals "actualBMI", then "isNotAtGoalWeight" should be false. + * If "targetBMI" does not equal "actualBMI", "isNotAtGoalWeight" should be true. + * Your answer should still work when "targetBMI" and "actualBMI" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/07-comparisons/03-is-larger-number.js b/exercises/07-comparisons/03-is-larger-number.js new file mode 100644 index 0000000..f78d1d8 --- /dev/null +++ b/exercises/07-comparisons/03-is-larger-number.js @@ -0,0 +1,12 @@ +let num1 = 15; // e.g. +let num2 = 20; // e.g. + +/** + * Create a variable called "isLargerNumber". (Do not use var.) + * If "num2" is larger than "num1", than "isLargerNumber" should be true. + * If "num1" is larger than "num2", than "isLargerNumber" should be false. + * If "num1" and "num2" are equal, than "isLargerNumber" should be false. + * Your answer should still work when "num1" and "num2" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/07-comparisons/04-is-teenager.js b/exercises/07-comparisons/04-is-teenager.js new file mode 100644 index 0000000..19abbbb --- /dev/null +++ b/exercises/07-comparisons/04-is-teenager.js @@ -0,0 +1,11 @@ +let age = 14; // e.g. + +/** + * Create a variable called "isTeenager". (Do not use var.) + * If "age" is greater than 12, but less than 20, "isTeenager" should be true. + * Otherwise, "isTeenager" should be false. + * You must use either the logical and (&&) or the logical or (||) to solve this problem. + * Your answer should still work when "age" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/07-comparisons/05-is-weekend.js b/exercises/07-comparisons/05-is-weekend.js new file mode 100644 index 0000000..4da6baf --- /dev/null +++ b/exercises/07-comparisons/05-is-weekend.js @@ -0,0 +1,11 @@ +let day = "Saturday"; + +/** + * Create a variable called "isWeekend". (Do not use var.) + * If "day" is Saturday or Sunday, "isWeekend" should be true. + * Otherwise "isWeekend" should be false. + * You must use either the logical and (&&) or the logical or (||) to solve this problem. + * Your answer should still work when "day" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/07-comparisons/06-is-even.js b/exercises/07-comparisons/06-is-even.js new file mode 100644 index 0000000..c98e684 --- /dev/null +++ b/exercises/07-comparisons/06-is-even.js @@ -0,0 +1,10 @@ +let num = 8; // e.g. + +/** + * Create a variable called "isEven". (Do not use var.) + * If "num" is even, "isEven" should be true. + * Otherwise, "isEven" should be false. + * Your answer should still work when "num" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/07-comparisons/comparisons-test-helper.js b/test/07-comparisons/comparisons-test-helper.js new file mode 100644 index 0000000..5a5d1f4 --- /dev/null +++ b/test/07-comparisons/comparisons-test-helper.js @@ -0,0 +1,51 @@ +import { getAnswer } from "../getAnswer.js"; + +const isEqualStr = getAnswer("../exercises/07-comparisons/01-is-equal.js"); + +const isNotEqualStr = getAnswer( + "../exercises/07-comparisons/02-is-not-equal.js" +); + +const isLargerNumberStr = getAnswer( + "../exercises/07-comparisons/03-is-larger-number.js" +); + +const isTeenagerStr = getAnswer( + "../exercises/07-comparisons/04-is-teenager.js" +); + +const isWeekendStr = getAnswer("../exercises/07-comparisons/05-is-weekend.js"); + +const isEvenStr = getAnswer("../exercises/07-comparisons/06-is-even.js"); + +export const isEqual = eval(`(userInput1, userInput2) => { + let isEqual; + ${isEqualStr} + return isEqual; +}`); + +export const isNotEqual = eval(`(targetBMI, actualBMI) => { + let isNotAtGoalWeight; + ${isNotEqualStr} + return isNotAtGoalWeight; +}`); + +export const isLargerNumber = eval(`(num1, num2) => { + ${isLargerNumberStr} + return isLargerNumber; +}`); + +export const isTeenager = eval(`(age) => { + ${isTeenagerStr} + return isTeenager; +}`); + +export const isWeekend = eval(`(day) => { + ${isWeekendStr} + return isWeekend; +}`); + +export const isEven = eval(`(num) => { + ${isEvenStr} + return isEven; +}`); diff --git a/test/07-comparisons/comparisons.spec.js b/test/07-comparisons/comparisons.spec.js new file mode 100644 index 0000000..c2b2ee6 --- /dev/null +++ b/test/07-comparisons/comparisons.spec.js @@ -0,0 +1,106 @@ +import { expect } from "chai"; +import { + isEqual, + isNotEqual, + isLargerNumber, + isTeenager, + isWeekend, + isEven, +} from "./comparisons-test-helper.js"; + +describe("7. Comparisons", () => { + describe("01-is-equal", () => { + it('"isEqual" should be true when "userInput1" strictly equals "userInput2', () => { + expect(isEqual(5, 5)).to.be.true; + expect(isEqual("5", "5")).to.be.true; + }); + it('"isEqual" should be false when "userInput1" does not strictly equal "userInput2', () => { + expect(isEqual(5, -5)).to.be.false; + expect(isEqual(5, "5")).to.be.false; + }); + }); + + describe("02-is-not-equal", () => { + it('"isNotAtGoalWeight" should be false when "targetBMI" equals "actualBMI"', () => { + expect(isNotEqual(20, 20)).to.be.false; + }); + it('"isNotAtGoalWeight" should be true when "targetBMI" does not equal "actualBMI"', () => { + expect(isNotEqual(20, 31)).to.be.true; + }); + }); + + describe("03-is-larger-number", () => { + it('should contain a variable called "isLargerNumber"', () => { + const isLargerNumberStr = isLargerNumber.toString(); + expect(isLargerNumberStr).to.match(/let isLargerNumber/); + }); + it('"isLargerNumber" should be true when "num2" is greater than "num1"', () => { + expect(isLargerNumber(1, 999999)).to.be.true; + }); + it('"isLargerNumber" should be false when "num1" is greater than "num2"', () => { + expect(isLargerNumber(1.1, -555)).to.be.false; + }); + it('"isLargerNumber" should be false when "num1" is equal to "num2"', () => { + expect(isLargerNumber(3, 3)).to.be.false; + }); + }); + + describe("04-is-teenager", () => { + it('should contain a variable called "isTeenager"', () => { + const isTeenagerStr = isTeenager.toString(); + expect(isTeenagerStr).to.match(/let isTeenager/); + }); + it('"isTeenager" should be true when ages is between 13 and 19', () => { + expect(isTeenager(13)).to.be.true; + expect(isTeenager(15)).to.be.true; + expect(isTeenager(19)).to.be.true; + }); + it('"isTeenager" should be false when ages is less than 13', () => { + expect(isTeenager(12)).to.be.false; + expect(isTeenager(0)).to.be.false; + }); + it('"isTeenager" should be false when ages is greater than 19', () => { + expect(isTeenager(20)).to.be.false; + expect(isTeenager(95)).to.be.false; + }); + it("should use either the logical and (&&) or the logical or (||)", () => { + const isTeenagerStr = isTeenager.toString(); + expect(isTeenagerStr).to.match(/&&|\|\|/); + }); + }); + + describe("05-is-weekend", () => { + it('should contain a variable called "isWeekend"', () => { + const isWeekendStr = isWeekend.toString(); + expect(isWeekendStr).to.match(/let isWeekend/); + }); + it('"isWeekend" should be true if "day" is "Saturday" or "Sunday"', () => { + expect(isWeekend("Saturday")).to.be.true; + expect(isWeekend("Sunday")).to.be.true; + }); + it('"isWeekend" should be false if "day" is any other day of the week', () => { + expect(isWeekend("Monday")).to.be.false; + expect(isWeekend("Tuesday")).to.be.false; + expect(isWeekend("Wednesday")).to.be.false; + expect(isWeekend("Thursday")).to.be.false; + expect(isWeekend("Friday")).to.be.false; + }); + it("should use either the logical and (&&) or the logical or (||)", () => { + const isWeekendStr = isWeekend.toString(); + expect(isWeekendStr).to.match(/&&|\|\|/); + }); + }); + + describe("06-is-even", () => { + it('should contain a variable called "isEven"', () => { + const isEvenStr = isEven.toString(); + expect(isEvenStr).to.match(/let isEven/); + }); + it('"isEven" should be true if "num" is even', () => { + expect(isEven(22)).to.be.true; + }); + it('"isEven" should be false if "num" is odd', () => { + expect(isEven(9)).to.be.false; + }); + }); +}); From 96ff2d6795b6937376898a590bdfc8b889037286 Mon Sep 17 00:00:00 2001 From: dreman8~ Date: Thu, 20 Oct 2022 18:48:03 -0400 Subject: [PATCH 017/105] add my name to the list --- exercises/00-git/IntroductionGit.md | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/00-git/IntroductionGit.md b/exercises/00-git/IntroductionGit.md index 8b1312e..ee65f04 100644 --- a/exercises/00-git/IntroductionGit.md +++ b/exercises/00-git/IntroductionGit.md @@ -14,3 +14,4 @@ - Michele Edington - Hal Katzman - Michelle Waldenmaier +-Andre Price From ddc4fcdb17edd3a5a401fc95bf9b36c25aa0aa33 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 23 Oct 2022 15:50:29 -0400 Subject: [PATCH 018/105] Solutions for control flow and comparison exercises --- exercises/00-git/IntroductionGit.md | 2 +- .../01-if-statement.solution.js | 23 +++++ .../02-if-statement.solution.js | 21 +++++ .../03-if-statement.solution.html | 90 +++++++++++++++++++ solutions/07-comparisons/01-is-equal.js | 24 +++++ solutions/07-comparisons/02-is-not-equal.js | 23 +++++ .../07-comparisons/03-is-larger-number.js | 31 +++++++ solutions/07-comparisons/04-is-teenager.js | 28 ++++++ solutions/07-comparisons/05-is-weekend.js | 28 ++++++ solutions/07-comparisons/06-is-even.js | 27 ++++++ 10 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 solutions/06-control-flow/01-if-statement.solution.js create mode 100644 solutions/06-control-flow/02-if-statement.solution.js create mode 100644 solutions/06-control-flow/03-if-statement.solution.html create mode 100644 solutions/07-comparisons/01-is-equal.js create mode 100644 solutions/07-comparisons/02-is-not-equal.js create mode 100644 solutions/07-comparisons/03-is-larger-number.js create mode 100644 solutions/07-comparisons/04-is-teenager.js create mode 100644 solutions/07-comparisons/05-is-weekend.js create mode 100644 solutions/07-comparisons/06-is-even.js diff --git a/exercises/00-git/IntroductionGit.md b/exercises/00-git/IntroductionGit.md index ee65f04..446fca7 100644 --- a/exercises/00-git/IntroductionGit.md +++ b/exercises/00-git/IntroductionGit.md @@ -14,4 +14,4 @@ - Michele Edington - Hal Katzman - Michelle Waldenmaier --Andre Price +- Andre Price diff --git a/solutions/06-control-flow/01-if-statement.solution.js b/solutions/06-control-flow/01-if-statement.solution.js new file mode 100644 index 0000000..07a855f --- /dev/null +++ b/solutions/06-control-flow/01-if-statement.solution.js @@ -0,0 +1,23 @@ +const burger = 7.0; // e.g. +const drink = 1.99; // e.g. + +let total = burger; + +let isBuyingDrink = true; // e.g. + +/** + * At the "Happy Burger", you have two choices: + * - A burger ($7.00) + * - A burger ($7.00) and a drink ($1.99) + * + * If "isBuyingDrink" is true, add the cost of "drink" to the "total". + * If "isBuyingDrink" is false, do not change the cost. + * + * This should still work when "burger" and "drink" are equal to different numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +if (isBuyingDrink) { + total = total + drink; +} diff --git a/solutions/06-control-flow/02-if-statement.solution.js b/solutions/06-control-flow/02-if-statement.solution.js new file mode 100644 index 0000000..592c23d --- /dev/null +++ b/solutions/06-control-flow/02-if-statement.solution.js @@ -0,0 +1,21 @@ +let subtotal = 50.0; // e.g. +let tip = 0.2; // e.g. + +let total; + +/** + * If a customer leaves a tip, change the variable "total" + * so that it is equal to the subtotal plus the subtotal times the tip. + * + * If a customer does not leave a tip (that is, "tip" equals 0), "total" should equal the "subtotal". + * + * This should still work when "subtotal" and "total" are equal to different numbers. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +if (tip) { + total = subtotal + subtotal * tip; +} else { + total = subtotal; +} diff --git a/solutions/06-control-flow/03-if-statement.solution.html b/solutions/06-control-flow/03-if-statement.solution.html new file mode 100644 index 0000000..fe54b5f --- /dev/null +++ b/solutions/06-control-flow/03-if-statement.solution.html @@ -0,0 +1,90 @@ + + + + + + + + EXERCISE + + + + +
+

+
+ + + + + +
+ +
+ + + diff --git a/solutions/07-comparisons/01-is-equal.js b/solutions/07-comparisons/01-is-equal.js new file mode 100644 index 0000000..f5770c5 --- /dev/null +++ b/solutions/07-comparisons/01-is-equal.js @@ -0,0 +1,24 @@ +let isEqual; + +let userInput1 = 39; // e,g, +let userInput2 = "39"; // e,g, + +/** + * You will be changing the value of "isEqual" below. + * If "userInput1" strictly equals "userInput2", "isEqual" should be true. + * Otherwise, it should be false. + * Hint: What does strictly mean? + * Your answer should still work when "userInput1" and "userInput2" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Method 1 +if (userInput1 === userInput2) { + isEqual = true; +} else { + isEqual = false; +} + +// Method 2 +isEqual = userInput1 === userInput2; diff --git a/solutions/07-comparisons/02-is-not-equal.js b/solutions/07-comparisons/02-is-not-equal.js new file mode 100644 index 0000000..ae00c48 --- /dev/null +++ b/solutions/07-comparisons/02-is-not-equal.js @@ -0,0 +1,23 @@ +let isNotAtGoalWeight; + +let targetBMI = 24; // e.g. +let actualBMI = 27; // e.g. + +/** + * You will be changing the value of "isNotAtGoalWeight" below. + * If "targetBMI" equals "actualBMI", then "isNotAtGoalWeight" should be false. + * If "targetBMI" does not equal "actualBMI", "isNotAtGoalWeight" should be true. + * Your answer should still work when "targetBMI" and "actualBMI" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Method 1 +if (targetBMI !== actualBMI) { + isNotAtGoalWeight = true; +} else { + isNotAtGoalWeight = false; +} + +// Method 2 +isNotAtGoalWeight = targetBMI !== actualBMI; diff --git a/solutions/07-comparisons/03-is-larger-number.js b/solutions/07-comparisons/03-is-larger-number.js new file mode 100644 index 0000000..e462f13 --- /dev/null +++ b/solutions/07-comparisons/03-is-larger-number.js @@ -0,0 +1,31 @@ +let num1 = 15; // e.g. +let num2 = 20; // e.g. + +/** + * Create a variable called "isLargerNumber". (Do not use var.) + * If "num2" is larger than "num1", than "isLargerNumber" should be true. + * If "num1" is larger than "num2", than "isLargerNumber" should be false. + * If "num1" and "num2" are equal, than "isLargerNumber" should be false. + * Your answer should still work when "num1" and "num2" are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Method 1 +let isLargerNumber; +if (num2 > num1) { + isLargerNumber = true; +} else if (num1 >= num2) { + isLargerNumber = false; +} + +// Method 2 +let isLargerNumber; +if (num2 > num1) { + isLargerNumber = true; +} else { + isLargerNumber = false; +} + +// Method 3 +let isLargerNumber = num2 > num1; diff --git a/solutions/07-comparisons/04-is-teenager.js b/solutions/07-comparisons/04-is-teenager.js new file mode 100644 index 0000000..53fa661 --- /dev/null +++ b/solutions/07-comparisons/04-is-teenager.js @@ -0,0 +1,28 @@ +let age = 14; // e.g. + +/** + * Create a variable called "isTeenager". (Do not use var.) + * If "age" is greater than 12, but less than 20, "isTeenager" should be true. + * Otherwise, "isTeenager" should be false. + * You must use either the logical and (&&) or the logical or (||) to solve this problem. + * Your answer should still work when "age" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Method 1 +let isTeenager; +if (age > 12 && age < 20) { + isTeenager = true; +} else { + isTeenager = false; +} + +// Method 2 +let isTeenager = false; +if (age > 12 && age < 20) { + isTeenager = true; +} + +// Method 3 +let isTeenager = age > 12 && age < 20; diff --git a/solutions/07-comparisons/05-is-weekend.js b/solutions/07-comparisons/05-is-weekend.js new file mode 100644 index 0000000..8485080 --- /dev/null +++ b/solutions/07-comparisons/05-is-weekend.js @@ -0,0 +1,28 @@ +let day = "Saturday"; + +/** + * Create a variable called "isWeekend". (Do not use var.) + * If "day" is Saturday or Sunday, "isWeekend" should be true. + * Otherwise "isWeekend" should be false. + * You must use either the logical and (&&) or the logical or (||) to solve this problem. + * Your answer should still work when "day" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Method 1 +let isWeekend; +if (day === "Saturday" || day === "Sunday") { + isWeekend = true; +} else { + isWeekend = false; +} + +// Method 2 +let isWeekend = false; +if (day === "Saturday" || day === "Sunday") { + isWeekend = true; +} + +// Method 3 +let isWeekend = day === "Saturday" || day === "Sunday"; diff --git a/solutions/07-comparisons/06-is-even.js b/solutions/07-comparisons/06-is-even.js new file mode 100644 index 0000000..d550414 --- /dev/null +++ b/solutions/07-comparisons/06-is-even.js @@ -0,0 +1,27 @@ +let num = 8; // e.g. + +/** + * Create a variable called "isEven". (Do not use var.) + * If "num" is even, "isEven" should be true. + * Otherwise, "isEven" should be false. + * Your answer should still work when "num" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Method 1 +let isEven; +if (num % 2 === 0) { + isEven = true; +} else { + isEven = false; +} + +// Method 2 +let isEven = false; +if (num % 2 === 0) { + isEven = true; +} + +// Method 3 +let isEven = num % 2 === 0; From ca4f53375e12ef82bc368d01245e43661b4afd96 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 16 Oct 2022 16:22:18 -0400 Subject: [PATCH 019/105] Functions exercise --- .vscode/launch.json | 13 +++ exercises/08-functions/01-invoke-function.js | 16 ++++ exercises/08-functions/02-print-greeting.js | 12 +++ exercises/08-functions/03-return-greeting.js | 15 +++ exercises/08-functions/04-multiply.js | 18 ++++ .../08-functions/05-lower-case-string.js | 18 ++++ exercises/08-functions/06-is-even-or-odd.js | 14 +++ .../08-functions/07-count-number-of-digits.js | 12 +++ test/08-functions/functions-test-helper.js | 61 +++++++++++++ test/08-functions/functions.spec.js | 91 +++++++++++++++++++ test/getAnswer.js | 20 +++- 11 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 exercises/08-functions/01-invoke-function.js create mode 100644 exercises/08-functions/02-print-greeting.js create mode 100644 exercises/08-functions/03-return-greeting.js create mode 100644 exercises/08-functions/04-multiply.js create mode 100644 exercises/08-functions/05-lower-case-string.js create mode 100644 exercises/08-functions/06-is-even-or-odd.js create mode 100644 exercises/08-functions/07-count-number-of-digits.js create mode 100644 test/08-functions/functions-test-helper.js create mode 100644 test/08-functions/functions.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 8e51b0f..528d6e9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -108,5 +108,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "8. Functions", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/08-functions/functions.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/08-functions/01-invoke-function.js b/exercises/08-functions/01-invoke-function.js new file mode 100644 index 0000000..3f1a599 --- /dev/null +++ b/exercises/08-functions/01-invoke-function.js @@ -0,0 +1,16 @@ +/** + * @param {number} subtotal + * @param {number} tax + * @returns {number} the total cost, including the tax + */ +const calculateTotal = (subtotal, tax) => { + return subtotal * tax + subtotal; +}; + +/** + * You are paying your bill. You have a subtotal of $50.00 and tax is 2%. + * + * Create a variable called "total". The variable "total" should be equal to the result of "calculateTotal" (which is 60). + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/08-functions/02-print-greeting.js b/exercises/08-functions/02-print-greeting.js new file mode 100644 index 0000000..538db9f --- /dev/null +++ b/exercises/08-functions/02-print-greeting.js @@ -0,0 +1,12 @@ +/** + * Create a function named called "printGreeting". + * It should accept a "name" as a parameter + * and print "Hello ______!" with console.log + * + * @param {string} name + * + * @example printGreeting("Tim"); // Hello Tim! + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/08-functions/03-return-greeting.js b/exercises/08-functions/03-return-greeting.js new file mode 100644 index 0000000..57315c4 --- /dev/null +++ b/exercises/08-functions/03-return-greeting.js @@ -0,0 +1,15 @@ +/** + * Create a function named called "returnGreeting". + * It should accept a "name" as a parameter + * and return "Hello ______!" + * (This is similar to the last exercise, + * except you are returning a value instead of using console.log) + * + * @param {string} name + * @returns {string} "Hello name" + * + * @example returnGreeting("Tim"); // Hello Tim! + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/08-functions/04-multiply.js b/exercises/08-functions/04-multiply.js new file mode 100644 index 0000000..fd649ca --- /dev/null +++ b/exercises/08-functions/04-multiply.js @@ -0,0 +1,18 @@ +/** + * Create a function named "multiply". + * It should have two parameters: "num1" and "num2". + * Both parameters should be numbers. + * The function should return the product of both numbers. + * (In other words, multiply!) + * + * @param {number} num1 + * @param {number} num2 + * @returns {number} num1 x num2 + * + * @example timesFive(5); // 25 + * @example timesFive(2); // 10 + * @example timesFive(0); // 0 + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/08-functions/05-lower-case-string.js b/exercises/08-functions/05-lower-case-string.js new file mode 100644 index 0000000..b858ca8 --- /dev/null +++ b/exercises/08-functions/05-lower-case-string.js @@ -0,0 +1,18 @@ +/** + * Create a function called "lowerCaseString". + * If given a string, it should return the string lower cased. + * @example lowerCaseString("HELLO WORLD"); // hello world + * + * If given a value that is not a string, this function should not throw an error. + * @see https://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string-in-javascript + * HINT: you will need to exit out of the function early. + * + * @param {string} str + * @returns {string} str capitalized + * + * @example lowerCaseString(); // undefined (should not throw an error) + * @example lowerCaseString(null); // undefined (should not throw an error) + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/08-functions/06-is-even-or-odd.js b/exercises/08-functions/06-is-even-or-odd.js new file mode 100644 index 0000000..7863ce1 --- /dev/null +++ b/exercises/08-functions/06-is-even-or-odd.js @@ -0,0 +1,14 @@ +/** + * Create a function called "isEvenOrOdd". + * If given an even number, it should return "even". + * If given an odd number, it should return "odd". + * + * @param {number} num + * @returns {string} either "even" or "odd" + * + * @example isEvenOrOdd(10); // even + * @example isEvenOrOdd(3); // odd + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/08-functions/07-count-number-of-digits.js b/exercises/08-functions/07-count-number-of-digits.js new file mode 100644 index 0000000..88572e1 --- /dev/null +++ b/exercises/08-functions/07-count-number-of-digits.js @@ -0,0 +1,12 @@ +/** + * Create a function called "countNumberOfDigits". + * Given an integer, it should return the number of digits in an integer. + * + * @param {int} num + * @returns {int} the number of digits + * + * @example countNumberOfDigits(5000); // 4 + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/08-functions/functions-test-helper.js b/test/08-functions/functions-test-helper.js new file mode 100644 index 0000000..b0ad1be --- /dev/null +++ b/test/08-functions/functions-test-helper.js @@ -0,0 +1,61 @@ +import { getAnswer } from "../getAnswer.js"; + +const invokeFunctionStr = getAnswer( + "../exercises/08-functions/01-invoke-function.js" +); +const printGreetingStr = getAnswer( + "../exercises/08-functions/02-print-greeting.js" +); +const returnGreetingStr = getAnswer( + "../exercises/08-functions/03-return-greeting.js" +); +const multiplyString = getAnswer("../exercises/08-functions/04-multiply.js"); +const lowerCaseStringStr = getAnswer( + "../exercises/08-functions/05-lower-case-string.js" +); +const isEvenOrOddStr = getAnswer( + "../exercises/08-functions/06-is-even-or-odd.js" +); +const countNumberOfDigitsStr = getAnswer( + "../exercises/08-functions/07-count-number-of-digits.js" +); + +const invokeFunction = () => { + let calculateTotalArguments = []; + const calculateTotal = (...args) => { + calculateTotalArguments = args; + + const [subtotal, tax] = args; + return subtotal * tax + subtotal; + }; + const fn = eval(`() => { + try { + calculateTotalArguments = []; + ${invokeFunctionStr} + return total; + } catch (err) {} + }`); + return [fn(), calculateTotalArguments]; +}; + +const functions = Object.entries({ + printGreeting: printGreetingStr, + returnGreeting: returnGreetingStr, + multiply: multiplyString, + lowerCaseString: lowerCaseStringStr, + isEvenOrOdd: isEvenOrOddStr, + countNumberOfDigits: countNumberOfDigitsStr, +}).reduce((acc, [name, str]) => { + const fn = eval(`() => { + ${str}; + try { + return ${name}; + } catch (err) {} + }`); + acc[name] = fn(); + return acc; +}, {}); + +functions.invokeFunction = invokeFunction; + +export default functions; diff --git a/test/08-functions/functions.spec.js b/test/08-functions/functions.spec.js new file mode 100644 index 0000000..f095f56 --- /dev/null +++ b/test/08-functions/functions.spec.js @@ -0,0 +1,91 @@ +import { expect } from "chai"; +import { readConsole } from "../getAnswer.js"; +import functions from "./functions-test-helper.js"; +const { + invokeFunction, + printGreeting, + returnGreeting, + multiply, + lowerCaseString, + isEvenOrOdd, + countNumberOfDigits, +} = functions; + +describe("8. Functions", () => { + describe("01-invoke-function", () => { + it('should invoke the function "calculateTotal", passing in the subtotal of 50 and tax of 0.2 as arguments', () => { + const [, args] = invokeFunction(); + expect(args).to.deep.equal([50, 0.2]); + }); + it('"total" should equal 60 when the subtotal is $50 and the tax is 2%', () => { + const [total] = invokeFunction(); + expect(total).to.be.a("number").to.equal(60); + }); + }); + describe("02-print-greeting", () => { + it('should contain a function called "printGreeting" in arrow syntax', () => { + expect(printGreeting).to.be.a("function"); + expect(printGreeting.toString().includes("=>")).to.equal(true); + }); + it('"printGreeting" should print "Hello ______!" with console.log', () => { + const greeting = readConsole(() => printGreeting("Tim")); + expect(greeting).to.equal("Hello Tim!\n"); + }); + }); + describe("03-return-greeting", () => { + it('should contain a function called "printGreeting" in arrow syntax', () => { + expect(returnGreeting).to.be.a("function"); + expect(returnGreeting.toString().includes("=>")).to.equal(true); + }); + it('"printGreeting" should return "Hello ______!"', () => { + expect(returnGreeting("Tim")).to.equal("Hello Tim!"); + }); + }); + describe("04-multiply", () => { + it('should contain a function called "multiply" in arrow syntax', () => { + expect(multiply).to.be.a("function"); + expect(multiply.toString().includes("=>")).to.equal(true); + }); + it('"multiply" should have two numbers as parameters ("num1" and "num2") and return num1 multiplied by num2', () => { + expect(multiply(5, 5)).to.equal(25); + expect(multiply(10, 0.3)).to.equal(3); + expect(multiply(2, -1)).to.equal(-2); + }); + }); + describe("05-lower-case-string", () => { + it('should contain a function called "lowerCaseString" in arrow syntax', () => { + expect(lowerCaseString).to.be.a("function"); + expect(lowerCaseString.toString().includes("=>")).to.equal(true); + }); + it('"lowerCaseString" should lower case a string', () => { + expect(lowerCaseString("HELLO WORLD")).to.equal("hello world"); + }); + it('"lowerCaseString" should not throw an error is given a value that is not a string. (NOTE that this test will pass if you have not solved this problem yet.)', () => { + const goodFn = () => lowerCaseString(null); + expect(goodFn).to.not.throw(); + expect(lowerCaseString()).to.not.be.ok; + expect(lowerCaseString(null)).to.not.be.ok; + }); + }); + describe("06-is-even-or-odd", () => { + it('should contain a function called "isEvenOrOdd" in arrow syntax', () => { + expect(isEvenOrOdd).to.be.a("function"); + expect(isEvenOrOdd.toString().includes("=>")).to.equal(true); + }); + it('"isEvenOrOdd" should return "even" if a number is even', () => { + expect(isEvenOrOdd(100)).to.equal("even"); + }); + it('"isEvenOrOdd" should return "odd" if a number is odd.', () => { + expect(isEvenOrOdd(7)).to.equal("odd"); + }); + }); + describe("07-count-number-of-digits", () => { + it('should contain a function called "countNumberOfDigits" in arrow syntax', () => { + expect(countNumberOfDigits).to.be.a("function"); + expect(countNumberOfDigits.toString().includes("=>")).to.equal(true); + }); + it('"countNumberOfDigits" should count the number of digits', () => { + expect(countNumberOfDigits(5000)).to.equal(4); + }); + }); +}); diff --git a/test/getAnswer.js b/test/getAnswer.js index 3c2a558..fdd8d83 100644 --- a/test/getAnswer.js +++ b/test/getAnswer.js @@ -22,4 +22,22 @@ const getAnswer = (filePath) => { } }; -export { getAnswer }; +const readConsole = (callback) => { + /** + * @source https://gajus.medium.com/capturing-stdout-stderr-in-node-js-using-domain-module-3c86f5b1536d + */ + let output = ""; + const originalStdoutWrite = process.stdout.write.bind(process.stdout); + process.stdout.write = (chunk, encoding, callback) => { + if (typeof chunk === "string") { + output += chunk; + } + + return originalStdoutWrite(chunk, encoding, callback); + }; + callback(); + process.stdout.write = originalStdoutWrite; + return output; +}; + +export { getAnswer, readConsole }; From 889b1e1ef98a8ae9c67368097355c4fb1f164806 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Mon, 17 Oct 2022 23:16:16 -0400 Subject: [PATCH 020/105] assignment 4 and 5 hkatzman --- exercises/04-combine-strings/01-concatenate-operator.js | 2 ++ exercises/04-combine-strings/02-template-literals.js | 2 ++ exercises/04-combine-strings/03-replace-last-name.js | 4 ++++ exercises/04-combine-strings/04-combine-text.html | 2 +- exercises/05-coercion/01-convert-string-to-int.js | 2 ++ exercises/05-coercion/02-fix-coercion-error.js | 4 +++- exercises/05-coercion/03-fix-coercion-input.html | 2 +- 7 files changed, 15 insertions(+), 3 deletions(-) diff --git a/exercises/04-combine-strings/01-concatenate-operator.js b/exercises/04-combine-strings/01-concatenate-operator.js index 2154224..beb9dcc 100644 --- a/exercises/04-combine-strings/01-concatenate-operator.js +++ b/exercises/04-combine-strings/01-concatenate-operator.js @@ -16,3 +16,5 @@ let author = "J. K. Rowling"; */ // WRITE YOUR ANSWER BELOW THIS LINE +let bookInfo = bookTitle + " " + "by" + " " + author; +console.log(bookInfo); diff --git a/exercises/04-combine-strings/02-template-literals.js b/exercises/04-combine-strings/02-template-literals.js index 43d025e..7ad5f38 100644 --- a/exercises/04-combine-strings/02-template-literals.js +++ b/exercises/04-combine-strings/02-template-literals.js @@ -16,3 +16,5 @@ let author = "J. K. Rowling"; */ // WRITE YOUR ANSWER BELOW THIS LINE +let bookInfo = `${bookTitle} by ${author}`; +console.log(bookInfo); diff --git a/exercises/04-combine-strings/03-replace-last-name.js b/exercises/04-combine-strings/03-replace-last-name.js index e1cb274..d80cb9f 100644 --- a/exercises/04-combine-strings/03-replace-last-name.js +++ b/exercises/04-combine-strings/03-replace-last-name.js @@ -16,3 +16,7 @@ let newLastName = "Fernandez"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let index = fullName.indexOf(" "); +let firstName = fullName.substring(0, index); +fullName = firstName + " " + newLastName; +console.log(firstName + " " + newLastName); diff --git a/exercises/04-combine-strings/04-combine-text.html b/exercises/04-combine-strings/04-combine-text.html index 9be95ee..6e4c31e 100644 --- a/exercises/04-combine-strings/04-combine-text.html +++ b/exercises/04-combine-strings/04-combine-text.html @@ -48,7 +48,7 @@ const firstName = document.querySelector("#firstName").value; const lastName = document.querySelector("#lastName").value; - alert(/* Combine "firstName" and "lastName" here */); + alert(firstName + " " + lastName); }); })(); diff --git a/exercises/05-coercion/01-convert-string-to-int.js b/exercises/05-coercion/01-convert-string-to-int.js index bd5e5ad..f24ce47 100644 --- a/exercises/05-coercion/01-convert-string-to-int.js +++ b/exercises/05-coercion/01-convert-string-to-int.js @@ -6,3 +6,5 @@ let answer = "55"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +answer = parseInt(answer); +console.log(answer); diff --git a/exercises/05-coercion/02-fix-coercion-error.js b/exercises/05-coercion/02-fix-coercion-error.js index eaa9b07..59d5875 100644 --- a/exercises/05-coercion/02-fix-coercion-error.js +++ b/exercises/05-coercion/02-fix-coercion-error.js @@ -9,4 +9,6 @@ let num2 = "7"; // e.g. // WRITE YOUR ANSWER BELOW THIS LINE -let sum = num1 + num2; +//let sum = num1 + num2; +let sum = num1 + parseInt(num2); +console.log(sum); diff --git a/exercises/05-coercion/03-fix-coercion-input.html b/exercises/05-coercion/03-fix-coercion-input.html index 334d6ae..13d930d 100644 --- a/exercises/05-coercion/03-fix-coercion-input.html +++ b/exercises/05-coercion/03-fix-coercion-input.html @@ -49,7 +49,7 @@ const num1 = document.querySelector("#a").value || ""; const num2 = document.querySelector("#b").value || ""; - const sum = num1 + num2; // Fix this line so that it adds the two numbers together instead of combining a string + const sum = parseInt(num1) + parseInt(num2); // Fix this line so that it adds the two numbers together instead of combining a string document.querySelector("#answer").textContent = sum || "-"; }); From f155d8b85f3ef070848484dd9e9c8c8c37047caa Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 18 Oct 2022 01:52:53 -0400 Subject: [PATCH 021/105] correct assignment 04-3 --- exercises/04-combine-strings/03-replace-last-name.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/04-combine-strings/03-replace-last-name.js b/exercises/04-combine-strings/03-replace-last-name.js index d80cb9f..9b6b165 100644 --- a/exercises/04-combine-strings/03-replace-last-name.js +++ b/exercises/04-combine-strings/03-replace-last-name.js @@ -19,4 +19,4 @@ let newLastName = "Fernandez"; // e.g. let index = fullName.indexOf(" "); let firstName = fullName.substring(0, index); fullName = firstName + " " + newLastName; -console.log(firstName + " " + newLastName); +console.log(fullName); From adeecfb664fb2650e6e31bf8d558af852e9edeb2 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 18 Oct 2022 09:50:30 -0400 Subject: [PATCH 022/105] correct assignment 04-03 katzman --- .../03-replace-last-name.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/exercises/04-combine-strings/03-replace-last-name.js b/exercises/04-combine-strings/03-replace-last-name.js index 9b6b165..c09023d 100644 --- a/exercises/04-combine-strings/03-replace-last-name.js +++ b/exercises/04-combine-strings/03-replace-last-name.js @@ -16,7 +16,24 @@ let newLastName = "Fernandez"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE -let index = fullName.indexOf(" "); + +//My original solution (works, but doesn't use the augmented assignment operator which it should) + +/*let index = fullName.indexOf(" "); let firstName = fullName.substring(0, index); fullName = firstName + " " + newLastName; +console.log(fullName);*/ + +//per Matina in chat - solution prints JoeFernandez (no space) + +//let index = fullName.indexOf(" "); +//fullName = fullName.substring(0, index); +//fullName += newLastName; +//console.log(fullName); + +// My revised solution based on above + +let index = fullName.indexOf(" "); +fullName = fullName.substring(0, index); +fullName += " " + newLastName; console.log(fullName); From 205513896505759ed885ec03d619cdd7033c6fcf Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:49:03 -0400 Subject: [PATCH 023/105] fix --- exercises/04-combine-strings/03-replace-last-name.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/04-combine-strings/03-replace-last-name.js b/exercises/04-combine-strings/03-replace-last-name.js index c09023d..2d39528 100644 --- a/exercises/04-combine-strings/03-replace-last-name.js +++ b/exercises/04-combine-strings/03-replace-last-name.js @@ -35,5 +35,5 @@ console.log(fullName);*/ let index = fullName.indexOf(" "); fullName = fullName.substring(0, index); -fullName += " " + newLastName; +fullName += " " + newLastName; //This is same as above but adds a space console.log(fullName); From 41cacfcbd9de2538a0134a01a249dd10eab8a9eb Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:27:21 -0400 Subject: [PATCH 024/105] prep for 7 --- exercises/06-control-flow/01-if-statement.js | 3 +++ exercises/06-control-flow/02-if-statement.js | 3 +++ exercises/06-control-flow/03-if-statement.html | 9 ++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/exercises/06-control-flow/01-if-statement.js b/exercises/06-control-flow/01-if-statement.js index 05773f5..736b0d6 100644 --- a/exercises/06-control-flow/01-if-statement.js +++ b/exercises/06-control-flow/01-if-statement.js @@ -17,3 +17,6 @@ let isBuyingDrink = true; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +if (isBuyingDrink) { + total += drink; +} diff --git a/exercises/06-control-flow/02-if-statement.js b/exercises/06-control-flow/02-if-statement.js index 71aedd6..7792d21 100644 --- a/exercises/06-control-flow/02-if-statement.js +++ b/exercises/06-control-flow/02-if-statement.js @@ -13,3 +13,6 @@ let total; */ // WRITE YOUR ANSWER BELOW THIS LINE +if (tip > 0) { + subtotal += subtotal * tip; +} diff --git a/exercises/06-control-flow/03-if-statement.html b/exercises/06-control-flow/03-if-statement.html index 4cc95ed..a6a83b7 100644 --- a/exercises/06-control-flow/03-if-statement.html +++ b/exercises/06-control-flow/03-if-statement.html @@ -55,9 +55,12 @@

// I can see "isLoggedIn" from here. // Change the line below so that it only executes if "isLoggedIn" is true - document.querySelector("#message").textContent = "Welcome back!"; + if (isLoggedIn) { + document.querySelector("#message").textContent = "Welcome back!"; + }; // Change this line below so that it only executes if "isLoggedIn" is false - document.querySelector("#message").textContent = "Please login"; + if (!isLoggedIn) { + document.querySelector("#message").textContent = "Please login"; }; // Do not change anything below @@ -81,7 +84,7 @@

document.querySelector("#logoutBtn").addEventListener("click", logout); logout(); - })(); + }; From 2eea535446137eeaace3d3b04bf3a89268b6d925 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 20 Oct 2022 12:52:08 -0400 Subject: [PATCH 025/105] finish assignment 06 and 07 hal katzman --- exercises/06-control-flow/02-if-statement.js | 5 +++-- exercises/07-comparisons/01-is-equal.js | 3 +++ exercises/07-comparisons/02-is-not-equal.js | 5 +++++ exercises/07-comparisons/03-is-larger-number.js | 9 +++++++++ exercises/07-comparisons/04-is-teenager.js | 5 +++++ exercises/07-comparisons/05-is-weekend.js | 7 +++++++ exercises/07-comparisons/06-is-even.js | 8 ++++++++ 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/exercises/06-control-flow/02-if-statement.js b/exercises/06-control-flow/02-if-statement.js index 7792d21..8689186 100644 --- a/exercises/06-control-flow/02-if-statement.js +++ b/exercises/06-control-flow/02-if-statement.js @@ -14,5 +14,6 @@ let total; // WRITE YOUR ANSWER BELOW THIS LINE if (tip > 0) { - subtotal += subtotal * tip; -} + total = subtotal + subtotal * tip; +} else total = subtotal; +console.log(total); diff --git a/exercises/07-comparisons/01-is-equal.js b/exercises/07-comparisons/01-is-equal.js index 99304e4..8f870f5 100644 --- a/exercises/07-comparisons/01-is-equal.js +++ b/exercises/07-comparisons/01-is-equal.js @@ -12,3 +12,6 @@ let userInput2 = "39"; // e,g, */ // WRITE YOUR ANSWER BELOW THIS LINE +if (userInput1 === userInput2) { + isEqual = true; +} else isEqual = false; diff --git a/exercises/07-comparisons/02-is-not-equal.js b/exercises/07-comparisons/02-is-not-equal.js index 0bb48c1..12fcb4b 100644 --- a/exercises/07-comparisons/02-is-not-equal.js +++ b/exercises/07-comparisons/02-is-not-equal.js @@ -11,3 +11,8 @@ let actualBMI = 27; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +if (targetBMI === actualBMI) { + isNotAtGoalWeight = false; +} else { + isNotAtGoalWeight = true; +} diff --git a/exercises/07-comparisons/03-is-larger-number.js b/exercises/07-comparisons/03-is-larger-number.js index f78d1d8..d0fd502 100644 --- a/exercises/07-comparisons/03-is-larger-number.js +++ b/exercises/07-comparisons/03-is-larger-number.js @@ -10,3 +10,12 @@ let num2 = 20; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let isLargerNumber; +if (num2 > num1) { + isLargerNumber = true; +} else if (num1 > num2) { + isLargerNumber = false; +} else if (num1 === num2) { + isLargerNumber = false; +} +console.log(isLargerNumber); diff --git a/exercises/07-comparisons/04-is-teenager.js b/exercises/07-comparisons/04-is-teenager.js index 19abbbb..d0c6e2e 100644 --- a/exercises/07-comparisons/04-is-teenager.js +++ b/exercises/07-comparisons/04-is-teenager.js @@ -9,3 +9,8 @@ let age = 14; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let isTeenager; +if (age > 12 && age < 20) { + isTeenager = true; +} else isTeenager = false; +console.log(isTeenager); diff --git a/exercises/07-comparisons/05-is-weekend.js b/exercises/07-comparisons/05-is-weekend.js index 4da6baf..c6c85a4 100644 --- a/exercises/07-comparisons/05-is-weekend.js +++ b/exercises/07-comparisons/05-is-weekend.js @@ -9,3 +9,10 @@ let day = "Saturday"; */ // WRITE YOUR ANSWER BELOW THIS LINE +let isWeekend; +if (day === "Saturday" || day === "Sunday") { + isWeekend = true; +} else { + isWeekend = false; +} +console.log(isWeekend); diff --git a/exercises/07-comparisons/06-is-even.js b/exercises/07-comparisons/06-is-even.js index c98e684..d268b06 100644 --- a/exercises/07-comparisons/06-is-even.js +++ b/exercises/07-comparisons/06-is-even.js @@ -8,3 +8,11 @@ let num = 8; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let isEven; +let test = num % 2; +if (test === 0) { + isEven = true; +} else { + isEven = false; +} +console.log(isEven); From e4b2a4b678d800344e9b044e73ea0926e09929b0 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 25 Oct 2022 08:26:13 -0400 Subject: [PATCH 026/105] Submit assignment 08 Hal Katzman --- exercises/08-functions/01-invoke-function.js | 5 ++++- exercises/08-functions/02-print-greeting.js | 6 ++++++ exercises/08-functions/03-return-greeting.js | 7 +++++++ exercises/08-functions/04-multiply.js | 4 ++++ exercises/08-functions/05-lower-case-string.js | 11 +++++++++++ exercises/08-functions/06-is-even-or-odd.js | 8 ++++++++ exercises/08-functions/07-count-number-of-digits.js | 7 +++++++ 7 files changed, 47 insertions(+), 1 deletion(-) diff --git a/exercises/08-functions/01-invoke-function.js b/exercises/08-functions/01-invoke-function.js index 3f1a599..6994330 100644 --- a/exercises/08-functions/01-invoke-function.js +++ b/exercises/08-functions/01-invoke-function.js @@ -8,9 +8,12 @@ const calculateTotal = (subtotal, tax) => { }; /** - * You are paying your bill. You have a subtotal of $50.00 and tax is 2%. + * You are paying your bill. You have a subtotal of $50.00 and tax is 20%. * * Create a variable called "total". The variable "total" should be equal to the result of "calculateTotal" (which is 60). */ // WRITE YOUR ANSWER BELOW THIS LINE + +let total = calculateTotal(50, 0.2); +console.log(total); diff --git a/exercises/08-functions/02-print-greeting.js b/exercises/08-functions/02-print-greeting.js index 538db9f..1f2058e 100644 --- a/exercises/08-functions/02-print-greeting.js +++ b/exercises/08-functions/02-print-greeting.js @@ -10,3 +10,9 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE + +const printGreeting = (name) => { + console.log(`Hello ${name}!`); +}; + +printGreeting("Matina"); diff --git a/exercises/08-functions/03-return-greeting.js b/exercises/08-functions/03-return-greeting.js index 57315c4..bae4813 100644 --- a/exercises/08-functions/03-return-greeting.js +++ b/exercises/08-functions/03-return-greeting.js @@ -13,3 +13,10 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE + +const returnGreeting = (name) => { + return `Hello ${name}!`; +}; + +let result = returnGreeting("Jamal"); +console.log(result); diff --git a/exercises/08-functions/04-multiply.js b/exercises/08-functions/04-multiply.js index fd649ca..db74305 100644 --- a/exercises/08-functions/04-multiply.js +++ b/exercises/08-functions/04-multiply.js @@ -16,3 +16,7 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +const multiply = (num1, num2) => { + return num1 * num2; +}; +console.log(multiply(7, 2)); diff --git a/exercises/08-functions/05-lower-case-string.js b/exercises/08-functions/05-lower-case-string.js index b858ca8..c9e086e 100644 --- a/exercises/08-functions/05-lower-case-string.js +++ b/exercises/08-functions/05-lower-case-string.js @@ -16,3 +16,14 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +const lowerCaseString = (isString) => { + if (typeof isString === "string") { + return isString.toLowerCase(); + } + return isString; +}; +console.log(lowerCaseString("Javascript!")); +console.log(lowerCaseString("HELP")); +console.log(lowerCaseString()); +console.log(lowerCaseString(1024)); +console.log(lowerCaseString("500BB")); diff --git a/exercises/08-functions/06-is-even-or-odd.js b/exercises/08-functions/06-is-even-or-odd.js index 7863ce1..b00bd78 100644 --- a/exercises/08-functions/06-is-even-or-odd.js +++ b/exercises/08-functions/06-is-even-or-odd.js @@ -12,3 +12,11 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +const isEvenOrOdd = (number) => { + if (number % 2 === 0) { + return "even"; + } + return "odd"; +}; +console.log(isEvenOrOdd(5)); +console.log(isEvenOrOdd(100)); diff --git a/exercises/08-functions/07-count-number-of-digits.js b/exercises/08-functions/07-count-number-of-digits.js index 88572e1..e96aa87 100644 --- a/exercises/08-functions/07-count-number-of-digits.js +++ b/exercises/08-functions/07-count-number-of-digits.js @@ -10,3 +10,10 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE + +const countNumberOfDigits = (int) => { + return int.toString().length; +}; + +console.log(countNumberOfDigits(12401)); +console.log(countNumberOfDigits(-999999999)); From 3b74e4e2d05a2011eb733815a010dc4bbb3d09b5 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Tue, 25 Oct 2022 20:01:15 -0400 Subject: [PATCH 027/105] Functions solutions --- .../01-invoke-function.solution.js | 18 +++++++++++++ .../02-print-greeting.solution.js | 16 ++++++++++++ .../03-return-greeting.solution.js | 19 ++++++++++++++ .../08-functions/04-multiply.solution.js | 22 ++++++++++++++++ .../05-lower-case-strings.solution.js | 24 +++++++++++++++++ .../06-is-even-or-odd.solution.js | 23 ++++++++++++++++ .../07-count-number-of-digits.solution.js | 26 +++++++++++++++++++ test/08-functions/functions.spec.js | 6 ++--- 8 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 solutions/08-functions/01-invoke-function.solution.js create mode 100644 solutions/08-functions/02-print-greeting.solution.js create mode 100644 solutions/08-functions/03-return-greeting.solution.js create mode 100644 solutions/08-functions/04-multiply.solution.js create mode 100644 solutions/08-functions/05-lower-case-strings.solution.js create mode 100644 solutions/08-functions/06-is-even-or-odd.solution.js create mode 100644 solutions/08-functions/07-count-number-of-digits.solution.js diff --git a/solutions/08-functions/01-invoke-function.solution.js b/solutions/08-functions/01-invoke-function.solution.js new file mode 100644 index 0000000..e13a902 --- /dev/null +++ b/solutions/08-functions/01-invoke-function.solution.js @@ -0,0 +1,18 @@ +/** + * @param {number} subtotal + * @param {number} tax + * @returns {number} the total cost, including the tax + */ +const calculateTotal = (subtotal, tax) => { + return subtotal * tax + subtotal; +}; + +/** + * You are paying your bill. You have a subtotal of $50.00 and tax is 2%. + * + * Create a variable called "total". The variable "total" should be equal to the result of "calculateTotal" (which is 51). + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let total = calculateTotal(50, 0.02); diff --git a/solutions/08-functions/02-print-greeting.solution.js b/solutions/08-functions/02-print-greeting.solution.js new file mode 100644 index 0000000..7a832ed --- /dev/null +++ b/solutions/08-functions/02-print-greeting.solution.js @@ -0,0 +1,16 @@ +/** + * Create a function named called "printGreeting". + * It should accept a "name" as a parameter + * and print "Hello ______!" with console.log + * + * @param {string} name + * + * @example printGreeting("Tim"); // Hello Tim! + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const printGreeting = (name) => { + console.log("Hello " + name + "!"); +}; diff --git a/solutions/08-functions/03-return-greeting.solution.js b/solutions/08-functions/03-return-greeting.solution.js new file mode 100644 index 0000000..7e988e3 --- /dev/null +++ b/solutions/08-functions/03-return-greeting.solution.js @@ -0,0 +1,19 @@ +/** + * Create a function named called "returnGreeting". + * It should accept a "name" as a parameter + * and return "Hello ______!" + * (This is similar to the last exercise, + * except you are returning a value instead of using console.log) + * + * @param {string} name + * @returns {string} "Hello name" + * + * @example returnGreeting("Tim"); // Hello Tim! + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const returnGreeting = (name) => { + return `Hello ${name}!`; +}; diff --git a/solutions/08-functions/04-multiply.solution.js b/solutions/08-functions/04-multiply.solution.js new file mode 100644 index 0000000..a823a7c --- /dev/null +++ b/solutions/08-functions/04-multiply.solution.js @@ -0,0 +1,22 @@ +/** + * Create a function named "multiply". + * It should have two parameters: "num1" and "num2". + * Both parameters should be numbers. + * The function should return the product of both numbers. + * (In other words, multiply!) + * + * @param {number} num1 + * @param {number} num2 + * @returns {number} num1 x num2 + * + * @example timesFive(5); // 25 + * @example timesFive(2); // 10 + * @example timesFive(0); // 0 + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const multiply = (num1, num2) => { + return num1 * num2; +}; diff --git a/solutions/08-functions/05-lower-case-strings.solution.js b/solutions/08-functions/05-lower-case-strings.solution.js new file mode 100644 index 0000000..805bf68 --- /dev/null +++ b/solutions/08-functions/05-lower-case-strings.solution.js @@ -0,0 +1,24 @@ +/** + * Create a function called "lowerCaseString". + * If given a string, it should return the string lower cased. + * @example lowerCaseString("HELLO WORLD"); // hello world + * + * If given a value that is not a string, this function should not throw an error. + * @see https://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string-in-javascript + * HINT: you will need to exit out of the function early. + * + * @param {string} str + * @returns {string} str capitalized + * + * @example lowerCaseString(); // undefined (should not throw an error) + * @example lowerCaseString(null); // undefined (should not throw an error) + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const lowerCaseString = (str) => { + if (typeof str === "string" || str instanceof String) { + return str.toLowerCase(); + } +}; diff --git a/solutions/08-functions/06-is-even-or-odd.solution.js b/solutions/08-functions/06-is-even-or-odd.solution.js new file mode 100644 index 0000000..b3e38f7 --- /dev/null +++ b/solutions/08-functions/06-is-even-or-odd.solution.js @@ -0,0 +1,23 @@ +/** + * Create a function called "isEvenOrOdd". + * If given an even number, it should return "even". + * If given an odd number, it should return "odd". + * + * @param {number} num + * @returns {string} either "even" or "odd" + * + * @example isEvenOrOdd(10); // even + * @example isEvenOrOdd(3); // odd + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const isEvenOrOdd = (num) => { + // If it has a remainder of 2, then the number is even. + if (num % 2 === 0) { + return "even"; + } else { + return "odd"; + } +}; diff --git a/solutions/08-functions/07-count-number-of-digits.solution.js b/solutions/08-functions/07-count-number-of-digits.solution.js new file mode 100644 index 0000000..24bad68 --- /dev/null +++ b/solutions/08-functions/07-count-number-of-digits.solution.js @@ -0,0 +1,26 @@ +/** + * Create a function called "countNumberOfDigits". + * Given an integer, it should return the number of digits in an integer. + * + * @param {int} num + * @returns {int} the number of digits + * + * @example countNumberOfDigits(5000); // 4 + * You should use arrow syntax. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const countNumberOfDigits = (num) => { + // I'm first converting this to a string + let str = `${num}`; + + // BONUS + // And removing the decimal point + str = str.replace(".", ""); + // And any negative signs + str = str.replace("-", ""); + + // And now I'm counting tbe number of numbers + return str.length; +}; diff --git a/test/08-functions/functions.spec.js b/test/08-functions/functions.spec.js index f095f56..8e17687 100644 --- a/test/08-functions/functions.spec.js +++ b/test/08-functions/functions.spec.js @@ -15,11 +15,11 @@ describe("8. Functions", () => { describe("01-invoke-function", () => { it('should invoke the function "calculateTotal", passing in the subtotal of 50 and tax of 0.2 as arguments', () => { const [, args] = invokeFunction(); - expect(args).to.deep.equal([50, 0.2]); + expect(args).to.deep.equal([50, 0.02]); }); - it('"total" should equal 60 when the subtotal is $50 and the tax is 2%', () => { + it('"total" should equal 51 when the subtotal is $50 and the tax is 2%', () => { const [total] = invokeFunction(); - expect(total).to.be.a("number").to.equal(60); + expect(total).to.be.a("number").to.equal(51); }); }); describe("02-print-greeting", () => { From 41bbabe94a98bd5a35995b2f67d548cf6c47edc4 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 23 Oct 2022 16:32:04 -0400 Subject: [PATCH 028/105] Arrays exercises --- .vscode/launch.json | 13 +++ exercises/09-arrays/01-create-an-array.js | 6 ++ .../09-arrays/02-accessing-item-in-array.js | 9 ++ exercises/09-arrays/03-destructuring.js | 12 +++ exercises/09-arrays/04-position-in-array.js | 21 +++++ exercises/09-arrays/05-add-item-to-array.js | 7 ++ exercises/09-arrays/06-combine-arrays-.js | 10 ++ test/09-arrays/arrays-sets-test-helper.js | 55 +++++++++++ test/09-arrays/arrays-sets.spec.js | 91 +++++++++++++++++++ 9 files changed, 224 insertions(+) create mode 100644 exercises/09-arrays/01-create-an-array.js create mode 100644 exercises/09-arrays/02-accessing-item-in-array.js create mode 100644 exercises/09-arrays/03-destructuring.js create mode 100644 exercises/09-arrays/04-position-in-array.js create mode 100644 exercises/09-arrays/05-add-item-to-array.js create mode 100644 exercises/09-arrays/06-combine-arrays-.js create mode 100644 test/09-arrays/arrays-sets-test-helper.js create mode 100644 test/09-arrays/arrays-sets.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 528d6e9..80e962f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -121,5 +121,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "9. Arrays", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/09-arrays/arrays-sets.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/09-arrays/01-create-an-array.js b/exercises/09-arrays/01-create-an-array.js new file mode 100644 index 0000000..7fb3218 --- /dev/null +++ b/exercises/09-arrays/01-create-an-array.js @@ -0,0 +1,6 @@ +/** + * Create an array called "restaurants". (Do not use var.) + * It should contain a list of at least three items + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/09-arrays/02-accessing-item-in-array.js b/exercises/09-arrays/02-accessing-item-in-array.js new file mode 100644 index 0000000..be3c419 --- /dev/null +++ b/exercises/09-arrays/02-accessing-item-in-array.js @@ -0,0 +1,9 @@ +const cars = ["BMW", "Honda", "Civic"]; // Do not change this line + +/** + * Create an array called "myCar". + * It should be equal to the first item in the array of cars. + * Solve this problem without using destructuring. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/09-arrays/03-destructuring.js b/exercises/09-arrays/03-destructuring.js new file mode 100644 index 0000000..997a86b --- /dev/null +++ b/exercises/09-arrays/03-destructuring.js @@ -0,0 +1,12 @@ +const cars = ["BMW", "Honda", "Civic"]; // Do not change this line + +/** + * This problem is a repeat of the last problem, + * except you will solve this problem with destructuring. + * + * Create an array called "myCar". + * It should be equal to the first item in the array of cars. + * Solve this problem without using destructuring. + */ + +// WRITE YOUR ANSWER BELOW THIS LINEs diff --git a/exercises/09-arrays/04-position-in-array.js b/exercises/09-arrays/04-position-in-array.js new file mode 100644 index 0000000..204a79f --- /dev/null +++ b/exercises/09-arrays/04-position-in-array.js @@ -0,0 +1,21 @@ +let results = [ + // e.g. + "Aaminata Kamau", + "Claire O'Hannigan", + "Jian Hou", + "María Rosales", + "Fathima Kaur", +]; + +/** + * The array "results" lists runners in the order + * in which they placed within a race. + * So, for example, Jian Hou placed 3rd in the example above. + * + * Create a variable called "place". + * It should be equal to whatever place Jian Hou is in. + * + * Your answer should still work when the names are in a different order. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/09-arrays/05-add-item-to-array.js b/exercises/09-arrays/05-add-item-to-array.js new file mode 100644 index 0000000..858362a --- /dev/null +++ b/exercises/09-arrays/05-add-item-to-array.js @@ -0,0 +1,7 @@ +let languages = ["C++"]; // Do not change this line + +/** + * Add three more computer languages to the languages array. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/09-arrays/06-combine-arrays-.js b/exercises/09-arrays/06-combine-arrays-.js new file mode 100644 index 0000000..518a34c --- /dev/null +++ b/exercises/09-arrays/06-combine-arrays-.js @@ -0,0 +1,10 @@ +let array1 = ["wolf", "fox"]; +let array2 = ["lion", "leopard", "saber tooth tiger"]; + +/** + * Create an array called "newArray". + * It should be equal to "array1" and "array2" combined. + * Combine the arrays by using the spread operator. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/09-arrays/arrays-sets-test-helper.js b/test/09-arrays/arrays-sets-test-helper.js new file mode 100644 index 0000000..af9ffbd --- /dev/null +++ b/test/09-arrays/arrays-sets-test-helper.js @@ -0,0 +1,55 @@ +import { getAnswer } from "../getAnswer.js"; + +const createAnArrayStr = getAnswer( + "../exercises/09-arrays/01-create-an-array.js" +); + +const accessingAnItemStr = getAnswer( + "../exercises/09-arrays/02-accessing-item-in-array.js" +); + +const destructuringStr = getAnswer( + "../exercises/09-arrays/03-destructuring.js" +); + +const getPositionInArrayStr = getAnswer( + "../exercises/09-arrays/04-position-in-array.js" +); + +const addItemToArrayStr = getAnswer( + "../exercises/09-arrays/05-add-item-to-array.js" +); + +const combineArraysStr = getAnswer( + "../exercises/09-arrays/06-combine-arrays-.js" +); + +export const createAnArray = eval(`() => { + ${createAnArrayStr} + return restaurants; +}`); + +export const accessingAnItem = eval(`(cars) => { + ${accessingAnItemStr} + return myCar; +}`); + +export const destructure = eval(`(cars) => { + ${destructuringStr} + return myCar; +}`); + +export const getPositionInArray = eval(`(results) => { + ${getPositionInArrayStr} + return place; +}`); + +export const addItemToArray = eval(`(languages) => { + ${addItemToArrayStr} + return languages; +}`); + +export const combineArrays = eval(`(array1, array2) => { + ${combineArraysStr} + return newArray; +}`); diff --git a/test/09-arrays/arrays-sets.spec.js b/test/09-arrays/arrays-sets.spec.js new file mode 100644 index 0000000..5324506 --- /dev/null +++ b/test/09-arrays/arrays-sets.spec.js @@ -0,0 +1,91 @@ +import { expect } from "chai"; +import { + createAnArray, + accessingAnItem, + destructure, + getPositionInArray, + addItemToArray, + combineArrays, +} from "./arrays-sets-test-helper.js"; + +describe("9. Arrays", () => { + describe("01-create-an-array", () => { + it('should contain an array called "restaurants"', () => { + const restaurants = createAnArray(); + expect(restaurants).to.be.an("array"); + }); + it('"restaurants" should have at least 3 items', () => { + const restaurants = createAnArray(); + expect(restaurants).to.have.lengthOf(3); + }); + }); + + describe("02-accessing-an-item", () => { + it('should contain an array called "myCar"', () => { + const accessingAnItemStr = accessingAnItem.toString(); + expect(accessingAnItemStr).to.match(/(const)|(let)/); + expect(accessingAnItemStr).to.match(/myCar/); + }); + it('"myCar" should be equal to the first item in an array', () => { + const cars = ["Mercedes", "Kia", "Toyota"]; + const myCar = accessingAnItem(cars); + expect(myCar).to.equal("Mercedes"); + }); + }); + + describe("03-destructuring", () => { + it('"myCar" should be equal to the first item in an array', () => { + const cars = ["Mercedes", "Kia", "Toyota"]; + const myCar = destructure(cars); + expect(myCar).to.equal("Mercedes"); + }); + it("should use destructuring to solve this problem", () => { + const destructureStr = destructure.toString(); + expect(destructureStr).to.match(/(const\s*\[)|(let\s*\[)/); + }); + }); + + describe("04-position-in-array.js", () => { + it('"place" should equal 3 if "Jian Hou" is the 3rd value in the array', () => { + const place = getPositionInArray([ + "Aaminata Kamau", + "Claire O'Hannigan", + "Jian Hou", + "María Rosales", + "Fathima Kaur", + ]); + expect(place).to.equal(3); + }); + it('"place" should equal 1 if "Jian Hou" is the 1st value in the array', () => { + const place = getPositionInArray([ + "Jian Hou", + "Aaminata Kamau", + "Claire O'Hannigan", + "María Rosales", + "Fathima Kaur", + ]); + expect(place).to.equal(1); + }); + }); + + describe("05-add-item-to-array", () => { + it('"languages" should contain three more items', () => { + const languages = addItemToArray(["C++"]); + expect(languages).to.have.lengthOf(4); + }); + }); + + describe("06-combine-arrays.js", () => { + it('should contain a new array called "newArray"', () => { + const newArray = combineArrays(["HTML"], ["CSS"]); + expect(newArray).to.be.an("array"); + }); + it('"newArray" should merge two arrays into one', () => { + const newArray = combineArrays(["HTML"], ["CSS"]); + expect(newArray).to.deep.equal(["HTML", "CSS"]); + }); + it('"newArray" should combine two arrays by using the spread operator', () => { + expect(combineArrays.toString().includes("...")).to.equal(true); + }); + }); +}); From 46d80bcbbb27df744fa41b8f4fa3df158772fb7b Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 26 Oct 2022 21:00:23 -0400 Subject: [PATCH 029/105] Submit assignment 09 hal katzman --- exercises/09-arrays/01-create-an-array.js | 3 +++ exercises/09-arrays/02-accessing-item-in-array.js | 4 ++++ exercises/09-arrays/03-destructuring.js | 4 +++- exercises/09-arrays/04-position-in-array.js | 3 +++ exercises/09-arrays/05-add-item-to-array.js | 2 ++ exercises/09-arrays/06-combine-arrays-.js | 2 ++ 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/exercises/09-arrays/01-create-an-array.js b/exercises/09-arrays/01-create-an-array.js index 7fb3218..6813fb4 100644 --- a/exercises/09-arrays/01-create-an-array.js +++ b/exercises/09-arrays/01-create-an-array.js @@ -4,3 +4,6 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE +const restaurants = ["Stadium Diner", "Peter Luger", "Juniors"]; + +console.log(restaurants); diff --git a/exercises/09-arrays/02-accessing-item-in-array.js b/exercises/09-arrays/02-accessing-item-in-array.js index be3c419..b9b5d80 100644 --- a/exercises/09-arrays/02-accessing-item-in-array.js +++ b/exercises/09-arrays/02-accessing-item-in-array.js @@ -7,3 +7,7 @@ const cars = ["BMW", "Honda", "Civic"]; // Do not change this line */ // WRITE YOUR ANSWER BELOW THIS LINE + +const myCar = cars[0]; + +console.log(myCar); diff --git a/exercises/09-arrays/03-destructuring.js b/exercises/09-arrays/03-destructuring.js index 997a86b..dc4b150 100644 --- a/exercises/09-arrays/03-destructuring.js +++ b/exercises/09-arrays/03-destructuring.js @@ -9,4 +9,6 @@ const cars = ["BMW", "Honda", "Civic"]; // Do not change this line * Solve this problem without using destructuring. */ -// WRITE YOUR ANSWER BELOW THIS LINEs +// WRITE YOUR ANSWER BELOW THIS LINE +let [myCar] = cars; +console.log(myCar); diff --git a/exercises/09-arrays/04-position-in-array.js b/exercises/09-arrays/04-position-in-array.js index 204a79f..0c6f0c9 100644 --- a/exercises/09-arrays/04-position-in-array.js +++ b/exercises/09-arrays/04-position-in-array.js @@ -19,3 +19,6 @@ let results = [ */ // WRITE YOUR ANSWER BELOW THIS LINE +let place = results.indexOf("Jian Hou") + 1; + +console.log(place); diff --git a/exercises/09-arrays/05-add-item-to-array.js b/exercises/09-arrays/05-add-item-to-array.js index 858362a..41d6a7a 100644 --- a/exercises/09-arrays/05-add-item-to-array.js +++ b/exercises/09-arrays/05-add-item-to-array.js @@ -5,3 +5,5 @@ let languages = ["C++"]; // Do not change this line */ // WRITE YOUR ANSWER BELOW THIS LINE +languages.push("Java", "GoLang", "Python"); +console.log(languages); diff --git a/exercises/09-arrays/06-combine-arrays-.js b/exercises/09-arrays/06-combine-arrays-.js index 518a34c..e41ba4a 100644 --- a/exercises/09-arrays/06-combine-arrays-.js +++ b/exercises/09-arrays/06-combine-arrays-.js @@ -8,3 +8,5 @@ let array2 = ["lion", "leopard", "saber tooth tiger"]; */ // WRITE YOUR ANSWER BELOW THIS LINE +let newArray = [...array1, ...array2]; +console.log(newArray); From bbe8fbdc913bdd3f23b905ad5f0039e72ab639d5 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Sun, 30 Oct 2022 20:01:22 -0400 Subject: [PATCH 030/105] correct 06-02 hal katzman --- exercises/06-control-flow/02-if-statement.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exercises/06-control-flow/02-if-statement.js b/exercises/06-control-flow/02-if-statement.js index 8689186..38cc641 100644 --- a/exercises/06-control-flow/02-if-statement.js +++ b/exercises/06-control-flow/02-if-statement.js @@ -13,7 +13,9 @@ let total; */ // WRITE YOUR ANSWER BELOW THIS LINE -if (tip > 0) { + +if (tip) { total = subtotal + subtotal * tip; } else total = subtotal; + console.log(total); From 2068a5234b53757796e18d8e939928a774f7fa74 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 29 Oct 2022 12:14:52 -0400 Subject: [PATCH 031/105] Arrays solutions --- .../09-arrays/01-create-an-array.solution.js | 12 ++++++++++ .../02-accessing-item-in-array.solution.js | 10 ++++++++ .../09-arrays/03-destructuring.solution.js | 15 ++++++++++++ .../04-position-in-array.solution.js | 23 +++++++++++++++++++ .../05-add-item-to-array.solution.js | 11 +++++++++ .../09-arrays/06-combine-arrays-.solution.js | 12 ++++++++++ 6 files changed, 83 insertions(+) create mode 100644 solutions/09-arrays/01-create-an-array.solution.js create mode 100644 solutions/09-arrays/02-accessing-item-in-array.solution.js create mode 100644 solutions/09-arrays/03-destructuring.solution.js create mode 100644 solutions/09-arrays/04-position-in-array.solution.js create mode 100644 solutions/09-arrays/05-add-item-to-array.solution.js create mode 100644 solutions/09-arrays/06-combine-arrays-.solution.js diff --git a/solutions/09-arrays/01-create-an-array.solution.js b/solutions/09-arrays/01-create-an-array.solution.js new file mode 100644 index 0000000..08f59ba --- /dev/null +++ b/solutions/09-arrays/01-create-an-array.solution.js @@ -0,0 +1,12 @@ +/** + * Create an array called "restaurants". (Do not use var.) + * It should contain a list of at least three items + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let restaurants = [ + "Lost & Found Bar & Kitchen", + "Dinosaur Bar-B-Que", + "Karavalli", +]; diff --git a/solutions/09-arrays/02-accessing-item-in-array.solution.js b/solutions/09-arrays/02-accessing-item-in-array.solution.js new file mode 100644 index 0000000..f63d050 --- /dev/null +++ b/solutions/09-arrays/02-accessing-item-in-array.solution.js @@ -0,0 +1,10 @@ +const cars = ["BMW", "Honda", "Civic"]; // Do not change this line + +/** + * Create a constant called "myCar". + * It should be equal to the first item in the array of cars. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const myCar = cars[0]; diff --git a/solutions/09-arrays/03-destructuring.solution.js b/solutions/09-arrays/03-destructuring.solution.js new file mode 100644 index 0000000..19ff7f3 --- /dev/null +++ b/solutions/09-arrays/03-destructuring.solution.js @@ -0,0 +1,15 @@ +const cars = ["BMW", "Honda", "Civic"]; // Do not change this line + +/** + * This problem is a repeat of the last problem, + * except you will solve this problem with destructuring. + * + * Create an array called "myCar". + * It should be equal to the first item in the array of cars. + * Solve this problem without using destructuring. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const [ myCar ] = cars; +console.log(myCar); diff --git a/solutions/09-arrays/04-position-in-array.solution.js b/solutions/09-arrays/04-position-in-array.solution.js new file mode 100644 index 0000000..e6f0854 --- /dev/null +++ b/solutions/09-arrays/04-position-in-array.solution.js @@ -0,0 +1,23 @@ +let results = [ + // e.g. + "Aaminata Kamau", + "Claire O'Hannigan", + "Jian Hou", + "María Rosales", + "Fathima Kaur", +]; + +/** + * The array "results" lists runners in the order + * in which they placed within a race. + * So, for example, Jian Hou placed 3rd in the example above. + * + * Create a variable called "place". + * It should be equal to whatever place Jian Hou is in. + * + * Your answer should still work when the names are in a different order. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const place = results.indexOf("Jian Hou") + 1; diff --git a/solutions/09-arrays/05-add-item-to-array.solution.js b/solutions/09-arrays/05-add-item-to-array.solution.js new file mode 100644 index 0000000..1460d79 --- /dev/null +++ b/solutions/09-arrays/05-add-item-to-array.solution.js @@ -0,0 +1,11 @@ +let languages = ["C++"]; // Do not change this line + +/** + * Add three more computer languages to the languages array. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +languages.push("HTML"); +languages.push("CSS"); +languages.push("JavaScript"); diff --git a/solutions/09-arrays/06-combine-arrays-.solution.js b/solutions/09-arrays/06-combine-arrays-.solution.js new file mode 100644 index 0000000..0fe57b1 --- /dev/null +++ b/solutions/09-arrays/06-combine-arrays-.solution.js @@ -0,0 +1,12 @@ +let array1 = ["wolf", "fox"]; +let array2 = ["lion", "leopard", "saber tooth tiger"]; + +/** + * Create a constant called "newArray". + * It should be equal to "array1" and "array2" combined. + * Combine the arrays by using the spread operator. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const newArray = [...array1, ...array2]; From 3650910fa4ff8b746f52dd822579aa69d8d22451 Mon Sep 17 00:00:00 2001 From: Matina Patsos Date: Wed, 26 Oct 2022 18:38:10 -0400 Subject: [PATCH 032/105] Loops exercise Loops exercises Part 1 --- .vscode/launch.json | 13 +++++ .../00-solving-problems-with-functions.js | 15 ++++++ exercises/10-loops/01-array-length.js | 15 ++++++ exercises/10-loops/02-while-loop.js | 27 ++++++++++ exercises/10-loops/03-for-loop.js | 20 +++++++ test/10-loops/loops-test-helper.js | 9 ++++ test/10-loops/loops.spec.js | 52 +++++++++++++++++++ 7 files changed, 151 insertions(+) create mode 100755 exercises/10-loops/00-solving-problems-with-functions.js create mode 100755 exercises/10-loops/01-array-length.js create mode 100644 exercises/10-loops/02-while-loop.js create mode 100644 exercises/10-loops/03-for-loop.js create mode 100755 test/10-loops/loops-test-helper.js create mode 100755 test/10-loops/loops.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 80e962f..315753c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -134,5 +134,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "10. Loops", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/10-loops/loops.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/10-loops/00-solving-problems-with-functions.js b/exercises/10-loops/00-solving-problems-with-functions.js new file mode 100755 index 0000000..4b6c6ba --- /dev/null +++ b/exercises/10-loops/00-solving-problems-with-functions.js @@ -0,0 +1,15 @@ +/** + * Return the function's argument. (This problem is to get you used to the new format.) + * @param {string} personName + * @returns {string} personName + * + * @example returnAnswer("Lesley"); // Lesley + */ + +const returnAnswer = (personName) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default returnAnswer; diff --git a/exercises/10-loops/01-array-length.js b/exercises/10-loops/01-array-length.js new file mode 100755 index 0000000..f8933b6 --- /dev/null +++ b/exercises/10-loops/01-array-length.js @@ -0,0 +1,15 @@ +/** + * Return the length of an array + * @param {array} array + * @returns {number} the length of an array + * + * @example arrayLength([1, 9, 3, 201]); // 4 + */ + +const arrayLength = (array) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default arrayLength; diff --git a/exercises/10-loops/02-while-loop.js b/exercises/10-loops/02-while-loop.js new file mode 100644 index 0000000..8a2c62e --- /dev/null +++ b/exercises/10-loops/02-while-loop.js @@ -0,0 +1,27 @@ +/** + * Using a while loop, log the following numbers: + * 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 + * + * @example + * logArrayWithWhile(); + * // 10 + * // 20 + * // 30 + * // 40 + * // 50 + * // 60 + * // 70 + * // 80 + * // 90 + * // 100 + */ + +const logWithWhile = () => { + // WRITE YOUR ANSWER HERE +}; + +logWithWhile(); + +// IGNORE THIS BELOW. It is for the tests. + +export default logWithWhile; diff --git a/exercises/10-loops/03-for-loop.js b/exercises/10-loops/03-for-loop.js new file mode 100644 index 0000000..ba96e6b --- /dev/null +++ b/exercises/10-loops/03-for-loop.js @@ -0,0 +1,20 @@ +/** + * Using a for loop, lop through an array + * and log each item with console.log + * @param {array} array + * + * @example + * const array = ["Honda", "Ford", "Ferrari"]; + * logArrayWithFor(array); + * // Honda + * // Ford + * // Ferrari + */ + +const logArrayWithFor = (array) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default logArrayWithFor; diff --git a/test/10-loops/loops-test-helper.js b/test/10-loops/loops-test-helper.js new file mode 100755 index 0000000..87b4e21 --- /dev/null +++ b/test/10-loops/loops-test-helper.js @@ -0,0 +1,9 @@ +import solvingProblems from "../../exercises/10-loops/00-solving-problems-with-functions.js"; + +import arrayLength from "../../exercises/10-loops/01-array-length.js"; + +import logWithWhile from "../../exercises/10-loops/02-while-loop.js"; + +import logArrayWithFor from "../../exercises/10-loops/03-for-loop.js"; + +export { solvingProblems, arrayLength, logWithWhile, logArrayWithFor }; diff --git a/test/10-loops/loops.spec.js b/test/10-loops/loops.spec.js new file mode 100755 index 0000000..3361a71 --- /dev/null +++ b/test/10-loops/loops.spec.js @@ -0,0 +1,52 @@ +import { expect } from "chai"; +import { readConsole } from "../getAnswer.js"; +import { + solvingProblems, + arrayLength, + logWithWhile, + logArrayWithFor, +} from "./loops-test-helper.js"; + +describe("10. Loops", () => { + describe("00-solving-problems", () => { + it("should pass the test", () => { + expect(solvingProblems("test")).to.equal("test"); + }); + }); + + describe("01-array-length", () => { + it("should return the length of the array supplied as an argument", () => { + expect(arrayLength([1, 2, 3, 4, 5, 6])).to.equal(6); + }); + }); + + describe("02-while-loop", () => { + it("should log each value in an array with console.log", () => { + const output = readConsole(() => { + logWithWhile(); + }); + const expected = + [10, 20, 30, 40, 50, 60, 70, 80, 90, 100].join("\n") + "\n"; + expect(output).to.deep.equal(expected); + }); + it("should use a while loop", () => { + const funcStr = logWithWhile.toString(); + expect(funcStr).to.match(/while\s*\(/); + }); + }); + + describe("03-for-loop", () => { + it("should log each value in an array with console.log", () => { + const array = ["Python", "JavaScript", "TypeScript", "Golang"]; + const output = readConsole(() => { + logArrayWithFor(array); + }); + const expected = array.join("\n") + "\n"; + expect(output).to.deep.equal(expected); + }); + it("should use a for loop", () => { + const funcStr = logArrayWithFor.toString(); + expect(funcStr).to.match(/for\s*\(/); + }); + }); +}); From c328164001680a2cae07aa48612016d2597ef367 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 30 Oct 2022 12:22:57 -0400 Subject: [PATCH 033/105] Update array instructions --- exercises/09-arrays/02-accessing-item-in-array.js | 2 +- exercises/09-arrays/03-destructuring.js | 2 +- exercises/10-loops/02-while-loop.js | 6 ++---- solutions/09-arrays/02-accessing-item-in-array.solution.js | 3 ++- solutions/09-arrays/03-destructuring.solution.js | 5 ++--- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/exercises/09-arrays/02-accessing-item-in-array.js b/exercises/09-arrays/02-accessing-item-in-array.js index b9b5d80..1fd7cb2 100644 --- a/exercises/09-arrays/02-accessing-item-in-array.js +++ b/exercises/09-arrays/02-accessing-item-in-array.js @@ -1,7 +1,7 @@ const cars = ["BMW", "Honda", "Civic"]; // Do not change this line /** - * Create an array called "myCar". + * Create a variable called "myCar". * It should be equal to the first item in the array of cars. * Solve this problem without using destructuring. */ diff --git a/exercises/09-arrays/03-destructuring.js b/exercises/09-arrays/03-destructuring.js index dc4b150..8873af4 100644 --- a/exercises/09-arrays/03-destructuring.js +++ b/exercises/09-arrays/03-destructuring.js @@ -4,7 +4,7 @@ const cars = ["BMW", "Honda", "Civic"]; // Do not change this line * This problem is a repeat of the last problem, * except you will solve this problem with destructuring. * - * Create an array called "myCar". + * Create a variable called "myCar". * It should be equal to the first item in the array of cars. * Solve this problem without using destructuring. */ diff --git a/exercises/10-loops/02-while-loop.js b/exercises/10-loops/02-while-loop.js index 8a2c62e..4e97eb5 100644 --- a/exercises/10-loops/02-while-loop.js +++ b/exercises/10-loops/02-while-loop.js @@ -1,7 +1,7 @@ /** * Using a while loop, log the following numbers: * 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 - * + * * @example * logArrayWithWhile(); * // 10 @@ -17,11 +17,9 @@ */ const logWithWhile = () => { - // WRITE YOUR ANSWER HERE + // WRITE YOUR ANSWER HERE }; -logWithWhile(); - // IGNORE THIS BELOW. It is for the tests. export default logWithWhile; diff --git a/solutions/09-arrays/02-accessing-item-in-array.solution.js b/solutions/09-arrays/02-accessing-item-in-array.solution.js index f63d050..b849575 100644 --- a/solutions/09-arrays/02-accessing-item-in-array.solution.js +++ b/solutions/09-arrays/02-accessing-item-in-array.solution.js @@ -1,8 +1,9 @@ const cars = ["BMW", "Honda", "Civic"]; // Do not change this line /** - * Create a constant called "myCar". + * Create a variable called "myCar". * It should be equal to the first item in the array of cars. + * Solve this problem without using destructuring. */ // WRITE YOUR ANSWER BELOW THIS LINE diff --git a/solutions/09-arrays/03-destructuring.solution.js b/solutions/09-arrays/03-destructuring.solution.js index 19ff7f3..a5987a9 100644 --- a/solutions/09-arrays/03-destructuring.solution.js +++ b/solutions/09-arrays/03-destructuring.solution.js @@ -4,12 +4,11 @@ const cars = ["BMW", "Honda", "Civic"]; // Do not change this line * This problem is a repeat of the last problem, * except you will solve this problem with destructuring. * - * Create an array called "myCar". + * Create a variable called "myCar". * It should be equal to the first item in the array of cars. * Solve this problem without using destructuring. */ // WRITE YOUR ANSWER BELOW THIS LINE -const [ myCar ] = cars; -console.log(myCar); +const [myCar] = cars; From d7868961f5c01134130a5279f4f4fd8e315ca378 Mon Sep 17 00:00:00 2001 From: Matina Patsos Date: Wed, 26 Oct 2022 18:38:10 -0400 Subject: [PATCH 034/105] Loops exercise part 2 --- exercises/10-loops/04-loops.html | 75 +++++++++++++++++++++++++ exercises/10-loops/05-add-an-array.js | 15 +++++ exercises/10-loops/06-highest-number.js | 17 ++++++ exercises/10-loops/07-is-palidrome.js | 17 ++++++ test/10-loops/loops-test-helper.js | 16 +++++- test/10-loops/loops.spec.js | 32 +++++++++++ 6 files changed, 171 insertions(+), 1 deletion(-) create mode 100755 exercises/10-loops/04-loops.html create mode 100755 exercises/10-loops/05-add-an-array.js create mode 100755 exercises/10-loops/06-highest-number.js create mode 100755 exercises/10-loops/07-is-palidrome.js diff --git a/exercises/10-loops/04-loops.html b/exercises/10-loops/04-loops.html new file mode 100755 index 0000000..ef23e3c --- /dev/null +++ b/exercises/10-loops/04-loops.html @@ -0,0 +1,75 @@ + + + + + + + + EXERCISE + + + +
+ + + + + + +
PlaceName
+
+ + + diff --git a/exercises/10-loops/05-add-an-array.js b/exercises/10-loops/05-add-an-array.js new file mode 100755 index 0000000..7b7ac3c --- /dev/null +++ b/exercises/10-loops/05-add-an-array.js @@ -0,0 +1,15 @@ +/** + * Add all of the numbers in an array and return the sum. + * @param {array} numbers an array of numbers + * @returns {number} the sum of all the numbers in an array + * + * @example add([1, 2, 3]); // 6 + */ + +const add = (numbers) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default add; diff --git a/exercises/10-loops/06-highest-number.js b/exercises/10-loops/06-highest-number.js new file mode 100755 index 0000000..847241e --- /dev/null +++ b/exercises/10-loops/06-highest-number.js @@ -0,0 +1,17 @@ +/** + * Loop through the array using a for loop (or for ... of loop) and return the highest number + * @param {array} numbers array of numbers + * @returns {number} the highest number that was in the array + * + * @example highestNumber([1, 10, 2, 3, 4]) // 10 + * @example highestNumber([-1, -5, -4]) // -1 + * + */ + +const highestNumber = (numbers) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default highestNumber; diff --git a/exercises/10-loops/07-is-palidrome.js b/exercises/10-loops/07-is-palidrome.js new file mode 100755 index 0000000..0031961 --- /dev/null +++ b/exercises/10-loops/07-is-palidrome.js @@ -0,0 +1,17 @@ +/** + * Check to see if a string is a palindrome. + * A palindrome is a word, phrase, or sequence that reads the same backward as forward, e.g., madam or racecar. + * Use the split and join methods to solve this problem. + * @param {string} string + * @returns {boolean} true is a string is a palindrome, false if it is not. + * @example isPalindrome("eye"); // true + * @example isPalindrome("nope"); // false + */ + +const isPalindrome = (string) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default isPalindrome; diff --git a/test/10-loops/loops-test-helper.js b/test/10-loops/loops-test-helper.js index 87b4e21..63a9c41 100755 --- a/test/10-loops/loops-test-helper.js +++ b/test/10-loops/loops-test-helper.js @@ -6,4 +6,18 @@ import logWithWhile from "../../exercises/10-loops/02-while-loop.js"; import logArrayWithFor from "../../exercises/10-loops/03-for-loop.js"; -export { solvingProblems, arrayLength, logWithWhile, logArrayWithFor }; +import add from "../../exercises/10-loops/05-add-an-array.js"; + +import highestNumber from "../../exercises/10-loops/06-highest-number.js"; + +import isPalindrome from "../../exercises/10-loops/07-is-palidrome.js"; + +export { + solvingProblems, + arrayLength, + logWithWhile, + logArrayWithFor, + add, + highestNumber, + isPalindrome, +}; diff --git a/test/10-loops/loops.spec.js b/test/10-loops/loops.spec.js index 3361a71..6bd6844 100755 --- a/test/10-loops/loops.spec.js +++ b/test/10-loops/loops.spec.js @@ -5,6 +5,9 @@ import { arrayLength, logWithWhile, logArrayWithFor, + add, + highestNumber, + isPalindrome, } from "./loops-test-helper.js"; describe("10. Loops", () => { @@ -49,4 +52,33 @@ describe("10. Loops", () => { expect(funcStr).to.match(/for\s*\(/); }); }); + + describe("04-add-an-array", () => { + it('should return a sum of all of the numbers within the array "numbers"', () => { + expect(add([-1, 0.5, 2, 5])).to.equal(6.5); + }); + }); + + describe("06-highest-number", () => { + it("should return the highest number in the array", () => { + const number1 = highestNumber([1, 10, 2, 3, 4]); + expect(number1).to.equal(10); + const number2 = highestNumber([-1, -5, -4]); + expect(number2).to.equal(-1); + }); + }); + + describe("07-is-palidrome", () => { + it("should return true if a word is a palindrome", () => { + expect(isPalindrome("rotator")).to.be.equal(true); + expect(isPalindrome("noon")).to.be.equal(true); + }); + it("should return false if a word is not a palindrome", () => { + expect(isPalindrome("difference")).to.be.equal(false); + expect(isPalindrome("wedding")).to.be.equal(false); + }); + it("should use split", () => { + expect(isPalindrome.toString().includes("split")).to.equal(true); + }); + }); }); From a255a68ac24cff3fa30504717c5f940452836caa Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Mon, 31 Oct 2022 20:37:21 -0400 Subject: [PATCH 035/105] Solutions for first half of loops exercise --- ...olving-problems-with-functions.solution.js | 16 ++++++++ .../10-loops/01-array-length.solution.js | 16 ++++++++ solutions/10-loops/02-while-loop.solution.js | 39 +++++++++++++++++++ solutions/10-loops/03-for-loop.solution.js | 24 ++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 solutions/10-loops/00-solving-problems-with-functions.solution.js create mode 100644 solutions/10-loops/01-array-length.solution.js create mode 100644 solutions/10-loops/02-while-loop.solution.js create mode 100644 solutions/10-loops/03-for-loop.solution.js diff --git a/solutions/10-loops/00-solving-problems-with-functions.solution.js b/solutions/10-loops/00-solving-problems-with-functions.solution.js new file mode 100644 index 0000000..bd5189a --- /dev/null +++ b/solutions/10-loops/00-solving-problems-with-functions.solution.js @@ -0,0 +1,16 @@ +/** + * Return the function's argument. (This problem is to get you used to the new format.) + * @param {string} personName + * @return {string} personName + * + * @example returnAnswer("Lesley"); // Lesley + */ + +const returnAnswer = (personName) => { + // WRITE YOUR ANSWER HERE + return personName; +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default returnAnswer; diff --git a/solutions/10-loops/01-array-length.solution.js b/solutions/10-loops/01-array-length.solution.js new file mode 100644 index 0000000..df99a7d --- /dev/null +++ b/solutions/10-loops/01-array-length.solution.js @@ -0,0 +1,16 @@ +/** + * Return the length of an array + * @param {array} array + * @return {number} the length of an array + * + * @example + */ + +const arrayLength = (array) => { + // WRITE YOUR ANSWER HERE + return array.length; +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default arrayLength; diff --git a/solutions/10-loops/02-while-loop.solution.js b/solutions/10-loops/02-while-loop.solution.js new file mode 100644 index 0000000..673ff0c --- /dev/null +++ b/solutions/10-loops/02-while-loop.solution.js @@ -0,0 +1,39 @@ +/** + * Using a while loop, log the following numbers: + * 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 + * + * @example + * logArrayWithWhile(); + * // 10 + * // 20 + * // 30 + * // 40 + * // 50 + * // 60 + * // 70 + * // 80 + * // 90 + * // 100 + */ + +const logWithWhile = () => { + // WRITE YOUR ANSWER HERE + + // Method 1 + let counter = 1; + while (counter <= 10) { + console.log(10 * counter); + counter++; + } + + // Method 2 + let counter = 10; + while (counter <= 100) { + console.log(counter); + counter = counter + 10; + } +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default logWithWhile; diff --git a/solutions/10-loops/03-for-loop.solution.js b/solutions/10-loops/03-for-loop.solution.js new file mode 100644 index 0000000..cb15a67 --- /dev/null +++ b/solutions/10-loops/03-for-loop.solution.js @@ -0,0 +1,24 @@ +/** + * Using a for loop, lop through an array + * and log each item with console.log + * @param {array} array + * + * @example + * const array = ["Honda", "Ford", "Ferrari"]; + * logArrayWithFor(array); + * // Honda + * // Ford + * // Ferrari + */ + +const logArrayWithFor = (array) => { + // WRITE YOUR ANSWER HERE + for (let i = 0; i < array.length; i++) { + let item = array[i]; + console.log(item); + } +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default logArrayWithFor; From 4a8159a9400539b8db963f99453f5442b3cffd7e Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:44:51 -0400 Subject: [PATCH 036/105] 1st attempt at loops assignment --- .../10-loops/00-solving-problems-with-functions.js | 1 + exercises/10-loops/01-array-length.js | 1 + exercises/10-loops/02-while-loop.js | 7 +++++++ exercises/10-loops/03-for-loop.js | 10 +++++++--- exercises/10-loops/04-loops.html | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/exercises/10-loops/00-solving-problems-with-functions.js b/exercises/10-loops/00-solving-problems-with-functions.js index 4b6c6ba..699476c 100755 --- a/exercises/10-loops/00-solving-problems-with-functions.js +++ b/exercises/10-loops/00-solving-problems-with-functions.js @@ -8,6 +8,7 @@ const returnAnswer = (personName) => { // WRITE YOUR ANSWER HERE + return personName; }; // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/10-loops/01-array-length.js b/exercises/10-loops/01-array-length.js index f8933b6..bece634 100755 --- a/exercises/10-loops/01-array-length.js +++ b/exercises/10-loops/01-array-length.js @@ -8,6 +8,7 @@ const arrayLength = (array) => { // WRITE YOUR ANSWER HERE + return array.length; }; // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/10-loops/02-while-loop.js b/exercises/10-loops/02-while-loop.js index 4e97eb5..afc90cc 100644 --- a/exercises/10-loops/02-while-loop.js +++ b/exercises/10-loops/02-while-loop.js @@ -18,8 +18,15 @@ const logWithWhile = () => { // WRITE YOUR ANSWER HERE + let counter = 10; + while (counter <= 100) { + console.log(counter); + counter = counter + 10; + } }; +console.log(logWithWhile()); + // IGNORE THIS BELOW. It is for the tests. export default logWithWhile; diff --git a/exercises/10-loops/03-for-loop.js b/exercises/10-loops/03-for-loop.js index ba96e6b..406abbb 100644 --- a/exercises/10-loops/03-for-loop.js +++ b/exercises/10-loops/03-for-loop.js @@ -1,8 +1,8 @@ /** * Using a for loop, lop through an array * and log each item with console.log - * @param {array} array - * + * @param {array} array + * * @example * const array = ["Honda", "Ford", "Ferrari"]; * logArrayWithFor(array); @@ -12,7 +12,11 @@ */ const logArrayWithFor = (array) => { - // WRITE YOUR ANSWER HERE + // WRITE YOUR ANSWER HERE + let array2 = ["Honda", "Ford", "Ferrari"]; + for (let car of array2) { + console.log(car); + } }; // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/10-loops/04-loops.html b/exercises/10-loops/04-loops.html index ef23e3c..c5a9ec3 100755 --- a/exercises/10-loops/04-loops.html +++ b/exercises/10-loops/04-loops.html @@ -62,7 +62,7 @@ const addToTable = (place, name) => { const htmlString = `${place}${name}`; - tableBody.insertAdjacentHTML('beforeend', htmlString); + tableBody.insertAdjacentHTML("beforeend", htmlString); }; // Right now, this only adds the first person in the "results" array to the table. From bd8ed3b6373ca07c02fee9734008b438773fd4c1 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 1 Nov 2022 15:27:26 -0400 Subject: [PATCH 037/105] continue work on 10-loops problems --- exercises/10-loops/03-for-loop.js | 7 ++++--- exercises/10-loops/04-loops.html | 3 ++- exercises/10-loops/05-add-an-array.js | 9 +++++++++ exercises/10-loops/07-is-palidrome.js | 11 +++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/exercises/10-loops/03-for-loop.js b/exercises/10-loops/03-for-loop.js index 406abbb..bd54aee 100644 --- a/exercises/10-loops/03-for-loop.js +++ b/exercises/10-loops/03-for-loop.js @@ -13,11 +13,12 @@ const logArrayWithFor = (array) => { // WRITE YOUR ANSWER HERE - let array2 = ["Honda", "Ford", "Ferrari"]; - for (let car of array2) { - console.log(car); + for (let i = 0; i < array.length; i++) { + let item = array[i]; + console.log(item); } }; +logArrayWithFor(["Honda", "Ford", "Ferrari"]); // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/10-loops/04-loops.html b/exercises/10-loops/04-loops.html index c5a9ec3..8e13455 100755 --- a/exercises/10-loops/04-loops.html +++ b/exercises/10-loops/04-loops.html @@ -68,7 +68,8 @@ // Right now, this only adds the first person in the "results" array to the table. // Create a loop here and use this function within the loop // to add every person's name to the table. - addToTable(1, results[0]); // Change me. This should be inside your loop. + // addToTable(1, results[0]); // Change me. This should be inside your loop. + addToTable(1, results[i + 1]); })(); diff --git a/exercises/10-loops/05-add-an-array.js b/exercises/10-loops/05-add-an-array.js index 7b7ac3c..d8a5ea8 100755 --- a/exercises/10-loops/05-add-an-array.js +++ b/exercises/10-loops/05-add-an-array.js @@ -8,7 +8,16 @@ const add = (numbers) => { // WRITE YOUR ANSWER HERE + + //let sumArray = [numbers]; //?? how to set up (get arguments into?) an array + let sum = 0; + for (let i = 0; i < numbers.length; i++) { + sum += numbers[i]; + } + + return sum; }; +add([16, 12, 2]); // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/10-loops/07-is-palidrome.js b/exercises/10-loops/07-is-palidrome.js index 0031961..d977845 100755 --- a/exercises/10-loops/07-is-palidrome.js +++ b/exercises/10-loops/07-is-palidrome.js @@ -10,7 +10,18 @@ const isPalindrome = (string) => { // WRITE YOUR ANSWER HERE + /* + array = string.split(""); + reverseArray = array.reverse(); + reverseString = reverseArray.join(""); + if (string === reverseString) { + return true; + } else { + return false; + } + */ }; +isPalindrome("kayak"); // IGNORE THIS BELOW. It is for the tests. From 4f194f0953792e7f2e3a8ccc6b7bf85bd04d09b3 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 1 Nov 2022 18:30:59 -0400 Subject: [PATCH 038/105] Work on problem 10-06 highest number hal katzman --- exercises/10-loops/06-highest-number.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/exercises/10-loops/06-highest-number.js b/exercises/10-loops/06-highest-number.js index 847241e..f0e4871 100755 --- a/exercises/10-loops/06-highest-number.js +++ b/exercises/10-loops/06-highest-number.js @@ -10,8 +10,19 @@ const highestNumber = (numbers) => { // WRITE YOUR ANSWER HERE + + let m = -Infinity, + i = 0; + for (; i != numbers.length; ++i) { + if (numbers[i] > m) { + m = numbers[i]; + } + } + return m; }; +console.log(highestNumber([30, 690, -242, 683])); + // IGNORE THIS BELOW. It is for the tests. export default highestNumber; From 4fc4066c8e33bb523c375ff94a349ac9d538ff5e Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 1 Nov 2022 21:55:20 -0400 Subject: [PATCH 039/105] Problem 10-6: made borrowed code my own --- exercises/10-loops/06-highest-number.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/10-loops/06-highest-number.js b/exercises/10-loops/06-highest-number.js index f0e4871..c002b15 100755 --- a/exercises/10-loops/06-highest-number.js +++ b/exercises/10-loops/06-highest-number.js @@ -11,9 +11,9 @@ const highestNumber = (numbers) => { // WRITE YOUR ANSWER HERE - let m = -Infinity, - i = 0; - for (; i != numbers.length; ++i) { + let m = -Infinity; + + for (let i = 0; i < numbers.length; i++) { if (numbers[i] > m) { m = numbers[i]; } From 97ea228f928a3f576c7fb827332bb786214f7c06 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 2 Nov 2022 12:14:34 -0400 Subject: [PATCH 040/105] Problem 10-06 add attribubtion and update --- exercises/10-loops/06-highest-number.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/exercises/10-loops/06-highest-number.js b/exercises/10-loops/06-highest-number.js index c002b15..52db502 100755 --- a/exercises/10-loops/06-highest-number.js +++ b/exercises/10-loops/06-highest-number.js @@ -11,14 +11,17 @@ const highestNumber = (numbers) => { // WRITE YOUR ANSWER HERE - let m = -Infinity; + // I adopted this solution from https://stackoverflow.com/questions/54623431/find-the-biggest-number-in-an-array-by-using-javascript-loops + //Answered by user Jack Bashford + + let highNum = -Infinity; for (let i = 0; i < numbers.length; i++) { - if (numbers[i] > m) { - m = numbers[i]; + if (numbers[i] > highNum) { + highNum = numbers[i]; } } - return m; + return highNum; }; console.log(highestNumber([30, 690, -242, 683])); From 26811a7a6eb07bd4c99a48aa7d368cb08795becf Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:09:26 -0400 Subject: [PATCH 041/105] Problem 10-07 palindrome and exercise 10-loops finished except for html --- exercises/10-loops/07-is-palidrome.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/exercises/10-loops/07-is-palidrome.js b/exercises/10-loops/07-is-palidrome.js index d977845..b431631 100755 --- a/exercises/10-loops/07-is-palidrome.js +++ b/exercises/10-loops/07-is-palidrome.js @@ -10,18 +10,15 @@ const isPalindrome = (string) => { // WRITE YOUR ANSWER HERE - /* - array = string.split(""); - reverseArray = array.reverse(); - reverseString = reverseArray.join(""); - if (string === reverseString) { + + let stringReversed = string.split("").reverse().join(""); + + if (string === stringReversed) { return true; - } else { - return false; - } - */ + } else return false; }; isPalindrome("kayak"); +console.log(isPalindrome("kayak")); // IGNORE THIS BELOW. It is for the tests. From 3484a75bad70708177c3f480aaadb64e4f6344ea Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 2 Nov 2022 20:18:33 -0400 Subject: [PATCH 042/105] 10-Loops minor change --- exercises/10-loops/04-loops.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/exercises/10-loops/04-loops.html b/exercises/10-loops/04-loops.html index 8e13455..8056c5c 100755 --- a/exercises/10-loops/04-loops.html +++ b/exercises/10-loops/04-loops.html @@ -69,7 +69,11 @@ // Create a loop here and use this function within the loop // to add every person's name to the table. // addToTable(1, results[0]); // Change me. This should be inside your loop. - addToTable(1, results[i + 1]); + for (let name of results); + { + let place = i; + addToTable(results.indexOf(name) + 1, name); + } })(); From 01f4999335df42314e6013b5d2f376c2c6424b80 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 29 Oct 2022 12:46:29 -0400 Subject: [PATCH 043/105] Objects exercises --- .vscode/launch.json | 13 ++ exercises/11-objects/01-create-object.js | 10 ++ .../11-objects/02-create-nested-object.js | 32 +++++ .../11-objects/03-accessing-item-in-object.js | 13 ++ exercises/11-objects/04-update-object.js | 17 +++ .../11-objects/05-return-object-values.js | 26 ++++ exercises/11-objects/06-combine-object.js | 19 +++ test/11-objects/objects-test-helper.js | 44 +++++++ test/11-objects/objects.spec.js | 118 ++++++++++++++++++ 9 files changed, 292 insertions(+) create mode 100644 exercises/11-objects/01-create-object.js create mode 100644 exercises/11-objects/02-create-nested-object.js create mode 100644 exercises/11-objects/03-accessing-item-in-object.js create mode 100644 exercises/11-objects/04-update-object.js create mode 100644 exercises/11-objects/05-return-object-values.js create mode 100644 exercises/11-objects/06-combine-object.js create mode 100644 test/11-objects/objects-test-helper.js create mode 100644 test/11-objects/objects.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 315753c..08bf6e8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -147,5 +147,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "11. Objects", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/11-objects/objects.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/11-objects/01-create-object.js b/exercises/11-objects/01-create-object.js new file mode 100644 index 0000000..abb1477 --- /dev/null +++ b/exercises/11-objects/01-create-object.js @@ -0,0 +1,10 @@ +/** + * Create an object "myDog" that represents a dog. It should contain the properties: + * @property {string} name + * @property {string} breed + * @property {number} age + * @property {array} owners (array of strings) + * Each should have a value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/11-objects/02-create-nested-object.js b/exercises/11-objects/02-create-nested-object.js new file mode 100644 index 0000000..a022657 --- /dev/null +++ b/exercises/11-objects/02-create-nested-object.js @@ -0,0 +1,32 @@ +let name = "Eddie Willard"; // e.g. +let graduationYear = 2022; // e.g. +let skills = ["Javascript", "React", "CSS"]; // e.g. +let githubLink = "https://github.com/example/profile"; // e.g. +let linkedInLink = "https://linkedin.com/profile"; // e.g. + +/** + * Create a nested object called "graduate". + * Assigns "name", "graduationYear", and many of the other values above to the object + * in this format: + * @property {string} name + * @property {string} graduationYear + * @property {array} skills + * @property {object} links e.g. { github: "...", linkedIn: "..." } + * + * @example + * console.log(graduate); // + * { + * name: "Eddie Willard", + * graduationYear: 2021, + * skills: ["JavaScript", "React", "CSS"], + * links: { + * github: "https://github.com/example/profile", + * linkedIn: "https://linkedin.com/profile" + * } + * } + * + * Your answer should work with "name", "graduation", and the other variables above + * are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/11-objects/03-accessing-item-in-object.js b/exercises/11-objects/03-accessing-item-in-object.js new file mode 100644 index 0000000..f2b6b0b --- /dev/null +++ b/exercises/11-objects/03-accessing-item-in-object.js @@ -0,0 +1,13 @@ +const clothes = { + hat: "ballcap", + shirt: "jersey", + shoes: "cleats", +}; + +/** + * Create a variable called "hat". + * It should be equal to whatever the "hat" property is inside of the "clothes" object. + * This should still work when "clothes" has different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/11-objects/04-update-object.js b/exercises/11-objects/04-update-object.js new file mode 100644 index 0000000..ab1ff29 --- /dev/null +++ b/exercises/11-objects/04-update-object.js @@ -0,0 +1,17 @@ +let student = { + name: "Maria Gómez", + skills: ["JavaScript"], +}; + +/** + * Update the "student" object name to equal your name. + * Add another skill to the "skills" array. + * @example + * console.log(student); + * { + * name: "Jamal Taylor", + * skills: ["JavaScript", "Being a permanent student"], + * }; + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/11-objects/05-return-object-values.js b/exercises/11-objects/05-return-object-values.js new file mode 100644 index 0000000..867b505 --- /dev/null +++ b/exercises/11-objects/05-return-object-values.js @@ -0,0 +1,26 @@ +/** + * Return all the properties contained in the "blogPost" object. + * @param {object} blogPost + * @returns {array} of strings + * + * @example + * + * const blogPost = { + * title: "Building a Form Validation API", + * author: "Mark Marshall", + * date: "2021-08-05", + * content: + * "It's required! Let's learn how to leverage the JavaScript Constraint API to remind your users when they need to finish filling out those pesky form fields. And we will show you how to do this with keeping accessibility in mind. ...", + * }; + * + * returnObjectValues(blogPost); + * // ["Building a Form Validation API", "Mark Marshall", "2021-08-05", "It's required! Let's learn how to leverage the JavaScript Constraint API to remind your users when they need to finish filling out those pesky form fields. And we will show you how to do this with keeping accessibility in mind. ..."] + */ + +const returnObjectValues = (blogPost) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default returnObjectValues; diff --git a/exercises/11-objects/06-combine-object.js b/exercises/11-objects/06-combine-object.js new file mode 100644 index 0000000..c439c43 --- /dev/null +++ b/exercises/11-objects/06-combine-object.js @@ -0,0 +1,19 @@ +/** + * Combine two objects into one + * @param {object} obj1 + * @param {object} obj2 + * @return {object} obj1 and obj2 combined + * + * @example + * const obj1 = { firstName: "Clark" } + * const obj2 = { lastName: "Kent" } + * combineObjects(obj1, obj2); // { firstName: "Clark", lastName: "Kent" } + */ + +const combineObjects = (obj1, obj2) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default combineObjects; diff --git a/test/11-objects/objects-test-helper.js b/test/11-objects/objects-test-helper.js new file mode 100644 index 0000000..dfc8d8c --- /dev/null +++ b/test/11-objects/objects-test-helper.js @@ -0,0 +1,44 @@ +import { getAnswer } from "../getAnswer.js"; + +const createDogObjectStr = getAnswer( + "../exercises/11-objects/01-create-object.js" +); + +const createGraduateObjectStr = getAnswer( + "../exercises/11-objects/02-create-nested-object.js" +); + +const accessAnItemObjectStr = getAnswer( + "../exercises/11-objects/03-accessing-item-in-object.js" +); + +const updateStudentObjectStr = getAnswer( + "../exercises/11-objects/04-update-object.js" +); + +import returnObjectValues from "../../exercises/11-objects/05-return-object-values.js"; + +import combineObjects from "../../exercises/11-objects/06-combine-object.js"; + +export const createDogObject = eval(`() => { + ${createDogObjectStr} + return myDog; +}`); + +export const createGraduateObject = + eval(`(name, graduationYear, skills, githubLink, linkedInLink) => { + ${createGraduateObjectStr} + return graduate; +}`); + +export const accessAnItemObject = eval(`(clothes) => { + ${accessAnItemObjectStr} + return hat; +}`); + +export const updateStudentObject = eval(`(student) => { + ${updateStudentObjectStr} + return student; +}`); + +export { returnObjectValues, combineObjects }; diff --git a/test/11-objects/objects.spec.js b/test/11-objects/objects.spec.js new file mode 100644 index 0000000..234acf4 --- /dev/null +++ b/test/11-objects/objects.spec.js @@ -0,0 +1,118 @@ +import { expect } from "chai"; +import { + createDogObject, + createGraduateObject, + updateStudentObject, + accessAnItemObject, + returnObjectValues, + combineObjects, +} from "./objects-test-helper.js"; + +describe("11. Objects", () => { + describe("01-create-object", () => { + it('should contain an object called "myDog"', () => { + const myDog = createDogObject(); + expect(myDog).to.be.an("object"); + }); + it('the "owners" property should be an array', () => { + const [name, breed, age, owners] = Object.values(createDogObject()); + expect(name).to.be.a("string").to.be.ok; + expect(breed).to.be.a("string").to.be.ok; + expect(age).to.be.a("number"); + expect(owners).to.be.an("array"); + }); + }); + + describe("02-create-nested-object.js", () => { + it("should return an object", () => { + const graduateObject = createGraduateObject( + "Eddie Willard", + 2020, + ["JavaScript", "React", "CSS"], + "https://github.com/example/profile", + "https://linkedin.com/profile" + ); + expect(graduateObject).to.be.an("object"); + }); + it("the object it returns should have the properties name (string), graduationYear (number), skills (array), links (object of strings)", () => { + const graduateObject = createGraduateObject( + "Eddie Willard", + 2020, + ["JavaScript", "React", "CSS"], + "https://github.com/example/profile", + "https://linkedin.com/profile" + ); + expect(graduateObject).to.deep.equal({ + name: "Eddie Willard", + graduationYear: 2020, + skills: ["JavaScript", "React", "CSS"], + links: { + github: "https://github.com/example/profile", + linkedIn: "https://linkedin.com/profile", + }, + }); + }); + }); + + describe("03-accessing-item-in-object", () => { + it('should return the value of "hat"', () => { + const hat = accessAnItemObject({ + hat: "fedora", + shirt: "button down vest", + shoes: "dress shoes", + }); + expect(hat).to.equal("fedora"); + }); + }); + + describe("04-update-object", () => { + it('should change the "name" property in the "student" object', () => { + const student = updateStudentObject({ + name: "Cary Grant", + skills: [], + }); + expect(student.name).to.not.equal("Cary Grant"); + expect(student.name).to.be.a("string").to.be.ok; + }); + it('should add a new skill to the "skills" array inside of the "student" object', () => { + const student = updateStudentObject({ + name: "Judy Garland", + skills: ["Acting", "Singing"], + }); + expect(student.skills.length).to.equal(3); + }); + }); + + describe("05-return-object-values", () => { + it("should return all the values in an object", () => { + const objectValues = returnObjectValues({ + title: "Best CSS Tricks of the Year", + author: "Mark Marshall", + date: "2021-12-31", + content: "1. Elegant Shadow ...", + }); + expect(objectValues).to.deep.equal([ + "Best CSS Tricks of the Year", + "Mark Marshall", + "2021-12-31", + "1. Elegant Shadow ...", + ]); + }); + }); + + describe("06-combine-object", () => { + it("should combine two objects and return a single object", () => { + const obj1 = { + firstName: "Clark", + }; + const obj2 = { + lastName: "Kent", + }; + const combinedObj = combineObjects(obj1, obj2); + expect(combinedObj).to.deep.equal({ + firstName: "Clark", + lastName: "Kent", + }); + }); + }); +}); From 0f64177c24f9e104e2a7914c564b4f39d72c6fb0 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 2 Nov 2022 23:35:58 -0400 Subject: [PATCH 044/105] Problems 10-04 complete --- exercises/10-loops/04-loops.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/exercises/10-loops/04-loops.html b/exercises/10-loops/04-loops.html index 8056c5c..c5c2fca 100755 --- a/exercises/10-loops/04-loops.html +++ b/exercises/10-loops/04-loops.html @@ -69,10 +69,9 @@ // Create a loop here and use this function within the loop // to add every person's name to the table. // addToTable(1, results[0]); // Change me. This should be inside your loop. - for (let name of results); - { - let place = i; - addToTable(results.indexOf(name) + 1, name); + + for (let i = 0; i < results.length; i++) { + addToTable(i + 1, results[i]); } })(); From 0cad38784afeb16ac1f37a40d299d788ef1de0ac Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 2 Nov 2022 23:40:46 -0400 Subject: [PATCH 045/105] Problems 11-object initial work --- exercises/11-objects/02-create-nested-object.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/exercises/11-objects/02-create-nested-object.js b/exercises/11-objects/02-create-nested-object.js index a022657..6fc17f3 100644 --- a/exercises/11-objects/02-create-nested-object.js +++ b/exercises/11-objects/02-create-nested-object.js @@ -30,3 +30,13 @@ let linkedInLink = "https://linkedin.com/profile"; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let graduate = { + name: name, + graduationYear: graduationYear, + skills: [], + links: { + githubLink: "https://github.com/example/profile", + linkedInLink: "https://linkedin.com/profile", + }, +}; +console.log(graduate); From bb074d4b09ebc114de3b1cfdd6b8b6e04a66cb28 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 3 Nov 2022 14:04:35 -0400 Subject: [PATCH 046/105] Problems 11-01, 11-02, 11-03 --- exercises/11-objects/01-create-object.js | 8 ++++++++ exercises/11-objects/02-create-nested-object.js | 6 +++--- exercises/11-objects/03-accessing-item-in-object.js | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/exercises/11-objects/01-create-object.js b/exercises/11-objects/01-create-object.js index abb1477..945db6a 100644 --- a/exercises/11-objects/01-create-object.js +++ b/exercises/11-objects/01-create-object.js @@ -8,3 +8,11 @@ */ // WRITE YOUR ANSWER BELOW THIS LINE + +const myDog = { + name: "Bassey", + breed: "Lab", + age: 3, + owners: ["Jack", "Floria"], +}; +console.log(myDog); diff --git a/exercises/11-objects/02-create-nested-object.js b/exercises/11-objects/02-create-nested-object.js index 6fc17f3..b0b54eb 100644 --- a/exercises/11-objects/02-create-nested-object.js +++ b/exercises/11-objects/02-create-nested-object.js @@ -33,10 +33,10 @@ let linkedInLink = "https://linkedin.com/profile"; // e.g. let graduate = { name: name, graduationYear: graduationYear, - skills: [], + skills: skills, links: { - githubLink: "https://github.com/example/profile", - linkedInLink: "https://linkedin.com/profile", + githubLink, + linkedInLink, }, }; console.log(graduate); diff --git a/exercises/11-objects/03-accessing-item-in-object.js b/exercises/11-objects/03-accessing-item-in-object.js index f2b6b0b..4096c18 100644 --- a/exercises/11-objects/03-accessing-item-in-object.js +++ b/exercises/11-objects/03-accessing-item-in-object.js @@ -11,3 +11,7 @@ const clothes = { */ // WRITE YOUR ANSWER BELOW THIS LINE + +let hat = clothes["hat"]; + +console.log(hat); From 1ee583b05f37d81f6699857b7cae33e6f4f1f1b2 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 3 Nov 2022 20:37:27 -0400 Subject: [PATCH 047/105] Problem 11-02 --- exercises/11-objects/04-update-object.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exercises/11-objects/04-update-object.js b/exercises/11-objects/04-update-object.js index ab1ff29..de73f97 100644 --- a/exercises/11-objects/04-update-object.js +++ b/exercises/11-objects/04-update-object.js @@ -15,3 +15,8 @@ let student = { */ // WRITE YOUR ANSWER BELOW THIS LINE + +student.name = "Hal Katzman"; +student.skills = [...student.skills, "CSS"]; + +console.log(student); From 1f58dab435aa86c8efd9b2721b41fab2b07cf033 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 3 Nov 2022 20:42:23 -0400 Subject: [PATCH 048/105] Problem 11-04 --- exercises/11-objects/04-update-object.js | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/11-objects/04-update-object.js b/exercises/11-objects/04-update-object.js index de73f97..98ec1c6 100644 --- a/exercises/11-objects/04-update-object.js +++ b/exercises/11-objects/04-update-object.js @@ -15,7 +15,6 @@ let student = { */ // WRITE YOUR ANSWER BELOW THIS LINE - student.name = "Hal Katzman"; student.skills = [...student.skills, "CSS"]; From 6c27b203ffaee76b67425fb4e36339177f5aa6b8 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 3 Nov 2022 21:05:22 -0400 Subject: [PATCH 049/105] Problem 11-04 a better solution --- exercises/11-objects/04-update-object.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/11-objects/04-update-object.js b/exercises/11-objects/04-update-object.js index 98ec1c6..c4e7645 100644 --- a/exercises/11-objects/04-update-object.js +++ b/exercises/11-objects/04-update-object.js @@ -16,6 +16,7 @@ let student = { // WRITE YOUR ANSWER BELOW THIS LINE student.name = "Hal Katzman"; -student.skills = [...student.skills, "CSS"]; +// student.skills = [...student.skills, "CSS"]; OR: +student.skills.push("HTML"); console.log(student); From 1b7a508686f9fbcdaecd0f47fa3902552c589861 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Sat, 5 Nov 2022 14:57:46 -0400 Subject: [PATCH 050/105] Problems 11-05 and 11-06 --- exercises/11-objects/05-return-object-values.js | 9 +++++++++ exercises/11-objects/06-combine-object.js | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/exercises/11-objects/05-return-object-values.js b/exercises/11-objects/05-return-object-values.js index 867b505..89027f5 100644 --- a/exercises/11-objects/05-return-object-values.js +++ b/exercises/11-objects/05-return-object-values.js @@ -19,7 +19,16 @@ const returnObjectValues = (blogPost) => { // WRITE YOUR ANSWER HERE + let values = Object.values(blogPost); + console.log(values); + return values; }; +returnObjectValues({ + title: "An Interesting Fact About Me, A Month Late", + author: "Paul Mermod", + date: "2022-11-05", + content: "I have a Bachelor of Fine Arts and worked in accounting.", +}); // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/11-objects/06-combine-object.js b/exercises/11-objects/06-combine-object.js index c439c43..e07b6d9 100644 --- a/exercises/11-objects/06-combine-object.js +++ b/exercises/11-objects/06-combine-object.js @@ -12,8 +12,12 @@ const combineObjects = (obj1, obj2) => { // WRITE YOUR ANSWER HERE + let combined = { ...obj1, ...obj2 }; + console.log(combined); + return combined; }; +combineObjects({ city: "Albany" }, { state: "NY" }); // IGNORE THIS BELOW. It is for the tests. export default combineObjects; From 947c72a738be38da15fd000945c3a6a3de29718f Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Sat, 5 Nov 2022 15:11:12 -0400 Subject: [PATCH 051/105] Problem 11-02 --- exercises/11-objects/04-update-object.js | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/11-objects/04-update-object.js b/exercises/11-objects/04-update-object.js index c4e7645..f4511a2 100644 --- a/exercises/11-objects/04-update-object.js +++ b/exercises/11-objects/04-update-object.js @@ -16,7 +16,6 @@ let student = { // WRITE YOUR ANSWER BELOW THIS LINE student.name = "Hal Katzman"; -// student.skills = [...student.skills, "CSS"]; OR: student.skills.push("HTML"); console.log(student); From e29c7f3548d29a41ae5cbf84915b5c94f617fe62 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Sat, 5 Nov 2022 15:55:48 -0400 Subject: [PATCH 052/105] Problem 11-02 revise --- exercises/11-objects/02-create-nested-object.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/11-objects/02-create-nested-object.js b/exercises/11-objects/02-create-nested-object.js index b0b54eb..63ccf94 100644 --- a/exercises/11-objects/02-create-nested-object.js +++ b/exercises/11-objects/02-create-nested-object.js @@ -31,9 +31,9 @@ let linkedInLink = "https://linkedin.com/profile"; // e.g. // WRITE YOUR ANSWER BELOW THIS LINE let graduate = { - name: name, - graduationYear: graduationYear, - skills: skills, + name, + graduationYear, + skills, links: { githubLink, linkedInLink, From 923c529041156af58a081997319a063d543a5388 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 5 Nov 2022 09:37:06 -0400 Subject: [PATCH 053/105] Loops and object exercise solutions --- solutions/10-loops/04-loops.solution.html | 78 +++++++++++++++++++ .../10-loops/05-add-an-array.solution.js | 29 +++++++ .../10-loops/06-highest-number.solution.js | 33 ++++++++ .../10-loops/07-is-palidrome.solution.js | 32 ++++++++ .../11-objects/01-create-object.solution.js | 17 ++++ .../02-create-nested-object.solution.js | 42 ++++++++++ .../03-accessing-item-in-object.solution.js | 15 ++++ .../11-objects/04-update-object.solution.js | 20 +++++ .../05-return-object-values.solution.js | 26 +++++++ .../11-objects/06-combine-object.solution.js | 20 +++++ 10 files changed, 312 insertions(+) create mode 100644 solutions/10-loops/04-loops.solution.html create mode 100644 solutions/10-loops/05-add-an-array.solution.js create mode 100644 solutions/10-loops/06-highest-number.solution.js create mode 100644 solutions/10-loops/07-is-palidrome.solution.js create mode 100644 solutions/11-objects/01-create-object.solution.js create mode 100644 solutions/11-objects/02-create-nested-object.solution.js create mode 100644 solutions/11-objects/03-accessing-item-in-object.solution.js create mode 100644 solutions/11-objects/04-update-object.solution.js create mode 100644 solutions/11-objects/05-return-object-values.solution.js create mode 100644 solutions/11-objects/06-combine-object.solution.js diff --git a/solutions/10-loops/04-loops.solution.html b/solutions/10-loops/04-loops.solution.html new file mode 100644 index 0000000..4579c3c --- /dev/null +++ b/solutions/10-loops/04-loops.solution.html @@ -0,0 +1,78 @@ + + + + + + + + EXERCISE + + + +
+ + + + + + +
PlaceName
+
+ + + diff --git a/solutions/10-loops/05-add-an-array.solution.js b/solutions/10-loops/05-add-an-array.solution.js new file mode 100644 index 0000000..1dd18f3 --- /dev/null +++ b/solutions/10-loops/05-add-an-array.solution.js @@ -0,0 +1,29 @@ +/** + * Add all of the numbers in an array and return the sum. + * @param {array} numbers an array of numbers + * @return {number} the sum of all the numbers in an array + * + * @example add([1, 2, 3]); // 6 + */ + +const add = (numbers) => { + // WRITE YOUR ANSWER HERE + + // Solution 1 + let sum = 0; + for (let i = 0; i < numbers.length; i++) { + sum = sum + numbers[i]; + } + return sum; + + // Solution 2 + let sum = 0; + for (let num of numbers) { + sum += num; + } + return sum; +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default add; diff --git a/solutions/10-loops/06-highest-number.solution.js b/solutions/10-loops/06-highest-number.solution.js new file mode 100644 index 0000000..c113501 --- /dev/null +++ b/solutions/10-loops/06-highest-number.solution.js @@ -0,0 +1,33 @@ +/** + * Loop through the array using a for loop (or for ... of loop) and return the highest number + * @param {array} numbers array of numbers + * @returns {number} the highest number that was in the array + * + * @example highestNumber([1, 10, 2, 3, 4]) // 10 + * @example highestNumber([-1, -5, -4]) // -1 + * + */ + +const highestNumber = (numbers) => { + // WRITE YOUR ANSWER HERE + + // Solution 1: For loop + let highest; + for (let i = 0; i < numbers.length; i++) { + let num = numbers[i]; + if (num > highest || highest === undefined) highest = num; + } + return highest; + + // Solution 2: For ... of loop + let highest; + for (let num of numbers) { + if (num > highest || highest === undefined) highest = num; + } + return highest; + + // Solution 3 + return Math.max(...numbers); +}; + +export default highestNumber; diff --git a/solutions/10-loops/07-is-palidrome.solution.js b/solutions/10-loops/07-is-palidrome.solution.js new file mode 100644 index 0000000..e4e8302 --- /dev/null +++ b/solutions/10-loops/07-is-palidrome.solution.js @@ -0,0 +1,32 @@ +/** + * Check to see if a string is a palindrome. + * A palindrome is a word, phrase, or sequence that reads the same backward as forward, e.g., madam or racecar. + * Use the split and join methods to solve this problem. + * @param {string} string + * @return {boolean} true is a string is a palindrome, false if it is not. + * @example isPalindrome("eye"); // true + * @example isPalindrome("nope"); // false + */ + +const isPalindrome = (string) => { + // WRITE YOUR ANSWER HERE + + // Solution 1: for ... of loop + let letters = string.split(""); + let reverse = ""; + for (let letter of letters) { + reverse = letter + reverse; + } + if (reverse === string) { + return true; + } + return false; + + // Solution 2: reverse + const reverse = string.split("").reverse().join(""); + return reverse === string; +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default isPalindrome; diff --git a/solutions/11-objects/01-create-object.solution.js b/solutions/11-objects/01-create-object.solution.js new file mode 100644 index 0000000..1d20ae4 --- /dev/null +++ b/solutions/11-objects/01-create-object.solution.js @@ -0,0 +1,17 @@ +/** + * Create an object "myDog" that represents a dog. It should contain the properties: + * @property {string} name + * @property {string} breed + * @property {number} age + * @property {array} owners (array of strings) + * Each should have a value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const myDog = { + name: "Fido", + breed: "Mastiff", + age: 8, + owners: ["Jack", "Jill"], +}; diff --git a/solutions/11-objects/02-create-nested-object.solution.js b/solutions/11-objects/02-create-nested-object.solution.js new file mode 100644 index 0000000..ecd0204 --- /dev/null +++ b/solutions/11-objects/02-create-nested-object.solution.js @@ -0,0 +1,42 @@ +let name = "Eddie Willard"; // e.g. +let graduationYear = 2022; // e.g. +let skills = ["Javascript", "React", "CSS"]; // e.g. +let githubLink = "https://github.com/example/profile"; // e.g. +let linkedInLink = "https://linkedin.com/profile"; // e.g. + +/** + * Create a nested object called "graduate". + * Assigns "name", "graduationYear", and many of the other values above to the object + * in this format: + * @property {string} name + * @property {string} graduationYear + * @property {array} skills + * @property {object} links e.g. { github: "...", linkedIn: "..." } + * + * @example + * console.log(graduate); // + * { + * name: "Eddie Willard", + * graduationYear: 2021, + * skills: ["JavaScript", "React", "CSS"], + * links: { + * github: "https://github.com/example/profile", + * linkedIn: "https://linkedin.com/profile" + * } + * } + * + * Your answer should work with "name", "graduation", and the other variables above + * are different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const graduate = { + name, + graduationYear, + skills, + links: { + github: githubLink, + linkedIn: linkedInLink, + }, +}; diff --git a/solutions/11-objects/03-accessing-item-in-object.solution.js b/solutions/11-objects/03-accessing-item-in-object.solution.js new file mode 100644 index 0000000..1b24a54 --- /dev/null +++ b/solutions/11-objects/03-accessing-item-in-object.solution.js @@ -0,0 +1,15 @@ +const clothes = { + hat: "ballcap", + shirt: "jersey", + shoes: "cleats", +}; + +/** + * Create a variable called "hat". + * It should be equal to whatever the "hat" property is inside of the "clothes" object. + * This should still work when "clothes" has different values. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let hat = clothes.hat; diff --git a/solutions/11-objects/04-update-object.solution.js b/solutions/11-objects/04-update-object.solution.js new file mode 100644 index 0000000..cab8aea --- /dev/null +++ b/solutions/11-objects/04-update-object.solution.js @@ -0,0 +1,20 @@ +let student = { + name: "Maria Gómez", + skills: ["JavaScript"], +}; + +/** + * Update the "student" object name to equal your name. + * Add another skill to the "skills" array. + * @example + * console.log(student); + * { + * name: "Jamal Taylor", + * skills: ["JavaScript", "Being a permanent student"], + * }; + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +student.name = "Simone Dubois"; +student.skills.push("SCSS"); diff --git a/solutions/11-objects/05-return-object-values.solution.js b/solutions/11-objects/05-return-object-values.solution.js new file mode 100644 index 0000000..2fafe3a --- /dev/null +++ b/solutions/11-objects/05-return-object-values.solution.js @@ -0,0 +1,26 @@ +/** + * Return all the properties contained in the "blogPost" object. + * @returns {array} of strings + * + * @example + * + * const blogPost = { + * title: "Building a Form Validation API", + * author: "Mark Marshall", + * date: "2021-08-05", + * content: + * "It's required! Let's learn how to leverage the JavaScript Constraint API to remind your users when they need to finish filling out those pesky form fields. And we will show you how to do this with keeping accessibility in mind. ...", + * }; + * + * returnObjectValues(blogPost); + * // ["Building a Form Validation API", "Mark Marshall", "2021-08-05", "It's required! Let's learn how to leverage the JavaScript Constraint API to remind your users when they need to finish filling out those pesky form fields. And we will show you how to do this with keeping accessibility in mind. ..."] + */ + +const returnObjectValues = (blogPost) => { + // WRITE YOUR ANSWER HERE + return Object.values(blogPost); +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default returnObjectValues; diff --git a/solutions/11-objects/06-combine-object.solution.js b/solutions/11-objects/06-combine-object.solution.js new file mode 100644 index 0000000..5a171c9 --- /dev/null +++ b/solutions/11-objects/06-combine-object.solution.js @@ -0,0 +1,20 @@ +/** + * Combine two objects into one + * @param {object} obj1 + * @param {object} obj2 + * @return {object} obj1 and obj2 combined + * + * @example + * const obj1 = { firstName: "Clark" } + * const obj2 = { lastName: "Kent" } + * combineObjects(obj1, obj2); // { firstName: "Clark", lastName: "Kent" } + */ + +const combineObjects = (obj1, obj2) => { + // WRITE YOUR ANSWER HERE + return { ...obj1, ...obj2 }; +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default combineObjects; From 4262858106fe0348d2b54803da0833860540307c Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 29 Oct 2022 14:45:41 -0400 Subject: [PATCH 054/105] Loops with objects exercises --- .vscode/launch.json | 13 ++++ .../01-loop-through-object.js | 25 ++++++ .../02-loop-through-object.html | 76 +++++++++++++++++++ .../loops-objects-test-helper.js | 3 + test/12-loops-objects/loops-objects.spec.js | 19 +++++ 5 files changed, 136 insertions(+) create mode 100644 exercises/12-loops-objects/01-loop-through-object.js create mode 100644 exercises/12-loops-objects/02-loop-through-object.html create mode 100644 test/12-loops-objects/loops-objects-test-helper.js create mode 100644 test/12-loops-objects/loops-objects.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 08bf6e8..25d48a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -160,5 +160,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "12. Loops with Objects", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/12-loops-objects/loops-objects.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/12-loops-objects/01-loop-through-object.js b/exercises/12-loops-objects/01-loop-through-object.js new file mode 100644 index 0000000..73978f6 --- /dev/null +++ b/exercises/12-loops-objects/01-loop-through-object.js @@ -0,0 +1,25 @@ +/** + * Loop through all properties within the "links" object + * an return a list of HTML links. + * @param {object} links e.g. { Text: "https://url.com" } + * @returns {string} of tags + * + * @example + * + * const links = { + * Dogs: "http://www.omfgdogs.com", + * Kittens: "https://giphy.com/search/kitten", + * "Hamster Dance": "https://hamster.dance/hamsterdance/", + * }; + * + * generateLinks(links); + * // DogsKittensHamster Dance + */ + +const generateLinks = (links) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default generateLinks; diff --git a/exercises/12-loops-objects/02-loop-through-object.html b/exercises/12-loops-objects/02-loop-through-object.html new file mode 100644 index 0000000..3f6ee6d --- /dev/null +++ b/exercises/12-loops-objects/02-loop-through-object.html @@ -0,0 +1,76 @@ + + + + + + + + EXERCISE + + + +
+

Now Playing

+
    +
    + + + diff --git a/test/12-loops-objects/loops-objects-test-helper.js b/test/12-loops-objects/loops-objects-test-helper.js new file mode 100644 index 0000000..f72bef6 --- /dev/null +++ b/test/12-loops-objects/loops-objects-test-helper.js @@ -0,0 +1,3 @@ +import generateLinks from "../../exercises/12-loops-objects/01-loop-through-object.js"; + +export { generateLinks }; diff --git a/test/12-loops-objects/loops-objects.spec.js b/test/12-loops-objects/loops-objects.spec.js new file mode 100644 index 0000000..91de587 --- /dev/null +++ b/test/12-loops-objects/loops-objects.spec.js @@ -0,0 +1,19 @@ +import { expect } from "chai"; +import { generateLinks } from "./loops-objects-test-helper.js"; + +describe("12. Loops with Objects", () => { + describe("01-loop-through-object", () => { + it("should return a string of tags", () => { + const anchors = generateLinks({ + Google: "https://www.google.com", + Facebook: "https://www.facebook.com", + }); + expect(anchors).to.be.a("string"); + expect(anchors).to.match(/(\s?Google\s?\s?Facebook\s? Date: Sat, 5 Nov 2022 14:53:27 -0400 Subject: [PATCH 055/105] More conditionals exercises --- .vscode/launch.json | 13 +++++++ .../01-ternary-operator.js | 13 +++++++ .../02-short-circuiting.js | 13 +++++++ .../more-conditionals-test-helper.js | 23 ++++++++++++ .../more-conditionals.spec.js | 35 +++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 exercises/13-more-conditionals/01-ternary-operator.js create mode 100644 exercises/13-more-conditionals/02-short-circuiting.js create mode 100644 test/13-more-conditionals/more-conditionals-test-helper.js create mode 100644 test/13-more-conditionals/more-conditionals.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 25d48a2..784f236 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -173,5 +173,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "13. More Conditionals", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/13-more-conditionals/more-conditionals.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/13-more-conditionals/01-ternary-operator.js b/exercises/13-more-conditionals/01-ternary-operator.js new file mode 100644 index 0000000..b4765b3 --- /dev/null +++ b/exercises/13-more-conditionals/01-ternary-operator.js @@ -0,0 +1,13 @@ +let num = 8; // e.g. + +/** + * This is similar to an older problem. + * Solve this problem with the ternary operator this time. + * + * Create a variable called "isEvenOrOdd". (Do not use var.) + * If "num" is even, "isEvenOrOdd" should equal the string "even". + * Otherwise, "isEvenOrOdd" should equal the string "odd". + * Your answer should still work when "num" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/13-more-conditionals/02-short-circuiting.js b/exercises/13-more-conditionals/02-short-circuiting.js new file mode 100644 index 0000000..2982947 --- /dev/null +++ b/exercises/13-more-conditionals/02-short-circuiting.js @@ -0,0 +1,13 @@ +let error = "Username already exists."; // When the test runs, this could also be an empty string + +/** + * Use short circuiting to solve this problem. + * + * Create a variable called "errorMessage". + * If "error" has a message (in order words, its a string that isn't an empty string), + * then "errorMessage" should equal that message. + * If "error" is equal to an empty string or some other falsy value, + * then "errorMessage" should equal "An unexpected error occurred.". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/13-more-conditionals/more-conditionals-test-helper.js b/test/13-more-conditionals/more-conditionals-test-helper.js new file mode 100644 index 0000000..8f6bf2c --- /dev/null +++ b/test/13-more-conditionals/more-conditionals-test-helper.js @@ -0,0 +1,23 @@ +import { getAnswer } from "../getAnswer.js"; + +const createDogObjectStr = getAnswer( + "../exercises/11-objects/01-create-object.js" +); + +const isEvenOrOddStr = getAnswer( + "../exercises/13-more-conditionals/01-ternary-operator.js" +); + +const errorMessageStr = getAnswer( + "../exercises/13-more-conditionals/02-short-circuiting.js" +); + +export const isEvenOrOdd = eval(`(num) => { + ${isEvenOrOddStr} + return isEvenOrOdd; +}`); + +export const getErrorMessage = eval(`(error) => { + ${errorMessageStr} + return errorMessage; +}`); diff --git a/test/13-more-conditionals/more-conditionals.spec.js b/test/13-more-conditionals/more-conditionals.spec.js new file mode 100644 index 0000000..007fd97 --- /dev/null +++ b/test/13-more-conditionals/more-conditionals.spec.js @@ -0,0 +1,35 @@ +import { expect } from "chai"; +import { + isEvenOrOdd, + getErrorMessage, +} from "./more-conditionals-test-helper.js"; + +describe("13. More Conditionals", () => { + describe("01-ternary-operator", () => { + it('"isEvenOrOdd" should equal "even" if "num" is even', () => { + expect(isEvenOrOdd(22)).to.equal("even"); + }); + it('"isEvenOrOdd" should equal "odd" if "num" is odd', () => { + expect(isEvenOrOdd(9)).to.equal("odd"); + }); + it("solve this problem with the ternary operator", () => { + const str = isEvenOrOdd.toString(); + expect(str).to.match(/=[\S\s]*\?[\S\s]*\:/); + }); + }); + + describe("02-short-circuiting", () => { + it('"errorMessage" should equal "Username already exists." when message equals "Username already exists."', () => { + const result = getErrorMessage("Username already exists."); + expect(result).to.equal("Username already exists."); + }); + it('"errorMessage" should equal "An unexpected error occurred." when message equals "" or another falsey value', () => { + const result = getErrorMessage(""); + expect(result).to.equal("An unexpected error occurred."); + }); + it("solve this problem with short circuiting (either || or &&)", () => { + const str = getErrorMessage.toString(); + expect(str).to.match(/\|\|/); + }); + }); +}); From dfe5f8543ee96af1edf145b7d9affc62a162016b Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 9 Nov 2022 15:33:11 -0500 Subject: [PATCH 056/105] Problem 12-01 hal --- exercises/12-loops-objects/01-loop-through-object.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/exercises/12-loops-objects/01-loop-through-object.js b/exercises/12-loops-objects/01-loop-through-object.js index 73978f6..ae16690 100644 --- a/exercises/12-loops-objects/01-loop-through-object.js +++ b/exercises/12-loops-objects/01-loop-through-object.js @@ -18,8 +18,19 @@ const generateLinks = (links) => { // WRITE YOUR ANSWER HERE + for (let oneLink in links) { + let title = links[oneLink]; + console.log('' + oneLink + ""); + } }; +const links = { + Dogs: "http://www.omfgdogs.com", + Kittens: "https://giphy.com/search/kitten", + "Hamster Dance": "https://hamster.dance/hamsterdance/", +}; + +generateLinks(links); // IGNORE THIS BELOW. It is for the tests. export default generateLinks; From 98728cfea5410307f060e9fcc52438d424cdeede Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 9 Nov 2022 16:02:20 -0500 Subject: [PATCH 057/105] Problem 12-02 attempt Hal --- exercises/12-loops-objects/02-loop-through-object.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/exercises/12-loops-objects/02-loop-through-object.html b/exercises/12-loops-objects/02-loop-through-object.html index 3f6ee6d..ae64ab4 100644 --- a/exercises/12-loops-objects/02-loop-through-object.html +++ b/exercises/12-loops-objects/02-loop-through-object.html @@ -60,14 +60,15 @@

    Now Playing

    * The code below should go inside the loop. * Change the code below so that it will work for the other movies too. */ - let movie = movies["halloween-ends"]; - const htmlString = `
  • + for (let movie in movies) { + const htmlString = `
  • ${movie.title}
    ${movie.description}
  • `; - list.insertAdjacentHTML("beforeend", htmlString); + list.insertAdjacentHTML("beforeend", htmlString); + } // Do not change anything below this line. })(); From 0e37e33c072b5e60cc53136e406ff8f36e9c37a4 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 9 Nov 2022 17:15:55 -0500 Subject: [PATCH 058/105] Problem 13-01 Hal --- exercises/13-more-conditionals/01-ternary-operator.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exercises/13-more-conditionals/01-ternary-operator.js b/exercises/13-more-conditionals/01-ternary-operator.js index b4765b3..73203bb 100644 --- a/exercises/13-more-conditionals/01-ternary-operator.js +++ b/exercises/13-more-conditionals/01-ternary-operator.js @@ -11,3 +11,8 @@ let num = 8; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE +let isEvenOrOdd; +let remainder = num % 2; +isEvenOrOdd = remainder === 0 ? "even" : "odd"; + +console.log(isEvenOrOdd); From 2f8edacede623b42ee64520c167e2f3362402c51 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 9 Nov 2022 17:41:34 -0500 Subject: [PATCH 059/105] Solutions for loops with objects and more conditionals exercises --- .../01-loop-through-object.solution.js | 30 ++++++++ .../02-loop-through-object.solution.html | 75 +++++++++++++++++++ .../01-ternary-operator.solution.js | 15 ++++ .../02-short-circuiting.solution.js | 15 ++++ 4 files changed, 135 insertions(+) create mode 100644 solutions/12-loops-objects/01-loop-through-object.solution.js create mode 100644 solutions/12-loops-objects/02-loop-through-object.solution.html create mode 100644 solutions/13-more-conditionals/01-ternary-operator.solution.js create mode 100644 solutions/13-more-conditionals/02-short-circuiting.solution.js diff --git a/solutions/12-loops-objects/01-loop-through-object.solution.js b/solutions/12-loops-objects/01-loop-through-object.solution.js new file mode 100644 index 0000000..4ee85fc --- /dev/null +++ b/solutions/12-loops-objects/01-loop-through-object.solution.js @@ -0,0 +1,30 @@ +/** + * Loop through all properties within the "links" object + * an return a list of HTML links. + * @param {object} links e.g. { Text: "https://url.com" } + * @returns {string} of tags + * + * @example + * + * const links = { + * Dogs: "http://www.omfgdogs.com", + * Kittens: "https://giphy.com/search/kitten", + * "Hamster Dance": "https://hamster.dance/hamsterdance/", + * }; + * + * generateLinks(links); + * // DogsKittensHamster Dance + */ + +const generateLinks = (links) => { + // WRITE YOUR ANSWER HERE + let html = ""; + for (let title in links) { + html += `${title}`; + } + return html; +}; + +// IGNORE THIS BELOW. It is for the tests. + +export default generateLinks; diff --git a/solutions/12-loops-objects/02-loop-through-object.solution.html b/solutions/12-loops-objects/02-loop-through-object.solution.html new file mode 100644 index 0000000..26942b0 --- /dev/null +++ b/solutions/12-loops-objects/02-loop-through-object.solution.html @@ -0,0 +1,75 @@ + + + + + + + + EXERCISE + + + +
    +

    Now Playing

    +
      +
      + + + diff --git a/solutions/13-more-conditionals/01-ternary-operator.solution.js b/solutions/13-more-conditionals/01-ternary-operator.solution.js new file mode 100644 index 0000000..ef6f7bc --- /dev/null +++ b/solutions/13-more-conditionals/01-ternary-operator.solution.js @@ -0,0 +1,15 @@ +let num = 8; // e.g. + +/** + * This is similar to an older problem. + * Solve this problem with the ternary operator this time. + * + * Create a variable called "isEvenOrOdd". (Do not use var.) + * If "num" is even, "isEvenOrOdd" should equal the string "even". + * Otherwise, "isEvenOrOdd" should equal the string "odd". + * Your answer should still work when "num" is a different value. + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const isEvenOrOdd = num % 2 === 0 ? "even" : "odd"; diff --git a/solutions/13-more-conditionals/02-short-circuiting.solution.js b/solutions/13-more-conditionals/02-short-circuiting.solution.js new file mode 100644 index 0000000..8650a0f --- /dev/null +++ b/solutions/13-more-conditionals/02-short-circuiting.solution.js @@ -0,0 +1,15 @@ +let error = "Username already exists."; // When the test runs, this could also be an empty string + +/** + * Use short circuiting to solve this problem. + * + * Create a variable called "errorMessage". + * If "error" has a message (in order words, its a string that isn't an empty string), + * then "errorMessage" should equal that message. + * If "error" is equal to an empty string or some other falsy value, + * then "errorMessage" should equal "An unexpected error occurred.". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +let errorMessage = error || "An unexpected error occurred."; From f315350aa867e7535729a933c91ede6e0c47a89b Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 12 Nov 2022 13:35:48 -0500 Subject: [PATCH 060/105] First project (hangman) --- README.md | 1 + projects/hangman/ProjectHangman.md | 161 +++++++++++++++++++++++++++++ projects/hangman/hangman.gif | Bin 0 -> 260731 bytes projects/hangman/word-bank.js | 1 + 4 files changed, 163 insertions(+) create mode 100644 projects/hangman/ProjectHangman.md create mode 100644 projects/hangman/hangman.gif create mode 100644 projects/hangman/word-bank.js diff --git a/README.md b/README.md index be04763..22bd7f7 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Whenever you are ready to submit your work, you will need to [commit your work, ## Resources +- Projects: [First Project: Hangman](projects/hangman/ProjectHangman.md) - Installation Guide: [Mac](docs/InstallationGuideMac.md) | [Windows](docs/InstallationGuideWindows.md) | [Linux](docs/InstallationGuideLinuxAndNVM.md) - JavaScript - [MDN](https://developer.mozilla.org/en-US/) (Unofficial JavaScript Manual) | [Tutorials](https://javascript.info/) - Command Line: [NPM Guide](https://nodesource.com/blog/an-absolute-beginners-guide-to-using-npm/) | [Unix Crash Course](https://www.vikingcodeschool.com/web-development-basics/a-command-line-crash-course) | [Unix Cheat Sheet](http://www.mathcs.emory.edu/~valerie/courses/fall10/155/resources/unix_cheatsheet.html) diff --git a/projects/hangman/ProjectHangman.md b/projects/hangman/ProjectHangman.md new file mode 100644 index 0000000..7f19136 --- /dev/null +++ b/projects/hangman/ProjectHangman.md @@ -0,0 +1,161 @@ +# First Project: Hangman + +**First Submission Due November 30, 2022 End Of Day** + +For your first project, you will be creating the classic game, Hangman, using Node.js. Hangman is a word game where the computer picks a word or phrase, and the player must guess what the word or phrase is, letter-by-letter. If she make too many guesses, the hangman is "hung" and she will lose. + +If you are not familiar with the game, you can [watch this video](https://www.youtube.com/watch?v=j-pBzBvJVKc) and [play the game here](https://hangmanwordgame.com). + +![Hangman example gameplay](hangman.gif) + +## Project Goals + +- To put together and make practical use of what was taught in class. +- To practice the operations in creating a project, like setting up an application, maintaining your own git repository and writing a _README.md_. +- To build a portfolio piece to show off to potential employers. + +This project will put together these topics that were covered in class: + +- Variables and constants +- Primitive data types (strings, numbers, booleans) +- Control flow and conditionals (if statements) +- Collections (arrays and objects) +- Functions + +## Getting Started + +You will need to [create a new public Github repository](https://help.github.com/en/articles/create-a-repo) for this project. Name your new repository "hangman". Once the new repository is set up, [clone the Github repository](https://help.github.com/en/articles/cloning-a-repository). Then type `cd hangman` in either your terminal or Git Bash. + +Inside this folder, create a new file called _package.json_. Inside the file, copy and paste the following. Replace where is says `` with your name and `` with your Github username. + +```json +{ + "name": "hangman", + "version": "1.0.0", + "engine": { + "node": "16.17.1" + }, + "type": "module", + "main": "index.js", + "author": "", + "repository": { + "type": "git", + "url": "git+https://github.com//hangman.git" + } +} +``` + +For this project, you will need to be able to read command line input. We suggest that you use the _[readline-sync](https://www.npmjs.com/package/readline-sync)_ library, which you can install by running this in your terminal: + +```shell +npm install --save readline-sync +``` + +However, you are welcome to use Node's built in _[readline](https://nodejs.org/docs/latest-v16.x/api/readline.html)_ module or [any other library](https://www.npmjs.com/search?q=prompt) of your choice. + +Inside the _JSFunFall2021_ repository, we have created a word bank file for you. This is the list of all the possible words that the computer can pick at random. Copy the _projects/hangman/word-bank.js_ file and paste it into your new repository. + +Create a new file called _index.js_. This is the main file for your first project. You will be writing your code in this file. The first two lines should look like this: + +```javascript +import prompt from "readline-sync"; +import wordBank from "./word-bank.js"; +``` + +The first line will include the _readline-sync_ library. The second will import all the words from our word bank into an array. + +Create a file called _.gitignore_ inside of the root of your project. It contains all the folder and files that you do not want to publish to git. You should ignore the _node_modules_ folder like this: + +``` +node_modules/ +``` + +You should also create a _README.md_ file, which you should write in [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). It should explain what the project is and how to play the game. You can find [a sample README here](https://www.makeareadme.com/). + +## Playing the Game + +In Visual Studio Code, open your terminal. To start the game, run `node .` To end the game, press `ctrl + c`. + +You will display messages to the user with `console.log`. For example: + +```javascript +console.log("\nWelcome to Hangman!\nPress ctrl+c to stop\n"); +``` + +The new line character (`\n`) is like pressing "enter" in text editors like Microsoft Word or Visual Studio Code. Use this to make your text output easier to read. + +The player will guess a letter over the command line. She will type a single letter and hit `enter`. To get input from the player with the _readline-sync_ library, you will do something like this: + +```javascript +const letter = prompt.question("Please guess a letter: "); +``` + +[You can read the full _readline-sync_ documentation here](https://www.npmjs.com/package/readline-sync). + +## Project Requirements + +### Application Requirements + +- Your application must start over the command line with `node .` +- Your application should not crash at any point. + +If your instructors cannot grade your project because we cannot start or run your application, **it will be an automatic failure.** + +### UI Requirements + +- Use words from a word bank (_word-bank.js_). For each round, a word must be chosen at random. +- When the game starts, let users know that they can stop the game by pressing `ctrl + c`. +- Throughout the game, the user should know: + - What letters they have guessed correctly + - Where, in the word, the correct letters are + - Where, in the word, contains a letter that hasn't been guessed yet + - How many guesses are left +- Your game must be case insensitive. This means that when the player guesses a letter, the computer will treat lower case and upper case versions of a letter as the same character. +- The game will stop when either a.) the player has guessed all the letters of b.) the play has made six incorrect guesses +- When the game finishes, let the play know if they have won and display the answer (the word the computer picked). +- Please make sure your game text is easily readable. Use the new line characters (`\n`) where needed. + +### Coding Requirements + +- You must have at least three arrow functions (but we recommend using arrow functions for all functions). +- You must use _let_ or _const_ instead of _var_. + +### Code Quality + +While you will not fail if you do not meet these quality requirements, we will ask you to resubmit your work if it is not up to a professional standard. One of the goals of this project is to help you build a portfolio. Just like an interviewer will judge you on your attire, employers will judge you on the neatness of your code. + +- You should have _README.md_ written in Markdown. It should explain the purpose of the project, describe how to play the game, give instructions on how to install and start your project and credit yourself as the author. Here are some resources on creating _README.md_ files: + - [Make a README](https://www.makeareadme.com/) + - [Markdown cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) +- Add anything that should not be committed to your _.gitigore_ file. Your _node_modules_ folder should be ignored. +- Choose descriptive and specific names for variables, constants, functions and anything else that is named. +- You must not leave any debugging statements in your code. This means when you commit your code, remove any `console.log` statements that are not intended for the user to see. +- Only have actual comments within comment tags. Do not commit code that you commented out for debugging purposes. +- Remove any code that is not being used. (This affects application load time as well as code quality.) +- Use proper indentation. (Prettier can take care of this.) + +### Hints + +- If you need to cheat so that you can develop and test a winning round, temporarily make your word bank a single word you know. For example, you can do this (but be sure to undo when you commit your code): + +```javascript +import prompt from "readline-sync"; +// import wordBank from "./word-bank.js"; +const wordBank = ["win"]; +``` + +- I completed this project with a _while_ loop. +- You can pick a random word with _Math.random_. +- You can use _console.clear()_ to clear all the text on the screen. + +## Project Help + +If you need help, please schedule a 1-on-1 with your instructors or any of the CanCode Communities staff who is available to help. + +## Project Submission + +Please email a link to your Github repository to both Matina (matina@albanycancode.org) and Jamal (jamal@albanycancode.org). If you have not completed your project, please turn in what you have. **Not turning anything in is the worst thing you can do.** + +## Project Resubmission + +You may resubmit this project again for a better grade. In order to resubmit, you must have made a valid attempt. (That is, and you must have followed all the steps in the _Getting Started_ documentation, your app must run, and you have started some of the requirements). You have until the last day of class to resubmit your project. diff --git a/projects/hangman/hangman.gif b/projects/hangman/hangman.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cade8131d5ed1ffd02944e1757a58b7e034d234 GIT binary patch literal 260731 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%0AD~J`QJiwF(nDRg= zNnvGIeY<+A+ZS9am#O4Yt7n6UZU3(-S@54s z&dn|;w1pLwmX%j*b|efVLW^5(Sa|+=AKXsxu4H~c_Gh3q5ASDqLD|+mICgXE@k0ri zsFaH&>0WV3`P7%FnmK0(i( zqB@jWImJD23%a<9OUY@veBxi)ec(*0|N0UZ1_|D@goQzZF-Y+0(0FASg+YQL*kCj( z9D@X}3$SC5;Kh&sfg`Y8<%29P1CpgV3<~~_b-h?hJOsh9D zJGXWpmwyx3#2~@H`N1$qFa`aZMbe!jjoYuVWUBtg#1GZl*r+83D9|(Ah6) z^K&ge4Y;13Fk6taM}r~=XtSZxd@wwCX1M7TmM)aRSjrP(x9`+AT@!#_nP%~Z#@~8} ztSZ`fujM|C0|+aU^1aY66CV4!w+O)uqfVqF}it*hn9({0DE{kQ~tWdLUDN ziTM&7z18;L>4U71peJE39|c@S9ykh9(QA9ArHY4^Sa9il-V%l;L4UKHZ$=w{CGg8p98D~~xGaAsc8RvdOHltV$SyC=yTTxw;jH>OVbGgT0gwja{xhRblvE^JVQ!_mMf598)D(!kc~Gs}3;JLD6SQ zt%^R=su{F$_f}#%A9H~@puv7Z)!*pOR`)5kvM}))ejxze!j?(QS`8^}+lx?o(s)|#E z4Y!r{QD zr+Qf_-RgtL4&sU*CUxHt$HQagnLfgtv4em!ZrcA1zV2bN!-Urh6(4$(V9|m-y`o0D zPhp8vR(c_UMr`a<9%N~F))Qye+5riqd-YpdJ-CbH*b?JWio^8aF-2jB(fm#}iDMwa zD$;Z9k`g;erl#iTff))8dW7%9^<{EMk-iT-0&0Xn;;4iiX99K-OkKocehRtoFLfIR zfF4jBMnXB4ObifGP1NLA_fSm(*isR&dng>87?d9tvQ|-qgfSiI(^iy884WhzXo^P5 z@8+wKhws1@^W``S#lH2+SlCSDb`@m!K_ zNvgq&C_IyHIJS%KtL!JI<(smT)aL1OFItRq=0({xCuirfim9IDA_dZyl~UFMvOp(xq0AQ~97%-?qBVrlW}asYeG+ z_0YS+rgdZ41Jx?2Ep%rmrdt{OxZkz0#M->O#gS9^uARGP;#~)SEBE`` zf)8!p-w_!teBUWPH}Sqp0*B|rT^TCd58VpvMIU-pgeO1TL&)>Y+}F~zo$1v(Q8e?w z@a*KwLt{Ul**^1F+u450oTAwQo0`elNA|5ebB`S#+RiIvI|~1_bgLysvU*o zODB}^VP}FE1u&P342A4?Ct?#mchlwNJ!&lE**N8cr$;9D8bMVJxR)X>p>4?+O58D1E&9Py@K5s)adES*>=Y z9G?u{6v01{1qXMJoGp?Xgh!M&Iq<0PWG5&c?7Ozh*HL=s#JrNk2#5%xVu`$;YAoi+ zc=1N_i{0|23~B(=^@ngz&lmy!ELe{eih2Y#)n-gu-;;VPT$+Qc8&{T_6d$i%1}1}R ziWg5x>LoF}Yd22X7djM7jYEl)AAy5V!;N;WC!wWGEV`lPX zx*dRTG!hXFYFuvTdo6i;=Q&GMDa?dh*~-{pyp6J%Tm$!h!@gpxEx${G+| z1JQ=vW2PCqt*z}TO5yT?@O&J_tUE3+!g&{K-XU^k7)Mm9AL(Aq1bn=IFZn$LjJ`l+tn~}BG#6i@keLS}Mq&Am%RiTW;J^hE3sIu|rs;3>F?SG?n zv7mjX*yT=vQQcI?Wzs4@bLREr8NG`v@L3%xm!`o|s>t2R1tFseO}Y6wimY0*@qIh) za2Mry-f`P|ZjA2UK3&TLp=u{HK77c96#4b+93f_}R?>Yx&yMP+buN;%FQBm5-S>3y z$9mel0&w8!f@+gzV!96~WdJ&PhDu_=0oZT(h--T36fQ_+nO?uZ*ytUpXM`UvGMik1 zYw^vyEACDu64w78d*2xrRl01wyXhu0smW0!XOW#BN21V4<3 zQ>HQl?#f>pc8D(#-_RaTGcVg_MAS@5mnnP5m<{kIVn4NjcQSIVDD%)8C6)X3{#@m_ zM>|MhI_(DoRyQB zY}Zzl>B?lI6JNI2L|#hQoGACW{1z`$T1vqra7oTdZ0bt;Y)6g)!vo9@W}zueNbZb^ zB>y@jR5(ia`C3cjqTvIptsAbv3Qv}|K@>2kdo8pf;ZbOg?G>C36ErNBtl-NoOhD9x_;{A z6P|9pO>czD$-4>4rPiepfTmL8g8TC8i>uApryd-#AbjfpYL6^>YkuTb;5lV)PO2Db z%S%Qxt~M!LoiAi&It7w1ZV^ggpSje1=D-wz3FK+u`yD;)M-Sfa>S<4_ysLfk;g!q& zbMKvPk1uE|+;W%m5>D*V-&%eDdJ`iJc%lpCp zxhL<|YmWv#7iONJM!JXTI9jiX?AUKE2g!C}Vrjs2hk2)%^;&OA-`1x(UdSqaC?Zh4 zNSdi8zW+MI$BMJuZmpxjYm)D-gmI9V&Ecvu$%s9VxV-+G71(c3iYaekZ#>r!}f z^%7BOQi6U7)rXfWYp2LhtRg~ha>NK#_+y=jXD}vyxAy3K(jg$lQ8CTi(uY;Ewn@!h zThZeMK|`fd&}pl!Drpl!f0JNmh3m3fsoJ)Ba!QWm%mW@uxA;g7?dZBa@cauqFcZANu0C0mWQOn@|GBx#6RkT!Z z0BED?{Xy?a4`3rgUlHMbCz?TM=G48nXHQf5(jXY;i*ZydGo41lXRl>Co!vxIPLj@z?Rq&>?SNcOm1rI4Ksl zBo|yG7D`UCby3SVs#$E{MbL$8&Z?@Qxn)i!6W8ZbT;*9hwT&*-Z1uAa7eKb6Fkm@_8e?5v|AZxoL~s-6#$vx`x=850u~qbd(E%y*KlkI|crIS_Fo z#_F-Kv2{#LW~}*otOgaSK2@Cc;~3}mSVyW@(>P%}J&1*ToMu3r417=1Lkv&=i2&L5 z3jHU|z)vgmJzPQEXHhoESgWs615?@8z}P-bpH!gLlIazSB@c3hIqg}YpQ-%3Lhtrd zkFda?;Qum@uztR_w%(@bPl|h=aAb+U(4N{-%Kv~PH&@sfK4K+8d~W(VQ3`3?SO7T? z28;vWz132^CP&*J&8J5|(h)h1zrf^vzv<8TA9r3`lL9w*eW!`GyT1BGm_Va9>ckfi z8`Y~~0VF^w5V_<1VC1|h(5gzE9Jxyqp`?sC}bLGm$JerD<= z_M~|z$=BSBJM|5X{|YhikBCS=13Z3pp|(=Rf6&@fyK5C_Gf6%mSz2QAw1Aax4_N)J zUh!U024kaD=to7}fPqH;ZOPY9fX5Gbq|{{-8GbH>K122W40h90=?5IenbWhIJ&IUz zR_l-0ZN81jw=Y1zPX~5j08|BQbdjPX#>_Z@%lZWBwNbdZ#eNaCE|10?D-(?6Bu};j zVp9zV;@^tOLvG^pwEd}G@t7A}mVMlNN3R%M?dNTi;WX3xjb8Cr@2AlwlY=+O7~9|{ zUb12m*S}03Cmy%X1c28J4orti-{(PWWn`mMNEBWzG4lh57CX+%7R7l(4^xk~9~!Q* zpR|!eF2RT*@!p(F0M@htpr~2HhZ8IKh%~m6V|#D{-;Q4KcCTvQg_ueAXDyh?2o{{1 z$qbj}oXv{XwwcY2w%}w*=oXgAVBQej<%PE*ED5{>DD=cl{oG+>zw3#oq zT+JIuberX1D`8Fks-)he^OC)exg zzkIGxV-+scL7Dr8ar+A;$DZ}n)zon82WXcSA$0~m3@_js7IqJFg1 z&X1nwMd0Mz5k7(X(e$$3X4Zcw-2EGf0_%VUKm-5~Uic?t&aPVoM(lrf=rOt*j9+Jn-@HWm-Iu8SzxyQuLb$(p ziJZ69{IkEjL{#y!CvxE4yOBfpzczAUzlt1&FOjozbG}3l9PxkU&_Q1g9p}5q`Qgy_ zL=Nw6=bS&xx#*mO&N*MJ zHFVDTY|@0zIjA~c9G!EPmUl}2osCX(pYwg6vj?R>38$hmExY(YIc@ zef3p6=JEa;Q3^}}yyXLiYwGeSltP>IFOia(SnW=8X zJ4M(wXOQTW@zeWNdkLkVFuIpg#bRT1CUezfPiy&dTsk5xSVnif|Nb1M7@lwM%RBMC zEz`4C`&NRMc+OSle)al6<4h>QgI%1d?6+{HHTjGgx`!xpK-tcW?GqFxMt-K1eRYLv zc|Pn_LPK-GM7>MVG*IZ4S=ra|8C@<*|UETIq1O#da&_zdq@Dy zo^5UWYrbLVoP*9ed#sCo+}J>aOlXh^4KksbOxKcY7h034_+NHX zL^GLwoQY~KTfB(N_Wn^1KXpv%lg97;Q5!eL7 z_Sjw7?FaBb(hDXb%23MJ_*?5VhZoaZ-D#mV5RL+-CU>}$iUNCmWCMbdg#@5XqxVqq zXEX7wg&QO9MP$+e#$&ve3hLy(A0M`r0RU(n;?hagXMGoRP|66N2F%HY>BoJJ=abC1Ng|*_D*WkXQxdVZwe84^ z8%TXIhE&O0^kj)8;{27^aBn8!PfS1u13SuJKFBzk>uf8sEdk504uOJ!|1U*an75t9 zNKjE6v#r)H9=S)Y9Tl${r^EHH4;49guv~#fl(=lOZ*-8lA?Kp7hy6_4^KZRgdtVLY zomxRTi^)0>Uvc&d2t4QGcQq(H;$(<>WNe&9w10e3GJ?Vvzzj>t&bgM8|7}lc>yA=u zzf*Vjj%NMWuTNw`f!N#uuzep4=y|oe&(+nasTfln!{!+9%nE}Z5XW?CB13|@ zPa2QeZmyf8StJ|*#3A^syjvz-s>dkDp^WesL7q20+z2|hpK*x6aH`7R;0ned))Qz( z6?B{zFpClQekL8G~x=^Wjr#;Bjc<#d4 zvaVs*IjNI$E9Cn(@SV3Lv}nsYN_b`nfQFlx`0%)x`Vw3Kw0S{y;NY8r%hobe)DQz~ z+rc*yjnI2ooCkfqYdh}t(NE9#Tj(uV-MGcRXaJPDx}6CHTZtC8*ZJSZyRUkBB%TM? zZp1$GPBgcGm?rZgdzYLZGXMeM$=Y;(b{4y$c|yT-#p9&1+_5Orie}%0C@0;qxQ7F7 zt>P~4i58tIe4Lt{4lxoe(|5z4J2?x4^*s(sIt9Kr_{46RZ)HU9)t!tdE^N!T`(j`5 zuhr&!+$Vg9^bu=><${Fm%H_z{kA)8k5=I?46n*g3`e$dcxN{q`dATJUb452^ZOoUp z@@y_tK03Fx`Lbp@?h{aSY{D4#LW`Xt5d+gOklai3Fl>B-!8O4?FH>jK1ivj5skq?~}$o9=@xCu*u^ zGdzwv_+QpUWUjx@;d$4q|$Aur?__pMYgg!Rzd7IcMOB-O&M8+;a;a` zmkj#I5SgQnM1UemCVefA2E2v{%Ri#tiHQD+IOmC|ChyE69xTVLG?Fgz=dnp2#!+Dw*5X_w z;@r>&w&Hg=8TQ%dlUnO32JZJ7#AP9mZ%Tku=HN9mPz%N}&tid9({*|A`--@;gN!x; zIs`wgT*s&MJ_Rv;0xjY=NUad1Xv81iNbC&q9+>BRvl3PPQTCp!C^I$tiG=-vt)y?q zXN0hbtt6ZzdV;Am)7y+6OB@ws3>Z~N-k09^Xbs8t)cS$2*KD4goI+n@;zPE^wPtYA zg+5$2Q07+Wnc3qX*Q%L~OZe+%e4A3JYE>5{JuYNxeWzYXr=DhxT}Ywfw8Ep> z;ZM$D@9saU+gQDh#4j?&QXFce7Nn6cBMa3nh{{`u+84^va<}HfV4PYk<>~ckiG+y# z!Qeh_D|>B~+W6K!4JP#_;c$CtuKK!85I1(cwb6ach7U5;1WQs~AIiZ8Hf>uDzIV8G zZWS?7-YYL$m>zW|shxB>-0Q5iBRPbio)-VTulMu@{W(`JDI>#h5o$MF*rWWDOMz;l zO$=MAI?tasu2xPT!=pZk$49A1Z8IYQHF;I5nJHAY0+)cDh67h!JOCO8f6DvxG2v@P zM8)`&n1Z(W9yRrSiLw%I3F;Eq(K4bSDX9}Uwzd`|vZBfP%4X7$vGo%?AKvpTz+R~Z zrFv!&oXrompPb!#wZcr8HXAjSV1Gr{HCVdDA=i-1jNSTBu@qQAE#=r$dch<@Su){# zr-ki6%+Q8;iSq#4sVPNWu!{f&!3|UM zo1CWKpRMej(MBxy6x_XREXCjY}n%7o-u94n^DVBaq-^dsG{|S+Z$XezHrM z;zDcHk&Ls|sfV&o)$k}ixg>*pkk|FveRJ~}upj3-xA3Ff0i0nvgGxNP@UvQG1Ed=uFXE~8Zr0Y&mdH5`{Ev~Jck!T%_n@xv zpdIp{Tl1i&^kfwFWY+a$b@616_vEbcyF(OOprIVn)l!%uP%oxh#9X8ohwRt-WoG-`8HfxgtxBM71bec#XO%| z;Xb(bJ|=5E1QI?EANg1bUpZ0Zqvh`{<>Gt$i+L5wQV9ChY-Q||*$UzZ8Pj+s1UGe< z0F83Mr)HDdEE3MXprrUx0gFX^jg-q{F$!DNZ7+@3C7YCrTi!l;NeiSx-SB zhiUt4hNSWH@pwhI)YQcrO<9CONJSBji@r!qFT~p(*9kCnR5vn^R-rO)r~m1~a^N@+ z2eB9V(fa(e2&RyIR^&KX=3<`mtVxgR(nUW`%igBy3EBCltnm^J@=u_2rrV z!c*OKcQ)Tm;8Ko_b^z};*Oup>b#LAFX{HdCdxnINTa9^Ov*wMBc;X4p?DZO=w8$Ix zrFEY9!D`5Dta&1cw=c~w_|Tx$^AO<|dCx;d-_AS_6UXG3442lP${>&-!kuwO6P z<;6F)xZdP8-&zg9a*>fgvl@!E2{1J^f7~7H9&PP;HdKw;+R#SHHMZywgaZ84T4a0M zCHRxO&}X+c;OFi_VQpC#c3fH5I~a;Tb!-2kfWt}5G!DVc<3u^!bot`=Mc2)tr4?U* zL?N6z^@qR>P0bbAEx%msVm>%AB~boiHvjJ2jup*Qf|(_hE6a{V^Y;xu+@tIg-XHnG zNB^o_+ws;a2&L`Kd_~V_-f%9zKUXbtkD2&zyA|Pet8n{$if=Jv%J+I}?VGSGd3wv` zB0u*fRZP#9z&Vw z82_o6%s*$Q!$h293QGN_RwCvM(&zVnr*czR-m5@yzFtlW)aASg@NVN$C{FVksNk8P z8(YSd#HatW=0R!u%CAAIJ`>q9VR!#A3pkORQ(+#Be(=55)XFOsH%x~NVMiG$@&;^DL@&*x;s)FfY_Kh!JcAH|UU0@hr##1t?T=bXFe2Gxd*!WgjLQ+{D4)aeKTlh$Ni_E8=M{J zh9W0lk*uKD98^+Pz6;$5Vce=aM1<;z%Ydd|YVxoi9D6QMIys$>H?vLNe*F}4agV#! zp0tHc5(pPpO8TxR{>0Vz+OLKD0d(VefxU9(h=c48T#Y3ErJhSUq=VOuE!A)otBW32 z?1gSl4jXSnH_LNRzlCmi$moBtMK@6QJHH@%J<*RInins<+gzjS`#mT09|PC&74cCg z1l@Z=IH(f>Z=X>1uTO}1_k`|zI-w^7FBZT0pM7&eoYLZFQ~ug6fkulyEVb7ma&;-WUyzZZB%!u*>P^5YFwL>bp7HN5)%gto1_X)C#(w}yWUt_e^< zH|Siv$JYIIuHq_q?*UKH?FAZI%W98eKY@nUx_f&2`XBzy8t3nHaA;`l{}0&pZ`Qxx z;@W6v?bqG?-+aO7-1py^`~Kq%#@~k4P*$SbxONf{2|`i!(@-o5Jz|T3#F@D|J6ehh zw$EHjUc0^Cs{gh#`GK5NHWn8c=W{pP&v5K4E%gF%_8aaGmb7{WeAcPXGC%*D({J1XNBFzWKb{NE} zwfLyR=0;R^$7uK6yH|T(`s`NL=+ur*?R$pS{Qn4ch{8P}02sAMkh8r=P#?65Z?N;R zQ()dRmj6smVR45=WM!%Wjyqm4JPMsJYuxHcmD*IY_Jz4gFDsmP^zwFqLSQf)dB1=l z#6>%gNS~Nk0}v)yG2xn`XKHj@W|ln6921rUrGpm8r$uE~RLbT8WC}NKBFaiLsv3OA zuTubca!pdLcQxx8d%S>t03!czAPPXro$v1*lY|dFlYKrZ4-RmeAK%My*w}pk;oI)n zu`{I zikgQAAWkynfjvALR)GtLv6IE5^@c+*VOji_X8stG8Z`Ks^gq893Dege2qV%JN?QQO9qt}CTKd34|rS)|X7cH1HEG6$Lz|WRiX3{oK~u*5shXYT3!g?+f3~LTTWEO>VuoK2$^TO&E6L08k&1)?U^By>u1DMFz6 zfa%FJae!jO3FP1C!v^tVWz>~6VbQo}?4w&GOdSzpD>M?Sh0jNDG6Sb9D5A^IxZwmr zr*p$)P2#c+`DgpyWT~q=Gs(wsf1Dvsgg0qI)m9kn$%yLA7$IPMK&wGLje`jy;7nbW z7zeN$OHkopk4a!)_xKypf$7I``S3*5I+MIP>n%ftG>G$nluFBoo{k`F4zTV`oTv~A zH5LL#a?YDtM+ka^yBN)D26OlXURs?=keL(_cgs{3Kx#?^`i307-Pg82)HrO;T6|Y* z$s=6S@XXo5yNnfuG*99^yRKSQGEJq)CU9-B6i$P&6EJ4(w?&C87hFDlTYHF$sWy># z9Juw86I5_anb{8aD$}?ZE!`N)!s0!+9QT_h3=S}Fb8n?DtYtY~s1XXgfTzms=Z~j) zPKD9>!lAy_lv2SSsnWePZdH`YK2%O-*|cP zU{ZF+SoHFY^zqc2udj^E4je2ms|Ra)AHm}WLoA)^Ur~7&HFcz63bi#5Tw3&^$4keS zLo^a6E_$;orNeaEB*UYbZ77hEiu{d{tzD*i#jqfZ{hq{293Zfmhazu$Z=NWg8l#*N ziOE@nf1!AqWOukC-ynbNoXHHgzZ#hAFch1?nI(w+UXa4vg=1CTEV33FipJ6Gl=t1< zkOdrRHi0k3tEO#bSYGAq`N*?K+g+1$xCZ>}TwukKruRgOk>M}~A&Eq}$rd7cfPlWx zEYWlX)3bxY&jIFiZANLDXrMRaj9?T~&qyN)2IGBCNmjB|B7aR;moT_yblXOFtELxB z93(ltUl4{Me!kvqOrROB1NN5ybOG(^dmxqQh@+6UAm0a*jI`}}cn%a%7tosB^G5o``nKPcx<};G1(aev=ghk5I!@tt`$NMM@P%3nX470Kg~2 zvDyk`G;<{Zofb)QL2{3K!5SENS_1o=TYZq1QhpSxekp-GWYxpvriKEo5te5v7HXeThvW%H7pmAtWfu{>TYz1c3e z%x>U8I>WV-XEY#>9v$nI*YQezY{+`6|9+9PAc>sy$z1vZUUf(DTku!@&Sjk&Z*SD& zm&_2?;|}u1S|wE^CLt&^+laWFs@W$ebnhqEJq~f`!Z!qKT)SD7jDNjdX>_1vaHQKl z@S}Wub;PvRlad5ohyhVjS$|vc|6K?(aIDRcbBX1qe!!SW07Hnzedt*-|)h z=NRVEwFY=-DUyPF9A>cANEy2b=kFXRxV(0+{}$jcr!+y#7T?IKQWmHaEKYuFt$DvJ zU$CW;Dc1R#7U2i>9_B^Q={AQvj}w%K`zcK_(yX^3RLUdcIwx6=uD7d&E(LEYPH`Hn z-`9Om9($v6is$lrhuj(P$EJH739b8__Q7q(YNk6&3!#b0#LqqzhapS zOKyukoXZzeJ6@-2PW#rzKxt@Ik)`sy{*#Ttng>-SB)&*QGBfPPNd*1}5B%b^ zb;ec|Fq~z`fQS29ip-HfBG3o;VG@BMePQ@T`Y19*#W!46)taw8FK@Y%RCeH`_jBr2 z{3tF~kAqgyhscBMZ4cA2@{Jw|Hsw@Szck0!qcSmRzlNPC-6E}e5$f~h zZSiYwD%@T4RBaFDPi>XFOTHAUgeBn*6KkdR&B<56cWF!H)o2z`WyT>pLL0$K+-uV0 zx;2x^mOLe@P}pNIm2u<3_`GZM#kdw`B)@Wd#-+MQH&J>BPs2W?(K{BS0sTEeB&8X| z`;J~4HiTB5P#6_?S(PG4W^LvM^Gy&Twd%ab9w%1!<`CI~iIbOR#a9z^)2`lr98}6_ z8Oy1CH;epm=^S;1S)xH9TS1vW3wLqL$JKs2awZGaHC3({*`!m23f_d5ZwS7_zauwa zeZQHcwLsrUaYhFiCA(g)fAxB7m5<3f)K!xLboX6`Tmyli9`;Nhu<@j7<55_6*Jw#a z`>EtsaaQX`A#bZHgY+D2riX)nh>LhlOx>4WcS8w(znyM2jN8o_C3^ zhC7^0Ve%}#XVfxw_)(Pz@;S~j+0ka>Q~qQgh8VO8a5#nOO{s1;WZ3h{~ zJ~o6MI*thGb1@wj4wZ$6V!=b6)r3w_hD_##Jk zLlnZm4`2Y+02zwl`yACP6(-Nk{gSr&UkDle+&O)R24Dq6Z4K|`q1y#{?hXcb)=V&f zTp(koh4I>LVdM|-{zSXrD-hC->9)O2GK%fq{d#i?wF~X#?c?j`9}pN6{O9W=2=H}` z>y?_=RauaewGq%WfF?{8M~a|cu2HH^25y0eMW+YtFlf@GQX~Y16!)ohtCn3HZdZa) zpx815+P!MPL#sDttrt~JKMs8xglJM)`Q0AB$krJBCY>oTzB}YBLly$*6&H6qfyDuOe5l(=hDQAEF^K}w(>&XZNYyM
      Limited Time: Members Save 30%
      " + + createLink(clickableText) + + "
      " + ); +}; + +// Update me too +createCallToAction("Book Now"); + +// IGNORE THIS BELOW. It is for the tests. + +export { createCallToAction }; diff --git a/exercises/15-callbacks/05-send-email.js b/exercises/15-callbacks/05-send-email.js new file mode 100644 index 0000000..da5e051 --- /dev/null +++ b/exercises/15-callbacks/05-send-email.js @@ -0,0 +1,23 @@ +// E.g. +const askForUpdate = () => { + return "Hi John. Is there any update on this?"; +}; + +/** + * Create a function called "sendEmail". + * It should accept a callback as a parameter. + * The callback should return the contents of an email as a string + * "sendEmail" should use console.log to print the callback to the screen. + * + * sendEmail + * @param {function} callback the callback function + * uses console.log to print the callback to the screen + * + * the callback function + * @returns {string} the text in an email + * + * @example + * sendEmail(askForUpdate); // Hi. John. Is there any update on this? + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/15-callbacks/callback-test-helper.js b/test/15-callbacks/callback-test-helper.js new file mode 100644 index 0000000..cd59627 --- /dev/null +++ b/test/15-callbacks/callback-test-helper.js @@ -0,0 +1,20 @@ +import { getAnswer } from "../getAnswer.js"; + +import { calculate } from "../../exercises/15-callbacks/01-calculate.js"; + +import printerFn from "../../exercises/15-callbacks/02-print-names.js"; + +import { findFirst } from "../../exercises/15-callbacks/03-find-first.js"; + +import { createCallToAction } from "../../exercises/15-callbacks/04-link-or-button.js"; + +const sendEmailStr = getAnswer("../exercises/15-callbacks/05-send-email.js"); + +export const sendEmail = eval(`(fn) => { + ${sendEmailStr} + try { + return sendEmail(fn); + } catch (err) {} +}`); + +export { calculate, findFirst, printerFn, createCallToAction }; diff --git a/test/15-callbacks/callbacks.spec.js b/test/15-callbacks/callbacks.spec.js index 2d10b72..5ba875a 100644 --- a/test/15-callbacks/callbacks.spec.js +++ b/test/15-callbacks/callbacks.spec.js @@ -1,10 +1,15 @@ import { expect } from "chai"; import sinon from "sinon"; +import { readConsole } from "../getAnswer.js"; -import { calculate } from "../../exercises/15-callbacks/01-calculate.js"; -import { findFirst } from "../../exercises/15-callbacks/03-find-first.js"; +import { + calculate, + findFirst, + printerFn, + createCallToAction, + sendEmail, +} from "./callback-test-helper.js"; -import printerFn from "../../exercises/15-callbacks/02-print-names.js"; const { printer, printNames } = printerFn; describe("10. Callbacks", () => { @@ -49,4 +54,33 @@ describe("10. Callbacks", () => { expect(result).to.equal(3); }); }); + describe("04-link-or-button", () => { + it('"createCallToAction" should be able to use "createLink", "createButton", and any other function that returns a string as a callback function', () => { + const createLabel = (text) => { + return ``; + }; + const html = createCallToAction("Sign me up", createLabel).replace( + "\n", + "" + ); + expect(html).to.equal( + '
      Limited Time: Members Save 30%
      ' + ); + }); + }); + describe("05-send-email.js", () => { + it('"sendEmail" should accept a callback as a parameter and log the result from invoking a callback to the screen.', () => { + const scheduleMeeting = () => { + return "Do you have time on Monday at 1pm to discuss this?"; + }; + + const output = readConsole(sendEmail.bind(null, scheduleMeeting)).replace( + "\n", + "" + ); + expect(output).to.equal( + "Do you have time on Monday at 1pm to discuss this?" + ); + }); + }); }); From acf1286dfc28f21743cd07c982629b769ec8bca6 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 5 Nov 2022 17:32:25 -0400 Subject: [PATCH 066/105] For each exercises --- .vscode/launch.json | 13 +++++++ exercises/16-for-each/01-lowest-num.js | 11 ++++++ exercises/16-for-each/02-generate-links.js | 26 ++++++++++++++ test/16-for-each/for-each-test-helper.js | 22 ++++++++++++ test/16-for-each/for-each.spec.js | 41 ++++++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100644 exercises/16-for-each/01-lowest-num.js create mode 100644 exercises/16-for-each/02-generate-links.js create mode 100644 test/16-for-each/for-each-test-helper.js create mode 100644 test/16-for-each/for-each.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index f728546..22494b0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -199,5 +199,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "16. For Each", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/16-for-each/for-each.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/16-for-each/01-lowest-num.js b/exercises/16-for-each/01-lowest-num.js new file mode 100644 index 0000000..331353f --- /dev/null +++ b/exercises/16-for-each/01-lowest-num.js @@ -0,0 +1,11 @@ +let lowestNumber = Infinity; // This is the highest possible number in JavaScript +const numbers = [1, 10, -2, 3, 4]; // e.g. + +/** + * Using ".forEach", loop through the array "numbers" + * and set "lowestNumber" equal to the lowest number in the array. + * + * Your answer should still work if there are different numbers inside the array "numbers". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/exercises/16-for-each/02-generate-links.js b/exercises/16-for-each/02-generate-links.js new file mode 100644 index 0000000..9f38103 --- /dev/null +++ b/exercises/16-for-each/02-generate-links.js @@ -0,0 +1,26 @@ +let htmlStr = ""; +const links = [ + // e.g. + "http://speakingjs.com/es5/ch04.html", + "https://www.ecma-international.org/", + "https://books.google.com/books?id=2weL0iAfrEMC", +]; + +/** + * You can imagine you are creating a list of reference links at the bottom of a Wikipedia page. + * + * Using ".forEach", loop through an array of URLs, + * create a tag string for each link, + * and append the tag string to the variable "htmlStr" + * + * @example + * // After you solve this problem, "htmlStr" should equal: + * 1. http://speakingjs.com/es5/ch04.html2. https://www.ecma-international.org/3. https://books.google.com/books?id=2weL0iAfrEMC + * + * HINT: You will need to use the index in the array to solve this problem. + * + * Your answer should still work if there are different URLs inside of the "links" array. + * + */ + +// WRITE YOUR ANSWER BELOW THIS LINE diff --git a/test/16-for-each/for-each-test-helper.js b/test/16-for-each/for-each-test-helper.js new file mode 100644 index 0000000..2a097d6 --- /dev/null +++ b/test/16-for-each/for-each-test-helper.js @@ -0,0 +1,22 @@ +import { getAnswer } from "../getAnswer.js"; + +const findLowestNumberStr = getAnswer( + "../exercises/16-for-each/01-lowest-num.js" +); +const generateLinksStr = getAnswer( + "../exercises/16-for-each/02-generate-links.js" +); + +const findLowestNumber = eval(`(numbers) => { + let lowestNumber = Infinity; + ${findLowestNumberStr} + return lowestNumber; +}`); + +const generateLinks = eval(`(links) => { + let htmlStr = ""; + ${generateLinksStr} + return htmlStr; +}`); + +export { findLowestNumber, generateLinks }; diff --git a/test/16-for-each/for-each.spec.js b/test/16-for-each/for-each.spec.js new file mode 100644 index 0000000..9c03436 --- /dev/null +++ b/test/16-for-each/for-each.spec.js @@ -0,0 +1,41 @@ +import { expect } from "chai"; +import { findLowestNumber, generateLinks } from "./for-each-test-helper.js"; + +describe("10. ForEach", () => { + describe("01-lowest-num", () => { + it('should change the variable "lowestNumber" so that it equals the lowest number in an array of numbers', () => { + const numbers = [1, 9999999, 4.13, -20]; + expect(findLowestNumber(numbers)).to.equal(-20); + }); + it("should use .forEach()", () => { + const funcStr = findLowestNumber.toString(); + expect(funcStr).to.contain(".forEach"); + }); + }); + + describe("02-generate-links", () => { + it('should return a string of tags, with one tag per URL in the "links" array', () => { + const links = ["http://vanilla-js.com", "https://developer.mozilla.org"]; + const anchors = generateLinks(links); + expect(anchors).to.be.a("string"); + expect(anchors).to.match(/(){2}/); + }); + it('each href attribute should equal a URL in the "links" array (e.g. { + const links = ["http://vanilla-js.com", "https://developer.mozilla.org"]; + const anchors = generateLinks(links); + expect(anchors).to.match(/href=("|')?http:\/\/vanilla-js.com/); + expect(anchors).to.match(/href=("|')?https:\/\/developer.mozilla.org/); + }); + it("the text between and for each link should look like e.g. 1. https://url1.com and the number should increment (HINT JavaScript starts with 0 instead of 1)", () => { + const links = ["http://vanilla-js.com", "https://developer.mozilla.org"]; + const anchors = generateLinks(links); + expect(anchors).to.match(/>\s?2\.? https:\/\/developer.mozilla.org\s?\s?2\.? https:\/\/developer.mozilla.org\s? { + const funcStr = generateLinks.toString(); + expect(funcStr).to.contain(".forEach"); + }); + }); +}); From 41f820aa5e3c75943de81675e213cb5ade7d9f63 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 24 Nov 2022 17:20:49 -0500 Subject: [PATCH 067/105] Problems 15-callbacks --- exercises/15-callbacks/02-print-names.js | 5 +++-- exercises/15-callbacks/03-find-first.js | 4 ++-- exercises/15-callbacks/04-link-or-button.js | 6 +++--- exercises/15-callbacks/05-send-email.js | 6 ++++++ exercises/16-for-each/01-lowest-num.js | 4 ++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/exercises/15-callbacks/02-print-names.js b/exercises/15-callbacks/02-print-names.js index a8b396e..b61b770 100644 --- a/exercises/15-callbacks/02-print-names.js +++ b/exercises/15-callbacks/02-print-names.js @@ -32,8 +32,9 @@ const printer = (name) => { */ const printNames = (array, callback) => { // WRITE PART 2 OF YOUR ANSWER HERE - for (let item of array); - printer(item); + for (let item of array) { + printer(item); + } }; // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/15-callbacks/03-find-first.js b/exercises/15-callbacks/03-find-first.js index 13d4ff8..f674104 100644 --- a/exercises/15-callbacks/03-find-first.js +++ b/exercises/15-callbacks/03-find-first.js @@ -24,8 +24,8 @@ const findFirst = (arrayOfNum, callback) => { // WRITE YOUR ANSWER HERE - for (let value of arrayOfNum) { - console.log(value); + for (let num of arrayOfNum) { + if (callback(num)) return num; } }; diff --git a/exercises/15-callbacks/04-link-or-button.js b/exercises/15-callbacks/04-link-or-button.js index 79d2642..dc423e3 100644 --- a/exercises/15-callbacks/04-link-or-button.js +++ b/exercises/15-callbacks/04-link-or-button.js @@ -16,16 +16,16 @@ const createButton = (text) => { * You must use a callback to solve this problem. */ -const createCallToAction = (clickableText) => { +const createCallToAction = (callback, clickableText) => { return ( "
      Limited Time: Members Save 30%
      " + - createLink(clickableText) + + callback(clickableText) + "
      " ); }; // Update me too -createCallToAction("Book Now"); +createCallToAction(createLink, "Book Now"); // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/15-callbacks/05-send-email.js b/exercises/15-callbacks/05-send-email.js index da5e051..28924c9 100644 --- a/exercises/15-callbacks/05-send-email.js +++ b/exercises/15-callbacks/05-send-email.js @@ -21,3 +21,9 @@ const askForUpdate = () => { */ // WRITE YOUR ANSWER BELOW THIS LINE + +const sendEmail = (callback) => { + console.log(callback()); +}; + +//sendEmail(askForUpdate); diff --git a/exercises/16-for-each/01-lowest-num.js b/exercises/16-for-each/01-lowest-num.js index 331353f..39c480a 100644 --- a/exercises/16-for-each/01-lowest-num.js +++ b/exercises/16-for-each/01-lowest-num.js @@ -9,3 +9,7 @@ const numbers = [1, 10, -2, 3, 4]; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE + +numbers.forEach((num, i) => { + if (num < lowestNumber) lowestNumber = num; +}); From 29364079a864c333a53fe2c464a3f14968162dfd Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 24 Nov 2022 18:06:50 -0500 Subject: [PATCH 068/105] Problems 16 --- exercises/16-for-each/01-lowest-num.js | 1 - exercises/16-for-each/02-generate-links.js | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/exercises/16-for-each/01-lowest-num.js b/exercises/16-for-each/01-lowest-num.js index 39c480a..ff0757e 100644 --- a/exercises/16-for-each/01-lowest-num.js +++ b/exercises/16-for-each/01-lowest-num.js @@ -9,7 +9,6 @@ const numbers = [1, 10, -2, 3, 4]; // e.g. */ // WRITE YOUR ANSWER BELOW THIS LINE - numbers.forEach((num, i) => { if (num < lowestNumber) lowestNumber = num; }); diff --git a/exercises/16-for-each/02-generate-links.js b/exercises/16-for-each/02-generate-links.js index 9f38103..4cd7432 100644 --- a/exercises/16-for-each/02-generate-links.js +++ b/exercises/16-for-each/02-generate-links.js @@ -3,7 +3,7 @@ const links = [ // e.g. "http://speakingjs.com/es5/ch04.html", "https://www.ecma-international.org/", - "https://books.google.com/books?id=2weL0iAfrEMC", + "https://www.google.com/books/edition/Eloquent_JavaScript_3rd_Edition/p1v6DwAAQBAJ", ]; /** @@ -24,3 +24,6 @@ const links = [ */ // WRITE YOUR ANSWER BELOW THIS LINE +links.forEach((link, i) => { + return (htmlStr += ` ${i + 1}. ${link}`); +}); From f21c664c42a79c503aaf36e27f9856003feffe52 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Mon, 21 Nov 2022 20:41:31 -0500 Subject: [PATCH 069/105] Solutions to some more callbacks and first forEach exercise --- .../04-link-or-button.solution.js | 32 +++++++++++++++++++ .../15-callbacks/05-send-email.solution.js | 27 ++++++++++++++++ .../16-for-each/01-lowest-num.solution.js | 25 +++++++++++++++ test/15-callbacks/callback-test-helper.js | 2 +- test/15-callbacks/callbacks.spec.js | 9 ++---- 5 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 solutions/15-callbacks/04-link-or-button.solution.js create mode 100644 solutions/15-callbacks/05-send-email.solution.js create mode 100644 solutions/16-for-each/01-lowest-num.solution.js diff --git a/solutions/15-callbacks/04-link-or-button.solution.js b/solutions/15-callbacks/04-link-or-button.solution.js new file mode 100644 index 0000000..173c1bc --- /dev/null +++ b/solutions/15-callbacks/04-link-or-button.solution.js @@ -0,0 +1,32 @@ +// E.g. do not change me +const createLink = (text) => { + return `${text}`; +}; + +// E.g. do not change me +const createButton = (text) => { + return ``; +}; + +/** + * Update the createCallToAction so that it can either: + * 1. Use createLink + * 2. Use createButton + * + * You must use a callback to solve this problem. + */ + +const createCallToAction = (clickableText, callback) => { + return ( + "
      Limited Time: Members Save 30%
      " + + callback(clickableText) + + "
      " + ); +}; + +// Update me too +createCallToAction("Book Now", createLink); + +// IGNORE THIS BELOW. It is for the tests. + +export { createCallToAction }; diff --git a/solutions/15-callbacks/05-send-email.solution.js b/solutions/15-callbacks/05-send-email.solution.js new file mode 100644 index 0000000..76c451d --- /dev/null +++ b/solutions/15-callbacks/05-send-email.solution.js @@ -0,0 +1,27 @@ +// E.g. +const askForUpdate = () => { + return "Hi John. Is there any update on this?"; +}; + +/** + * Create a function called "sendEmail". + * It should accept a callback as a parameter. + * The callback should return the contents of an email as a string + * "sendEmail" should use console.log to print the callback to the screen. + * + * sendEmail + * @param {function} callback the callback function + * uses console.log to print the callback to the screen + * + * the callback function + * @returns {string} the text in an email + * + * @example + * sendEmail(askForUpdate); // Hi. John. Is there any update on this? + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +const sendEmail = (callback) => { + console.log(callback()); +}; diff --git a/solutions/16-for-each/01-lowest-num.solution.js b/solutions/16-for-each/01-lowest-num.solution.js new file mode 100644 index 0000000..394b0b6 --- /dev/null +++ b/solutions/16-for-each/01-lowest-num.solution.js @@ -0,0 +1,25 @@ +let lowestNumber = Infinity; // This is the highest possible number in JavaScript +const numbers = [1, 10, -2, 3, 4]; // e.g. + +/** + * Using ".forEach", loop through the array "numbers" + * and set "lowestNumber" equal to the lowest number in the array. + * + * Your answer should still work if there are different numbers inside the array "numbers". + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Solution 1 +const findLowestNumber = (num) => { + if (num < lowestNumber) { + lowestNumber = num; + } +}; + +numbers.forEach(findLowestNumber); + +// Solution 2 +numbers.forEach((num) => { + if (num < lowestNumber) lowestNumber = num; +}); diff --git a/test/15-callbacks/callback-test-helper.js b/test/15-callbacks/callback-test-helper.js index cd59627..e2c67e9 100644 --- a/test/15-callbacks/callback-test-helper.js +++ b/test/15-callbacks/callback-test-helper.js @@ -11,7 +11,7 @@ import { createCallToAction } from "../../exercises/15-callbacks/04-link-or-butt const sendEmailStr = getAnswer("../exercises/15-callbacks/05-send-email.js"); export const sendEmail = eval(`(fn) => { - ${sendEmailStr} + ${sendEmailStr.replace("askForUpdate", "() => {}")} try { return sendEmail(fn); } catch (err) {} diff --git a/test/15-callbacks/callbacks.spec.js b/test/15-callbacks/callbacks.spec.js index 5ba875a..272e1da 100644 --- a/test/15-callbacks/callbacks.spec.js +++ b/test/15-callbacks/callbacks.spec.js @@ -74,12 +74,9 @@ describe("10. Callbacks", () => { return "Do you have time on Monday at 1pm to discuss this?"; }; - const output = readConsole(sendEmail.bind(null, scheduleMeeting)).replace( - "\n", - "" - ); - expect(output).to.equal( - "Do you have time on Monday at 1pm to discuss this?" + const output = readConsole(sendEmail.bind(null, scheduleMeeting)); + expect(output).to.match( + /Do you have time on Monday at 1pm to discuss this\?/ ); }); }); From 99f97a3b0691e5bf00e9e57a705685dc91b3cbc4 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 26 Nov 2022 20:27:12 -0500 Subject: [PATCH 070/105] Solution to final foreach problem --- .../16-for-each/02-generate-links.solution.js | 37 +++++++++++++++++++ test/15-callbacks/callbacks.spec.js | 1 + test/16-for-each/for-each.spec.js | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 solutions/16-for-each/02-generate-links.solution.js diff --git a/solutions/16-for-each/02-generate-links.solution.js b/solutions/16-for-each/02-generate-links.solution.js new file mode 100644 index 0000000..42c2091 --- /dev/null +++ b/solutions/16-for-each/02-generate-links.solution.js @@ -0,0 +1,37 @@ +let htmlStr = ""; +const links = [ + // e.g. + "http://speakingjs.com/es5/ch04.html", + "https://www.ecma-international.org/", + "https://books.google.com/books?id=2weL0iAfrEMC", +]; + +/** + * You can imagine you are creating a list of reference links at the bottom of a Wikipedia page. + * + * Using ".forEach", loop through an array of URLs, + * create a tag string for each link, + * and append the tag string to the variable "htmlStr" + * + * @example + * // After you solve this problem, "htmlStr" should equal: + * 1. http://speakingjs.com/es5/ch04.html2. https://www.ecma-international.org/3. https://books.google.com/books?id=2weL0iAfrEMC + * + * HINT: You will need to use the index in the array to solve this problem. + * + * Your answer should still work if there are different URLs inside of the "links" array. + * + */ + +// WRITE YOUR ANSWER BELOW THIS LINE + +// Solution 1 +links.forEach((href, idx) => { + const num = idx + 1; + htmlStr = htmlStr + '' + num + ". " + href + ""; +}); + +// Solution 2 +links.forEach((href, idx) => { + htmlStr += `${idx + 1}. ${href}`; +}); diff --git a/test/15-callbacks/callbacks.spec.js b/test/15-callbacks/callbacks.spec.js index 272e1da..426da64 100644 --- a/test/15-callbacks/callbacks.spec.js +++ b/test/15-callbacks/callbacks.spec.js @@ -59,6 +59,7 @@ describe("10. Callbacks", () => { const createLabel = (text) => { return ``; }; + // TODO account for the arguments being in a different order const html = createCallToAction("Sign me up", createLabel).replace( "\n", "" diff --git a/test/16-for-each/for-each.spec.js b/test/16-for-each/for-each.spec.js index 9c03436..55ab6a1 100644 --- a/test/16-for-each/for-each.spec.js +++ b/test/16-for-each/for-each.spec.js @@ -14,7 +14,7 @@ describe("10. ForEach", () => { }); describe("02-generate-links", () => { - it('should return a string of tags, with one tag per URL in the "links" array', () => { + it('"htmlStr" should be a string of tags, with one tag per URL in the "links" array', () => { const links = ["http://vanilla-js.com", "https://developer.mozilla.org"]; const anchors = generateLinks(links); expect(anchors).to.be.a("string"); From f76da1a10bd704de8951885882871b21ccf68b83 Mon Sep 17 00:00:00 2001 From: Matina Patsos Date: Sun, 27 Nov 2022 16:00:03 -0500 Subject: [PATCH 071/105] Fix typos --- projects/hangman/ProjectHangman.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/hangman/ProjectHangman.md b/projects/hangman/ProjectHangman.md index 7f19136..d2a74fd 100644 --- a/projects/hangman/ProjectHangman.md +++ b/projects/hangman/ProjectHangman.md @@ -111,7 +111,7 @@ If your instructors cannot grade your project because we cannot start or run you - Where, in the word, contains a letter that hasn't been guessed yet - How many guesses are left - Your game must be case insensitive. This means that when the player guesses a letter, the computer will treat lower case and upper case versions of a letter as the same character. -- The game will stop when either a.) the player has guessed all the letters of b.) the play has made six incorrect guesses +- The game will stop when either a.) the player has guessed all the letters or b.) the player has made six incorrect guesses - When the game finishes, let the play know if they have won and display the answer (the word the computer picked). - Please make sure your game text is easily readable. Use the new line characters (`\n`) where needed. From 6bf419c37cf4ea534e16ea52969f532ede9d390f Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 26 Nov 2022 21:25:26 -0500 Subject: [PATCH 072/105] Targeting DOM exercises --- exercises/17-targeting-dom/targeting-dom.html | 118 ++++++++++++++++++ exercises/17-targeting-dom/targeting-dom.js | 15 +++ 2 files changed, 133 insertions(+) create mode 100644 exercises/17-targeting-dom/targeting-dom.html create mode 100644 exercises/17-targeting-dom/targeting-dom.js diff --git a/exercises/17-targeting-dom/targeting-dom.html b/exercises/17-targeting-dom/targeting-dom.html new file mode 100644 index 0000000..be6aea0 --- /dev/null +++ b/exercises/17-targeting-dom/targeting-dom.html @@ -0,0 +1,118 @@ + + + + + + EXERCISES Targeting DOM + + + + +
      +
      + You will need to inspect this with your browser tools to see if this + worked. Press option + command + i on a + Mac or ctrl + shift + i on Windows and + open the Console tab. +
      +
      + +
      +

      Single elements

      +

      + Do not modify the HTML in this <section>. +

      +
        +
      • + Target this first <li> element, but no other + <li> elements . +
      • +
      • Target this element with an id of myId.
      • +
      +
      + +
      +

      Groups of elements

      +

      + Do not modify the HTML in this <section>. +

      +

      + Target every <li> element below that has a yellow + background with a single document.query____. +

      +
        +
      • Do not target me.
      • +
      • + Target this element and every other element with the class + bg-warning. +
      • +
      • Do not target me.
      • +
      • + Target this element and every other element with the class + bg-warning. +
      • +
      • + Target this element and every other element with the class + bg-warning. +
      • +
      +
      + +
      +

      Structuring your HTML for JavaScript

      +

      + You will need to modify the HTML in this <section>. +

      +

      + Target the button labeled "Target Me" only. You will need to modify the + HTML. +

      +
      + + + + +
      +

      + Target every <a> element below that is a social media + site with a single document.query____. You will need to + modify the HTML. +

      +
      +
      + +
      +

      Nested elements

      +

      + Do not modify the HTML in this <section>. +

      +
      +
      Ignore Me
      +
      Ignore Me
      +
      +
      +
      + Target Me (the cell, not the whole row) +
      +
      + Target Me (the cell, not the whole row) +
      +
      +
      +
      Ignore Me
      +
      Ignore Me
      +
      +
      + + diff --git a/exercises/17-targeting-dom/targeting-dom.js b/exercises/17-targeting-dom/targeting-dom.js new file mode 100644 index 0000000..d9e409b --- /dev/null +++ b/exercises/17-targeting-dom/targeting-dom.js @@ -0,0 +1,15 @@ +/** + * You will be targeting DOM elements (the HTML) on the page using + * "document.querySelector" or "document.querySelectorAll" + * You will then use "console.log" to print the results. + * + * @example console.log( document.querySelector("#myTarget") ); + * + * When you use "document.querySelectorAll", you must loop through each + * element in the collection and console.log each element. (See the slides) + * + * Do not change the HTML unless you are instructed to do so. + */ +(function () { + // Put your answers in here +})(); From 9794f21e361c1619af4c8cc2f2a4fe42547bfc97 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 30 Nov 2022 20:20:47 -0500 Subject: [PATCH 073/105] Problems 17 --- exercises/17-targeting-dom/targeting-dom.html | 12 +++++++----- exercises/17-targeting-dom/targeting-dom.js | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/exercises/17-targeting-dom/targeting-dom.html b/exercises/17-targeting-dom/targeting-dom.html index be6aea0..b381ed9 100644 --- a/exercises/17-targeting-dom/targeting-dom.html +++ b/exercises/17-targeting-dom/targeting-dom.html @@ -74,7 +74,9 @@

      Structuring your HTML for JavaScript

      - +
      @@ -84,11 +86,11 @@

      Structuring your HTML for JavaScript

      modify the HTML.

      diff --git a/exercises/17-targeting-dom/targeting-dom.js b/exercises/17-targeting-dom/targeting-dom.js index d9e409b..f7dc3fc 100644 --- a/exercises/17-targeting-dom/targeting-dom.js +++ b/exercises/17-targeting-dom/targeting-dom.js @@ -12,4 +12,23 @@ */ (function () { // Put your answers in here + let li1 = document.querySelector("li"); + console.log(li1); + let li2 = document.querySelector("#myId"); + console.log(li2); + /******/ + let warnings = document.querySelectorAll(".bg-warning"); + for (let warning of warnings) { + console.log(warning); + } + /********/ + let button = document.querySelector("#target-button"); + console.log(button); + /*******/ + let anchors = document.querySelectorAll(".social"); + for (let anchor of anchors) { + console.log(anchor); + /********/ + let cells = document.querySelectorAll(""); + } })(); From bafa9e81b320eadf79692f9cf2ba6053ae41176c Mon Sep 17 00:00:00 2001 From: Matina Patsos Date: Wed, 30 Nov 2022 17:44:33 -0500 Subject: [PATCH 074/105] Remove "x-rary" from Hangman project word bank --- projects/hangman/word-bank.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/hangman/word-bank.js b/projects/hangman/word-bank.js index 692a70a..fcf398f 100644 --- a/projects/hangman/word-bank.js +++ b/projects/hangman/word-bank.js @@ -1 +1 @@ -export default ["rumor","happen","match","sail","sick","floor","summit","shadow","census","chorus","launch","abbey","eject","resist","guilt","repeat","drama","easy","morsel","swipe","equip","reader","pray","grave","cord","cheek","figure","rebel","native","rack","fade","basket","reform","hall","area","root","breeze","shift","cane","cash","hour","galaxy","breed","straw","offset","speech","appear","porter","mosque","flush","sheet","whip","finger","suite","glare","base","catch","cheque","critic","circle","block","talk","salad","bronze","occupy","morale","policy","weak","narrow","essay","Koran","direct","aware","worth","choose","outer","stamp","agile","weave","case","lift","shell","liver","safari","linear","star","makeup","snack","snow","cope","fault","alive","ideal","foot","reduce","solid","inch","arise","master","sigh","shelf","brake","admire","leader","tooth","bitch","coach","dare","beam","sell","change","broken","edge","absorb","side","basin","mess","crown","effort","burst","series","upset","beard","lane","palm","wing","torch","heaven","young","stand","polish","pardon","mouth","sphere","charge","grace","back","writer","bridge","even","rent","endure","story","remain","gloom","exile","need","revise","punch","future","date","forest","crash","bald","coup","coma","soak","joint","begin","screen","apple","weight","yard","order","sermon","bird","pity","efflux","mirror","stroll","menu","tube","guest","terms","reveal","long","scrap","rough","lake","score","summer","orbit","seem","wonder","bold","thumb","attack","coffin","sketch","form","tumble","half","member","bacon","rush","castle","poison","mail","steam","core","snail","seller","invite","disk","ready","refer","indoor","kill","weapon","haunt","TRUE","slice","fame","extent","knife","party","margin","tray","number","medal","bottle","throw","cafe","driver","source","cook","frank","absent","unique","bland","jury","sofa","bundle","brag","clock","debut","nuance","aisle","stroke","wrap","real","wound","slump","friend","kick","powder","crouch","chord","shine","smile","garage","nerve","mayor","depart","lock","oral","close","choke","virtue","tiger","honor","soft","stable","final","pour","snake","prize","damage","donor","land","boat","patrol","light","park","ring","revoke","field","method","widen","chance","revive","tile","watch","pillow","waist","spit","spirit","host","dinner","dine","gown","slip","give","still","item","hurl","cancer","guitar","silk","moving","fence","yearn","oppose","rank","goal","lawyer","turn","rear","hole","asylum","plant","output","detail","soar","entry","full","swim","flex","draw","horn","curl","herd","rock","plan","zone","groan","money","adopt","eaux","space","danger","tract","racism","month","stream","sample","knot","outfit","decide","fair","runner","pain","brown","skate","dome","minor","text","wander","heel","lemon","find","braid","gold","design","seal","title","abuse","bake","king","mile","wine","voice","steep","take","club","jockey","seize","hold","center","filter","shower","blue","bread","enemy","lean","dress","gravel","know","jacket","navy","tone","exact","arch","stake","last","slap","spell","stitch","jest","tiptoe","grain","deck","fire","tired","fight","common","soil","wild","shiver","bill","bishop","dawn","rice","bulb","free","dream","excuse","credit","miss","muscle","offend","fine","chew","cousin","dull","acid","rifle","crew","Venus","truck","remind","trace","effect","stun","debate","glory","crowd","slam","barrel","grief","store","chin","mercy","wall","pawn","debt","layout","video","stem","copy","belief","sweep","appeal","army","hike","asset","brave","list","thread","decade","noble","polite","pile","frame","fate","grip","virus","pure","tidy","sodium","harbor","thigh","public","view","taxi","bait","riot","ridge","tongue","utter","build","funny","scene","trip","movie","scan","ritual","planet","sale","fare","option","just","study","note","tycoon","please","survey","ankle","double","poem","enjoy","useful","drug","theft","horse","pack","instal","fear","quota","bowel","cover","rape","arena","split","elite","allow","wake","grind","doll","crime","cruel","remark","ditch","insure","clue","favor","topple","move","memory","seed","chaos","X-ray","follow","swear","greet","tactic","column","style","smash","lend","tail","coffee","press","wire","lead","bench","belt","penny","obese","taste","poll","quote","expand","mask","golf","ignite","worm","dragon","tasty","sticky","ivory","spoil","strike","pepper","pilot","iron","gene","reach","sight","bother","twin","heat","file","jelly","angle","desire","amber","neck","vain","float","boom","sting","winter","facade","equal","dozen","valley","tell","want","fairy","carry","bite","string","size","jump","ride","reward","site","teach","help","ignore","gaffe","diet","rate","animal","camera","marble","jail","novel","horror","herb","banner","remedy","mold","desk","aspect","lung","hero","course","fleet","angel","bring","banana","script","room","answer","award","tread","impact","formal","solve","pump","scream","nature","theme","tumour","sweat","ferry","idea","trust","visual","feast","misery","loose","kidnap","lobby","relate","peace","onion","exempt","count","branch","test","harass","bolt","flag","brand","panel","drown","bless","mark","layer","volume","player","dash","prince","locate","cotton","zero","lunch","mature","bind","care","late","deputy","rider","drop","basic","ticket","wait","deep","storm","short","wear","banish","robot","make","earwax","review","sleeve","thesis","black","bell","clear","flock","mind","colony","market","loss","heroin","patent","love","snub","prison","refund","petty","part","card","issue","drain","deadly","tempt","frown","goat","term","drag","vote","east","turkey","flow","lamb","cycle","buffet","prove","moment","show","wage","cower","hammer","heavy","spin","drawer","panic","salt","inside","pull","shrink","shorts","senior","square","lily","meet","dairy","hand","canvas","hell","poor","embryo","meal","year","budget","viable","notice","marsh","punish","shame","rung","wrist","nose","escape","elect","shave","smoke","fill","train","lost","cheap","shop","mutter","fibre","faint","vague","arrest","stool","thaw","colon","high","family","injury","work","enfix","Bible","fruit","person","crisis","pick","stock","bond","urge","fresh","pride","fail","jewel","bloody","virgin","chalk","axis","ballet","laser","extend","desert","cheat","marine","slab","preach","front","ladder","toast","safety","feel","woman","muggy","rise","skip","echo","stage","chest","flight","tease","kidney","forbid","brick","origin","prey","color","draft","team","cheese","agree","junior","carpet","maze","city","shot","suffer","lace","cinema","basis","pastel","large","acquit","afford","organ","hair","power","chase","merit","elbow","energy","place","velvet","exotic","growth","proud","thin","pair","fish","lodge","thank","labour","slime","gain","belly","garlic","climb","latest","time","eagle","wife","pause","chop","kettle","green","album","swell","matrix","rich","wood","sink","spring","worry","tick","voter","fist","plead","relief","slant","bike","brush","fever","door","cable","profit","glass","path","dead","corpse","creed","bang","scrape","minute","thick","jungle","moral","bride","handy","giant","death","start","Sunday","squash","tune","clean","gossip","chain","sacred","father","salmon","tense","halt","gutter","middle"]; \ No newline at end of file +export default ["rumor","happen","match","sail","sick","floor","summit","shadow","census","chorus","launch","abbey","eject","resist","guilt","repeat","drama","easy","morsel","swipe","equip","reader","pray","grave","cord","cheek","figure","rebel","native","rack","fade","basket","reform","hall","area","root","breeze","shift","cane","cash","hour","galaxy","breed","straw","offset","speech","appear","porter","mosque","flush","sheet","whip","finger","suite","glare","base","catch","cheque","critic","circle","block","talk","salad","bronze","occupy","morale","policy","weak","narrow","essay","Koran","direct","aware","worth","choose","outer","stamp","agile","weave","case","lift","shell","liver","safari","linear","star","makeup","snack","snow","cope","fault","alive","ideal","foot","reduce","solid","inch","arise","master","sigh","shelf","brake","admire","leader","tooth","bitch","coach","dare","beam","sell","change","broken","edge","absorb","side","basin","mess","crown","effort","burst","series","upset","beard","lane","palm","wing","torch","heaven","young","stand","polish","pardon","mouth","sphere","charge","grace","back","writer","bridge","even","rent","endure","story","remain","gloom","exile","need","revise","punch","future","date","forest","crash","bald","coup","coma","soak","joint","begin","screen","apple","weight","yard","order","sermon","bird","pity","efflux","mirror","stroll","menu","tube","guest","terms","reveal","long","scrap","rough","lake","score","summer","orbit","seem","wonder","bold","thumb","attack","coffin","sketch","form","tumble","half","member","bacon","rush","castle","poison","mail","steam","core","snail","seller","invite","disk","ready","refer","indoor","kill","weapon","haunt","TRUE","slice","fame","extent","knife","party","margin","tray","number","medal","bottle","throw","cafe","driver","source","cook","frank","absent","unique","bland","jury","sofa","bundle","brag","clock","debut","nuance","aisle","stroke","wrap","real","wound","slump","friend","kick","powder","crouch","chord","shine","smile","garage","nerve","mayor","depart","lock","oral","close","choke","virtue","tiger","honor","soft","stable","final","pour","snake","prize","damage","donor","land","boat","patrol","light","park","ring","revoke","field","method","widen","chance","revive","tile","watch","pillow","waist","spit","spirit","host","dinner","dine","gown","slip","give","still","item","hurl","cancer","guitar","silk","moving","fence","yearn","oppose","rank","goal","lawyer","turn","rear","hole","asylum","plant","output","detail","soar","entry","full","swim","flex","draw","horn","curl","herd","rock","plan","zone","groan","money","adopt","eaux","space","danger","tract","racism","month","stream","sample","knot","outfit","decide","fair","runner","pain","brown","skate","dome","minor","text","wander","heel","lemon","find","braid","gold","design","seal","title","abuse","bake","king","mile","wine","voice","steep","take","club","jockey","seize","hold","center","filter","shower","blue","bread","enemy","lean","dress","gravel","know","jacket","navy","tone","exact","arch","stake","last","slap","spell","stitch","jest","tiptoe","grain","deck","fire","tired","fight","common","soil","wild","shiver","bill","bishop","dawn","rice","bulb","free","dream","excuse","credit","miss","muscle","offend","fine","chew","cousin","dull","acid","rifle","crew","Venus","truck","remind","trace","effect","stun","debate","glory","crowd","slam","barrel","grief","store","chin","mercy","wall","pawn","debt","layout","video","stem","copy","belief","sweep","appeal","army","hike","asset","brave","list","thread","decade","noble","polite","pile","frame","fate","grip","virus","pure","tidy","sodium","harbor","thigh","public","view","taxi","bait","riot","ridge","tongue","utter","build","funny","scene","trip","movie","scan","ritual","planet","sale","fare","option","just","study","note","tycoon","please","survey","ankle","double","poem","enjoy","useful","drug","theft","horse","pack","instal","fear","quota","bowel","cover","rape","arena","split","elite","allow","wake","grind","doll","crime","cruel","remark","ditch","insure","clue","favor","topple","move","memory","seed","chaos","follow","swear","greet","tactic","column","style","smash","lend","tail","coffee","press","wire","lead","bench","belt","penny","obese","taste","poll","quote","expand","mask","golf","ignite","worm","dragon","tasty","sticky","ivory","spoil","strike","pepper","pilot","iron","gene","reach","sight","bother","twin","heat","file","jelly","angle","desire","amber","neck","vain","float","boom","sting","winter","facade","equal","dozen","valley","tell","want","fairy","carry","bite","string","size","jump","ride","reward","site","teach","help","ignore","gaffe","diet","rate","animal","camera","marble","jail","novel","horror","herb","banner","remedy","mold","desk","aspect","lung","hero","course","fleet","angel","bring","banana","script","room","answer","award","tread","impact","formal","solve","pump","scream","nature","theme","tumour","sweat","ferry","idea","trust","visual","feast","misery","loose","kidnap","lobby","relate","peace","onion","exempt","count","branch","test","harass","bolt","flag","brand","panel","drown","bless","mark","layer","volume","player","dash","prince","locate","cotton","zero","lunch","mature","bind","care","late","deputy","rider","drop","basic","ticket","wait","deep","storm","short","wear","banish","robot","make","earwax","review","sleeve","thesis","black","bell","clear","flock","mind","colony","market","loss","heroin","patent","love","snub","prison","refund","petty","part","card","issue","drain","deadly","tempt","frown","goat","term","drag","vote","east","turkey","flow","lamb","cycle","buffet","prove","moment","show","wage","cower","hammer","heavy","spin","drawer","panic","salt","inside","pull","shrink","shorts","senior","square","lily","meet","dairy","hand","canvas","hell","poor","embryo","meal","year","budget","viable","notice","marsh","punish","shame","rung","wrist","nose","escape","elect","shave","smoke","fill","train","lost","cheap","shop","mutter","fibre","faint","vague","arrest","stool","thaw","colon","high","family","injury","work","enfix","Bible","fruit","person","crisis","pick","stock","bond","urge","fresh","pride","fail","jewel","bloody","virgin","chalk","axis","ballet","laser","extend","desert","cheat","marine","slab","preach","front","ladder","toast","safety","feel","woman","muggy","rise","skip","echo","stage","chest","flight","tease","kidney","forbid","brick","origin","prey","color","draft","team","cheese","agree","junior","carpet","maze","city","shot","suffer","lace","cinema","basis","pastel","large","acquit","afford","organ","hair","power","chase","merit","elbow","energy","place","velvet","exotic","growth","proud","thin","pair","fish","lodge","thank","labour","slime","gain","belly","garlic","climb","latest","time","eagle","wife","pause","chop","kettle","green","album","swell","matrix","rich","wood","sink","spring","worry","tick","voter","fist","plead","relief","slant","bike","brush","fever","door","cable","profit","glass","path","dead","corpse","creed","bang","scrape","minute","thick","jungle","moral","bride","handy","giant","death","start","Sunday","squash","tune","clean","gossip","chain","sacred","father","salmon","tense","halt","gutter","middle"]; From 5841c852df459dc60e77cd13a15b31c11c202617 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 30 Nov 2022 18:30:29 -0500 Subject: [PATCH 075/105] Targeting DOM solutions --- .../targeting-dom.solution.html | 120 ++++++++++++++++++ .../targeting-dom.solution.js | 38 ++++++ 2 files changed, 158 insertions(+) create mode 100644 solutions/17-targeting-dom/targeting-dom.solution.html create mode 100644 solutions/17-targeting-dom/targeting-dom.solution.js diff --git a/solutions/17-targeting-dom/targeting-dom.solution.html b/solutions/17-targeting-dom/targeting-dom.solution.html new file mode 100644 index 0000000..8bba03e --- /dev/null +++ b/solutions/17-targeting-dom/targeting-dom.solution.html @@ -0,0 +1,120 @@ + + + + + + EXERCISES Targeting DOM + + + + +
      +
      + You will need to inspect this with your browser tools to see if this + worked. Press option + command + i on a + Mac or ctrl + shift + i on Windows and + open the Console tab. +
      +
      + +
      +

      Single elements

      +

      + Do not modify the HTML in this <section>. +

      +
        +
      • + Target this first <li> element, but no other + <li> elements . +
      • +
      • Target this element with an id of myId.
      • +
      +
      + +
      +

      Groups of elements

      +

      + Do not modify the HTML in this <section>. +

      +

      + Target every <li> element below that has a yellow + background with a single document.query____. +

      +
        +
      • Do not target me.
      • +
      • + Target this element and every other element with the class + bg-warning. +
      • +
      • Do not target me.
      • +
      • + Target this element and every other element with the class + bg-warning. +
      • +
      • + Target this element and every other element with the class + bg-warning. +
      • +
      +
      + +
      +

      Structuring your HTML for JavaScript

      +

      + You will need to modify the HTML in this <section>. +

      + Target the button labeled "Target Me" only. You will need to modify the + HTML. +
      + + + + + +
      +

      + Target every <a> element below that is a social media + site with a single document.query____. You will need to + modify the HTML. +

      + + +
      + +
      +

      Nested elements

      +

      + Do not modify the HTML in this <section>. +

      +
      +
      Ignore Me
      +
      Ignore Me
      +
      +
      +
      + Target Me (the cell, not the whole row) +
      +
      + Target Me (the cell, not the whole row) +
      +
      +
      +
      Ignore Me
      +
      Ignore Me
      +
      +
      + + diff --git a/solutions/17-targeting-dom/targeting-dom.solution.js b/solutions/17-targeting-dom/targeting-dom.solution.js new file mode 100644 index 0000000..2162ebb --- /dev/null +++ b/solutions/17-targeting-dom/targeting-dom.solution.js @@ -0,0 +1,38 @@ +/** + * You will be targeting DOM elements (the HTML) on the page using + * "document.querySelector" or "document.querySelectorAll" + * You will then use "console.log" to print the results. + * + * @example console.log( document.querySelector("#myTarget") ); + * + * When you use "document.querySelectorAll", you must loop through each + * element in the collection and console.log each element. (See the slides) + * + * Do not change the HTML unless you are instructed to do so. + */ +(function () { + const firstLi = document.querySelector("li"); + console.log("firstLi", firstLi); + + const myId = document.querySelector("#myId"); + console.log("myId", myId); + + const allLi = document.querySelectorAll("li"); + allLi.forEach((li) => { + console.log("allLi", li); + }); + + const allBgWarning = document.querySelectorAll(".bg-warning"); + allBgWarning.forEach((li) => { + console.log(".bg-warning", li); + }); + + const targetButton = document.querySelector("#targetButton"); + console.log(targetButton); + + const targetLinks = document.querySelectorAll(".target-link"); + targetLinks.forEach((link) => console.log(link)); + + const cells = document.querySelectorAll("#myRow > .col"); + cells.forEach((cell) => console.log("cell", cell)); +})(); From 9f550364f74cbc9e2f1260e65403ea566c43e763 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 30 Nov 2022 20:32:09 -0500 Subject: [PATCH 076/105] Transforming DOM exercises --- .../18-transforming-dom/transforming-dom.html | 88 +++++++++++++++++++ .../18-transforming-dom/transforming-dom.js | 8 ++ 2 files changed, 96 insertions(+) create mode 100644 exercises/18-transforming-dom/transforming-dom.html create mode 100644 exercises/18-transforming-dom/transforming-dom.js diff --git a/exercises/18-transforming-dom/transforming-dom.html b/exercises/18-transforming-dom/transforming-dom.html new file mode 100644 index 0000000..32bb3ca --- /dev/null +++ b/exercises/18-transforming-dom/transforming-dom.html @@ -0,0 +1,88 @@ + + + + + + EXERCISES Transforming DOM + + + + + +
      +

      + Edit the <img> tag below so that + it displays an image. (You can use the image + https://media.giphy.com/media/3oKIPnAiaMCws8nOsE/giphy.gif + or any other image of your choice.) +

      + Hard at Work +
      + +
      + Change the link below so that when clicked on, it links to + https://developer.mozilla.org/en-US/docs/Web/JavaScript. + +
      + +
      + Change the text inside this <div> to say "I am + victorious!" +
      + +
      + Change the background color of this <div> to another + color using inline styles. +
      + +
      + Change the text color of this <div> to another color by + changing the class. + See Bootstrap colors. +
      + +
      + Hide this <div> using inline styles. +
      + +

      + Show the hidden <div> below by modifying the + class in some way. +

      + + +
      + Using conditional logic (e.g. an if statement), change the + <div> below to say "✓ blue" if + + has class btn-primary. +
      + +
      +
      + + + diff --git a/exercises/18-transforming-dom/transforming-dom.js b/exercises/18-transforming-dom/transforming-dom.js new file mode 100644 index 0000000..0c5178b --- /dev/null +++ b/exercises/18-transforming-dom/transforming-dom.js @@ -0,0 +1,8 @@ +/** + * You will follow the instructions in the transforming-dom.html + * to transform various elements on the page in different ways. + * You may modify the HTML to add ids, classes, data attributes, etc. + */ +(function () { + // Put your answers in here +})(); From c86874b5de70414646f134031acc5198a7a2e661 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Mon, 5 Dec 2022 19:12:52 -0500 Subject: [PATCH 077/105] Problems 18 --- .../18-transforming-dom/transforming-dom.html | 17 ++++++++------- .../18-transforming-dom/transforming-dom.js | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/exercises/18-transforming-dom/transforming-dom.html b/exercises/18-transforming-dom/transforming-dom.html index 32bb3ca..d5a627a 100644 --- a/exercises/18-transforming-dom/transforming-dom.html +++ b/exercises/18-transforming-dom/transforming-dom.html @@ -36,23 +36,23 @@ Change the link below so that when clicked on, it links to https://developer.mozilla.org/en-US/docs/Web/JavaScript. -
      +
      Change the text inside this <div> to say "I am victorious!"
      -
      +
      Change the background color of this <div> to another color using inline styles.
      -
      +
      Change the text color of this <div> to another color by changing the class.
      -
      +
      Hide this <div> using inline styles.
      @@ -70,16 +70,17 @@ Show the hidden <div> below by modifying the class in some way.

      - +
      Peek a boo!
      +
      Using conditional logic (e.g. an if statement), change the <div> below to say "✓ blue" if - has class btn-primary. -
      +
      diff --git a/exercises/18-transforming-dom/transforming-dom.js b/exercises/18-transforming-dom/transforming-dom.js index 0c5178b..d138cb4 100644 --- a/exercises/18-transforming-dom/transforming-dom.js +++ b/exercises/18-transforming-dom/transforming-dom.js @@ -5,4 +5,25 @@ */ (function () { // Put your answers in here + const img = document.querySelector("img"); + img.src = "https://media.giphy.com/media/3oKIPnAiaMCws8nOsE/giphy.gif"; + // + const link = document.querySelector("#jsref"); + link.href = "https://developer.mozilla.org/en-US/docs/Web/JavaScript"; + // + const text = document.querySelector("#textchange"); + text.textContent = "I am victorious!"; + // + const bgColor = document.querySelector("#colorchange"); + bgColor.style.backgroundColor = "#bbbbbb"; + // + //const TxtClassColor = document.querySelector("text-info"); + // + const divToHide = document.querySelector("#hide"); + divToHide.style.display = "none"; + + const myButton = document.querySelector("#button1"); + if (myButton.classList.contains("btn-primary")) { + myButton.textContent = "checkmark blue"; + } })(); From 205db69b2e18c59ddcb23eecbba9e92635d3744e Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 3 Dec 2022 12:49:46 -0500 Subject: [PATCH 078/105] DOM attributes exercise --- .../18-dom-attributes/dom-attributes.html | 25 ++++++++++++ .../dom-attributes.solutions.html | 38 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 exercises/18-dom-attributes/dom-attributes.html create mode 100644 solutions/18-dom-attributes/dom-attributes.solutions.html diff --git a/exercises/18-dom-attributes/dom-attributes.html b/exercises/18-dom-attributes/dom-attributes.html new file mode 100644 index 0000000..0be6cbd --- /dev/null +++ b/exercises/18-dom-attributes/dom-attributes.html @@ -0,0 +1,25 @@ + + + + + + + Document + + + + + + diff --git a/solutions/18-dom-attributes/dom-attributes.solutions.html b/solutions/18-dom-attributes/dom-attributes.solutions.html new file mode 100644 index 0000000..87994e5 --- /dev/null +++ b/solutions/18-dom-attributes/dom-attributes.solutions.html @@ -0,0 +1,38 @@ + + + + + + + Document + + + + + + From 4d790d409380d4eefb98b6e27e54c1d83bcee6c2 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 3 Dec 2022 12:52:18 -0500 Subject: [PATCH 079/105] Fix image not loading in solution --- solutions/18-dom-attributes/dom-attributes.solutions.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/18-dom-attributes/dom-attributes.solutions.html b/solutions/18-dom-attributes/dom-attributes.solutions.html index 87994e5..86e831e 100644 --- a/solutions/18-dom-attributes/dom-attributes.solutions.html +++ b/solutions/18-dom-attributes/dom-attributes.solutions.html @@ -27,7 +27,7 @@ // 2: img.src = - "https://en.wikipedia.org/wiki/Polar_bear#/media/File:Polar_Bear_-_Alaska_(cropped).jpg"; + "https://upload.wikimedia.org/wikipedia/commons/6/66/Polar_Bear_-_Alaska_%28cropped%29.jpg"; // 3: img.alt = "Polar bear"; From 32fa94fa0197a8ab0eb7118e9853153e9a29f0a2 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Mon, 5 Dec 2022 17:57:28 -0500 Subject: [PATCH 080/105] Solutions to transforming DOM exercises --- .../transforming-dom.solution.html | 100 ++++++++++++++++++ .../transforming-dom.solution.js | 28 +++++ 2 files changed, 128 insertions(+) create mode 100644 solutions/18-transforming-dom/transforming-dom.solution.html create mode 100644 solutions/18-transforming-dom/transforming-dom.solution.js diff --git a/solutions/18-transforming-dom/transforming-dom.solution.html b/solutions/18-transforming-dom/transforming-dom.solution.html new file mode 100644 index 0000000..99cb8eb --- /dev/null +++ b/solutions/18-transforming-dom/transforming-dom.solution.html @@ -0,0 +1,100 @@ + + + + + + EXERCISES Transforming DOM + + + + + +
      + + +
      + Change the link below so that when clicked on, it links to + https://developer.mozilla.org/en-US/docs/Web/JavaScript. + +
      + + +
      + Change the text inside this <div> to say "I am + victorious!" +
      + + +
      + Change the background color of this <div> to another + color using inline styles. +
      + + +
      + Change the text color of this <div> to another color by + changing the class. + See Bootstrap colors. +
      + + +
      + Hide this <div> using inline styles. +
      + +

      + Show the hidden <div> below by modifying the + class in some way. +

      + + +
      + Using conditional logic (e.g. an if statement), change the + <div> below to say "✓ blue" if + + + has class btn-primary. + +
      + +
      +
      +
      + + diff --git a/solutions/18-transforming-dom/transforming-dom.solution.js b/solutions/18-transforming-dom/transforming-dom.solution.js new file mode 100644 index 0000000..a4fd17e --- /dev/null +++ b/solutions/18-transforming-dom/transforming-dom.solution.js @@ -0,0 +1,28 @@ +/** + * You will follow the instructions in the transforming-dom.html + * to transform various elements on the page in different ways. + * You may modify the HTML to add ids, classes, data attributes, etc. + */ +(function () { + const image = document.querySelector("#image"); + image.src = "https://media.giphy.com/media/3oKIPnAiaMCws8nOsE/giphy.gif"; + + document.querySelector("#javascriptLink").href = + "https://developer.mozilla.org/en-US/docs/Web/JavaScript"; + + document.querySelector("#victorious").textContent = "I am victorious!"; + + document.querySelector("#inlineStyles").style.backgroundColor = "white"; + + const dangerNoMore = document.querySelector("#dangerNoMore"); + dangerNoMore.classList.add("text-dark"); + + document.querySelector("#hideMe").style.display = "none"; + + document.querySelector("#abraKadabra").classList.remove("hidden"); + + const button = document.querySelector("#thisButton"); + if (button.classList.contains("btn-primary")) { + document.querySelector("#buttonOutput").textContent = "✓ blue"; + } +})(); From 738efcf885ae6a14e93afc8b06f036e848898ed1 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 3 Dec 2022 11:50:49 -0500 Subject: [PATCH 081/105] Click events exercises --- exercises/19-click-events/click-events.html | 46 +++++++++++++++++++++ exercises/19-click-events/click-events.js | 20 +++++++++ 2 files changed, 66 insertions(+) create mode 100644 exercises/19-click-events/click-events.html create mode 100644 exercises/19-click-events/click-events.js diff --git a/exercises/19-click-events/click-events.html b/exercises/19-click-events/click-events.html new file mode 100644 index 0000000..c32f04a --- /dev/null +++ b/exercises/19-click-events/click-events.html @@ -0,0 +1,46 @@ + + + + + + + EXERCISES Events + + + + + + + + + + + + +
      + + +
      + +
      + + +
      + + diff --git a/exercises/19-click-events/click-events.js b/exercises/19-click-events/click-events.js new file mode 100644 index 0000000..2423609 --- /dev/null +++ b/exercises/19-click-events/click-events.js @@ -0,0 +1,20 @@ +(function () { + /** + * You have two challenges to solve below with Vanilla JavaScript. + * You are allowed to make changes to the HTML and CSS. + */ + /** + * Problem 1: Alert Me + * When the clicks on the button that says "Alert Me!", it should display an alert. + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/alert + */ + // Write your answer here + /** + * Problem 2: Disable a button that will charge a credit card. + * + * To prevent users from charging the credit card more than once: + * 1. Disable the button when it is clicked. + * 2. Change the text to say e.g. "Loading ..." once it is clicked. + */ + // Write your answer here +})(); From 5b8ec27a61f4a1e356dad19f1154da5cf3d1f7bd Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Tue, 6 Dec 2022 12:14:06 -0500 Subject: [PATCH 082/105] Problems 19 --- exercises/19-click-events/click-events.html | 6 ++++-- exercises/19-click-events/click-events.js | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/exercises/19-click-events/click-events.html b/exercises/19-click-events/click-events.html index c32f04a..48cedef 100644 --- a/exercises/19-click-events/click-events.html +++ b/exercises/19-click-events/click-events.html @@ -35,12 +35,14 @@ >
      - +
      - +
      diff --git a/exercises/19-click-events/click-events.js b/exercises/19-click-events/click-events.js index 2423609..4d5aca7 100644 --- a/exercises/19-click-events/click-events.js +++ b/exercises/19-click-events/click-events.js @@ -9,6 +9,11 @@ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/alert */ // Write your answer here + const button1 = document.querySelector("#btn1"); + const eventHandler = (click) => { + alert("You clicked me!"); + }; + button1.addEventListener("click", eventHandler); /** * Problem 2: Disable a button that will charge a credit card. * @@ -17,4 +22,10 @@ * 2. Change the text to say e.g. "Loading ..." once it is clicked. */ // Write your answer here + const creditCardButton = document.querySelector("#btn2"); + const chargeOnce = () => { + creditCardButton.textContent = "Loading..."; + creditCardButton.disabled = "disabled"; + }; + creditCardButton.addEventListener("click", chargeOnce); })(); From 7e654128047cd71e126ab1dcbb36510a5cdc48c6 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Mon, 5 Dec 2022 20:20:16 -0500 Subject: [PATCH 083/105] Solutions to click event problems --- .../click-events.solution.html | 50 +++++++++++++++++++ .../19-click-events/click-events.solution.js | 41 +++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 solutions/19-click-events/click-events.solution.html create mode 100644 solutions/19-click-events/click-events.solution.js diff --git a/solutions/19-click-events/click-events.solution.html b/solutions/19-click-events/click-events.solution.html new file mode 100644 index 0000000..64e85b9 --- /dev/null +++ b/solutions/19-click-events/click-events.solution.html @@ -0,0 +1,50 @@ + + + + + + + EXERCISES Events + + + + + + + + + + + + +
      + + + +
      + +
      + + + +
      + + diff --git a/solutions/19-click-events/click-events.solution.js b/solutions/19-click-events/click-events.solution.js new file mode 100644 index 0000000..c9464df --- /dev/null +++ b/solutions/19-click-events/click-events.solution.js @@ -0,0 +1,41 @@ +(function () { + /** + * You have two challenges to solve below with Vanilla JavaScript. + * You are allowed to make changes to the HTML and CSS. + */ + /** + * Problem 1: Alert Me + * When the clicks on the button that says "Alert Me!", it should display an alert. + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/alert + */ + + // Step 1 Target + const alertButton = document.querySelector("#alertMe"); + + // Step 2 React to the event + alertButton.addEventListener("click", () => { + // Step 3 Do something + // The thing that happens after the event occurs + alert("Alert Me!"); + }); + + /** + * Problem 2: Disable a button that will charge a credit card. + * + * To prevent users from charging the credit card more than once: + * 1. Disable the button when it is clicked. + * 2. Change the text to say e.g. "Loading ..." once it is clicked. + */ + + // Step 1 Target + const chargeButton = document.querySelector("#chargeCreditCard"); + chargeButton.type = "submit"; + + // Step 2 React to an event + const reactToCharge = () => { + // Step 3 Do something - disable the button and change the test to say loading + chargeButton.disabled = "disabled"; + chargeButton.textContent = "Loading ..."; + }; + chargeButton.addEventListener("click", reactToCharge); +})(); From 4dbc62c1dc8f280b10a4ba93e3712350f467320b Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 3 Dec 2022 12:35:08 -0500 Subject: [PATCH 084/105] Toggle events exercise --- exercises/20-toggle-events/toggle-events.html | 110 ++++++++++++++++++ exercises/20-toggle-events/toggle-events.js | 26 +++++ 2 files changed, 136 insertions(+) create mode 100644 exercises/20-toggle-events/toggle-events.html create mode 100644 exercises/20-toggle-events/toggle-events.js diff --git a/exercises/20-toggle-events/toggle-events.html b/exercises/20-toggle-events/toggle-events.html new file mode 100644 index 0000000..e7fb0c7 --- /dev/null +++ b/exercises/20-toggle-events/toggle-events.html @@ -0,0 +1,110 @@ + + + + + + + EXERCISES Events + + + + + + + + + + + + +
      +
      +

      + We use cookies to give you the best online experience, measure your + visits to our sites and to enable marketing activities (including with + our marketing partners). +

      + +
      +
      + +
      +
      +

      + Icy Road Conditions Lead To Multi-Deer Pileup On Highway +

      +

      + Source: + The Onion +

      +
      + Multi-Deer Pileup +
      +

      Highway I-87 is now closed.

      + + +

      + + + +
      +
      + + diff --git a/exercises/20-toggle-events/toggle-events.js b/exercises/20-toggle-events/toggle-events.js new file mode 100644 index 0000000..a4ab841 --- /dev/null +++ b/exercises/20-toggle-events/toggle-events.js @@ -0,0 +1,26 @@ +(function () { + /** + * Problem 1: Dismiss the "Accept Cookies" popup + * + * When the user clicks on the "Accept Cookies" button, the "Accept Cookies" popup should disappear. + */ + // Write your answer here + /** + * Problem 2: Show comments for the news story. + * + * You will need modify the HTML so that you can target HTML elements o the page. + * + * You will be toggling the comments on the page. + * If the comments are hidden, this should happen when the user clicks on the "View Comments" button: + * 1. The comment section should appear + * 2. The "View Comments" button will change to say "Hide Comments" + * + * If the comments are visible, this should happen when the user clicks on the "Hide Comments" button: + * 1. The comments sections should disappear + * 2. The "Hide Comments" button should change to say "View Comments" + * + * HINT: Right now, the comments are hidden because they have the class ".hidden", + * but you can switch up the HTML so that it uses inline styles if you like. + */ + // Write your answer here +})(); From 2473a307cdb88e31fad028d1da85121e99961fc4 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Thu, 8 Dec 2022 08:41:39 -0500 Subject: [PATCH 085/105] Problems 20 --- exercises/20-toggle-events/toggle-events.html | 8 +++++-- exercises/20-toggle-events/toggle-events.js | 22 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/exercises/20-toggle-events/toggle-events.html b/exercises/20-toggle-events/toggle-events.html index e7fb0c7..e2c8eeb 100644 --- a/exercises/20-toggle-events/toggle-events.html +++ b/exercises/20-toggle-events/toggle-events.html @@ -86,10 +86,14 @@

      Highway I-87 is now closed.

      -

      +

      + +

      -

      lX=DJL@E{Mk0>$m>NTRgxQDL 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 literal 0 HcmV?d00001 diff --git a/projects/hangman/word-bank.js b/projects/hangman/word-bank.js new file mode 100644 index 0000000..692a70a --- /dev/null +++ b/projects/hangman/word-bank.js @@ -0,0 +1 @@ +export default ["rumor","happen","match","sail","sick","floor","summit","shadow","census","chorus","launch","abbey","eject","resist","guilt","repeat","drama","easy","morsel","swipe","equip","reader","pray","grave","cord","cheek","figure","rebel","native","rack","fade","basket","reform","hall","area","root","breeze","shift","cane","cash","hour","galaxy","breed","straw","offset","speech","appear","porter","mosque","flush","sheet","whip","finger","suite","glare","base","catch","cheque","critic","circle","block","talk","salad","bronze","occupy","morale","policy","weak","narrow","essay","Koran","direct","aware","worth","choose","outer","stamp","agile","weave","case","lift","shell","liver","safari","linear","star","makeup","snack","snow","cope","fault","alive","ideal","foot","reduce","solid","inch","arise","master","sigh","shelf","brake","admire","leader","tooth","bitch","coach","dare","beam","sell","change","broken","edge","absorb","side","basin","mess","crown","effort","burst","series","upset","beard","lane","palm","wing","torch","heaven","young","stand","polish","pardon","mouth","sphere","charge","grace","back","writer","bridge","even","rent","endure","story","remain","gloom","exile","need","revise","punch","future","date","forest","crash","bald","coup","coma","soak","joint","begin","screen","apple","weight","yard","order","sermon","bird","pity","efflux","mirror","stroll","menu","tube","guest","terms","reveal","long","scrap","rough","lake","score","summer","orbit","seem","wonder","bold","thumb","attack","coffin","sketch","form","tumble","half","member","bacon","rush","castle","poison","mail","steam","core","snail","seller","invite","disk","ready","refer","indoor","kill","weapon","haunt","TRUE","slice","fame","extent","knife","party","margin","tray","number","medal","bottle","throw","cafe","driver","source","cook","frank","absent","unique","bland","jury","sofa","bundle","brag","clock","debut","nuance","aisle","stroke","wrap","real","wound","slump","friend","kick","powder","crouch","chord","shine","smile","garage","nerve","mayor","depart","lock","oral","close","choke","virtue","tiger","honor","soft","stable","final","pour","snake","prize","damage","donor","land","boat","patrol","light","park","ring","revoke","field","method","widen","chance","revive","tile","watch","pillow","waist","spit","spirit","host","dinner","dine","gown","slip","give","still","item","hurl","cancer","guitar","silk","moving","fence","yearn","oppose","rank","goal","lawyer","turn","rear","hole","asylum","plant","output","detail","soar","entry","full","swim","flex","draw","horn","curl","herd","rock","plan","zone","groan","money","adopt","eaux","space","danger","tract","racism","month","stream","sample","knot","outfit","decide","fair","runner","pain","brown","skate","dome","minor","text","wander","heel","lemon","find","braid","gold","design","seal","title","abuse","bake","king","mile","wine","voice","steep","take","club","jockey","seize","hold","center","filter","shower","blue","bread","enemy","lean","dress","gravel","know","jacket","navy","tone","exact","arch","stake","last","slap","spell","stitch","jest","tiptoe","grain","deck","fire","tired","fight","common","soil","wild","shiver","bill","bishop","dawn","rice","bulb","free","dream","excuse","credit","miss","muscle","offend","fine","chew","cousin","dull","acid","rifle","crew","Venus","truck","remind","trace","effect","stun","debate","glory","crowd","slam","barrel","grief","store","chin","mercy","wall","pawn","debt","layout","video","stem","copy","belief","sweep","appeal","army","hike","asset","brave","list","thread","decade","noble","polite","pile","frame","fate","grip","virus","pure","tidy","sodium","harbor","thigh","public","view","taxi","bait","riot","ridge","tongue","utter","build","funny","scene","trip","movie","scan","ritual","planet","sale","fare","option","just","study","note","tycoon","please","survey","ankle","double","poem","enjoy","useful","drug","theft","horse","pack","instal","fear","quota","bowel","cover","rape","arena","split","elite","allow","wake","grind","doll","crime","cruel","remark","ditch","insure","clue","favor","topple","move","memory","seed","chaos","X-ray","follow","swear","greet","tactic","column","style","smash","lend","tail","coffee","press","wire","lead","bench","belt","penny","obese","taste","poll","quote","expand","mask","golf","ignite","worm","dragon","tasty","sticky","ivory","spoil","strike","pepper","pilot","iron","gene","reach","sight","bother","twin","heat","file","jelly","angle","desire","amber","neck","vain","float","boom","sting","winter","facade","equal","dozen","valley","tell","want","fairy","carry","bite","string","size","jump","ride","reward","site","teach","help","ignore","gaffe","diet","rate","animal","camera","marble","jail","novel","horror","herb","banner","remedy","mold","desk","aspect","lung","hero","course","fleet","angel","bring","banana","script","room","answer","award","tread","impact","formal","solve","pump","scream","nature","theme","tumour","sweat","ferry","idea","trust","visual","feast","misery","loose","kidnap","lobby","relate","peace","onion","exempt","count","branch","test","harass","bolt","flag","brand","panel","drown","bless","mark","layer","volume","player","dash","prince","locate","cotton","zero","lunch","mature","bind","care","late","deputy","rider","drop","basic","ticket","wait","deep","storm","short","wear","banish","robot","make","earwax","review","sleeve","thesis","black","bell","clear","flock","mind","colony","market","loss","heroin","patent","love","snub","prison","refund","petty","part","card","issue","drain","deadly","tempt","frown","goat","term","drag","vote","east","turkey","flow","lamb","cycle","buffet","prove","moment","show","wage","cower","hammer","heavy","spin","drawer","panic","salt","inside","pull","shrink","shorts","senior","square","lily","meet","dairy","hand","canvas","hell","poor","embryo","meal","year","budget","viable","notice","marsh","punish","shame","rung","wrist","nose","escape","elect","shave","smoke","fill","train","lost","cheap","shop","mutter","fibre","faint","vague","arrest","stool","thaw","colon","high","family","injury","work","enfix","Bible","fruit","person","crisis","pick","stock","bond","urge","fresh","pride","fail","jewel","bloody","virgin","chalk","axis","ballet","laser","extend","desert","cheat","marine","slab","preach","front","ladder","toast","safety","feel","woman","muggy","rise","skip","echo","stage","chest","flight","tease","kidney","forbid","brick","origin","prey","color","draft","team","cheese","agree","junior","carpet","maze","city","shot","suffer","lace","cinema","basis","pastel","large","acquit","afford","organ","hair","power","chase","merit","elbow","energy","place","velvet","exotic","growth","proud","thin","pair","fish","lodge","thank","labour","slime","gain","belly","garlic","climb","latest","time","eagle","wife","pause","chop","kettle","green","album","swell","matrix","rich","wood","sink","spring","worry","tick","voter","fist","plead","relief","slant","bike","brush","fever","door","cable","profit","glass","path","dead","corpse","creed","bang","scrape","minute","thick","jungle","moral","bride","handy","giant","death","start","Sunday","squash","tune","clean","gossip","chain","sacred","father","salmon","tense","halt","gutter","middle"]; \ No newline at end of file From d82218eddde9d457e9b9a30bd9e2d39f46058ed6 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sat, 5 Nov 2022 17:23:34 -0400 Subject: [PATCH 061/105] Callback exercises --- .vscode/launch.json | 13 ++++++ exercises/15-callbacks/01-calculate.js | 30 ++++++++++++++ exercises/15-callbacks/02-print-names.js | 46 +++++++++++++++++++++ exercises/15-callbacks/03-find-first.js | 31 ++++++++++++++ test/15-callbacks/callbacks.spec.js | 52 ++++++++++++++++++++++++ 5 files changed, 172 insertions(+) create mode 100644 exercises/15-callbacks/01-calculate.js create mode 100644 exercises/15-callbacks/02-print-names.js create mode 100644 exercises/15-callbacks/03-find-first.js create mode 100644 test/15-callbacks/callbacks.spec.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 784f236..f728546 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -186,5 +186,18 @@ ], "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "15. Callbacks", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/test/15-callbacks/callbacks.spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + }, ] } diff --git a/exercises/15-callbacks/01-calculate.js b/exercises/15-callbacks/01-calculate.js new file mode 100644 index 0000000..a920528 --- /dev/null +++ b/exercises/15-callbacks/01-calculate.js @@ -0,0 +1,30 @@ +/** + * Perform a calculation on numbers. + * @param {number} num1 number + * @param {number} num2 number + * @param {function} callback that performs an operation on two numbers + * @returns {number} that is the result of a callback + * + * callback + * @param {number} num1 number + * @param {number} num2 number + * @returns {number} that is the result of a calculation like add or subtract + * + * @example + * const add = (a, b) => { + * return a + b; + * } + * const subtract = (a, b) => { + * return a - b; + * } + * console.log( calculate(5, 10, add) ); // 15 + * console.log( calculate(7, 3, subtract) ); // 4 + */ + +const calculate = (num1, num2, callback) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export { calculate }; diff --git a/exercises/15-callbacks/02-print-names.js b/exercises/15-callbacks/02-print-names.js new file mode 100644 index 0000000..3712d8b --- /dev/null +++ b/exercises/15-callbacks/02-print-names.js @@ -0,0 +1,46 @@ +/** + * This is a question with two parts. + * + * PART 1 + * Create a function called "printer". + * Given a student name, it should format and prints out the value in a visually appealing way + * (e.g. with hyphens or asterisks before each value) with `console.log` + * slide + * @example + * - Jamal + * - Matina + * @param {string} name instructor name + */ + +// WRITE PART 1 OF YOUR ANSWER HERE + +/** + * PART 2 + * NOTE that the test will use the "printer" function that you completed in the problem above. + * Loop through the array of strings. + * For each name, calls upon the function "printer" to print out the name + * @param {array} + * @param {function} callback printer function + * + * @example + * printNames(["Jamal", "Matina"], printer); + * // - Jamal + * // - Matina + */ +const printNames = (array, callback) => { + // WRITE PART 2 OF YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +const myExports = { + printer: undefined, + printNames, +}; +try { + //eslint-disable-next-line no-undef + if (printer) myExports.printer = printer; + // eslint-disable-next-line no-undef +} catch (e) {} + +export default myExports; diff --git a/exercises/15-callbacks/03-find-first.js b/exercises/15-callbacks/03-find-first.js new file mode 100644 index 0000000..7efc43b --- /dev/null +++ b/exercises/15-callbacks/03-find-first.js @@ -0,0 +1,31 @@ +/** + * Returns the first number in an array that meets a condition. + * @param {array} arrayOfNum e.g. [3,4, 20, 333] + * @param {function} callback that receives a number and returns true or false + * @returns {number} in the array that is the result of the callback + * + * callback + * @param {number} num an item in an array + * @returns {boolean} if a number meets a condition + * + * @example + * const isNumberEven = (num) => { + * if (num % 2 === 0) return true; + * else return false; + * }; + * const isNumberTwoDigits = (num) => { + * if (`${num}`.length === 2) { + * return true; + * } else return false; + * }; + * console.log( findFirst([1, 3, 7, 8, 20], isNumberEven) ) // 8 + * console.log( findFirst([4, 500, 30, 2], isNumberTwoDigits) ) // 30 + */ + +const findFirst = (arrayOfNum, callback) => { + // WRITE YOUR ANSWER HERE +}; + +// IGNORE THIS BELOW. It is for the tests. + +export { findFirst }; diff --git a/test/15-callbacks/callbacks.spec.js b/test/15-callbacks/callbacks.spec.js new file mode 100644 index 0000000..2d10b72 --- /dev/null +++ b/test/15-callbacks/callbacks.spec.js @@ -0,0 +1,52 @@ +import { expect } from "chai"; +import sinon from "sinon"; + +import { calculate } from "../../exercises/15-callbacks/01-calculate.js"; +import { findFirst } from "../../exercises/15-callbacks/03-find-first.js"; + +import printerFn from "../../exercises/15-callbacks/02-print-names.js"; +const { printer, printNames } = printerFn; + +describe("10. Callbacks", () => { + describe("01-calculate", () => { + it("should use the callback", () => { + const funcStr = calculate.toString(); + const matches = funcStr.match(/callback/g) || []; + expect(matches.length).to.be.above(1); + }); + it("should return the result of a callback invoked on two numbers", () => { + const multiply = (a, b) => { + return a * b; + }; + const result = calculate(5, 10, multiply); + expect(result).to.equal(50); + }); + }); + describe("02-print-names", () => { + it("should call on a callback for each item in an array", () => { + const callback = sinon.spy(); + printNames(["test", "test1", "test3"], callback); + expect(callback.calledThrice).to.equal(true); + }); + it('should `console.log` a name when the callback is the "printer" function', () => { + expect(printer).to.be.a("function"); + expect(printer.toString()).to.include("console.log"); + printNames(["Jamal", "Matina"], printer); + }); + }); + describe("03-find-first", () => { + it("should use the callback", () => { + const funcStr = findFirst.toString(); + const matches = funcStr.match(/callback/g) || []; + expect(matches.length).to.be.above(1); + }); + it("should find the first number in an array that, when passed as an argument into a callback, returns true", () => { + const isNumberDivisibleByThree = (num) => { + if (num % 3 === 0) return true; + else return false; + }; + const result = findFirst([1, 3, 7, 8, 20], isNumberDivisibleByThree); + expect(result).to.equal(3); + }); + }); +}); From 64a0cd3ce9afbb1281a62004c5c4983b33cce5c9 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 16 Nov 2022 19:08:16 -0500 Subject: [PATCH 062/105] Problem 15-01 --- exercises/15-callbacks/01-calculate.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/exercises/15-callbacks/01-calculate.js b/exercises/15-callbacks/01-calculate.js index a920528..9e14b34 100644 --- a/exercises/15-callbacks/01-calculate.js +++ b/exercises/15-callbacks/01-calculate.js @@ -23,8 +23,19 @@ const calculate = (num1, num2, callback) => { // WRITE YOUR ANSWER HERE + return callback(num1, num2); }; +const divide = (num1, num2) => { + return num1 / num2; +}; + +const multiply = (num1, num2) => { + return num1 * num2; +}; + +console.log(calculate(10, 3, divide)); +console.log(calculate(500, 100, multiply)); // IGNORE THIS BELOW. It is for the tests. export { calculate }; From cb164d5583076b9010b83b179b345497283dd252 Mon Sep 17 00:00:00 2001 From: pmermod <93401090+pmermod@users.noreply.github.com> Date: Wed, 16 Nov 2022 20:36:29 -0500 Subject: [PATCH 063/105] Problems 15 - initial work --- exercises/15-callbacks/02-print-names.js | 5 +++++ exercises/15-callbacks/03-find-first.js | 3 +++ 2 files changed, 8 insertions(+) diff --git a/exercises/15-callbacks/02-print-names.js b/exercises/15-callbacks/02-print-names.js index 3712d8b..a8b396e 100644 --- a/exercises/15-callbacks/02-print-names.js +++ b/exercises/15-callbacks/02-print-names.js @@ -13,6 +13,9 @@ */ // WRITE PART 1 OF YOUR ANSWER HERE +const printer = (name) => { + console.log("**" + name); +}; /** * PART 2 @@ -29,6 +32,8 @@ */ const printNames = (array, callback) => { // WRITE PART 2 OF YOUR ANSWER HERE + for (let item of array); + printer(item); }; // IGNORE THIS BELOW. It is for the tests. diff --git a/exercises/15-callbacks/03-find-first.js b/exercises/15-callbacks/03-find-first.js index 7efc43b..13d4ff8 100644 --- a/exercises/15-callbacks/03-find-first.js +++ b/exercises/15-callbacks/03-find-first.js @@ -24,6 +24,9 @@ const findFirst = (arrayOfNum, callback) => { // WRITE YOUR ANSWER HERE + for (let value of arrayOfNum) { + console.log(value); + } }; // IGNORE THIS BELOW. It is for the tests. From 4b06aaed796f65d2c7d4d052122ec3c4f2e5180a Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Wed, 16 Nov 2022 20:05:02 -0500 Subject: [PATCH 064/105] Callback solutions --- .../15-callbacks/01-calculate.solution.js | 31 +++++++++++ .../15-callbacks/02-print-names.solution.js | 52 +++++++++++++++++++ .../15-callbacks/03-find-first.solution.js | 41 +++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 solutions/15-callbacks/01-calculate.solution.js create mode 100644 solutions/15-callbacks/02-print-names.solution.js create mode 100644 solutions/15-callbacks/03-find-first.solution.js diff --git a/solutions/15-callbacks/01-calculate.solution.js b/solutions/15-callbacks/01-calculate.solution.js new file mode 100644 index 0000000..8b7ef08 --- /dev/null +++ b/solutions/15-callbacks/01-calculate.solution.js @@ -0,0 +1,31 @@ +/** + * Perform a calculation on a number. + * @param {number} num1 number + * @param {number} num2 number + * @param {function} callback that performs an operation on two numbers + * @returns {number} that is the result of a callback + * + * callback + * @param {number} num1 number + * @param {number} num2 number + * @returns {number} that is the result of a calculation like add or subtract + * + * @example + * const add = (a, b) => { + * return a + b; + * } + * const subtract = (a, b) => { + * return a - b; + * } + * console.log( calculate(5, 10, add) ); // 15 + * console.log( calculate(7, 3, subtract) ); // 4 + */ + +const calculate = (num1, num2, callback) => { + // WRITE YOUR ANSWER HERE + return callback(num1, num2); +}; + +// IGNORE THIS BELOW. It is for the tests. + +export { calculate }; diff --git a/solutions/15-callbacks/02-print-names.solution.js b/solutions/15-callbacks/02-print-names.solution.js new file mode 100644 index 0000000..74e78c2 --- /dev/null +++ b/solutions/15-callbacks/02-print-names.solution.js @@ -0,0 +1,52 @@ +/** + * This is a question with two parts. + * + * PART 1 + * Create a function called "printer". + * Given a student name, it should format and prints out the value in a visually appealing way + * (e.g. with hyphens or asterisks before each value) with `console.log` + * slide + * @example + * - Jamal + * - Matina + * @param {string} name instructor name + */ + +// WRITE PART 1 OF YOUR ANSWER HERE +const printer = (name) => { + console.log(`- ${name}\n`); +}; + +/** + * PART 2 + * NOTE that the test will use the "printer" function that you completed in the problem above. + * Loop through the array of strings. + * For each name, calls upon the function "printer" to print out the name + * @param {array} + * @param {function} callback printer function + * + * @example + * printNames(["Jamal", "Matina"], printer); + * // - Jamal + * // - Matina + */ +const printNames = (array, callback) => { + // WRITE PART 2 OF YOUR ANSWER HERE + for (let item of array) { + callback(item); + } +}; + +// IGNORE THIS BELOW. It is for the tests. + +const myExports = { + printer: undefined, + printNames, +}; +try { + //eslint-disable-next-line no-undef + if (printer) myExports.printer = printer; + // eslint-disable-next-line no-undef +} catch (e) {} + +export default myExports; diff --git a/solutions/15-callbacks/03-find-first.solution.js b/solutions/15-callbacks/03-find-first.solution.js new file mode 100644 index 0000000..2374b1c --- /dev/null +++ b/solutions/15-callbacks/03-find-first.solution.js @@ -0,0 +1,41 @@ +/** + * Returns the first number in an array that meets a condition. + * @param {array} arrayOfNum e.g. [3,4, 20, 333] + * @param {function} callback that receives a number and returns true or false + * @returns {number} in the array that is the result of the callback + * + * callback + * @param {number} num an item in an array + * @returns {boolean} if a number meets a condition + * + * @example + * const isNumberEven = (num) => { + * if (num % 2 === 0) return true; + * else return false; + * }; + * const isNumberTwoDigits = (num) => { + * if (`${num}`.length === 2) { + * return true; + * } else return false; + * }; + * console.log( findFirst([1, 3, 7, 8, 20], isNumberEven) ) // 8 + * console.log( findFirst([4, 500, 30, 2], isNumberTwoDigits) ) // 30 + */ + +const findFirst = (arrayOfNum, callback) => { + // WRITE YOUR ANSWER HERE + + // Solution 1: for loop + for (let i = 0; i < arrayOfNum.length; i++) { + if (callback(arrayOfNum[i])) return arrayOfNum[i]; + } + + // Solution 2: for ... of loop + for (let num of arrayOfNum) { + if (callback(num)) return num; + } +}; + +// IGNORE THIS BELOW. It is for the tests. + +export { findFirst }; From 14f703ecdaafa46f169ee5d0a89818268568c6e9 Mon Sep 17 00:00:00 2001 From: matinaspatsos Date: Sun, 20 Nov 2022 19:07:09 -0500 Subject: [PATCH 065/105] More callback exercises --- exercises/15-callbacks/04-link-or-button.js | 32 +++++++++++++++++ exercises/15-callbacks/05-send-email.js | 23 ++++++++++++ test/15-callbacks/callback-test-helper.js | 20 +++++++++++ test/15-callbacks/callbacks.spec.js | 40 +++++++++++++++++++-- 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 exercises/15-callbacks/04-link-or-button.js create mode 100644 exercises/15-callbacks/05-send-email.js create mode 100644 test/15-callbacks/callback-test-helper.js diff --git a/exercises/15-callbacks/04-link-or-button.js b/exercises/15-callbacks/04-link-or-button.js new file mode 100644 index 0000000..79d2642 --- /dev/null +++ b/exercises/15-callbacks/04-link-or-button.js @@ -0,0 +1,32 @@ +// E.g. do not change me +const createLink = (text) => { + return `${text}`; +}; + +// E.g. do not change me +const createButton = (text) => { + return ``; +}; + +/** + * Update the createCallToAction so that it can either: + * 1. Use createLink + * 2. Use createButton + * + * You must use a callback to solve this problem. + */ + +const createCallToAction = (clickableText) => { + return ( + "