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..d5fc13ae4 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,8 +1,9 @@ // 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? +// How can you fix it? i will loop through ingredient to get each single ingredient const recipe = { title: "bruschetta", @@ -11,5 +12,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +ingredients: +${recipe.ingredients.join("\n")}`); 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..ea41bc567 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -30,6 +30,40 @@ test.todo("contains on empty object returns false"); // When passed to contains with a non-existent property name // Then it should return false + + // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +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 a6746e07f..97ed7fd6e 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,14 @@ -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 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' }); +}); 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') 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