From 1cfe7cdc04df2bcf86a2eee55d3cbbf89e15326a Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sat, 2 May 2026 14:30:32 +0200 Subject: [PATCH 01/13] feat: implement calculateMedian with input validation --- Sprint-1/fix/median.js | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b22590bc6..afdcda19e 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -1,14 +1,29 @@ -// Fix this implementation -// Start by running the tests for this function -// If you're in the Sprint-1 directory, you can run `npm test -- fix` to run the tests in the fix directory +function calculateMedian(list) { + // Check if input is a valid array + if (!Array.isArray(list)) { + return null; + } -// Hint: Please consider scenarios when 'list' doesn't have numbers (the function is expected to return null) -// or 'list' has mixed values (the function is expected to sort only numbers). + // Filter the list to keep only numbers + const numbers = list.filter((item) => typeof item === "number"); -function calculateMedian(list) { - const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; - return median; -} + // Return null if no numbers are found + if (numbers.length === 0) { + return null; + } + + // Sort the numbers in ascending order + // Note: we use [...numbers] or just numbers because filter already created a new array + numbers.sort((a, b) => a - b); + const middleIndex = Math.floor(numbers.length / 2); + + // If the count of numbers is odd, return the middle one + if (numbers.length % 2 !== 0) { + return numbers[middleIndex]; + } + + // If the count is even, return the average of the two middle numbers + return (numbers[middleIndex - 1] + numbers[middleIndex]) / 2; +} module.exports = calculateMedian; From fd5a5587a1c104bc7ce4c4026a2ac05b593de5d1 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:04:57 +0200 Subject: [PATCH 02/13] feat: implement dedupe function to remove duplicates from array --- Sprint-1/implement/dedupe.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..ed21667c2 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,18 @@ -function dedupe() {} +function dedupe(elements) { + // Create a new empty array to store unique items + let uniqueItems = []; + + // Loop through every item in the input array + for (let i = 0; i < elements.length; i++) { + // Check if the item is already in our uniqueItems array + if (!uniqueItems.includes(elements[i])) { + // If not present, add it to the uniqueItems array + uniqueItems.push(elements[i]); + } + } + + // Return the final array without duplicates + return uniqueItems; +} + +module.exports = dedupe; From 598944dc85d3dd32373194fc3a441eeff5dbfdbf Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:06:10 +0200 Subject: [PATCH 03/13] test: convert todo tests to active tests for dedupe function --- Sprint-1/implement/dedupe.test.js | 36 +++++++++++-------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 23e0f8638..4d566b994 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -1,27 +1,17 @@ const dedupe = require("./dedupe.js"); -/* -Dedupe Array -📖 Dedupe means **deduplicate** +test("given an empty array, it returns an empty array", () => { + // If input is empty, output should be empty + expect(dedupe([])).toEqual([]); +}); -In this kata, you will need to deduplicate the elements of an array +test("given an array with no duplicates, it returns a copy of the original array", () => { + // If there are no duplicates, the array stays the same + expect(dedupe([1, 2, 3])).toEqual([1, 2, 3]); +}); -E.g. dedupe(['a','a','a','b','b','c']) target output: ['a','b','c'] -E.g. dedupe([5, 1, 1, 2, 3, 2, 5, 8]) target output: [5, 1, 2, 3, 8] -E.g. dedupe([1, 2, 1]) target output: [1, 2] -*/ - -// Acceptance Criteria: - -// Given an empty array -// When passed to the dedupe function -// Then it should return an empty array -test.todo("given an empty array, it returns an empty array"); - -// Given an array with no duplicates -// When passed to the dedupe function -// Then it should return a copy of the original array - -// Given an array with strings or numbers -// When passed to the dedupe function -// Then it should remove the duplicate values, preserving the first occurence of each element +test("given an array with strings or numbers, it removes duplicate values", () => { + // Test if duplicates like 'a' or '1' are removed + expect(dedupe(["a", "a", "b"])).toEqual(["a", "b"]); + expect(dedupe([1, 1, 2, 2, 3])).toEqual([1, 2, 3]); +}); From a8b15357873811f527d14f905538b45624562e32 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:09:09 +0200 Subject: [PATCH 04/13] feat: implement max function with numeric filtering --- Sprint-1/implement/max.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..dd8a05b6e 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,14 @@ -function findMax(elements) { +function max(elements) { + // First, we filter the list to keep ONLY numbers + const onlyNumbers = elements.filter((item) => typeof item === "number"); + + // If there are no numbers at all, we return -Infinity (standard math behavior) + if (onlyNumbers.length === 0) { + return -Infinity; + } + + // Use Math.max with the spread operator (...) to find the largest number + return Math.max(...onlyNumbers); } -module.exports = findMax; +module.exports = max; From 6b61d9b7e20d9b8e540179ff30b5e20fdbb81a8a Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:15:16 +0200 Subject: [PATCH 05/13] fix: rename function to findMax to match test requirements --- Sprint-1/implement/max.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index dd8a05b6e..1ee3f8fcd 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,4 @@ -function max(elements) { +function findMax(elements) { // First, we filter the list to keep ONLY numbers const onlyNumbers = elements.filter((item) => typeof item === "number"); @@ -11,4 +11,4 @@ function max(elements) { return Math.max(...onlyNumbers); } -module.exports = max; +module.exports = findMax; From 743611da5df8ee40d18b544719a0e61a2e4946ef Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:17:36 +0200 Subject: [PATCH 06/13] test: implement full suite of tests for findMax function --- Sprint-1/implement/max.test.js | 75 +++++++++++++++------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 82f18fd88..66e85a7ec 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -1,43 +1,36 @@ -/* Find the maximum element of an array of numbers - -In this kata, you will need to implement a function that find the largest numerical element of an array. - -E.g. max([30, 50, 10, 40]), target output: 50 -E.g. max(['hey', 10, 'hi', 60, 10]), target output: 60 (sum ignores any non-numerical elements) - -You should implement this function in max.js, and add tests for it in this file. - -We have set things up already so that this file can see your function from the other file. -*/ - const findMax = require("./max.js"); -// Given an empty array -// 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"); - -// Given an array with one number -// When passed to the max function -// Then it should return that number - -// Given an array with both positive and negative numbers -// When passed to the max function -// Then it should return the largest number overall - -// Given an array with just negative numbers -// When passed to the max function -// Then it should return the closest one to zero - -// Given an array with decimal numbers -// When passed to the max function -// Then it should return the largest decimal number - -// Given an array with non-number values -// When passed to the max function -// Then it should return the max and ignore non-numeric values - -// 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 empty array, returns -Infinity", () => { + // Test case for empty input + expect(findMax([])).toBe(-Infinity); +}); + +test("given an array with one number, it returns that number", () => { + // Test case for single element + expect(findMax([5])).toBe(5); +}); + +test("given an array with both positive and negative numbers, it returns the largest", () => { + // Test case for mixed positive and negative numbers + expect(findMax([-1, 10, -5])).toBe(10); +}); + +test("given an array with just negative numbers, it returns the closest one to zero", () => { + // Test case for negative numbers + expect(findMax([-10, -1, -5])).toBe(-1); +}); + +test("given an array with decimal numbers, it returns the largest decimal number", () => { + // Test case for decimal numbers + expect(findMax([1.1, 1.5, 1.2])).toBe(1.5); +}); + +test("given an array with non-number values, it returns the max and ignores others", () => { + // Test case to ensure non-numeric values are ignored + expect(findMax([10, "hi", 20, null])).toBe(20); +}); + +test("given an array with only non-number values, it returns -Infinity", () => { + // Test case where no valid numbers exist in the array + expect(findMax(["a", "b", "c"])).toBe(-Infinity); +}); From 0096aca5c09c82bdb9b66999e341eb341c802604 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:21:57 +0200 Subject: [PATCH 07/13] feat: implement sum function with a simple for loop --- Sprint-1/implement/sum.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..4ddab1926 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,18 @@ function sum(elements) { + // Start with a total of 0 + let total = 0; + + // Go through every item in the array one by one + for (let i = 0; i < elements.length; i++) { + // We only care about numbers, so we check the type + if (typeof elements[i] === "number") { + // Add the number to our total + total = total + elements[i]; + } + } + + // Return the final result + return total; } module.exports = sum; From 681b8a5222e79deb96980f9ab40aeb31b0c98a70 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:22:36 +0200 Subject: [PATCH 08/13] test: add all test cases for sum function --- Sprint-1/implement/sum.test.js | 48 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index dd0a090ca..187df5229 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -1,36 +1,26 @@ -/* Sum the numbers in an array - -In this kata, you will need to implement a function that sums the numerical elements of an array - -E.g. sum([10, 20, 30]), target output: 60 -E.g. sum(['hey', 10, 'hi', 60, 10]), target output: 80 (ignore any non-numerical elements) -*/ - const sum = require("./sum.js"); -// Acceptance Criteria: - -// Given an empty array -// When passed to the sum function -// Then it should return 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 just one number, returns that number", () => { + expect(sum([10])).toBe(10); +}); -// 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 containing negative numbers, returns correct total", () => { + expect(sum([10, -5, 5])).toBe(10); +}); -// 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/float numbers, returns correct total", () => { + expect(sum([1.5, 2.5, 1])).toBe(5); +}); -// 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 containing non-number values, ignores them", () => { + 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", () => { + // 0 is the 'least surprising value' since it's the starting point + expect(sum(["apple", "orange"])).toBe(0); +}); From f30840c6cfec7cb9756c2f835ab49782a42a4a21 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:31:45 +0200 Subject: [PATCH 09/13] refactor: replace for loop with for...of in includes function --- Sprint-1/refactor/includes.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..039e3334f 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,8 +1,7 @@ -// Refactor the implementation of includes to use a for...of loop - +// This function checks if the target exists in the list function includes(list, target) { - for (let index = 0; index < list.length; index++) { - const element = list[index]; + // We use for...of for a cleaner syntax (refactoring) + for (const element of list) { if (element === target) { return true; } From 2ac1a873d8c184212f3ad9c933d75a814a4c084e Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Sun, 3 May 2026 21:32:55 +0200 Subject: [PATCH 10/13] test: ensure refactored includes function passes all original test cases --- Sprint-1/refactor/includes.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sprint-1/refactor/includes.test.js b/Sprint-1/refactor/includes.test.js index 812158470..543a7346e 100644 --- a/Sprint-1/refactor/includes.test.js +++ b/Sprint-1/refactor/includes.test.js @@ -1,5 +1,3 @@ -// Refactored version of includes should still pass the tests below: - const includes = require("./includes.js"); test("returns true when target is in array", () => { From dcc9355c7bf270783579e92dbf2280dd93493614 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Tue, 5 May 2026 09:44:32 +0200 Subject: [PATCH 11/13] fix: access houseNumber using dot notation in address.js --- Sprint-2/debug/address.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..19fe3324d 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -11,5 +11,7 @@ const address = { country: "England", postcode: "XYZ 123", }; - -console.log(`My house number is ${address[0]}`); +// The error was using [0] like an array. +// In JavaScript, we use the property name to get the value from an object. +// We use the dot notation here to get houseNumber. +console.log("My house number is " + address.houseNumber); From 1308564353fb99c39eba1256b48c7cf9f2339559 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Tue, 5 May 2026 09:54:43 +0200 Subject: [PATCH 12/13] fix: objects are not iterable, used Object.values for the loop --- Sprint-2/debug/author.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..09e415801 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -10,7 +10,8 @@ const author = { age: 40, alive: true, }; - -for (const value of author) { +// Error: Objects are not iterable, so we cannot use for...of directly on them. +// Fix: We use Object.values() to turn the object values into an array first. +for (const value of Object.values(author)) { console.log(value); } From 8c7c52cfc7140c4108255af07bfb9f286b879692 Mon Sep 17 00:00:00 2001 From: Meysam Razagh Date: Tue, 5 May 2026 10:00:13 +0200 Subject: [PATCH 13/13] fix: address object printing error and list ingredients individually --- Sprint-2/debug/recipe.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..8b5a594e4 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -10,6 +10,13 @@ const recipe = { ingredients: ["olive oil", "tomatoes", "salt", "pepper"], }; -console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +// Error: Logging the whole object 'recipe' results in "[object Object]". +// Fix: We need to access 'recipe.ingredients' and log each item separately. + +console.log(recipe.title + " serves " + recipe.serves); +console.log("ingredients:"); + +// We use a loop to log each ingredient on a new line +for (const item of recipe.ingredients) { + console.log(item); +}