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
2 changes: 2 additions & 0 deletions Sprint-2/debug/address.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,4 +12,6 @@ const address = {
postcode: "XYZ 123",
};

// console.log(`${address[2]}`)
console.log(`My house number is ${address[0]}`);

10 changes: 7 additions & 3 deletions Sprint-2/debug/author.js
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
// Predict and explain first...
// TypeError: author is not iterable because A for...of loop is used for iterable things such as arrays, strings, Maps, and Sets.

// But author is a plain object. Plain objects aren't directly iterable with for...of.

// To loop through an object's values, use:

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

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

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

// the code might print something like this bruschetta serves 2
//ingredients: [object Object] because the ${recipe} is an object and we only trying to print the
// ingredients inside the object
// 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,5 @@ const recipe = {
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
ingredients:
${recipe.ingredients.join("\n")}`);
10 changes: 9 additions & 1 deletion Sprint-2/implement/contains.js
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
function contains() {}
function contains(object, property) {
if (typeof object !== "object" || object === null || Array.isArray(object)) {
return false;
}

return Object.hasOwn(object, property);
}

module.exports = contains;


15 changes: 13 additions & 2 deletions Sprint-2/implement/contains.test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,15 +21,26 @@ as the object doesn't contains a key of 'c'
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");

test("contains on empty object returns false", () => {
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("contains returns true when property exists", () => {
expect(contains({ a: 1, b: 2 }, "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 returns false when property does not exist", () => {
expect(contains({ a: 1, b: 2 }, "c")).toBe(false);
});


// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("contains returns false when passed an array", () => {
expect(contains([], "a")).toBe(false);
});
12 changes: 11 additions & 1 deletion Sprint-2/implement/lookup.js
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
function createLookup() {
function createLookup(countryCurrencyPairs) {
// implementation here
const lookup = {};

for (const pair of countryCurrencyPairs) {
const [countryCode, currencyCode] = pair;
lookup[countryCode] = currencyCode;
}

return lookup;
}

module.exports = createLookup;

module.exports = createLookup;
11 changes: 11 additions & 0 deletions Sprint-2/implement/lookup.test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,3 +33,14 @@ It should return:
'CA': 'CAD'
}
*/
test("creates a country currency code lookup for multiple codes", () => {
const countryCurrencyPairs = [
["US", "USD"],
["CA", "CAD"],
];

expect(createLookup(countryCurrencyPairs)).toEqual({
US: "USD",
CA: "CAD",
});
});
41 changes: 39 additions & 2 deletions Sprint-2/implement/querystring.js
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,50 @@
function parseQueryString(queryString) {
const queryParams = {};

// If the query string is empty, return an empty object
if (queryString.length === 0) {
return queryParams;
}

// Split the query string into separate key-value pairs
const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
// Ignore empty pairs
if (pair === "") {
continue;
}

// Find the first "="
const equalsPosition = pair.indexOf("=");

let key;
let value;

// If there is no "="
if (equalsPosition === -1) {
key = pair;
value = "";
} else {
// Everything before "=" is the key
key = pair.substring(0, equalsPosition);

// Everything after the first "=" is the value
value = pair.substring(equalsPosition + 1);
}

// Replace "+" with spaces and decode special characters
key = decodeURIComponent(key.replace(/\+/g, " "));
value = decodeURIComponent(value.replace(/\+/g, " "));

// If the key already exists, store multiple values in an array
if (queryParams[key] === undefined) {
queryParams[key] = value;
} else if (Array.isArray(queryParams[key])) {
queryParams[key].push(value);
} else {
queryParams[key] = [queryParams[key], value];
}
}

return queryParams;
Expand Down
20 changes: 19 additions & 1 deletion Sprint-2/implement/tally.js
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
function tally() {}
function tally(items) {
// Check that the input is an array
if (!Array.isArray(items)) {
throw new Error("Input must be an array");
}

const counts = {};

// Go through each item in the array
for (const item of items) {
if (counts[item] === undefined) {
counts[item] = 1;
} else {
counts[item] = counts[item] + 1;
}
}

return counts;
}

module.exports = tally;
14 changes: 13 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,11 +24,23 @@ const tally = require("./tally.js");
// 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("tally counts duplicate items", () => {
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("tally throws an error when given a string", () => {
expect(() => tally("hello")).toThrow();
});
12 changes: 10 additions & 2 deletions Sprint-2/interpret/invert.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,20 +10,28 @@ function invert(obj) {
const invertedObj = {};

for (const [key, value] of Object.entries(obj)) {
invertedObj.key = value;
invertedObj[value] = key;
}

return invertedObj;
}
module.exports = invert

// a) What is the current return value when invert is called with { a : 1 }
// {key: 1} because the invertedObj,ket = value does not use the variable key


// b) What is the current return value when invert is called with { a: 1, b: 2 }
// {key:2} the loop runs twice and the second iteration replaces the first one so the answer becomes 2

// c) What is the target return value when invert is called with {a : 1, b: 2}
// The target return value is to swap the keys and values so {a:1, b:2} becomes {1:a, 2:b}

// c) What does Object.entries return? Why is it needed in this program?
// Object.entries() turns an object into an array containing key-value pairs

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

// invertedObj.key means to create or access an object called key
// and inverted invertedObj[key] means to use whatever value is stored in the key variable
// e) Fix the implementation of invert (and write tests to prove it's fixed!)

21 changes: 21 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
const invert = require("./invert.js");

test("inverts an object with one property", () => {
expect(invert({ a: 1 })).toEqual({
1: "a",
});
});

test("inverts an object with multiple properties", () => {
expect(invert({ a: 1, b: 2 })).toEqual({
1: "a",
2: "b",
});
});

test("inverts the example object", () => {
expect(invert({ x: 10, y: 20 })).toEqual({
10: "x",
20: "y",
});
});
Loading