Skip to content
Closed
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
28 changes: 25 additions & 3 deletions Sprint-1/fix/median.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,31 @@
// or 'list' has mixed values (the function is expected to sort only numbers).

function calculateMedian(list) {
const middleIndex = Math.floor(list.length / 2);
const median = list.splice(middleIndex, 1)[0];
return median;
// Validate input: must be an array
if (!Array.isArray(list)) {
return null;
}

// Filter out non-numeric values
const numbers = list.filter((item) => typeof item === "number");

// If no numeric values, return null
if (numbers.length === 0) {
return null;
}

// Sort numbers without mutating original list
const sorted = [...numbers].sort((a, b) => a - b);

const middleIndex = Math.floor(sorted.length / 2);

// Odd length → return middle number
if (sorted.length % 2 !== 0) {
return sorted[middleIndex];
}

// Even length → average of two middle numbers
return (sorted[middleIndex - 1] + sorted[middleIndex]) / 2;
}

module.exports = calculateMedian;
6 changes: 5 additions & 1 deletion Sprint-1/implement/dedupe.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
function dedupe() {}
function dedupe(arr) {
return [...new Set(arr)];
}

module.exports = dedupe;
5 changes: 5 additions & 0 deletions Sprint-1/implement/max.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
function findMax(elements) {
const numbers = elements.filter((item) => typeof item === "number");
if (numbers.length === 0) {
return -Infinity;
}
return Math.max(...numbers);
}

module.exports = findMax;
23 changes: 22 additions & 1 deletion Sprint-1/implement/max.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,49 @@ const findMax = require("./max.js");
// When passed to the max function
// Then it should return -Infinity
// Delete this test.todo and replace it with a test.
test.todo("given an empty array, returns -Infinity");
//test.todo("given an empty array, returns -Infinity");
test("given an empty array, returns -Infinity", () => {
expect(findMax([])).toBe(-Infinity);
});

// Given an array with one number
// When passed to the max function
// Then it should return that number
test("given an array with one number, returns that number", () => {
expect(findMax([42])).toBe(42);
});

// Given an array with both positive and negative numbers
// When passed to the max function
// Then it should return the largest number overall
test("given an array with positive and negative numbers, returns the largest", () => {
expect(findMax([-10, 5, 3, -2])).toBe(5);
});

// Given an array with just negative numbers
// When passed to the max function
// Then it should return the closest one to zero
test("given an array with only negative numbers, returns the closest to zero", () => {
expect(findMax([-10, -3, -20])).toBe(-3);
});

// Given an array with decimal numbers
// When passed to the max function
// Then it should return the largest decimal number
test("given an array with decimal numbers, returns the largest decimal", () => {
expect(findMax([1.2, 3.5, 2.8])).toBe(3.5);
});

// Given an array with non-number values
// When passed to the max function
// Then it should return the max and ignore non-numeric values
test("given an array with non-number values, ignores them and returns the max", () => {
expect(findMax(['hey', 10, 'hi', 60, 10])).toBe(60);
});

// Given an array with only non-number values
// When passed to the max function
// Then it should return the least surprising value given how it behaves for all other inputs
test("given an array with only non-number values, returns -Infinity", () => {
expect(findMax(['a', 'b', null, undefined])).toBe(-Infinity);
});
5 changes: 5 additions & 0 deletions Sprint-1/implement/sum.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
function sum(elements) {
const numbers = elements.filter((item) => typeof item === "number");
if (numbers.length === 0) {
return 0;
}
return numbers.reduce((total, num) => total + num, 0);
}

module.exports = sum;
20 changes: 19 additions & 1 deletion Sprint-1/implement/sum.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,42 @@ const sum = require("./sum.js");
// Given an empty array
// When passed to the sum function
// Then it should return 0
test.todo("given an empty array, returns 0")
// test.todo("given an empty array, returns 0")
test("given an empty array, returns 0", () => {
expect(sum([])).toBe(0);
});

// Given an array with just one number
// When passed to the sum function
// Then it should return that number
test("given an array with one number, returns that number", () => {
expect(sum([42])).toBe(42);
});

// Given an array containing negative numbers
// When passed to the sum function
// Then it should still return the correct total sum
test("given an array with negative numbers, returns the correct total", () => {
expect(sum([-5, 10, -3])).toBe(2);
});

// Given an array with decimal/float numbers
// When passed to the sum function
// Then it should return the correct total sum
test("given an array with decimal numbers, returns the correct total", () => {
expect(sum([1.5, 2.5, 3.1])).toBe(7.1);
});

// Given an array containing non-number values
// When passed to the sum function
// Then it should ignore the non-numerical values and return the sum of the numerical elements
test("given an array with non-number values, ignores them and returns the sum of numbers", () => {
expect(sum(["hey", 10, "hi", 60, 10])).toBe(80);
});

// Given an array with only non-number values
// When passed to the sum function
// Then it should return the least surprising value given how it behaves for all other inputs
test("given an array with only non-number values, returns 0", () => {
expect(sum(["a", null, undefined, "b"])).toBe(0);
});
3 changes: 1 addition & 2 deletions Sprint-1/refactor/includes.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Refactor the implementation of includes to use a for...of loop

function includes(list, target) {
for (let index = 0; index < list.length; index++) {
const element = list[index];
for (const element of list) {
if (element === target) {
return true;
}
Expand Down
15 changes: 14 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
// but it isn't working...
// Fix anything that isn't working

/*const address = {
houseNumber: 42,
street: "Imaginary Road",
city: "Manchester",
country: "England",
postcode: "XYZ 123",
};

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

// The line "address[0]" is wrong. Because address is an object not an array, so "address[0]" is undefined. The output will be "My house number is undefined".

// Corrected code
const address = {
houseNumber: 42,
street: "Imaginary Road",
Expand All @@ -12,4 +25,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
20 changes: 19 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// 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 = {
/* const author = {
firstName: "Zadie",
lastName: "Smith",
occupation: "writer",
Expand All @@ -14,3 +14,21 @@ const author = {
for (const value of author) {
console.log(value);
}
*/

// Prediction and Explanation
/* The line "for (const value of author) {console.log(value);}" will not work because for-of is used only for iterable things, e.g: arrays, strings, maps, sets.
But author is a plain object (created with {}), and plain objects are not iterable. So Javascript throws: TypeError: author is not iterable because objects don't have a natural order to loop through. */

// Corrected code
const author = {
firstName: "Zadie",
lastName: "Smith",
occupation: "writer",
age: 40,
alive: true,
};

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

const recipe = {
/*const recipe = {
title: "bruschetta",
serves: 2,
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
Expand All @@ -13,3 +13,26 @@ const recipe = {
console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
*/

// Prediction and Explanation
/*
The line inside the template string: ${recipe} does not print the ingredients.
Instead, JavaScript converts the entire recipe object into a string, which becomes "[object Object]". This happens
because plain objects {} are not automatically converted into readable text. The program should print each ingredient on a new line, but the current code
never loops through recipe.ingredients, so nothing is printed correctly.
*/

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

console.log(`${recipe.title} serves ${recipe.serves}
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) {
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
return false;
}

return obj.hasOwnProperty(prop);
}

module.exports = contains;

29 changes: 28 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,47 @@ 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("returns true when object contains the property", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "a")).toBe(true);
});

test("returns false when object does not contain the property", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "c")).toBe(false);
});


// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns 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("returns true when object contains the property", () => {
const obj = { a: 1, b: 2 };
expect(contains(obj, "a")).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 when object does not contain the 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 parameters like an array", () => {
expect(contains([], "a")).toBe(false);
expect(contains(null, "a")).toBe(false);
expect(contains(123, "a")).toBe(false);
expect(contains("hello", "a")).toBe(false);
});
9 changes: 8 additions & 1 deletion Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
function createLookup() {
function createLookup(pairs) {
// implementation here
const lookup = {};

for (const [country, currency] of pairs) {
lookup[country] = currency;
}

return lookup;
}

module.exports = createLookup;
26 changes: 24 additions & 2 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
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
Expand Down Expand Up @@ -33,3 +31,27 @@ It should return:
'CA': 'CAD'
}
*/

test("creates a country currency code lookup for multiple codes", () => {
const input = [
["US", "USD"],
["CA", "CAD"],
["NG", "NGN"],
["GB", "GBP"],
["EU", "EUR"],
["JP", "JPY"],
["AU", "AUD"],
];

const result = createLookup(input);

expect(result).toEqual({
US: "USD",
CA: "CAD",
NG: "NGN",
GB: "GBP",
EU: "EUR",
JP: "JPY",
AU: "AUD",
});
});
Loading
Loading