From aeabc14b14d4745f580b105a8801b761968dc267 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Fri, 14 Nov 2025 12:05:06 +0000 Subject: [PATCH 01/32] Fix the bug in address.js file --- Sprint-2/debug/address.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..b99ea43cf 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,4 +1,7 @@ // Predict and explain first... +//Prediction: The will be an error at ${address[0]}. +//Explanation: calling an object using the index as in array. Instead we should use the dot method(.address) or the brackets["address"]. + // This code should log out the houseNumber from the address object // but it isn't working... @@ -12,4 +15,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); From 26642e01fabfbd9c4736a214e9119e8d026d37e1 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Fri, 14 Nov 2025 12:18:58 +0000 Subject: [PATCH 02/32] Fix the bug in author.js file --- Sprint-2/debug/author.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..3a540064c 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,6 @@ // Predict and explain first... +// Prediction: Going to shows an error in the for loop. +// Explanation: we should have used the for .. in method (The for...in statement iterates over all enumerable string properties of an object (ignoring properties keyed by symbols), including inherited enumerable properties.) // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem @@ -11,6 +13,6 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); +for (const value in author){ + console.log(`${value}: ${author[value]}`); } From ab693e347811f9c459b3643a69bc61c6e0213db4 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Fri, 14 Nov 2025 12:26:15 +0000 Subject: [PATCH 03/32] Fix the bug in recipe.js file --- Sprint-2/debug/recipe.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..bebef6316 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,4 +1,6 @@ // Predict and explain first... +// Prediction: An error in logging out the ingredients. +// Explanation: Because of the way to get the value or an element from an array should used the dot notation for example and reach each element using its index. // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line @@ -12,4 +14,7 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: -${recipe}`); +${recipe.ingredients[0]} +${recipe.ingredients[1]} +${recipe.ingredients[2]} +${recipe.ingredients[3]}`); From 710514624ee9a1681a94d09a8d7b1cdde2e288fa Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 13:58:26 +0000 Subject: [PATCH 04/32] Implement a function in contains.js file --- Sprint-2/implement/contains.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..2716d7051 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,9 @@ -function contains() {} +function contains(input, propertyName) { + if (input && typeof input === 'object' && !Array.isArray(input)) { + return input.hasOwnProperty(propertyName); + } + return false; + +} module.exports = contains; From 19ca88dea3971087ee3ef1939d6f3ef158c739ce Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 13:59:07 +0000 Subject: [PATCH 05/32] Adding tests in contains.test.js file --- Sprint-2/implement/contains.test.js | 46 ++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..3f7778611 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -17,19 +17,63 @@ as the object doesn't contains a key of 'c' // When passed an object and a property name // Then it should return true if the object contains the property, false otherwise +test("given an object contains a property name, returns true", function (){ + const input = {a: 1, b: 2}; + const propertyName = 'a'; + const currentOutput = contains(input, propertyName); + const targetOutput = true; + + expect(currentOutput).toEqual(targetOutput); +}); + // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); + +test("given an empty object, returns false", function (){ + const input = {}; + const propertyName = 'a'; + const currentOutput = contains(input, propertyName); + const targetOutput = false; + + expect(currentOutput).toEqual(targetOutput); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("given an object contains a property name, returns true", function (){ + const input = {a: 1, b: 2}; + const propertyName = 'a'; + const currentOutput = contains(input, propertyName); + const targetOutput = true; + + expect(currentOutput).toEqual(targetOutput); +}); + // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("given an object does not contain a property name, returns false", function (){ + const input = {a: 1, b: 2}; + const propertyName = 'c'; + const currentOutput = contains(input, propertyName); + const targetOutput = false; + + expect(currentOutput).toEqual(targetOutput); +}); + // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error + +test("given invalid parameters like an array, returns false", function (){ + const input = [1, 2, 3]; + const propertyName = 'a'; + const currentOutput = contains(input, propertyName); + const targetOutput = false; + + expect(currentOutput).toEqual(targetOutput); +}); \ No newline at end of file From 63b7d455fc99dc64cdb68ebb23ae3e70b2ced624 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 14:21:02 +0000 Subject: [PATCH 06/32] Implementing a function in lookup.js file --- Sprint-2/implement/lookup.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..1accb2d54 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,11 @@ -function createLookup() { - // implementation here +function createLookup(pairs) { + const lookup = {}; + + for (const [country, currency] of pairs) { + lookup[country] = currency; + } + + return lookup; } -module.exports = createLookup; +module.exports = createLookup; \ No newline at end of file From ed3cee8f3f32041fc6407428e2738a7a4669bf7c Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 14:21:23 +0000 Subject: [PATCH 07/32] Adding tests in lookup.test.js file --- Sprint-2/implement/lookup.test.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..0838285d4 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,7 +1,20 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); - +test("creates a country currency code lookup for multiple codes", () => { + const input = [ + ["US", "USD"], + ["CA", "CAD"], + ["GB", "GBP"], + ]; + + const result = createLookup(input); + + expect(result).toEqual({ + US: "USD", + CA: "CAD", + GB: "GBP", + }); +}); /* Create a lookup object of key value pairs from an array of code pairs From 1babce8a07a48bbec54a6b61372224d90261d32b Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 15:15:42 +0000 Subject: [PATCH 08/32] Fix the implement function in querysrting.js file --- Sprint-2/implement/querystring.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..334e259dd 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,12 +1,33 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { + + if (!queryString) { return queryParams; } + + if (queryString.startsWith("?")) { + queryString = queryString.slice(1); + } + const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + if (!pair) continue; + + const firstEq = pair.indexOf("="); + + let key; + let value; + + if (firstEq === -1) { + + key = pair; + value = ""; + } else { + key = pair.slice(0, firstEq); + value = pair.slice(firstEq + 1); + } + queryParams[key] = value; } From fd422f1d9c7266fac783a8ea37e2c3eb21546c3e Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 15:16:10 +0000 Subject: [PATCH 09/32] Adding tests in querystring.test.js file --- Sprint-2/implement/querystring.test.js | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..42ec0039d 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,31 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); + +test("parses multiple key=value pairs", () => { + expect(parseQueryString("a=1&b=2")).toEqual({ a: "1", b: "2" }); +}); + +test("handles empty value (a=)", () => { + expect(parseQueryString("a=")).toEqual({ a: "" }); +}); + +test("handles key with no '=' (a)", () => { + expect(parseQueryString("a")).toEqual({ a: "" }); +}); + +test("last value wins for repeated keys", () => { + expect(parseQueryString("a=1&a=2")).toEqual({ a: "2" }); +}); + +test("supports leading question mark", () => { + expect(parseQueryString("?a=1&b=2")).toEqual({ a: "1", b: "2" }); +}); + +test("ignores empty pairs from trailing or consecutive &", () => { + expect(parseQueryString("a=1&&b=2&")).toEqual({ a: "1", b: "2" }); +}); + +test("handles empty key (=value) producing empty-string key", () => { + expect(parseQueryString("=value")).toEqual({ "": "value" }); +}); \ No newline at end of file From 9279df9adbdbc2f13fd1f7136ad21a870995ebea Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 15:22:14 +0000 Subject: [PATCH 10/32] Fix the implement function in tally.js file --- Sprint-2/implement/tally.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..831ae67e2 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,19 @@ -function tally() {} +function tally(items) { + if (!Array.isArray(items)) { + throw new Error("tally expects an array"); + } + + const counts = {}; + + for (const item of items) { + if (counts[item] === undefined) { + counts[item] = 1; + } else { + counts[item] += 1; + } + } + + return counts; +} module.exports = tally; From 1c6ccc3cc5656df997c0b0e8a321942efe66ff0f Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 15:22:30 +0000 Subject: [PATCH 11/32] Adding tests in tally.test.js file --- Sprint-2/implement/tally.test.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..8a8893067 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -19,16 +19,37 @@ const tally = require("./tally.js"); // Given a function called tally // When passed an array of items // Then it should return an object containing the count for each unique item +test("tally returns counts for each unique item", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ + a: 2, + b: 1, + c: 1, + }); +}); // Given an empty array // When passed to tally // Then it should return an empty object -test.todo("tally on an empty array returns an empty object"); +test("tally on an empty array returns an empty object", () => { + expect(tally([])).toEqual({}); +}); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test("tally counts each unique item", () => { + expect(tally(["a", "a", "b", "c", "a"])).toEqual({ + a: 3, + b: 1, + c: 1, + }); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("tally throws an error when given a non-array", () => { + expect(() => tally("not an array")).toThrow(); + expect(() => tally(123)).toThrow(); + expect(() => tally({})).toThrow(); +}); \ No newline at end of file From 8465e56c93abf81706f0a6731bf1e0d7cdbd6e12 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Sun, 16 Nov 2025 15:39:12 +0000 Subject: [PATCH 12/32] Answering questions and fix the implemention and adding tests --- Sprint-2/interpret/invert.js | 48 ++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..7c7aa6230 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -16,14 +16,52 @@ function invert(obj) { return invertedObj; } -// a) What is the current return value when invert is called with { a : 1 } +// a) What is the current return value when invert is called with { a : 1 } >> { key: 1 } -// b) What is the current return value when invert is called with { a: 1, b: 2 } +// b) What is the current return value when invert is called with { a: 1, b: 2 } >> { key: 2 } -// c) What is the target return value when invert is called with {a : 1, b: 2} +// c) What is the target return value when invert is called with {a : 1, b: 2} >> { "1": "a", "2": "b" } -// c) What does Object.entries return? Why is it needed in this program? +// c) What does Object.entries return? Why is it needed in this program? >> Object.entries returns an array of key-value paris. -// d) Explain why the current return value is different from the target output +// d) Explain why the current return value is different from the target output >> Because invertedObj.key = value creates a property called (key) instead of using hte variable key. // e) Fix the implementation of invert (and write tests to prove it's fixed!) +// The fixed code: +function invert(obj) { + const invertedObj = {}; + + for (const [key, value] of Object.entries(obj)) { + invertedObj[value] = key; + } + + return invertedObj; +} + +module.exports = invert; + +// Tests: +const invert = require("./invert.js"); + +// Single key +test("invert works for one key-value pair", () => { + expect(invert({ a: 1 })).toEqual({ "1": "a" }); +}); + +// Multiple keys +test("invert swaps keys and values for multiple pairs", () => { + expect(invert({ a: 1, b: 2 })).toEqual({ + "1": "a", + "2": "b", + }); +}); + +// Empty object +test("invert of an empty object returns empty", () => { + expect(invert({})).toEqual({}); +}); + +// Values become string keys +test("invert always returns string keys", () => { + expect(invert({ x: 10 })).toEqual({ "10": "x" }); +}); From 81769d1f3162f57b19910ad0be372a298b8cee18 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 24 Nov 2025 17:15:39 +0000 Subject: [PATCH 13/32] Adding implementation and test to the file --- Sprint-2/stretch/count-words.js | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Sprint-2/stretch/count-words.js b/Sprint-2/stretch/count-words.js index 8e85d19d7..f805275ba 100644 --- a/Sprint-2/stretch/count-words.js +++ b/Sprint-2/stretch/count-words.js @@ -26,3 +26,51 @@ 3. Order the results to find out which word is the most common in the input */ + + + +/* The implementation: +function countWords(str) { + const result = {}; + + if (!str || str.trim().length === 0) { + return result; + } + + const words = str.split(" "); + + for (const word of words) { + if (result[word] === undefined) { + result[word] = 1; + } else { + result[word] += 1; + } + } + + return result; +} + +module.exports = countWords; +*/ + +/* The tests: + +const countWords = require("./countWords.js"); + +test("counts words from a string", () => { + expect(countWords("you and me and you")).toEqual({ + you: 2, + and: 2, + me: 1, + }); +}); + +test("returns empty object for empty string", () => { + expect(countWords("")).toEqual({}); + expect(countWords(" ")).toEqual({}); +}); + +test("counts correctly with single word", () => { + expect(countWords("hello")).toEqual({ hello: 1 }); +}); +*/ \ No newline at end of file From d5a5bcde6ad8b32b809a21ec74d83d041fd4caac Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 24 Nov 2025 17:17:46 +0000 Subject: [PATCH 14/32] Answering questions --- Sprint-2/stretch/mode.js | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Sprint-2/stretch/mode.js b/Sprint-2/stretch/mode.js index 3f7609d79..f1dfd8bec 100644 --- a/Sprint-2/stretch/mode.js +++ b/Sprint-2/stretch/mode.js @@ -8,29 +8,38 @@ // refactor calculateMode by splitting up the code // into smaller functions using the stages above -function calculateMode(list) { - // track frequency of each value - let freqs = new Map(); - - for (let num of list) { - if (typeof num !== "number") { - continue; - } +// Stage 1: count frequencies +function countFrequencies(list) { + const freqs = new Map(); + for (const num of list) { + if (typeof num !== "number") continue; freqs.set(num, (freqs.get(num) || 0) + 1); } - // Find the value with the highest frequency + return freqs; +} + +// Stage 2: find the value with highest frequency +function findMode(freqs) { let maxFreq = 0; let mode; - for (let [num, freq] of freqs) { + + for (const [num, freq] of freqs.entries()) { if (freq > maxFreq) { - mode = num; maxFreq = freq; + mode = num; } } return maxFreq === 0 ? NaN : mode; } +// Main function +function calculateMode(list) { + const freqs = countFrequencies(list); + return findMode(freqs); +} + module.exports = calculateMode; + From f5a92f8841a3ab888ea04efe6b354dac25109b9e Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 24 Nov 2025 17:20:07 +0000 Subject: [PATCH 15/32] Answering till.js questions --- Sprint-2/stretch/till.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Sprint-2/stretch/till.js b/Sprint-2/stretch/till.js index 6a08532e7..d47c4b906 100644 --- a/Sprint-2/stretch/till.js +++ b/Sprint-2/stretch/till.js @@ -22,10 +22,32 @@ const till = { }; const totalAmount = totalTill(till); -// a) What is the target output when totalTill is called with the till object +// a) What is the target output when totalTill is called with the till object >> "£4.40" -// b) Why do we need to use Object.entries inside the for...of loop in this function? +// b) Why do we need to use Object.entries inside the for...of loop in this function? >> To iterate over both the keys (coin types) and values (quantities) of the till object. -// c) What does coin * quantity evaluate to inside the for...of loop? +// c) What does coin * quantity evaluate to inside the for...of loop? >> It evaluates to NaN because coin is a string (e.g., "1p") and cannot be directly multiplied by a number (quantity). // d) Write a test for this function to check it works and then fix the implementation of totalTill + +// Fixed implementation +function totalTillFixed(till) { + let total = 0; + + for (const [coin, quantity] of Object.entries(till)) { + const coinValue = parseInt(coin); + total += coinValue * quantity; + } + + return `£${(total / 100).toFixed(2)}`; +} + +// Test +const tillTest = { + "1p": 10, + "5p": 6, + "50p": 4, + "20p": 10, +}; +const totalAmountTest = totalTillFixed(tillTest); +console.log(totalAmountTest); From 6d8e6c5c7adef99af1abe444230a002af7b95282 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Wed, 26 Nov 2025 14:56:29 +0000 Subject: [PATCH 16/32] Implementing a alarmclock function --- Sprint-3/alarmclock/alarmclock.js | 34 ++++++++++++++++++- Sprint-3/alarmclock/alarmclock.test.js | 2 +- .../{index.html => alarmclockapp.html} | 0 3 files changed, 34 insertions(+), 2 deletions(-) rename Sprint-3/alarmclock/{index.html => alarmclockapp.html} (100%) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..4f99379d9 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,36 @@ -function setAlarm() {} +function setAlarm() { + let time = Number(document.getElementById("alarmSet").value); + const heading = document.getElementById("timeRemaining"); + + audio.loop = true; + + document.body.style.backgroundColor = ""; + + function updateDisplay(t) { + const minutes = String(Math.floor(t / 60)).padStart(2, "0"); + const seconds = String(t % 60).padStart(2, "0"); + heading.innerText = `Time Remaining: ${minutes}:${seconds}`; + } + + updateDisplay(time); + + const intervalId = setInterval(() => { + time--; + + if (time <= 0) { + clearInterval(intervalId); + updateDisplay(0); + + document.body.style.backgroundColor = "red"; + + playAlarm(); + + } else { + updateDisplay(time); + } + }, 1000); +} + // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/alarmclock.test.js b/Sprint-3/alarmclock/alarmclock.test.js index 85b7356dc..9abeb618b 100644 --- a/Sprint-3/alarmclock/alarmclock.test.js +++ b/Sprint-3/alarmclock/alarmclock.test.js @@ -8,7 +8,7 @@ const { JSDOM } = require("jsdom"); let page = null; beforeEach(async () => { - page = await JSDOM.fromFile(path.join(__dirname, "index.html"), { + page = await JSDOM.fromFile(path.join(__dirname, "alarmclockapp.html"), { resources: "usable", runScripts: "dangerously", }); diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/alarmclockapp.html similarity index 100% rename from Sprint-3/alarmclock/index.html rename to Sprint-3/alarmclock/alarmclockapp.html From 7221a18718793e9e97b462d67861b10aeee7096f Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Wed, 26 Nov 2025 15:01:06 +0000 Subject: [PATCH 17/32] Editing file index.html --- Sprint-3/alarmclock/{alarmclockapp.html => index.html} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Sprint-3/alarmclock/{alarmclockapp.html => index.html} (94%) diff --git a/Sprint-3/alarmclock/alarmclockapp.html b/Sprint-3/alarmclock/index.html similarity index 94% rename from Sprint-3/alarmclock/alarmclockapp.html rename to Sprint-3/alarmclock/index.html index 48e2e80d9..4a91379d3 100644 --- a/Sprint-3/alarmclock/alarmclockapp.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Title here + Alarm Clock App
From b6b3f4af71fd2f703ad0b09530e238e6eaecdffb Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Wed, 26 Nov 2025 15:33:52 +0000 Subject: [PATCH 18/32] Editing file index.html and quotes.js files --- Sprint-3/quote-generator/index.html | 13 ++++++++----- Sprint-3/quote-generator/quotes.js | 13 +++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..6001b2f42 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,13 +3,16 @@ - Title here + Quote Generator App -

hello there

-

-

- +

Quote Generator App

+
+

+

+ +
+ diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..fcdd3d897 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -20,6 +20,19 @@ function pickFromArray(choices) { return choices[Math.floor(Math.random() * choices.length)]; } +function showRandomQuote() { + const randomQuote = pickFromArray(quotes); + const quoteText = document.getElementById("quote-text"); + const quoteAuthor = document.getElementById("quote-author"); + + quoteText.innerText = randomQuote.quote; + quoteAuthor.innerText = `— ${randomQuote.author}`; +} + +window.onload = showRandomQuote; + +document.getElementById("new-quote-button").addEventListener("click", showRandomQuote); + // A list of quotes you can use in your app. // DO NOT modify this array, otherwise the tests may break! const quotes = [ From 70e0519cee0a05ee5f9e779de86524288ac17fc8 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:00:43 +0000 Subject: [PATCH 19/32] Revert "Editing file index.html and quotes.js files" This reverts commit b6b3f4af71fd2f703ad0b09530e238e6eaecdffb. --- Sprint-3/quote-generator/index.html | 13 +++++-------- Sprint-3/quote-generator/quotes.js | 13 ------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 6001b2f42..30b434bcf 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,16 +3,13 @@ - Quote Generator App + Title here -

Quote Generator App

-
-

-

- -
- +

hello there

+

+

+ diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index fcdd3d897..4a4d04b72 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -20,19 +20,6 @@ function pickFromArray(choices) { return choices[Math.floor(Math.random() * choices.length)]; } -function showRandomQuote() { - const randomQuote = pickFromArray(quotes); - const quoteText = document.getElementById("quote-text"); - const quoteAuthor = document.getElementById("quote-author"); - - quoteText.innerText = randomQuote.quote; - quoteAuthor.innerText = `— ${randomQuote.author}`; -} - -window.onload = showRandomQuote; - -document.getElementById("new-quote-button").addEventListener("click", showRandomQuote); - // A list of quotes you can use in your app. // DO NOT modify this array, otherwise the tests may break! const quotes = [ From 5ad1f39068cf5b4824ceff8e7ecf6e6b332235b7 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:00:51 +0000 Subject: [PATCH 20/32] Revert "Editing file index.html" This reverts commit 7221a18718793e9e97b462d67861b10aeee7096f. --- Sprint-3/alarmclock/{index.html => alarmclockapp.html} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Sprint-3/alarmclock/{index.html => alarmclockapp.html} (94%) diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/alarmclockapp.html similarity index 94% rename from Sprint-3/alarmclock/index.html rename to Sprint-3/alarmclock/alarmclockapp.html index 4a91379d3..48e2e80d9 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/alarmclockapp.html @@ -4,7 +4,7 @@ - Alarm Clock App + Title here
From 413577b4b53b90178f89f6c4ff1f64cdb137bb02 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:02 +0000 Subject: [PATCH 21/32] Revert "Implementing a alarmclock function" This reverts commit 6d8e6c5c7adef99af1abe444230a002af7b95282. --- Sprint-3/alarmclock/alarmclock.js | 34 +------------------ Sprint-3/alarmclock/alarmclock.test.js | 2 +- .../{alarmclockapp.html => index.html} | 0 3 files changed, 2 insertions(+), 34 deletions(-) rename Sprint-3/alarmclock/{alarmclockapp.html => index.html} (100%) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 4f99379d9..6ca81cd3b 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,36 +1,4 @@ -function setAlarm() { - let time = Number(document.getElementById("alarmSet").value); - const heading = document.getElementById("timeRemaining"); - - audio.loop = true; - - document.body.style.backgroundColor = ""; - - function updateDisplay(t) { - const minutes = String(Math.floor(t / 60)).padStart(2, "0"); - const seconds = String(t % 60).padStart(2, "0"); - heading.innerText = `Time Remaining: ${minutes}:${seconds}`; - } - - updateDisplay(time); - - const intervalId = setInterval(() => { - time--; - - if (time <= 0) { - clearInterval(intervalId); - updateDisplay(0); - - document.body.style.backgroundColor = "red"; - - playAlarm(); - - } else { - updateDisplay(time); - } - }, 1000); -} - +function setAlarm() {} // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/alarmclock.test.js b/Sprint-3/alarmclock/alarmclock.test.js index 9abeb618b..85b7356dc 100644 --- a/Sprint-3/alarmclock/alarmclock.test.js +++ b/Sprint-3/alarmclock/alarmclock.test.js @@ -8,7 +8,7 @@ const { JSDOM } = require("jsdom"); let page = null; beforeEach(async () => { - page = await JSDOM.fromFile(path.join(__dirname, "alarmclockapp.html"), { + page = await JSDOM.fromFile(path.join(__dirname, "index.html"), { resources: "usable", runScripts: "dangerously", }); diff --git a/Sprint-3/alarmclock/alarmclockapp.html b/Sprint-3/alarmclock/index.html similarity index 100% rename from Sprint-3/alarmclock/alarmclockapp.html rename to Sprint-3/alarmclock/index.html From 67ecaaaf70ac40cf270d39ac9fae0a00debafaaa Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:09 +0000 Subject: [PATCH 22/32] Revert "Answering till.js questions" This reverts commit f5a92f8841a3ab888ea04efe6b354dac25109b9e. --- Sprint-2/stretch/till.js | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/Sprint-2/stretch/till.js b/Sprint-2/stretch/till.js index d47c4b906..6a08532e7 100644 --- a/Sprint-2/stretch/till.js +++ b/Sprint-2/stretch/till.js @@ -22,32 +22,10 @@ const till = { }; const totalAmount = totalTill(till); -// a) What is the target output when totalTill is called with the till object >> "£4.40" +// a) What is the target output when totalTill is called with the till object -// b) Why do we need to use Object.entries inside the for...of loop in this function? >> To iterate over both the keys (coin types) and values (quantities) of the till object. +// b) Why do we need to use Object.entries inside the for...of loop in this function? -// c) What does coin * quantity evaluate to inside the for...of loop? >> It evaluates to NaN because coin is a string (e.g., "1p") and cannot be directly multiplied by a number (quantity). +// c) What does coin * quantity evaluate to inside the for...of loop? // d) Write a test for this function to check it works and then fix the implementation of totalTill - -// Fixed implementation -function totalTillFixed(till) { - let total = 0; - - for (const [coin, quantity] of Object.entries(till)) { - const coinValue = parseInt(coin); - total += coinValue * quantity; - } - - return `£${(total / 100).toFixed(2)}`; -} - -// Test -const tillTest = { - "1p": 10, - "5p": 6, - "50p": 4, - "20p": 10, -}; -const totalAmountTest = totalTillFixed(tillTest); -console.log(totalAmountTest); From 0939554ac0a2e3a94f2bf1f797f28b3dd35bb48f Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:18 +0000 Subject: [PATCH 23/32] Revert "Answering questions" This reverts commit d5a5bcde6ad8b32b809a21ec74d83d041fd4caac. --- Sprint-2/stretch/mode.js | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/Sprint-2/stretch/mode.js b/Sprint-2/stretch/mode.js index f1dfd8bec..3f7609d79 100644 --- a/Sprint-2/stretch/mode.js +++ b/Sprint-2/stretch/mode.js @@ -8,38 +8,29 @@ // refactor calculateMode by splitting up the code // into smaller functions using the stages above -// Stage 1: count frequencies -function countFrequencies(list) { - const freqs = new Map(); +function calculateMode(list) { + // track frequency of each value + let freqs = new Map(); + + for (let num of list) { + if (typeof num !== "number") { + continue; + } - for (const num of list) { - if (typeof num !== "number") continue; freqs.set(num, (freqs.get(num) || 0) + 1); } - return freqs; -} - -// Stage 2: find the value with highest frequency -function findMode(freqs) { + // Find the value with the highest frequency let maxFreq = 0; let mode; - - for (const [num, freq] of freqs.entries()) { + for (let [num, freq] of freqs) { if (freq > maxFreq) { - maxFreq = freq; mode = num; + maxFreq = freq; } } return maxFreq === 0 ? NaN : mode; } -// Main function -function calculateMode(list) { - const freqs = countFrequencies(list); - return findMode(freqs); -} - module.exports = calculateMode; - From 0d54919e8b8a5734d774e12e98ae959e8aa45e8f Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:25 +0000 Subject: [PATCH 24/32] Revert "Adding implementation and test to the file" This reverts commit 81769d1f3162f57b19910ad0be372a298b8cee18. --- Sprint-2/stretch/count-words.js | 48 --------------------------------- 1 file changed, 48 deletions(-) diff --git a/Sprint-2/stretch/count-words.js b/Sprint-2/stretch/count-words.js index f805275ba..8e85d19d7 100644 --- a/Sprint-2/stretch/count-words.js +++ b/Sprint-2/stretch/count-words.js @@ -26,51 +26,3 @@ 3. Order the results to find out which word is the most common in the input */ - - - -/* The implementation: -function countWords(str) { - const result = {}; - - if (!str || str.trim().length === 0) { - return result; - } - - const words = str.split(" "); - - for (const word of words) { - if (result[word] === undefined) { - result[word] = 1; - } else { - result[word] += 1; - } - } - - return result; -} - -module.exports = countWords; -*/ - -/* The tests: - -const countWords = require("./countWords.js"); - -test("counts words from a string", () => { - expect(countWords("you and me and you")).toEqual({ - you: 2, - and: 2, - me: 1, - }); -}); - -test("returns empty object for empty string", () => { - expect(countWords("")).toEqual({}); - expect(countWords(" ")).toEqual({}); -}); - -test("counts correctly with single word", () => { - expect(countWords("hello")).toEqual({ hello: 1 }); -}); -*/ \ No newline at end of file From 206b392b0fe71d22772f0d9c8b6fef5a5330aa52 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:32 +0000 Subject: [PATCH 25/32] Revert "Answering questions and fix the implemention and adding tests" This reverts commit 8465e56c93abf81706f0a6731bf1e0d7cdbd6e12. --- Sprint-2/interpret/invert.js | 48 ++++-------------------------------- 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 7c7aa6230..bb353fb1f 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -16,52 +16,14 @@ function invert(obj) { return invertedObj; } -// a) What is the current return value when invert is called with { a : 1 } >> { key: 1 } +// a) What is the current return value when invert is called with { a : 1 } -// b) What is the current return value when invert is called with { a: 1, b: 2 } >> { key: 2 } +// b) What is the current return value when invert is called with { a: 1, b: 2 } -// c) What is the target return value when invert is called with {a : 1, b: 2} >> { "1": "a", "2": "b" } +// c) What is the target return value when invert is called with {a : 1, b: 2} -// c) What does Object.entries return? Why is it needed in this program? >> Object.entries returns an array of key-value paris. +// c) What does Object.entries return? Why is it needed in this program? -// d) Explain why the current return value is different from the target output >> Because invertedObj.key = value creates a property called (key) instead of using hte variable key. +// d) Explain why the current return value is different from the target output // e) Fix the implementation of invert (and write tests to prove it's fixed!) -// The fixed code: -function invert(obj) { - const invertedObj = {}; - - for (const [key, value] of Object.entries(obj)) { - invertedObj[value] = key; - } - - return invertedObj; -} - -module.exports = invert; - -// Tests: -const invert = require("./invert.js"); - -// Single key -test("invert works for one key-value pair", () => { - expect(invert({ a: 1 })).toEqual({ "1": "a" }); -}); - -// Multiple keys -test("invert swaps keys and values for multiple pairs", () => { - expect(invert({ a: 1, b: 2 })).toEqual({ - "1": "a", - "2": "b", - }); -}); - -// Empty object -test("invert of an empty object returns empty", () => { - expect(invert({})).toEqual({}); -}); - -// Values become string keys -test("invert always returns string keys", () => { - expect(invert({ x: 10 })).toEqual({ "10": "x" }); -}); From 75e0482be0b1f1b703e642a441d32345c63571a4 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:39 +0000 Subject: [PATCH 26/32] Revert "Adding tests in tally.test.js file" This reverts commit 1c6ccc3cc5656df997c0b0e8a321942efe66ff0f. --- Sprint-2/implement/tally.test.js | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 8a8893067..2ceffa8dd 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -19,37 +19,16 @@ const tally = require("./tally.js"); // Given a function called tally // When passed an array of items // Then it should return an object containing the count for each unique item -test("tally returns counts for each unique item", () => { - expect(tally(["a", "a", "b", "c"])).toEqual({ - a: 2, - b: 1, - c: 1, - }); -}); // Given an empty array // When passed to tally // Then it should return an empty object -test("tally on an empty array returns an empty object", () => { - expect(tally([])).toEqual({}); -}); +test.todo("tally on an empty array returns an empty object"); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item -test("tally counts each unique item", () => { - expect(tally(["a", "a", "b", "c", "a"])).toEqual({ - a: 3, - b: 1, - c: 1, - }); -}); // Given an invalid input like a string // When passed to tally // Then it should throw an error -test("tally throws an error when given a non-array", () => { - expect(() => tally("not an array")).toThrow(); - expect(() => tally(123)).toThrow(); - expect(() => tally({})).toThrow(); -}); \ No newline at end of file From 8bb7f6accd0ad043cbb4445135f376d6bac4a49e Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:47 +0000 Subject: [PATCH 27/32] Revert "Fix the implement function in tally.js file" This reverts commit 9279df9adbdbc2f13fd1f7136ad21a870995ebea. --- Sprint-2/implement/tally.js | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 831ae67e2..f47321812 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,19 +1,3 @@ -function tally(items) { - if (!Array.isArray(items)) { - throw new Error("tally expects an array"); - } - - const counts = {}; - - for (const item of items) { - if (counts[item] === undefined) { - counts[item] = 1; - } else { - counts[item] += 1; - } - } - - return counts; -} +function tally() {} module.exports = tally; From 562022f84e72f984f0a8f9012f923a5fee2d466a Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:01:55 +0000 Subject: [PATCH 28/32] Revert "Adding tests in querystring.test.js file" This reverts commit fd422f1d9c7266fac783a8ea37e2c3eb21546c3e. --- Sprint-2/implement/querystring.test.js | 28 -------------------------- 1 file changed, 28 deletions(-) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 42ec0039d..3e218b789 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,31 +10,3 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); - -test("parses multiple key=value pairs", () => { - expect(parseQueryString("a=1&b=2")).toEqual({ a: "1", b: "2" }); -}); - -test("handles empty value (a=)", () => { - expect(parseQueryString("a=")).toEqual({ a: "" }); -}); - -test("handles key with no '=' (a)", () => { - expect(parseQueryString("a")).toEqual({ a: "" }); -}); - -test("last value wins for repeated keys", () => { - expect(parseQueryString("a=1&a=2")).toEqual({ a: "2" }); -}); - -test("supports leading question mark", () => { - expect(parseQueryString("?a=1&b=2")).toEqual({ a: "1", b: "2" }); -}); - -test("ignores empty pairs from trailing or consecutive &", () => { - expect(parseQueryString("a=1&&b=2&")).toEqual({ a: "1", b: "2" }); -}); - -test("handles empty key (=value) producing empty-string key", () => { - expect(parseQueryString("=value")).toEqual({ "": "value" }); -}); \ No newline at end of file From 62ef964f53cc8c0d9b7f1e329fb89946bb4cd93f Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:02:02 +0000 Subject: [PATCH 29/32] Revert "Fix the implement function in querysrting.js file" This reverts commit 1babce8a07a48bbec54a6b61372224d90261d32b. --- Sprint-2/implement/querystring.js | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 334e259dd..45ec4e5f3 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,33 +1,12 @@ function parseQueryString(queryString) { const queryParams = {}; - - if (!queryString) { + if (queryString.length === 0) { return queryParams; } - - if (queryString.startsWith("?")) { - queryString = queryString.slice(1); - } - const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - if (!pair) continue; - - const firstEq = pair.indexOf("="); - - let key; - let value; - - if (firstEq === -1) { - - key = pair; - value = ""; - } else { - key = pair.slice(0, firstEq); - value = pair.slice(firstEq + 1); - } - + const [key, value] = pair.split("="); queryParams[key] = value; } From 53775153a50ef3c9b98bcf54f59d366764f93ff5 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:02:08 +0000 Subject: [PATCH 30/32] Revert "Adding tests in lookup.test.js file" This reverts commit ed3cee8f3f32041fc6407428e2738a7a4669bf7c. --- Sprint-2/implement/lookup.test.js | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 0838285d4..547e06c5a 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,20 +1,7 @@ const createLookup = require("./lookup.js"); -test("creates a country currency code lookup for multiple codes", () => { - const input = [ - ["US", "USD"], - ["CA", "CAD"], - ["GB", "GBP"], - ]; - - const result = createLookup(input); - - expect(result).toEqual({ - US: "USD", - CA: "CAD", - GB: "GBP", - }); -}); +test.todo("creates a country currency code lookup for multiple codes"); + /* Create a lookup object of key value pairs from an array of code pairs From 9610268ce67fc2f35a2452adda3e8dea2f10a175 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:02:16 +0000 Subject: [PATCH 31/32] Revert "Implementing a function in lookup.js file" This reverts commit 63b7d455fc99dc64cdb68ebb23ae3e70b2ced624. --- Sprint-2/implement/lookup.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 1accb2d54..a6746e07f 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,11 +1,5 @@ -function createLookup(pairs) { - const lookup = {}; - - for (const [country, currency] of pairs) { - lookup[country] = currency; - } - - return lookup; +function createLookup() { + // implementation here } -module.exports = createLookup; \ No newline at end of file +module.exports = createLookup; From a657abbc476c29752885256d90e595fa31009d55 Mon Sep 17 00:00:00 2001 From: Fares Bakhet Date: Mon, 1 Dec 2025 15:16:28 +0000 Subject: [PATCH 32/32] Fix quotes generator app --- Sprint-3/quote-generator/index.html | 8 ++++++-- Sprint-3/quote-generator/quotes.js | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..cb9f3e860 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,13 +3,17 @@ - Title here - + Quote Generator App</A> +
+

hello there

+ +
+ diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..66c56caf8 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -1,3 +1,19 @@ +const quoteElem = document.getElementById("quote"); +const authorElem = document.getElementById("author"); +const button = document.getElementById("new-quote"); + +function showNewQuote() { + const random = pickFromArray(quotes); + quoteElem.textContent = random.quote; + authorElem.textContent = random.author; +} + +window.addEventListener("DOMContentLoaded", () => { + showNewQuote(); + + button.addEventListener("click", showNewQuote); +}); + // DO NOT EDIT BELOW HERE // pickFromArray is a function which will return one item, at