Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2c983b7
Updated code for median.js to pass the late expectations
Jul 20, 2026
6c109e9
Added code to dedupe.js
Jul 20, 2026
d57add3
added code for max.js
Jul 20, 2026
e3befbb
Added code to sum.js
Jul 20, 2026
872ddf0
modified code on includes.js to use a for...of loop
Jul 21, 2026
6c28930
Changed code in address. js to specify houseNumber
Jul 21, 2026
bbf0a73
Updated code and added notes for author.js
Jul 21, 2026
5c2b4b5
update the code and added notes to recipe.js
Jul 21, 2026
663412b
Added code and tests for contains.js
Jul 23, 2026
4c0d767
added code to lookup.test
Jul 23, 2026
827b052
added code and passed tests for querystring.test.js
Jul 28, 2026
2c0a94c
added code and tests for tally.test and js
Jul 28, 2026
f583fd7
updated tests output for tally.test
Jul 29, 2026
93df342
added answers to invert.js and added a .test.js page to
Jul 29, 2026
6998347
Merge branch 'main' into coursework/sprint-2
JorvanW Aug 10, 2026
5b96abc
removed code from sprint 1 and removed prep folder
Aug 10, 2026
f6cf1e1
removed file
Aug 10, 2026
fca3dde
removed errors in the lookup.js code and updated the test to function…
Aug 13, 2026
edb970d
removed console.log in code
Aug 13, 2026
d7af84e
updated tally.js and tally.test to turn and empty array into a empty …
Aug 13, 2026
37deb3c
removed excess comments in invert.js. fixed the code and added more …
Aug 13, 2026
bdcc0fc
updated answers for invert.js
Aug 13, 2026
04d19dd
removed unecessary comment
Aug 13, 2026
ec4725c
added more test cases for invert.test.js
Aug 18, 2026
25e5aff
added more test cases for lookup.test and test involving various curr…
Aug 18, 2026
10e5ae4
added a test for testing empty objects
Aug 18, 2026
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
4 changes: 3 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// Predict and explain first...
/* To specify house number the console.log should use. address.houseNumber.
without it, It would show as undefined */

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

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

/* The code wants to log the property value and is using a for...of loop
to make sure it logs everything, however Objects aren't in order and Javascript
doesn't know what you want. Author is an Object and objects are not
iterable which is the error. To fix this change (const value of author) to
(const value of object.values(author)) to specify we want the values (not properties)
in the Object which is 'author'. Using a loop allows up to add information in author
without needing to make changes anywhere else while getting an updated log */

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

for (const value of author) {
for (const value of Object.values(author)) {
console.log(value);
}
12 changes: 9 additions & 3 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Predict and explain first...
/* In the console.log the {recipe} doesn't specify ingredients so it will
show up as undefined. Changing it to {recipe.ingredients} should fix that issue.
To log each ingredient on a new line you can use (.join("\n")) which
separate the code by line */


// This program should log out the title, how many it serves and the ingredients.
// Each ingredient should be logged on a new line
Expand All @@ -10,6 +15,7 @@ const recipe = {
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
console.log(`${recipe.title}
serves ${recipe.serves}
ingredients:
${recipe.ingredients.join("\n")}`);
Comment thread
Poonam-raj marked this conversation as resolved.
8 changes: 7 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
function contains() {}
function contains(object, property) {
if (Array.isArray(object)) {
throw new Error("Invalid parameter");
}

return property in object;
}

module.exports = contains;
21 changes: 20 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,39 @@ as the object doesn't contains a key of 'c'
// 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
test("contains a passed object should return true, false otherwise",() => {
expect(contains({a: 1, b: 2}, 2)).toEqual(false);
expect(contains({a: 1, b: 2}, 'b')).toEqual(true);
});

// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");
test("contains an empty object, returns false",() => {
expect(contains({})).toEqual(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test("contains object with properties, return true when passed with existing property name",() => {
expect(contains({name: 'alice'}, 'name')).toEqual(true);
});


// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test("contains a passed object with non-existent property names return false",() => {
expect(contains({a: 1, b: 2}, 'c')).toEqual(false);
});


// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("contains passed invalid parameters like an array to throw error", () => {
expect(() => contains(['horse', 'dog', 'fish'], 'fish'))
.toThrow("Invalid parameter");
});

10 changes: 8 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
function createLookup() {
// implementation here
function createLookup(countryCurrencyPairs) {
const lookup = {};

countryCurrencyPairs.forEach((pair) => {
lookup[pair[0]] = pair[1];
});

return lookup;
}

module.exports = createLookup;
44 changes: 43 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
const createLookup = require("./lookup.js");

test.todo("creates a country currency code lookup for multiple codes");
test("creates a lookup from one country currency pair", () => {
const countryCurrencyPairs = [["JP", "JPY"]];

expect(createLookup(countryCurrencyPairs)).toEqual({
JP: "JPY",
});
});

test("creates a lookup for multiple country currency pairs", () => {
const countryCurrencyPairs = [
["US", "USD"],
["CA", "CAD"],
["EN", "GBP"],
];

expect(createLookup(countryCurrencyPairs)).toEqual({
US: "USD",
CA: "CAD",
EN: "GBP",
});
});

test("creates a lookup for a larger list of country currency pairs", () => {
const countryCurrencyPairs = [
["FR", "EUR"],
["AU", "AUD"],
["CH", "CHF"],
["MX", "MXN"],
["SE", "SEK"],
];

expect(createLookup(countryCurrencyPairs)).toEqual({
FR: "EUR",
AU: "AUD",
CH: "CHF",
MX: "MXN",
SE: "SEK",
});
});

test("creates an empty lookup when given an empty array", () => {
expect(createLookup([])).toEqual({});
});

/*

Expand Down
14 changes: 12 additions & 2 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ function parseQueryString(queryString) {
if (queryString.length === 0) {
return queryParams;
}
const keyValuePairs = queryString.split("&");
let keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
if (!pair) continue; // continue is to skip empty strings
let [key, ...values] = pair.split("=");

key = decodeURIComponent(key.replace(/\+/g, " "));
const value = decodeURIComponent(values.join("=").replace(/\+/g, " "));

/* decodeURIComponent function decodes percent encoded characters
"replace" swaps one character with another
(/../) means the begining and end of a regex pattern (better for characters)
'\+' is an escaped '+' because it has its own function in coding */

queryParams[key] = value;
}

Expand Down
5 changes: 3 additions & 2 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ test("should decode percent-encoded characters", () => {
});
});

test("should replace '+' by ' '", () => {
test("should replace '+' by ' '", () => {
expect(parseQueryString("full+name=John+Doe")).toEqual({
"full name": "John Doe",
});
});

// Stretch exercise: Handling query strings that contain identical keys
/* Stretch exercise: Handling query strings that contain identical keys

// Delete this test if you are not working on this optional case
test("should store values of a key in an array when the key has 2 or more values", () => {
Expand All @@ -46,3 +46,4 @@ test("should store values of a key in an array when the key has 2 or more values
foo: "bar",
});
});
*/
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(array) {
if (!Array.isArray(array)) {
throw new Error("Input must be an array");
}

if (array.length === 0) {
return {};
}

const result = {};

for (const item of array) {
if (result[item]) {
result[item]++;
} else {
result[item] = 1;
}
}

return result;
}

module.exports = tally;
13 changes: 12 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,27 @@ const tally = require("./tally.js");
// 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("tally should return an count of each item passed through an array ", () => {
expect(tally(["a", "b", "c"])).toEqual({ a: 1, b: 1, c: 1 });
});

// 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("tally on an array with duplicate items return a count for each item ", () => {
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 with a invalid string should throw an error", () => {
expect(() => tally("car")).toThrow("Input must be an array");
});
11 changes: 9 additions & 2 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,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 }
// { key: 1 }

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

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

// c) What does Object.entries return? Why is it needed in this program?
// Object Entries return an array of key value pairs and it's needed so the for...of loop goes through each key and value individually

// d) Explain why the current return value is different from the target output
// The current return value only shows {key: 2}. It doesn't show the first key and value only the second,
// and it doesn't specify the second key. Its just defined as 'key'. It also doesn't swap the key and value around as intended

// e) Fix the implementation of invert (and write tests to prove it's fixed!)
Comment thread
Poonam-raj marked this conversation as resolved.

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

test("when passed invert swaps single key-value pair", () => {
expect(invert({ a: 1 })).toEqual({ 1: "a" });
});

test("when invert is passed two key-value pairs, it swaps both keys and values", () => {
expect(invert({ a: 1, b: 2 })).toEqual({
1: "a",
2: "b",
});
});

test("When invert is passed, multiple keys and values in the object should be swapped ", () => {
expect(invert({ x: 10, y: 20 })).toEqual({ 10: "x", 20: "y" });
});

test("when invert is passed a larger object, it swaps all keys and values", () => {
expect(invert({ a: 1, b: 2, c: 3, d: 4 })).toEqual({
1: "a",
2: "b",
3: "c",
4: "d",
});
});

test("when passed invert swaps string values", () => {
expect(invert({ first: "hello", second: "world" })).toEqual({
hello: "first",
world: "second",
});
});

test("when invert is passed duplicate values, the last key is kept", () => {
expect(invert({ a: 1, b: 1 })).toEqual({
1: "b",
});
});

test("when invert is passed with empty objects it should return an empty object", () => {
expect(invert({})).toEqual({});
});
Loading