diff --git a/Sprint-1/fix/median.js b/Sprint-1/fix/median.js index 5c5b796e1..d272d61af 100644 --- a/Sprint-1/fix/median.js +++ b/Sprint-1/fix/median.js @@ -5,10 +5,42 @@ // Hint: Please consider scenarios when 'list' isn't an array, is empty, // or contains values that aren't numbers (the function is expected to throw - see the tests). -function calculateMedian(list) { +function calculateMedian(list = 0) { + if (list === null) { + throw new Error("calculateMedian requires an array of numbers"); + } + + if (list.length === 0) { + throw new Error("calculateMedian requires a non-empty array"); + } + + if (typeof list === "string") { + throw new Error("calculateMedian requires an array of numbers"); + } + + if (typeof list === "number") { + throw new Error("calculateMedian requires an array of numbers"); + } + + if (typeof list === "object" && !Array.isArray(list)) { + throw new Error("calculateMedian requires an array of numbers"); + } + + for (item of list) { + if (typeof item === "string" || item === null || item === undefined) { + throw new Error("calculateMedian requires an array of numbers"); + } + } + + const sortedList = list.toSorted((a, b) => a - b); + const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; - return median; + + if (list.length % 2 === 0) { + return (sortedList[middleIndex - 1] + sortedList[middleIndex]) / 2; + } + + return sortedList[middleIndex]; } module.exports = calculateMedian; diff --git a/Sprint-1/implement/dedupe.js b/Sprint-1/implement/dedupe.js index 781e8718a..999b81e16 100644 --- a/Sprint-1/implement/dedupe.js +++ b/Sprint-1/implement/dedupe.js @@ -1 +1,13 @@ -function dedupe() {} +function dedupe(elements) { + const dedupedArr = []; + + for (element of elements) { + if (!dedupedArr.includes(element)) { + dedupedArr.push(element); + } + } + + return dedupedArr; +} + +module.exports = dedupe; diff --git a/Sprint-1/implement/dedupe.test.js b/Sprint-1/implement/dedupe.test.js index d7c8e3d8e..9f9caae20 100644 --- a/Sprint-1/implement/dedupe.test.js +++ b/Sprint-1/implement/dedupe.test.js @@ -16,13 +16,34 @@ 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"); +it("given an empty array, returns empty array", () => { + expect(dedupe([])).toEqual([]); +}); // Given an array with no duplicates // When passed to the dedupe function // Then it should return a copy of the original array +it("given array without duplicates, returns that array", () => { + expect(dedupe([4, 6, 9, 23])).toEqual([4, 6, 9, 23]); +}); // 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 +// Then it should return a new array with duplicates removed while preserving the // first occurrence of each element from the original array. +it("given array with duplicates, returns array without duplicates", () => { + expect(dedupe([4, 6, 9, 23, 9, 23, 23])).toEqual([4, 6, 9, 23]); + expect(dedupe([4, "Hi", 9, "Hi", 9, 23, 23, "hi"])).toEqual([ + 4, + "Hi", + 9, + 23, + "hi", + ]); + expect(dedupe(["Hi", "Hi", "hi", "bye", "Hi", "bye", "yes"])).toEqual([ + "Hi", + "hi", + "bye", + "yes", + ]); +}); diff --git a/Sprint-1/implement/describe-median.js b/Sprint-1/implement/describe-median.js index 3381cfc0a..e6a0a4033 100644 --- a/Sprint-1/implement/describe-median.js +++ b/Sprint-1/implement/describe-median.js @@ -20,6 +20,13 @@ function calculateMedian(list) { } // Implement this function. See describe-median.test.js for the acceptance criteria. -function describeMedian(list) {} +function describeMedian(list) { + try { + const median = calculateMedian(list); + return "The median is " + median; + } catch (error) { + return "Could not calculate a median: " + error.message; + } +} module.exports = describeMedian; diff --git a/Sprint-1/implement/describe-median.test.js b/Sprint-1/implement/describe-median.test.js index e7d18a264..6ce2adc8a 100644 --- a/Sprint-1/implement/describe-median.test.js +++ b/Sprint-1/implement/describe-median.test.js @@ -21,12 +21,30 @@ const describeMedian = require("./describe-median.js"); // When passed to describeMedian // Then it should return "The median is " followed by the median // Delete this test.todo and replace it with a test. -test.todo('given [1, 2, 3], returns "The median is 2"'); +it("Given array of positive numbers, it returns the correct message", () => { + expect(describeMedian([1, 2, 6])).toEqual("The median is 2"); +}); // Given an empty array // When passed to describeMedian // Then it should return "Could not calculate a median: calculateMedian requires a non-empty array" +it("Given an empty array, it tells you it couldn't calculate the median and why", () => { + expect(describeMedian([])).toEqual( + "Could not calculate a median: calculateMedian requires a non-empty array" + ); +}); // Given something that isn't an array of numbers, e.g. "banana" // When passed to describeMedian // Then it should return "Could not calculate a median: calculateMedian requires an array of numbers" +it("Given something that isn't array of numbers, it tells you it couldn't calculate the median and why", () => { + expect(describeMedian("banana")).toEqual( + "Could not calculate a median: calculateMedian requires an array of numbers" + ); + expect(describeMedian([3, "5", 8])).toEqual( + "Could not calculate a median: calculateMedian requires an array of numbers" + ); + expect(describeMedian(42)).toEqual( + "Could not calculate a median: calculateMedian requires an array of numbers" + ); +}); diff --git a/Sprint-1/implement/max.js b/Sprint-1/implement/max.js index 6dd76378e..f10e67d8c 100644 --- a/Sprint-1/implement/max.js +++ b/Sprint-1/implement/max.js @@ -1,4 +1,24 @@ function findMax(elements) { + if (!Array.isArray(elements)) { + throw new Error("findMax requires an array of numbers"); + } + + if (elements.length === 0) { + return -Infinity; + } + + let max = elements[0]; + + for (element of elements) { + if (typeof element != "number") { + throw new Error("findMax requires an array of numbers"); + } + if (element > max) { + max = element; + } + } + + return max; } module.exports = findMax; diff --git a/Sprint-1/implement/max.test.js b/Sprint-1/implement/max.test.js index ff3fbb5e5..84e9830cd 100644 --- a/Sprint-1/implement/max.test.js +++ b/Sprint-1/implement/max.test.js @@ -16,28 +16,58 @@ 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"); +it("given an empty array, returns -Infinity", () => { + expect(findMax([])).toEqual(-Infinity); +}); // Given an array with one number // When passed to the max function // Then it should return that number +it("Given array with one number should return that number", () => { + expect(findMax([3])).toEqual(3); +}); // Given an array with both positive and negative numbers // When passed to the max function // Then it should return the largest number overall +it("Given array of positive and negative values returns the biggest", () => { + expect(findMax([4, -7, 47, -90])).toEqual(47); +}); // Given an array with just negative numbers // When passed to the max function // Then it should return the closest one to zero +it("Given array of negative values returns the closest to zero", () => { + expect(findMax([-4, -7, -47, -90])).toEqual(-4); +}); // Given an array with decimal numbers // When passed to the max function // Then it should return the largest decimal number +it("Given array of positive and negative values returns the biggest", () => { + expect(findMax([4.3, -7.83, 47.134, -90.2947])).toEqual(47.134); +}); // Given an array containing a value that isn't a number // When passed to the max function // Then it should throw Error("findMax requires an array of numbers") +it("Given array with value that isn't a number, should throw", () => { + expect(() => { + findMax([5, "ooo", 203]); + }).toThrow("findMax requires an array of numbers"); +}); // Given something that isn't an array at all, such as "hey", 42 or no argument // When passed to the max function // Then it should throw Error("findMax requires an array of numbers") +it("Given argument that isn't an array, should throw", () => { + expect(() => { + findMax("hey"); + }).toThrow("findMax requires an array of numbers"); + expect(() => { + findMax(42); + }).toThrow("findMax requires an array of numbers"); + expect(() => { + findMax(); + }).toThrow("findMax requires an array of numbers"); +}); diff --git a/Sprint-1/implement/mean.js b/Sprint-1/implement/mean.js index 36909ea1f..47a471137 100644 --- a/Sprint-1/implement/mean.js +++ b/Sprint-1/implement/mean.js @@ -1,3 +1,21 @@ -function calculateMean(list) {} +function calculateMean(list) { + if (!Array.isArray(list)) { + throw new Error("calculateMean requires an array of numbers"); + } + if (list.length === 0) { + throw new Error("calculateMean requires a non-empty array"); + } + + let sum = 0; + + for (item of list) { + if (typeof item != "number") { + throw new Error("calculateMean requires an array of numbers"); + } + sum += item; + } + + return sum / list.length; +} module.exports = calculateMean; diff --git a/Sprint-1/implement/mean.test.js b/Sprint-1/implement/mean.test.js index 847b88676..634d8b5b4 100644 --- a/Sprint-1/implement/mean.test.js +++ b/Sprint-1/implement/mean.test.js @@ -23,28 +23,65 @@ const calculateMean = require("./mean.js"); // When passed to calculateMean // Then it should return their mean // Delete this test.todo and replace it with a test. -test.todo("given [1, 2, 6], returns 3"); +it("Given array of positive numbers, it returns their mean", () => { + expect(calculateMean([1, 2, 6])).toEqual(3); +}); // Given an array with a single number // When passed to calculateMean // Then it should return that number +it("Given array of one number, it returns that number", () => { + expect(calculateMean([2])).toEqual(2); +}); // Given an array containing negative or decimal numbers // When passed to calculateMean // Then it should return the correct mean +it("Given array of negative or decimal number, it returns their mean", () => { + expect(calculateMean([1, -2, 6, 5.89, -43.284])).toEqual(-6.4788); +}); // Given an empty array // When passed to calculateMean // Then it should throw Error("calculateMean requires a non-empty array") +it("Given an empty array, it should throw", () => { + expect(() => { + calculateMean([]); + }).toThrow("calculateMean requires a non-empty array"); +}); // Given a value that isn't an array, e.g. "banana", 42, null or {} // When passed to calculateMean // Then it should throw Error("calculateMean requires an array of numbers") +it("Given value that isn't array, it should throw", () => { + expect(() => { + calculateMean("banana"); + }).toThrow("calculateMean requires an array of numbers"); + expect(() => { + calculateMean(42); + }).toThrow("calculateMean requires an array of numbers"); + expect(() => { + calculateMean(null); + }).toThrow("calculateMean requires an array of numbers"); + expect(() => { + calculateMean({}); + }).toThrow("calculateMean requires an array of numbers"); +}); // Given no argument at all // When passed to calculateMean // Then it should throw Error("calculateMean requires an array of numbers") +it("Given no value at all, it should throw", () => { + expect(() => { + calculateMean(); + }).toThrow("calculateMean requires an array of numbers"); +}); // Given an array containing a non-number value, e.g. [1, "2", 3] // When passed to calculateMean // Then it should throw Error("calculateMean requires an array of numbers") +it("Given array containing non-number, it should throw", () => { + expect(() => { + calculateMean([1, "2", 3]); + }).toThrow("calculateMean requires an array of numbers"); +}); diff --git a/Sprint-1/implement/sum.js b/Sprint-1/implement/sum.js index 9062aafe3..f2a635262 100644 --- a/Sprint-1/implement/sum.js +++ b/Sprint-1/implement/sum.js @@ -1,4 +1,18 @@ function sum(elements) { + if (!Array.isArray(elements)) { + throw new Error("sum requires an array of numbers"); + } + + let theSum = 0; + + for (element of elements) { + if (typeof element != "number") { + throw new Error("sum requires an array of numbers"); + } + theSum += element; + } + + return theSum; } module.exports = sum; diff --git a/Sprint-1/implement/sum.test.js b/Sprint-1/implement/sum.test.js index a288e0f0a..946a47f3b 100644 --- a/Sprint-1/implement/sum.test.js +++ b/Sprint-1/implement/sum.test.js @@ -13,24 +13,51 @@ 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") +it("given an empty array, returns 0", () => { + expect(sum([])).toEqual(0); +}); // Given an array with just one number // When passed to the sum function // Then it should return that number +it("given array with one number, returns that number", () => { + expect(sum([6])).toEqual(6); +}); // Given an array containing negative numbers // When passed to the sum function // Then it should still return the correct total sum +it("given array with negative numbers, returns the correct sum", () => { + expect(sum([6, -10, 3, 5])).toEqual(4); +}); // Given an array with decimal/float numbers // When passed to the sum function // Then it should return the correct total sum +it("given array with decimal numbers, returns the correct sum", () => { + expect(sum([6, 3.68, 3, 5])).toEqual(17.68); +}); // Given an array containing a value that isn't a number // When passed to the sum function // Then it should throw Error("sum requires an array of numbers") +it("given array with values that aren't numbers, should throw", () => { + expect(() => { + sum([6, 3.68, 3, "hey", 5]); + }).toThrow("sum requires an array of numbers"); +}); // Given something that isn't an array at all, such as "hey", 42 or no argument // When passed to the sum function // Then it should throw Error("sum requires an array of numbers") +it("Given argument that isn't an array, should throw", () => { + expect(() => { + sum("hey"); + }).toThrow("sum requires an array of numbers"); + expect(() => { + sum(42); + }).toThrow("sum requires an array of numbers"); + expect(() => { + sum(); + }).toThrow("sum requires an array of numbers"); +}); diff --git a/Sprint-1/refactor/includes.js b/Sprint-1/refactor/includes.js index 29dad81f0..cef2f4b62 100644 --- a/Sprint-1/refactor/includes.js +++ b/Sprint-1/refactor/includes.js @@ -1,9 +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]; - if (element === target) { + for (item of list) { + if (item === target) { return true; } }