Skip to content
Draft
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
40 changes: 40 additions & 0 deletions sprint-5/01-predict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
def half(value):
return value / 2

def double(value):
return value * 2

def second(value):
return value[1]

# 1. Predict what you think will happen with each of the following functions
# 2. Then, test it, and explain in your own words what is actually happening and why
# (feel free to comment out lines if you think they cause errors or crashes while testing)

print(half(22))
# Prediction:
# What actually happens and why:

print(half("22"))
# Prediction:
# What actually happens and why:

print(double(22))
# Prediction:
# What actually happens and why:

print(double("22"))
# Prediction:
# What actually happens and why:

print(second(22))
# Prediction:
# What actually happens and why:

print(second(0x16))
# Prediction:
# What actually happens and why:

print(second("22"))
# Prediction:
# What actually happens and why:
27 changes: 27 additions & 0 deletions sprint-5/02-playcomputer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import process from "node:process";
import readline from "node:readline";

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

rl.question("What URL should we fetch?\n> ", async (url) => {
const response = await fetch(url);
if (!response.ok) {
if (response.body.toLowerCase().includes("permission")) {
console.error("You didn't have permission to get that URL");
} else {
console.error(`The request failed - body: ${response.body}`);
}
process.exit(1);
}

const contents = await response.json();

console.log(contents);

rl.close();
});

// Task: Leave a comment on any line that you can see has some errors explaining what you think the problem is
9 changes: 9 additions & 0 deletions sprint-5/03-fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
def double(number):
return number * 3

print(double(10))

# Task:
# What is the bug here?
# How could you fix it?
# Are there multiple possible ways to fix it?
39 changes: 39 additions & 0 deletions sprint-5/04-addmypy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
def open_account(balances, name, amount):
balances[name] = amount

def sum_balances(accounts):
total = 0
for name, pence in accounts.items():
print(f"{name} had balance {pence}")
total += pence
return total

def format_pence_as_string(total_pence):
if total_pence < 100:
return f"{total_pence}p"
pounds = int(total_pence / 100)
pence = total_pence % 100
return f"£{pounds}.{pence:02d}"

balances = {
"Sima": 700,
"Linn": 545,
"Georg": 831,
}

open_account("Tobi", 9.13)
open_account("Olya", "£7.13")

total_pence = sum_balances(balances)
total_string = format_pence_as_str(total_pence)

print(f"The bank accounts total {total_string}")

# TASK
# This code contains bugs related to types. They are bugs mypy can catch.
#
# 1. Read this code to understand what it's trying to do.
# 2. Install and set up mypy in a python virtual environment
# 3. Add type annotations everywhere appropriate
# 4. Run `mypy 04-addmypy.py`, and fix any errors
# 5. When you're confident all of the type annotations are correct, and the bugs are fixed, run the code and check it works.
20 changes: 20 additions & 0 deletions sprint-5/05-predict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
imran = {
"name": "Imran",
"age": 22,
"preferred_operating_system": "Ubuntu",
}

eliza = {
"name": "Eliza",
"age": 34,
"preferred_operating_system": "Arch Linux",
}


print(imran["name"])
print(imran["address"])

# Task:
# Try running mypy on this file and see what happens
# Predict what do you think will happen when you run this task?
# Can you explain what actualy happens?
28 changes: 28 additions & 0 deletions sprint-5/06-classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Person:
def __init__(self, name: str, age: int, preferred_operating_system: str):
self.name = name
self.age = age
self.preferred_operating_system = preferred_operating_system

imran = Person("Imran", 22, "Ubuntu")
print(imran.name)
print(imran.address)

eliza = Person("Eliza", 34, "Arch Linux")
print(eliza.name)
print(eliza.address)

# Task 6.1:
# Run mypy on this code
# Fix the code so there are no errors in mypy or when it runs

# Task 6.2:
# Create a new function in this file called likes_apple
# It should take a person as parameter
# It returns true if the preferred operating system is "macOS" or "iOS"
# It should return false for any other preferred os
# Add all the appropriate type annotations and test it has no errors in mypy

# Task 6.3:
# Compare objects and classes
# What are some advantages and disadvantages of each?
4 changes: 4 additions & 0 deletions sprint-5/07-methods.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Answer the following question:
What is the difference between a method and a function?
Can you give some advantages of methods over functions?

30 changes: 30 additions & 0 deletions sprint-5/08-implement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class Person:
def __init__(self, name: str, age: int, preferred_operating_system: str):
self.name = name
self.age = age
self.preferred_operating_system = preferred_operating_system

imran = Person("Imran", 22, "Ubuntu")
print(imran.is_adult())

# Task:
# 1. Add the `drivers_license_check` free function and the `is_adult` method into the code
# Make sure your code currently gives the expected output.
#
# 2. Change the `Person` class to take a date of birth
# Use the standard library's `datetime.date` class
# https://docs.python.org/3/library/datetime.html#datetime.date
# Store the `date of birth` in a field instead of `age` (it should be a `str`)
#
# 3. Try to run your code
# How does this change break your code.
# What kind of error do you get?
# Is it helpful in identifying where your next change needs to be?
# Type your thoughts here:
#
#
#
#
# 4. Update the `is_adult` method so the error is fixed.
# Using the `drivers_license_check` function check everything runs as expected

12 changes: 12 additions & 0 deletions sprint-5/09-dataclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Task 9.1:
# Copy the code you have so far from task 08-implement.py
# Convert this to a dataclass
# Test that the dataclass works with mypy, with equality checks

# Task 9.2:
# Add a greeting method that says "Hello, <person name>!"

# Task 9.3:
# Read the @datatype documentation here: https://docs.python.org/3/library/dataclasses.html
# Explain what does `frozen=True` do to the class?
# What other options could you play around with and explore? Offer suggestions for any that would be useful here.
30 changes: 30 additions & 0 deletions sprint-5/10-predict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from dataclasses import dataclass

@dataclass(frozen=True)
class Animal:
name: str
species: str

@dataclass(frozen=True)
class Person:
name: str
age: int

@dataclass(frozen=True)
class FamilyTree:
parent: Person
members: list

pet = Animal(name="Gromit", species="Dog")
fatma = Person(name="Fatma", age=4)
aisha = Person(name="Aisha", age=6)
imran = Person(name="Imran", age=30)

family = FamilyTree(parent=imran, members=[fatma, aisha, pet])

def print_family_tree(family: FamilyTree):
print(family.parent.name)
for child in family.members:
print(f"{child.name} ({child.age} years old)")

print_family_tree(family)
63 changes: 63 additions & 0 deletions sprint-5/11-fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from dataclasses import dataclass
from typing import List

@dataclass(frozen=True)
class Animal:
name: str
size: str

@dataclass(frozen=True)
class Person:
name: str
age: int

@dataclass(frozen=True)
class Tree[T]:
parent: T
children: List[T]

def print_tree(self):
print(self.parent)
for child in self.children:
print(child)

fatma = Person(name="Fatma", age=4)
aisha = Person(name="Aisha", age=6)
imran = Person(name="Imran", age=30)
family_tree = Tree[Person](parent=imran, children=[fatma, aisha])

cats = Animal(name="Cat", size="Small")
dogs = Animal(name="Dog", size="Medium")
mammals = Animal(name="Mammals", size="Variable")
species_tree = Tree[Animal](parent=mammals, children=[cats, dogs])

family_tree.print_tree()
species_tree.print_tree()

# Task 11:
# Experiment with mypy and make sure that the family tree only takes `Person` types and the species tree only takes `Animal` types.
#
# We are going to add printing to the above code.
#
# Unlike our earlier example, we want to avoid having to create two
# separate looping methods to print out an entire tree for each datatype.
# So we have created a single looping function within Tree that will work for any datatype.
#
# Currently the `Tree.print_tree()` function doesn't do anything.
#
# Add some appropriate methods to each of the Animal and Person classes to allow it to work.
#
# **Stretch task**
#
# Think of another type of data that can be organised into a tree.
#
# Add a new class for this, instantiate some variables, and have the existing `Tree` class print it out.
# Here is an example of what should be printed out
'''
Imran (30 years old)
- Fatma (4 years old)
- Aisha (6 years old))
Mammals (Variable size)
- Cat (Small size)
- Dog (Medium size)
'''
57 changes: 57 additions & 0 deletions sprint-5/12-refactor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from dataclasses import dataclass
from typing import List

@dataclass(frozen=True)
class Person:
name: str
age: int
preferred_operating_system: str


@dataclass(frozen=True)
class Laptop:
id: int
manufacturer: str
model: str
screen_size_in_inches: float
operating_system: str


def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]:
possible_laptops = []
for laptop in laptops:
if laptop.operating_system == person.preferred_operating_system:
possible_laptops.append(laptop)
return possible_laptops


people = [
Person(name="Imran", age=22, preferred_operating_system="Ubuntu"),
Person(name="Eliza", age=34, preferred_operating_system="Arch Linux"),
]

laptops = [
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system="Arch Linux"),
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="Ubuntu"),
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="ubuntu"),
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system="macOS"),
]

for person in people:
possible_laptops = find_possible_laptops(laptops, person)
print(f"Possible laptops for {person.name}: {possible_laptops}")

# Task 12
#Try changing the type annotation of `Person.preferred_operating_system` from `str` to `List[str]`.
#
#Run mypy on the code.
#
#It tells us different places that our code is now wrong. Fix it to remov eany errors.
#
#Now we changed the types, we probably also want to _rename_ our fields to something appropriate.
#
#Run mypy again.
#
#Fix all of the places that mypy tells you need changing.
#
#Then, make sure the program works as you'd expect.
Loading