From ddf0157209f60f40d72299e78bcf0cb1b5f79404 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Fri, 10 Apr 2026 11:34:59 +0100 Subject: [PATCH 01/13] I depuged the function uesing the property name rather than the index. --- Sprint-2/debug/address.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..d2809c142 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,8 +1,13 @@ // Predict and explain first... - +I predict that the code will not log out the housenumber +because there is no method declared inside the object to return the object's properties. // This code should log out the houseNumber from the address object // but it isn't working... // Fix anything that isn't working +when I run the code it give this message as output (My house number is undefined). +when I changed the console.log declaration to : +console.log('my house number is' + ' ' + address.houseNumber); +it give the right output for the house number. const address = { houseNumber: 42, @@ -12,4 +17,9 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +// console.log(`My house number is ${address[0]}`); +console.log('my house number is' + ' ' + address.houseNumber); + +when I checked an AI tool it explained that address is an object, not an array. +So address[0] tries to access a property with the key "0" — which doesn’t exist → undefined. +to access the houseNumber property we need to use the property name not an index. From d9a0ef07105d8f085e62ca456a5b69f80cbd4ba3 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Fri, 10 Apr 2026 23:12:18 +0100 Subject: [PATCH 02/13] I edited the const variable for values to give the correct output. --- Sprint-2/debug/author.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..8d4c8d7e4 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,5 +1,5 @@ // Predict and explain first... - +I predict that the program will not the property values of the object because the for loop is not correctly calling the values of the auther object CSSStyleProperties. // 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 +11,17 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); -} +// for (const value of author) { +// console.log(value); +// } + +let text = " "; +for (let x in author) { + text+= author[x] + " "; +}; +console.log(text); + +// or: +const values = Object.values(author); +console.log(values); + From f5fa49398279c68dc60d78dbc34bdced344a9892 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 08:29:48 +0100 Subject: [PATCH 03/13] I fixed the console.log function access to ingridents to log out the correct output --- Sprint-2/debug/recipe.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..aee3d6c4d 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,4 +1,6 @@ // Predict and explain first... +I expect that the program will not log out the right output because the ingridents are not being accssed correctly. +as the recipe object is being logged out rather than the ingridents. // 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,4 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: -${recipe}`); +${recipe.ingredients .join("\n") }`); From 5d9c49db835a65031be59faf595f51b6acaf332c Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 12:02:52 +0100 Subject: [PATCH 04/13] I implemented the contains function and write different test cases that passed the npm try in treminal. --- Sprint-2/implement/contains.js | 4 +++- Sprint-2/implement/contains.test.js | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..c7a188e23 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,5 @@ -function contains() {} +function contains(obj, key) { + return key in obj; +} module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..9d6b70ff0 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,16 +20,35 @@ 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.todo("contains on empty object returns false"); +test("contains an empty object returns false", () => { + const obj = {}; + expect(contains(obj,"a")).toBe(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test ("contains an object with properties return ture", ()=> { + const obj = {a:1 ,b:2, c:3}; + expect (contains(obj ,"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 with propreties return false for non-existing property", ()=> { + const obj = {a:1, b:2, c:3}; + expect(contains(obj ,"d")).toBe(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test ("contains with invalid parameters return false", () => { + const obj = ['a','b','c','d']; + expect(contains(obj , "a")).toBe (false); +}); + + // or to throw error +// })) \ No newline at end of file From 07f2e56d6b2ae94e138c5fd8cc6303bc17917748 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 13:10:15 +0100 Subject: [PATCH 05/13] I implemented a lookup function and write & run the test case. --- Sprint-2/implement/lookup.js | 4 ++-- Sprint-2/implement/lookup.test.js | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..5c120898b 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,5 @@ -function createLookup() { - // implementation here +function createLookup(countryCurrencyPairs) { + return Object.fromEntries(countryCurrencyPairs); } module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..f6b1c33a4 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -33,3 +33,11 @@ It should return: 'CA': 'CAD' } */ +test('Create a lookup object of key value pairs from an array of code pairs', ()=> +{ + const countryCurrencyPairs = [["US", "USD"], ["CA", "CAD"]]; + expect(createLookup(countryCurrencyPairs)).toEqual({ + US: "USD", + CA: "CAD"}); + +}); \ No newline at end of file From 93e9e877b1a8d412bbce15cc6ec2a85ae1cf89d5 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 22:26:57 +0100 Subject: [PATCH 06/13] Implement tally function and wrote diffrent test cases. --- Sprint-2/implement/tally.js | 11 ++++++++++- Sprint-2/implement/tally.test.js | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..2b37f9446 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,12 @@ -function tally() {} +function tally(items) { + if (!Array.isArray(items)) { + throw new Error("Input must be an array"); + } + const result ={ }; + for (let item of items){ + result[item]=(result[item] || 0)+1; + } + return result; +} module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..d0cf86fce 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -19,11 +19,17 @@ 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 on an array of items returns an object with counts of each item", () => { + const items = ["a","a","b","c"] + expect(tally(items)).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", () => { + const items = []; + expect(tally(items)).toEqual({}); +}); // Given an array with duplicate items // When passed to tally @@ -32,3 +38,7 @@ 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 +test('tally on invalid input throw an error', ()=> { + const items = 'invalid input'; + expect(() => tally(items)).toThrow(); +}) \ No newline at end of file From fffec287125820550f9347f64beb85b2422c53fb Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 22:54:06 +0100 Subject: [PATCH 07/13] Implement parseQueryString function and wrote test cases. --- Sprint-2/implement/querystring.js | 21 +++++++++++--- Sprint-2/implement/querystring.test.js | 40 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..cff0ef026 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,12 +1,25 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { - return queryParams; - } + + if (!queryString) return queryParams; + const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + if (!pair) continue; + + const index = pair.indexOf("="); + + let key, value; + + if (index === -1) { + key = pair; + value = true; + } else { + key = pair.slice(0, index); + value = pair.slice(index + 1); + } + queryParams[key] = value; } diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..19815d900 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,43 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); +// Empty query string: +test("parses querystring with empty string", () => { + expect(parseQueryString("")).toEqual({}); +}); +// Key without value: +test("parses querystring handles key without =", () => { + expect(parseQueryString("flag")).toEqual({ + flag: true, + }); +}); + +// Empty value: +test("parses querystring with empty value", () => { + expect(parseQueryString("key=")).toEqual({ + key: "", + }); +}); + +// Multiple params: +test("parses querystring with multiple params", () => { + expect(parseQueryString("name=John&age=30&city=New+York")).toEqual({ + name: "John", + age: "30", + city: "New York" + }); +}); + +// Value containing = : +test("parses querystring values containing =", () => { + expect(parseQueryString("equation=x=y+1")).toEqual({ + "equation": "x=y+1", + }); +}); + +// Trailing ampersand: +test("parses querystring with trailing ampersand", () => { + expect(parseQueryString("name=John&")).toEqual({ + name: "John" + }); +}); From 6e578a4eb91f4dfe968d0937a9e29161719d37ee Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 23:24:28 +0100 Subject: [PATCH 08/13] fixed the invert function and wrote test cases --- Sprint-2/interpret/invert.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..6af13915e 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,34 @@ 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 } - +the 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 should be {"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 of an object. it is needed in this program to loop through the object and access both the key and value at the same Time . // d) Explain why the current return value is different from the target output - +because using the key element in the loop is not correct. as using it in this line : invertedObj.key = value; +creats a propty called key rather than using it as a variable . it also doesn't swap the key/vlaue . // e) Fix the implementation of invert (and write tests to prove it's fixed!) + + +test ("invert should swap keys and values in an object with one key and value", ()=> { +expect(invert({a :1})).toEqual({"1" :"a"}) +}); + +test ("invert should swap keys and values in an object with multiple keys and values", ()=> { +expect(invert({a :1, b: 2})).toEqual({"1" :"a", "2" : "b"}) +}); + +test('invert should return an empty object when given an empty object', ()=> { + expect(invert({})).toEqual({}); +}); \ No newline at end of file From 5cba6b1e7c5dc57ace243695d0ff8c886b6a4f30 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Sat, 11 Apr 2026 23:34:33 +0100 Subject: [PATCH 09/13] reedited the function implementation. --- Sprint-2/implement/querystring.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index cff0ef026..1ee34343a 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,9 +3,9 @@ function parseQueryString(queryString) { if (!queryString) return queryParams; - const keyValuePairs = queryString.split("&"); + const pairs = queryString.split("&"); - for (const pair of keyValuePairs) { + for (const pair of pairs) { if (!pair) continue; const index = pair.indexOf("="); @@ -13,11 +13,11 @@ function parseQueryString(queryString) { let key, value; if (index === -1) { - key = pair; + key = decodeURIComponent(pair); value = true; } else { - key = pair.slice(0, index); - value = pair.slice(index + 1); + key = decodeURIComponent(pair.slice(0, index)); + value = decodeURIComponent(pair.slice(index + 1)); } queryParams[key] = value; @@ -26,4 +26,4 @@ function parseQueryString(queryString) { return queryParams; } -module.exports = parseQueryString; +module.exports = parseQueryString; \ No newline at end of file From da48732ebc0f6896b5e66b1a107473ed88b9d1b6 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Mon, 13 Apr 2026 22:10:41 +0100 Subject: [PATCH 10/13] fixed the program to have the output proprety values one by one in a new line. --- Sprint-2/debug/author.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8d4c8d7e4..59d644c17 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,5 +1,5 @@ // Predict and explain first... -I predict that the program will not the property values of the object because the for loop is not correctly calling the values of the auther object CSSStyleProperties. +I predict that the program will not give the property values of the object because the for loop is not correctly calling the values of the auther object . // 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 @@ -17,7 +17,7 @@ const author = { let text = " "; for (let x in author) { - text+= author[x] + " "; + text+= author[x] + "\n "; }; console.log(text); From 1f6e611e2441cd3a9506fd16b84dfd45b9c47929 Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Mon, 13 Apr 2026 22:21:56 +0100 Subject: [PATCH 11/13] reformatted the doc. --- Sprint-2/implement/contains.test.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 9d6b70ff0..88f574595 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -24,31 +24,31 @@ as the object doesn't contains a key of 'c' test("contains an empty object returns false", () => { const obj = {}; - expect(contains(obj,"a")).toBe(false); + expect(contains(obj, "a")).toBe(false); }); // Given an object with properties // When passed to contains with an existing property name // Then it should return true -test ("contains an object with properties return ture", ()=> { - const obj = {a:1 ,b:2, c:3}; - expect (contains(obj ,"a")).toBe (true);}); - +test("contains an object with properties return ture", () => { + const obj = { a: 1, b: 2, c: 3 }; + expect(contains(obj, "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 with propreties return false for non-existing property", ()=> { - const obj = {a:1, b:2, c:3}; - expect(contains(obj ,"d")).toBe(false); +test("contains an object with propreties return false for non-existing property", () => { + const obj = { a: 1, b: 2, c: 3 }; + expect(contains(obj, "d")).toBe(false); }); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error -test ("contains with invalid parameters return false", () => { - const obj = ['a','b','c','d']; - expect(contains(obj , "a")).toBe (false); +test("contains with invalid parameters return false", () => { + const obj = ["a", "b", "c", "d"]; + expect(contains(obj, "a")).toBe(false); }); - - // or to throw error -// })) \ No newline at end of file + +// or to throw error +// })) From 08e0087925a6df77be5e6439b0afdb9f7f0a865c Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Tue, 14 Apr 2026 21:06:33 +0100 Subject: [PATCH 12/13] add mor tests for invalid values --- Sprint-2/implement/contains.test.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 88f574595..e4c60cf22 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -50,5 +50,27 @@ test("contains with invalid parameters return false", () => { expect(contains(obj, "a")).toBe(false); }); -// or to throw error -// })) +// Give an error for null values: + +test("contains give an error when obj is null", ()=> { + expect((()=> contains(null , "a"))).toThrow(); +}); +// throw error for undefiend values: +test("contains give an error when obj is undefined", ()=> { + expect((()=> contains(undefined , "a"))).toThrow(); +}); + +// throw error for non object typs: +test(" give an error when obj is a number", ()=> { +expect((()=> contains(123, "a"))).toThrow(); +}); + +// throw error when obj is a string: +test(" give an error when obj is a string", ()=> { + expect((()=> contains("hello", "a"))).toThrow(); +}); + +// give error when obj is boolean: +test(" give an error when obj is a boolean", ()=> { + expect((()=> contains(true, "a"))).toThrow(); +}); From 74e551f70bdcc9608b48df61b6e910dc1a93de0b Mon Sep 17 00:00:00 2001 From: Mona-Eltantawy Date: Tue, 14 Apr 2026 21:19:11 +0100 Subject: [PATCH 13/13] I fixed the function. --- Sprint-2/implement/tally.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 2b37f9446..3ee2b7767 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,12 +1,19 @@ function tally(items) { - if (!Array.isArray(items)) { - throw new Error("Input must be an array"); - } - const result ={ }; - for (let item of items){ - result[item]=(result[item] || 0)+1; - } - return result; + if (!Array.isArray(items)) { + throw new Error("Input must be an array"); + } + + const result = {}; + + for (let item of items) { + if (Object.hasOwn(result, item)) { + result[item] += 1; + } else { + result[item] = 1; + }npm TextDecoderStream + } + + return result; } module.exports = tally;