From 6e09b6448d76fef3e0693cfe6867562779773f23 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 23 Oct 2025 12:07:07 +0100 Subject: [PATCH 01/64] Add initial mean.js and mean.test.js files --- prep/mean.js | 9 +++++++++ prep/mean.test.js | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 prep/mean.js create mode 100644 prep/mean.test.js diff --git a/prep/mean.js b/prep/mean.js new file mode 100644 index 000000000..485efedb8 --- /dev/null +++ b/prep/mean.js @@ -0,0 +1,9 @@ +function calculateMean(list) { + let total = 0; + + for (const item of list) { + total += item; + } +} + +calculateMean([1,2,3,4,5]); \ No newline at end of file diff --git a/prep/mean.test.js b/prep/mean.test.js new file mode 100644 index 000000000..cac7bfbfa --- /dev/null +++ b/prep/mean.test.js @@ -0,0 +1,7 @@ +Test("Calculate the average of a list of numbers", () => { + const list = [3, 50, 7]; + const currentOutput = calculateMean(list); + const targetOutput = 20; // 20 is (3 + 50 + 7) / 3 + + expect(currentOutput).toEqual(targetOutput); +}); From 49b82d5e422e6703f028ff69669b697aea6145a7 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 23 Oct 2025 12:30:58 +0100 Subject: [PATCH 02/64] Write a test for the function in the median.js file. --- prep/median.test.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 prep/median.test.js diff --git a/prep/median.test.js b/prep/median.test.js new file mode 100644 index 000000000..5f8ef9c1e --- /dev/null +++ b/prep/median.test.js @@ -0,0 +1,7 @@ +test("Calculate the median of the list of numbers", () => { + list = [10, 20, 30, 40, 50]; + const currentOutput = calaculateMedian(list); + const targetOutput = 30; + + expect(currentOutput).toEqual(targetOutput); +}) \ No newline at end of file From 94d5edf356155dbd76115de580146991b7ca2f38 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 23 Oct 2025 12:57:24 +0100 Subject: [PATCH 03/64] Implement calculateMedian function --- prep/median.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 prep/median.js diff --git a/prep/median.js b/prep/median.js new file mode 100644 index 000000000..5961bed42 --- /dev/null +++ b/prep/median.js @@ -0,0 +1,6 @@ +function calculateMedian(list) { + const middleIndex = Math.floor(list.length / 2); + const median = list.splice(middleIndex, 1)[0]; + + return median; +} \ No newline at end of file From b6b20602775cfae82cf5f22c6343e838530af319 Mon Sep 17 00:00:00 2001 From: iswat Date: Fri, 24 Oct 2025 10:21:30 +0100 Subject: [PATCH 04/64] Add functions, extra code, and explanatory comments to mean-median.js about arrays as reference types --- prep/mean-median.js | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 prep/mean-median.js diff --git a/prep/mean-median.js b/prep/mean-median.js new file mode 100644 index 000000000..c79e65573 --- /dev/null +++ b/prep/mean-median.js @@ -0,0 +1,53 @@ +function calculateMean(list) { + let total = 0; + + for (const item of list) { + total += item; + } + console.log("the total of the array is", total); + console.log("the element has",list.length, "elements"); + return (total/list.length); + +} + +function calculateMedian(list) { + const middleIndex = Math.floor(list.length / 2); + const median = list.splice(middleIndex, 1)[0]; // Because the splice method has been used on the variable list, + // the array stored in memory will change, and any variable that points to it will show the updated array. + + return median; +} + +const salaries = [10, 20, 30, 40, 60, 80, 80]; +const median = calculateMedian(salaries); + +console.log(salaries, "<--- salaries input before we call calculateMean"); +const mean = calculateMean(salaries); + +console.log(`The median of the salaries is ${median}`); +console.log(`The mean of the salaries is ${mean}`); +console.log(salaries); + +// Notes to understand Array as a reference type +// 1. Arrays are reference types + +// This means that when you create an array like this: +// const salaries = [10, 20, 30, 40, 60, 80, 80]; +// JavaScript doesn’t store the array itself directly in the variable salaries. + +// Instead, the array is stored somewhere in memory, and salaries holds a reference (or pointer) to that memory location. +// 2. What “reference” means + +// Think of it like this: the array is a house, and salaries is the address of that house. + +// If you write: +// const other = salaries; +// now other has the same address. Both salaries and other point to the same array in memory. + +// 3. Implication: modifying the array + +// Because both variables point to the same array, changing it through one variable affects the other: +// other[0] = 100; +// console.log(salaries[0]); // 100 +// This happens because there is only one array in memory, and both variables reference it. + From 935e47ed28c003f1ecdbe7ca2bb8d3818a3de012 Mon Sep 17 00:00:00 2001 From: iswat Date: Fri, 24 Oct 2025 10:25:37 +0100 Subject: [PATCH 05/64] Add a return statement to the function calculateMean --- prep/mean.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/prep/mean.js b/prep/mean.js index 485efedb8..b6fcc88f0 100644 --- a/prep/mean.js +++ b/prep/mean.js @@ -4,6 +4,9 @@ function calculateMean(list) { for (const item of list) { total += item; } + console.log("the total of the array is", total); + console.log("the element has", list.length, "elements"); + return total / list.length; } calculateMean([1,2,3,4,5]); \ No newline at end of file From dfe0f4434ae9bfd1137326d901a1589f1199664d Mon Sep 17 00:00:00 2001 From: iswat Date: Fri, 24 Oct 2025 16:05:08 +0100 Subject: [PATCH 06/64] Export function to test file using module.exports --- prep/mean.js | 4 +++- prep/median.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/prep/mean.js b/prep/mean.js index b6fcc88f0..de9d6f4d7 100644 --- a/prep/mean.js +++ b/prep/mean.js @@ -9,4 +9,6 @@ function calculateMean(list) { return total / list.length; } -calculateMean([1,2,3,4,5]); \ No newline at end of file +//calculateMean([1,2,3,4,5]); + +module.exports = calculateMean; \ No newline at end of file diff --git a/prep/median.js b/prep/median.js index 5961bed42..c30ccddd4 100644 --- a/prep/median.js +++ b/prep/median.js @@ -3,4 +3,6 @@ function calculateMedian(list) { const median = list.splice(middleIndex, 1)[0]; return median; -} \ No newline at end of file +} + +module.exports = calculateMedian; \ No newline at end of file From 22abc47946189c101917a77af63b9c1e7fc1bd83 Mon Sep 17 00:00:00 2001 From: iswat Date: Fri, 24 Oct 2025 16:07:16 +0100 Subject: [PATCH 07/64] Import calculateMean function from mean.js --- prep/mean.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/prep/mean.test.js b/prep/mean.test.js index cac7bfbfa..4123bf07e 100644 --- a/prep/mean.test.js +++ b/prep/mean.test.js @@ -1,4 +1,6 @@ -Test("Calculate the average of a list of numbers", () => { +const calculateMean = require("./mean"); + +test("Calculate the average of a list of numbers", () => { const list = [3, 50, 7]; const currentOutput = calculateMean(list); const targetOutput = 20; // 20 is (3 + 50 + 7) / 3 From e0bed316dfe739315cf391e660e7ef7ca1f75506 Mon Sep 17 00:00:00 2001 From: iswat Date: Fri, 24 Oct 2025 16:07:36 +0100 Subject: [PATCH 08/64] Import calculateMedian function from median.js --- prep/median.test.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/prep/median.test.js b/prep/median.test.js index 5f8ef9c1e..5e9695e63 100644 --- a/prep/median.test.js +++ b/prep/median.test.js @@ -1,7 +1,13 @@ +const calaculateMedian = require("./median"); + test("Calculate the median of the list of numbers", () => { - list = [10, 20, 30, 40, 50]; + const list = [10, 20, 30, 40, 50]; const currentOutput = calaculateMedian(list); const targetOutput = 30; expect(currentOutput).toEqual(targetOutput); -}) \ No newline at end of file +}) + +// test("should not mutate the list of numbers", () => { +// const list = +// }) \ No newline at end of file From e092070074e48f4c7c1027c1f3c0cd64233fa12a Mon Sep 17 00:00:00 2001 From: iswat Date: Fri, 24 Oct 2025 16:08:38 +0100 Subject: [PATCH 09/64] Add package.json file --- prep/package.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 prep/package.json diff --git a/prep/package.json b/prep/package.json new file mode 100644 index 000000000..8cf1fc5ab --- /dev/null +++ b/prep/package.json @@ -0,0 +1,13 @@ +{ + "devDependencies": { + "jest": "^30.2.0" + }, + "scripts": { + "test": "jest" + } +} + + + + + From 4fe7d13636b6365c327ea6f75ab734203000f15f Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 26 Oct 2025 19:25:59 +0000 Subject: [PATCH 10/64] Comment out function that mutates array with splice --- prep/median.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/prep/median.js b/prep/median.js index c30ccddd4..8f91e67a5 100644 --- a/prep/median.js +++ b/prep/median.js @@ -1,8 +1,18 @@ -function calculateMedian(list) { - const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; +// How to calculate the median of an array by mutating the array - return median; -} +// function calculateMedian(list) { +// const middleIndex = Math.floor(list.length / 2); +// const median = list.splice(middleIndex, 1)[0]; +// console.log("middleIndex", middleIndex); +// console.log(list); +// return median; +// } + +// const actualOutput = calculateMedian([1, 2, 3]); +// console.log("median", actualOutput); +module.exports = calculateMedian; -module.exports = calculateMedian; \ No newline at end of file +// How to calculate the median of an array without muatating the array +function calculateMedian(list) { + const arrayLength = list.length; +} From f72964348947972503419c8e8809d107a5c0c782 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 27 Oct 2025 10:44:46 +0000 Subject: [PATCH 11/64] Add function to calculate median without mutating the array This implementation handles arrays with an odd length. --- prep/median.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/prep/median.js b/prep/median.js index 8f91e67a5..11cd3d86c 100644 --- a/prep/median.js +++ b/prep/median.js @@ -14,5 +14,15 @@ module.exports = calculateMedian; // How to calculate the median of an array without muatating the array function calculateMedian(list) { - const arrayLength = list.length; + let median = "no implementation for this test case yet"; + const arrayLength = list.length; // 3 + if (arrayLength % 2 !== 0) { + const lengthDividedByTwo = Math.floor(arrayLength / 2); + median = lengthDividedByTwo; + + } + return list[median]; } + +const actualOutput = calculateMedian([10, 20, 30, 40, 50]); +console.log("median", actualOutput); \ No newline at end of file From 3449f32621c5f610dad32f16f2d07e3c271cbf68 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 27 Oct 2025 11:03:06 +0000 Subject: [PATCH 12/64] Add Jest test case to verify that the function implementation does not mutate the array --- prep/median.test.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/prep/median.test.js b/prep/median.test.js index 5e9695e63..b260117c7 100644 --- a/prep/median.test.js +++ b/prep/median.test.js @@ -1,13 +1,17 @@ -const calaculateMedian = require("./median"); +const calculateMedian = require("./median"); test("Calculate the median of the list of numbers", () => { - const list = [10, 20, 30, 40, 50]; - const currentOutput = calaculateMedian(list); - const targetOutput = 30; + const list = [10, 20, 30, 40, 50]; + const currentOutput = calculateMedian(list); + const targetOutput = 30; - expect(currentOutput).toEqual(targetOutput); -}) + expect(currentOutput).toEqual(targetOutput); +}); + +test("should not modify the input", () => { + const list = [1, 2, 3]; + calculateMedian(list); + + expect(list).toEqual([1, 2, 3]); +}); -// test("should not mutate the list of numbers", () => { -// const list = -// }) \ No newline at end of file From 696f20b6a908334bfe40cfc4fffe93f0f265f4e6 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 30 Oct 2025 22:10:42 +0000 Subject: [PATCH 13/64] Add a Jest test case to check that calculateMedian returns the correct median for an even-length array --- prep/median.test.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/prep/median.test.js b/prep/median.test.js index b260117c7..9f407df2b 100644 --- a/prep/median.test.js +++ b/prep/median.test.js @@ -10,8 +10,17 @@ test("Calculate the median of the list of numbers", () => { test("should not modify the input", () => { const list = [1, 2, 3]; - calculateMedian(list); + const currentOutput = calculateMedian(list); - expect(list).toEqual([1, 2, 3]); + expect(currentOutput).toEqual(2); }); +test( + "should return the average of the two middle numbers as the median for an array with even length", + () => { + const list = [2, 6, 4, 3]; + const currentOutput = calculateMedian(list); + expect(currentOutput).toEqual(5); + } +); + From 2bf9d3cd33f7d09734b8e89485bea75695872448 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 30 Oct 2025 22:42:33 +0000 Subject: [PATCH 14/64] Update function implementation to handle even-length arrays when calculating the median --- prep/median.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/prep/median.js b/prep/median.js index 11cd3d86c..d89688342 100644 --- a/prep/median.js +++ b/prep/median.js @@ -14,15 +14,24 @@ module.exports = calculateMedian; // How to calculate the median of an array without muatating the array function calculateMedian(list) { - let median = "no implementation for this test case yet"; + let medianIndex; + let actualMedian; const arrayLength = list.length; // 3 if (arrayLength % 2 !== 0) { - const lengthDividedByTwo = Math.floor(arrayLength / 2); - median = lengthDividedByTwo; - + medianIndex = (arrayLength + 1) / 2; + console.log(medianIndex - 1); + actualMedian = list[medianIndex - 1]; + } + else { + medianIndex = (arrayLength) / 2; + console.log(medianIndex); + firstMedianIndex = list[medianIndex - 1]; + secondMedianIndex = list[medianIndex]; + actualMedian = (firstMedianIndex + secondMedianIndex) / 2 + } - return list[median]; + return actualMedian; } -const actualOutput = calculateMedian([10, 20, 30, 40, 50]); -console.log("median", actualOutput); \ No newline at end of file +const actualOutput = calculateMedian([10, 20, 30, 50]); +console.log("median", actualOutput); From f658cab3ba40187b26133d675865f4bcfe8d8f34 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 30 Oct 2025 22:47:57 +0000 Subject: [PATCH 15/64] Remove function call and console.log debugging statements --- prep/median.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/prep/median.js b/prep/median.js index d89688342..d008917bb 100644 --- a/prep/median.js +++ b/prep/median.js @@ -19,19 +19,13 @@ function calculateMedian(list) { const arrayLength = list.length; // 3 if (arrayLength % 2 !== 0) { medianIndex = (arrayLength + 1) / 2; - console.log(medianIndex - 1); actualMedian = list[medianIndex - 1]; - } - else { - medianIndex = (arrayLength) / 2; - console.log(medianIndex); - firstMedianIndex = list[medianIndex - 1]; - secondMedianIndex = list[medianIndex]; - actualMedian = (firstMedianIndex + secondMedianIndex) / 2 - + } else { + medianIndex = arrayLength / 2; + + firstMedianIndex = list[medianIndex - 1]; + secondMedianIndex = list[medianIndex]; + actualMedian = (firstMedianIndex + secondMedianIndex) / 2; } return actualMedian; } - -const actualOutput = calculateMedian([10, 20, 30, 50]); -console.log("median", actualOutput); From 7ecf9490c8a3c2fee9864e75e0fd8933846b3150 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 30 Oct 2025 22:51:17 +0000 Subject: [PATCH 16/64] Fix inconsistent indentation in jest test --- prep/median.test.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/prep/median.test.js b/prep/median.test.js index 9f407df2b..b0ed64d2d 100644 --- a/prep/median.test.js +++ b/prep/median.test.js @@ -15,12 +15,10 @@ test("should not modify the input", () => { expect(currentOutput).toEqual(2); }); -test( - "should return the average of the two middle numbers as the median for an array with even length", - () => { +test("should return the average of the two middle numbers as the median for an array with even length", () => { const list = [2, 6, 4, 3]; const currentOutput = calculateMedian(list); - expect(currentOutput).toEqual(5); + expect(currentOutput).toEqual(5) } ); From c217567c79a7aa918879a4d997ffea0e24592f8c Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 16:41:58 +0000 Subject: [PATCH 17/64] Add input validation to return null when a non-array is passed --- Sprint-1/fix/median.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b22590bc6..ff8a86d67 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,9 +6,16 @@ // 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; + // Check that the input passed to the function calculateMeddian is an array + if (!Array.isArray(list)) { + return null; + } + + if (list.length % 2 !== 0) { + const middleIndex = Math.floor(list.length / 2); + const median = list.splice(middleIndex, 1)[0]; + return median; + } } module.exports = calculateMedian; From d75a3ce2d0cea771d49c78b4be3e86ce5ef35707 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 16:47:05 +0000 Subject: [PATCH 18/64] Reformat median test suite for readability - Adjusted indentation and arrow function formatting - Added consistent line breaks and spacing - No changes to test logic or order --- Sprint-1/fix/median.test.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Sprint-1/fix/median.test.js b/Sprint-1/fix/median.test.js index 21da654d7..c262c3776 100644 --- a/Sprint-1/fix/median.test.js +++ b/Sprint-1/fix/median.test.js @@ -13,7 +13,8 @@ describe("calculateMedian", () => { { input: [1, 2, 3, 4], expected: 2.5 }, { input: [1, 2, 3, 4, 5, 6], expected: 3.5 }, ].forEach(({ input, expected }) => - it(`returns the median for [${input}]`, () => expect(calculateMedian(input)).toEqual(expected)) + it(`returns the median for [${input}]`, () => + expect(calculateMedian(input)).toEqual(expected)) ); [ @@ -24,7 +25,8 @@ describe("calculateMedian", () => { { input: [110, 20, 0], expected: 20 }, { input: [6, -2, 2, 12, 14], expected: 6 }, ].forEach(({ input, expected }) => - it(`returns the correct median for unsorted array [${input}]`, () => expect(calculateMedian(input)).toEqual(expected)) + it(`returns the correct median for unsorted array [${input}]`, () => + expect(calculateMedian(input)).toEqual(expected)) ); it("doesn't modify the input array [3, 1, 2]", () => { @@ -33,8 +35,17 @@ describe("calculateMedian", () => { expect(list).toEqual([3, 1, 2]); }); - [ 'not an array', 123, null, undefined, {}, [], ["apple", null, undefined] ].forEach(val => - it(`returns null for non-numeric array (${val})`, () => expect(calculateMedian(val)).toBe(null)) + [ + "not an array", + 123, + null, + undefined, + {}, + [], + ["apple", null, undefined], + ].forEach((val) => + it(`returns null for non-numeric array (${val})`, () => + expect(calculateMedian(val)).toBe(null)) ); [ @@ -45,6 +56,7 @@ describe("calculateMedian", () => { { input: [3, "apple", 1, null, 2, undefined, 4], expected: 2.5 }, { input: ["banana", 5, 3, "apple", 1, 4, 2], expected: 3 }, ].forEach(({ input, expected }) => - it(`filters out non-numeric values and calculates the median for [${input}]`, () => expect(calculateMedian(input)).toEqual(expected)) + it(`filters out non-numeric values and calculates the median for [${input}]`, () => + expect(calculateMedian(input)).toEqual(expected)) ); }); From 4040d9b15fb7cfe2b0f27c52b64358d41a3a34d5 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 21:46:37 +0000 Subject: [PATCH 19/64] Add validation to ensure input is an array --- Sprint-1/fix/median.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index ff8a86d67..c3bcc3167 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,16 +6,12 @@ // or 'list' has mixed values (the function is expected to sort only numbers). function calculateMedian(list) { - // Check that the input passed to the function calculateMeddian is an array + // this statement checks that the input passed to the function calculateMeddian is an array if (!Array.isArray(list)) { return null; } - if (list.length % 2 !== 0) { - const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; - return median; - } + } module.exports = calculateMedian; From 57c20f41e06e1a0c9891efc40cc0cac4dd34ba09 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 21:48:50 +0000 Subject: [PATCH 20/64] Filter out non-numeric values from the array and assign its reference to the `validNumbers` --- Sprint-1/fix/median.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index c3bcc3167..0f0f6b9f5 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -11,7 +11,10 @@ function calculateMedian(list) { return null; } - + // this statement filters valid numbers and make variable validNumbers to hold a reference to the new array + const validNumbers = list.filter( + (item) => typeof item === "number" && !isNaN(item) + ); } module.exports = calculateMedian; From 8a413462c1b3f55b5dcf1ec77d2cf3823801742f Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 21:53:48 +0000 Subject: [PATCH 21/64] Add statements to duplicate the input array and sort it in ascending order --- Sprint-1/fix/median.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index 0f0f6b9f5..7e1c01330 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -15,6 +15,19 @@ function calculateMedian(list) { const validNumbers = list.filter( (item) => typeof item === "number" && !isNaN(item) ); + + // This statement returns `null` if the length of the array is strictly equals to zero + // i.e empty array or invalid array + if (validNumbers.length === 0) { + return null; + } + + // this statement creates a copy of the array and variable copyArray will hold a reference to the new array + const copyArray = validNumbers.slice(); + + // this statement uses sort function to arrange the elements in the array in ascending order. + // sort function mutates the `copyArray` so, sortArray and copyArray hold reference to the same array in memory + const sortArray = copyArray.sort((a, b) => a - b); } module.exports = calculateMedian; From 17d40f7e0de3e553df05edf06b4f99462d3f0ecc Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 21:58:20 +0000 Subject: [PATCH 22/64] Add logic to calculate the median for arrays with odd or even lengths --- Sprint-1/fix/median.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index 7e1c01330..59fd0fc33 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -28,6 +28,20 @@ function calculateMedian(list) { // this statement uses sort function to arrange the elements in the array in ascending order. // sort function mutates the `copyArray` so, sortArray and copyArray hold reference to the same array in memory const sortArray = copyArray.sort((a, b) => a - b); + + // this statement divides the length of `sortArray` by 2, rounds it down to the + // nearest whole number, and assigns it to `middleIndex` + const middleIndex = Math.floor(sortArray.length / 2); + + // this statement checks if `sortArray` has an odd number of elements, and if so, returns the middle element + if (sortArray.length % 2 !== 0) { + return sortArray[middleIndex]; + } else { + // this statement checks if `sortArray` has an even number of length + const firstMiddleIndex = sortArray[middleIndex - 1]; + const secondMiddleIndex = sortArray[middleIndex]; + return (firstMiddleIndex + secondMiddleIndex) / 2; + } } module.exports = calculateMedian; From a22309d089c6688d311325436112393a12e8cbe3 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 22:18:58 +0000 Subject: [PATCH 23/64] Add test case to ensure `dedupe` returns an empty array for empty input --- Sprint-1/implement/dedupe.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 23e0f8638..8754fdaa0 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -25,3 +25,12 @@ test.todo("given an empty array, it returns an empty 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 + +describe("dedupe", () => { + test("returns an empty array when given an empty array", () => { + const inputArray = []; + const actualOutput = dedupe(inputArray); + const expectedOutput = []; + expect(actualOutput).toStrictEqual(expectedOutput); + }); +}); From 8d1429815d08fff3c0ed529481de0a9ca5b54183 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 22:21:44 +0000 Subject: [PATCH 24/64] Make function accessible in other files by adding module.exports --- Sprint-1/implement/dedupe.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..bfd8f1d0f 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,8 @@ -function dedupe() {} +function dedupe(arrayInput) { + if (arrayInput.length === 0) { + return []; + } +} + + +module.exports = dedupe; \ No newline at end of file From 50670f0d915f2726e246e0fcd024aceac9fbdc9a Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 3 Nov 2025 22:52:02 +0000 Subject: [PATCH 25/64] Add test case for `dedupe` to ensure it returns a copy of the array when input has no duplicates --- Sprint-1/implement/dedupe.test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 8754fdaa0..53cd83c2b 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -31,6 +31,13 @@ describe("dedupe", () => { const inputArray = []; const actualOutput = dedupe(inputArray); const expectedOutput = []; - expect(actualOutput).toStrictEqual(expectedOutput); + expect(actualOutput).toEqual(expectedOutput); }); + + test("returns a copy of the original array when there is no duplicates", () => { + const inputArray = [1, 2, 3]; + const actualOutput = dedupe(inputArray); + const expectedOutput = [1, 2, 3]; + expect(actualOutput).toEqual(expectedOutput); + }) }); From 63e538fcb095a334f7de27f4166870d37b355350 Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 11:37:13 +0000 Subject: [PATCH 26/64] Refactor test cases to data-driven format using an array and loop --- Sprint-1/implement/dedupe.test.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 53cd83c2b..d1ab64bd1 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -27,17 +27,19 @@ test.todo("given an empty array, it returns an empty array"); // Then it should remove the duplicate values, preserving the first occurence of each element describe("dedupe", () => { - test("returns an empty array when given an empty array", () => { - const inputArray = []; - const actualOutput = dedupe(inputArray); - const expectedOutput = []; - expect(actualOutput).toEqual(expectedOutput); - }); - - test("returns a copy of the original array when there is no duplicates", () => { - const inputArray = [1, 2, 3]; - const actualOutput = dedupe(inputArray); - const expectedOutput = [1, 2, 3]; - expect(actualOutput).toEqual(expectedOutput); - }) + [{ input: [], expected: [] }].forEach(({ input, expected }) => + test(`returns an empty array for input [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); + + [{ input: [1, 2, 3], expected: [1, 2, 3] }].forEach(({ input, expected }) => + test(`returns a copy of the array when no duplicates exist for input [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); + + [{ input: [5, 1, 1, 2, 3, 2, 5, 8], expected: [5, 1, 2, 3, 8] }].forEach( + ({ input, expected }) => + test(`removes duplicate elements and keep the first occurrence for [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); }); From 950a4a3817c16239700da8de14b11bafe8dde3d0 Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 12:07:17 +0000 Subject: [PATCH 27/64] Add test case to ensure dedupe removes duplicates and keeps the first occurrence for arrays of strings and numbers --- Sprint-1/implement/dedupe.test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index d1ab64bd1..e1c68b78a 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -42,4 +42,10 @@ describe("dedupe", () => { test(`removes duplicate elements and keep the first occurrence for [${input}]`, () => expect(dedupe(input)).toEqual(expected)) ); + + [{ input: ["1", 1, "1", 1], expected: ["1", 1] }].forEach( + ({ input, expected }) => + test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); }); From 37d11330007058809de72619f7af25d559299a2c Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 12:08:36 +0000 Subject: [PATCH 28/64] Comment out unused test.todo --- Sprint-1/implement/dedupe.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index e1c68b78a..82028f0a6 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -16,7 +16,7 @@ E.g. dedupe([1, 2, 1]) target output: [1, 2] // 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"); +// test.todo("given an empty array, it returns an empty array"); // Given an array with no duplicates // When passed to the dedupe function From 1f1729105dc77b72bbc9bcf9c4c52b24aef5ebac Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 12:26:10 +0000 Subject: [PATCH 29/64] Add additional test cases for no duplicates, duplicate and mixed string-number array handling --- Sprint-1/implement/dedupe.test.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 82028f0a6..8ca52de2d 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -32,20 +32,30 @@ describe("dedupe", () => { expect(dedupe(input)).toEqual(expected)) ); - [{ input: [1, 2, 3], expected: [1, 2, 3] }].forEach(({ input, expected }) => + [ + { input: [1, 2, 3], expected: [1, 2, 3] }, + { input: ["a", "b", "car"], expected: ["a", "b", "car"] }, + { input: [0, 1, 5, 6], expected: [0, 1, 5, 6]}, + ].forEach(({ input, expected }) => test(`returns a copy of the array when no duplicates exist for input [${input}]`, () => expect(dedupe(input)).toEqual(expected)) ); - [{ input: [5, 1, 1, 2, 3, 2, 5, 8], expected: [5, 1, 2, 3, 8] }].forEach( - ({ input, expected }) => - test(`removes duplicate elements and keep the first occurrence for [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + [ + { input: [5, 1, 1, 2, 3, 2, 5, 8], expected: [5, 1, 2, 3, 8] }, + { input: [1, 1, 1, 1], expected: [1] }, + { input: ["a", "a", "a", "b", "b", "c"], expected: ["a", "b", "c"]}, + + ].forEach(({ input, expected }) => + test(`removes duplicate elements and keep the first occurrence for [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) ); - [{ input: ["1", 1, "1", 1], expected: ["1", 1] }].forEach( - ({ input, expected }) => - test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + [ + { input: ["1", 1, "1", 1], expected: ["1", 1] }, + { input: [2, "3", "hello", 5], expected: [2, "3", "hello", 5]}, + ].forEach(({ input, expected }) => + test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) ); }); From a73b980260327673e17eed813df9a96d0cd9c993 Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 13:03:59 +0000 Subject: [PATCH 30/64] Add case to verify dedupe removes invalid elements and duplicates, returning a new array --- Sprint-1/implement/dedupe.test.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 8ca52de2d..4065f9910 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -35,7 +35,7 @@ describe("dedupe", () => { [ { input: [1, 2, 3], expected: [1, 2, 3] }, { input: ["a", "b", "car"], expected: ["a", "b", "car"] }, - { input: [0, 1, 5, 6], expected: [0, 1, 5, 6]}, + { input: [0, 1, 5, 6], expected: [0, 1, 5, 6] }, ].forEach(({ input, expected }) => test(`returns a copy of the array when no duplicates exist for input [${input}]`, () => expect(dedupe(input)).toEqual(expected)) @@ -44,8 +44,7 @@ describe("dedupe", () => { [ { input: [5, 1, 1, 2, 3, 2, 5, 8], expected: [5, 1, 2, 3, 8] }, { input: [1, 1, 1, 1], expected: [1] }, - { input: ["a", "a", "a", "b", "b", "c"], expected: ["a", "b", "c"]}, - + { input: ["a", "a", "a", "b", "b", "c"], expected: ["a", "b", "c"] }, ].forEach(({ input, expected }) => test(`removes duplicate elements and keep the first occurrence for [${input}]`, () => expect(dedupe(input)).toEqual(expected)) @@ -53,9 +52,18 @@ describe("dedupe", () => { [ { input: ["1", 1, "1", 1], expected: ["1", 1] }, - { input: [2, "3", "hello", 5], expected: [2, "3", "hello", 5]}, + { input: [2, "3", "hello", 5], expected: [2, "3", "hello", 5] }, ].forEach(({ input, expected }) => test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + expect(dedupe(input)).toEqual(expected)); + ); + + [ + { input: [1, 2, true, 3, null, "a", {}], expected: [1, 2, 3, "a"] }, + { input: ["x", undefined, "x", "y", []], expected: ["x", "y"] }, + { input: [false, 5, 5, "hello", () => {}, 5], expected: [5, "hello"] }, + ].forEach(({ input, expected }) => + test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => + expect(dedupe(input)).toEqual(expected)); ); }); From 4ea5009bf14c38049b2655e64711eaf49fd5ac18 Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 13:10:45 +0000 Subject: [PATCH 31/64] Remove the semi-colon after the expect expression --- Sprint-1/implement/dedupe.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 4065f9910..fc2916ed0 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -55,7 +55,7 @@ describe("dedupe", () => { { input: [2, "3", "hello", 5], expected: [2, "3", "hello", 5] }, ].forEach(({ input, expected }) => test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => - expect(dedupe(input)).toEqual(expected)); + expect(dedupe(input)).toEqual(expected)) ); [ @@ -64,6 +64,6 @@ describe("dedupe", () => { { input: [false, 5, 5, "hello", () => {}, 5], expected: [5, "hello"] }, ].forEach(({ input, expected }) => test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => - expect(dedupe(input)).toEqual(expected)); + expect(dedupe(input)).toEqual(expected)) ); }); From e8bda7b7776f67385f8ac10c0a25bda20bedda93 Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 13:27:08 +0000 Subject: [PATCH 32/64] Add test case in invalid elements category to ensure NaN is ignored --- Sprint-1/implement/dedupe.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index fc2916ed0..70ce45dab 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -62,6 +62,7 @@ describe("dedupe", () => { { input: [1, 2, true, 3, null, "a", {}], expected: [1, 2, 3, "a"] }, { input: ["x", undefined, "x", "y", []], expected: ["x", "y"] }, { input: [false, 5, 5, "hello", () => {}, 5], expected: [5, "hello"] }, + { input: [1, NaN, 2, NaN, "hello"], expected: [1, NaN, 2, NaN, "hello"] }, ].forEach(({ input, expected }) => test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => expect(dedupe(input)).toEqual(expected)) From c5249d99a28c8cf5d303c27b5b66e1d88cda9773 Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 13:39:04 +0000 Subject: [PATCH 33/64] Rename describe block to 'dedupe - valid inputs' --- Sprint-1/implement/dedupe.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 70ce45dab..424ceaa23 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -26,7 +26,7 @@ E.g. dedupe([1, 2, 1]) target output: [1, 2] // When passed to the dedupe function // Then it should remove the duplicate values, preserving the first occurence of each element -describe("dedupe", () => { +describe("dedupe - valid inputs", () => { [{ input: [], expected: [] }].forEach(({ input, expected }) => test(`returns an empty array for input [${input}]`, () => expect(dedupe(input)).toEqual(expected)) @@ -67,4 +67,6 @@ describe("dedupe", () => { test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => expect(dedupe(input)).toEqual(expected)) ); + + }); From e95f6a4955bb5fb5d92cf024d2b8061bdb4f6c0e Mon Sep 17 00:00:00 2001 From: iswat Date: Tue, 4 Nov 2025 16:00:15 +0000 Subject: [PATCH 34/64] Add describe block for invalid inputs and a test case to ensure dedupe returns expected output --- Sprint-1/implement/dedupe.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 424ceaa23..2b678997d 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -67,6 +67,15 @@ describe("dedupe - valid inputs", () => { test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => expect(dedupe(input)).toEqual(expected)) ); +}); +describe("dedupe - invalid inputs", () => { +const invalidInputs = [null, undefined, 123, "string", {}, () => {}]; +invalidInputs.forEach((input) => + test(`throws typeError when input is ${String(input)}`, () => { + expect(dedupe(input)).toThrow(TypeError); + expect(dedupe(input)).toThrow("Input must be an array") + }) +) }); From 4e105a65c367d5c1fd533a254b3163e9047188e8 Mon Sep 17 00:00:00 2001 From: iswat Date: Wed, 5 Nov 2025 12:52:55 +0000 Subject: [PATCH 35/64] Remove the if statement that checks if length of the array is equlas to zero --- Sprint-1/implement/dedupe.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index bfd8f1d0f..db804c573 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1,7 +1,5 @@ function dedupe(arrayInput) { - if (arrayInput.length === 0) { - return []; - } + } From ae9fb0ecc9cee19079f6c6c6004b570d61c2b0c1 Mon Sep 17 00:00:00 2001 From: iswat Date: Wed, 5 Nov 2025 13:49:06 +0000 Subject: [PATCH 36/64] Add input validation for non-array values --- Sprint-1/implement/dedupe.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index db804c573..85b03dddb 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1,6 +1,9 @@ function dedupe(arrayInput) { - + if (!Array.isArray(arrayInput)) { + throw new TypeError("Input must be an array"); + } } +console.log(dedupe("food")); module.exports = dedupe; \ No newline at end of file From 54e1a28b410da1df8581df79963d6fb130c2a364 Mon Sep 17 00:00:00 2001 From: iswat Date: Wed, 5 Nov 2025 13:54:18 +0000 Subject: [PATCH 37/64] Add implementation for when empty array is passed as input --- Sprint-1/implement/dedupe.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 85b03dddb..47e061829 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -2,6 +2,10 @@ function dedupe(arrayInput) { if (!Array.isArray(arrayInput)) { throw new TypeError("Input must be an array"); } + + if (arrayInput.length === 0) { + return []; + } } console.log(dedupe("food")); From 52e97c6ef803bbc5668004cf0626f0bd7fc34e2a Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 09:47:55 +0000 Subject: [PATCH 38/64] Update dedupe test cases for correct expected output - Remove NaN elements from expected outputs - Add missing element 5 in the test input for a duplicate case - Wrap dedupe function calls in a function so Jest can catch thrown errors --- Sprint-1/implement/dedupe.test.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 2b678997d..a67597eb9 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -52,7 +52,7 @@ describe("dedupe - valid inputs", () => { [ { input: ["1", 1, "1", 1], expected: ["1", 1] }, - { input: [2, "3", "hello", 5], expected: [2, "3", "hello", 5] }, + { input: [2, "3", "hello", 5, 5], expected: [2, "3", "hello", 5] }, ].forEach(({ input, expected }) => test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => expect(dedupe(input)).toEqual(expected)) @@ -62,7 +62,7 @@ describe("dedupe - valid inputs", () => { { input: [1, 2, true, 3, null, "a", {}], expected: [1, 2, 3, "a"] }, { input: ["x", undefined, "x", "y", []], expected: ["x", "y"] }, { input: [false, 5, 5, "hello", () => {}, 5], expected: [5, "hello"] }, - { input: [1, NaN, 2, NaN, "hello"], expected: [1, NaN, 2, NaN, "hello"] }, + { input: [1, NaN, 2, NaN, "hello"], expected: [1, 2, "hello"] }, ].forEach(({ input, expected }) => test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => expect(dedupe(input)).toEqual(expected)) @@ -74,8 +74,9 @@ const invalidInputs = [null, undefined, 123, "string", {}, () => {}]; invalidInputs.forEach((input) => test(`throws typeError when input is ${String(input)}`, () => { - expect(dedupe(input)).toThrow(TypeError); - expect(dedupe(input)).toThrow("Input must be an array") + expect(() => dedupe(null)).toThrow(TypeError); + expect(() => dedupe(null)).toThrow("Input must be an array"); + }) ) }); From ba0eff32fb98ba4ea51eebe6f4a12060448c094a Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 09:54:28 +0000 Subject: [PATCH 39/64] Implement dedupe function to remove duplicate numbers and strings, filter out invalid elements, and return a new array preserving first occurrences --- Sprint-1/implement/dedupe.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 47e061829..56772a912 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1,13 +1,28 @@ function dedupe(arrayInput) { - if (!Array.isArray(arrayInput)) { + if (!Array.isArray(arrayInput)) { throw new TypeError("Input must be an array"); - } + } - if (arrayInput.length === 0) { + if (arrayInput.length === 0) { return []; - } + } + + const newArray = []; + const seen = new Set(); + + for (const item of arrayInput) { + if ( + (typeof item === "number" && !Number.isNaN(item) || typeof item === "string") && + !seen.has(item) + ) { + newArray.push(item); + seen.add(item); + } + } + + return newArray; } -console.log(dedupe("food")); +console.log(dedupe([null, undefined])); -module.exports = dedupe; \ No newline at end of file +module.exports = dedupe; From 0da3ea8bd1b8a3ca8f38d683483e13d4f98099dd Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 10:24:52 +0000 Subject: [PATCH 40/64] Refactor condition in dedupe for easier reading and parsing - Reorganized the logical condition to improve readability - Ensured number and string checks remain consistent - Simplified the order of operations to make the logic clearer and easier to maintain --- Sprint-1/implement/dedupe.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 56772a912..e212fe0e8 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -12,8 +12,9 @@ function dedupe(arrayInput) { for (const item of arrayInput) { if ( - (typeof item === "number" && !Number.isNaN(item) || typeof item === "string") && - !seen.has(item) + !seen.has(item) && + ((typeof item === "number" && !Number.isNaN(item)) || + typeof item === "string") ) { newArray.push(item); seen.add(item); From a7e57bfb8174efd936a78b4e61634eabe475140d Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 10:28:00 +0000 Subject: [PATCH 41/64] Remove console.log statement used for debugging --- Sprint-1/implement/dedupe.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index e212fe0e8..5403e0b57 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -24,6 +24,4 @@ function dedupe(arrayInput) { return newArray; } -console.log(dedupe([null, undefined])); - module.exports = dedupe; From 06f06ed7ed5c03e03220d2e8a2c1777fc0fe4600 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 12:05:22 +0000 Subject: [PATCH 42/64] Add comments to clarify dedupe implementation --- Sprint-1/implement/dedupe.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 5403e0b57..b7372b6e7 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1,27 +1,43 @@ +// This defines a function named dedupe with a parameter arrayInput. arrayInput should be an array. function dedupe(arrayInput) { + // This checks whether the input is not an array. if (!Array.isArray(arrayInput)) { + // If the input is not an array, the function stops, throws a TypeError and shows an error message saying:“Input must be an array.” throw new TypeError("Input must be an array"); } - + // This checks if the array is empty (has no elements). if (arrayInput.length === 0) { + // If the array is empty, it returns an empty array. return []; } + // This declares a new variable `newArray` which will hold a reference to an empty array in memory const newArray = []; - const seen = new Set(); + // This decares a new varibale `seen` which will hold a reference to the actual set object in memory + const seen = new Set(); // variable seen keeps track of all items that have already been added to the result array + // seen is a Set object that remembers items, + + // newArray is an array that holds the actual result. + // This starts a loop that goes through each element in the input array one by one. for (const item of arrayInput) { + // This big condition checks two things before adding an item: + + // !seen.has(item) — The item has not been added before. + + // The item is either a number (but not NaN) or a string. + // So only real numbers and strings that haven’t appeared yet will be kept. if ( !seen.has(item) && ((typeof item === "number" && !Number.isNaN(item)) || typeof item === "string") ) { - newArray.push(item); - seen.add(item); + newArray.push(item); // If the item passes the condition, it gets added to the new array. + seen.add(item); // The item is then recorded in the Set, so it won’t be added again later. } } - - return newArray; + // After the loop finishes, return the final deduplicated array + return newArray; // After checking all items, the function returns the new array with duplicates removed and invalid items filtered out. } -module.exports = dedupe; +module.exports = dedupe; // This line allows the dedupe function to be used in other files (like the test file). From b38a131b126a2899f344c0073afbd23bff95f725 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 12:44:02 +0000 Subject: [PATCH 43/64] Replace test.todo with actual test cases for findMax - Implement tests for empty array, single number, positive/negative numbers, negative numbers only, decimal numbers, mixed non-numeric values, and only non-number values. - Covers all scenarios described in the comments. --- Sprint-1/implement/max.test.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 82f18fd88..d92793182 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -16,28 +16,48 @@ 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("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([8])).toBe(8); +}); // 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 both positive and negative numbers, returns the largest number overall", () => { + expect(findMax([10, -5, 20, 0])).toBe(20); +}); // 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 just negative numbers, returns the closest one to zero", () => { + expect(findMax([-10, -5, -20])).toBe(-5); +}); // 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 number", () => { + expect(findMax([1.1, 2.5, 0.3])).toBe(2.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, returns the max and ignore the non-numeric values", () => { + expect(findMax([10, "hi", 20, null])).toBe(20); +}); // 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", () => { + expect(findMax(["a", null, undefined])).toBe(-Infinity); +}); From 110ef310e8efc8912f9cef071e2d38bd37c00dd8 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 13:47:04 +0000 Subject: [PATCH 44/64] Add tests for non-array inputs in findMax --- Sprint-1/implement/max.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index d92793182..fbc28d4e4 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -61,3 +61,18 @@ test("given an array with non-number values, returns the max and ignore the non- test("given an array with only non-number values", () => { expect(findMax(["a", null, undefined])).toBe(-Infinity); }); + +// Edge cases +// Given an array with non-array values +// when passed to the max function +// Then it should throw and error +test("given a non-array input, throws a TypeError with message 'Input must be an array'", () => { + expect(() => findMax(42)).toThrow(new TypeError("Input must be an array")); + expect(() => findMax("hello")).toThrow( + new TypeError("Input must be an array") + ); + expect(() => findMax(null)).toThrow(new TypeError("Input must be an array")); + expect(() => findMax(undefined)).toThrow( + new TypeError("Input must be an array") + ); +}); From 6e91a426e6cea3250bf45f806636699c6aafb242 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 6 Nov 2025 22:44:17 +0000 Subject: [PATCH 45/64] Change deduplicate back to dedupe --- Sprint-1/implement/dedupe.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index a67597eb9..fd5207171 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -2,9 +2,9 @@ const dedupe = require("./dedupe.js"); /* Dedupe Array -📖 Dedupe means **deduplicate** +📖 Dedupe means **dedupe** -In this kata, you will need to deduplicate the elements of an array +In this kata, you will need to dedupe the elements of an array 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] From bd49eed1f96029dcf01ed5f2706fc7f651ed7db6 Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 10:41:49 +0000 Subject: [PATCH 46/64] Add findMax implementation for numeric arrays and handle empty array case --- Sprint-1/implement/max.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..52b8ed05d 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,10 @@ function findMax(elements) { + if (Array.isArray(elements)) { + return Math.max(...elements); + } + + } + module.exports = findMax; From 7957277fd53b979c5e25b52e0ff4b3c6b9b0a39b Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 11:18:15 +0000 Subject: [PATCH 47/64] Add logic to findMax to handle non-array inputs by throwing a TypeError --- Sprint-1/implement/max.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 52b8ed05d..25352806a 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,9 +1,10 @@ function findMax(elements) { - if (Array.isArray(elements)) { - return Math.max(...elements); - } - - + console.log("findMax called with:", elements); + if (Array.isArray(elements)) { + return Math.max(...elements); + } else { + throw new TypeError("Input must be an array"); + } } From b3a96a6939fe568fed7fbd39b701982daa32e246 Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 12:42:39 +0000 Subject: [PATCH 48/64] Add full findMax implementation: - Returns max number from array, ignoring non-numbers - Returns -Infinity for empty or non-number-only arrays - Throws TypeError for non-array inputs --- Sprint-1/implement/max.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 25352806a..0e06ebe78 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,11 +1,12 @@ function findMax(elements) { - console.log("findMax called with:", elements); - if (Array.isArray(elements)) { - return Math.max(...elements); - } else { - throw new TypeError("Input must be an array"); - } + if (!Array.isArray(elements)) { + throw new TypeError("Input must be an array"); + } else { + const filteredArray = elements.filter( + (ele) => typeof ele === "number" && !isNaN(ele) + ) + return Math.max(...filteredArray); + } } - module.exports = findMax; From 68b555750f3589bfaa6bffc0dae484d671993758 Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 13:09:47 +0000 Subject: [PATCH 49/64] Add multiple test cases for each findMax scenario --- Sprint-1/implement/max.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index fbc28d4e4..0782a7d62 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -25,6 +25,8 @@ test("given an empty array, returns -Infinity", () => { // Then it should return that number test("given an array with one number, returns that number", () => { expect(findMax([8])).toBe(8); + expect(findMax([-42])).toBe(-42); + expect(findMax([0])).toBe(0); }); // Given an array with both positive and negative numbers @@ -32,6 +34,8 @@ test("given an array with one number, returns that number", () => { // Then it should return the largest number overall test("given an array with both positive and negative numbers, returns the largest number overall", () => { expect(findMax([10, -5, 20, 0])).toBe(20); + expect(findMax([-1, -100, -50, 30])); + expect(findMax([0, -10, 5])).toBe(5); }); // Given an array with just negative numbers @@ -39,6 +43,8 @@ test("given an array with both positive and negative numbers, returns the larges // Then it should return the closest one to zero test("given an array with just negative numbers, returns the closest one to zero", () => { expect(findMax([-10, -5, -20])).toBe(-5); + expect(findMax([-100, -50, -60])).toBe(-50); + expect(findMax([-1000, -60, -1])).toBe(-1); }); // Given an array with decimal numbers @@ -46,6 +52,8 @@ test("given an array with just negative numbers, returns the closest one to zero // Then it should return the largest decimal number test("given an array with decimal numbers, returns the largest decimal number", () => { expect(findMax([1.1, 2.5, 0.3])).toBe(2.5); + expect(findMax([-1.2, -0.5, -0.1])).toBe(-0.1); + expect(findMax([-1000.23, -80.54, -63.110])).toBe(-63.110); }); // Given an array with non-number values @@ -53,6 +61,8 @@ test("given an array with decimal numbers, returns the largest decimal number", // Then it should return the max and ignore non-numeric values test("given an array with non-number values, returns the max and ignore the non-numeric values", () => { expect(findMax([10, "hi", 20, null])).toBe(20); + expect(findMax([0, false, 5, "a"])).toBe(5); + expect(findMax([undefined, 5, null, NaN, -9])).toBe(5); }); // Given an array with only non-number values @@ -60,6 +70,9 @@ test("given an array with non-number values, returns the max and ignore the non- // 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", () => { expect(findMax(["a", null, undefined])).toBe(-Infinity); + expect(findMax([{}, [], "hi"])); + expect(findMax([true, false, true])).toBe(-Infinity); + expect(findMax([Symbol("x"), () => {}, function () {}])).toBe(-Infinity); }); // Edge cases From d5d84f75183f0cdd5bedcf5d216a11a9f2788e56 Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 13:15:26 +0000 Subject: [PATCH 50/64] Add comments to each acceptance criteria scenario --- Sprint-1/implement/dedupe.test.js | 40 ++++++++++++++----------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index fd5207171..e6a4b7703 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -13,25 +13,19 @@ 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 - describe("dedupe - valid inputs", () => { + // 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"); [{ input: [], expected: [] }].forEach(({ input, expected }) => test(`returns an empty array for input [${input}]`, () => expect(dedupe(input)).toEqual(expected)) ); + // Given an array with no duplicates + // When passed to the dedupe function + // Then it should return a copy of the original array [ { input: [1, 2, 3], expected: [1, 2, 3] }, { input: ["a", "b", "car"], expected: ["a", "b", "car"] }, @@ -50,6 +44,9 @@ describe("dedupe - valid inputs", () => { expect(dedupe(input)).toEqual(expected)) ); + // 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 [ { input: ["1", 1, "1", 1], expected: ["1", 1] }, { input: [2, "3", "hello", 5, 5], expected: [2, "3", "hello", 5] }, @@ -62,7 +59,7 @@ describe("dedupe - valid inputs", () => { { input: [1, 2, true, 3, null, "a", {}], expected: [1, 2, 3, "a"] }, { input: ["x", undefined, "x", "y", []], expected: ["x", "y"] }, { input: [false, 5, 5, "hello", () => {}, 5], expected: [5, "hello"] }, - { input: [1, NaN, 2, NaN, "hello"], expected: [1, 2, "hello"] }, + { input: [1, NaN, 2, NaN, "hello"], expected: [1, 2, "hello"] }, ].forEach(({ input, expected }) => test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => expect(dedupe(input)).toEqual(expected)) @@ -70,13 +67,12 @@ describe("dedupe - valid inputs", () => { }); describe("dedupe - invalid inputs", () => { -const invalidInputs = [null, undefined, 123, "string", {}, () => {}]; + const invalidInputs = [null, undefined, 123, "string", {}, () => {}]; -invalidInputs.forEach((input) => - test(`throws typeError when input is ${String(input)}`, () => { - expect(() => dedupe(null)).toThrow(TypeError); - expect(() => dedupe(null)).toThrow("Input must be an array"); - - }) -) + invalidInputs.forEach((input) => + test(`throws typeError when input is ${String(input)}`, () => { + expect(() => dedupe(null)).toThrow(TypeError); + expect(() => dedupe(null)).toThrow("Input must be an array"); + }) + ); }); From 4882181bd19255a2aa139cf79a49c8b48c9c82a5 Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 15:59:44 +0000 Subject: [PATCH 51/64] Remove .todo and add test cases for each scenario of the sum function --- Sprint-1/implement/sum.test.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index dd0a090ca..9a416819a 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -13,24 +13,41 @@ 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("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 one number in an array, returns that number", () => { + expect(sum([5])).toBe(5); +}) // 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, should return the correct total sum", () => { + expect(sum([-5, -9, -100])).toBe(-114); +}) // 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, should return the correct total number", () => { + expect(sum([-8.24, 5.46, 3.22])).toBe(0.44); +}) // 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, should ignore the non-numerical values and return the sum of the numerical elements", () => { + expect(sum([5, -8, 5.6, null, "kettle"])).toBe(2.6); +}) // 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, should return 0", () => { + expect(sum(["food", null, false, true])).toBe(0); +}) From 1cad41b8f355b8a98956343f5aba95ab0a647d08 Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 16:39:10 +0000 Subject: [PATCH 52/64] Implement sum function to pass all acceptance criteria test cases --- Sprint-1/implement/sum.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..2c4d90bb1 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,16 @@ function sum(elements) { + if (!Array.isArray(elements)) { + throw new TypeError("Input must be an array"); + } + const filteredElements = elements.filter( + (ele) => typeof ele === "number" && !isNaN(ele) + ); + let sumElements = 0; + + for (const item of filteredElements) { + sumElements += item; + } + return Number(sumElements.toFixed(2)); } module.exports = sum; From ba3563181c920bd8f5ed8ee53aa412f233ebc1ca Mon Sep 17 00:00:00 2001 From: iswat Date: Sun, 9 Nov 2025 16:45:42 +0000 Subject: [PATCH 53/64] Update input and expected value for test when array contains non-number values --- Sprint-1/implement/sum.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index 9a416819a..ef8e5532d 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -42,7 +42,7 @@ test("given an array with decimal/float numbers, should return the correct total // 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, should ignore the non-numerical values and return the sum of the numerical elements", () => { - expect(sum([5, -8, 5.6, null, "kettle"])).toBe(2.6); + expect(sum([5, -18, 5.601, null, "kettle"])).toBe(-7.4); }) // Given an array with only non-number values From 9f244db18038b30290a0c8575da88863431ebd17 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 10 Nov 2025 11:22:55 +0000 Subject: [PATCH 54/64] Add additional test cases for each acceptance criteria scenario --- Sprint-1/implement/sum.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index ef8e5532d..25e13a2ec 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -15,6 +15,9 @@ const sum = require("./sum.js"); // Then it should return 0 test("given an empty array, returns 0", () => { expect(sum([])).toBe(0); + + const arr = []; + expect(sum(arr)).toBe(0); }) // Given an array with just one number @@ -22,6 +25,8 @@ test("given an empty array, returns 0", () => { // Then it should return that number test("given one number in an array, returns that number", () => { expect(sum([5])).toBe(5); + expect(sum([-3])).toBe(-3); + expect(sum([0])).toBe(0); }) // Given an array containing negative numbers @@ -29,6 +34,8 @@ test("given one number in an array, returns that number", () => { // Then it should still return the correct total sum test("given an array containing negative numbers, should return the correct total sum", () => { expect(sum([-5, -9, -100])).toBe(-114); + expect(sum([-1000, -2000, -3000])).toBe(-6000); + expect(sum([-1, -2, -3])).toBe(-6); }) // Given an array with decimal/float numbers @@ -36,6 +43,8 @@ test("given an array containing negative numbers, should return the correct tota // Then it should return the correct total sum test("given an array with decimal/float numbers, should return the correct total number", () => { expect(sum([-8.24, 5.46, 3.22])).toBe(0.44); + expect(sum([-2.5, 2.5, 5.25])).toBe(5.25); + expect(sum([1.11, 2.22, 3.33])).toBe(6.66); }) // Given an array containing non-number values @@ -43,6 +52,8 @@ test("given an array with decimal/float numbers, should return the correct total // Then it should ignore the non-numerical values and return the sum of the numerical elements test("given an array containing non-number values, should ignore the non-numerical values and return the sum of the numerical elements", () => { expect(sum([5, -18, 5.601, null, "kettle"])).toBe(-7.4); + expect(sum([true, false, 10, -5])).toBe(5); + expect(sum([null, 4, 6, "test"])).toBe(10); }) // Given an array with only non-number values @@ -50,4 +61,6 @@ test("given an array containing non-number values, should ignore the non-numeric // 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, should return 0", () => { expect(sum(["food", null, false, true])).toBe(0); + expect(sum(["apple", "banana", null, undefined])).toBe(0); + expect(sum([NaN, NaN, NaN])).toBe(0); }) From 973758bc170e634375ee52e6719e4882dfc1a65e Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 10 Nov 2025 11:48:53 +0000 Subject: [PATCH 55/64] Refactor the implementation of includes to use a for...of loop --- Sprint-1/refactor/includes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..22bba1aae 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,8 +1,8 @@ // 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 item of list) { + const element = item; if (element === target) { return true; } From 0fb3f24e8073c2af659f6745374da29ec0151a40 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 10 Nov 2025 11:52:17 +0000 Subject: [PATCH 56/64] Remove redundant variable element and use item in the if statement --- Sprint-1/refactor/includes.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 22bba1aae..6aeac0b5d 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -2,8 +2,7 @@ function includes(list, target) { for (const item of list) { - const element = item; - if (element === target) { + if (item === target) { return true; } } From e5e09ee4c9cb7ec653402909c422b8b69b1e0c95 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 12:53:01 +0000 Subject: [PATCH 57/64] Refactor calculateMedian to remove unnecessary intermediate array clone - Replaced `const copyArray = validNumbers.slice(); const sortArray = copyArray.sort(...)` with `const sorted = [...validNumbers].sort(...)`. - Created a shallow copy and sorts in one step. - Eliminated redundant `copyArray` variable while keeping original array intact. --- Sprint-1/fix/median.js | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index 59fd0fc33..b2709cb5b 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,41 +6,34 @@ // or 'list' has mixed values (the function is expected to sort only numbers). function calculateMedian(list) { - // this statement checks that the input passed to the function calculateMeddian is an array + // Check that the input passed to the function is an array if (!Array.isArray(list)) { return null; } - // this statement filters valid numbers and make variable validNumbers to hold a reference to the new array + // Filter valid numbers and store them in `validNumbers` const validNumbers = list.filter( (item) => typeof item === "number" && !isNaN(item) ); - // This statement returns `null` if the length of the array is strictly equals to zero - // i.e empty array or invalid array + // Return `null` if there are no valid numbers if (validNumbers.length === 0) { return null; } - // this statement creates a copy of the array and variable copyArray will hold a reference to the new array - const copyArray = validNumbers.slice(); + // Create a shallow copy of `validNumbers` and sort it in ascending order + // This avoids modifying the original array + const sorted = [...validNumbers].sort((a, b) => a - b); - // this statement uses sort function to arrange the elements in the array in ascending order. - // sort function mutates the `copyArray` so, sortArray and copyArray hold reference to the same array in memory - const sortArray = copyArray.sort((a, b) => a - b); + // Calculate the middle index of the sorted array + const middleIndex = Math.floor(sorted.length / 2); - // this statement divides the length of `sortArray` by 2, rounds it down to the - // nearest whole number, and assigns it to `middleIndex` - const middleIndex = Math.floor(sortArray.length / 2); - - // this statement checks if `sortArray` has an odd number of elements, and if so, returns the middle element - if (sortArray.length % 2 !== 0) { - return sortArray[middleIndex]; + // If the array has an odd number of elements, return the middle element + if (sorted.length % 2 !== 0) { + return sorted[middleIndex]; } else { - // this statement checks if `sortArray` has an even number of length - const firstMiddleIndex = sortArray[middleIndex - 1]; - const secondMiddleIndex = sortArray[middleIndex]; - return (firstMiddleIndex + secondMiddleIndex) / 2; + // If the array has an even number of elements, return the average of the two middle elements + return (sorted[middleIndex - 1] + sorted[middleIndex]) / 2; } } From 9ed4c2cc4fc9b111fa65b5650f8ec0022da705e1 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 13:08:22 +0000 Subject: [PATCH 58/64] test: ensure dedupe returns a new array copy - Added `expect(result).not.toBe(input)` to tests that check array output. - Confirms that the returned array is a new object, not the same reference as the input. - Maintains `toEqual` checks for content correctness. - Addresses feedback about verifying array copy vs original reference. --- Sprint-1/implement/dedupe.test.js | 47 ++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index e6a4b7703..41fc280d5 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -1,4 +1,5 @@ const dedupe = require("./dedupe.js"); + /* Dedupe Array @@ -17,10 +18,12 @@ describe("dedupe - valid inputs", () => { // 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"); [{ input: [], expected: [] }].forEach(({ input, expected }) => - test(`returns an empty array for input [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + test(`returns an empty array for input [${input}]`, () => { + const result = dedupe(input); + expect(result).toEqual(expected); + expect(result).not.toBe(input); // ensures it's a new array + }) ); // Given an array with no duplicates @@ -31,38 +34,50 @@ describe("dedupe - valid inputs", () => { { input: ["a", "b", "car"], expected: ["a", "b", "car"] }, { input: [0, 1, 5, 6], expected: [0, 1, 5, 6] }, ].forEach(({ input, expected }) => - test(`returns a copy of the array when no duplicates exist for input [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + test(`returns a copy of the array when no duplicates exist for input [${input}]`, () => { + const result = dedupe(input); + expect(result).toEqual(expected); + expect(result).not.toBe(input); // ensures it's a new array + }) ); + // Given arrays with duplicates [ { input: [5, 1, 1, 2, 3, 2, 5, 8], expected: [5, 1, 2, 3, 8] }, { input: [1, 1, 1, 1], expected: [1] }, { input: ["a", "a", "a", "b", "b", "c"], expected: ["a", "b", "c"] }, ].forEach(({ input, expected }) => - test(`removes duplicate elements and keep the first occurrence for [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + test(`removes duplicate elements and keeps the first occurrence for [${input}]`, () => { + const result = dedupe(input); + expect(result).toEqual(expected); + expect(result).not.toBe(input); // ensures it's a new 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 + // Given arrays with numbers and strings mixed [ { input: ["1", 1, "1", 1], expected: ["1", 1] }, { input: [2, "3", "hello", 5, 5], expected: [2, "3", "hello", 5] }, ].forEach(({ input, expected }) => - test(`removes duplicates from an array of numbers and strings, keeping the first occurrence of each element, for the input [${input}]`, () => - expect(dedupe(input)).toEqual(expected)) + test(`removes duplicates from an array of numbers and strings, keeping the first occurrence for input [${input}]`, () => { + const result = dedupe(input); + expect(result).toEqual(expected); + expect(result).not.toBe(input); // ensures it's a new array + }) ); + // Given arrays with invalid elements [ { input: [1, 2, true, 3, null, "a", {}], expected: [1, 2, 3, "a"] }, { input: ["x", undefined, "x", "y", []], expected: ["x", "y"] }, { input: [false, 5, 5, "hello", () => {}, 5], expected: [5, "hello"] }, { input: [1, NaN, 2, NaN, "hello"], expected: [1, 2, "hello"] }, ].forEach(({ input, expected }) => - test(`Ensures dedupe filters out invalid elements, removes duplicates, and returns a copy of the array`, () => - expect(dedupe(input)).toEqual(expected)) + test(`filters invalid elements, removes duplicates, and returns a copy for input [${input}]`, () => { + const result = dedupe(input); + expect(result).toEqual(expected); + expect(result).not.toBe(input); // ensures it's a new array + }) ); }); @@ -71,8 +86,8 @@ describe("dedupe - invalid inputs", () => { invalidInputs.forEach((input) => test(`throws typeError when input is ${String(input)}`, () => { - expect(() => dedupe(null)).toThrow(TypeError); - expect(() => dedupe(null)).toThrow("Input must be an array"); + expect(() => dedupe(input)).toThrow(TypeError); + expect(() => dedupe(input)).toThrow("Input must be an array"); }) ); }); From f6c5f8aaa6ca073ac980a8eacdb761d9dc45349b Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 13:19:27 +0000 Subject: [PATCH 59/64] Update sum.test.js to use toBeCloseTo for decimal/float sums - Replaced `toBe` with `toBeCloseTo` for all tests involving decimal numbers. - Ensures floating-point sums are tested correctly despite precision issues. - Updated expected values to match actual sums when necessary (e.g., -7.4 instead of -7.399). - Keeps integer and exact sums using `toBe`. --- Sprint-1/implement/sum.test.js | 50 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index 25e13a2ec..deaaecdf2 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -14,53 +14,53 @@ const sum = require("./sum.js"); // When passed to the sum function // Then it should return 0 test("given an empty array, returns 0", () => { - expect(sum([])).toBe(0); - - const arr = []; - expect(sum(arr)).toBe(0); -}) + expect(sum([])).toBe(0); + + const arr = []; + expect(sum(arr)).toBe(0); +}); // Given an array with just one number // When passed to the sum function // Then it should return that number test("given one number in an array, returns that number", () => { - expect(sum([5])).toBe(5); - expect(sum([-3])).toBe(-3); - expect(sum([0])).toBe(0); -}) + expect(sum([5])).toBe(5); + expect(sum([-3])).toBe(-3); + expect(sum([0])).toBe(0); +}); // 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, should return the correct total sum", () => { - expect(sum([-5, -9, -100])).toBe(-114); - expect(sum([-1000, -2000, -3000])).toBe(-6000); - expect(sum([-1, -2, -3])).toBe(-6); -}) + expect(sum([-5, -9, -100])).toBe(-114); + expect(sum([-1000, -2000, -3000])).toBe(-6000); + expect(sum([-1, -2, -3])).toBe(-6); +}); // 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, should return the correct total number", () => { - expect(sum([-8.24, 5.46, 3.22])).toBe(0.44); - expect(sum([-2.5, 2.5, 5.25])).toBe(5.25); - expect(sum([1.11, 2.22, 3.33])).toBe(6.66); -}) + expect(sum([-8.24, 5.46, 3.22])).toBeCloseTo(0.44, 5); + expect(sum([-2.5, 2.5, 5.25])).toBeCloseTo(5.25, 5); + expect(sum([1.11, 2.22, 3.33])).toBeCloseTo(6.66, 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, should ignore the non-numerical values and return the sum of the numerical elements", () => { - expect(sum([5, -18, 5.601, null, "kettle"])).toBe(-7.4); - expect(sum([true, false, 10, -5])).toBe(5); - expect(sum([null, 4, 6, "test"])).toBe(10); -}) + expect(sum([5, -18, 5.601, null, "kettle"])).toBeCloseTo(-7.4, 5); + expect(sum([true, false, 10, -5])).toBe(5); + expect(sum([null, 4, 6, "test"])).toBe(10); +}); // 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, should return 0", () => { - expect(sum(["food", null, false, true])).toBe(0); - expect(sum(["apple", "banana", null, undefined])).toBe(0); - expect(sum([NaN, NaN, NaN])).toBe(0); -}) + expect(sum(["food", null, false, true])).toBe(0); + expect(sum(["apple", "banana", null, undefined])).toBe(0); + expect(sum([NaN, NaN, NaN])).toBe(0); +}); From 68a0f817fbe9c20f40db5b23ce1326327226f88a Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 14:17:51 +0000 Subject: [PATCH 60/64] Refactor calculateMedian by removing unnecessary array copy - Remove redundant cloning of validNumbers before sorting - Allow safe in-place sort since validNumbers is newly created from list - Update comments to allign with changes --- Sprint-1/fix/median.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b2709cb5b..4507226c4 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -21,19 +21,19 @@ function calculateMedian(list) { return null; } - // Create a shallow copy of `validNumbers` and sort it in ascending order - // This avoids modifying the original array - const sorted = [...validNumbers].sort((a, b) => a - b); + // Sort `validNumbers` in ascending order + // Sort validNumbers (safe to mutate because it's a new array created by filter) + validNumbers.sort((a, b) => a - b); // Calculate the middle index of the sorted array - const middleIndex = Math.floor(sorted.length / 2); + const middleIndex = Math.floor(validNumbers.length / 2); // If the array has an odd number of elements, return the middle element - if (sorted.length % 2 !== 0) { - return sorted[middleIndex]; + if (validNumbers.length % 2 !== 0) { + return validNumbers[middleIndex]; } else { // If the array has an even number of elements, return the average of the two middle elements - return (sorted[middleIndex - 1] + sorted[middleIndex]) / 2; + return (validNumbers[middleIndex - 1] + validNumbers[middleIndex]) / 2; } } From 3b01ceec2f35b901a1765585130dc39894454699 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 14:50:59 +0000 Subject: [PATCH 61/64] Fix errors and omissions in findMax tests: add missing assertions and handle non-numeric arrays --- Sprint-1/implement/max.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 0782a7d62..8ba3d5fd3 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -34,7 +34,7 @@ test("given an array with one number, returns that number", () => { // Then it should return the largest number overall test("given an array with both positive and negative numbers, returns the largest number overall", () => { expect(findMax([10, -5, 20, 0])).toBe(20); - expect(findMax([-1, -100, -50, 30])); + expect(findMax([-1, -100, -50, 30])).toBe(30); expect(findMax([0, -10, 5])).toBe(5); }); @@ -70,7 +70,7 @@ test("given an array with non-number values, returns the max and ignore the non- // 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", () => { expect(findMax(["a", null, undefined])).toBe(-Infinity); - expect(findMax([{}, [], "hi"])); + expect(findMax([{}, [], "hi"])).toBe(-Infinity); expect(findMax([true, false, true])).toBe(-Infinity); expect(findMax([Symbol("x"), () => {}, function () {}])).toBe(-Infinity); }); From 0a5cd8168db6f0242650dd009c29967d4dc864e8 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 14:52:54 +0000 Subject: [PATCH 62/64] Remove .toFixed(2) when returning the numeric value of sumElements --- Sprint-1/implement/sum.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 2c4d90bb1..42610488e 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -10,7 +10,7 @@ function sum(elements) { for (const item of filteredElements) { sumElements += item; } - return Number(sumElements.toFixed(2)); + return Number(sumElements); } module.exports = sum; From d112b5b3135e338f4980f9dcd9f52102ff0cf15c Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 14:57:42 +0000 Subject: [PATCH 63/64] Remove explicit precision from `toBeCloseTo` test cases --- Sprint-1/implement/sum.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index deaaecdf2..dc4748e3a 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -42,16 +42,16 @@ test("given an array containing negative numbers, should return the correct tota // When passed to the sum function // Then it should return the correct total sum test("given an array with decimal/float numbers, should return the correct total number", () => { - expect(sum([-8.24, 5.46, 3.22])).toBeCloseTo(0.44, 5); - expect(sum([-2.5, 2.5, 5.25])).toBeCloseTo(5.25, 5); - expect(sum([1.11, 2.22, 3.33])).toBeCloseTo(6.66, 5); + expect(sum([-8.24, 5.46, 3.22])).toBeCloseTo(0.44); + expect(sum([-2.5, 2.5, 5.25])).toBeCloseTo(5.25); + expect(sum([1.11, 2.22, 3.33])).toBeCloseTo(6.66); }); // 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, should ignore the non-numerical values and return the sum of the numerical elements", () => { - expect(sum([5, -18, 5.601, null, "kettle"])).toBeCloseTo(-7.4, 5); + expect(sum([5, -18, 5.601, null, "kettle"])).toBeCloseTo(-7.4); expect(sum([true, false, 10, -5])).toBe(5); expect(sum([null, 4, 6, "test"])).toBe(10); }); From b32105e8277508ad8ffaced32228217d24d59c86 Mon Sep 17 00:00:00 2001 From: iswat Date: Thu, 20 Nov 2025 17:17:05 +0000 Subject: [PATCH 64/64] Remove redundant Number() conversion around sumElement --- Sprint-1/implement/sum.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 42610488e..721239868 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -10,7 +10,7 @@ function sum(elements) { for (const item of filteredElements) { sumElements += item; } - return Number(sumElements); + return sumElements; } module.exports = sum;