adds 2025 materials
This commit is contained in:
commit
e85b3b21ca
23 changed files with 378 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.egg-info
|
||||
*.DS_Store
|
||||
*~$*.pptx
|
0
README.md
Normal file
0
README.md
Normal file
34
exercises/Exercise 1a Local imports.md
Normal file
34
exercises/Exercise 1a Local imports.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
## Exercise 1a: Local importing
|
||||
|
||||
#### Goal
|
||||
|
||||
Retrival practice in "basic" importing.
|
||||
|
||||
#### Preparation
|
||||
|
||||
(none)
|
||||
|
||||
#### Tasks
|
||||
|
||||
We are simulating having code in one folder and calling the code from the folder above.
|
||||
|
||||
0. Create a file in the `src/` folder called `daily_menu.py` and copy the code below
|
||||
into it.
|
||||
|
||||
```python
|
||||
def todays_special():
|
||||
pizza_margherita = make_margherita_pizza()
|
||||
|
||||
schorle = make_apfelschorle()
|
||||
|
||||
print("Today's special is ready! Buon Appetito!")
|
||||
return pizza_margherita, schorle
|
||||
|
||||
pizza, drink = todays_special()
|
||||
```
|
||||
|
||||
1. Figure out what import statements are missing, either by visual inspection or
|
||||
by running the code and seeing what does. Add the missing import statements at
|
||||
the top of the file. You may need to inspect the files in `src/italianfood/`.
|
||||
|
||||
2. Run `daily_menu.py`. Did it work?
|
24
exercises/Exercise 1b Unprotected code.md
Normal file
24
exercises/Exercise 1b Unprotected code.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
## Exercise 1b: Unprotected code
|
||||
|
||||
#### Goal
|
||||
|
||||
Investigate what happens when importing from modules with "unprotected" code.
|
||||
|
||||
#### Preparation
|
||||
|
||||
(none)
|
||||
|
||||
#### Tasks
|
||||
|
||||
0. Create a file in the `src/` folder called `unprotectd_code.py`.
|
||||
|
||||
1. Add a line in `unprotectd_code.py` that imports the `todays_special` function from `daily_menu.py`.
|
||||
|
||||
2. **BEFORE YOU EXECUTE THE FILE**. Discuss with your partner what you think will happen when you run `unprotectd_code.py`.
|
||||
|
||||
3. Run `unprotectd_code.py`. Does your prediction match reality?
|
||||
|
||||
4. (optional, for those who know) Discuss with your partner:
|
||||
* Why did this behaviour occur?
|
||||
* Why is it not good?
|
||||
* What can you do to "fix" the behaviour?
|
27
exercises/Exercise 2 editable installation workflow.md
Normal file
27
exercises/Exercise 2 editable installation workflow.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
## Exercise 2: Editable installation workflow
|
||||
|
||||
#### Goal
|
||||
|
||||
Experience that working with an editable installation does not change how you interact with your code.
|
||||
This is supposed to be easy and fun, so run the inspection often and make mistakes with the potion.
|
||||
|
||||
Use your git skills to commit the changes you made to a new branch, and create a pull request.
|
||||
|
||||
|
||||
#### Tasks
|
||||
|
||||
- In the `make_pizzas.py` file add another function that makes your favourite pizza.
|
||||
Be creative with your toppings :).
|
||||
|
||||
- Call this function from different places in your code
|
||||
- in `make_pizzas.py` call your function in the if __name__ == "__main__" part
|
||||
- add it to the tasting menu in the `scripts/run_pizza_restaurant.py` file
|
||||
- replace the margherita pizza in the `src/daily_menu.py` file with your pizza
|
||||
|
||||
-------------
|
||||
#### Extra credit
|
||||
|
||||
Once you are done, reflect on what you did to find out where the function making the pizza was and how it worked
|
||||
- Where did you look, why did you look there first?
|
||||
- How did you figure out what it does? What part of the function did you read first?
|
||||
- Did it work on your first try? If not, how did you try to fix it - trial and error or read documentation?
|
45
exercises/Exercise 4 PEP8.md
Normal file
45
exercises/Exercise 4 PEP8.md
Normal file
|
@ -0,0 +1,45 @@
|
|||
## Exercise 4: PEP8
|
||||
|
||||
#### Goal
|
||||
|
||||
Get you familiar with some of the fun facts hidden in the PEP8 guide.
|
||||
|
||||
#### Preparation
|
||||
|
||||
(none)
|
||||
|
||||
#### Tasks
|
||||
|
||||
0. Navigate to [PEP8](https://peps.python.org/pep-0008/).
|
||||
|
||||
1. Depending on your assigned letter, answer the questions in the corresponding
|
||||
set below. Feel to tackle the questions out of order. You can also split the
|
||||
questions between your pair, but be you must leave time to discuss the answers
|
||||
together.
|
||||
|
||||
##### Set A
|
||||
1. What should you use instead of if y == None?
|
||||
2. If you have an acronym in camel case, should you capitalize the first letter
|
||||
only or the whole acronym?
|
||||
3. How should you check if a variable equals False?
|
||||
4. What is important about how underscores work with variable names? What happens
|
||||
if I put an underscore after a variable? One before? Two before?
|
||||
5. How many spaces should you use after a period in a comment?
|
||||
|
||||
##### Set B
|
||||
1. What are the capitalization guidelines for classes, functions, and variables?
|
||||
Give examples.
|
||||
2. How should you check if a path ends in .txt?
|
||||
3. What is the difference between mixed case, camel case, and snake case?
|
||||
4. How should you indicate block comments?
|
||||
5. What are the whitespace rules around operators? Give several examples.
|
||||
|
||||
##### Set C
|
||||
1. If I need to import os, sys, numpy, matplotlib, and a local module called
|
||||
_utils.py, what does my import block look like?
|
||||
2. How many blank lines go before a function I define at the top of a module? How
|
||||
many after?
|
||||
3. Which of these is correct: x[3:4] or x[3 : 4]?
|
||||
4. Should you use single or double quotes to indicate strings?
|
||||
5. Give examples of a long line of code and how you can break it onto multiple
|
||||
lines.
|
42
exercises/Exercise 5 Virtual Environments.md
Normal file
42
exercises/Exercise 5 Virtual Environments.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
## Exercise 5: Virtual Environments
|
||||
|
||||
#### Goal
|
||||
|
||||
Create a virtual environment + install a package + see that that package was installed only in environment
|
||||
|
||||
#### Tasks
|
||||
|
||||
We will use `venv` as our environment manager - while commands might differ, the principles apply to all other package managers as well.
|
||||
|
||||
1. Check which Python you are currently using, and which packages are installed. Also check which folders are in the folder you are installing the environment into.
|
||||
3. Create and activate a new environment.
|
||||
4. Check again which Python you are using and which packages are installed - are they different?
|
||||
5. Install a specific version of a package using pip e.g. pandas=1.5.3
|
||||
6. See that dependencies are also installed (more packages than only pandas appear)
|
||||
7. Deactivate and delete the environment
|
||||
8. Check the packages that are installed when no environment is active again (as step 1). Have they changed?
|
||||
|
||||
|
||||
#### Commands in case you get stuck (not in correct order):
|
||||
|
||||
```bash
|
||||
% investigate Python and packages
|
||||
> which python
|
||||
> pip freeze
|
||||
> pip install <package-name>
|
||||
> pip install <package-name>==0.0.1
|
||||
|
||||
% create an environment option 1 (create folder called venv_folder for files related to virtual environment, feel free to change the name)
|
||||
> cd <path-to-project_folder>
|
||||
> mkdir venv_folder
|
||||
> python3 -m venv venv_folder
|
||||
> source venv_folder/bin/activate
|
||||
|
||||
% create an environment option 2
|
||||
> python3 -m venv <path-to-folder-for-venv>
|
||||
> source <path-to-folder-for-venv>/bin/activate
|
||||
|
||||
% deactivate and delete a venv environment
|
||||
> deactivate
|
||||
> rm -rf venv_folder
|
||||
```
|
BIN
materials/part0_intro.pptx
Normal file
BIN
materials/part0_intro.pptx
Normal file
Binary file not shown.
BIN
materials/part1_local_imports.pptx
Normal file
BIN
materials/part1_local_imports.pptx
Normal file
Binary file not shown.
BIN
materials/part2_packages_editable_install.pptx
Normal file
BIN
materials/part2_packages_editable_install.pptx
Normal file
Binary file not shown.
BIN
materials/part3_repo_structure.pptx
Normal file
BIN
materials/part3_repo_structure.pptx
Normal file
Binary file not shown.
BIN
materials/part4_accessibility.pptx
Normal file
BIN
materials/part4_accessibility.pptx
Normal file
Binary file not shown.
BIN
materials/part5_environments.pptx
Normal file
BIN
materials/part5_environments.pptx
Normal file
Binary file not shown.
BIN
materials/part6_summary.pptx
Normal file
BIN
materials/part6_summary.pptx
Normal file
Binary file not shown.
11
pyproject.toml
Normal file
11
pyproject.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[project]
|
||||
name = "italianfood"
|
||||
version = "0.1.1"
|
||||
description = "This is a project about pizza making"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = []
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
13
scripts/run_pizza_restaurant.py
Normal file
13
scripts/run_pizza_restaurant.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from italianfood.make_pizzas import make_margherita_pizza
|
||||
|
||||
|
||||
def pizza_tasting_menu():
|
||||
pizza_margherita = make_margherita_pizza(num_pizzas=10)
|
||||
|
||||
all_pizzas = [pizza_margherita]
|
||||
|
||||
return all_pizzas
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pizzas = pizza_tasting_menu()
|
0
src/italianfood/__init__.py
Normal file
0
src/italianfood/__init__.py
Normal file
16
src/italianfood/dough.py
Normal file
16
src/italianfood/dough.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
class PizzaDough:
|
||||
flour_weight: int
|
||||
water_weight: int
|
||||
salt_weight: int
|
||||
yeast_weight: int
|
||||
|
||||
def __init__(self, flour_weight, water_weight, salt_weight, yeast_weight):
|
||||
self.hydration = water_weight / flour_weight
|
||||
self.total_weight = flour_weight + water_weight + salt_weight + yeast_weight
|
||||
self.prepare_dough()
|
||||
|
||||
def prepare_dough(self):
|
||||
print("Kneading the dough. This will be delicious!\n...")
|
||||
|
||||
|
||||
|
11
src/italianfood/drinks.py
Normal file
11
src/italianfood/drinks.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
class Schorle:
|
||||
juice: str
|
||||
|
||||
def __init__(self, juice):
|
||||
self.name = f"{juice}schorle"
|
||||
|
||||
|
||||
def make_apfelschorle():
|
||||
print("Mixing a delicious Apfelschorle!\n...")
|
||||
apfelschorle = Schorle(juice="apple")
|
||||
return apfelschorle
|
17
src/italianfood/ingredients_and_toppings.py
Normal file
17
src/italianfood/ingredients_and_toppings.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Dough ingredients
|
||||
FLOUR_PER_PIZZA = 250 # grams
|
||||
WATER_PER_PIZZA = 150 # grams
|
||||
SALT_PER_PIZZA = 5 # grams
|
||||
YEAST_PER_PIZZA = 2 # grams
|
||||
|
||||
# Toppings
|
||||
TOMATO_SAUCE = "tomato sauce"
|
||||
MOZZARELLA = "mozzarella"
|
||||
TOPPINGS_MARGARITA_PIZZA = [TOMATO_SAUCE, MOZZARELLA]
|
||||
TOPPINGS_FUNGHI_PIZZA = [TOMATO_SAUCE, MOZZARELLA, "mushrooms"]
|
||||
TOPPINGS_VERDURE_GRIGLIATE_PIZZA = [
|
||||
TOMATO_SAUCE,
|
||||
MOZZARELLA,
|
||||
"grilled vegetables"
|
||||
]
|
||||
|
77
src/italianfood/make_pizza_refactored.py
Normal file
77
src/italianfood/make_pizza_refactored.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
from italianfood.dough import PizzaDough
|
||||
from italianfood.ovens import bake_pizza
|
||||
|
||||
STANDARD_FLOUR_WEIGHT = 180 # grams per pizza
|
||||
STANDARD_WATER_WEIGHT = 126 # grams per pizza
|
||||
STANDARD_SALT_WEIGHT = 2 # grams per pizza
|
||||
STANDARD_YEAST_WEIGHT = 1 # grams per pizza
|
||||
|
||||
MARGARITA_TOPPINGS = ["tomato sauce", "mozzarella cheese", "fresh basil"]
|
||||
MUSHROOM_TOPPINGS = ["tomato sauce", "mozzarella cheese", "mushrooms"]
|
||||
|
||||
|
||||
class Pizza:
|
||||
dough: PizzaDough
|
||||
num_pizzas: int = 1
|
||||
is_ready: bool = False
|
||||
|
||||
def __init__(self, dough, num_pizza_balls):
|
||||
if num_pizza_balls < 1:
|
||||
raise ValueError("Number of pizza balls must be at least 1.")
|
||||
self.num_pizzas = num_pizza_balls
|
||||
self.dough = dough
|
||||
self.make_pizza_balls()
|
||||
|
||||
def make_pizza_balls(self):
|
||||
self.weight_per_pizza_ball = self.dough.total_weight / self.num_pizzas
|
||||
print(
|
||||
f"Each Pizza will be made out of {self.weight_per_pizza_ball} g dough.\n..."
|
||||
)
|
||||
print("Now imagine expert pizza tossing skills!\n...")
|
||||
return self
|
||||
|
||||
def add_toppings(self, toppings):
|
||||
self.toppings = toppings
|
||||
print(f"Adding {self.toppings} to pizza(s).\n...")
|
||||
return self
|
||||
|
||||
|
||||
def make_margarita_pizza_more_readable(num_pizzas: int = 1):
|
||||
dough = make_pizza_dough(num_pizzas)
|
||||
baked_pizza = make_and_bake_pizza(dough, num_pizzas, MARGARITA_TOPPINGS)
|
||||
return baked_pizza
|
||||
|
||||
|
||||
def make_pizza_dough(num_pizzas: int = 1):
|
||||
dough = PizzaDough(
|
||||
flour_weight=STANDARD_FLOUR_WEIGHT * num_pizzas,
|
||||
water_weight=STANDARD_WATER_WEIGHT * num_pizzas,
|
||||
salt_weight=STANDARD_SALT_WEIGHT * num_pizzas,
|
||||
yeast_weight=STANDARD_YEAST_WEIGHT * num_pizzas,
|
||||
)
|
||||
return dough
|
||||
|
||||
|
||||
def make_and_bake_pizza(dough, num_pizzas, toppings):
|
||||
pizza = Pizza(dough=dough, num_pizza_balls=num_pizzas)
|
||||
pizza.add_toppings(toppings)
|
||||
baked_pizza = bake_pizza(pizza)
|
||||
return baked_pizza
|
||||
|
||||
|
||||
def make_pizza_reusable(num_pizzas, toppings):
|
||||
dough = make_pizza_dough(num_pizzas)
|
||||
baked_pizza = make_and_bake_pizza(dough, num_pizzas, toppings)
|
||||
return baked_pizza
|
||||
|
||||
|
||||
def pizza_tasting_menu():
|
||||
all_pizzas = []
|
||||
|
||||
margarita_pizza = make_pizza_reusable(num_pizzas=1, toppings=MARGARITA_TOPPINGS)
|
||||
all_pizzas.append(margarita_pizza)
|
||||
|
||||
mushroom_pizza = make_pizza_reusable(num_pizzas=2, toppings=MUSHROOM_TOPPINGS)
|
||||
all_pizzas.append(mushroom_pizza)
|
||||
|
||||
return all_pizzas
|
51
src/italianfood/make_pizzas.py
Normal file
51
src/italianfood/make_pizzas.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
from italianfood.dough import PizzaDough
|
||||
from italianfood.ovens import bake_pizza
|
||||
|
||||
|
||||
class Pizza:
|
||||
dough: PizzaDough
|
||||
num_pizzas: int = 1
|
||||
is_ready: bool = False
|
||||
|
||||
def __init__(self, dough, num_pizza_balls):
|
||||
if num_pizza_balls < 1:
|
||||
raise ValueError("Number of pizza balls must be at least 1.")
|
||||
self.num_pizzas = num_pizza_balls
|
||||
self.dough = dough
|
||||
self.make_pizza_balls()
|
||||
|
||||
def make_pizza_balls(self):
|
||||
self.weight_per_pizza_ball = self.dough.total_weight / self.num_pizzas
|
||||
print(
|
||||
f"Each Pizza will be made out of {self.weight_per_pizza_ball} g dough.\n..."
|
||||
)
|
||||
print("Now imagine expert pizza tossing skills!\n...")
|
||||
return self
|
||||
|
||||
def add_toppings(self, toppings):
|
||||
self.toppings = toppings
|
||||
print(f"Adding {self.toppings} to pizza(s).\n...")
|
||||
return self
|
||||
|
||||
|
||||
def make_margherita_pizza(num_pizzas: int = 1):
|
||||
total_flour_weight = 180 * num_pizzas
|
||||
total_water_weight = 126 * num_pizzas
|
||||
total_salt_weight = 2 * num_pizzas
|
||||
total_yeast_weight = 1 * num_pizzas
|
||||
|
||||
dough = PizzaDough(
|
||||
flour_weight=total_flour_weight,
|
||||
water_weight=total_water_weight,
|
||||
salt_weight=total_salt_weight,
|
||||
yeast_weight=total_yeast_weight,
|
||||
)
|
||||
|
||||
toppings = ["tomato sauce", "mozzarella cheese", "fresh basil"]
|
||||
|
||||
pizza = Pizza(dough=dough, num_pizza_balls=num_pizzas)
|
||||
pizza.add_toppings(toppings)
|
||||
|
||||
baked_pizza = bake_pizza(pizza)
|
||||
|
||||
return baked_pizza
|
7
src/italianfood/ovens.py
Normal file
7
src/italianfood/ovens.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
def bake_pizza(pizza, baking_time=2, temperature=450):
|
||||
# just pretend there is some complicated code
|
||||
print(
|
||||
f"The Pizza was baked for {baking_time} min at {temperature} C. It is now ready!\n..."
|
||||
)
|
||||
pizza.is_ready = True
|
||||
return pizza
|
Loading…
Add table
Add a link
Reference in a new issue