diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..50a16814 Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/launch.json b/.vscode/launch.json index c23b2622..6d706e81 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,7 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { "type": "node", "request": "launch", diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..6f3a2913 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cde37d56..d6cb8f1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "CYF-Coursework-Template", + "name": "Module-JS2", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "CYF-Coursework-Template", + "name": "Module-JS2", "version": "1.0.0", "license": "CC-BY-SA-4.0", "devDependencies": { diff --git a/week-1/fix/median.js b/week-1/fix/median.js index 046be3d0..adab38b4 100644 --- a/week-1/fix/median.js +++ b/week-1/fix/median.js @@ -3,9 +3,18 @@ // If you're in the week-1 directory, you can run npm test -- fix to run the tests in the fix directory function calculateMedian(list) { - const middleIndex = Math.floor(list.length / 2); - const median = list.splice(middleIndex, 1)[0]; - return median; + const middleIndex = (list.length + 1)/2; + + if(list.length%2 !== 0){ + return list[middleIndex-1]; + } + else{ + const firstIndex = Math.floor(middleIndex); + const secondIndex = Math.round(middleIndex); + + return (list[firstIndex-1]+list[secondIndex-1])/2; + + } } -module.exports = calculateMedian; +module.exports = calculateMedian; \ No newline at end of file diff --git a/week-1/implement/dedupe.js b/week-1/implement/dedupe.js index 781e8718..1c8ed568 100644 --- a/week-1/implement/dedupe.js +++ b/week-1/implement/dedupe.js @@ -1 +1,49 @@ -function dedupe() {} +//manual check +// function dedupe(input) { + +// let output = []; + +// for(let i=0; i { + expect(dedupe([])).toStrictEqual([]); +}); // Given an array with no duplicates // When passed to the dedupe function // Then it should return a copy of the original array +test("given an array with no duplicates, it returns a copy of the original array", () => { + expect(dedupe([5, 1, 2, 3, 8])).toStrictEqual([5, 1, 2, 3, 8]); +}); + + // Given an array with strings or numbers // When passed to the dedupe function // Then it should remove the duplicate values + + +test("given an array with strings or numbers, it removes the duplicate values", () => { + expect(dedupe([5, 1, 'a', 'a', 2, 'b', 3, 3, 8, 8])).toStrictEqual([5, 1, 'a', 2,'b', 3, 8]); +}); \ No newline at end of file diff --git a/week-1/implement/max.js b/week-1/implement/max.js index e69de29b..65e513ac 100644 --- a/week-1/implement/max.js +++ b/week-1/implement/max.js @@ -0,0 +1,39 @@ +// Manual check +// function max(input){ +// if(input.length == 0){ +// return -Infinity; +// } + +// if(input.length == 1){ +// return input[0]; +// } +// let maxNum = input[0]; +// for (let i=0; i maxNum){ +// maxNum = input[i]; +// } +// } +// return maxNum; +// } + + +function max(input){ + let output = []; + for(let i=0; i { + expect(max([])).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 number", () => { + expect(max([2])).toBe(2); +}); + // 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 number, returns max", () => { + expect(max([-7, 6, 4, -3])).toBe(6); +}); + // 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 number, returns max", () => { + expect(max([7.6, 1.6, 9.4, 3.4])).toBe(9.4); +}); + // 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 max, ignore non-numeric values", () => { + expect(max(["17", 12, "c", 5.4])).toBe(12); +}); \ No newline at end of file diff --git a/week-1/implement/sum.js b/week-1/implement/sum.js index e69de29b..9ae5a9cc 100644 --- a/week-1/implement/sum.js +++ b/week-1/implement/sum.js @@ -0,0 +1,20 @@ + +function sum(input) { + let output = []; + for (let i = 0; i < input.length; i++) { + if (typeof input[i] !== "string") { + output.push(input[i]); + } + } + let total = 0; + for (let i = 0; i < output.length; i++){ + total = total + output[i]; + } + return total; +} + + + + + +module.exports = sum; diff --git a/week-1/implement/sum.test.js b/week-1/implement/sum.test.js index 6b623592..2b11f62e 100644 --- a/week-1/implement/sum.test.js +++ b/week-1/implement/sum.test.js @@ -5,6 +5,7 @@ In this kata, you will need to implement a function that sums the numerical elem E.g. sum([10, 20, 30]), target output: 60 E.g. sum(['hey', 10, 'hi', 60, 10]), target output: 80 (ignore any non-numerical elements) */ +const sum = require("./sum.js"); // Acceptance Criteria: @@ -12,18 +13,40 @@ E.g. sum(['hey', 10, 'hi', 60, 10]), target output: 80 (ignore any non-numerical // When passed to the sum function // Then it should return 0 +test("given an empty array, returns 0 ", () => { + expect(sum([])).toBe(0); +}); + + // Given an array with just one number // When passed to the sum function // Then it should return that number +test("given an array with just one number, returns that number ", () => { + expect(sum([12])).toBe(12); +}); + + // 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 with both positive and negative number, returns correct total sum ", () => { + expect(sum([-7, 6, 4, -3])).toBe(0); +}); + // 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 number, returns the correct total sum", () => { + expect(sum([7.6, 1.6, 9.4, 3.4])).toBe(22); +}); + // 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 with non-number values, returns the sum of the numerical elements, ignore non-numeric values", () => { + expect(sum(["17", 12, "c", 5.4])).toBe(17.4); +}); \ No newline at end of file diff --git a/week-1/refactor/find.js b/week-1/refactor/find.js index 7df447b9..c0e432d1 100644 --- a/week-1/refactor/find.js +++ b/week-1/refactor/find.js @@ -1,10 +1,9 @@ // Refactor the implementation of find to use a for...of loop function find(list, target) { - for (let index = 0; index < list.length; index++) { - const element = list[index]; + for (const element of list){ if (element === target) { - return index; + return list.indexOf(element); } } return -1; diff --git a/week-2/debug/address.js b/week-2/debug/address.js index 940a6af8..3992d554 100644 --- a/week-2/debug/address.js +++ b/week-2/debug/address.js @@ -1,5 +1,7 @@ // Predict and explain first... +// Address is an object, and properties are accessed using their names, not numerical indices. + // This code should log out the houseNumber from the address object // but it isn't working... // Fix anything that isn't working @@ -12,4 +14,6 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); +console.log(`My house number is ${address.city}`); + diff --git a/week-2/debug/author.js b/week-2/debug/author.js index 8c212597..ddaa4180 100644 --- a/week-2/debug/author.js +++ b/week-2/debug/author.js @@ -1,5 +1,5 @@ // Predict and explain first... - +// for...of loop is designed to iterate over iterable objects like arrays, not over plain objects. we need to use for .. in or Object.values() with for of // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem @@ -11,6 +11,10 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); +for (const element of Object.values(author)){ + console.log(element); +} + +for (const element in author) { + console.log(author[element]); } diff --git a/week-2/debug/recipe.js b/week-2/debug/recipe.js index 6cbdd22c..34b34284 100644 --- a/week-2/debug/recipe.js +++ b/week-2/debug/recipe.js @@ -11,5 +11,8 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); + ingredients:`); + +for (const element of recipe.ingredients) { + console.log(element); +} \ No newline at end of file diff --git a/week-2/implement/contains.js b/week-2/implement/contains.js index cd779308..55f89b14 100644 --- a/week-2/implement/contains.js +++ b/week-2/implement/contains.js @@ -1,3 +1,8 @@ -function contains() {} +function contains(obj, key) { + if (typeof obj === "object" && Object.hasOwnProperty.call(obj, key)) { + return true; + } + return false; +} module.exports = contains; diff --git a/week-2/implement/contains.test.js b/week-2/implement/contains.test.js index e75984b8..1a45a78d 100644 --- a/week-2/implement/contains.test.js +++ b/week-2/implement/contains.test.js @@ -17,18 +17,53 @@ as the object doesn't contains a key of 'c' // When passed an object and a property name // Then it should return true if the object contains the property, false otherwise +test("if the object contains the property turn true", () => { + expect(contains({ a : 1, b: 2 },'a')).toBe(true); +}); + + + +test("if the object doesn't contains the property turn false", () => { + expect(contains({ a: 1, b: 2 }, 'c')).toBe(false); +}); + + // Given an empty object // When passed to contains // Then it should return false +test("if the object is empty, turn false", () => { + expect(contains({ }, 'c')).toBe(false); +}); + // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("When passed to contains with an existing property name should turn true", () => { + expect(contains({ a: 1, b: 2 }, "a")).toBe(true); +}); + + + // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("When passed to contains with a non-existent property name, turn false", () => { + expect(contains({ a: 1, b: 2 }, "c")).toBe(false); +}); + + // Given invalid parameters like arrays // When passed to contains // Then it should return false or throw an error + +test("When passed to contains invalid parameters like arrays, turn false", () => { + expect(contains([], "c")).toBe(false); + expect(contains(2, "c")).toBe(false); + expect(contains(NaN, "c")).toBe(false); + expect(contains(true, "c")).toBe(false); + expect(contains(false, "c")).toBe(false); + expect(contains(undefined, "c")).toBe(false); +}); diff --git a/week-2/implement/lookup.js b/week-2/implement/lookup.js index d4677714..48ffa3dc 100644 --- a/week-2/implement/lookup.js +++ b/week-2/implement/lookup.js @@ -1,17 +1,11 @@ -function createLookup() { - // implementation here -} +function createLookup(countryCurrencyArray) { + const lookup = {}; -/* ======= Test suite is provided below... ===== - */ + for (let element of countryCurrencyArray) { + lookup[element[0]]= element[1]; + } + return lookup; +} -test("converts a single pair of currency codes", () => { - expect(createLookup([["GB", "GBP"]])).toEqual({ - GB: "GBP", - }); - expect(createLookup([["DE", "EUR"]])).toEqual({ - DE: "EUR", - }); -}); -test.todo("creates a country currency code lookup for multiple codes"); +module.exports = createLookup; diff --git a/week-2/implement/lookup.test.js b/week-2/implement/lookup.test.js index 8804cb65..6c14bffd 100644 --- a/week-2/implement/lookup.test.js +++ b/week-2/implement/lookup.test.js @@ -1,3 +1,5 @@ +const createLookup = require("./lookup.js"); + /* Create a lookup object of key value pairs from an array of code pairs @@ -29,3 +31,26 @@ It should return: 'CA': 'CAD' } */ + +test("converts a single pair of currency codes", () => { + expect(createLookup([["GB", "GBP"]])).toEqual({ + GB: "GBP", + }); + expect(createLookup([["DE", "EUR"]])).toEqual({ + DE: "EUR", + }); +}); + +test("converts multiple pairs of currency codes", () => { + expect( + createLookup([ + ["US", "USD"], + ["CA", "CAD"], + ["GB", "GBP"], + ]) + ).toEqual({ + US: "USD", + CA: "CAD", + GB: "GBP", + }); +}); \ No newline at end of file diff --git a/week-2/implement/tally.js b/week-2/implement/tally.js index e69de29b..21d10b03 100644 --- a/week-2/implement/tally.js +++ b/week-2/implement/tally.js @@ -0,0 +1,13 @@ +function tally(items) { + if (!Array.isArray(items)) { + throw new Error("Input must be an array"); + } + + const counts = {}; + for (let item of items) { + counts[item] = (counts[item] || 0) + 1; + } + return counts; +} + +module.exports= tally; diff --git a/week-2/implement/tally.test.js b/week-2/implement/tally.test.js index b473b750..cb503fec 100644 --- a/week-2/implement/tally.test.js +++ b/week-2/implement/tally.test.js @@ -1,3 +1,5 @@ +const tally = require("./tally.js") + /** * tally array * @@ -18,14 +20,30 @@ // When passed an array of items // Then it should return an object containing the count for each unique item +test("When passed to tally an array of items, return an object containing the count for each unique item", () => { + expect(tally(["a", "b", "c"])).toEqual({ a: 1, b: 1, c: 1 }); +}); + // Given an empty array // When passed to tally // Then it should return an empty object +test("When passed to tally an empty array, return an empty object", () => { + expect(tally([])).toEqual({}); +}); + // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test("When passed to tally an array with duplicate items, return counts for each unique item", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); +}); + // Given an invalid input like a string // When passed to tally // Then it should throw an error + +test("When passed an invalid input like a string to tally, it should throw an error", () => { + expect(() => { tally("invalid input");}).toThrow("Input must be an array"); +}) \ No newline at end of file diff --git a/week-2/interpret/invert.js b/week-2/interpret/invert.js index 00d27025..60b82b84 100644 --- a/week-2/interpret/invert.js +++ b/week-2/interpret/invert.js @@ -10,7 +10,7 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; @@ -18,10 +18,22 @@ function invert(obj) { // a) What is the current return value when invert is called with { a : 1 } +// key: 1; + // b) What is the current return value when invert is called with { a: 1, b: 2 } +// key: 1; key: 2; + // c) What is the target return value when invert is called with {a : 1, b: 2} +// "1": "a", "2": "b" + +console.log(invert({ a: 1, b: 2 })); + // c) What does Object.entries return? Why is it needed in this program? +// Returns an array of key/values of the enumerable properties of an object + // d) Explain why the current return value is different from the target output + +// he current return value is different from the target output due to a mistake in the way the invert function is assigning values to the invertedObj. \ No newline at end of file