From bdef88040cfe295a78b7f3dd8bcac731188d3ab0 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 18:48:25 +0100 Subject: [PATCH 01/12] address.js --- Sprint-2/debug/address.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..e7e330cdf 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -13,3 +13,20 @@ const address = { }; console.log(`My house number is ${address[0]}`); + + +This code doesnot work because address[0] is calling objects not array. +Instead of using ${address[0]}, we should use $[address.houseNumber]. + + + + +const address = { + houseNumber: 42, + street: "Imaginary Road", + city: "Manchester", + country: "England", + postcode: "XYZ 123", +}; + +console.log(`My house number is ${address.houseNumber}`); \ No newline at end of file From 12f396a819f04a520003f2d3279547ee2be37740 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 18:52:27 +0100 Subject: [PATCH 02/12] author.js --- Sprint-2/debug/author.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..87abf932c 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -3,6 +3,7 @@ // 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", @@ -11,6 +12,23 @@ const author = { alive: true, }; -for (const value of author) { +for (const value in author){ console.log(value); } + +because we use for...of loop in array instead of objects. To use it in objects, we can change it to for...in loop +In order to print out all the variable and the value , we should use console.log(${key}:${author[key]}). + + + +const author = { + firstName: "Zadie", + lastName: "Smith", + occupation: "writer", + age: 40, + alive: true, +}; + +for (const key in author) { + console.log(`${key}: ${author[key]}`); +} \ No newline at end of file From 90522ebe10002037b0f086a88025f9551ff6df5d Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 18:54:04 +0100 Subject: [PATCH 03/12] recipe.js --- Sprint-2/debug/recipe.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..68804070a 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -13,3 +13,18 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: ${recipe}`); + + +We should not call directly the variable instead we should use recipe.ingredients to call the value insides the label. + + +const recipe = { + title: "bruschetta", + serves: 2, + ingredients: ["olive oil", "tomatoes", "salt", "pepper"], +}; + +console.log(`${recipe.title} serves ${recipe.serves} + ingredients: +${recipe.ingredients}`); + From 5d6fe57f242cef75f25d24b56b4aca79ca08d11f Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 18:55:32 +0100 Subject: [PATCH 04/12] contains.js --- Sprint-2/implement/contains.js | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..b8229e21d 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,33 @@ -function contains() {} +const object = { + a: 1, + b: 2, +}; + +function contains(object, key) { + if (Array.isArray(object)) { + throw new Error(); + } + + if (!object) { + return false; + } + + if (key in object) { + return true; + } else { + return false; + } +} module.exports = contains; + +/* +Implement a function called contains that checks an object contains a +particular property + +E.g. contains({a: 1, b: 2}, 'a') // returns true +as the object contains a key of 'a' + +E.g. contains({a: 1, b: 2}, 'c') // returns false +as the object doesn't contains a key of 'c' +*/ From d74c77517a131133949189e7dd190ea0d4b7b452 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 18:57:06 +0100 Subject: [PATCH 05/12] contain.test.js --- Sprint-2/implement/contains.test.js | 43 ++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..811ab9057 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -13,6 +13,48 @@ as the object doesn't contains a key of 'c' // Acceptance criteria: +describe("contains function", () => { + test("return true when there is a variable inside", () => { + const object = { + a: 1, + b: 2, + }; + const key = "c"; + expect(contains(object, key)).toBe(false); + }); + + test("Given an empty object", () => { + const object = {}; + const key = "c"; + expect(contains(object, key)).toBe(false); + }); + + test("Given an object with properties", () => { + const object = { + a: 1, + b: 2, + }; + const key = "b"; + expect(contains(object, key)).toBe(true); + }); + + test("Given an object with non-existing properties", () => { + const object = { + a: 1, + b: 2, + }; + const key = "c"; + expect(contains(object.key)).toBe(false); + }); + + test("Given invalid parameters like an array", () => { + const object = ["apple", "orange"]; + const key = "c"; + expect(() => contains(object, key)).toThrow(); + }); + //if it is array !objects , you should throw errors// +}); + // 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 @@ -20,7 +62,6 @@ as the object doesn't contains a key of 'c' // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); // Given an object with properties // When passed to contains with an existing property name From db23e2ce79657bc28b4f8e95786effa7aef4f4ca Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 18:58:32 +0100 Subject: [PATCH 06/12] lookup.js --- Sprint-2/implement/lookup.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..9890adf6d 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,13 @@ -function createLookup() { - // implementation here +function createLookup(pairs) { + if (!Array.isArray(pairs)) { + throw Error; + } + const myLookup = {}; + + for (let pair of pairs) { + myLookup[pair[0]] = pair[1]; + } + return myLookup; } module.exports = createLookup; From 5004f23e467578af68a2da93eaeb3498f1a655b9 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 19:00:00 +0100 Subject: [PATCH 07/12] lookup.test.js --- Sprint-2/implement/lookup.test.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..a974252fe 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,7 +1,24 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); - +describe("lookup function", () => { + test("creates a country currency code lookup for multiple codes", () => { + const countryCurrentPairs = [ + ["US", "USD"], + ["CA", "CAD"], + ]; + expect(createLookup(countryCurrentPairs)).toEqual({ US: "USD", CA: "CAD" }); + }); + + test("it show a string and will throw error", () => { + expect(() => { + createLookup("Red"); + }).toThrow(); + }); + + test(" it throws empty array , it will return an empty object", () => { + expect(createLookup([])).toEqual({}); + }); +}); /* Create a lookup object of key value pairs from an array of code pairs From 60936b2ea6dd82b5650692fd4fdcd113a0592501 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 19:02:48 +0100 Subject: [PATCH 08/12] querystring.js --- Sprint-2/implement/querystring.js | 52 +++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..33468eecb 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,16 +1,56 @@ function parseQueryString(queryString) { - const queryParams = {}; + const result = {}; + if (queryString.length === 0) { - return queryParams; + return result; } + const keyValuePairs = queryString.split("&"); - for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + for (let pair of keyValuePairs) { + const cleanPair = pair.replace(/\+/g, " "); + // Step 3: Change all '+' signs into regular spaces + const firstEqualIndex = cleanPair.indexOf("="); + + let key, value; + + if (firstEqualIndex === -1) { + key = cleanPair; + value = ""; + } else { + key = cleanPair.slice(0, firstEqualIndex); + value = cleanPair.slice(firstEqualIndex + 1); + } + + let decodedKey, decodedValue; + try { + // Try to decode normally + decodedKey = decodeURIComponent(key); + } catch (error) { + // If it's a broken code (like "100%"), just use the raw text instead of crashing! + decodedKey = key; + } + + try { + decodedValue = decodeURIComponent(value); + } catch (error) { + decodedValue = value; + } + + // Step 6: Put them into our boxes (Handling the Stretch Goal too!) + if (result.hasOwnProperty(decodedKey)) { + // If the box already has a secret message, make it a list or add to the list + if (!Array.isArray(result[decodedKey])) { + result[decodedKey] = [result[decodedKey]]; + } + result[decodedKey].push(decodedValue); + } else { + // If the box is brand new, just put the message inside + result[decodedKey] = decodedValue; + } } - return queryParams; + return result; } module.exports = parseQueryString; From 490e0d56b3f1170e7207aaec01dc60a37342ea53 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 19:04:54 +0100 Subject: [PATCH 09/12] querystring.test.js --- Sprint-2/implement/querystring.test.js | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 328b8df61..7743afa7e 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -3,33 +3,28 @@ // Below are some test cases the implementation doesn't handle well. // Fix the implementation for these tests, and try to think of as many other edge cases as possible - write tests and fix those too. -const parseQueryString = require("./querystring.js") +const parseQueryString = require("./querystring.js"); test("should parse values containing '='", () => { expect(parseQueryString("equation=a=b-2")).toEqual({ equation: "a=b-2", }); }); - test("should ignore empty key-value pairs", () => { - expect(parseQueryString("key1=value1&&key2=value2&")).toEqual({ - key1: "value1", - key2: "value2", - }); + expect(parseQueryString("")).toEqual({}); }); - test("should accept empty string as key or as value", () => { expect(parseQueryString("=value")).toEqual({ "": "value" }); expect(parseQueryString("key")).toEqual({ key: "" }); expect(parseQueryString("key=")).toEqual({ key: "" }); expect(parseQueryString("=")).toEqual({ "": "" }); }); - test("should decode percent-encoded characters", () => { expect(parseQueryString("%24half=1%2F2")).toEqual({ $half: "1/2", }); }); +// test("should replace '+' by ' '", () => { expect(parseQueryString("full+name=John+Doe")).toEqual({ @@ -37,12 +32,16 @@ test("should replace '+' by ' '", () => { }); }); -// Stretch exercise: Handling query strings that contain identical keys +test("should ignore extra or duplicate ampersands", () => { + expect(parseQueryString("key1=value1&key2=value2")).toEqual({ + key1: "value1", + key2: "value2", + }); +}); -// Delete this test if you are not working on this optional case -test("should store values of a key in an array when the key has 2 or more values", () => { - expect(parseQueryString("key=value1&key=value2&key=value3&foo=bar")).toEqual({ - key: ["value1", "value2", "value3"], - foo: "bar", +test("should not crash when given malformed percent-encoding", () => { + // If decoding fails, it should just keep the original raw text safely + expect(parseQueryString("discount=100%")).toEqual({ + discount: "100%", }); }); From 2075fc0a27cd0cf73a7cafbbe292fe13e43e7fe7 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 19:07:58 +0100 Subject: [PATCH 10/12] tally.js --- Sprint-2/implement/tally.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..1b93d5280 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,26 @@ -function tally() {} +function tally(items) { + // 1. Check for bad inputs (like a string or number instead of an array) + // If it's bad, throw a massive red error code! + if (!Array.isArray(items)) { + throw new Error("Input must be an array!"); + } + + // 2. Create our empty chest to hold our item counts + const countObject = {}; + + // 3. Loop through every single item in the array + for (const item of items) { + if (countObject[item]) { + // If the block is already in our chest, increase the stack count by 1! + countObject[item] += 1; + } else { + // If it's a brand new block type, start the counter at 1! + countObject[item] = 1; + } + } + + // 4. Hand back our beautifully organized chest! + return countObject; +} module.exports = tally; From 840614fabb027f5ad20a3252b37e4d59784ebdd7 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 19:10:39 +0100 Subject: [PATCH 11/12] tally.test.js --- Sprint-2/implement/tally.test.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..d707d8a15 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -14,6 +14,19 @@ const tally = require("./tally.js"); * tally(['a', 'a', 'b', 'c']), target output: { a : 2, b: 1, c: 1 } */ +test("tally on an empty array returns an empty object", () => { + expect(tally([])).toEqual({}); +}); + +test("tally should return counts for each unique item", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); +}); + +test("tally should throw an error when passed an invalid input like a string", () => { + expect(() => { + tally("not an array"); + }).toThrow(); +}); // Acceptance criteria: // Given a function called tally @@ -23,7 +36,6 @@ 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"); // Given an array with duplicate items // When passed to tally @@ -32,3 +44,4 @@ test.todo("tally on an empty array returns an empty object"); // Given an invalid input like a string // When passed to tally // Then it should throw an error + From 213eee29a4810bcd77611094878904df10c8d128 Mon Sep 17 00:00:00 2001 From: Arthur <> Date: Sat, 11 Jul 2026 19:12:04 +0100 Subject: [PATCH 12/12] invert.js --- Sprint-2/interpret/invert.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..e2ab10618 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,30 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; } +console.log(invert({ a: 1 })); // a) What is the current return value when invert is called with { a : 1 } - +//{1: a } +{a : 1} // b) What is the current return value when invert is called with { a: 1, b: 2 } +{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? +because for... loop doesn't recognize object insides, so by turning objects into objects.entries, it will become an array format that the for...loop function can recognize. + // d) Explain why the current return value is different from the target output +because we didn't switch the position of key and value insides the function. +Also we forgot to add [ ], it is to recognize the data insides item. + + // e) Fix the implementation of invert (and write tests to prove it's fixed!)