Skip to content
Merged
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
195 changes: 195 additions & 0 deletions lesson_10/SOLUTION_EXERCISE_10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Exercise Lesson 10

## Instructions

Todays exercises goal is to practice more on object oriented programming

### `Exercise 1` override

1. Create a class that has at least one method

```python
class Bicycle:

def __init__(self):
self.speed = 2

def accelerate(self):
self.speed += 1

def slow(self):
self.speed -= 1
```

2. Create a subclass that uses your class (1) as base class

```python
class MTB(Bicycle):
pass
```

3. In the subclass (2) you should override the method from (1)

```python
class MTB(Bicycle):

def slow(self):
self.speed -= 1.2
```

4. Print a instance of (1) and (2) both calling the same method name

```python
bicycle = Bicycle()
bicycle.slow()
print(bicycle.speed)

mtb = MTB()
mtb.slow()
print(mtb.speed)
```

<div class="page"/>

### `Exercise 2` menu

1. Create a class, i.e `Dog`, `Animal`, `Fridge`
2. Create a program that uses a menu
1. The first option will create an object from your class
2. The second option will print the object
3. The third option will delete the object
3. If you try to print before creating an object or after deleted it, the program should print `No object available to print`
4. If you try to delete a object that doesn't exist, the program should print `No object to delete`

```python

class Dog:
def __init__(self):
self.food = 0

def eat(self):
self.food += 1

def __str__(self):
return f"I'm your best friend and my food level is ${self.food}"

class Dog:
def __init__(self):
self.food = 0

def eat(self):
self.food += 1

def __str__(self):
return f"I'm your best friend and my food level is ${self.food}"

class Menu:

MAIN_MENU_TEXT = """
Welcome to this program!

1. Create a new object
2. Print your object
3. Delete your object

type q or Q to delete
"""

def user_choice(self):
return input("Enter your choice 1-3 or q: ")

def wait_for_user(self):
if self.running:
input("Please press any key to continues.")

def menu_commands(self, choice):
if choice == 'q' or choice == 'Q':
self.running = False
elif choice == "1":
self.dog = Dog()
elif choice == "2":
try:
print(self.dog)
except AttributeError:
print("No object available to print")
elif choice == "3":
try:
del self.dog
except AttributeError:
print("No object to delete")
# Alternative self.dog = None

def start_loop(self):
self.running = True
while self.running:
print(Menu.MAIN_MENU_TEXT)
choice = self.user_choice()
self.menu_commands(choice)
self.wait_for_user()

Menu().start_loop()
```

<div class="page"/>

## `Exercise 3` composition vs inheritance

In this exercise you will write two alternative solutions, one with inheritance and one with composition.

### Inheritance

1. Create a class named `Person`, it should have `address` stored, with street name, street number, postal code, country.

2. Create a class `Employee` that uses `Person´ as base class. Add employee number and salary.

```python
class Person:
def __init__(self, street_name, postal_code, country):
self.street_name = street_name
self.postal_code = postal_code
self.country = country


class Employee(Person):
def __init__(self, street_name, postal_code, country, emp_number, salary):
super().__init__(street_name, postal_code, country)
self.emp_number = emp_number
self.salary = salary

def __str__(self):
return f"emp {self.emp_number} live on {self.street_name}"


emp = Employee("Sveavägen", "11350", "Sweden", 1, 10000)
print(emp)
```

<div class="page"/>

### Composition

1. Create a class `Address` with street name, street number, postal code, country.
2. Create a class `Employee` that has an address class, employee number and salary

```python
class Address:
def __init__(self, street_name, postal_code, country):
self.street_name = street_name
self.postal_code = postal_code
self.country = country


class Employee:
def __init__(self, address, emp_number, salary):
self.address = address
self.emp_number = emp_number
self.salary = salary

def __str__(self):
return f"emp {self.emp_number} live on {self.address.street_name}"


address = Address("Sveavägen", "11350", "Sweden")
emp = Employee(address, 1, 10000)
print(emp)
```
41 changes: 41 additions & 0 deletions lesson_11/EXERCISE_11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Group Exercise Lesson 11

## Instructions

This is probably your first slightly larger program, so you will tackle it as a group exercise. Each team consists of 3-4 members. You can write your program fully object-oriented or not, this is up to your team to decide. The only requirement is that you somewhere use a class `Person`.

### `Exercise 1` Load data from a file

1. Create a file in either csv or json format (your choice). It should contain data for at least 5 Persons, you can create it manually or with a script.
2. A person has a firstname, lastname, birthdate and address.
3. Let the user enter the path to the file
4. Read the file and insert it into a SQLite database you have created.

### `Exercise 2` List all persons stored in the database

*Hint* here is a good place to use the class `Person`. e.g you can create a Person object for each row, and print it with a custom `__str__` method.

1. Create a (SQL) query that gets all rows (select *) from the table
2. Print all rows

### `Exercise 3` Menu

1. Create a menu with options:
1. Load data from file (Use your solution from Exercise 1)
2. List all persons (select *) (Use your solution from Exercise 2)
1. EXTRA let the user type a firstname and query the database with that firstname
2. EXTRA let the user type a lastname and query the database with that lastname
3. EXTRA let the user type a birthdate and query query the database with that birthdate
4. EXTRA let the user type an address and query the database with that address
3. Delete a person
4. EXTRA update a persons address with input from the user

### EXTRA EXTRA Add another table

Create another table, i.e Vehicles, Friends or Transactions. Make sure the content
would have some relation to Persons defined in the other table, e.g. a vehicle is owned
by a person or a transaction was done by a person.

1. Add it to your menu
2. Make it possible to add data to the second table
3. Query the database with a join between Person table and your second table, so you can see the combined results.
26 changes: 26 additions & 0 deletions lesson_11/LINKS_11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Links

## Sql

- Python docs a lightweight disk-based database [sqlite3](https://docs.python.org/3/library/sqlite3.html)
- SQLite extension for Visual Studio Code [vscode-sqlite](https://marketplace.visualstudio.com/items?itemName=alexcvzz.vscode-sqlite)
- Sql [create db](https://www.w3schools.com/sql/sql_create_db.asp)
- Sql [create table](https://www.w3schools.com/sql/sql_create_table.asp)
- Sql [insert into](https://www.w3schools.com/sql/sql_insert.asp)
- Sql [select](https://www.w3schools.com/sql/sql_select.asp)
- Sql [delete](https://www.w3schools.com/sql/sql_delete.asp)

## Sql Extra

- Sql [update](https://www.w3schools.com/sql/sql_update.asp)
- Sql [where](https://www.w3schools.com/sql/sql_where.asp)
- Sql tables [join](https://www.w3schools.com/sql/sql_join.asp)

## Python

- Python docs about file format [csv](https://docs.python.org/3/library/csv.html)
- Python docs about file format [json](https://docs.python.org/3/library/json.html)

## Git

- Git [cheat sheet](https://education.github.com/git-cheat-sheet-education.pdf)
5 changes: 5 additions & 0 deletions lesson_11/examples/10_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
try:
with open("a_lost_file", "r") as f:
print(f)
except FileNotFoundError:
print("File not found")
54 changes: 54 additions & 0 deletions lesson_11/examples/11_extra_sql.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import sqlite3
from tabulate import tabulate

try:
with sqlite3.connect(':memory:', isolation_level=None) as conn:
conn.execute(
"""
CREATE TABLE customers (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
firstname TEXT,
lastname TEXT
)
""")

conn.execute(
"""
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
customer_id INTEGER NOT NULL,
status TEXT
)
""")

conn.executemany(
"""
INSERT INTO customers (
firstname,
lastname
) VALUES(?, ?)
""", (("Nils", "Smith"), ("Adam", "Williams"), ("Joe", "Clinton")))

conn.executemany(
"""
INSERT INTO orders (
customer_id,
status
) VALUES(?, ?)
""", ((1, "shipped"), (1, "prepared"), (2, "cancelled")))

customer_orders = conn.execute(
"""
SELECT o.id as order_id, c.id as customer_id, c.firstname, c.lastname, o.status
FROM orders AS o
INNER JOIN customers AS c ON o.customer_id=c.id
"""
)

description = tuple(map(lambda x: x[0], customer_orders.description))
print(tabulate(customer_orders.fetchall(), description))

except Exception as e:
print(e)
finally:
conn.close()
28 changes: 28 additions & 0 deletions lesson_11/examples/1_generate_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import csv

cars = [
{
"Manufacturer": "Tesla",
"Model": "Model 3",
"Year": "2019",
"Price": "523800"
},
{
"Manufacturer": "Volvo",
"Model": "XC60",
"Year": "2018",
"Price": "313000"
},
{
"Manufacturer": "Saab",
"Model": "900",
"Year": "1994",
"Price": "3000"
}
]

# https://docs.python.org/3/library/csv.html
with open('lesson_11/examples/data/cars.csv', 'w') as f:
csv_writer = csv.DictWriter(f, fieldnames=cars[0].keys())
csv_writer.writeheader()
csv_writer.writerows(cars)
25 changes: 25 additions & 0 deletions lesson_11/examples/2_generate_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import json

persons = {
"persons": [{
"firstname": "pelle",
"lastname": "svensson",
"year_of_birth": 1994
},
{
"firstname": "olle",
"lastname": "svensson",
"year_of_birth": 1943
},
{
"firstname": "nisse",
"lastname": "svensson",
"year_of_birth": 1967
}
]

}

# https://docs.python.org/3/library/json.html
with open('lesson_11/examples/data/persons.json', 'w') as f:
f.write(json.dumps(persons, indent=4))
6 changes: 6 additions & 0 deletions lesson_11/examples/3_read_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import csv

with open("lesson_11/examples/data/cars.csv") as f:
reader = csv.reader(f)
for row in reader:
print(row)
5 changes: 5 additions & 0 deletions lesson_11/examples/4_read_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import json

with open("lesson_11/examples/data/persons.json") as f:
cars = json.load(f)
print(cars)
Loading