diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index b22590bc6..5ea4838b7 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -6,9 +6,22 @@ // 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; + if (!Array.isArray(list) || list.length === 0) { + return null; + } + + const numbers = list.filter(n => typeof n === "number" && !Number.isNaN(n)); + + if (numbers.length === 0) { + return null; + } + + const sorted = numbers.sort((a, b) => a - b); + const mid = Math.floor(sorted.length / 2); + + return sorted.length % 2 + ? sorted[mid] + : (sorted[mid - 1] + sorted[mid]) / 2; } -module.exports = calculateMedian; +module.exports = calculateMedian; \ No newline at end of file diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..0276a2969 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,6 @@ -function dedupe() {} +function dedupe(arr) { + if (!Array.isArray(arr)) return []; + return [...new Set(arr)]; +} + +module.exports = dedupe; diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index d7c8e3d8e..038ee58db 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -16,13 +16,29 @@ E.g. dedupe([1, 2, 1]) returns [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 -// Then it should return a copy of the original array +describe("dedupejs", () => { + test.each([ + { input: [""], expected: [""] }, -// Given an array of strings or numbers -// When passed to the dedupe function -// Then it should return a new array with duplicates removed while preserving the -// first occurrence of each element from the original array. + // 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] }, + + // Given an array of strings or numbers + // When passed to the dedupe function + // Then it should return a new array with duplicates removed while preserving the + // first occurrence of each element from the original array. + + { input: [1, 2, 2, 3], expected: [1, 2, 3] }, + { input: [1, "a", 2, "a"], expected: [1, "a", 2] }, + { input: ["b", "c", "d", "e"], expected: ["b", "c", "d", "e"] }, + ])("removes duplicates from $input", ({ input, expected }) => { + const result = dedupe(input); // stores the result in a variable called result + expect(result).toEqual(expected); // Check that the result matches the expected output + expect(result).not.toBe(input); // Check that it's a new array (not the original) + }); +}); diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..bbf7d159a 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,26 @@ function findMax(elements) { + //find largest number in an array + if (!Array.isArray(elements)) { + throw new Error("Input must be an array"); //checks input is an array if not throws error + } + + let max = -Infinity; //starts at -Infinity so any number will be bigger + let foundValid = false; //starts at false and will become true if valid number found + + for (const val of elements) { + if (!Number.isFinite(val)) continue; //skips non-numeric values + + foundValid = true; //sets to true if a valid number is found + if (val > max) { + max = val; //updates max if current value is greater + } + } + if (!foundValid) { + //if no valid numbers found, returns"-Inifinity" this includes invalid data and empty arrays + return -Infinity; + } + + return max; //returns the largest number found } module.exports = findMax; diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index 82f18fd88..bdd689cfc 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -16,28 +16,56 @@ 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"); +describe("findMax.js", () => { + test.each([ + { input: [], expected: -Infinity }, + // Given an array with one number + // When passed to the max function + // Then it should return that number -// Given an array with one number -// When passed to the max function -// Then it should return that number + { input: [1], expected: 1 }, -// Given an array with both positive and negative numbers -// When passed to the max function -// Then it should return the largest number overall + // Given an array with both positive and negative numbers + // When passed to the max function + // Then it should return the largest number overall -// Given an array with just negative numbers -// When passed to the max function -// Then it should return the closest one to zero + { input: [1, 2, -3], expected: 2 }, -// Given an array with decimal numbers -// When passed to the max function -// Then it should return the largest decimal number + // Given an array with just negative numbers + // When passed to the max function + // Then it should return the closest one to zero -// Given an array with non-number values -// When passed to the max function -// Then it should return the max and ignore non-numeric values + { input: [-6, -2, -3], expected: -2 }, -// 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 + // Given an array with decimal numbers + // When passed to the max function + // Then it should return the largest decimal number + + { input: [3.5, 2.9, 6.3], expected: 6.3 }, + + // Given an array with non-number values + // When passed to the max function + // Then it should return the max and ignore non-numeric values + + { input: ["a", 2, 3], expected: 3 }, + + // 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 + // It will return -Infinity as it ignores all non-numeric values and returns -Infinity if no valid numbers found + + { input: ["a", "!", "x"], expected: -Infinity }, + + // Given an array contains a number string it will ignore the string and return the max number + + { input: ["5", 2, 3], expected: 3 }, + + + // Given an array contains only number strings it will rerturn -Infinity + + { input: ["5", "2", "3"], expected: -Infinity }, + + ])("returns correct max for %o", ({ input, expected }) => { + expect(findMax(input)).toBe(expected); + }); +}); diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..fbfdb9132 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,21 @@ function sum(elements) { -} + // adds numbers and ignores non-numbers unless there are no valid numbers then throws error + + if (!Array.isArray(elements)) { + throw new Error("Input must be an array"); //checks input is an array if not throws error + } + + if (elements.length === 0) return 0; // <-- empty array returns 0 + let total = 0; + let foundValid = false; //starts at false and will become true if valid number found + + for (const val of elements) { + if (!Number.isFinite(val)) continue; + foundValid = true; // loops and checks if input valid and if valid changes foundValid to true + total += val; //adds number to sum + } + + return foundValid ? total : "Invalid Input"; // if at least one valid value is found return sum if no valid number is found return Invalid Input +} module.exports = sum; diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index dd0a090ca..8005e3d8e 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -7,30 +7,57 @@ E.g. sum(['hey', 10, 'hi', 60, 10]), target output: 80 (ignore any non-numerical */ const sum = require("./sum.js"); +describe("sum.js", () => { + test.each([ + // Acceptance Criteria: -// Acceptance Criteria: + // Given an empty array + // When passed to the sum function + // Then it should return 0 -// Given an empty array -// When passed to the sum function -// Then it should return 0 -test.todo("given an empty array, returns 0") + { input: [], expected: 0 }, -// Given an array with just one number -// When passed to the sum function -// Then it should return that number + // Given an array with just one number + // When passed to the sum function + // Then it should return that number -// Given an array containing negative numbers -// When passed to the sum function -// Then it should still return the correct total sum + { input: [1], expected: 1 }, -// Given an array with decimal/float numbers -// When passed to the sum function -// Then it should return the correct total sum + // Given an array containing negative numbers + // When passed to the sum function + // Then it should still return the correct total sum -// 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 + { input: [-2, 3, 4, -6], expected: -1 }, + { input: [4, -2], expected: 2 }, -// 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 + // Given an array with decimal/float numbers + // When passed to the sum function + // Then it should return the correct total sum + + { input: [2.3, 4.2, 3.5], expected: 10 }, + { input: [4, 1.5], expected: 5.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 + + { input: ["a", 2, 5, "b"], expected: 7 }, + + // 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 + + { input: ["a", "n", "p"], expected: "Invalid Input" }, + ])( + "sums all numbers from $input and expects $expected", + ({ input, expected }) => { + const result = sum(input); + + if (typeof expected === "number") { + expect(Math.abs(result - expected)).toBeLessThan(1e-10); // for special cases of decimals to avoid precision issues + } else { + expect(result).toEqual(expected); // for non-numeric expected values, check for exact match + } + } + ); +}); diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..e301c31a7 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,12 +1,11 @@ // Refactor the implementation of includes to use a for...of loop function includes(list, target) { - for (let index = 0; index < list.length; index++) { - const element = list[index]; + for (const element of list) if (element === target) { return true; } - } + return false; }