diff --git a/.vscode/launch.json b/.vscode/launch.json index 8649ba4..22494b0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -30,5 +30,187 @@ ], "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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" + }, + { + "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/README.md b/README.md index cbc895d..a0fcdae 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,10 @@ Whenever you are ready to submit your work, you will need to [commit your work, ## Resources +- Projects: [First Project: Hangman](projects/hangman/ProjectHangman.md) | [Final Project: Document Object Model](projects/final-project/FinalProject.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) - 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) 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 diff --git a/examples/xss/README.md b/examples/xss/README.md new file mode 100644 index 0000000..fff9416 --- /dev/null +++ b/examples/xss/README.md @@ -0,0 +1,15 @@ +# Cross-Site Scripting (XSS) Vulnerability Example + +This is an example of code that is vulnerable to a [Cross-Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/) attack. + +Open _examples\xss\xss.html_ inside of Chrome, Firefox, Safari, Edge or another web browser. To replicate a XSS vulnerability, insert some HTML with an inline event. The inline event should contain some Javascript that triggers some kind of an attack. Then click on the "Submit" button below. + +Here is an example of code that code be used within a client-side XSS attack. + +``` + +``` + +``` + +``` diff --git a/examples/xss/xss.html b/examples/xss/xss.html new file mode 100644 index 0000000..e623400 --- /dev/null +++ b/examples/xss/xss.html @@ -0,0 +1,57 @@ + + + + My title + + + + + +
+

Please read the README.md

+
+
+ + +
+ Display Text + +
+
+
+ + +
+ +
+
+
+
+
+ + + + diff --git a/exercises/00-git/IntroductionGit.md b/exercises/00-git/IntroductionGit.md index 8b1312e..446fca7 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 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..b9b1a56 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); diff --git a/exercises/02-numbers/01-add.js b/exercises/02-numbers/01-add.js new file mode 100644 index 0000000..461346d --- /dev/null +++ b/exercises/02-numbers/01-add.js @@ -0,0 +1,7 @@ +/** + * 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 = 10 + 6; diff --git a/exercises/02-numbers/02-subtract.js b/exercises/02-numbers/02-subtract.js new file mode 100644 index 0000000..c7cfcd0 --- /dev/null +++ b/exercises/02-numbers/02-subtract.js @@ -0,0 +1,10 @@ +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/exercises/02-numbers/03-multiply-and-divide.js b/exercises/02-numbers/03-multiply-and-divide.js new file mode 100644 index 0000000..9b45bde --- /dev/null +++ b/exercises/02-numbers/03-multiply-and-divide.js @@ -0,0 +1,9 @@ +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 = (60 - 40) / ONE_HUNDRED; diff --git a/exercises/02-numbers/04-increment.js b/exercises/02-numbers/04-increment.js new file mode 100644 index 0000000..7064fe5 --- /dev/null +++ b/exercises/02-numbers/04-increment.js @@ -0,0 +1,10 @@ +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/exercises/02-numbers/05-decrement.js b/exercises/02-numbers/05-decrement.js new file mode 100644 index 0000000..9d1ea9f --- /dev/null +++ b/exercises/02-numbers/05-decrement.js @@ -0,0 +1,10 @@ +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/exercises/02-numbers/06-order-of-operations.js b/exercises/02-numbers/06-order-of-operations.js new file mode 100644 index 0000000..32f398c --- /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..191d3eb --- /dev/null +++ b/exercises/02-numbers/07-calcuator.html @@ -0,0 +1,59 @@ + + + + + + + + EXERCISE + + + + +
+ + + + + = + 0 +
+ + + 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..f99aaf3 --- /dev/null +++ b/exercises/03-strings/01-create-a-string.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 = "Hal"; 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..936e5de --- /dev/null +++ b/exercises/03-strings/02-get-the-character-position.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 = 1; diff --git a/exercises/03-strings/03-string-length.js b/exercises/03-strings/03-string-length.js new file mode 100644 index 0000000..4b201ae --- /dev/null +++ b/exercises/03-strings/03-string-length.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 + +let strLength = str.length; 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..89b862f --- /dev/null +++ b/exercises/03-strings/04-get-last-character.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/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..81aa39b --- /dev/null +++ b/exercises/03-strings/05-get-last-word-in-place-name.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); 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..beb9dcc --- /dev/null +++ b/exercises/04-combine-strings/01-concatenate-operator.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; +console.log(bookInfo); 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..7ad5f38 --- /dev/null +++ b/exercises/04-combine-strings/02-template-literals.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}`; +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 new file mode 100644 index 0000000..2d39528 --- /dev/null +++ b/exercises/04-combine-strings/03-replace-last-name.js @@ -0,0 +1,39 @@ +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 + +//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; //This is same as above but adds a space +console.log(fullName); 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..6e4c31e --- /dev/null +++ b/exercises/04-combine-strings/04-combine-text.html @@ -0,0 +1,56 @@ + + + + + + + + EXERCISE + + + +
+
+ + +
+
+ + +
+ +
+ + + 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..f24ce47 --- /dev/null +++ b/exercises/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); +console.log(answer); 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..59d5875 --- /dev/null +++ b/exercises/05-coercion/02-fix-coercion-error.js @@ -0,0 +1,14 @@ +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; +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 new file mode 100644 index 0000000..13d930d --- /dev/null +++ b/exercises/05-coercion/03-fix-coercion-input.html @@ -0,0 +1,60 @@ + + + + + + + + EXERCISE + + + + +
+ + + + + = + 0 +
+ + + 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..736b0d6 --- /dev/null +++ b/exercises/06-control-flow/01-if-statement.js @@ -0,0 +1,22 @@ +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 += drink; +} 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..38cc641 --- /dev/null +++ b/exercises/06-control-flow/02-if-statement.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; + +console.log(total); 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..a6a83b7 --- /dev/null +++ b/exercises/06-control-flow/03-if-statement.html @@ -0,0 +1,90 @@ + + + + + + + + EXERCISE + + + + +
+

+
+ + + + + +
+ +
+ + + diff --git a/exercises/07-comparisons/01-is-equal.js b/exercises/07-comparisons/01-is-equal.js new file mode 100644 index 0000000..8f870f5 --- /dev/null +++ b/exercises/07-comparisons/01-is-equal.js @@ -0,0 +1,17 @@ +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 +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 new file mode 100644 index 0000000..12fcb4b --- /dev/null +++ b/exercises/07-comparisons/02-is-not-equal.js @@ -0,0 +1,18 @@ +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 +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 new file mode 100644 index 0000000..d0fd502 --- /dev/null +++ b/exercises/07-comparisons/03-is-larger-number.js @@ -0,0 +1,21 @@ +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 +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 new file mode 100644 index 0000000..d0c6e2e --- /dev/null +++ b/exercises/07-comparisons/04-is-teenager.js @@ -0,0 +1,16 @@ +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 +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 new file mode 100644 index 0000000..c6c85a4 --- /dev/null +++ b/exercises/07-comparisons/05-is-weekend.js @@ -0,0 +1,18 @@ +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 +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 new file mode 100644 index 0000000..d268b06 --- /dev/null +++ b/exercises/07-comparisons/06-is-even.js @@ -0,0 +1,18 @@ +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 +let isEven; +let test = num % 2; +if (test === 0) { + isEven = true; +} else { + isEven = false; +} +console.log(isEven); diff --git a/exercises/08-functions/01-invoke-function.js b/exercises/08-functions/01-invoke-function.js new file mode 100644 index 0000000..6994330 --- /dev/null +++ b/exercises/08-functions/01-invoke-function.js @@ -0,0 +1,19 @@ +/** + * @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 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 new file mode 100644 index 0000000..1f2058e --- /dev/null +++ b/exercises/08-functions/02-print-greeting.js @@ -0,0 +1,18 @@ +/** + * 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}!`); +}; + +printGreeting("Matina"); diff --git a/exercises/08-functions/03-return-greeting.js b/exercises/08-functions/03-return-greeting.js new file mode 100644 index 0000000..bae4813 --- /dev/null +++ b/exercises/08-functions/03-return-greeting.js @@ -0,0 +1,22 @@ +/** + * 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}!`; +}; + +let result = returnGreeting("Jamal"); +console.log(result); diff --git a/exercises/08-functions/04-multiply.js b/exercises/08-functions/04-multiply.js new file mode 100644 index 0000000..db74305 --- /dev/null +++ b/exercises/08-functions/04-multiply.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; +}; +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 new file mode 100644 index 0000000..c9e086e --- /dev/null +++ b/exercises/08-functions/05-lower-case-string.js @@ -0,0 +1,29 @@ +/** + * 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 = (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 new file mode 100644 index 0000000..b00bd78 --- /dev/null +++ b/exercises/08-functions/06-is-even-or-odd.js @@ -0,0 +1,22 @@ +/** + * 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 = (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 new file mode 100644 index 0000000..e96aa87 --- /dev/null +++ b/exercises/08-functions/07-count-number-of-digits.js @@ -0,0 +1,19 @@ +/** + * 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 = (int) => { + return int.toString().length; +}; + +console.log(countNumberOfDigits(12401)); +console.log(countNumberOfDigits(-999999999)); 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..6813fb4 --- /dev/null +++ b/exercises/09-arrays/01-create-an-array.js @@ -0,0 +1,9 @@ +/** + * 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 +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 new file mode 100644 index 0000000..1fd7cb2 --- /dev/null +++ b/exercises/09-arrays/02-accessing-item-in-array.js @@ -0,0 +1,13 @@ +const cars = ["BMW", "Honda", "Civic"]; // Do not change this line + +/** + * 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[0]; + +console.log(myCar); diff --git a/exercises/09-arrays/03-destructuring.js b/exercises/09-arrays/03-destructuring.js new file mode 100644 index 0000000..8873af4 --- /dev/null +++ b/exercises/09-arrays/03-destructuring.js @@ -0,0 +1,14 @@ +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 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 +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 new file mode 100644 index 0000000..0c6f0c9 --- /dev/null +++ b/exercises/09-arrays/04-position-in-array.js @@ -0,0 +1,24 @@ +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 +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 new file mode 100644 index 0000000..41d6a7a --- /dev/null +++ b/exercises/09-arrays/05-add-item-to-array.js @@ -0,0 +1,9 @@ +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("Java", "GoLang", "Python"); +console.log(languages); diff --git a/exercises/09-arrays/06-combine-arrays-.js b/exercises/09-arrays/06-combine-arrays-.js new file mode 100644 index 0000000..e41ba4a --- /dev/null +++ b/exercises/09-arrays/06-combine-arrays-.js @@ -0,0 +1,12 @@ +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 +let newArray = [...array1, ...array2]; +console.log(newArray); 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..699476c --- /dev/null +++ b/exercises/10-loops/00-solving-problems-with-functions.js @@ -0,0 +1,16 @@ +/** + * 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 + return personName; +}; + +// 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..bece634 --- /dev/null +++ b/exercises/10-loops/01-array-length.js @@ -0,0 +1,16 @@ +/** + * 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 + return array.length; +}; + +// 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..afc90cc --- /dev/null +++ b/exercises/10-loops/02-while-loop.js @@ -0,0 +1,32 @@ +/** + * 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 + 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 new file mode 100644 index 0000000..bd54aee --- /dev/null +++ b/exercises/10-loops/03-for-loop.js @@ -0,0 +1,25 @@ +/** + * 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); + } +}; +logArrayWithFor(["Honda", "Ford", "Ferrari"]); + +// IGNORE THIS BELOW. It is for the tests. + +export default logArrayWithFor; diff --git a/exercises/10-loops/04-loops.html b/exercises/10-loops/04-loops.html new file mode 100755 index 0000000..c5c2fca --- /dev/null +++ b/exercises/10-loops/04-loops.html @@ -0,0 +1,79 @@ + + + + + + + + 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..d8a5ea8 --- /dev/null +++ b/exercises/10-loops/05-add-an-array.js @@ -0,0 +1,24 @@ +/** + * 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 + + //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. + +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..52db502 --- /dev/null +++ b/exercises/10-loops/06-highest-number.js @@ -0,0 +1,31 @@ +/** + * 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 + + // 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] > highNum) { + highNum = numbers[i]; + } + } + return highNum; +}; + +console.log(highestNumber([30, 690, -242, 683])); + +// 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..b431631 --- /dev/null +++ b/exercises/10-loops/07-is-palidrome.js @@ -0,0 +1,25 @@ +/** + * 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 + + let stringReversed = string.split("").reverse().join(""); + + if (string === stringReversed) { + return true; + } else return false; +}; +isPalindrome("kayak"); +console.log(isPalindrome("kayak")); + +// IGNORE THIS BELOW. It is for the tests. + +export default isPalindrome; diff --git a/exercises/11-objects/01-create-object.js b/exercises/11-objects/01-create-object.js new file mode 100644 index 0000000..945db6a --- /dev/null +++ b/exercises/11-objects/01-create-object.js @@ -0,0 +1,18 @@ +/** + * 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: "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 new file mode 100644 index 0000000..63ccf94 --- /dev/null +++ b/exercises/11-objects/02-create-nested-object.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 +let graduate = { + name, + graduationYear, + skills, + links: { + 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 new file mode 100644 index 0000000..4096c18 --- /dev/null +++ b/exercises/11-objects/03-accessing-item-in-object.js @@ -0,0 +1,17 @@ +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"]; + +console.log(hat); diff --git a/exercises/11-objects/04-update-object.js b/exercises/11-objects/04-update-object.js new file mode 100644 index 0000000..f4511a2 --- /dev/null +++ b/exercises/11-objects/04-update-object.js @@ -0,0 +1,21 @@ +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 = "Hal Katzman"; +student.skills.push("HTML"); + +console.log(student); 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..89027f5 --- /dev/null +++ b/exercises/11-objects/05-return-object-values.js @@ -0,0 +1,35 @@ +/** + * 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 + 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. + +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..e07b6d9 --- /dev/null +++ b/exercises/11-objects/06-combine-object.js @@ -0,0 +1,23 @@ +/** + * 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 + 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; 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..ae16690 --- /dev/null +++ b/exercises/12-loops-objects/01-loop-through-object.js @@ -0,0 +1,36 @@ +/** + * 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 + 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; 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..ae64ab4 --- /dev/null +++ b/exercises/12-loops-objects/02-loop-through-object.html @@ -0,0 +1,77 @@ + + + + + + + + EXERCISE + + + +
+

Now Playing

+ +
+ + + 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..73203bb --- /dev/null +++ b/exercises/13-more-conditionals/01-ternary-operator.js @@ -0,0 +1,18 @@ +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 +let isEvenOrOdd; +let remainder = num % 2; +isEvenOrOdd = remainder === 0 ? "even" : "odd"; + +console.log(isEvenOrOdd); 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/exercises/15-callbacks/01-calculate.js b/exercises/15-callbacks/01-calculate.js new file mode 100644 index 0000000..9e14b34 --- /dev/null +++ b/exercises/15-callbacks/01-calculate.js @@ -0,0 +1,41 @@ +/** + * 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 + 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 }; diff --git a/exercises/15-callbacks/02-print-names.js b/exercises/15-callbacks/02-print-names.js new file mode 100644 index 0000000..b61b770 --- /dev/null +++ b/exercises/15-callbacks/02-print-names.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); +}; + +/** + * 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) { + printer(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/exercises/15-callbacks/03-find-first.js b/exercises/15-callbacks/03-find-first.js new file mode 100644 index 0000000..f674104 --- /dev/null +++ b/exercises/15-callbacks/03-find-first.js @@ -0,0 +1,34 @@ +/** + * 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 + for (let num of arrayOfNum) { + if (callback(num)) return num; + } +}; + +// IGNORE THIS BELOW. It is for the tests. + +export { findFirst }; 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..dc423e3 --- /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 = (callback, clickableText) => { + return ( + "
Limited Time: Members Save 30%
" + + callback(clickableText) + + "
" + ); +}; + +// Update me too +createCallToAction(createLink, "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..28924c9 --- /dev/null +++ b/exercises/15-callbacks/05-send-email.js @@ -0,0 +1,29 @@ +// 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()); +}; + +//sendEmail(askForUpdate); 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..ff0757e --- /dev/null +++ b/exercises/16-for-each/01-lowest-num.js @@ -0,0 +1,14 @@ +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 +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 new file mode 100644 index 0000000..4cd7432 --- /dev/null +++ b/exercises/16-for-each/02-generate-links.js @@ -0,0 +1,29 @@ +let htmlStr = ""; +const links = [ + // e.g. + "http://speakingjs.com/es5/ch04.html", + "https://www.ecma-international.org/", + "https://www.google.com/books/edition/Eloquent_JavaScript_3rd_Edition/p1v6DwAAQBAJ", +]; + +/** + * 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 +links.forEach((link, i) => { + return (htmlStr += ` ${i + 1}. ${link}`); +}); diff --git a/exercises/17-targeting-dom/targeting-dom.html b/exercises/17-targeting-dom/targeting-dom.html new file mode 100644 index 0000000..b381ed9 --- /dev/null +++ b/exercises/17-targeting-dom/targeting-dom.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>. +

+ +
+ +
+

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____. +

+ +
+ +
+

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. +

+
+ | + Google Search Engine | + | + | + +
+
+ +
+

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..f7dc3fc --- /dev/null +++ b/exercises/17-targeting-dom/targeting-dom.js @@ -0,0 +1,34 @@ +/** + * 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 + 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(""); + } +})(); 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/exercises/18-transforming-dom/transforming-dom.html b/exercises/18-transforming-dom/transforming-dom.html new file mode 100644 index 0000000..d5a627a --- /dev/null +++ b/exercises/18-transforming-dom/transforming-dom.html @@ -0,0 +1,89 @@ + + + + + + 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. +
+ Read the (unofficial) JavaScript manual +
+
+ +
+ 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. +

+
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 new file mode 100644 index 0000000..d138cb4 --- /dev/null +++ b/exercises/18-transforming-dom/transforming-dom.js @@ -0,0 +1,29 @@ +/** + * 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 + 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"; + } +})(); diff --git a/exercises/19-click-events/click-events.html b/exercises/19-click-events/click-events.html new file mode 100644 index 0000000..48cedef --- /dev/null +++ b/exercises/19-click-events/click-events.html @@ -0,0 +1,48 @@ + + + + + + + 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..4d5aca7 --- /dev/null +++ b/exercises/19-click-events/click-events.js @@ -0,0 +1,31 @@ +(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 + 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. + * + * 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 + const creditCardButton = document.querySelector("#btn2"); + const chargeOnce = () => { + creditCardButton.textContent = "Loading..."; + creditCardButton.disabled = "disabled"; + }; + creditCardButton.addEventListener("click", chargeOnce); +})(); diff --git a/exercises/20-toggle-events/toggle-events.html b/exercises/20-toggle-events/toggle-events.html new file mode 100644 index 0000000..e2c8eeb --- /dev/null +++ b/exercises/20-toggle-events/toggle-events.html @@ -0,0 +1,114 @@ + + + + + + + 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..8e3f299 --- /dev/null +++ b/exercises/20-toggle-events/toggle-events.js @@ -0,0 +1,44 @@ +(function () { + /** + * Problem 1: Dismiss the "Accept Cookies" popup + * + * When the user clicks on the "Accept Cookies" button, the "Accept Cookies" popup should disappear. + */ + const cookiesPopup = document.querySelector("#acceptCookiesPopup"); + const cookiesButton = document.querySelector("#acceptCookiesButton"); + const accept = () => { + cookiesPopup.style.display = "none"; + }; + cookiesButton.addEventListener("click", accept); + + // 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 + const commentsButton = document.querySelector("#commentsButton"); + const comments = document.querySelector("#comments"); + + commentsButton.addEventListener("click", () => { + if (comments.classList.contains("hidden")) { + comments.classList.remove("hidden"); + commentsButton.textContent = "Hide Comments"; + } else { + comments.classList.add("hidden"); + commentsButton.textContent = "View Comments"; + } + }); +})(); diff --git a/exercises/21-forms/forms.html b/exercises/21-forms/forms.html new file mode 100644 index 0000000..c4d9ccf --- /dev/null +++ b/exercises/21-forms/forms.html @@ -0,0 +1,107 @@ + + + + + + + EXERCISES Events + + + + + + + + + + + + +
+
+ + + + +
+
+
+ +
+
+ +
+
+ +
+ +
+
+
+ + +

+
+
+ +
+
+
+
+
+ + + +
+ + +
+ + + + + + +
+
+
+ + diff --git a/exercises/21-forms/forms.js b/exercises/21-forms/forms.js new file mode 100644 index 0000000..0988c9a --- /dev/null +++ b/exercises/21-forms/forms.js @@ -0,0 +1,66 @@ +(function () { + /** + * You have three challenges to solve below with Vanilla JavaScript. + * You are allowed to make changes to the HTML and CSS. + */ + /** + * Problem 1: Rendering what a user is typing on the page. + * + * When the user types inside the textbook labeled "Enter mystery text here", + * it should display what the user is typing in the
tags below. + */ + // Write your answer here + const textBox = document.querySelector("#textbox"); + const inputMessage = document.querySelector("#inputmessage"); + textBox.addEventListener("input", (event) => { + inputMessage.textContent = event.target.value; + }); + /** + * Problem 2: Display the results of the world's most pointless search engine. + * + * When the user types in the textbook and either clicks "Search" button or hits the enter key, + * display the message "No results for ___ found" inside of this

below. + * For example, if the user searches for "Indian Ocean", display "No results for Indian Ocean found". + * (Since there are no oceans near Albany, NY, the search engine should + * display the "No results for ___ found" message every time.) + * + * The exercise must be completed with a form handler + * and you must prevent the page from refreshing when the form is submitted. + */ + // Write your answer here + + const searchForm = document.querySelector("#search-form"); + const results = document.querySelector("#search-results"); + searchForm.addEventListener("submit", (e) => { + e.preventDefault(); + const input = document.querySelector("#input").value; + results.textContent = `No results for ${input} found`; + }); + /** + * Problem 3: Agree to the terms and conditions + * + * Whenever the user clicks the "Continue" button, if she has not agreed to the terms, + * the error "You must agree to the terms and conditions" should appear + * and the label "I Agree to the Terms and Conditions" should turn red. + * If she has, then display "Thank you for signing up". + * + * To start, you will need to hide some element on the page and change the input's classes. + */ + // Write your answer here + + const checkBox = document.querySelector("#check-box"); + const formTerms = document.querySelector("#form-terms"); + const textSuccess = document.querySelector("#text-sucess"); + const textDanger = document.querySelector("#text-danger"); + const labelAgree = document.querySelector("#label-agree"); + + formTerms.addEventListener("click", (e) => { + //e.preventDefault(); + if (checkBox.target.checked) { + textSuccess.classList.remove(".hidden"); + } else { + labelAgree.classList.add(".is-invalid"); + textDanger.classList.remove(".hidden"); + } + }); +})(); diff --git a/exercises/22-identify-elements/bulma-pricingtable.min.css b/exercises/22-identify-elements/bulma-pricingtable.min.css new file mode 100644 index 0000000..512ffa4 --- /dev/null +++ b/exercises/22-identify-elements/bulma-pricingtable.min.css @@ -0,0 +1,4 @@ +/** + * @source https://github.com/Wikiki/bulma-pricingtable + */ +@-webkit-keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.pricing-table{display:flex;align-items:stretch;flex-direction:row;flex-flow:row wrap;justify-content:space-between}.pricing-table.is-comparative .pricing-plan{border-radius:initial;margin:0}.pricing-table.is-comparative .pricing-plan:not(:last-child){border-right:none}.pricing-table.is-comparative .pricing-plan:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.pricing-table.is-comparative .pricing-plan:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.pricing-table.is-comparative .pricing-plan.is-active{border:.1rem solid #f5f5f5;border-radius:4px}.pricing-table .pricing-plan{display:flex;flex-direction:column;flex:1 1 auto;background-color:#fff;border:.1rem solid #f5f5f5;border-radius:4px;list-style-type:none;transition:.25s;margin:.5em}.pricing-table .pricing-plan .plan-header{border-top-left-radius:4px;border-top-right-radius:4px;background-color:#fff;color:#4a4a4a;font-size:1.25rem;font-weight:600;padding:.75em;align-content:center;text-align:center}.pricing-table .pricing-plan .plan-item{background:#f5f5f5;border-bottom:.1rem solid #fff;padding:.75em;align-content:center;text-align:center;font-size:.9em;color:#7a7a7a}.pricing-table .pricing-plan .plan-price{background-color:#fff;color:#4a4a4a;font-size:.75rem;font-weight:400;padding:.75em;align-content:center;text-align:center}.pricing-table .pricing-plan .plan-price .plan-price-amount{font-size:2.5rem;font-weight:700}.pricing-table .pricing-plan .plan-price .plan-price-amount .plan-price-currency{vertical-align:super;font-size:1rem!important;font-weight:400!important;color:#4a4a4a;margin-right:.25rem}.pricing-table .pricing-plan .plan-footer{border-bottom-left-radius:4px;border-bottom-right-radius:4px;padding:.75em;align-content:center;text-align:center;margin-top:auto}.pricing-table .pricing-plan.is-active{box-shadow:0 8px 12px 0 rgba(122,122,122,.2);-webkit-transform:scale(1.05);transform:scale(1.05)}.pricing-table .pricing-plan.is-active .plan-price .plan-price-amount{color:#00d1b2}.pricing-table .pricing-plan.is-active .plan-footer .button{background-color:#00d1b2;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-active .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-active .plan-footer .button:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-active .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-active .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.pricing-table .pricing-plan.is-active .plan-footer .button.is-active,.pricing-table .pricing-plan.is-active .plan-footer .button:active{background-color:#00b89c;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-active .plan-footer .button[disabled]{background-color:#00d1b2;border-color:transparent}.pricing-table .pricing-plan.is-white .plan-price .plan-price-amount{color:#fff}.pricing-table .pricing-plan.is-white .plan-footer .button{background-color:#fff;border-color:transparent;color:#0a0a0a}.pricing-table .pricing-plan.is-white .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-white .plan-footer .button:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.pricing-table .pricing-plan.is-white .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-white .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.pricing-table .pricing-plan.is-white .plan-footer .button.is-active,.pricing-table .pricing-plan.is-white .plan-footer .button:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.pricing-table .pricing-plan.is-white .plan-footer .button[disabled]{background-color:#fff;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-black .plan-price .plan-price-amount{color:#0a0a0a}.pricing-table .pricing-plan.is-black .plan-footer .button{background-color:#0a0a0a;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-black .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-black .plan-footer .button:hover{background-color:#040404;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-black .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-black .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.pricing-table .pricing-plan.is-black .plan-footer .button.is-active,.pricing-table .pricing-plan.is-black .plan-footer .button:active{background-color:#000;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-black .plan-footer .button[disabled]{background-color:#0a0a0a;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-light .plan-price .plan-price-amount{color:#f5f5f5}.pricing-table .pricing-plan.is-light .plan-footer .button{background-color:#f5f5f5;border-color:transparent;color:#363636}.pricing-table .pricing-plan.is-light .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-light .plan-footer .button:hover{background-color:#eee;border-color:transparent;color:#363636}.pricing-table .pricing-plan.is-light .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-light .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:#363636}.pricing-table .pricing-plan.is-light .plan-footer .button.is-active,.pricing-table .pricing-plan.is-light .plan-footer .button:active{background-color:#e8e8e8;border-color:transparent;color:#363636}.pricing-table .pricing-plan.is-light .plan-footer .button[disabled]{background-color:#f5f5f5;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-dark .plan-price .plan-price-amount{color:#363636}.pricing-table .pricing-plan.is-dark .plan-footer .button{background-color:#363636;border-color:transparent;color:#f5f5f5}.pricing-table .pricing-plan.is-dark .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-dark .plan-footer .button:hover{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.pricing-table .pricing-plan.is-dark .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-dark .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#f5f5f5}.pricing-table .pricing-plan.is-dark .plan-footer .button.is-active,.pricing-table .pricing-plan.is-dark .plan-footer .button:active{background-color:#292929;border-color:transparent;color:#f5f5f5}.pricing-table .pricing-plan.is-dark .plan-footer .button[disabled]{background-color:#363636;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-primary .plan-price .plan-price-amount{color:#00d1b2}.pricing-table .pricing-plan.is-primary .plan-footer .button{background-color:#00d1b2;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-primary .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-primary .plan-footer .button:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-primary .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-primary .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.pricing-table .pricing-plan.is-primary .plan-footer .button.is-active,.pricing-table .pricing-plan.is-primary .plan-footer .button:active{background-color:#00b89c;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-primary .plan-footer .button[disabled]{background-color:#00d1b2;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-link .plan-price .plan-price-amount{color:#3273dc}.pricing-table .pricing-plan.is-link .plan-footer .button{background-color:#3273dc;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-link .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-link .plan-footer .button:hover{background-color:#276cda;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-link .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-link .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(50,115,220,.25);color:#fff}.pricing-table .pricing-plan.is-link .plan-footer .button.is-active,.pricing-table .pricing-plan.is-link .plan-footer .button:active{background-color:#2366d1;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-link .plan-footer .button[disabled]{background-color:#3273dc;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-info .plan-price .plan-price-amount{color:#209cee}.pricing-table .pricing-plan.is-info .plan-footer .button{background-color:#209cee;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-info .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-info .plan-footer .button:hover{background-color:#1496ed;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-info .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-info .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(32,156,238,.25);color:#fff}.pricing-table .pricing-plan.is-info .plan-footer .button.is-active,.pricing-table .pricing-plan.is-info .plan-footer .button:active{background-color:#118fe4;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-info .plan-footer .button[disabled]{background-color:#209cee;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-success .plan-price .plan-price-amount{color:#23d160}.pricing-table .pricing-plan.is-success .plan-footer .button{background-color:#23d160;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-success .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-success .plan-footer .button:hover{background-color:#22c65b;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-success .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-success .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(35,209,96,.25);color:#fff}.pricing-table .pricing-plan.is-success .plan-footer .button.is-active,.pricing-table .pricing-plan.is-success .plan-footer .button:active{background-color:#20bc56;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-success .plan-footer .button[disabled]{background-color:#23d160;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-warning .plan-price .plan-price-amount{color:#ffdd57}.pricing-table .pricing-plan.is-warning .plan-footer .button{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.pricing-table .pricing-plan.is-warning .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-warning .plan-footer .button:hover{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.pricing-table .pricing-plan.is-warning .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-warning .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(255,221,87,.25);color:rgba(0,0,0,.7)}.pricing-table .pricing-plan.is-warning .plan-footer .button.is-active,.pricing-table .pricing-plan.is-warning .plan-footer .button:active{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.pricing-table .pricing-plan.is-warning .plan-footer .button[disabled]{background-color:#ffdd57;border-color:transparent;box-shadow:none}.pricing-table .pricing-plan.is-danger .plan-price .plan-price-amount{color:#ff3860}.pricing-table .pricing-plan.is-danger .plan-footer .button{background-color:#ff3860;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-danger .plan-footer .button.is-hovered,.pricing-table .pricing-plan.is-danger .plan-footer .button:hover{background-color:#ff2b56;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-danger .plan-footer .button.is-focused,.pricing-table .pricing-plan.is-danger .plan-footer .button:focus{border-color:transparent;box-shadow:0 0 .5em rgba(255,56,96,.25);color:#fff}.pricing-table .pricing-plan.is-danger .plan-footer .button.is-active,.pricing-table .pricing-plan.is-danger .plan-footer .button:active{background-color:#ff1f4b;border-color:transparent;color:#fff}.pricing-table .pricing-plan.is-danger .plan-footer .button[disabled]{background-color:#ff3860;border-color:transparent;box-shadow:none}@media screen and (min-width:769px),print{.pricing-table.is-comparative{margin:.5rem}.pricing-table.is-comparative.is-features{display:none}.pricing-table.is-comparative .plan-item::before{content:attr("data-feature")}.pricing-table.is-horizontal .pricing-plan{display:flex;flex-direction:row;flex-basis:100%}.pricing-table.is-horizontal .pricing-plan .plan-header{width:50%;display:flex;flex-direction:column;justify-content:center}.pricing-table.is-horizontal .pricing-plan .plan-price{width:100%;display:flex;flex-direction:row;justify-content:center}.pricing-table.is-horizontal .pricing-plan .plan-items{width:100%;background-color:#f5f5f5;columns:2;-webkit-columns:2;-moz-columns:2;-webkit-column-gap:.1rem;column-gap:.1rem}.pricing-table.is-horizontal .pricing-plan .plan-footer{width:50%;display:flex;flex-direction:column;justify-content:center;margin:auto}}@media screen and (max-width:768px){.pricing-table.is-comparative .pricing-plan{margin:.5rem}.pricing-table.is-comparative .pricing-plan.is-plan-first-mobile{order:-1}.pricing-table.is-comparative .pricing-plan.is-features{display:none}.pricing-table.is-comparative .pricing-plan .plan-item::before{content:attr(data-feature);display:block;font-weight:600;font-size:.75rem;color:#b5b5b5}} \ No newline at end of file diff --git a/exercises/22-identify-elements/indentify-elements.html b/exercises/22-identify-elements/indentify-elements.html new file mode 100644 index 0000000..3362c1d --- /dev/null +++ b/exercises/22-identify-elements/indentify-elements.html @@ -0,0 +1,84 @@ + + + + + + + + + EXERCISES Events + + + + + +
+ + + + +
+ + +
+
+
Community
+
+ $5/month +
+
+
20GB Storage
+
1 Domain
+
1GB Bandwidth
+
-
+
+ +
+ +
+
Professional
+
+ $10/month +
+
+
200GB Storage
+
5 Domains
+
1TB Bandwidth
+
100 Email Boxes
+
+ +
+ +
+
Enterprise
+
+ $50/month +
+
+
2TB Storage
+
50 Domains
+
1TB Bandwidth
+
1000 Email Boxes
+
+ +
+
+ + diff --git a/exercises/22-identify-elements/indentify-elements.js b/exercises/22-identify-elements/indentify-elements.js new file mode 100644 index 0000000..6b5eaf2 --- /dev/null +++ b/exercises/22-identify-elements/indentify-elements.js @@ -0,0 +1,18 @@ +!(function () { + /** + * When the user clicks on one of the "Select" buttons to select a plan, + * display the following message in the aqua green notification at the top of the screen, + * where "Premium" is the name of the plan that user selected: + * "Thank you for purchasing the Premium plan!" + * + * You must use "document.querySelectorAll" to solve this problem. + * + * You can edit the HTML on the page to solve this problem. + * + * As a bonus, you can hide the notification before the user selects a plan. + * You can also make the "x" icon dismiss the notification. + */ + // Write your answer here + // queryselectAll all the buttons + //add an event listener for each +})(); diff --git a/exercises/23-creating-elements/creating-elements.html b/exercises/23-creating-elements/creating-elements.html new file mode 100644 index 0000000..c0c096d --- /dev/null +++ b/exercises/23-creating-elements/creating-elements.html @@ -0,0 +1,44 @@ + + + + + + + EXERCISES Creating Elements + + + + + + + +
+ + diff --git a/exercises/23-creating-elements/creating-elements.js b/exercises/23-creating-elements/creating-elements.js new file mode 100644 index 0000000..ffa9517 --- /dev/null +++ b/exercises/23-creating-elements/creating-elements.js @@ -0,0 +1,8 @@ +const createElementButton = document.querySelector("#create-element-button"); +const container = document.querySelector("#container"); + +createElementButton.addEventListener("click", () => { + const newElement = document.createElement("div"); + newElement.innerHTML = "This is a new element"; + container.appendChild(newElement); +}); diff --git a/exercises/24-http-and-rest/404-not-found.png b/exercises/24-http-and-rest/404-not-found.png new file mode 100644 index 0000000..830e88e Binary files /dev/null and b/exercises/24-http-and-rest/404-not-found.png differ diff --git a/exercises/24-http-and-rest/README.md b/exercises/24-http-and-rest/README.md new file mode 100644 index 0000000..2273c5f --- /dev/null +++ b/exercises/24-http-and-rest/README.md @@ -0,0 +1,3 @@ +# HTTP and REST APIs + +This is a quiz assignment you will need to complete in Teams. The assignment is called "24 HTTP and REST APIs". I'm using this Github folder to host the images that are used in the assignment. diff --git a/exercises/24-http-and-rest/create-user-thunderclient.png b/exercises/24-http-and-rest/create-user-thunderclient.png new file mode 100644 index 0000000..428f388 Binary files /dev/null and b/exercises/24-http-and-rest/create-user-thunderclient.png differ diff --git a/exercises/24-http-and-rest/list-of-users-doc.png b/exercises/24-http-and-rest/list-of-users-doc.png new file mode 100644 index 0000000..9762537 Binary files /dev/null and b/exercises/24-http-and-rest/list-of-users-doc.png differ diff --git a/exercises/24-http-and-rest/list-of-users-thunderclient.png b/exercises/24-http-and-rest/list-of-users-thunderclient.png new file mode 100644 index 0000000..5ed3b12 Binary files /dev/null and b/exercises/24-http-and-rest/list-of-users-thunderclient.png differ diff --git a/exercises/24-http-and-rest/list-of-users-ui.png b/exercises/24-http-and-rest/list-of-users-ui.png new file mode 100644 index 0000000..8a23184 Binary files /dev/null and b/exercises/24-http-and-rest/list-of-users-ui.png differ diff --git a/exercises/24-http-and-rest/thunder-client-vscode.png b/exercises/24-http-and-rest/thunder-client-vscode.png new file mode 100644 index 0000000..f469af6 Binary files /dev/null and b/exercises/24-http-and-rest/thunder-client-vscode.png differ diff --git a/exercises/25-axios/axios.css b/exercises/25-axios/axios.css new file mode 100644 index 0000000..37454da --- /dev/null +++ b/exercises/25-axios/axios.css @@ -0,0 +1,26 @@ +body { + font-family: "Syncopate", sans-serif; + padding: 1rem; + text-align: center; +} +.container { + max-width: 1200px; + margin: auto; +} +h1 { + font-family: "Amatic SC", sans-serif; + font-size: 100px; + padding: -20px; + margin: -40px; + color: #b0aac2; +} +h2 { + font-family: "Amatic SC", sans-serif; + font-size: 60px; +} +img { + display: inline-block; +} +.button { + font-weight: bold; +} diff --git a/exercises/25-axios/axios.html b/exercises/25-axios/axios.html new file mode 100644 index 0000000..675630e --- /dev/null +++ b/exercises/25-axios/axios.html @@ -0,0 +1,39 @@ + + + + EXERCISES Axios + + + + + + + +
+

Oshi the dog tribute page

+ +

The best dog in the land.

+ +

+ +

+

+ Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere + rip the couch sleep in the sink fluffy fur catnip scratched. +

+

+
+ + diff --git a/exercises/25-axios/axios.js b/exercises/25-axios/axios.js new file mode 100644 index 0000000..d2e056e --- /dev/null +++ b/exercises/25-axios/axios.js @@ -0,0 +1,26 @@ +(function () { + /** + * As a user, I should be able to click on the a button to see random dog images. + * Please use axios in this example. + * + * You will be making an HTTP request to this API: + * https://dog.ceo/api/breeds/image/random + * + * You should expect this as a response: + * { + * "status": "success", + * "message": "https://images.dog.ceo/breeds/poodle-toy/n02113624_9550.jpg" + * } + */ + /* + axios({ + url: "https://dog.ceo/api/breeds/image/random", + method: "GET", + }); + */ + const button = document.querySelector("button"); + button.addEventListener("click", (e) => { + const image = document.querySelector("#image"); + image.src = "https://dog.ceo/api/breeds/image/random"; + }); +})(); diff --git a/projects/final-project/FinalProject.md b/projects/final-project/FinalProject.md new file mode 100644 index 0000000..d170b05 --- /dev/null +++ b/projects/final-project/FinalProject.md @@ -0,0 +1,267 @@ +# Final Project - the Document Object Model (DOM) + +**Due Date: January 9, 2023 11:59pm** + +For your final project, you will be developing a front-end web based user interface in Vanilla JavaScript. You you have a choice of creating: + +1. A game of "Rock, Paper, Scissors" +2. A calculator +3. A game of "Tic-Tac-Toe" + +## Project Goals + +- To put together and make practical use of what was taught in class. +- To learn about developer practices, like setting up a new website, 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: + +- Fundamentals of JavaScript +- Working with the Document Object Model (DOM) +- Handling events +- Structuring your project + +## Projects + +Please select one of the project ideas below. + +### Option 1: Rock, Paper, Scissors Requirements + +Create a web version of the game ["Rock", "Paper", "Scissors"](https://www.youtube.com/watch?v=ND4fd6yScBM). Your user will be playing against a computer AI. + +![The user should select either rock, paper, or scissors](rock-paper-scissors1.png) + +![Reveal who one the game](rock-paper-scissors2.png) + +#### UI Requirements + +If you choose this project, you must meet the following UI requirements: + +- There should be at least two screens: + - In one screen, the user should select either rock, paper, or scissors (or something similar). + - In a following screen, reveal who has won the game. +- You must write some code to select rock, paper, or scissors for the computer at random. +- The user should be able to play again without refreshing the screen. + +Feel free to add to more features to the game. + +#### Coding Requirements + +Each project must also meet the following requirements: + +- You put your code in file(s) external to the HTML that are loaded with ` + + + + + +``` + +```javascript +// Wrap in Immediately Invoked Functional Express (IIFE) to protect your code +(function () { + // All of your code goes here +})(); +``` + +For both projects, you may need to identify what the user clicked on. For example, you may have a single add event handler, and you want to know whether the user clicked on the "rock", "paper", or "scissors" button. One way you can do this is to use IDs: + +```html +rock +paper +scissors +``` + +```javascript +// Target all three options (rock, paper, scissors) +const handSignals = document.querySelectorAll(".hand-signal"); + +// Loop through each option +handSignals.forEach((signal) => { + // Attaches a click event + signal.addEventListener("click", () => { + // Gets the ID so you can figure out what the user clicked on + const whatTheUserSelected = signal.id; + alert("You picked " + whatTheUserSelected); + }); +}); +``` + +Another option is to embed data with data attributes. + +```html + + + + + +``` + +```javascript +// Targets all the caluator buttons that are a number +const numberButtons = document.querySelectorAll("[data-number]"); + +// Loops through each button +numberButtons.forEach((button) => { + // Attaches a click event + button.addEventListener("click", () => { + // Gets the value from a data attribute so you can figure out what the user clicked on + const whatTheUserClickedOn = button.getAttribute('[data-number']); + alert('You clicked on the number ' + whatTheUserClickedOn); + }); +}); +``` + +For the "Tic-Tac-Toe" and "Rock, Paper, Scissors" games, you may want to store the winning combinations in a collection (array, object, array or objects, etc). Here is what you can use for "Tic-Tac-Toe": + +```javascript +const winningConditions = [ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + [0, 3, 6], + [1, 4, 7], + [2, 5, 8], + [0, 4, 8], + [2, 4, 6], +]; +``` + +## 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. + +## Github Repository and Pages + +You will need to [create a new public Github repository](https://help.github.com/en/articles/create-a-repo) for this project. It must be public. You should also include a _README.md_ and _.gitignore_ file. + +Your _README.md_ file should be written in [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). This should be written for employers who may be looking at your work. Describe your project and explain how to get started. + +You can generate _.gitignore_ file with [gitignore.io](https://www.toptal.com/developers/gitignore). If you have a _node_modules_ folder, be sure to include it in your _.gitignore_. + +In addition to submitting code, you will need to submit a hosted version of your project. An easy way to do this is to publish your project with Github pages. Here are the steps: + +1. Open you Github repository e.g. https://github.com/my-github-username/final-project for your project in a web browser. +2. Click on the "Settings" tab below the "Unwatch", "Star", and "Fork" buttons. +3. In the sidebar, click on "Pages". +4. Underneath where it says "Source", click on the "Branch" dropdown and select "Main". +5. Hit the "Save" button. +6. You will see the URL for your published project (e.g. https://my-github-username.github.io/final-project), but it may take up to 15 minutes before the link works. If you click on the link and click a page not found error, you can try opening it an Incognito window or another browser. + +## Project Submission + +You will submit to following to both of you instructors by emailing it to Jamal (jamal@albanycancode.org) and Matina (matina@albanycancode.org) by the project deadline: + +1. The link to your Github repository. +2. The link to you where your project is published. You can publish your project with Github Pages or you can a different hosting service. + +Your project does not have to be 100% complete, but it does have to be presentable to employers. CanCode Communities will host your project in a public space and they will be sharing your work with employers. + +## Graduation and Project Showcase + +There will be a virtual graduation and networking ceremony. You will receive an email from CanCode Communities with more information about this as we get closer to the date. You will be asked present your project, so it should be ready to share by the project due date. diff --git a/projects/final-project/rock-paper-scissors1.png b/projects/final-project/rock-paper-scissors1.png new file mode 100644 index 0000000..5d444ce Binary files /dev/null and b/projects/final-project/rock-paper-scissors1.png differ diff --git a/projects/final-project/rock-paper-scissors2.png b/projects/final-project/rock-paper-scissors2.png new file mode 100644 index 0000000..356bb38 Binary files /dev/null and b/projects/final-project/rock-paper-scissors2.png differ diff --git a/projects/final-project/tic-tac-toe.gif b/projects/final-project/tic-tac-toe.gif new file mode 100644 index 0000000..45f315f Binary files /dev/null and b/projects/final-project/tic-tac-toe.gif differ diff --git a/projects/hangman/ProjectHangman.md b/projects/hangman/ProjectHangman.md new file mode 100644 index 0000000..d2a74fd --- /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 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. + +### 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 0000000..2cade81 Binary files /dev/null and b/projects/hangman/hangman.gif differ diff --git a/projects/hangman/word-bank.js b/projects/hangman/word-bank.js new file mode 100644 index 0000000..fcf398f --- /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","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"]; 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 + + + +
+ + + +
+ + + 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); 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 +
+ + + 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; 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/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..b849575 --- /dev/null +++ b/solutions/09-arrays/02-accessing-item-in-array.solution.js @@ -0,0 +1,11 @@ +const cars = ["BMW", "Honda", "Civic"]; // Do not change this line + +/** + * 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[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..a5987a9 --- /dev/null +++ b/solutions/09-arrays/03-destructuring.solution.js @@ -0,0 +1,14 @@ +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 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; 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]; 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; 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; 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."; 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 }; 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/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/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)); +})(); 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..86e831e --- /dev/null +++ b/solutions/18-dom-attributes/dom-attributes.solutions.html @@ -0,0 +1,38 @@ + + + + + + + Document + + + + + + 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 + + + + + +
    +
    +

    + 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/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"; + } +})(); 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); +})(); diff --git a/solutions/20-toggle-events/toggle-events.solutions.html b/solutions/20-toggle-events/toggle-events.solutions.html new file mode 100644 index 0000000..82f6bbb --- /dev/null +++ b/solutions/20-toggle-events/toggle-events.solutions.html @@ -0,0 +1,116 @@ + + + + + + + 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/solutions/20-toggle-events/toggle-events.solutions.js b/solutions/20-toggle-events/toggle-events.solutions.js new file mode 100644 index 0000000..3f6a0cb --- /dev/null +++ b/solutions/20-toggle-events/toggle-events.solutions.js @@ -0,0 +1,55 @@ +(function () { + /** + * Problem 1: Dismiss the "Accept Cookies" popup + * + * When the user clicks on the "Accept Cookies" button, the "Accept Cookies" popup should disappear. + */ + + // Step 1 Target + const acceptCookiesPopup = document.querySelector("#acceptCookiesPopup"); + const acceptCookiesButton = document.querySelector("#acceptCookiesButton"); + + // Step 3 Do something + const dismissPopup = () => { + acceptCookiesPopup.style.display = "none"; + }; + + // Step 2 React to an event + acceptCookiesButton.addEventListener("click", dismissPopup); + + /** + * 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. + */ + + // Step 1 Target + const toggleComments = document.querySelector("#toggleComments"); + const comments = document.querySelector("#comments"); + + // Step 2 React to an event + toggleComments.addEventListener("click", () => { + // Step 3 Do something + // Show comments if they are hidden + if (comments.classList.contains("hidden")) { + comments.classList.remove("hidden"); + toggleComments.textContent = "Hide Comments"; + } else { + // Hide comments if they are not hidden + comments.classList.add("hidden"); + toggleComments.textContent = "Show Comments"; + } + }); +})(); diff --git a/solutions/21-forms/forms.solution.html b/solutions/21-forms/forms.solution.html new file mode 100644 index 0000000..6bb3455 --- /dev/null +++ b/solutions/21-forms/forms.solution.html @@ -0,0 +1,131 @@ + + + + + + + EXERCISES Events + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    +
    + +
    +
    + + +
    +
    + + +
    + +
    +
    +
    + + + +

    +
    +
    + +
    +
    + +
    +
    +
    + + + + +
    + + +
    + + + + + + + + +
    +
    +
    + + diff --git a/solutions/21-forms/forms.solution.js b/solutions/21-forms/forms.solution.js new file mode 100644 index 0000000..73c189f --- /dev/null +++ b/solutions/21-forms/forms.solution.js @@ -0,0 +1,113 @@ +(function () { + /** + * You have three challenges to solve below with Vanilla JavaScript. + * You are allowed to make changes to the HTML and CSS. + */ + /** + * Problem 1: Rendering what a user is typing on the page. + * + * When the user types inside the textbook labeled "Enter mystery text here", + * it should display what the user is typing in the
    tags below. + */ + + // Step 1: Target + const mysteryText = document.querySelector("#mysteryText"); + const showUserText = document.querySelector("#mysteryTextDisplay"); + + const callback = (event) => { + // Step 3: Do something - display the text that the user is typing to the screen + showUserText.textContent = event.target.value; + }; + + // Step 2: React to Event + mysteryText.addEventListener("input", callback); + + /** + * Problem 2: Display the results of the world's most pointless search engine. + * + * When the user types in the textbook and either clicks "Search" button or hits the enter key, + * display the message "No results for ___ found" inside of this

    below. + * For example, if the user searches for "Indian Ocean", display "No results for Indian Ocean found". + * (Since there are no oceans near Albany, NY, the search engine should + * display the "No results for ___ found" message every time.) + * + * The exercise must be completed with a form handler + * and you must prevent the page from refreshing when the form is submitted. + */ + + // Step 1: Target + const oceanForm = document.querySelector("#handleThisForm"); + const oceanInput = document.querySelector("#oceanInput"); + const oceanDisplay = document.querySelector("#oceanOutput"); + + // Step 2: React to event + oceanForm.addEventListener("submit", (event) => { + event.preventDefault(); + // Step 3: Do something - stop the form from refreshing and display "No results for ____ found". + oceanDisplay.textContent = `No results for ${oceanInput.value} found`; + }); + + /** + * Problem 3: Agree to the terms and conditions + * + * Whenever the user clicks the "Continue" button, if she has not agreed to the terms, + * the error "You must agree to the terms and conditions" should appear + * and the label "I Agree to the Terms and Conditions" should turn red. + * If she has, then display "Thank you for signing up". + * + * To start, you will need to hide some element on the page and change the input's classes. + */ + + // Step 1: Target + const terms = document.querySelector("#terms"); + const termsError = document.querySelector("#termsError"); + const termsSuccess = document.querySelector("#termsSuccess"); + const checkbox = document.querySelector("#terms"); + + // Step 3: Do something + + const showTermsError = () => { + // Makes "I Agree to the Terms and Conditions" red + if (!terms.classList.contains("is-invalid")) { + terms.classList.add("is-invalid"); + } + + // Hides success message + if (!termsSuccess.classList.contains("hidden")) { + termsSuccess.classList.add("hidden"); + } + + // Shows error message + if (termsError.classList.contains("hidden")) { + termsError.classList.remove("hidden"); + } + }; + + const showTermsSuccess = () => { + // Reverts "I Agree to the Terms and Conditions" back to original color + if (terms.classList.contains("is-invalid")) { + terms.classList.remove("is-invalid"); + } + + // Hides success message + if (termsSuccess.classList.contains("hidden")) { + termsSuccess.classList.remove("hidden"); + } + + // Shows error message + if (!termsError.classList.contains("hidden")) { + termsError.classList.add("hidden"); + } + }; + + // Step 2: React to an event + document.querySelector("#termsForm").addEventListener("submit", (event) => { + event.preventDefault(); + + if (checkbox.checked) { + showTermsSuccess(); + } else { + showTermsError(); + } + }); +})(); diff --git a/solutions/22-identify-elements/indentify-elements.solution.js b/solutions/22-identify-elements/indentify-elements.solution.js new file mode 100644 index 0000000..3bc5ba2 --- /dev/null +++ b/solutions/22-identify-elements/indentify-elements.solution.js @@ -0,0 +1,35 @@ +!(function () { + /** + * When the user clicks on one of the "Select" buttons to select a plan, + * display the following message in the aqua green notification at the top of the screen, + * where "Premium" is the name of the plan that user selected: + * "Thank you for purchasing the Premium plan!" + * + * You must use "document.querySelectorAll" to solve this problem. + * + * You can edit the HTML on the page to solve this problem. + * + * As a bonus, you can hide the notification before the user selects a plan. + * You can also make the "x" icon dismiss the notification. + */ + // Write your answer here + + // Targets all the "Select" buttons + const pricingPlanButtons = document.querySelectorAll(".pricing-plan button"); + + // Targets the success message + const notificationMessage = document.querySelector("#notificationMessage"); + const notification = document.querySelector("#notification"); + + // Loops through the buttons on the page + pricingPlanButtons.forEach((plan) => { + // React to when a user clicks on a button + plan.addEventListener("click", () => { + // I set the button ID as the name of the plan. Changing the success message to include the name of the plan. + notificationMessage.textContent = `Thank you for purchasing the ${plan.id} plan!`; + + // Shows the hidden success message + notification.style.display = "block"; + }); + }); +})(); 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..58d10e3 --- /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 "b" minus "a"', () => { + const difference = subtract(3, 20); + 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(/\*/); + }); + }); +}); 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"); + }); + }); +}); 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"); + }); + }); +}); 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); + }); + }); +}); 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); + }); + }); +}); 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; + }); + }); +}); 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..8e17687 --- /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.02]); + }); + 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(51); + }); + }); + 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/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); + }); + }); +}); diff --git a/test/10-loops/loops-test-helper.js b/test/10-loops/loops-test-helper.js new file mode 100755 index 0000000..63a9c41 --- /dev/null +++ b/test/10-loops/loops-test-helper.js @@ -0,0 +1,23 @@ +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"; + +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 new file mode 100755 index 0000000..6bd6844 --- /dev/null +++ b/test/10-loops/loops.spec.js @@ -0,0 +1,84 @@ +import { expect } from "chai"; +import { readConsole } from "../getAnswer.js"; +import { + solvingProblems, + arrayLength, + logWithWhile, + logArrayWithFor, + add, + highestNumber, + isPalindrome, +} 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*\(/); + }); + }); + + 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); + }); + }); +}); 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", + }); + }); + }); +}); 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? { + ${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(/\|\|/); + }); + }); +}); diff --git a/test/15-callbacks/callback-test-helper.js b/test/15-callbacks/callback-test-helper.js new file mode 100644 index 0000000..e2c67e9 --- /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.replace("askForUpdate", "() => {}")} + 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 new file mode 100644 index 0000000..426da64 --- /dev/null +++ b/test/15-callbacks/callbacks.spec.js @@ -0,0 +1,84 @@ +import { expect } from "chai"; +import sinon from "sinon"; +import { readConsole } from "../getAnswer.js"; + +import { + calculate, + findFirst, + printerFn, + createCallToAction, + sendEmail, +} from "./callback-test-helper.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); + }); + }); + 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 ``; + }; + // TODO account for the arguments being in a different order + 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)); + expect(output).to.match( + /Do you have time on Monday at 1pm to discuss this\?/ + ); + }); + }); +}); 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..55ab6a1 --- /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('"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"); + 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"); + }); + }); +}); 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 };