From f40f808da0fa43c17055537e4ea80c9445f5029a Mon Sep 17 00:00:00 2001 From: Majd Hamde Date: Tue, 7 Oct 2025 13:12:59 +0200 Subject: [PATCH 1/2] Complete Week 1 exercises for 3-UsingAPIs --- 3-UsingAPIs/Week1/assignment/ex1-johnWho.js | 26 +++++++------ .../Week1/assignment/ex2-checkDoubleDigits.js | 10 ++++- 3-UsingAPIs/Week1/assignment/ex3-rollDie.js | 38 ++++++++++++------- .../Week1/assignment/ex4-pokerDiceAll.js | 19 ++++++++-- .../Week1/assignment/ex5-pokerDiceChain.js | 25 +++++++++++- 5 files changed, 85 insertions(+), 33 deletions(-) diff --git a/3-UsingAPIs/Week1/assignment/ex1-johnWho.js b/3-UsingAPIs/Week1/assignment/ex1-johnWho.js index 5851c8c4f..b2dc2b4ac 100644 --- a/3-UsingAPIs/Week1/assignment/ex1-johnWho.js +++ b/3-UsingAPIs/Week1/assignment/ex1-johnWho.js @@ -8,23 +8,27 @@ Rewrite this function, but replace the callback syntax with the Promise syntax: didn't pass in a first name!" ------------------------------------------------------------------------------*/ // TODO see above -export const getAnonName = (firstName, callback) => { - setTimeout(() => { - if (!firstName) { - callback(new Error("You didn't pass in a first name!")); - return; - } +export const getAnonName = (firstName) => { + return new Promise((resolve, reject) => { + setTimeout(() => { + if (!firstName) { + reject(new Error("You didn't pass in a first name!")); + return; + } - const fullName = `${firstName} Doe`; - - callback(fullName); - }, 1000); + const fullName = `${firstName} Doe`; + resolve(fullName); + }, 1000); + }); }; function main() { - getAnonName('John', console.log); + getAnonName('John') + .then(console.log) + .catch(console.error); } + // ! Do not change or remove the code below if (process.env.NODE_ENV !== 'test') { main(); diff --git a/3-UsingAPIs/Week1/assignment/ex2-checkDoubleDigits.js b/3-UsingAPIs/Week1/assignment/ex2-checkDoubleDigits.js index 4b31d1927..1682da6d5 100644 --- a/3-UsingAPIs/Week1/assignment/ex2-checkDoubleDigits.js +++ b/3-UsingAPIs/Week1/assignment/ex2-checkDoubleDigits.js @@ -11,8 +11,14 @@ Complete the function called `checkDoubleDigits` such that: "Expected a double digit number but got `number`", where `number` is the number that was passed as an argument. ------------------------------------------------------------------------------*/ -export function checkDoubleDigits(/* TODO add parameter(s) here */) { - // TODO complete this function +export function checkDoubleDigits(number) { + return new Promise((resolve, reject) => { + if (number >= 10 && number <= 99) { + resolve("This is a double digit number!"); + } else { + reject(new Error(`Expected a double digit number but got ${number}`)); + } + }); } function main() { diff --git a/3-UsingAPIs/Week1/assignment/ex3-rollDie.js b/3-UsingAPIs/Week1/assignment/ex3-rollDie.js index 7e4b77888..b278a8dc7 100644 --- a/3-UsingAPIs/Week1/assignment/ex3-rollDie.js +++ b/3-UsingAPIs/Week1/assignment/ex3-rollDie.js @@ -11,7 +11,9 @@ Full description at: https://github.com/HackYourFuture/Assignments/tree/main/3-U ------------------------------------------------------------------------------*/ // TODO Remove callback and return a promise -export function rollDie(callback) { +export function rollDie() { + return new Promise((resolve, reject) => { + // Compute a random number of rolls (3-10) that the die MUST complete const randomRollsToDo = Math.floor(Math.random() * 8) + 3; console.log(`Die scheduled for ${randomRollsToDo} rolls...`); @@ -24,34 +26,31 @@ export function rollDie(callback) { // Use callback to notify that the die rolled off the table after 6 rolls if (roll > 6) { // TODO replace "error" callback - callback(new Error('Oops... Die rolled off the table.')); + reject(new Error('Oops... Die rolled off the table.')); + return; } // Use callback to communicate the final die value once finished rolling if (roll === randomRollsToDo) { - // TODO replace "success" callback - callback(null, value); + resolve(value); + return; } // Schedule the next roll todo until no more rolls to do - if (roll < randomRollsToDo) { setTimeout(() => rollOnce(roll + 1), 500); - } }; // Start the initial roll rollOnce(1); + }); } function main() { // TODO Refactor to use promise - rollDie((error, value) => { - if (error !== null) { - console.log(error.message); - } else { - console.log(`Success! Die settled on ${value}.`); - } - }); + rollDie(() => { + .then((value) => console.log(`Success! Die settled on ${value}.`)) + .catch((error) => console.log(error.message)); +} } // ! Do not change or remove the code below @@ -59,4 +58,15 @@ if (process.env.NODE_ENV !== 'test') { main(); } -// TODO Replace this comment by your explanation that was asked for in the assignment description. +/*Explanation: + +Before, using callbacks caused a problem because when the die rolled off the table or finished rolling, the messages could happen in a random order + +Now, using a Promise + +1. We call `resolve()` when the die finishes rolling successfully. +2. We call `reject()` if the die rolls off the table (more than 6 rolls) + +Promises make sure only one thing happens: either success or error. We can handle it easily with `.then()` for success and `.catch()` for errors. + +Because of this, the previous problem does not happen anymore, and everything runs in a clear predictable order */ \ No newline at end of file diff --git a/3-UsingAPIs/Week1/assignment/ex4-pokerDiceAll.js b/3-UsingAPIs/Week1/assignment/ex4-pokerDiceAll.js index d88cd71d2..4919deb43 100644 --- a/3-UsingAPIs/Week1/assignment/ex4-pokerDiceAll.js +++ b/3-UsingAPIs/Week1/assignment/ex4-pokerDiceAll.js @@ -27,11 +27,12 @@ exercise file. import { rollDie } from '../../helpers/pokerDiceRoller.js'; export function rollDice() { - // TODO Refactor this function const dice = [1, 2, 3, 4, 5]; - return rollDie(1); -} + const dicePromises = dice.map(() => rollDie()); + return Promise.all(dicePromises); + } + function main() { rollDice() .then((results) => console.log('Resolved!', results)) @@ -43,4 +44,14 @@ if (process.env.NODE_ENV !== 'test') { main(); } -// TODO Replace this comment by your explanation that was asked for in the assignment description. +/* +Explanation: + +We throw five dice at the same time using Promise.all. Each die is like a separate promise. +- If all dice finish rolling without problems, we get an array with all the results. +- If one die falls off the table, Promise.all stops and gives an error. + +Even if one die fails, the other dice keep rolling. +This happens because each die rolls in its own process, and Promise.all cannot stop them once they started. +It only stops the main result from coming, but the dice themselves keep going until they finish. +*/ diff --git a/3-UsingAPIs/Week1/assignment/ex5-pokerDiceChain.js b/3-UsingAPIs/Week1/assignment/ex5-pokerDiceChain.js index 5b1394b84..cfe316e6a 100644 --- a/3-UsingAPIs/Week1/assignment/ex5-pokerDiceChain.js +++ b/3-UsingAPIs/Week1/assignment/ex5-pokerDiceChain.js @@ -17,15 +17,26 @@ import { rollDie } from '../../helpers/pokerDiceRoller.js'; export function rollDice() { const results = []; - // TODO: expand the chain to include five dice return rollDie(1) .then((value) => { results.push(value); return rollDie(2); }) + .then((value) => { + results.push(value); + return rollDie(3); + }) + .then((value) => { + results.push(value); + return rollDie(4); + }) .then((value) => { results.push(value); - return results; + return rollDie(5); + }) + .then((value) => { + results.push(value); + return results; // Return all results at the end }); } @@ -39,3 +50,13 @@ function main() { if (process.env.NODE_ENV !== 'test') { main(); } +/* +Explanation: + +We throw five dice one by one, waiting for each to finish before throwing the next. +- If a die finishes normally, its value is added to the results array. +- If a die rolls off the table, the chain stops immediately and the error is caught. + +This is different from Promise.all(), because here each die waits for the previous one. +Even though a die falls off, any dice that haven't started yet never roll. +*/ \ No newline at end of file From f95e6fe7c17767384f4ec5df666471f451337380 Mon Sep 17 00:00:00 2001 From: Majd Hamde Date: Tue, 7 Oct 2025 13:23:08 +0200 Subject: [PATCH 2/2] All Week 1 exercises for 3-UsingAPIs completed and tested --- 3-UsingAPIs/Week1/assignment/ex1-johnWho.js | 1 - 3-UsingAPIs/Week1/assignment/ex3-rollDie.js | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/3-UsingAPIs/Week1/assignment/ex1-johnWho.js b/3-UsingAPIs/Week1/assignment/ex1-johnWho.js index b2dc2b4ac..7683823c0 100644 --- a/3-UsingAPIs/Week1/assignment/ex1-johnWho.js +++ b/3-UsingAPIs/Week1/assignment/ex1-johnWho.js @@ -7,7 +7,6 @@ Rewrite this function, but replace the callback syntax with the Promise syntax: - If the Promise `rejects`, pass an error as the argument to reject with: "You didn't pass in a first name!" ------------------------------------------------------------------------------*/ -// TODO see above export const getAnonName = (firstName) => { return new Promise((resolve, reject) => { setTimeout(() => { diff --git a/3-UsingAPIs/Week1/assignment/ex3-rollDie.js b/3-UsingAPIs/Week1/assignment/ex3-rollDie.js index b278a8dc7..eb5250685 100644 --- a/3-UsingAPIs/Week1/assignment/ex3-rollDie.js +++ b/3-UsingAPIs/Week1/assignment/ex3-rollDie.js @@ -10,7 +10,6 @@ Full description at: https://github.com/HackYourFuture/Assignments/tree/main/3-U explanation? Add your answer as a comment to be bottom of the file. ------------------------------------------------------------------------------*/ -// TODO Remove callback and return a promise export function rollDie() { return new Promise((resolve, reject) => { @@ -25,7 +24,6 @@ export function rollDie() { // Use callback to notify that the die rolled off the table after 6 rolls if (roll > 6) { - // TODO replace "error" callback reject(new Error('Oops... Die rolled off the table.')); return; } @@ -37,7 +35,9 @@ export function rollDie() { } // Schedule the next roll todo until no more rolls to do + if (roll < randomRollsToDo) { setTimeout(() => rollOnce(roll + 1), 500); + } }; // Start the initial roll @@ -46,13 +46,12 @@ export function rollDie() { } function main() { - // TODO Refactor to use promise - rollDie(() => { - .then((value) => console.log(`Success! Die settled on ${value}.`)) - .catch((error) => console.log(error.message)); -} + rollDie() + .then(value => console.log(`Success! Die settled on ${value}.`)) + .catch(error => console.log(error.message)); } + // ! Do not change or remove the code below if (process.env.NODE_ENV !== 'test') { main();