Skip to content
This repository was archived by the owner on Jan 3, 2023. It is now read-only.
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
144 changes: 114 additions & 30 deletions mandatory/1-writers.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
use values inside Objects.
*/



// We've created an array of objects for you here:

let writers = [
{
firstName: "Virginia",
Expand Down Expand Up @@ -55,9 +58,11 @@ let writers = [
occupation: "writer",
age: 49,
alive: true,
}
},
];



/*
Exercise 1:

Expand All @@ -66,9 +71,23 @@ Exercise 1:

"Hi, my name is {firstName} {lastName}. I am {age} years old, and work as a {occupation}."
*/



function logAllWriters() {
// write your code to log all writers here
};
writers.forEach((writer) => {
console.log(
`Hi, my name is ${writer.firstName} ${writer.lastName}. I am ${writer.age} years old, and work as a ${writer.occupation}.`
);
});
}

// Because we have an ***array of objects***, I have used .forEach to iterate over each array object.
// Inside the forEach there is a call back function that takes the array as a parameter (writers)
// and console.logs a concatenated string that prints the desired properties of the objects.




/*
Exercise 2:
Expand All @@ -79,10 +98,44 @@ Exercise 2:
"Writer {firstName} {lastName} died at {age} years old."
*/


function logDeadWritersInTheirForties() {
// write your code here
return writers.forEach((writer) => {
if (writer.age >= 40 && writer.age <= 49 && writer.alive === false) {
console.log(
`Writer ${writer.firstName} ${writer.lastName} died at ${writer.age} years old.`
);
}
});
}

// Here .forEach has been used again to iterate over each array object. A callback function taking the array
// a parameter has been used but this time uses an if-statement to console.log selected objects (writers)
// if they meet a certain condition. In this case we are checking the writers age and the value of one of
// the property "alive".

/* ALTERNATIVE SOLUTION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

writers.forEach(function ({ firstName, lastName, age, alive }) {
const isIn40s = 40 <= age && age <= 49;

if (!alive && isIn40s) console.log(`Writer ${firstName} ${lastName} died at ${age} years old.`);
});

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

In this solution, notice that we've stored the expression 40 <= age && age <= 49
in a variable called isIn40s. Sometimes well named variables will help improve the
readability and maintenance of your code base.

We also use the ! operator, called the logical NOT operator.
This will invert the value of a boolean, for example:

*/




/*
Exercise 3:

Expand All @@ -92,38 +145,69 @@ Exercise 3:
*/

function logAliveWritersInTheirForties() {
// write your code here
return writers.forEach((writer) => {
if (writer.age >= 40 && writer.age <= 49 && writer.alive === true) {
console.log(
`Hi, my name is ${writer.firstName} ${writer.lastName}. I am ${writer.age} years old.`
);
}
});
}

/* ======= TESTS - DO NOT MODIFY =====
/*

ALTERNATIVE SOLUTION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.

writers.forEach(function ({ firstName, lastName, age, alive }) {
const isIn40s = 40 <= age && age <= 49;

if (alive && isIn40s)
console.log(`Hi, my name is ${firstName} ${lastName}. I am ${age} years old.`);
});


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>









======= TESTS - DO NOT MODIFY =====
- To run the tests for this exercise, run `npm test -- --testPathPattern 1-writers.js`
- To run all exercises/tests in the mandatory folder, run `npm test`
- (Reminder: You must have run `npm install` one time before this will work!)
*/

test("exercise 1", () => expectFunctionToLog(logAllWriters, [
"Hi, my name is Virginia Woolf. I am 59 years old, and work as a writer.",
"Hi, my name is Zadie Smith. I am 40 years old, and work as a writer.",
"Hi, my name is Jane Austen. I am 41 years old, and work as a writer.",
"Hi, my name is Bell Hooks. I am 63 years old, and work as a writer.",
"Hi, my name is Yukiko Motoya. I am 49 years old, and work as a writer."
]));

test("exercise 2", () => expectFunctionToLog(logDeadWritersInTheirForties, [
"Writer Jane Austen died at 41 years old."
]));

test("exercise 3", () => expectFunctionToLog(logAliveWritersInTheirForties, [
"Hi, my name is Zadie Smith. I am 40 years old.",
"Hi, my name is Yukiko Motoya. I am 49 years old."
]));
test("exercise 1", () =>
expectFunctionToLog(logAllWriters, [
"Hi, my name is Virginia Woolf. I am 59 years old, and work as a writer.",
"Hi, my name is Zadie Smith. I am 40 years old, and work as a writer.",
"Hi, my name is Jane Austen. I am 41 years old, and work as a writer.",
"Hi, my name is Bell Hooks. I am 63 years old, and work as a writer.",
"Hi, my name is Yukiko Motoya. I am 49 years old, and work as a writer.",
]));

test("exercise 2", () =>
expectFunctionToLog(logDeadWritersInTheirForties, [
"Writer Jane Austen died at 41 years old.",
]));

test("exercise 3", () =>
expectFunctionToLog(logAliveWritersInTheirForties, [
"Hi, my name is Zadie Smith. I am 40 years old.",
"Hi, my name is Yukiko Motoya. I am 49 years old.",
]));

function expectFunctionToLog(f, values) {
const consoleLogSpy = jest.spyOn(console, 'log');
f();
expect(consoleLogSpy).toBeCalledTimes(values.length);
values.forEach((value, i) => {
expect(consoleLogSpy).nthCalledWith(i+1, value);
});
consoleLogSpy.mockRestore();
};
const consoleLogSpy = jest.spyOn(console, "log");
f();
expect(consoleLogSpy).toBeCalledTimes(values.length);
values.forEach((value, i) => {
expect(consoleLogSpy).nthCalledWith(i + 1, value);
});
consoleLogSpy.mockRestore();
}
33 changes: 30 additions & 3 deletions mandatory/10-cheap-diner.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@

The Frugal Gentleman

Atticus has been invited to a dinner party, and he decides to purchase a meal to share with he party
Being a very frugal gentleman (yet disliking looking like a cheapskate), he decides to use a very simple rule.
Atticus has been invited to a dinner party, and he decides to purchase a meal
to share with he party. Being a very frugal gentleman (yet disliking looking
like a cheapskate), he decides to use a very simple rule.

In any selection of two or more meals, he will always buy the second-cheapest.
If there is no choice, then he will buy the only meal given to him.
If there are no meals available, then he will return null

Given an array of Meal objects, write a function that returns the name of the Meal he will buy for the party. If given an array of only one, Atticus will buy that Meal.
Given an array of Meal objects, write a function that returns the name of the
Meal he will buy for the party. If given an array of only one, Atticus will buy that Meal.

let setOne = [
{ name: "Turkey", price: 8.99 },
{ name: "Chicken", price: 13.99 },
{ name: "Lobster", price: 10.99 }
]

chosenMeal(setOne)

Should give the answer "Lobster"
Expand All @@ -27,6 +30,30 @@ chosenMeal(emptyArray)

Should give the answer "Nothing :("

SOLUTION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


function chooseMeal(mealArray) {
mealArray.sort((mealA, mealB) => mealA.price - mealB.price);

const secondCheapestMeal = mealArray[1];
const cheapestMeal = mealArray[0];
const nothingAvailableMessage = 'Nothing :(';

if (secondCheapestMeal) return secondCheapestMeal.name;
else if (cheapestMeal) return cheapestMeal.name;
else return nothingAvailableMessage;
}

We can break down this solution into several parts:

Sort the array of meals into ascending order by price
Access the first and second positions in the array
(which should be the cheapest and second cheapest, respectively )
Check these elements and then return the names depending on whether the elements exist or not
Notice in our solution that we are passing a callback function to sort in order to specify
that we want to sort by the price property on each meal object.

**/

function chooseMeal(mealArray) {
Expand Down
57 changes: 56 additions & 1 deletion mandatory/11-choose-your-own-adventure.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,62 @@ room doesn't allow? For example if you are in the Classroom and you try to move
east? If there is a bug in your code, try to fix it.

To enable the tests for the stretch goals, remove the ".skip" on the appropriate tests below.
*/

******************************************************************************************/
//SOLUTION COPIED

let game = {
currentRoom: null,
start: function (roomName) {
// This function is called with the name of the room that the player wants
// to start in.
// Finish the function so that the currentRoom property is set to the room
// object for the correct room.
// Hint: the only valid rooms are "hall", "classroom" and "library".
if (roomName === "hall") {
this.currentRoom = rooms.hall;
} else if (roomName === "classroom") {
this.currentRoom = rooms.classroom;
} else if (roomName === "library") {
this.currentRoom = rooms.library;
}
},

move: function (direction) {
// This function is called with the direction that the player wants to move.
// Finish the function so that the currentRoom property is updated with new
// room in the direction that the player wants to move in.
//
// Hint: the room objects have north/east/south/west methods which return
// a new room object that is in the relevant direction.

if (direction === "north") {
this.currentRoom = this.currentRoom.north();
} else if (direction === "east") {
this.currentRoom = this.currentRoom.east();
} else if (direction === "south") {
this.currentRoom = this.currentRoom.south();
} else if (direction === "west") {
this.currentRoom = this.currentRoom.west();
}
},
};

/***************************************************************************************

The basic solution is to check the roomName to determine which room
object within the rooms object should be assigned to this.currentRoom.
So for example, if the player types "hall", it is passed to the start method
as the roomName parameter. We can then check whether it is "hall", "classroom"
or "library" and set this.currentRoom to be the appropriate object inside rooms.

The basic solution is to check the direction to determine which method to call on the
this.currentRoom object. When the player types in a direction, it is passed to the move
method as the direction parameter. We can then check if it is "north", "east", "south" or "west"
and call the appropriate method in the this.currentRoom object.
This returns the new room object and so we change this.currentRoom to be assigned to the new room object.

******************************************************************************************/

let game = {
currentRoom: null,
Expand Down
49 changes: 37 additions & 12 deletions mandatory/2-eligible-students.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,61 @@
After you complete the exercise, compare your solution to your previous one.
Can you see how using objects leads to more clear code?

-------------------------------------------------------------------------
**LAST WEEKS SOLUTION**

const getEligibleStudents =
arr => arr.filter((item => item[1] >= 8)).map(item => item[0]);

******************************************************************************************
Only students who have attended enough classes are eligible to sit an exam.

Create a function which:

- Accepts an array which contains all the students' names and their attendance counts
(see tests to confirm how this data will be structured)
- Returns an array containing only the names of the who have attended AT LEAST 8 classes
*/

******************************************************************************************/

function eligibleStudents(attendances) {

return attendances
.filter((student) => student.attendance >= 8)
.map((student) => student.name);
}

/******************************************************************************************

As we have an *array of objects* we can use the array method .filter
to filter out only the array values to return. The .filter method filters
the values but it does not return an array so we can chain the method .map to
return a new array containing only the student names of the filtered results.

My code is almost the same as last weeks, except rather than filtering nested
array values we are filtering object values. I'm unsure if this is any easier or
what the specific benefits are.

*******************************************************************************************/

/* ======= TESTS - DO NOT MODIFY =====
- To run the tests for this exercise, run `npm test -- --testPathPattern 2-eligible-students.js`
- To run all exercises/tests in the mandatory folder, run `npm test`
- (Reminder: You must have run `npm install` one time before this will work!)
*/

const attendances = [
{name: "Ahmed", attendance: 8},
{name: "Clement", attendance: 10},
{name: "Elamin", attendance: 6},
{name: "Adam", attendance: 7},
{name: "Tayoa", attendance: 11},
{name: "Nina", attendance: 10},
{ name: "Ahmed", attendance: 8 },
{ name: "Clement", attendance: 10 },
{ name: "Elamin", attendance: 6 },
{ name: "Adam", attendance: 7 },
{ name: "Tayoa", attendance: 11 },
{ name: "Nina", attendance: 10 },
];

test("eligibleStudents function works", () => {
expect(eligibleStudents(attendances)).toEqual(["Ahmed", "Clement", "Tayoa", "Nina"]);
expect(eligibleStudents(attendances)).toEqual([
"Ahmed",
"Clement",
"Tayoa",
"Nina",
]);
});

Loading