From 809dc28f1c4db251798bf643c8fc643098e29a45 Mon Sep 17 00:00:00 2001 From: abduhasen Date: Mon, 27 Jul 2026 19:37:01 +0100 Subject: [PATCH 1/4] sprint-2-data-groups-backlog. worked on fixing code and writing code based on tdd --- Sprint-2/debug/address.js | 4 ++-- Sprint-2/debug/author.js | 9 +++++---- Sprint-2/debug/recipe.js | 9 ++++++--- Sprint-2/implement/contains.js | 19 ++++++++++++++++++- Sprint-2/implement/contains.test.js | 26 ++++++++++++++++++++++++-- Sprint-2/implement/lookup.js | 9 +++++++-- Sprint-2/implement/lookup.test.js | 28 +++++++++++++++++++++++++++- Sprint-2/implement/querystring.js | 27 +++++++++++++++++++++++++-- Sprint-2/implement/tally.js | 18 ++++++++++++++++-- Sprint-2/implement/tally.test.js | 24 +++++++++++++++++++++++- Sprint-2/interpret/invert.js | 16 ++++++++++++++++ 11 files changed, 169 insertions(+), 20 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..52f2f8bb8 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,5 +1,5 @@ // Predict and explain first... - +//My prediction is that it will log undefined because we used array index to access object value instead of key name. // This code should log out the houseNumber from the address object // but it isn't working... // Fix anything that isn't working @@ -12,4 +12,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address["houseNumber"]}`); diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..e60f61092 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,5 +1,7 @@ // Predict and explain first... - +/* In this code the problem is that the method for...of is used for array + not for object type instead we use for...in this will work through the object + and list the key and for value We use author[property] */ // 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 @@ -10,7 +12,6 @@ const author = { age: 40, alive: true, }; - -for (const value of author) { - console.log(value); +for (const values in author) { + console.log(`${author[values]}`); } diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..baf0f19e5 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,5 +1,6 @@ // Predict and explain first... - +/* My prediction is that on the ingredients didn't used dot notation to access the element that why it will log undefined + instead using for..of loop we can print all the ingredient in 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? @@ -11,5 +12,7 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +ingredients`); +for (const ingredient of recipe.ingredients) { + console.log(`*${ingredient}`); +} diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..56b7375bc 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,20 @@ -function contains() {} +function contains(givenObject, keyString) { + console.log(givenObject, keyString); + if ( + typeof givenObject !== "object" || + givenObject === null || + Array.isArray(givenObject) + ) { + return false; + } + for (const keyProperty in givenObject) { + console.log(keyString); + if (keyProperty === keyString) { + return true; + } + } + return false; +} +console.log(contains({ a: 2, b: 1 }, "a")); module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..dfe02e45a 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,16 +20,38 @@ 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"); +test("should return false when an empty object is passed to the function", () => { + expect(contains({})).toEqual(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true - +test("the function should return true when object contains a given property", () => { + expect(contains({ a: 1, b: 2, c: 3 }, "c")).toEqual(true); + expect(contains({ name: "lee", age: 30 }, "name")).toEqual(true); + expect(contains({ place: "spain", city: "madrid", rank: 9 }, "city")).toEqual( + true + ); + expect(contains({ zone: 2, zone: 3, zone: 4 }, "zone")).toEqual(true); +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("the function should return false when property don't exist in the given object", () => { + expect(contains({ a: 1, b: 2, c: 3 }, "d")).toEqual(false); + expect(contains({ year: 1998, month: 10, Date: 16 }, "age")).toEqual(false); + expect( + contains({ meal: "pizza", drink: "water", table: 3 }, "starter") + ).toEqual(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test("the function should return false when invalid parameter like an array is passed", () => { + expect(contains([10, 23, 34, 45], "3")).toEqual(false); + expect(contains("hello", "0")).toEqual(false); + expect(contains(["green", "yellow", "rad"], "0")).toEqual(false); + expect(contains(((30, 40, 50), 30))).toEqual(false); +}); diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..a14b633d8 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,10 @@ -function createLookup() { +function createLookup(countryCurrencyPairs) { // implementation here + const currencyPairs = {}; + for (const innerPair of countryCurrencyPairs) { + const [key, value] = innerPair; + currencyPairs[key] = value; + } + return currencyPairs; } - module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..575904be5 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,32 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); +test("Function should create an object that have country code as key and country currency code as value", () => { + expect( + createLookup([ + ["US", "USD"], + ["CA", "CAD"], + ]) + ).toEqual({ + US: "USD", + CA: "CAD", + }); + expect( + createLookup([ + ["BE", "EUR"], + ["BR", "BRL"], + ["FI", "FIN"], + ]) + ).toEqual({ BE: "EUR", BR: "BRL", FI: "FIN" }); + expect( + createLookup([ + ["CV", "CPV"], + ["CN", "CHN"], + ["CR", "CRI"], + ["DE", "DEU"], + ["IN", "IND"], + ]) + ).toEqual({ CV: "CPV", CN: "CHN", CR: "CRI", DE: "DEU", IN: "IND" }); +}); /* diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..87eee586f 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -6,8 +6,31 @@ function parseQueryString(queryString) { const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + if (pair.length === 0) { + continue; + } else { + const equalityPosition = pair.indexOf("="); + + if (equalityPosition === -1) { + queryParams[pair] = ""; + } else { + const key = decodeURIComponent(pair.slice(0, equalityPosition)); + const replacedKey = key.replace("+", " "); + + const value = decodeURIComponent(pair.slice(equalityPosition + 1)); + const replacedValue = value.replace("+", " "); + + if (queryParams[replacedKey]) { + if (!Array.isArray(queryParams[replacedKey])) { + queryParams[replacedKey] = [queryParams[replacedKey]]; + } + + queryParams[replacedKey].push(replacedValue); + } else { + queryParams[replacedKey] = replacedValue; + } + } + } } return queryParams; diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..9b6a2cbed 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,17 @@ -function tally() {} - +function tally(myArray) { + if (!Array.isArray(myArray)) { + throw "Error"; + } else if (myArray.length === 0) { + return {}; + } + let tallyObject = Object.create(null); + for (const singleItems of myArray) { + if (tallyObject[singleItems] === undefined) { + tallyObject[singleItems] = 1; + } else { + tallyObject[singleItems] += 1; + } + } + return tallyObject; +} module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..1627ecd32 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,12 +23,34 @@ 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("The function should return empty object when an empty array is passed to the function", () => { + expect(tally([])).toEqual({}); +}); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test("The function should return an object where each key is a unique item from the array, and each index is how many times that item duplicate", () => { + expect(tally(["a", "a", "a", "b", "b", "b", "c", "c", "c"])).toEqual({ + a: 3, + b: 3, + c: 3, + }); + expect( + tally(["manchester", "manchester", "london", "london", "leeds"]) + ).toEqual({ manchester: 2, london: 2, leeds: 1 }); + expect(tally([1, 1, 2])).toEqual({ 1: 2, 2: 1 }); + expect(tally(["a"])).toEqual({ a: 1 }); + expect(tally(["a", "a", "a"])).toEqual({ a: 3 }); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("The function should throw an error when invalid input is passed", () => { + expect(() => { + tally("hello"); + }).toThrow("Error"); + /*expect(tally(134)).toThrow; + expect(tally({ a: 1, b: 3, d: 2 })).toThrow;*/ +}); diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..0efb84c7e 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -17,13 +17,29 @@ function invert(obj) { } // a) What is the current return value when invert is called with { a : 1 } +// the current return value when invert is called with { a:1 } is { key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// the current return value when invert is called with { a: 1, b: 2 } is { key: 2} // c) What is the target return value when invert is called with {a : 1, b: 2} +// the target return value when invert is called with {a : 1, b: 2} is { '1':'a','2':'b'} // c) What does Object.entries return? Why is it needed in this program? +// Object.entries is needed because it will gave as the access of the key and value by separating each key value pair. // d) Explain why the current return value is different from the target output +/*the current value is different from the targeted value because the for loop already give as access for the key value pairs +but when we declare a new object the function where looking the word key in the loop because it was dot notation and taking the +word key and pairing it withe the last loop value. */ // e) Fix the implementation of invert (and write tests to prove it's fixed!) +/* function invert(obj) { + const invertedObj = {}; + + for (const [key, value] of Object.entries(obj)) { + invertedObj[value] = key; + } + + return invertedObj; +} */ From 03b11158951e06259e1dc04ab2e88dadf61f5df4 Mon Sep 17 00:00:00 2001 From: abduhasen Date: Wed, 5 Aug 2026 13:13:25 +0100 Subject: [PATCH 2/4] fix codes based on mentor feedback --- Sprint-2/implement/contains.js | 2 -- Sprint-2/implement/querystring.js | 6 +++--- Sprint-2/interpret/invert.js | 34 ++++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 56b7375bc..ecc9b058a 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -8,13 +8,11 @@ function contains(givenObject, keyString) { return false; } for (const keyProperty in givenObject) { - console.log(keyString); if (keyProperty === keyString) { return true; } } return false; } -console.log(contains({ a: 2, b: 1 }, "a")); module.exports = contains; diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 87eee586f..294657aca 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -15,10 +15,10 @@ function parseQueryString(queryString) { queryParams[pair] = ""; } else { const key = decodeURIComponent(pair.slice(0, equalityPosition)); - const replacedKey = key.replace("+", " "); + const replacedKey = key.replace(/\+/g, " "); const value = decodeURIComponent(pair.slice(equalityPosition + 1)); - const replacedValue = value.replace("+", " "); + const replacedValue = value.replace(/\+/g, " "); if (queryParams[replacedKey]) { if (!Array.isArray(queryParams[replacedKey])) { @@ -35,5 +35,5 @@ function parseQueryString(queryString) { return queryParams; } - +console.log(parseQueryString("key=value1&key=value2&key=value3&foo=bar")); module.exports = parseQueryString; diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 0efb84c7e..b45e5b63d 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -6,7 +6,7 @@ // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} -function invert(obj) { +/*function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { @@ -14,7 +14,7 @@ function invert(obj) { } return invertedObj; -} +}*/ // a) What is the current return value when invert is called with { a : 1 } // the current return value when invert is called with { a:1 } is { key: 1 } @@ -34,12 +34,32 @@ but when we declare a new object the function where looking the word key in the word key and pairing it withe the last loop value. */ // e) Fix the implementation of invert (and write tests to prove it's fixed!) -/* function invert(obj) { - const invertedObj = {}; +function invert(obj) { + const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj[value] = key; - } + invertedObj[value] = key; + } return invertedObj; -} */ +} + +function test(description, actual, expected) { + if (JSON.stringify(actual) !== JSON.stringify(expected)) { + throw new Error(`${description} failed`); + } +} +test("swapping key and value of the object", invert({ x: 10, y: 20 }), { + 10: "x", + 20: "y", +}); +test("swapping key and value of the object", invert({ x: 10, y: 20, z: 30 }), { + 10: "x", + 20: "y", + 30: "z", +}); +test("swapping key and value of the object", invert({ x: 10, y: 20, z: 30 }), { + x: 10, + 20: "y", + z: 30, +}); From e9ba1539bc73c01b75636dec60969a2248155c9e Mon Sep 17 00:00:00 2001 From: abduhasen Date: Wed, 5 Aug 2026 13:27:44 +0100 Subject: [PATCH 3/4] cleaned unnecessary line --- Sprint-2/implement/querystring.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 294657aca..db05dbe97 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -35,5 +35,5 @@ function parseQueryString(queryString) { return queryParams; } -console.log(parseQueryString("key=value1&key=value2&key=value3&foo=bar")); + module.exports = parseQueryString; From 91c0de4dd29ada32e3356b293c1fe08f94cbb2ec Mon Sep 17 00:00:00 2001 From: abduhasen Date: Wed, 5 Aug 2026 16:43:08 +0100 Subject: [PATCH 4/4] fixing test case based on mentor feedback --- Sprint-2/interpret/invert.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index b45e5b63d..27f2c6495 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -58,8 +58,8 @@ test("swapping key and value of the object", invert({ x: 10, y: 20, z: 30 }), { 20: "y", 30: "z", }); -test("swapping key and value of the object", invert({ x: 10, y: 20, z: 30 }), { - x: 10, - 20: "y", - z: 30, +test("swapping key and value of the object", invert({ A: 50, B: 40, D: 30 }), { + 50: "A", + 40: "B", + 30: "D", });