Skip to content

London | May-2025 | Ikenna Agulobi | Data Groups | sprint-2 #642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
dd81331
Stop tracking prep-for-data-groups-module folder
ike-agu Jul 15, 2025
0b1ba9a
Stop tracking prep-for-data-groups-module folder
ike-agu Jul 15, 2025
2a5622c
Add prep-for-data-groups-module to .gitignore
ike-agu Jul 15, 2025
d139960
Update .gitignore to ignore prep-for-data-groups-module folder
ike-agu Jul 15, 2025
bd94341
fixed address object
ike-agu Jul 15, 2025
4404e06
fixed the author object in author.js
ike-agu Jul 15, 2025
4e6e1fd
fixed the recipe object in recipe.js
ike-agu Jul 15, 2025
99926ba
implemented contains function and test cases to return true if obvjec…
ike-agu Jul 15, 2025
83f6a17
fixed contains function to throw an error if invalid parameters are p…
ike-agu Jul 15, 2025
7e8f294
added descriptive comments for future reference
ike-agu Jul 15, 2025
9e7e414
created a create look up function and a test case multiple country co…
ike-agu Jul 15, 2025
b4ae8c6
added test case to return empty object if emty array is given
ike-agu Jul 15, 2025
8259a3d
added descriptive comment for my future reference
ike-agu Jul 15, 2025
60c733a
fixed parseQueryString function to work as expected and pass first test
ike-agu Jul 16, 2025
8cc240c
fixed parse query function to throw new error for type of query strin…
ike-agu Jul 16, 2025
7b8a20b
Implemented tally function and completed test cases
ike-agu Jul 17, 2025
f3943f1
Added comments to my code for my future reference
ike-agu Jul 17, 2025
117b5c0
fixed the invert function to work as expected. Made comments to answe…
ike-agu Jul 17, 2025
2b8644e
added test for function to return the inverted object
ike-agu Jul 17, 2025
8f9a3f1
fixed the invert function to throw error incase the input is invalid.…
ike-agu Jul 17, 2025
f52d229
added test case to valid when invaklid inputs are passed to contains
ike-agu Jul 17, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules
.vscode
**/.DS_Store
.idea
prep-for-data-groups-module/
3 changes: 2 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Predict and explain first...
// The output will be undefined because we don't access object properties by index.

// This code should log out the houseNumber from the address object
// but it isn't working...
Expand All @@ -12,4 +13,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
3 changes: 2 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Predict and explain first...
// The code will print an error because in JS we cannot iterate directly on author object. To access the values of author we need to use Object.values() method.

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

for (const value of author) {
for (const value of Object.values(author)) {
console.log(value);
}
7 changes: 5 additions & 2 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Predict and explain first...
//In this code, recipe.title and recipe.serves will execute as expected but ingredients: recipe will not execute as expected because we are printing out the entire recipe object. Instead What we want to do is log each ingredient on a new line.

// This program should log out the title, how many it serves and the ingredients.
// Each ingredient should be logged on a new line
Expand All @@ -11,5 +12,7 @@ const recipe = {
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
ingredients:`);
for(const ingredient of recipe.ingredients){
console.log(`- ${ingredient}`)
}
23 changes: 22 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
function contains() {}
function contains(obj, property) {
//throw error if parameters are invalid
if (typeof obj !== "object" || Array.isArray(obj) || obj === null) {
return false;
}

//return false if object is empty
if (Object.keys(obj).length === 0) {
return false;
}
//check that the obj contains a property, and the property is not inherited.
//N:B Object.hasOwn() strictly check for own properties and not inherited ones.
if (Object.hasOwn(obj, property)) {
return true;
} else {
return false;
}
}

// console.log(contains({ a: 1, b: 2 }, "a"));
// console.log(contains({ a: 1, b: 2 }, "c"));
console.log(contains([], "c")); // console.log(contains({}, "c"))

module.exports = contains;
27 changes: 23 additions & 4 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const contains = require("./contains.js");
const contains = require("./contains");

/*
Implement a function called contains that checks an object contains a
Expand All @@ -16,20 +16,39 @@ 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("Given an object and a property name, should return true if object contains the property otherwise false", () => {
const obj = { a: 1, b: 2 };
const property = "a";
expect(contains(obj, property)).toEqual(true);
});
// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");

test("contains should returns false for an empty object", () => {
expect(contains({}, "a")).toEqual(false);
});

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

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

test("When object passed to contains with non existent property name, should return false", () => {
const obj = { a: 1, b: " " };
const property = " ";
expect(contains(obj, property)).toEqual(false);
});
// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("When invalid parameters like array are passed to contains, should return false or throw error", () => {
expect(contains([], 'c')).toEqual(false);
});
10 changes: 8 additions & 2 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(countryCodes) {
const countryCodeAndCurrency = {};
//Iterating over the array to access the inner arrays
for(const item of countryCodes){
countryCodeAndCurrency[item[0]] = item[1]
}
return countryCodeAndCurrency;
}
console.log(createLookup([["US", "USD"],["CA", "CAD"]]));

module.exports = createLookup;
15 changes: 14 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
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 countryCodeAndCurrency = [["US", "USD"],["CA", "CAD"]];
const expectedReturn = {US: "USD",CA: "CAD"};
const lookupFunction = createLookup(countryCodeAndCurrency);
expect(lookupFunction).toEqual(expectedReturn);
});

//should return an empty object when given an empty array
test("should return an empty object when given an empty array", () => {
const emptyArray = [];
const lookupFunction = createLookup(emptyArray);
expect(lookupFunction).toEqual({});
});


/*

Expand Down
17 changes: 15 additions & 2 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
function parseQueryString(queryString) {
const queryParams = {};

if (typeof queryString !== "string") {
throw new Error("Your input is not valid");
}

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

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

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
//get the indexof the first occurrence of "="
const index = pair.indexOf("=");
//slice the first part and store in a variable
const slicedFirstPart = pair.slice(0, index)
//get the second part and store in a variable
const slicedSecondPart = pair.slice(index + 1);
//then add it to the queryParams object
queryParams[slicedFirstPart] = slicedSecondPart;

}

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



test(" when invalid strings are passed, should throw an error", () => {
expect(() => parseQueryString(123)).toThrow("Your input is not valid");
expect(() => parseQueryString({})).toThrow("Your input is not valid");
expect(() => parseQueryString([])).toThrow("Your input is not valid");
});

// When empty strings are passed, should return empty object

test("When empty strings are passed, should return empty object", () => {
expect(parseQueryString("")).toEqual({});
});
33 changes: 31 additions & 2 deletions Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
function tally() {}

function tally(list) {
const countItem = {};
//Throw new error if type is not array
if (!Array.isArray(list)) {
throw new Error("Your input is invalid!");
}
//return empty object if array is empty
if(list.length === 0){
return {}
}
//Loop through the array and count how many times each item occurs.
for (let i = 0; i < list.length; i++) {
let currentItem = list[i];
//if the current item exist, increment its count by 1.
if (countItem[currentItem]) {
countItem[currentItem] + 1;
} else {
//Otherwise initial its count by 1
countItem[currentItem] = 1;
}
}
return countItem;
}
// // let call1 = tally("");
// let call2 = tally(["a", "a", "b", "c"]);
// let call3 = tally(["a", "a", "a", "b", "z", "z"]);
// let call4 = tally([]);
// // console.log(call1);
// console.log(call2);
// console.log(call3);
// console.log(call4);
module.exports = tally;
14 changes: 13 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,28 @@ 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("When passed an array of items, returns an object containing the count for each unique item", () => {
expect(tally(["a"])).toEqual({ a: 1 });
expect(tally(["a", "a", "a"])).toEqual({ a: 3 });
});

// 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",() => {
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 an array with duplicate items, returns count 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 invalid input like string, throw an error ", () => {
expect(() => tally("")).toThrow("Your input is invalid!");
});
23 changes: 17 additions & 6 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,32 @@
function invert(obj) {
const invertedObj = {};

if(typeof obj !== "object" || Array.isArray(obj)){
throw new Error("Your input is invalid!")
}

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 }
// let call1 = invert([]);
// let call2 = invert({ a: 1, b: 2});
// console.log(call1)
// console.log(call2)

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

module.exports = invert;
// a) What is the current return value when invert is called with { a : 1 }
// The return value is { key: 1 }
// b) What is the current return value when invert is called with { a: 1, b: 2 }
// The 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 does Object.entries return? Why is it needed in this program?

// Object.entries returns an array of key/value pairs of the same object and each pair is also an array with two elements(key and value). We need it in this program so that it will enable us to loop through the array and invert the items.
// d) Explain why the current return value is different from the target output

//The current return value is different from the target output because the code uses .key instead of [key]. Given that we are using .key, it gets interpreted as a property literal called "key" and not the value stored in the variable key. This causes the invert object to only have a single key called "key". To fix it and get the desired output, we need to use [key] so that the value it's storing can be use as property name when creating the new object.
// e) Fix the implementation of invert (and write tests to prove it's fixed!)
24 changes: 24 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// const invert = require("./invert.js")
const invert = require("./invert.js");


//Given a function invert
// When passed an object and a property name
// Then it should return the inverted object
test("", () => {
expect(invert({ a: 1 })).toEqual({ '1': 'a' });
});

// Given an empty object
// When passed to invert
// Then it should return an empty object
test("When passed an empty object to invert, should return an empty object", () => {
expect(invert({})).toEqual({});
});

// Given an invalid input,
// When passed to invert
// Then it should throw an error
test("When invalid input, throw an error ", () => {
expect(() => invert("")).toThrow("Your input is invalid!");
});