From d4df6a48c8b6f1720b5fbd06c2ce2d6511b872cb Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 26 Jul 2026 19:20:57 +0100 Subject: [PATCH 01/17] fix the problem --- 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..500678113 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -12,4 +12,7 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address["houseNumber"]}`); +// to access the houseNumber of the object using bracket notation, +// we need to use the key as a string. In this case, "houseNumber" +// is the correct key, so the code should work as expected. From 9256b7f5bf8b60cc4f65bdceab3e80d26282a18a Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 27 Jul 2026 13:11:03 +0100 Subject: [PATCH 02/17] debug the code --- Sprint-2/debug/author.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..88dee3e5a 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -3,13 +3,18 @@ // 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 -const author = { - firstName: "Zadie", - lastName: "Smith", - occupation: "writer", - age: 40, - alive: true, -}; +// I think the issue with the original code is it was trying to loop over the object directly, +// which is not iterable. Instead, we should loop over the array that contains the object. + +const author = [ + { + firstName: "Zadie", + lastName: "Smith", + occupation: "writer", + age: 40, + alive: true, + }, +]; for (const value of author) { console.log(value); From 522cb564d58ec8f26c3482b8a0a18bf801288717 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 27 Jul 2026 13:18:29 +0100 Subject: [PATCH 03/17] debug, and fix code --- Sprint-2/debug/recipe.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..36cade6d0 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -12,4 +12,5 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: -${recipe}`); +${recipe.ingredients.join("\n")}`); //the DOT expression was missing in the original code. +// also adding a join method to the ingredients array to log each ingredient on a new line. From 5dcae6a49f6f6b33e9b9b4f80a1724424c5d9c6e Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 27 Jul 2026 14:08:02 +0100 Subject: [PATCH 04/17] add two tests and implement function acordingly --- Sprint-2/implement/contains.js | 4 +++- Sprint-2/implement/contains.test.js | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..61ea51616 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,5 @@ -function contains() {} +function contains(obj, prop) { + return prop in obj; // checks if the property exists in the object and returns true or false +} module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..f8ea9e9e1 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -16,11 +16,16 @@ as the object doesn't contains a key of 'c' // Given a contains function // When passed an object and a property name // Then it should return true if the object contains the property, false otherwise +test("contains an object returns true, or false otherwise", () => { + expect(contains({a: 1, b: 2, c: 3}, "a")).toBe(true); +}); // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); +test("contains on empty object returns false", () => { + expect(contains({}, "a")).toBe(false); +}); // Given an object with properties // When passed to contains with an existing property name From c68ec3e5df65687d5ee52d503a80740df2c74946 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 27 Jul 2026 14:13:38 +0100 Subject: [PATCH 05/17] add more tests --- Sprint-2/implement/contains.test.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index f8ea9e9e1..9701b0d8b 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -16,9 +16,7 @@ as the object doesn't contains a key of 'c' // Given a contains function // When passed an object and a property name // Then it should return true if the object contains the property, false otherwise -test("contains an object returns true, or false otherwise", () => { - expect(contains({a: 1, b: 2, c: 3}, "a")).toBe(true); -}); + // Given an empty object // When passed to contains @@ -30,11 +28,20 @@ test("contains on empty object returns false", () => { // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("contains an object returns true, or false otherwise", () => { + expect(contains({a: 1, b: 2, c: 3}, "a")).toBe(true); +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("contains an object returns true, or false otherwise", () => { + expect(contains({a: 1, b: 2, c: 3}, "d")).toBe(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test("contains an object returns true, or false otherwise", () => { + expect(contains([1, 2, 3, 'a'], "a")).toBe(false); +}); From bc5e89a67377d89a2ff249f0347b2b0aa7ec76e1 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 27 Jul 2026 14:49:44 +0100 Subject: [PATCH 06/17] implement createLookup() function --- Sprint-2/implement/lookup.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..95bd5e475 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,6 @@ -function createLookup() { - // implementation here +function createLookup(entries) { + let obj = Object.fromEntries(entries); + return obj; } -module.exports = createLookup; +module.exports = createLookup; \ No newline at end of file From 2114a9e3605ac10fcebcf9c7e9b1243cb78de05c Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 27 Jul 2026 16:08:46 +0100 Subject: [PATCH 07/17] write test --- Sprint-2/implement/lookup.test.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..65d5878e0 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,11 @@ 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", () => { + expect(createLookup([['US', 'USD'], ['CA', 'CAD']])).toEqual({ + 'US': 'USD', + 'CA': 'CAD' + }); +}); /* From 78041d6228ba22ca5dc00f9d8c5f5038862cddfd Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 2 Aug 2026 18:24:17 +0100 Subject: [PATCH 08/17] write complete function to meet the test requirements --- Sprint-2/implement/querystring.js | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..ff2f0b4a5 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,11 +3,31 @@ function parseQueryString(queryString) { if (queryString.length === 0) { return queryParams; } + queryString = queryString.replace(/\+/g, " "); const keyValuePairs = queryString.split("&"); - for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + if (pair === "") { + continue; + } + let key; + let value; + const index = pair.indexOf("="); + if (index === -1) { + key = decodeURIComponent(pair); + value = ""; + } else { + key = decodeURIComponent(pair.slice(0, index)); + value = decodeURIComponent(pair.slice(index + 1)); + } + if (!queryParams[key]) { + queryParams[key] = value; + } else { + if (Array.isArray(queryParams[key])) { + queryParams[key].push(value); + } else { + queryParams[key] = [queryParams[key], value]; + } + } } return queryParams; From 6d8eefd2c004e51889fc5668d0efb75e8db69e90 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 2 Aug 2026 21:35:42 +0100 Subject: [PATCH 09/17] write complete function to taly --- Sprint-2/implement/tally.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..961c8ebe9 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,20 @@ -function tally() {} +function tally(arr) { + let countOfItemsObj = {}; + if (!Array.isArray(arr)) { + throw new Error("Invalid input"); + } else if (arr.length < 1) { + return countOfItemsObj; + } else { + for (let element = 0; element < arr.length; element++) { + const exist = Object.hasOwn(countOfItemsObj, arr[element]); + if (!exist) { + countOfItemsObj[arr[element]] = 1; + } else { + countOfItemsObj[arr[element]] = countOfItemsObj[arr[element]] + 1; + } + } + } + return countOfItemsObj; +} module.exports = tally; From fbce304baddac1cf73003eb50ca2910d4903b4b1 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 2 Aug 2026 21:38:15 +0100 Subject: [PATCH 10/17] wrte tests --- Sprint-2/implement/tally.test.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..5284747d9 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,12 +23,20 @@ const tally = require("./tally.js"); // 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 on an array with duplicate items returns counts for each unique item", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("tally on an invalid input like a string throws an error", () => { + expect(() => tally("invalid input")).toThrow("Invalid input"); +}); From b10547d56264027c894a2227147fb43579f4e493 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Mon, 3 Aug 2026 10:20:13 +0100 Subject: [PATCH 11/17] fix function, write tests --- Sprint-2/interpret/invert.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..8cedb37da 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,40 @@ 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 } +// the current return value is { key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// current return value is { key: 2 } // c) What is the target return value when invert is called with {a : 1, b: 2} +// the target return value is { "1": "a", "2": "b" } // c) What does Object.entries return? Why is it needed in this program? +// Object.entries returns an array of key-value pairs from the object. It is needed +// in this program to iterate over each key-value pair in the object so that we can +// swap them and create a new inverted object. // d) Explain why the current return value is different from the target output +// I think current return value is different from the return value because the +// current implementation is not really swapping the properties of the object. +// Instead, it is just creating a new property called "key" and assigning the +// value to it. The target output requires us to swap the keys and values, which +// is not happening in the current implementation. // e) Fix the implementation of invert (and write tests to prove it's fixed!) +console.assert( + JSON.stringify(invert({ a: 1 })) === JSON.stringify({ "1": "a" }), + "Test 1 failed" +); + +console.assert( + JSON.stringify(invert({ a: 1, b: 2 })) === + JSON.stringify({ "1": "a", "2": "b" }), + "Test 2 failed" +); From 2dbe395b23f853e92edb18ad7aaea62479ef9e0b Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 9 Aug 2026 14:05:10 +0100 Subject: [PATCH 12/17] Fix author iteration by using Object.entries --- Sprint-2/debug/author.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 88dee3e5a..8be7fc47f 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -6,16 +6,15 @@ // I think the issue with the original code is it was trying to loop over the object directly, // which is not iterable. Instead, we should loop over the array that contains the object. -const author = [ +const author = { firstName: "Zadie", lastName: "Smith", occupation: "writer", age: 40, alive: true, - }, -]; + } -for (const value of author) { - console.log(value); +for (let [key, value] of Object.entries(author)) { + console.log(key, value); } From 91bfc231a542eee24df8d5c9c3462802827e9396 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 9 Aug 2026 15:20:15 +0100 Subject: [PATCH 13/17] Update property check to use hasOwnProperty --- Sprint-2/implement/contains.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 61ea51616..a8d359816 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,5 +1,5 @@ function contains(obj, prop) { - return prop in obj; // checks if the property exists in the object and returns true or false + return obj.hasOwnProperty(prop); // checks if the property exists in the object and returns true or false } module.exports = contains; From aa5ee6806149252817d26802a72eee0e4baa854f Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 9 Aug 2026 16:18:33 +0100 Subject: [PATCH 14/17] Update test case to check for array's indices --- Sprint-2/implement/contains.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 9701b0d8b..ac93fea13 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -43,5 +43,5 @@ test("contains an object returns true, or false otherwise", () => { // When passed to contains // Then it should return false or throw an error test("contains an object returns true, or false otherwise", () => { - expect(contains([1, 2, 3, 'a'], "a")).toBe(false); + expect(contains([1, 2, 3, 'a'], "0")).toBe(false); }); From 4349ed1443ffa3e3e5e56ad0215cada0e9dde90b Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 9 Aug 2026 16:20:25 +0100 Subject: [PATCH 15/17] Modify contains function to handle arrays Add check for arrays in contains function --- Sprint-2/implement/contains.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index a8d359816..f38484cd5 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,5 +1,6 @@ function contains(obj, prop) { - return obj.hasOwnProperty(prop); // checks if the property exists in the object and returns true or false + if (Array.isArray(obj)) { + return false; // returns false if an object contains an array + } + return obj.hasOwnProperty(prop); } - -module.exports = contains; From aff50e0c64b9f04404ea29a73c1a5f39f8dcc17d Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 9 Aug 2026 16:47:14 +0100 Subject: [PATCH 16/17] Fix loop index variable in tally function --- Sprint-2/implement/tally.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 961c8ebe9..0cee81429 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -5,16 +5,15 @@ function tally(arr) { } else if (arr.length < 1) { return countOfItemsObj; } else { - for (let element = 0; element < arr.length; element++) { - const exist = Object.hasOwn(countOfItemsObj, arr[element]); + for (let index = 0; index < arr.length; index++) { + const exist = Object.hasOwn(countOfItemsObj, arr [index]); if (!exist) { - countOfItemsObj[arr[element]] = 1; + countOfItemsObj[arr[index]] = 1; } else { - countOfItemsObj[arr[element]] = countOfItemsObj[arr[element]] + 1; + countOfItemsObj[arr[index]] = countOfItemsObj[arr[index]] + 1; } } } return countOfItemsObj; } - module.exports = tally; From 9ca3f78279f62d5090173125c0363bd9ec3ae600 Mon Sep 17 00:00:00 2001 From: vmoratti Date: Sun, 9 Aug 2026 23:33:58 +0100 Subject: [PATCH 17/17] Improve contains function property check Refactor contains function to handle null, undefined, and Number types. --- Sprint-2/implement/contains.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index f38484cd5..99d4dfe98 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,6 +1,7 @@ function contains(obj, prop) { - if (Array.isArray(obj)) { - return false; // returns false if an object contains an array - } + const notArray = !Array.isArray(obj); + if (obj === null || Array.isArray(obj) || obj === Number || obj === undefined) { + return false; + } return obj.hasOwnProperty(prop); }