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
6 changes: 5 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
// Predict and explain first...
// My prediction: the code will show an Error or "undefined", the Object is fine but
// called in a wrong way in the last line. we cant use object[number] to get a value
// withing an Object, that works only with arrays. Instead, we need to write
// the name of the key that we need.

// This code should log out the houseNumber from the address object
// but it isn't working...
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["houseNumber"]}`);
6 changes: 4 additions & 2 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// Predict and explain first...
// Prediction: the code will throw an error
// Explanation: An object can not be used or accessed as an array.

// 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
Expand All @@ -11,6 +13,6 @@ const author = {
alive: true,
};

for (const value of author) {
console.log(value);
for ( const key in author ) {
console.log(author[key]);
}
26 changes: 14 additions & 12 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// Predict and explain first...
// Predict and explain first...
// to separate the ingredients in different lines we need to use the function: join()
// the ingredients is an array not an object, so we can use join() and pass "\n" to put
// new line between every item.

// 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?
// 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?

const recipe = {
title: "bruschetta",
serves: 2,
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
};
const recipe = {
title: "bruschetta",
serves: 2,
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
};

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

if(typeof obj !== 'object' || !obj || Array.isArray(obj)) {
return false;
}
return obj.hasOwnProperty(find);
}

module.exports = contains;
29 changes: 28 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const contains = require("./contains.js");

/*
Implement a function called contains that checks an object contains a
particular property
particular property

E.g. contains({a: 1, b: 2}, 'a') // returns true
as the object contains a key of 'a'
Expand All @@ -16,20 +16,47 @@ 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
test.todo("contains on empty object returns false");
test("When the object contains the property return true, false otherwise", () => {
expect(contains({a: 1, b: 2, c: 3}, "a")).toBe(true);
expect(contains({a: 1, b: 2, c: 3}, "d")).toBe(false);
})

// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");
test("if contains on empty object returns false", () => {
expect(contains({}, "a")).toBe(false);
expect(contains({}, "Hello")).toBe(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test.todo("if contains on object with existing property returns true");
test("if contains on object with existing property returns true", () => {
expect(contains({m: 10, s: 20, w: 5}, "s")).toBe(true);
expect(contains({x: 100, y: 200, z: 300}, "z")).toBe(true);
expect(contains({name: "Ahmed", age: 30}, "name")).toBe(true);
});

// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test.todo("if contains on object with non-existent property returns false");
test("if contains on object with non-existent property returns false", () => {
expect(contains({m: 10, s: 20, w: 5}, "x")).toBe(false);
expect(contains({num1: 100, num2: 200, num3: 300}, "num5")).toBe(false);
expect(contains({name: "Ahmed", age: 30}, "address")).toBe(false);
});

// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test.todo("if contains with invalid parameters returns false or throws an error");
test("if contains with invalid parameters returns false or throws an error", () => {
expect(contains(['a','b','c'], "1")).toBe(false);
expect(contains("string", "a")).toBe(false);
expect(contains(12345, "a")).toBe(false);
});
12 changes: 9 additions & 3 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
function createLookup() {
// implementation here
}
function createLookup(arrayOfPairs) {
let obj = {};

for (let i = 0; i < arrayOfPairs.length; i++) {
const [key, value] = arrayOfPairs[i];
obj[key] = value;
}
return obj;
};

module.exports = createLookup;
10 changes: 9 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
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", () => {
expect(createLookup([['US', 'USD'], ['CA', 'CAD'], ['GB', 'GBP'], ['JP', 'JPY']])).toEqual({
'US': 'USD',
'CA': 'CAD',
'GB': 'GBP',
'JP': 'JPY'
});
});

/*

Expand All @@ -21,7 +29,7 @@ Then
- The values are the corresponding currency codes

Example
Given: [['US', 'USD'], ['CA', 'CAD']]
Given: [['US', 'USD'], ['CA', 'CAD']]

When
createLookup(countryCurrencyPairs) is called
Expand Down
23 changes: 16 additions & 7 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
function parseQueryString(queryString) {
const queryParams = {};
if (queryString.length === 0) {
return queryParams;
}
const keyValuePairs = queryString.split("&");
if (!queryString) return queryParams;

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

for (const pair of pairs) {
const eqIndex = pair.indexOf("=");

let key, value;
if (eqIndex === -1) {
key = decodeURIComponent(pair);
value = "";
} else {
key = decodeURIComponent(pair.slice(0, eqIndex));
value = decodeURIComponent(pair.slice(eqIndex + 1));
}

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
}

return queryParams;
}

module.exports = parseQueryString;
module.exports = parseQueryString;
30 changes: 29 additions & 1 deletion Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,38 @@
// 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",
});
});

test("parses empty querystring", () => {
expect(parseQueryString("")).toEqual({});
});

test("parses single key-value pair", () => {
expect(parseQueryString("name=John")).toEqual({
"name": "John",
});
});

test("parses key with empty value", () => {
expect(parseQueryString("key=")).toEqual({
"key": "",
});
});

test("parses empty key with value", () => {
expect(parseQueryString("=value")).toEqual({
"": "value",
});
});

test("parses key without '=' separator", () => {
expect(parseQueryString("key")).toEqual({
"key": "",
});
});
17 changes: 15 additions & 2 deletions Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
function tally() {}
function tally(arr) {
let obj = Object.create(null);
if (!Array.isArray(arr)) {
throw new Error("Input must be an array");
}

module.exports = tally;
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]])
obj[arr[i]] = 1;
else
obj[arr[i]]++;
}
return obj;
}

module.exports = tally;
22 changes: 22 additions & 0 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,38 @@ 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.todo("when passed an array of items, it returns an object with counts for each unique item");
test("when passed an array of items, it returns an object with counts for each unique item", () => {
const input = ['a', 'a', 'b', 'c'];
const expectedOutput = { a: 2, b: 1, c: 1 };
expect(tally(input)).toEqual(expectedOutput);
});

// 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("tally on an empty array returns an empty object", () => {
const input = [];
const expectedOutput = {};
expect(tally(input)).toEqual(expectedOutput);
});

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item
test.todo("tally counts each unique item in an array with duplicates");
test("tally counts each unique item in an array with duplicates", () => {
const input = ['x', 'y', 'x', 'z', 'y', 'x'];
const expectedOutput = { x: 3, y: 2, z: 1 };
expect(tally(input)).toEqual(expectedOutput);
});

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
test.todo("tally throws an error when passed invalid input");
test("tally throws an error when passed invalid input", () => {
const input = "invalid input";
expect(() => tally(input)).toThrow("Input must be an array");
});
12 changes: 11 additions & 1 deletion Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,30 @@ function invert(obj) {
const invertedObj = {};

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

return invertedObj;
}

// a) What is the current return value when invert is called with { 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 }
// 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 should be { '1': 'a', '2': 'b' }

// c) What does Object.entries return? Why is it needed in this program?
// it returns an array of a given object in [key, value] pairs.

// d) Explain why the current return value is different from the target output
// because in the loop, it always assigns the property 'key' to the value,
// so the final result only contains one property 'key' with the last value assigned in the loop.

// e) Fix the implementation of invert (and write tests to prove it's fixed!)
// Code fixed.

console.log(invert({ a: 1 })); // { '1': 'a' }
module.exports = invert;
9 changes: 9 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
test.todo("check if invert function swaps keys and values");
test("check if invert function swaps keys and values", () => {
const invert = require("./invert");

expect(invert({ a: 1 })).toEqual({ '1': 'a' });
expect(invert({ a: 1, b: 2 })).toEqual({ '1': 'a', '2': 'b' });
expect(invert({ x: 10, y: 20 })).toEqual({ '10': 'x', '20': 'y' });
expect(invert({})).toEqual({});
});
22 changes: 22 additions & 0 deletions Sprint-2/stretch/count-words.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,25 @@

3. Order the results to find out which word is the most common in the input
*/

function countWords(string) {
let outputObject = Object.create(null);
let splitString = string.split(" ");

for ( let i = 0; i < splitString.length; i++) {
let word = splitString[i].toLowerCase();
word = word.replace(/[.,!?]/g, '');

if (word.length != 0) {
if (!outputObject[word])
outputObject[word] = 1;
else
outputObject[word]++;
}
}

return outputObject;
}
console.log(countWords("Hello,World! Hello World!"));
console.log(countWords("constructor constructor"));
console.log(countWords(" Hello World "));