From a5f25c773d2954ed3b7dc7265c667654187834a9 Mon Sep 17 00:00:00 2001 From: pathywang Date: Fri, 27 Feb 2026 21:37:59 +0000 Subject: [PATCH 1/9] commit --- Sprint-2/debug/address.js | 5 +++-- Sprint-2/debug/author.js | 4 +++- Sprint-2/debug/recipe.js | 15 --------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..0c5ce99ea 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,8 +1,9 @@ // Predict and explain first... +// it will print out My house number is undefined because the address is object rather than array so address[0] will look for property 0 which does not exit // This code should log out the houseNumber from the address object // but it isn't working... -// Fix anything that isn't working +// Fix anything that isn't working, it should be address.houseNumber in order to get value 42 const address = { houseNumber: 42, @@ -12,4 +13,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..911a76841 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,7 +1,9 @@ // Predict and explain first... +// it will throw error or just print out undefined because // 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 +// Because author is not array rather object so we can not use for loop, we use object.values to get loop const author = { firstName: "Zadie", @@ -11,6 +13,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of Object.values(author)) { console.log(value); } diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..e69de29bb 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,15 +0,0 @@ -// Predict and explain first... - -// 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? - -const recipe = { - title: "bruschetta", - serves: 2, - ingredients: ["olive oil", "tomatoes", "salt", "pepper"], -}; - -console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); From ca26a21e0048f36027128bc2b50f9794f634f38f Mon Sep 17 00:00:00 2001 From: pathywang Date: Fri, 27 Feb 2026 22:01:50 +0000 Subject: [PATCH 2/9] commit --- Sprint-2/debug/recipe.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index e69de29bb..7481a5cec 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -0,0 +1,19 @@ +// Predict and explain first... +// It might print out undefined or something else + +// 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? i will loop through ingredient to get each single ingredient + +const recipe = { + title: "bruschetta", + serves: 2, + ingredients: ["olive oil", "tomatoes", "salt", "pepper"], +}; + +console.log(`${recipe.title} serves ${recipe.serves} +ingredients:`); + +for (const ingredient of recipe.ingredients) { + console.log(ingredient); +} From b8b5c2ca7213ccc2b38ddf2b8f843fd811a6b072 Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 1 Mar 2026 12:11:38 +0000 Subject: [PATCH 3/9] commit --- Sprint-2/implement/contains.js | 14 +++++++++++++- Sprint-2/implement/contains.test.js | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..ac4885493 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,15 @@ -function contains() {} +function contains(object, property) { + if (typeof object !== 'object' || object === null || Array.isArray(object)) { + return false; + } + return object.hasOwnProperty(property); +} + + + +const object={name:'jin', age:13} + +console.log (contains(object, 'age')) +console.log (contains(object, 'nice')) module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..3b278cc51 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,16 +20,30 @@ as the object doesn't contains a key of 'c' // Given an empty object // When passed to contains // Then it should return false +object={} +console.log(object,'') test.todo("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 +object={name:'jin', age:13} +console.log (contains(object, 'age')) +test.todo("contains age property in object return true") + // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +object={name:'jin', age:13} +console.log (contains(object, 'nice')) +test.todo("contains no nice property in object return false") + + // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +object={name:'jin', age:13} +console.log (contains(object, '[1,2,5]')) +test.todo("contains no array property in object return false") From 3339f76a4561b442ab2cf57a9ca9d5cbbf3a3a2f Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 1 Mar 2026 14:29:02 +0000 Subject: [PATCH 4/9] complete look up --- Sprint-2/implement/lookup.js | 11 +++++++++-- Sprint-2/implement/lookup.test.js | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..f84776beb 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,12 @@ -function createLookup() { - // implementation here +function createLookup(countryCurrencyPairs) { + const countryCodeCurrency={} + for (const[country, currency] of countryCurrencyPairs){ + countryCodeCurrency[country]=currency + } + + return countryCodeCurrency } +console.log(createLookup([['GB','GBP']])) + module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..2fcea7249 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,5 +1,7 @@ const createLookup = require("./lookup.js"); +const result=createLookup([['US','USD'],['CA','CAD']]) +console.log (result) test.todo("creates a country currency code lookup for multiple codes"); /* @@ -33,3 +35,12 @@ It should return: 'CA': 'CAD' } */ + +// create single country currency in countryCurrencyPairs +const result1=createLookup([['GB','GBP']]) +console.log(result1) +test.todo('creates a single county code currency ') + +//given an empty country currency pair/array +console.log(createLookup([[]])) +test.todo('return an empty object with empty pair given') \ No newline at end of file From d25f0a17f0103a4569c7095f54cf12a51f5d7284 Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 1 Mar 2026 17:03:47 +0000 Subject: [PATCH 5/9] complete query --- Sprint-2/implement/querystring.js | 12 +++++++++-- Sprint-2/implement/querystring.test.js | 28 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..c3f9cb563 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,16 +1,24 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { + if (typeof queryString!=="string"||queryString.length === 0) { return queryParams; } const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + const equalIndex = pair.indexOf("="); + + const key = pair.slice(0, equalIndex); + const value = pair.slice(equalIndex + 1); + queryParams[key] = value; } return queryParams; } +console.log(parseQueryString("color=blue&quality=good")) +console.log(parseQueryString("equation=x=y+1")) +console.log(parseQueryString("")) + module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..696609e50 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,31 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); + +// Duplicate keys, last one wins +test('duplicate keys overwrite previous', () => { + expect(parseQueryString('color=blue&color=red')).toEqual({ + color: 'red' + }); +}); + +// Empty string input +test('returns empty object for empty string', () => { + expect(parseQueryString('')).toEqual({}); +}); + +// Null/invalid input +test('returns empty object for null or non-string', () => { + expect(parseQueryString(null)).toEqual({}); + expect(parseQueryString(123)).toEqual({}); +}); + +// Missing value +test('handles keys with empty values', () => { + expect(parseQueryString('empty=')).toEqual({ empty: '' }); +}); + +// Missing key +test('ignores pairs without keys', () => { + expect(parseQueryString('=novalue')).toEqual({ '': 'novalue' }); +}); From 4b2cca7d66a22226c86882765b942077864f02b4 Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 1 Mar 2026 17:54:55 +0000 Subject: [PATCH 6/9] complete tally --- Sprint-2/implement/tally.js | 26 +++++++++++++++++++++++++- Sprint-2/implement/tally.test.js | 5 ++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..79004f99b 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,27 @@ -function tally() {} +function tally(array) { + if (!Array.isArray(array)) { + throw new Error("Invalid input: expected an array"); + } + + const count={} + for(item of array){ + if (count[item]){ + count[item] += 1 + } + else{ + count[item] = 1 + } + } + return count + } + +console.log(tally([ 2,"bee",2,"apple","apple",2, "banana"])) + +try { + console.log(tally('morning')); +} catch (err) { + console.error(err.message); +} + module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..c8c43e067 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,12 +23,15 @@ const tally = require("./tally.js"); // Given an empty array // When passed to tally // Then it should return an empty object +console.log(tally([ ])) test.todo("tally on an empty array returns an empty object"); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item - +console.log(tally([ 2,"bee",2,"apple","apple",2, "banana"])) +test.todo("tally on single, repeated or duplicate items return counts for each unique item ") // Given an invalid input like a string // When passed to tally // Then it should throw an error +test.todo('tally on string return throw an error:invalid input, expected an array') From 9fcea2619fddb2ef91f33d398d92874674b5262b Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 1 Mar 2026 18:25:44 +0000 Subject: [PATCH 7/9] amend function --- Sprint-2/interpret/invert.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..1b3a723ea 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 } +console.log(invert({a:1, b:2, apple:4})) + +// a) What is the current return value when invert is called with { a : 1 } +// it returns {key:1} // b) What is the current return value when invert is called with { a: 1, b: 2 } +// it returns {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(obj) lets loop [key, value] pairs easily because .entries(object/array) is built in method in javascript // d) Explain why the current return value is different from the target output +// Because invertedObj.key=value is wrong which means key of property will be always 'key' and value will remains the same as obj array in invertedObj // e) Fix the implementation of invert (and write tests to prove it's fixed!) +// I put invertedObh[value]= key instead then the function works as expected \ No newline at end of file From bac8a52d52d85fd815908cd4d54364d4d3bdc448 Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 22 Mar 2026 09:58:29 +0000 Subject: [PATCH 8/9] correction --- Sprint-2/debug/recipe.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 7481a5cec..d5fc13ae4 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -12,8 +12,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} -ingredients:`); - -for (const ingredient of recipe.ingredients) { - console.log(ingredient); -} +ingredients: +${recipe.ingredients.join("\n")}`); From a25d8cf398605d9d3694146fb7ff5c71a4efaff5 Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 22 Mar 2026 10:24:58 +0000 Subject: [PATCH 9/9] correction --- Sprint-2/implement/contains.test.js | 44 +++++++++++++++++++++-------- Sprint-2/implement/lookup.js | 10 ++++--- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 3b278cc51..ea41bc567 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,30 +20,50 @@ as the object doesn't contains a key of 'c' // Given an empty object // When passed to contains // Then it should return false -object={} -console.log(object,'') test.todo("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 -object={name:'jin', age:13} -console.log (contains(object, 'age')) -test.todo("contains age property in object return true") - // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false -object={name:'jin', age:13} -console.log (contains(object, 'nice')) -test.todo("contains no nice property in object return false") // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error -object={name:'jin', age:13} -console.log (contains(object, '[1,2,5]')) -test.todo("contains no array property in object return false") +describe('contains function', () => { + + test('returns false for an empty object', () => { + const object = {}; + expect(contains({}, 'name')).toBe(false); + }); + + test('returns true when property exists', () => { + const object = { name: 'jin', age: 13 }; + expect(contains(object, 'age')).toBe(true); + }); + + test('returns false when property does not exist', () => { + const object = { name: 'jin', age: 13 }; + expect(contains(object, 'nice')).toBe(false); + }); + + test('returns false when input is an array', () => { + const object = [1, 2, 5]; + expect(contains(object, '0')).toBe(false); + }); + + test('returns false when input is null', () => { + expect(contains(null, 'age')).toBe(false); + }); + + test('returns false when input is not an object', () => { + expect(contains(123, 'age')).toBe(false); + expect(contains('hello', 'length')).toBe(false); + }); + +}); \ No newline at end of file diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index f84776beb..97ed7fd6e 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,12 +1,14 @@ function createLookup(countryCurrencyPairs) { - const countryCodeCurrency={} - for (const[country, currency] of countryCurrencyPairs){ - countryCodeCurrency[country]=currency + const countryCodeCurrency = {} + + for (const[country, currency] of countryCurrencyPairs) { + countryCodeCurrency[country] = currency } return countryCodeCurrency } -console.log(createLookup([['GB','GBP']])) +console.log(createLookup([['GB', 'GBP']])); + module.exports = createLookup;