Functional Programming – Python 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)
Apples Exercises
Create a new python project using the following code:
from enum import Enum
import datetime
class Colour(Enum):
RED = "Red"
YELLOW = "Yellow"
GREEN = "Green"
class Apple:
def __init__(self, colour, date_picked, best_before):
self.colour = colour
self.date_picked = date_picked
self.best_before = best_before
apples = [Apple(Colour.RED, datetime.datetime(2023, 3, 8), datetime.datetime(2023, 5, 4)),
Apple(Colour.RED, datetime.datetime(2023, 2, 10), datetime.datetime(2023, 6, 20)),
Apple(Colour.RED, datetime.datetime(2023, 1, 7), datetime.datetime(2023, 4, 18)),
Apple(Colour.YELLOW, datetime.datetime(2023, 3, 25), datetime.datetime(2023, 5, 11)),
Apple(Colour.YELLOW, datetime.datetime(2023, 2, 23), datetime.datetime(2023, 4, 16)),
Apple(Colour.GREEN, datetime.datetime(2023, 2, 12), datetime.datetime(2023, 3, 7)),
Apple(Colour.GREEN, datetime.datetime(2023, 2, 9), datetime.datetime(2023, 5, 9)),
Apple(Colour.GREEN, datetime.datetime(2023, 3, 1), datetime.datetime(2023, 4, 10))]
print(apples)
List comprehension
Start by printing the list of apples. As you can see, it prints information about each apple such as object location. For the purposes of this exercise, we would like to see more detail about the apples themselves.
To do so let’s create a new method on the apple class:
- Create a new function inside the apple class called
get_summary
- Make it return
"Colour: {self.colour}, Date picked: {self.date_picked}, Best before: {self.best_before}"
- Iterate over all
apples
and printget_summary
for each apple. - Extract this to a function called
print_apple_summary
.
Now we have the ability to print a nicely formatted list of apples.
Lambda functions
- Print a new list of apples sorted by their best before date
- Print a new list of apples that are green
- Print a new list of apples picked in February
- Print a new list of red apples that are picked in February
- Print a new list of apples containing only apples where the colour contains the letter “e”
List comprehension
- If your initial
get_summary
function used afor
loop, update this function to use list comprehension. - Using list comprehension, print a new list of apples if the apple was picked on a Wednesday
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 poetry run pytest
.
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 split the logic to be more readable?