Skip to content

Commit 51155a4

Browse files
authored
SDC Types Rework (#686)
Updates for CodeYourFuture/curriculum#2018 Adds the latest prep tasks as individual files for submission Adds a new stretch task to replace the old laptop allocation one --------- Co-authored-by: l <l>
1 parent bb71b06 commit 51155a4

21 files changed

Lines changed: 663 additions & 0 deletions

‎types-stretch/README.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Sprint 5 Stretch - Radio Control App
2+
3+
This is part of an app that can be used to control an online radio station
4+
5+
Your task is to:
6+
1. Add type annotations where appropriate.
7+
1. Upgrade everything use dataclasses. Use `frozen` where appropriate.
8+
1. Observe how the given `__str__` method works, and add one to the other classes
9+
1. When the `__str__` method is called, have it print the duration in formatted mm:ss rather than just seconds
10+
1. Add a new class of `Person` - you can use your imagination what this includes, but it should have at least a string name
11+
1. Turn the fields for _artists_, _host_, and _guest_ into `Person` classes
12+
1. Make a new class `Podcast` that _extends_ the `TalkShow` class, with an extra string field for _sponsor_
13+
1. Finish implementing the class `Playlist`, and set it to takes a generic, e.g. either `Song` or `TalkShow` or `Podcast`
14+
15+
As you implement, make sure to keep checking with mypy and add your own code at the end to test it works correctly

‎types-stretch/requirements.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mypy

‎types-stretch/stretch-radio.py‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class Song:
2+
def __init__(self, artist, duration, title):
3+
self.artist = artist # should be a string
4+
self.duration = duration # should be an integer in seconds
5+
self.title = title # should be a string
6+
7+
def __str__(self):
8+
return f"{self.artist} - {self.title} ({self.duration})"
9+
10+
class TalkShow:
11+
def __init__(self, host, guests, duration, title):
12+
self.host = host # should be a string
13+
self.guests = guests # should be a list of strings
14+
self.duration = duration # should be an integer in seconds
15+
self.title = title # should be a string
16+
17+
class Playlist:
18+
def __init__(self, items):
19+
self.items = items # A list of Song or TalkShow
20+
self.currently_playing_index = 0
21+
22+
def play_next(self):
23+
pass
24+
# TODO: increment the currently_playing_index, when you get to the end loop back to 0
25+
26+
def get_currently_playing(self):
27+
return "todo"
28+
# TODO: return a string representation of whatever is playing at the current index
29+
# See the __str__ method in Song for an example of how to make a string representation of a class
30+
31+
def get_total_duration(self):
32+
return 0
33+
# TODO: return
34+
35+
song_a = Song("Rick Astley", 210, "Never Gonna Give You Up")
36+
print(song_a)
37+
38+
song_b = Song("Psy", 219, "Gangnam Style")
39+
funny_songs = Playlist([song_a, song_b])
40+
print(funny_songs.get_currently_playing())
41+
42+
show_a = TalkShow("Melvyn Bragg", ["Jim Al-Khalili", "Sheila Rowan", "Carolin Crawford"], 2700, "Gravitational Waves")
43+

‎types/01-predict.py‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
def half(value):
2+
return value / 2
3+
4+
def double(value):
5+
return value * 2
6+
7+
def second(value):
8+
return value[1]
9+
10+
# TASK 1:
11+
# 1. Predict what you think will happen with each of the following functions
12+
# 2. Then, test it, and explain in your own words what is actually happening and why
13+
# (feel free to comment out lines if you think they cause errors or crashes while testing)
14+
15+
print(half(22))
16+
# Prediction:
17+
# What actually happens and why:
18+
19+
print(half("22"))
20+
# Prediction:
21+
# What actually happens and why:
22+
23+
print(double(22))
24+
# Prediction:
25+
# What actually happens and why:
26+
27+
print(double("22"))
28+
# Prediction:
29+
# What actually happens and why:
30+
31+
print(second(22))
32+
# Prediction:
33+
# What actually happens and why:
34+
35+
print(second(0x16))
36+
# Prediction:
37+
# What actually happens and why:
38+
39+
print(second("22"))
40+
# Prediction:
41+
# What actually happens and why:

‎types/02-playcomputer.js‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import process from "node:process";
2+
import readline from "node:readline";
3+
4+
const rl = readline.createInterface({
5+
input: process.stdin,
6+
output: process.stdout,
7+
});
8+
9+
rl.question("What URL should we fetch?\n> ", async (url) => {
10+
const response = await fetch(url);
11+
if (!response.ok) {
12+
if (response.body.toLowerCase().includes("permission")) {
13+
console.error("You didn't have permission to get that URL");
14+
} else {
15+
console.error(`The request failed - body: ${response.body}`);
16+
}
17+
process.exit(1);
18+
}
19+
20+
const contents = await response.json();
21+
22+
console.log(contents);
23+
24+
rl.close();
25+
});
26+
27+
// TASK 2
28+
// Read through this file and predict what it does.
29+
// Leave a comment on any lines if you spot any errors, offering an explanation of the problem.

‎types/03-fix.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def double(number):
2+
return number * 3
3+
4+
print(double(10))
5+
6+
# TASK 3:
7+
# Read the code and see if you can find any bugs.
8+
# Write down what the bug is, and how would you fix it?
9+
# Are there multiple ways you could fix it?

‎types/04-addmypy.py‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
def open_account(balances, name, amount):
2+
balances[name] = amount
3+
4+
def sum_balances(accounts):
5+
total = 0
6+
for name, pence in accounts.items():
7+
print(f"{name} had balance {pence}")
8+
total += pence
9+
return total
10+
11+
def format_pence_as_string(total_pence):
12+
if total_pence < 100:
13+
return f"{total_pence}p"
14+
pounds = int(total_pence / 100)
15+
pence = total_pence % 100
16+
return f"£{pounds}.{pence:02d}"
17+
18+
balances = {
19+
"Sima": 700,
20+
"Linn": 545,
21+
"Georg": 831,
22+
}
23+
24+
open_account("Tobi", 9.13)
25+
open_account("Olya", "£7.13")
26+
27+
total_pence = sum_balances(balances)
28+
total_string = format_pence_as_str(total_pence)
29+
30+
print(f"The bank accounts total {total_string}")
31+
32+
# TASK 4
33+
# This code contains bugs related to types. They are bugs mypy can catch.
34+
# Read this code to understand what it's trying to do.
35+
# Add type annotations to the method parameters and return types of this code.
36+
# Run the code through mypy, and fix all of the bugs that show up.
37+
# When you're confident all of the type annotations are correct, and the bugs are fixed, run the code and check it works.

‎types/05-predict.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
imran = {
2+
"name": "Imran",
3+
"age": 22,
4+
"preferred_operating_system": "Ubuntu",
5+
}
6+
7+
eliza = {
8+
"name": "Eliza",
9+
"age": 34,
10+
"preferred_operating_system": "Arch Linux",
11+
}
12+
13+
14+
print(imran["name"])
15+
print(imran["address"])
16+
17+
# TASK 5:
18+
# This code contains some untyped objects.
19+
# Try checking it with mypy before running the code and predict what you think will happen when you run the code.
20+
#
21+
# Prediction:
22+
#
23+
# Can you explain what actualy happens?
24+
#

‎types/06-classes.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Person:
2+
def __init__(self, name: str, age: int, preferred_operating_system: str):
3+
self.name = name
4+
self.age = age
5+
self.preferred_operating_system = preferred_operating_system
6+
7+
imran = Person("Imran", 22, "Ubuntu")
8+
print(imran.name)
9+
print(imran.address)
10+
11+
eliza = Person("Eliza", 34, "Arch Linux")
12+
print(eliza.name)
13+
print(eliza.address)
14+
15+
# TASK 6.1:
16+
# Run mypy and fix any errors.
17+
18+
# TASK 6.2:
19+
# Create a new function in this file called likes_apple
20+
# It should take a person as parameter
21+
# It returns true if the preferred operating system is "macOS" or "iOS"
22+
# It should return false for any other preferred os
23+
# Add all the appropriate type annotations and test it has no errors in mypy
24+
25+
# TASK 6.3:
26+
# Compare objects and classes
27+
# What are some advantages and disadvantages of each?

‎types/07-methods.txt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
TASK 7:
2+
Answer the following questions:
3+
What is the difference between a method and a function?
4+
Can you give some advantages of methods over functions?
5+

0 commit comments

Comments
 (0)