Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
7 changes: 5 additions & 2 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// 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

// ==> this code is looping through an object and only return the key not the value.
// ==> After testing I found that (for of) does not loop directly in objects and it was throwing error "author is not iterable". In this case we should use (for in) to iterate.

const author = {
firstName: "Zadie",
lastName: "Smith",
Expand All @@ -11,6 +14,6 @@ const author = {
alive: true,
};

for (const value of author) {
console.log(value);
for (const value in author) {
console.log(author[value]);
}
8 changes: 6 additions & 2 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Predict and explain first...
// ==> this code is not correct as the ingredients act as string not an object key therefore we wont have the value.

// This program should log out the title, how many it serves and the ingredients.
// Each ingredient should be logged on a new line
// How can you fix it?
// ==> to fix the issue and print each ingredients in new line we need to loop through the array inside our recipe object.

const recipe = {
title: "bruschetta",
Expand All @@ -11,5 +13,7 @@ const recipe = {
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
ingredients:`);
for (let fruits of recipe.ingredients) {
console.log(fruits);
}
17 changes: 16 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
function contains() {}
// start your function

function contains(object, key) {
if (Array.isArray(object) && Object.keys(object).length === 0) {
return false;
} else if (object.hasOwnProperty(key)) {
return true;
} else return false;
}

let key = "name";
const object = {
name: "Roman",
age: 33,
city: "Birmingham",
};

module.exports = contains;
34 changes: 32 additions & 2 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,51 @@ as the object doesn't contains a key of 'c'

// Given a contains function
// When passed an object and a property name
// Then it should return true if the object contains the property, false otherwise
// Then it should return true if the object contains the property,
test("It return true when the object contains the property", () => {
let object = { name: "Roman", age: 34 };
let key = "name";
expect(contains(object, key)).toEqual(true);
});
// object does not contain the property
test("It return false when the object does not contains the property", () => {
let object = { name: "Roman", age: 34 };
let key = "lastName";
expect(contains(object, key)).toEqual(false);
});

// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");
test("It return false when the object has not any property", () => {
let object = {};
let key = "name";
expect(contains(object, key)).toEqual(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test("It returns true when the object has the specified property", () => {
const object = { name: "Roman", age: 34, city: "Birmingham" };
const key = "name";
expect(contains(object, key)).toEqual(true);
});

// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test("It returns false when the object does NOT have the specified property", () => {
const object = { name: "Roman", age: 34, city: "Birmingham" };
const key = "lastName";
expect(contains(object, key)).toEqual(false);
});

// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("It return false when an array is passed instead of object", () => {
let object = [1, 2, 3];
let key = "name";
expect(contains(object, key)).toEqual(false);
});
16 changes: 13 additions & 3 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
function createLookup() {
// implementation here
// start your function;
function createLookup(input) {
let output = {};
for (let pair of input) {
let key = pair[0];
let value = pair[1];
output[key] = value;
}
return output;
}

let input = [
["US", "USD"],
["CA", "CAD"],
];
module.exports = createLookup;
18 changes: 15 additions & 3 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
const createLookup = require("./lookup.js");

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

/*

Create a lookup object of key value pairs from an array of code pairs

Acceptance Criteria:
Expand Down Expand Up @@ -33,3 +31,17 @@ It should return:
'CA': 'CAD'
}
*/

test("creates a country currency code lookup for multiple codes", () => {
const input = [
["US", "USD"],
["CA", "CAD"],
];

const expected = {
US: "USD",
CA: "CAD",
};

expect(createLookup(input)).toEqual(expected);
});
20 changes: 14 additions & 6 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
// start your function;
function parseQueryString(queryString) {
const queryParams = {};
if (queryString.length === 0) {
return queryParams;
}
const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
// URLSearchParams is a built-in JavaScript object that can read query strings.
const params = new URLSearchParams(queryString); // params stores the query string internally as key-value pairs.
for (let pair of params) {
let key = pair[0];
let value = pair[1];
queryParams[key] = value.replace(/ /g, "+");
}

return queryParams;
}
let queryString = "equation=x=y+1";

module.exports = parseQueryString;

// Notice: ===> URLSearchParams is a class, not a plain function.
// Classes in JS must be called with new.
// new URLSearchParams(...) → creates a new instance (object) of the class.
// That instance knows how to store and iterate key-value pairs.
// URLSearchParams decodes URL-encoded characters, and in query strings, a + represents a space. and this is why we need .replace(/ /g, "+");
4 changes: 2 additions & 2 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// Below is one test case for an edge case the implementation doesn't handle well.
// Fix the implementation for this test, and try to think of as many other edge cases as possible - write tests and fix those too.

const parseQueryString = require("./querystring.js")
const parseQueryString = require("./querystring.js");

test("parses querystring values containing =", () => {
expect(parseQueryString("equation=x=y+1")).toEqual({
"equation": "x=y+1",
equation: "x=y+1",
});
});
16 changes: 14 additions & 2 deletions Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
function tally() {}

function tally(arr) {
let output = {};
if (!Array.isArray(arr)) {
throw new Error("Invalid input");
} else if (arr.length === 0) {
return output;
}
for (let item of arr) {
let count = arr.filter((x) => x === item).length;
output[item] = count;
}
return output;
}
let arr = ["a", "b"];
module.exports = tally;
18 changes: 16 additions & 2 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,30 @@ const tally = require("./tally.js");
// Given a function called tally
// When passed an array of items
// Then it should return an object containing the count for each unique item
test("returns count 1 for a single item", () => {
const arr = ["a"];
expect(tally(arr)).toEqual({ a: 1 });
});

// Given an empty array
// When passed to tally
// Then it should return an empty object
test.todo("tally on an empty array returns an empty object");
test("returns an empty object when given an empty array", () => {
const arr = [];
expect(tally(arr)).toEqual({});
});

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item

test("returns counts for each unique item for given duplicate items ", () => {
const arr = ["a", "a", "b", "c"];
expect(tally(arr)).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("it throw an error if given a string", () => {
const str = "a";
expect(() => tally(str)).toThrowError();
});
11 changes: 9 additions & 2 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,27 @@ function invert(obj) {
const invertedObj = {};

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

return invertedObj;
}

obj = { a: 1, b: 2 };
module.exports = invert;
// a) What is the current return value when invert is called with { a : 1 }
// answer ===> the output will be {"key": 1}

// b) What is the current return value when invert is called with { a: 1, b: 2 }
// answer ===> the output ll be {"key": 2}

// c) What is the target return value when invert is called with {a : 1, b: 2}
// answer ===> the output ll be {"1": "a", "2": "b"};

// c) What does Object.entries return? Why is it needed in this program?
// answer ===> converts an object into an array of key-value pairs, we need it to loop through and access the elements.

// d) Explain why the current return value is different from the target output
// answer ===> because of this line --> invertedObj.key = value; as it creates a "key" and assign the value to it. and with variables we need to use bracket notation not dot notation.

// e) Fix the implementation of invert (and write tests to prove it's fixed!)
// I have fixed the implementation: from invertedObj.key = value to invertedObj[value] = key;
13 changes: 13 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const invert = require("./invert.js");
// testing time
test("Empty object returns empty object", () => {
expect(invert({})).toEqual({});
});

test("Single key-value pair", () => {
expect(invert({ a: 1 })).toEqual({ 1: "a" });
});

test("Given an object, then it should swap the keys and values in the object", () => {
expect(invert({ x: 10, y: 20 })).toEqual({ 10: "x", 20: "y" });
});
2 changes: 2 additions & 0 deletions Sprint-2/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions Sprint-2/stretch/count-words.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

countWords("you and me and you") then the target output is { you: 2, and: 2, me: 1 }



To complete this exercise you should understand
- Strings and string manipulation
- Loops
Expand All @@ -26,3 +28,16 @@

3. Order the results to find out which word is the most common in the input
*/
function countWords(str) {
let cleanStr = str.split(" ");
let objWords = {};
for (let word of cleanStr) {
if (word !== "") continue;
if (objWords[word]) {
objWords[word]++;
} else {
objWords[word] = 1;
}
}
return objWords;
}
31 changes: 16 additions & 15 deletions Sprint-2/stretch/mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,29 @@
// into smaller functions using the stages above

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

// Stage 1: Count frequencies
let freqs = {};
for (let num of list) {
if (typeof num !== "number") {
continue;
}
if (typeof num !== "number") continue; // skip non-number values

freqs.set(num, (freqs.get(num) || 0) + 1);
if (freqs[num] === undefined) {
freqs[num] = 1;
} else {
freqs[num] += 1;
}
}

// Find the value with the highest frequency
// Stage 2: Find the value with the highest frequency
let maxFreq = 0;
let mode;
for (let [num, freq] of freqs) {
if (freq > maxFreq) {
mode = num;
maxFreq = freq;
let mode = null;

for (let num in freqs) {
if (freqs[num] > maxFreq) {
maxFreq = freqs[num];
mode = Number(num); // convert string key to number
}
}

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

module.exports = calculateMode;
Loading
Loading