From 6e3bb1f26309a79f717550dce0cf66335aa3cf3a Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Sun, 9 Nov 2025 10:37:21 +0000 Subject: [PATCH 01/14] Sumarry:update calulateMedian implementation ...checked if input is an array,otherwise return null..........Filtered out non-numeric element .......Added a check for emty numeric arrays ....Cloned the array to prevent mutation(avoid side effects)......Sorted numbers in ascending order.......Calculated the median for both even and odd length --- Sprint-1/fix/median.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b22590bc6..c58f3f369 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,9 +6,27 @@ // 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; + // must be an array + if (!Array.isArray(list)) return null; + //filter out non-numeric values + + const numericList = list.filter( + (item) => typeof item === "number" && !isNaN(item) + ); + // return null if no valid numbers + if (numericList.length === 0) return null; + + sortedList = [...numericList]; + + sortedList.sort((a, b) => a - b); + if (sortedList.length % 2 === 0) { + let middleIndex = sortedList.length / 2; + return (sortedList[middleIndex] + sortedList[middleIndex - 1]) / 2; + } else { + const middleIndex = Math.floor(sortedList.length / 2); + const median = sortedList.splice(middleIndex, 1)[0]; + return median; + } } module.exports = calculateMedian; From 3dcaaabcaf9df6447b2ea294437e226b0eeaface Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Mon, 10 Nov 2025 08:26:28 +0000 Subject: [PATCH 02/14] max... add a test to check that the function returns -infinty whey the array is empty and update the function's code to handles this scenario --- Sprint-1/implement/max.js | 1 + Sprint-1/implement/max.test.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..d23a3e347 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,5 @@ function findMax(elements) { + if(elements===0) return -Infinity; } module.exports = findMax; diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 82f18fd88..cebd7f28c 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -16,6 +16,12 @@ 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. +describe("findMax",() => { +it ("given an empty array,returns -Infinity",() =>{ + expect(findMax([])).toEqual(-Infinity) +}) + +}) test.todo("given an empty array, returns -Infinity"); // Given an array with one number From cb84ef6dff3dc001293c4d08a88c43f862e81644 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Tue, 11 Nov 2025 09:33:27 +0000 Subject: [PATCH 03/14] add comprehensive tests for finMax function and implement finMax to handle all test scenarios the scenarios are \n-empty array\n -Single elemnt array \n -Mixed positive and negative numbers\n-All negative numbers\n-Decimal values\n-Array with mixed (numeric/non-numeric)values \n- Array with only non-numeric values --- Sprint-1/implement/max.js | 14 ++++++++++- Sprint-1/implement/max.test.js | 45 +++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index d23a3e347..63aa79357 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,5 +1,17 @@ function findMax(elements) { - if(elements===0) return -Infinity; + const elementsClone = [...elements]; + + const numericElements = elementsClone.filter( + (item) => typeof item === "number" && !isNaN(item) + ); + if (numericElements.length === 0) return -Infinity; + + let max = numericElements[0]; + for (let i = 0; i < numericElements.length; i++) { + if (max < numericElements[i]) max = numericElements[i]; + } + + return max; } module.exports = findMax; diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index cebd7f28c..7c53f16c6 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -16,13 +16,46 @@ 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. -describe("findMax",() => { -it ("given an empty array,returns -Infinity",() =>{ - expect(findMax([])).toEqual(-Infinity) -}) +describe("findMax", () => { + it("return -Infinity when given an empty array", () => { + expect(findMax([])).toEqual(-Infinity); + }); -}) -test.todo("given an empty array, returns -Infinity"); + [ + { input: [0], expected: 0 }, + { input: [-12], expected: -12 }, + { input: [4], expected: 4 }, + ].forEach(({ input, expected }) => + it(`return the same number when the array has one element, for array[${input}] `, () => + expect(findMax(input)).toEqual(expected)) + ); + [ + { input: [10, 11, 13, 3, 4], expected: 13 }, + { input: [99, 3, 10, 11], expected: 99 }, + { input: [-12, -33, -10, -111], expected: -10 }, + { input: [-1, -11, -33], expected: -1 }, + { input: [-99, -2, 0, 0, -2], expected: 0 }, + ].forEach(({ input, expected }) => + it(`return the largest number for array containing, positive, negative, or mixed values , for array [${input}]`, () => + expect(findMax(input)).toEqual(expected)) + ); + [ + { input: [11.1, 14.1, 17.223, 16], expected: 17.223 }, + { input: [11.1, 11.33, 11.34, 11.2999], expected: 11.34 }, + ].forEach(({ input, expected }) => + it(`give an array with decimal numbers, return the largest decimal numbers for array [${input}]`, () => + expect(findMax(input)).toEqual(expected)) + ); + + it(`given an array with non-number values , return the largest after ignore the no-number values for an array input:["a",2,null,undefined,13,18]`, () => { + expect(findMax(["a", 2, null, undefined, 13, 18])).toEqual(18); + }); + it(`given an array with only non-number values , return -infinity`, () => { + expect(findMax(["a", "2", null, undefined, "ahmad", "Hmedan"])).toEqual( + -Infinity + ); + }); +}); // Given an array with one number // When passed to the max function From af680aca1531595e92998f8de7c6d66ef70808a6 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Tue, 11 Nov 2025 11:14:06 +0000 Subject: [PATCH 04/14] add comprehensive tests for sum function and implement sum to handle all test scenarios the scenarios are \n-empty array\n -Single elemnt array \n -Mixed positive and negative numbers\n-All negative numbers\n-Decimal values\n-Array with mixed (numeric/non-numeric)values \n- Array with only non-numeric value --- Sprint-1/implement/sum.js | 10 +++++++++ Sprint-1/implement/sum.test.js | 39 +++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..a3f85b8e7 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,14 @@ function sum(elements) { + if (!Array.isArray(elements)) return 0; + const numericElements = [...elements].filter( + (item) => typeof item === "number" && !isNaN(item) + ); + if (numericElements.length === 0) return 0; + let sum = 0; + for (let i = 0; i < numericElements.length; i++) { + sum += numericElements[i]; + } + return sum; } module.exports = sum; diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index dd0a090ca..916da1599 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -13,7 +13,44 @@ 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") +describe("sum", () => { + it("return 0 when given an empty array", () => { + expect(sum([])).toBe(0); + }); + + [ + { input: [0], expected: 0 }, + { input: [-12], expected: -12 }, + { input: [4], expected: 4 }, + ].forEach(({ input, expected }) => + it(`return the same number when the array has one element, for array[${input}] `, () => + expect(sum(input)).toBe(expected)) + ); + [ + { input: [10, 11, 13, 3, 4], expected: 41 }, + { input: [99, 3, 10, 11], expected: 123 }, + { input: [-12, -33, -10, -111], expected: -166 }, + { input: [-1, -11, -33], expected: -45 }, + { input: [-99, -2, 0, 0, -2], expected: -103 }, + ].forEach(({ input, expected }) => + it(`return the sum of numbers for array containing, positive, negative, or mixed values , for array [${input}]`, () => + expect(sum(input)).toBe(expected)) + ); + + [ + { input: [11.1, 14.1, 17.223, 16], expected: 58.423 }, + { input: [11.1, 11.33, 11.34, 11.2999], expected: 45.0699 }, + ].forEach(({ input, expected }) => + it(`returns the sum for decimal values for array [${input}]`, () => + expect(sum(input)).toBe(expected)) + ); + it("ignores non-numeric values and returns the sum of numeric ones", () => { + expect(sum(["2", 2, null, undefined, 13, 18])).toBe(33); + }); + it("returns 0 when no numeric values are present", () => { + expect(sum(["a", "2", null, undefined, "ahmad", "Hmedan"])).toBe(0); + }); +}); // Given an array with just one number // When passed to the sum function From 94589a92af551f54aa9323eb086f5251bac2fcef Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Tue, 11 Nov 2025 11:16:03 +0000 Subject: [PATCH 05/14] return infinity if the input not an array --- Sprint-1/implement/max.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 63aa79357..9cc876839 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,5 @@ function findMax(elements) { + if (!Array.isArray(elements)) return -Infinity; const elementsClone = [...elements]; const numericElements = elementsClone.filter( From f16627ae2da3e03071328647fea87ed580c4695b Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Tue, 11 Nov 2025 19:55:33 +0000 Subject: [PATCH 06/14] Implement dedupe function with jest tests --- Sprint-1/implement/dedupe.js | 18 +++++++++++++++++- Sprint-1/implement/dedupe.test.js | 30 +++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..b8464226e 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,17 @@ -function dedupe() {} +function dedupe(elements) { + const elementsClone = [...elements]; + if (elementsClone.length === 0) return elementsClone; + + for (let i = 1; i < elementsClone.length; i++) { + for (let j = i; j > 0; j--) { + if (elementsClone[i] === elementsClone[j - 1]) { + elementsClone.splice(i, 1); + i--; // because I deleted one element from my array + break; + } + } + } + return elementsClone; +} + +module.exports = dedupe; diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index 23e0f8638..7f78f6de8 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -16,7 +16,35 @@ 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"); +describe("Dedupe", () => { + it("returns an empty array when it given an empty array", () => { + expect(dedupe([])).toEqual([]); + }); + [ + { input: [10, 12, 13], expected: [10, 12, 13] }, + { + input: ["a", "b", "keke", 1, 21, 3], + expected: ["a", "b", "keke", 1, 21, 3], + }, + { input: [null, undefined, 1, 3], expected: [null, undefined, 1, 3] }, + ].forEach(({ input, expected }) => + it(`returns a copy of the original array when given an array with no duplicates, for [${input}]`, () => + expect(dedupe(input)).toEqual(expected)) + ); + [ + { input: [10, 12, 10, 13], expected: [10, 12, 13] }, + { input: [1, "a", "a", "b", 1, 1, "a"], expected: [1, "a", "b"] }, + { + input: [null, undefined, 1, 3, 1, 1, 1, 1], + expected: [null, undefined, 1, 3], + }, + ].forEach(({ input, expected }) => { + it(`remove duplicates from [${input}]`, () => expect(dedupe(input)).toEqual(expected)); + }); + it("treats different types separately", () => { + expect(dedupe([1, "1", true, "true", false, 0])).toEqual([1, "1", true, "true", false, 0]); + }); +}); // Given an array with no duplicates // When passed to the dedupe function From 36822dc6944d19da295671c4b8dd5a57795898ad Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Wed, 12 Nov 2025 08:15:19 +0000 Subject: [PATCH 07/14] refactoring the impementation --- Sprint-1/refactor/includes.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..d9322a091 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,13 +1,15 @@ // 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]; - if (element === target) { - return true; - } + for (const element of list) { + if (element === target) return true; } return false; } - module.exports = includes; + +// function includes(list, target) { + +// return (list.indexOf(target)===-1)? false:true; +// } +// module.exports = includes; From 5aa44a8879b296b26826b107a561321f4889430f Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Wed, 12 Nov 2025 08:15:48 +0000 Subject: [PATCH 08/14] clean the code --- Sprint-1/refactor/includes.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index d9322a091..aead3967a 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -7,9 +7,3 @@ function includes(list, target) { return false; } module.exports = includes; - -// function includes(list, target) { - -// return (list.indexOf(target)===-1)? false:true; -// } -// module.exports = includes; From cca85e965fff097ff834d85797f0adfd867bd411 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Mon, 1 Dec 2025 08:36:28 +0000 Subject: [PATCH 09/14] remove unncessary clone --- Sprint-1/fix/median.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index c58f3f369..a253e6237 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,25 +6,23 @@ // or 'list' has mixed values (the function is expected to sort only numbers). function calculateMedian(list) { - // must be an array + if (!Array.isArray(list)) return null; - //filter out non-numeric values - const numericList = list.filter( (item) => typeof item === "number" && !isNaN(item) ); - // return null if no valid numbers + if (numericList.length === 0) return null; - sortedList = [...numericList]; - sortedList.sort((a, b) => a - b); - if (sortedList.length % 2 === 0) { - let middleIndex = sortedList.length / 2; - return (sortedList[middleIndex] + sortedList[middleIndex - 1]) / 2; + + numericList.sort((a, b) => a - b); + if (numericList.length % 2 === 0) { + let middleIndex = numericList.length / 2; + return (numericList[middleIndex] + numericList[middleIndex - 1]) / 2; } else { - const middleIndex = Math.floor(sortedList.length / 2); - const median = sortedList.splice(middleIndex, 1)[0]; + const middleIndex = Math.floor(numericList.length / 2); + const median = numericList.splice(middleIndex, 1)[0]; return median; } } From e49a7004f74f935e56174ed20feed1129701d571 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Mon, 1 Dec 2025 09:51:38 +0000 Subject: [PATCH 10/14] add test to check if the input array and the result array are different --- 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 7f78f6de8..76724579a 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -44,6 +44,12 @@ describe("Dedupe", () => { it("treats different types separately", () => { expect(dedupe([1, "1", true, "true", false, 0])).toEqual([1, "1", true, "true", false, 0]); }); + it("Test if the input array and result array are different",()=>{ + const input=[1,2,3,3,2,1] + const result=dedupe(input) + expect(input).not.toBe(result) + expect(result).toEqual([1,2,3]) + }) }); // Given an array with no duplicates From a3a1636a5afac1b56c4b7b3c8940a4c9b128722c Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Mon, 1 Dec 2025 10:09:21 +0000 Subject: [PATCH 11/14] remove unnecessary clone and update fliter by using Number.isFinite --- Sprint-1/implement/sum.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index a3f85b8e7..2b659ad5a 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,8 +1,6 @@ function sum(elements) { if (!Array.isArray(elements)) return 0; - const numericElements = [...elements].filter( - (item) => typeof item === "number" && !isNaN(item) - ); + const numericElements = elements.filter(Number.isFinite) if (numericElements.length === 0) return 0; let sum = 0; for (let i = 0; i < numericElements.length; i++) { From dc1f26263b2807b056285e2e891ff3999ebaaf79 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Mon, 1 Dec 2025 10:30:10 +0000 Subject: [PATCH 12/14] use toBeCloseTo instead toBe for solve floating-point issue --- Sprint-1/implement/sum.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index 916da1599..a3e0ec7d1 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -40,9 +40,10 @@ describe("sum", () => { [ { input: [11.1, 14.1, 17.223, 16], expected: 58.423 }, { input: [11.1, 11.33, 11.34, 11.2999], expected: 45.0699 }, + { input: [1.2, 0.6, 0.005], expected: 1.805 }, ].forEach(({ input, expected }) => it(`returns the sum for decimal values for array [${input}]`, () => - expect(sum(input)).toBe(expected)) + expect(sum(input)).toBeCloseTo(expected)) ); it("ignores non-numeric values and returns the sum of numeric ones", () => { expect(sum(["2", 2, null, undefined, 13, 18])).toBe(33); From 95c9737b289d40eecb2059f667a8d79a98016db6 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Fri, 5 Dec 2025 09:29:13 +0000 Subject: [PATCH 13/14] update the code --- Sprint-1/fix/median.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index a253e6237..9a7c7ac40 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -22,7 +22,7 @@ function calculateMedian(list) { return (numericList[middleIndex] + numericList[middleIndex - 1]) / 2; } else { const middleIndex = Math.floor(numericList.length / 2); - const median = numericList.splice(middleIndex, 1)[0]; + const median = numericList[middleIndex]; return median; } } From 339a9324b89068ecce783b760e89585d3c3e5f33 Mon Sep 17 00:00:00 2001 From: Ahmad Hmedan Date: Fri, 5 Dec 2025 09:57:46 +0000 Subject: [PATCH 14/14] use built-in function --- Sprint-1/implement/dedupe.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index b8464226e..1d136d0fc 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1,17 +1,8 @@ -function dedupe(elements) { - const elementsClone = [...elements]; - if (elementsClone.length === 0) return elementsClone; - for (let i = 1; i < elementsClone.length; i++) { - for (let j = i; j > 0; j--) { - if (elementsClone[i] === elementsClone[j - 1]) { - elementsClone.splice(i, 1); - i--; // because I deleted one element from my array - break; - } - } - } - return elementsClone; -} + function dedupe(elements) { + return [...new Set(elements)]; + } + + module.exports = dedupe;