Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Predict and explain first...

//answer: this code defines an object called address, and it has several properties (key–value pairs).

// This code should log out the houseNumber from the address object
// but it isn't working...
//answer : it doesnt work because in object, we dont use numeric index and the result is undefined

// Fix anything that isn't working

const address = {
Expand All @@ -12,4 +16,5 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
// console.log(`My house number is ${address[0]}`); wrong
console.log(`My house number is ${address.houseNumber}`); //correct
8 changes: 7 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// 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

//answer : the result is TypeError: author is not iterable Because objects are not iterable with for...of — that loop only works with arrays, strings, and other iterable types.

const author = {
firstName: "Zadie",
lastName: "Smith",
Expand All @@ -11,6 +13,10 @@ const author = {
alive: true,
};

for (const value of author) {
// for (const value of author) { wrong code
// console.log(value);
// }

for (const value of Object.values(author)) {
console.log(value);
}
18 changes: 15 additions & 3 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@
// Each ingredient should be logged on a new line
// How can you fix it?

//answer :
// ${recipe.title} → "bruschetta"

// ${recipe.serves} → 2

// ${recipe} → wrong! = > because recipe is an object, and when you interpolate it into a string, it becomes:

// [object Object]

const recipe = {
title: "bruschetta",
serves: 2,
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
};

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

for (let i = 0; i < recipe.ingredients.length; i++) {
console.log(recipe.ingredients[i]);
}
12 changes: 11 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
function contains() {}
// Implement the contains function
function contains(obj, propName) {
// Check that the first argument is an object, not null or an array
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
return false;
}

// Check if the object has the property
return obj.hasOwnProperty(propName);
}

// Export the function so other files can use it
module.exports = contains;
54 changes: 26 additions & 28 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,31 @@ const contains = require("./contains.js");
/*
Implement a function called contains that checks an object contains a
particular property

E.g. contains({a: 1, b: 2}, 'a') // returns true
as the object contains a key of 'a'

E.g. contains({a: 1, b: 2}, 'c') // returns false
as the object doesn't contains a key of 'c'
*/

// Acceptance criteria:

// Given a contains function
// When passed an object and a property name
// Then it should return true if the object contains the property, false otherwise

// Given an empty object
// When passed to contains
// Then it should return false
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

// Given an object with properties
// 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
// Test 1: Empty object
test("contains on empty object returns false", () => {
expect(contains({}, "a")).toBe(false);
});

// Test 2: Existing property
test("returns true when the property exists in the object", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "a")).toBe(true);
});

// Test 3: Non-existent property
test("returns false when the property does not exist in the object", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "c")).toBe(false);
});

// Test 4: Invalid input - array
test("returns false if input is an array", () => {
expect(contains([], "a")).toBe(false);
});

// Test 5: Invalid input - null
test("returns false if input is null", () => {
expect(contains(null, "a")).toBe(false);
});
21 changes: 19 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
function createLookup() {
// implementation here
// This function takes an array of country-currency pairs
// and turns it into an object where keys are country codes
// and values are currency codes
function createLookup(pairs) {
// Create an empty object to store the result
const lookup = {};

// Loop through each pair in the array
for (let i = 0; i < pairs.length; i++) {
const pair = pairs[i]; // e.g. ['US', 'USD']
const country = pair[0]; // first element is country code
const currency = pair[1]; // second element is currency code

lookup[country] = currency; // add it to the object
}

// Return the final lookup object
return lookup;
}

// Export the function so it can be used in tests or other files
module.exports = createLookup;
72 changes: 41 additions & 31 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@
const createLookup = require("./lookup.js");

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

/*

Create a lookup object of key value pairs from an array of code pairs

Acceptance Criteria:

Given
- An array of arrays representing country code and currency code pairs
e.g. [['US', 'USD'], ['CA', 'CAD']]

When
- createLookup function is called with the country-currency array as an argument

Then
- It should return an object where:
- The keys are the country codes
- The values are the corresponding currency codes

Example
Given: [['US', 'USD'], ['CA', 'CAD']]

When
createLookup(countryCurrencyPairs) is called

Then
It should return:
{
'US': 'USD',
'CA': 'CAD'
}
Implement a function called createLookup that turns an array of
country-currency code pairs into an object.
*/

// Test 1: multiple pairs
test("creates a country currency code lookup for multiple codes", () => {
const input = [
["US", "USD"],
["CA", "CAD"],
["GB", "GBP"],
];
const expected = {
US: "USD",
CA: "CAD",
GB: "GBP",
};
expect(createLookup(input)).toEqual(expected);
});

// Test 2: empty array should return empty object
test("returns empty object when given an empty array", () => {
const input = [];
const expected = {};
expect(createLookup(input)).toEqual(expected);
});

// Test 3: single pair
test("works with a single country-currency pair", () => {
const input = [["JP", "JPY"]];
const expected = { JP: "JPY" };
expect(createLookup(input)).toEqual(expected);
});

// Test 4: duplicate keys (last one wins)
test("handles duplicate country codes (last value wins)", () => {
const input = [
["US", "USD"],
["US", "USN"],
];
const expected = { US: "USN" }; // last one overwrites
expect(createLookup(input)).toEqual(expected);
});
17 changes: 14 additions & 3 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
function parseQueryString(queryString) {
const queryParams = {};
if (queryString.length === 0) {

// Return empty object if input is empty
if (!queryString || queryString.length === 0) {
return queryParams;
}

const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
// Split only on the first '='
const index = pair.indexOf("=");
if (index === -1) {
// No '=' in this pair, treat as key with empty string value
queryParams[pair] = "";
} else {
const key = pair.slice(0, index);
const value = pair.slice(index + 1);
queryParams[key] = value;
}
}

return queryParams;
Expand Down
35 changes: 27 additions & 8 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
// In the prep, we implemented a function to parse query strings.
// Unfortunately, it contains several bugs!
// Below is one test case for an edge case the implementation doesn't handle well.
// Fix the implementation for this test, and try to think of as many other edge cases as possible - write tests and fix those too.
const parseQueryString = require("./querystring.js");

const parseQueryString = require("./querystring.js")
// Test 1: normal key=value pairs
test("parses simple query string", () => {
expect(parseQueryString("a=1&b=2")).toEqual({ a: "1", b: "2" });
});

// Test 2: value contains '='
test("parses querystring values containing =", () => {
expect(parseQueryString("equation=x=y+1")).toEqual({
"equation": "x=y+1",
});
expect(parseQueryString("equation=x=y+1")).toEqual({ equation: "x=y+1" });
});

// Test 3: empty string returns empty object
test("returns empty object for empty query string", () => {
expect(parseQueryString("")).toEqual({});
});

// Test 4: key without value
test("parses key without value as empty string", () => {
expect(parseQueryString("keyWithoutValue")).toEqual({ keyWithoutValue: "" });
});

// Test 5: multiple keys including empty value
test("parses multiple keys including empty values", () => {
expect(parseQueryString("a=1&b=&c=3")).toEqual({ a: "1", b: "", c: "3" });
});

// Test 6: only & characters with empty keys
test("handles consecutive & correctly", () => {
expect(parseQueryString("a=1&&b=2")).toEqual({ a: "1", b: "2", "": "" });
});
22 changes: 21 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
function tally() {}
function tally(items) {
// Check if input is an array
if (!Array.isArray(items)) {
throw new Error("Input must be an array");
}

const result = {};

// Loop through each item in the array
for (const item of items) {
// If the item already exists in result, increment the count
if (result[item]) {
result[item] += 1;
} else {
// Otherwise, initialize the count to 1
result[item] = 1;
}
}

return result;
}

module.exports = tally;
48 changes: 20 additions & 28 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
const tally = require("./tally.js");

/**
* tally array
*
* In this task, you'll need to implement a function called tally
* that will take a list of items and count the frequency of each item
* in an array
*
* For example:
*
* tally(['a']), target output: { a: 1 }
* tally(['a', 'a', 'a']), target output: { a: 3 }
* tally(['a', 'a', 'b', 'c']), target output: { a : 2, b: 1, c: 1 }
*/
// Test 1: empty array should return empty object
test("tally on an empty array returns an empty object", () => {
expect(tally([])).toEqual({});
});

// Acceptance criteria:
// Test 2: array with single item
test("counts a single item", () => {
expect(tally(["a"])).toEqual({ a: 1 });
});

// 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 3: array with multiple duplicates
test("counts duplicates correctly", () => {
expect(tally(["a", "a", "a"])).toEqual({ a: 3 });
});

// 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 4: array with multiple unique items
test("counts multiple unique items correctly", () => {
expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 });
});

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
// Test 5: invalid input should throw an error
test("throws an error if input is not an array", () => {
expect(() => tally("not an array")).toThrow("Input must be an array");
});
Loading