Functional Programming – Javascript Exercise
- Software design approaches and patterns, to identify reusable solutions to commonly occurring problems
- Apply an appropriate software development approach according to the relevant paradigm (for example object oriented, event driven or procedural)
- VSCode
- Node (version 18)
- Mocha testing library (version 5.2.0)
- Sinon (version 5.0.10)
- Mocha-sinon (version 2.1.0)
- Chai (version 4.1.2)
Apples
Create a new Javascript project, and add the following code to main.js
function pickApples(amount) {
let colourIndex = 1;
let poisonIndex = 7;
let priceInPenceIndex = 4;
const output = [];
for (let i = 0; i < amount; i++) {
output.push(new Apple(getColour(colourIndex), poisonIndex % 41 === 0, priceInPenceIndex % 51 + 1))
colourIndex += 5;
poisonIndex += 37;
priceInPenceIndex += 23;
}
return output
}
function getColour(colourIndex) {
if (colourIndex % 13 === 0 || colourIndex % 29 === 0) {
return "Green";
}
if (colourIndex % 11 === 0 || colourIndex % 19 === 0) {
return "Yellow";
}
return "Red";
}
class Apple {
constructor(colour, poisoned, priceInPence) {
this.colour = colour;
this.poisoned = poisoned;
this.priceInPence = priceInPence;
}
toString() {
return `${this.colour} apple priceInPence ${this.priceInPence}p${this.poisoned ? " (poisoned!)" : ""}`;
}
}
const apples = pickApples(10000);
Exercises
The above code generates a specified number of apples with different prices. Some of them have been poisoned. It is intentionally rather obtuse. Use both an anonymous function and an arrow function to answer the following questions about the first 10,000 apples:
- How many apples are poisoned?
- How many yellow apples are poisoned?
- If you pick a green apple, how many times will the next apple also be green?
- How much do all the green apples cost?
- What is the index of the last occurring red poisoned apple that costs 32 pence?
Revisit the above questions, and look to see how this code can be made reusable by replacing the inline anonymous/arrow functions with named functions.
A “Functional” Gilded Rose
There is an established refactoring exercise called The Gilded Rose. We have made a slightly custom version of the exercise for you to complete. The original version is here.
Firstly, fork and clone the starter repo here to your machine and follow the instructions in the README. Your task is to follow a functional approach for rewriting the code. The requirements for the Gilded Rose can be found in your repo in the file gilded_rose_requirements.md.
The repository includes a “golden master” test, which is a simple snapshot test to check that your refactor hasn’t broken anything. It also includes a simple example test that can be used as a pattern if you want to implement more targeted unit tests. The initial version of the example test has been written to fail, so you will need to fix that.
You can run the tests with npm test
.
Things you might want to consider improving:
- The structure of the Gilded Rose class is very OOP currently, how could we convert that to be fundamentally more functional?
- E.g. could we convert the
update_quality
function to be a “pure” function? - This may require changing the tests to follow the new pattern
- E.g. could we convert the
- Could we split up the handling of the
quality
&sell_in
properties to be separate? - Could we reduce (or even eliminate!) any “assignment” operations (
x = y
) where state is being handled? - Could we ensure that any remaining assignments only ever assign to
const
values? - Could we split the logic to be more readable?