Skip to content
5 changes: 4 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Predict and explain first...

// The result will be undefine. The reason we are trying to get an information using an array index method for and object.


// This code should log out the houseNumber from the address object
// but it isn't working...
// Fix anything that isn't working
Expand All @@ -12,4 +15,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
5 changes: 4 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Predict and explain first...

//The for...of loop only works on iterable objects, like arrays, strings, Maps, Sets.


// 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

Expand All @@ -11,6 +14,6 @@ const author = {
alive: true,
};

for (const value of author) {
for (const value of Object.values (author)) {
console.log(value);
}
9 changes: 7 additions & 2 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Predict and explain first...

// This is trying to print the whole object (recipe) instead of the ingredients array.

// 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?
Expand All @@ -11,5 +13,8 @@ const recipe = {
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
ingredients:`);

for (const ingredient of recipe.ingredients) {
console.log(ingredient);
}
9 changes: 8 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
function contains() {}
function contains(obj, prop) {
// Check that obj is an object (not null) and not an array
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
return false;
}
// Check if the property exists directly on the object
return Object.prototype.hasOwnProperty.call(obj, prop);
}

module.exports = contains;
20 changes: 18 additions & 2 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,32 @@ 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("returns false for empty object", () => {
expect(contains({}, "a")).toBe(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true

test("returns true for existing property", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "a")).toBe(true);
expect(contains(obj, "b")).toBe(true);
});
// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test("returns false for non-existent property", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "c")).toBe(false);
});

// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("returns false for invalid inputs", () => {
expect(contains([1, 2, 3], "0")).toBe(false);
expect(contains(null, "a")).toBe(false);
expect(contains(undefined, "a")).toBe(false);
expect(contains("string", "length")).toBe(false);
});
20 changes: 19 additions & 1 deletion Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
function createLookup() {

// implementation here
function createLookup(pairs) {

if (!Array.isArray(pairs)) {
throw new Error('Input must be an array of pairs');
}

const lookup = {};

for (const pair of pairs) {

if (!Array.isArray(pair) || pair.length !== 2) {
throw new Error('Each element must be an array of [countryCode, currencyCode]');
}
const [country, currency] = pair;
lookup[country] = currency;
}

return lookup;
}

module.exports = createLookup;
15 changes: 13 additions & 2 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
const createLookup = require("./lookup.js");

test.todo("creates a country currency code lookup for multiple codes");

test("creates a country currency code lookup for multiple codes", () => {
const input = [
["US", "USD"],
["CA", "CAD"],
];

const expected = {
US: "USD",
CA: "CAD",
};

expect(createLookup(input)).toEqual(expected);
});
/*

Create a lookup object of key value pairs from an array of code pairs
Expand Down
5 changes: 3 additions & 2 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
function parseQueryString(queryString) {
const queryParams = {};
if (queryString.length === 0) {
if (!queryString || queryString.length === 0) {
return queryParams;
}
const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
const [key, ...rest] = pair.split("=");
const value = rest.join("="); // this join back the remaining parts
queryParams[key] = value;
}

Expand Down
17 changes: 17 additions & 0 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,20 @@ test("parses querystring values containing =", () => {
"equation": "x=y+1",
});
});

test("parses multiple query params", () => {
expect(parseQueryString("a=1&b=2")).toEqual({
a: "1",
b: "2",
});
});

test("handles key with no value", () => {
expect(parseQueryString("a=")).toEqual({
a: "",
});
});

test("returns empty object for empty string", () => {
expect(parseQueryString("")).toEqual({});
});
14 changes: 13 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
function tally() {}
function tally(items) {
if (!Array.isArray(items)) {
throw new Error("Input must be an array");
}

const result = {};

for (const item of items) {
result[item] = (result[item] || 0) + 1;
}

return result;
}

module.exports = tally;
14 changes: 13 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@ 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("tally on an empty array returns an empty object", () => {
expect(tally([])).toEqual({});
});

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item
test("returns counts for each unique item when array has duplicates", () => {
expect(tally(["a", "a", "b", "c"])).toEqual({
a: 2,
b: 1,
c: 1,
});
});

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
test("throws an error for invalid input like a string", () => {
expect(() => tally("abc")).toThrow("Input must be an array");
});
27 changes: 24 additions & 3 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,43 @@

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 }));
//Result: { key: 1 }

// b) What is the current return value when invert is called with { a: 1, b: 2 }
console.log(invert({ a: 1, b: 2 }));
// Result: { key: 2 }

// c) What is the target return value when invert is called with {a : 1, b: 2}

console.log(invert({ a: 1, b: 2 }));
// Result should be{"1": a, "2":"b"}

// c) What does Object.entries return? Why is it needed in this program?

// It takes an object and returns an array of key-value pairs, where each pair is itself an array:
const obj = { a: 1, b: 2 };
console.log(Object.entries(obj));
//Result:[ [ 'a', 1 ], [ 'b', 2 ] ]

// d) Explain why the current return value is different from the target output

// The line invertedObj.key = value; creates a "key" and assign the value to it. With variables, we need to use bracket notation and dot notation.

// e) Fix the implementation of invert (and write tests to prove it's fixed!)

// After fixing the code i ran node and got the following accordingly:
//{ '1': 'a' }
//{ '1': 'a', '2': 'b' }
//{ '1': 'a', '2': 'b' }
//[ [ 'a', 1 ], [ 'b', 2 ] ]


module.exports = invert;
23 changes: 23 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const invert = require('./invert');
test("inverts a single key-value pair", () => {
expect(invert({ a: 1 })).toEqual({ 1: "a" });
});

test("inverts multiple key-value pairs", () => {
expect(invert({ a: 1, b: 2 })).toEqual({ 1: "a", 2: "b" });
});

test("handles string values", () => {
expect(invert({ x: "orange", y: "grape" })).toEqual({
orange: "x",
grape: "y",
});
});

test("returns empty object when input is empty", () => {
expect(invert({})).toEqual({});
});

test("overwrites duplicate values (last key wins)", () => {
expect(invert({ a: 1, b: 1 })).toEqual({ 1: "b" });
});
Loading