Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// This code should log out the houseNumber from the address object
// but it isn't working...
// Fix anything that isn't working
function postalAddress(postcode){
const address = address.postcode
return address
}

const address = {
houseNumber: 42,
Expand All @@ -12,4 +16,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.postcode}`);
7 changes: 4 additions & 3 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const author = {
age: 40,
alive: true,
};
console.log(author)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works (for displaying the properties) to certain extent.

However, I think the objective of this exercise is to practice how to iterate through all the property values of an object. Can you figure out how to use a loop to accomplish that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it


for (const value of author) {
console.log(value);
}
// for (const value of author) {
// console.log(author);
// }
2 changes: 1 addition & 1 deletion Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ const recipe = {

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
${recipe.ingredients.join("\n")}`);
10 changes: 8 additions & 2 deletions Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
function contains() {}

function contains(object, properityValue){
if (typeof object !== 'object' || object === null || Array.isArray(object)) {
return false;
}

return properityValue in object;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion
Consider the following two approaches for determining if an object contains a property:

  let obj = {}, propertyName = "toString";
  console.log( propertyName in obj );                // true
  console.log( Object.hasOwn(obj, propertyName) );   // false

Which of these approaches suits your needs better?
For more info, you can look up JS "in" operator vs Object.hasOwn.


}
module.exports = contains;
23 changes: 22 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,37 @@ as the object doesn't contains a key of 'c'
// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");

test("contains an empty object returns false", () => {
const input = {};
const result = contains(input, 'a');
expect(result).toBe(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test("contains an object with existing property returns true", () => {
const input = { a: 1, b: 2, c: 3 };
const result = contains(input, 'b');
expect(result).toBe(true);
})

// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false

test("contains an object with non-existent property returns false", () => {
const input = { x: 10, y: 20, z: 30 };
const result = contains(input, 'a');
expect(result).toBe(false);
})
// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error

test("contains with invalid parameters returns false", () => {
const input = [1, 2, 3];
const result = contains(input, '0');
expect(result).toBe(false);
})
4 changes: 3 additions & 1 deletion Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
function createLookup() {
function createLookup(pairsArray) {
// implementation here
const lookup = Object.fromEntries(pairsArray);
return lookup;
}

module.exports = createLookup;
17 changes: 16 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
const createLookup = require("./lookup.js");

test.todo("creates a country currency code lookup for multiple codes");


test("creates a country currency code lookup for multiple codes", () => {
const input = [["UK","Pound"], ["EU", "Euro"], ["Kenya", "Ksh"], ["Norway", "NK"], ["Eritrea", "ENKF"], ["USA", "USD"], ["Japan", "JPY"]];
const result = createLookup(input);
expect(result).toEqual({
'UK': 'Pound',
'EU': 'Euro',
'Kenya': 'Ksh',
'Norway': 'NK',
'Eritrea': 'ENKF',
'USA': 'USD',
'Japan': 'JPY'
})
});


/*

Expand Down
17 changes: 12 additions & 5 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
function parseQueryString(queryString) {

const queryParams = {};
if (queryString.length === 0) {
return queryParams;
}
if (!queryString) return queryParams;

const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
const index = pair.indexOf("=");
if (index === -1) {
queryParams[pair] = undefined;
} else {
const key = pair.slice(0, index);
const value = pair.slice(index + 1);
queryParams[key] = value;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that in real querystring, both key and value are percent-encoded or URL encoded in the URL. For example, the string "5%" will be encoded as "5%25". So to get the actual value of "5%25" (whether it is a key or value in the querystring), you should call a function to decode it.
May I suggest looking up any of these terms, and "How to decode URL encoded string in JS"?

}

return queryParams;
}

module.exports = parseQueryString;

4 changes: 4 additions & 0 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ test("parses querystring values containing =", () => {
"equation": "x=y+1",
});
});

test ("parses empty querystring", () => {
expect(parseQueryString("")).toEqual({});
});
13 changes: 12 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
function tally() {}
function tally(input) {
if (!Array.isArray(input)) {
throw new Error("Input must be an array");
}

const counts = {};
for (let item of input) {
counts[item] = (counts[item] || 0) + 1;
}

return counts;
}
Comment on lines 1 to 12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the following function call returns the value you expect?

tally(["toString", "toString"]);

Suggestion: Look up an approach to create an empty object with no inherited properties.


module.exports = tally;
17 changes: 17 additions & 0 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,28 @@ const tally = require("./tally.js");
// When passed to tally
// Then it should return an empty object
test.todo("tally on an empty array returns an empty object");
test("tally on an empty array returns an empty object", () => {
const input = [];
const result = tally(input);
expect(result).toEqual({});
});

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item
test("tally on an array with duplicate items returns correct counts", () => {
const input = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const result = tally(input);
expect(result).toEqual({apple: 3, banana: 2, orange: 1});
});

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error

test("tally with invalid input throws an error", () => {
const input = "not an array";
expect(() => {
tally(input);
}).toThrow("Input must be an array");
});
29 changes: 28 additions & 1 deletion Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,40 @@ function invert(obj) {
}

// a) What is the current return value when invert is called with { a : 1 }
console.log(invert({ a: 1 }));
// The current return value is { key: 1 }


// b) What is the current return value when invert is called with { a: 1, b: 2 }
console.log(invert({ a: 1, b: 2 }));
// The current return value is { key: 2 }


// c) What is the target return value when invert is called with {a : 1, b: 2}
// The target return value is { "1": "a", "2": "b" }

// c) What is the target return value when invert is called with {a : 1, b: 2}

// c) What does Object.entries return? Why is it needed in this program?
// Object.entries returns an array of a key, value pairs, and also an object to array of arrays
// It is needed in this program to access and iterate over the key value pairs of the object,allowing us to process both the property names and their corresponding values.


// d) Explain why the current return value is different from the target output
/*The current return value is different from the target output
because in line 13 the invertedObj.key is assigning the string "key" as a property name, Not the actual value of the key variable.*/


// e) Fix the implementation of invert (and write tests to prove it's fixed!)
function invert(obj) {
const invertedObj = {};

for (const [key, value] of Object.entries(obj)) {
invertedObj[value] = key;
}

return invertedObj;
}

// Tests
console.log(invert({ a: 1 }));
console.log(invert({ a: 1, b: 2 }));
17 changes: 17 additions & 0 deletions Sprint-2/stretch/count-words.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,20 @@

3. Order the results to find out which word is the most common in the input
*/
function countWords(input) {

const wordCounts = {};
const words = input.split(/\s+/);

for (let word of words) {

const cleanedWord = word.replace(/[.,!?;:()"]/g, '').toLowerCase();
if (cleanedWord) {
wordCounts[cleanedWord] = (wordCounts[cleanedWord] || 0) + 1;
}
}

return wordCounts;
}
console.log(countWords("Hello, hello, World, feed him or keep him world! Hello."));
console.log(countWords("You and me and you and Me again."));
27 changes: 16 additions & 11 deletions Sprint-2/stretch/mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,34 @@
// refactor calculateMode by splitting up the code
// into smaller functions using the stages above

function calculateMode(list) {
// track frequency of each value
let freqs = new Map();

for (let num of list) {
if (typeof num !== "number") {
continue;
function getFrequencies(list) {
// Track frequency of each value
const freqs = new Map();
for (const num of list) {
if (typeof num === "number") {
freqs.set(num, (freqs.get(num) || 0) + 1);
}

freqs.set(num, (freqs.get(num) || 0) + 1);
}
return freqs;
}

function findHighestFrequency(freqs) {
// Find the value with the highest frequency
let maxFreq = 0;
let mode;
for (let [num, freq] of freqs) {
for (const [num, freq] of freqs) {
if (freq > maxFreq) {
mode = num;
maxFreq = freq;
}
}

return maxFreq === 0 ? NaN : mode;
}

function calculateMode(list) {
// Combine both stages
const freqs = getFrequencies(list);
return findHighestFrequency(freqs);
}

module.exports = calculateMode;
1 change: 1 addition & 0 deletions Sprint-2/stretch/mode.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// testing the mode.js
const calculateMode = require("./mode.js");

// Acceptance criteria for calculateMode function
Expand Down
16 changes: 13 additions & 3 deletions Sprint-2/stretch/till.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ function totalTill(till) {
let total = 0;

for (const [coin, quantity] of Object.entries(till)) {
total += coin * quantity;
const numericCoin = parseInt(coin.replace('p', ''));
total += numericCoin * quantity;

}

return `£${total / 100}`;
Expand All @@ -23,9 +25,17 @@ const till = {
const totalAmount = totalTill(till);

// a) What is the target output when totalTill is called with the till object
// Target output: £4.10

// b) Why do we need to use Object.entries inside the for...of loop in this function?
// b) Why do we need to use Object.entries inside the for...of loop in this function?
// We use Object.entries to convert the till object into an array of [key, value] pairs, allowing us to iterate over each coin type and its corresponding quantity easily.

// c) What does coin * quantity evaluate to inside the for...of loop?
// Inside the for...of loop, coin * quantity evaluates to NaN (Not a Number) because coin is a string (e.g., "1p") and multiplying a string by a number results in NaN.

// d) Write a test for this function to check it works and then fix the implementation of totalTill


// d) Write a test for this function to check it works and then fix the implementation of totalTill
// Tests
console.log(totalTill(till));
console.log(totalTill({ "2p": 5, "10p": 3 }));