From aa836e650a451f2d789322c075e159060992f353 Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:37:39 +0000 Subject: [PATCH 01/12] Sprint 2 debug: add prediction for address.js --- Sprint-2/debug/address.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..21a4e494c 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,5 +1,9 @@ // Predict and explain first... +// Prediction: address is an object, not an array. +// Using address[0] will return undefined because objects are accessed using keys, not indexes. +// So the output will be: "My house number is undefined" + // This code should log out the houseNumber from the address object // but it isn't working... // Fix anything that isn't working From 1acb7e117c21acdadca65d1f52585338f062c12e Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:38:41 +0000 Subject: [PATCH 02/12] Sprint 2: update package-lock.json after npm install --- Sprint-2/package-lock.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sprint-2/package-lock.json b/Sprint-2/package-lock.json index 9b4c725d6..ceda7296e 100644 --- a/Sprint-2/package-lock.json +++ b/Sprint-2/package-lock.json @@ -56,6 +56,7 @@ "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.25.7", @@ -1368,6 +1369,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001663", "electron-to-chromium": "^1.5.28", From 8d14398b1fd033aa906ebb07b04fe8d335c06ba3 Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:42:28 +0000 Subject: [PATCH 03/12] Sprint 2 debug: fix address.js by using object property instead of index --- Sprint-2/debug/address.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 21a4e494c..075fb08c9 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -16,4 +16,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); From e1211e98ebff154c0a373e29834346b49a872d5d Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:45:56 +0000 Subject: [PATCH 04/12] Sprint 2 debug: add prediction for author.js --- Sprint-2/debug/author.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..6fab9b0af 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,5 +1,10 @@ // Predict and explain first... +// Prediction: This code will throw an error. +// The error happens because "author is an object and objects are not iterable. +// The "for...of" loop only works with iterable objects like arrays or strings +// So the program will throw a type error + // 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 +16,6 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); +for (const key in author) { + console.log(author[key]); } From e3940401958be4cfcfa901cfd647adbee5c430b7 Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:48:31 +0000 Subject: [PATCH 05/12] Sprint 2 debug: fix author.js by iterating over object keys --- Sprint-2/debug/author.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 6fab9b0af..5307ba2c1 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -19,3 +19,4 @@ const author = { for (const key in author) { console.log(author[key]); } + From 018803e672b25c82dfbf47fc161e21d1d5727d47 Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:51:51 +0000 Subject: [PATCH 06/12] Sprint 2 debug: add prediction for recipe.js --- Sprint-2/debug/recipe.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..3b1dada82 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,5 +1,10 @@ // Predict and explain first... +// Prediction: The program may print [object Object]" instead of the ingredients. +// This happens because recipe is an object, and printing an object inside a string +// converts it to "[object Object]". +// The ingredients array should be printed instead, with each ingredient on a new line. + // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line // How can you fix it? From ef9b0b1cad687203f84797076d7d57866f5861db Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:53:02 +0000 Subject: [PATCH 07/12] Sprint 2 debug: fix recipe.js to print ingredients correctly --- Sprint-2/debug/recipe.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 3b1dada82..c03dfeabc 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -16,5 +16,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +ingredients: +${recipe.ingredients.join("\n")}`); From b34749c893011881f32ac4858259062cdf0659dd Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:56:30 +0000 Subject: [PATCH 08/12] Sprint 2 implement: add contains function --- Sprint-2/implement/contains.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..3665f85ca 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,9 @@ -function contains() {} +function contains(object, propertyName) { + if (typeof object !== "object" || object === null || Array.isArray(object)) { + return false; + } -module.exports = contains; + return Object.prototype.hasOwnProperty.call(object, propertyName); +} + +module.exports = contains; \ No newline at end of file From 66182faf1dc172de58ddeea6006214c0431ed74b Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 14:59:29 +0000 Subject: [PATCH 09/12] Sprint 2 implement: add createLookup function --- Sprint-2/implement/lookup.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..980148ae4 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,14 @@ -function createLookup() { - // implementation here +function createLookup(countryCurrencyPairs) { + const lookup = {}; + + for (const pair of countryCurrencyPairs) { + const country = pair[0]; + const currency = pair[1]; + + lookup[country] = currency; + } + + return lookup; } -module.exports = createLookup; +module.exports = createLookup; \ No newline at end of file From 39864e7f62ffea30ea552bc5543eabe3216c9c13 Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 15:01:33 +0000 Subject: [PATCH 10/12] Sprint 2 implement: handle '=' inside querystring values --- Sprint-2/implement/querystring.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..a81a3e0b1 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,14 +3,16 @@ function parseQueryString(queryString) { if (queryString.length === 0) { return queryParams; } + const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + const [key, ...rest] = pair.split("="); + const value = rest.join("="); queryParams[key] = value; } return queryParams; } -module.exports = parseQueryString; +module.exports = parseQueryString; \ No newline at end of file From 03edbba32122823780a860940c91173650acde82 Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 15:03:44 +0000 Subject: [PATCH 11/12] Sprint 2 implement: add tally function to count array items --- Sprint-2/implement/tally.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..82fe688f1 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("Input must be an array"); + } -module.exports = tally; + const counts = {}; + + for (const item of items) { + if (counts[item]) { + counts[item] += 1; + } else { + counts[item] = 1; + } + } + + return counts; +} + +module.exports = tally; \ No newline at end of file From 5e77530218809710b53fcd05f91f307d0d1a6b6b Mon Sep 17 00:00:00 2001 From: Laura C Date: Wed, 4 Mar 2026 15:12:43 +0000 Subject: [PATCH 12/12] Sprint 2 interpret: fix invert implementation and answer questions --- Sprint-2/interpret/invert.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..87530c8c5 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,29 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; } // a) What is the current return value when invert is called with { a : 1 } +// With the buggy implementation (invertedObj.key = value), the result is: +// { key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// { key: 2 } +// because the property key" is overwritten in each loop iteration // 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? +// d) What does Object.entries return? Why is it needed in this program? +// Object.entries(obj) returns an array of [key, value] pairs. +// Example: Object.entries( {a:1,b:2}) → [['a',1],['b',2]] +// It allows us to loop through both the keys and values of the object. -// 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!) +// e) Explain why the current return value is different from the target output +// Because the buggy code used invertedObj.key = value +// which creates a property literally called "key +// Instead, we need to use invertedObj[value] = key to swap keys and values