day1-code
This commit is contained in:
parent
8abf830f57
commit
23f03e90d1
66
src/T00_Intro.py
Normal file
66
src/T00_Intro.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# git clone https://git.budem.de/philip/tennet_course.git
|
||||||
|
|
||||||
|
# Standardpython
|
||||||
|
|
||||||
|
# externe libraries
|
||||||
|
# pandas, geopandas, matplotlib, numpy, etc
|
||||||
|
|
||||||
|
a = 13
|
||||||
|
print(a, type(a))
|
||||||
|
s = "hello"
|
||||||
|
t = 'python'
|
||||||
|
print(s, t)
|
||||||
|
|
||||||
|
# unveränderlichen datentypen und veränderlichen Datentypen
|
||||||
|
# immutable und mutable
|
||||||
|
|
||||||
|
print(id(a))
|
||||||
|
b = a # erstellt immer eine NamensReferenz auf das Objekt auf der rechten seite
|
||||||
|
print(id(b))
|
||||||
|
print()
|
||||||
|
a += 1 # a = a + 1
|
||||||
|
print(id(a))
|
||||||
|
print(a)
|
||||||
|
print(id(b))
|
||||||
|
print(b)
|
||||||
|
|
||||||
|
# unveränderliche Objekte:
|
||||||
|
# * Zahlen: int, float, (complex)
|
||||||
|
# * Strings
|
||||||
|
# * tuple (unveränderliche Liste) (nur wenn unveränderliche elemente im tuple sind)
|
||||||
|
# * (frozenset)
|
||||||
|
# alles andere ist veränderlich
|
||||||
|
|
||||||
|
s = "Hello World"
|
||||||
|
s = s.upper()
|
||||||
|
print(s)
|
||||||
|
s = s.replace("WORLD", "PYTHON")
|
||||||
|
print(s)
|
||||||
|
|
||||||
|
# Listen sind veränderlich
|
||||||
|
|
||||||
|
l1 = [5, "python", 1.3]
|
||||||
|
l2 = l1 # erzeugt einen zweiten verweis auf die Liste [5, "python", 1.3]
|
||||||
|
l1.append(42)
|
||||||
|
print(l2)
|
||||||
|
# += besser append und extend nutzen
|
||||||
|
l1 += [6, 1, 9]
|
||||||
|
print(l1)
|
||||||
|
print(l2)
|
||||||
|
# + (erzeuge eine neue Liste)
|
||||||
|
print(id(l1))
|
||||||
|
l1 = l1 + [1]
|
||||||
|
print(id(l1))
|
||||||
|
print(l1)
|
||||||
|
print(l2)
|
||||||
|
# best practise: append und extend
|
||||||
|
l1.append(15)
|
||||||
|
|
||||||
|
l1 = [1, 2, 3]
|
||||||
|
l2 = [4, 5, 6]
|
||||||
|
l1.extend([5, 8])
|
||||||
|
print(l1)
|
||||||
|
l1.extend("python") # jedes element einzeln eingefügt
|
||||||
|
print(l1)
|
||||||
|
l1.extend(["python"])
|
||||||
|
print(l1)
|
||||||
138
src/T01_Funktionen.py
Normal file
138
src/T01_Funktionen.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
# float: float oder integer
|
||||||
|
DEFAULT_B = 13 # all_caps
|
||||||
|
|
||||||
|
SPEED_OF_SOUND = 343
|
||||||
|
|
||||||
|
|
||||||
|
def divide(a, b):
|
||||||
|
# nicht überprüfen ob b != 0 da dies ein fehler ist!
|
||||||
|
return a / b
|
||||||
|
|
||||||
|
# : typehint
|
||||||
|
def convert_dog_to_human_age(dogage: int) -> int:
|
||||||
|
"""
|
||||||
|
Konvertiert ein Hundealter in Menschenjahren.
|
||||||
|
:param dogage: (int) Hundealter in Jahren
|
||||||
|
:return (int): Entsprechendes alter in Menschenjahren
|
||||||
|
Ein Hund ist immer ganze Jahre alt. z.B. 1, 2, 3, 4
|
||||||
|
"""
|
||||||
|
# assert oder raise
|
||||||
|
assert dogage >= 0, "ALter muss immer positiv sein"
|
||||||
|
# assert isinstance(dogage, int), "Muss integer sein"
|
||||||
|
human_age = 0 # lokale variable
|
||||||
|
if dogage == 1:
|
||||||
|
human_age = 14
|
||||||
|
elif dogage == 2:
|
||||||
|
human_age = 22
|
||||||
|
elif dogage > 2:
|
||||||
|
human_age = 22 + (dogage - 2) * 5
|
||||||
|
|
||||||
|
return human_age
|
||||||
|
|
||||||
|
def substract_mean(lst: list[float]) -> None:
|
||||||
|
mean = sum(lst) / len(lst)
|
||||||
|
for i in range(len(lst)):
|
||||||
|
lst[i] -= mean
|
||||||
|
# diese Zeile steht immer bei fehlendem return am Ende
|
||||||
|
return None
|
||||||
|
|
||||||
|
def create_mean_free_list(lst):
|
||||||
|
res = []
|
||||||
|
mean = sum(lst) / len(lst)
|
||||||
|
for el in lst:
|
||||||
|
res.append(el - mean)
|
||||||
|
return res
|
||||||
|
# positionelle argumente, schlüsselwort-argumente
|
||||||
|
def foo(a, b=DEFAULT_B, verbose=0):
|
||||||
|
# f-string
|
||||||
|
# formatted-string
|
||||||
|
print(f"a={a}")
|
||||||
|
print(f"{b=}")
|
||||||
|
print(f"{verbose=}")
|
||||||
|
print(f"a/b = {a/b}")
|
||||||
|
# r-string
|
||||||
|
return a / b
|
||||||
|
|
||||||
|
def open_file(file_path: str):
|
||||||
|
print(f"Opening {file_path}")
|
||||||
|
|
||||||
|
def food(bag=None, debug=False):
|
||||||
|
# is und nicht ==
|
||||||
|
# is vergleicht id
|
||||||
|
if debug:
|
||||||
|
print("Debug message")
|
||||||
|
if bag is None:
|
||||||
|
bag = []
|
||||||
|
bag.append("Spam")
|
||||||
|
return bag
|
||||||
|
|
||||||
|
def calculate_time(dist):
|
||||||
|
# 1. in der Funktion nach SPEED_OF_SOUND
|
||||||
|
# 2. Global im file + imports (selten nutzen)
|
||||||
|
# 3. im eingebauten namensraum
|
||||||
|
return dist / SPEED_OF_SOUND
|
||||||
|
|
||||||
|
|
||||||
|
def calc_circle_area(radius):
|
||||||
|
return 3.14 * radius ** 2
|
||||||
|
|
||||||
|
def calc_rect_area(height, width):
|
||||||
|
return height * width
|
||||||
|
|
||||||
|
def calc_area(shape, *sides: tuple[float], **kwargs):
|
||||||
|
print(kwargs, type(kwargs))
|
||||||
|
if "verbose" in kwargs:
|
||||||
|
verbose = kwargs.pop("verbose") # entfernt schlüssel verbose und gibt den dazugehörigen wert zurück
|
||||||
|
print(verbose)
|
||||||
|
if shape.lower() == "circle":
|
||||||
|
return calc_circle_area(*sides, **kwargs)
|
||||||
|
elif shape.lower() == "rectangle":
|
||||||
|
return calc_rect_area(*sides, **kwargs) # args[0], args[1]
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Shape {shape} is not yet supported, Circle, Rectangle")
|
||||||
|
|
||||||
|
def complete_function(pos_arg1, pos_argn, *args, kw1=True, kwn="N", **kwargs):
|
||||||
|
print(pos_arg1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
dst = 10
|
||||||
|
print("test")
|
||||||
|
t = "hello"
|
||||||
|
# Beispiele
|
||||||
|
print(__name__)
|
||||||
|
scooby_doo = 6
|
||||||
|
scooby_name = "Scooby doo"
|
||||||
|
scooby_doo_human = convert_dog_to_human_age(scooby_doo)
|
||||||
|
print(scooby_doo_human)
|
||||||
|
divide(5, 1)
|
||||||
|
numbers = [42, 14, 7, 11, 13, 39]
|
||||||
|
print(numbers, id(numbers))
|
||||||
|
res = numbers.copy()
|
||||||
|
substract_mean(res)
|
||||||
|
print(numbers)
|
||||||
|
numbers.insert(0, -1)
|
||||||
|
print(numbers)
|
||||||
|
foo(31, verbose=2)
|
||||||
|
foo(10, b=3)
|
||||||
|
foo(b=5, a=2) # nicht schreiben
|
||||||
|
datei = r"C:\neuer Ordner\neuesfile" # raw-string
|
||||||
|
open_file(datei)
|
||||||
|
res = food()
|
||||||
|
print(res)
|
||||||
|
res2 = food()
|
||||||
|
print(res2)
|
||||||
|
res3 = food()
|
||||||
|
print(res3)
|
||||||
|
print(res)
|
||||||
|
l1 = [101, 102, 103]
|
||||||
|
l2 = [101, 102, 103]
|
||||||
|
print(l1 == l2)
|
||||||
|
t = calculate_time(10)
|
||||||
|
print(t)
|
||||||
|
area = calc_area("rectangle", 5, 2)
|
||||||
|
print(area)
|
||||||
|
area = calc_area("circle", 4, verbose=True)
|
||||||
|
print(area)
|
||||||
|
rect = [6, 2]
|
||||||
|
ra = calc_rect_area(*rect)
|
||||||
|
print(ra)
|
||||||
72
src/T02_Datentypen.py
Normal file
72
src/T02_Datentypen.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from copy import deepcopy
|
||||||
|
# Listen
|
||||||
|
l = ["python", 42,18, 4, 2, 19]
|
||||||
|
print(l[0])
|
||||||
|
print(l[2:4]) # inklusive:exklusive
|
||||||
|
print(len(l))
|
||||||
|
for i in range(len(l)):
|
||||||
|
print(i, l[i])
|
||||||
|
l2 = [[1, 2, 3], [10, 11, 12]]
|
||||||
|
print(l2)
|
||||||
|
print(l2[0])
|
||||||
|
print(l2[0][1])
|
||||||
|
# kopien von veschachtelten strukturen
|
||||||
|
l_copy = l2.copy()
|
||||||
|
l_copy[0][0] = 10
|
||||||
|
print(l2)
|
||||||
|
# was ist eine Liste
|
||||||
|
# sammlung an verweise
|
||||||
|
|
||||||
|
|
||||||
|
l2 = [[1, 2, 3], [10, 11, 12]]
|
||||||
|
print(l2)
|
||||||
|
print(l2[0])
|
||||||
|
print(l2[0][1])
|
||||||
|
# kopien von veschachtelten strukturen
|
||||||
|
l_copy = deepcopy(l2)
|
||||||
|
l_copy[0][0] = 10
|
||||||
|
print(l2)
|
||||||
|
# python ist objektorientiert aufgebaut
|
||||||
|
|
||||||
|
# Dictionaries (ungeordnete Datenstruktur)
|
||||||
|
prices = {"bananas": 2.19, "oranges": 3.39, "ice-cream": 2.79, 0:"zero"}
|
||||||
|
print(prices["oranges"])
|
||||||
|
print(len(prices))
|
||||||
|
print(prices)
|
||||||
|
print(prices[0])
|
||||||
|
# hinzufügen von schlüsselwertpaaren
|
||||||
|
prices["ice-tea"] = 0.99
|
||||||
|
print(prices)
|
||||||
|
prices["bananas"] = 2.49 # update den wert
|
||||||
|
print(prices["bananas"])
|
||||||
|
print(prices)
|
||||||
|
prices.pop(0)
|
||||||
|
print(prices)
|
||||||
|
# über ein dictionary iterieren
|
||||||
|
for product in prices: # über die schlüssel
|
||||||
|
print(f"{product:10s} {prices[product]:7.2f}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
for product, price in prices.items():
|
||||||
|
print(f"{product:10s} {price:7.2f}")
|
||||||
|
reduced_price = price * 0.9
|
||||||
|
|
||||||
|
product_names = ["bananas", "oranges", "ice-cream", "ice_tea"]
|
||||||
|
# gibt es ein element in einer Liste bzw. einen Schlüssel in einem dictionary
|
||||||
|
# in bei listen ist eine for-schleife (lineare Laufzeit)
|
||||||
|
if "coffee" in product_names:
|
||||||
|
print("Coffee available")
|
||||||
|
else:
|
||||||
|
print("Coffee not available")
|
||||||
|
|
||||||
|
# in bei dict: konstante Zeit
|
||||||
|
if "coffee" in prices: # überprüft nur schlüssel
|
||||||
|
print("Coffee available")
|
||||||
|
else:
|
||||||
|
print("Coffee not available")
|
||||||
|
|
||||||
|
# oder set (merkt sich nicht die reihenfolge des einfügens)
|
||||||
|
|
||||||
|
# schlüssel im dictionary:
|
||||||
|
# 1. unveränderlich
|
||||||
|
# 2. hashable
|
||||||
81
src/T03_Klassen.py
Normal file
81
src/T03_Klassen.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
# PascalCase
|
||||||
|
class Robot:
|
||||||
|
# alle funktionen mit unterstrichen links und rechts müssen exakt so heißen
|
||||||
|
def __init__(self, name):
|
||||||
|
print(f"Creating a new robot named {name}")
|
||||||
|
# sollten immer alle attribute initialisiert werden
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def say_hi(self):
|
||||||
|
print(f"Hello, I'm a robot called {self.name}")
|
||||||
|
|
||||||
|
r1 = Robot("Bender") # führt die init-funktion aus
|
||||||
|
print(r1.name)
|
||||||
|
r1.say_hi() # r1 -> Robot -> Robot.say_hi(r1)
|
||||||
|
Robot.say_hi(r1) # wird so nie geschrieben
|
||||||
|
# Attribute können zu jeder Zeit geändert werden
|
||||||
|
r1.name = "Calculon"
|
||||||
|
r1.say_hi()
|
||||||
|
# 2 eigene Klassen schreiben
|
||||||
|
# Circle und Rectangle
|
||||||
|
# radius
|
||||||
|
# Rectangle hat die Attribute: height, width
|
||||||
|
# beide Klassen haben die Funktionen:
|
||||||
|
# calc_area() # kreis: pi*radius**2 3.14
|
||||||
|
# calc_perimeter() # 2 * pi * radius
|
||||||
|
import math
|
||||||
|
class Circle:
|
||||||
|
def __init__(self, radius):
|
||||||
|
self.radius = radius
|
||||||
|
self.area = 0
|
||||||
|
|
||||||
|
def calc_area(self):
|
||||||
|
self.area = 3.14 * self.radius ** 2 # ^,|,& -> binäre operatoren
|
||||||
|
return self.area
|
||||||
|
|
||||||
|
def calc_perimeter(self):
|
||||||
|
return 2 * 3.14 * self.radius
|
||||||
|
|
||||||
|
class Rectangle:
|
||||||
|
def __init__(self, width, height):
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
def calc_area(self):
|
||||||
|
area = self.width * self.height
|
||||||
|
return area
|
||||||
|
|
||||||
|
def calc_perimeter(self):
|
||||||
|
perimeter = 2 * (self.width + self.height)
|
||||||
|
return perimeter
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("-"*100)
|
||||||
|
c1 = Circle(2)
|
||||||
|
c2 = Circle(3.2)
|
||||||
|
print(c1.radius)
|
||||||
|
area = c1.calc_area() # Circle.calc_area(c1)
|
||||||
|
print(area)
|
||||||
|
perimeter = c1.calc_perimeter()
|
||||||
|
print(perimeter)
|
||||||
|
print(c1.calc_area() > c2.calc_area())
|
||||||
|
|
||||||
|
print(c1.radius, c1.area)
|
||||||
|
c1.radius += 1 # daran denken die fläche zu berechnen
|
||||||
|
print(c1.radius, c1.area)
|
||||||
|
|
||||||
|
r1 = Rectangle(3, 9)
|
||||||
|
print(r1.width)
|
||||||
|
print(r1.calc_area(), r1.calc_perimeter())
|
||||||
|
|
||||||
|
# inkorrekte Zustände
|
||||||
|
r1.width -= 12
|
||||||
|
print(r1.calc_area(), r1.calc_perimeter())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# rectangle ohne oop
|
||||||
|
r = [4, 2] # h, w oder w,h?
|
||||||
|
r = {"height": 4, "width": 2}
|
||||||
99
src/T04_Klassen_privat.py
Normal file
99
src/T04_Klassen_privat.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
# PascalCase
|
||||||
|
class Robot:
|
||||||
|
# alle funktionen mit unterstrichen links und rechts müssen exakt so heißen
|
||||||
|
def __init__(self, name):
|
||||||
|
print(f"Creating a new robot named {name}")
|
||||||
|
# __ führt dazu das ein Attribut privat ist
|
||||||
|
# bedeutet, es kann nur innerhalb der Klasse genutzt werden
|
||||||
|
self.__name = name
|
||||||
|
self.set_name(name)
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
def set_name(self, name):
|
||||||
|
if len(name) < 6:
|
||||||
|
raise ValueError("RObot name has to have at least 6 characters")
|
||||||
|
self.__name = name
|
||||||
|
|
||||||
|
def say_hi(self):
|
||||||
|
print(f"Hello, I'm a robot called {self.__name}")
|
||||||
|
|
||||||
|
|
||||||
|
r1 = Robot("Bender") # führt die init-funktion aus
|
||||||
|
print(r1.__dict__)
|
||||||
|
r1.build_year = 2996
|
||||||
|
print(r1.__dict__)
|
||||||
|
print(r1.__dict__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(r1.get_name())
|
||||||
|
r1.say_hi() # r1 -> Robot -> Robot.say_hi(r1)
|
||||||
|
Robot.say_hi(r1) # wird so nie geschrieben
|
||||||
|
# Attribute können zu jeder Zeit geändert werden (nicht private)
|
||||||
|
r1.__name = "Calculon"
|
||||||
|
r1.say_hi()
|
||||||
|
# 2 eigene Klassen schreiben
|
||||||
|
# Circle und Rectangle
|
||||||
|
# radius
|
||||||
|
# Rectangle hat die Attribute: height, width
|
||||||
|
# beide Klassen haben die Funktionen:
|
||||||
|
# calc_area() # kreis: pi*radius**2 3.14
|
||||||
|
# calc_perimeter() # 2 * pi * radius
|
||||||
|
import math
|
||||||
|
class Circle:
|
||||||
|
def __init__(self, radius):
|
||||||
|
self.__radius = radius
|
||||||
|
self.set_radius(radius)
|
||||||
|
self.__area = 0
|
||||||
|
self.__area_computed = False
|
||||||
|
|
||||||
|
def get_radius(self):
|
||||||
|
return self.__radius
|
||||||
|
|
||||||
|
def set_radius(self, radius):
|
||||||
|
assert radius > 0, (f"Radius {radius}, was smaller 0")
|
||||||
|
self.__radius = radius
|
||||||
|
self.__area_computed = False
|
||||||
|
# area berechnen
|
||||||
|
|
||||||
|
def get_area(self):
|
||||||
|
if self.__area_computed:
|
||||||
|
return self.__area
|
||||||
|
print("Calculting the area")
|
||||||
|
self.__area = 3.14 * self.__radius ** 2 # ^,|,& -> binäre operatoren
|
||||||
|
self.__area_computed = True
|
||||||
|
return self.__area
|
||||||
|
|
||||||
|
def calc_perimeter(self):
|
||||||
|
return 2 * 3.14 * self.__radius
|
||||||
|
|
||||||
|
class Rectangle:
|
||||||
|
def __init__(self, width, height):
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
def calc_area(self):
|
||||||
|
area = self.width * self.height
|
||||||
|
return area
|
||||||
|
|
||||||
|
def calc_perimeter(self):
|
||||||
|
perimeter = 2 * (self.width + self.height)
|
||||||
|
return perimeter
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("-"*100)
|
||||||
|
c1 = Circle(2)
|
||||||
|
area = c1.get_area() # Circle.calc_area(c1)
|
||||||
|
print(area)
|
||||||
|
print()
|
||||||
|
print(c1.get_area())
|
||||||
|
c1.set_radius(5)
|
||||||
|
print(c1.get_area())
|
||||||
|
# schönen weg mit properties
|
||||||
|
c1.set_radius(c1.get_radius() + 1)
|
||||||
|
c1.radius += 3 # fehleranfällig
|
||||||
|
# beides verbinden -> properties
|
||||||
|
# als dataclasses!
|
||||||
52
src/T05_Klassen_properties.py
Normal file
52
src/T05_Klassen_properties.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
class Circle:
|
||||||
|
def __init__(self, radius):
|
||||||
|
# keine normale Attributzuweisung
|
||||||
|
# versteckter Aufruf einer Funktion
|
||||||
|
self.radius = radius
|
||||||
|
|
||||||
|
@property
|
||||||
|
def radius(self):
|
||||||
|
print("Getting the radius")
|
||||||
|
return self.__radius
|
||||||
|
|
||||||
|
@radius.setter
|
||||||
|
def radius(self, radius):
|
||||||
|
print("Setting a new radius")
|
||||||
|
assert radius > 0, "Radius has to be positive"
|
||||||
|
self.__radius = radius
|
||||||
|
|
||||||
|
@property
|
||||||
|
def diameter(self):
|
||||||
|
return 2 * self.radius
|
||||||
|
|
||||||
|
@diameter.setter
|
||||||
|
def diameter(self, d):
|
||||||
|
self.radius = d / 2
|
||||||
|
|
||||||
|
@property
|
||||||
|
def area(self):
|
||||||
|
# keine teuren/langsamen operationen geschehen
|
||||||
|
return self.calc_area()
|
||||||
|
|
||||||
|
def calc_area(self):
|
||||||
|
area = 3.14 * self.radius ** 2
|
||||||
|
return area
|
||||||
|
|
||||||
|
def calc_perimeter(self):
|
||||||
|
return 3.14 * self.diameter
|
||||||
|
|
||||||
|
# muss str zurück geben
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Circle(radius={self.radius})"
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
c1 = Circle(2)
|
||||||
|
print(c1.radius)
|
||||||
|
c1.radius += 0.5
|
||||||
|
print(c1.diameter)
|
||||||
|
c1.diameter -= 1
|
||||||
|
print(c1) # -> entweder __str__ oder __repr__ definierens
|
||||||
|
c2 = Circle(2)
|
||||||
|
print(c1 == c2)
|
||||||
|
# beides verbinden -> properties
|
||||||
|
# als dataclasses!
|
||||||
46
src/T06_Klassen_dataclasses.py
Normal file
46
src/T06_Klassen_dataclasses.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Circle:
|
||||||
|
__radius: field(init=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def radius(self):
|
||||||
|
return self.__radius
|
||||||
|
|
||||||
|
@radius.setter
|
||||||
|
def radius(self, r):
|
||||||
|
assert r > 0, "Error radius < 0"
|
||||||
|
self.__radius = r
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
self.radius = self.__radius
|
||||||
|
print("Checking all attributes")
|
||||||
|
print(f"Checking {self.radius=}")
|
||||||
|
|
||||||
|
# def __init__(self, radius):
|
||||||
|
# self.__radius = radius
|
||||||
|
# self.__post_init__()
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Rectangle:
|
||||||
|
width: float
|
||||||
|
height: float
|
||||||
|
|
||||||
|
# automatisch ein __init__
|
||||||
|
# automatisch ein __repr__
|
||||||
|
# automatisch ein __eq__
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
c1 = Circle(2)
|
||||||
|
print(c1.radius)
|
||||||
|
c1.radius += 0.5
|
||||||
|
print(c1.radius)
|
||||||
|
print(c1)
|
||||||
|
# beides verbinden -> properties
|
||||||
|
r1 = Rectangle(2, 5)
|
||||||
|
print(r1.width, r1.height)
|
||||||
|
r1 = Rectangle(r1.width + 2, r1.height)
|
||||||
|
d = {r1: "Ein rechteck"}
|
||||||
|
d[c1] = "Ein Kreis" # __hash__
|
||||||
|
# als dataclasses!
|
||||||
113
src/T07_pandas.py
Normal file
113
src/T07_pandas.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import pandas as pd
|
||||||
|
# standardbibliothek
|
||||||
|
# Zwei Datenstrukturen
|
||||||
|
# Series (eine spalte)
|
||||||
|
|
||||||
|
# Dem Dataframe
|
||||||
|
|
||||||
|
cities = {"Stadt": ["London", "Berlin", "Madrid", "Rom",
|
||||||
|
"Paris", "Wien", "Bukarest", "Hamburg",
|
||||||
|
"Budapest", "Warsaw", "Barcelona",
|
||||||
|
"München", "Mailand"],
|
||||||
|
"Population": [8615246, 3562166, 3165235, 2874038,
|
||||||
|
2273305, 1805681, 1803425, 1760433,
|
||||||
|
1754000, 1740119, 1602386, 1493900,
|
||||||
|
1350680],
|
||||||
|
"Land": ["England", "Deutschland", "Spanien", "Italien",
|
||||||
|
"Frankreich", "Österreich", "Romanien",
|
||||||
|
"Deutschland", "Ungarn", "Polen", "Spanien",
|
||||||
|
"Deutschland", "Italien"]}
|
||||||
|
# erstellung des dataframes
|
||||||
|
cities_df = pd.DataFrame(cities)
|
||||||
|
|
||||||
|
# einfügen von neuen Spalten
|
||||||
|
areas = [1572, 892, 604, 1285, 105,415, 228, 755, 525, 517, 101, 310, 182]
|
||||||
|
# cities_df["Flaeche"] = areas # spalte an
|
||||||
|
print(cities_df)
|
||||||
|
# insert (position wo die spalte eingefügt wird, name, werte [skalar oder anzahl zeilen]
|
||||||
|
# insert(position, name, werte)
|
||||||
|
cities_df.insert(2, "Flaeche", areas) # wenn keine spalte namens flaeche existiert
|
||||||
|
# cities_df["Flaeche"] = -1 # keine überprüfung ob spalte existiert statt
|
||||||
|
print(cities_df)
|
||||||
|
print("-"*100)
|
||||||
|
# Setzen unseren eigenen Index
|
||||||
|
df2 = cities_df.set_index("Stadt", inplace=False) # standardwert
|
||||||
|
print(df2)
|
||||||
|
print(cities_df)
|
||||||
|
cities_df.set_index("Stadt", inplace=True)
|
||||||
|
print(cities_df)
|
||||||
|
print("\n", "*"*100)
|
||||||
|
# Selektion in Pandas
|
||||||
|
# spalten selektieren
|
||||||
|
print(cities_df["Population"])
|
||||||
|
print("-" * 100)
|
||||||
|
# Selektion von Zeilen
|
||||||
|
# nach index
|
||||||
|
print(cities_df.loc["Paris"])
|
||||||
|
# nach numerischen index
|
||||||
|
print()
|
||||||
|
print(cities_df.iloc[7])
|
||||||
|
print()
|
||||||
|
# slicing
|
||||||
|
# slicing bei loc benötigt eine der 2 Bedingungen
|
||||||
|
# * index muss einzigartig sein
|
||||||
|
# * sortiert sein
|
||||||
|
print(cities_df.loc["Rom":"Warsaw"]) # inklusiv:inklusiv
|
||||||
|
# ändern den index auf land
|
||||||
|
# 1) Index zurücksetzen
|
||||||
|
cities_df.reset_index(inplace=True)
|
||||||
|
cities_df.set_index("Land", inplace=True)
|
||||||
|
print(cities_df)
|
||||||
|
print(cities_df.loc["England":"Polen"])
|
||||||
|
|
||||||
|
cities_df.sort_index(inplace=True)
|
||||||
|
print("-"*100)
|
||||||
|
print(cities_df)
|
||||||
|
print(cities_df.loc["Deutschland":"Italien"])
|
||||||
|
print("-"*100)
|
||||||
|
print(cities_df.loc["Italien"])
|
||||||
|
print("-"*100)
|
||||||
|
print(cities_df.iloc[0:5])
|
||||||
|
|
||||||
|
|
||||||
|
cities_df = pd.DataFrame(cities)
|
||||||
|
cities_df["Flaeche"] = areas
|
||||||
|
print(cities_df)
|
||||||
|
cities_df.sort_values(by="Stadt", inplace=True)
|
||||||
|
print(cities_df)
|
||||||
|
print(cities_df.loc[4])
|
||||||
|
print(cities_df.iloc[4])
|
||||||
|
print("-"* 100)
|
||||||
|
print(cities_df)
|
||||||
|
# Selektion nach Information in Spalte
|
||||||
|
# boolsche Selektionsmaske
|
||||||
|
print(cities_df[cities_df["Population"] > 2e6])
|
||||||
|
print(cities_df[cities_df["Population"] > 2_000_000])
|
||||||
|
|
||||||
|
# Maske selbst
|
||||||
|
print(cities_df["Population"] > 2_000_000)
|
||||||
|
print()
|
||||||
|
print("-" * 100)
|
||||||
|
print(cities_df[
|
||||||
|
(cities_df["Population"] > 2_000_000) &
|
||||||
|
(cities_df["Flaeche"] > 1_000)
|
||||||
|
]) # 0000000000001 & 1000010000010001
|
||||||
|
|
||||||
|
# spalten mit strings (contains unterstützt regulären ausdrücke)
|
||||||
|
print(cities_df[cities_df["Land"].str.contains("[E|e]n")])
|
||||||
|
print(cities_df[cities_df["Land"] == "Spanien"])
|
||||||
|
print()
|
||||||
|
print("-" * 100)
|
||||||
|
spanische_staedte = cities_df[cities_df["Land"] == "Spanien"]
|
||||||
|
spanien_info = spanische_staedte[["Population", "Flaeche"]]
|
||||||
|
print(spanien_info.sum())
|
||||||
|
|
||||||
|
|
||||||
|
# & und
|
||||||
|
# | oder
|
||||||
|
# ^ exklusive_oder (1 + 1 == 0)
|
||||||
|
stadt_de_esp = cities_df[(cities_df["Land"] == "Spanien") | (cities_df["Land"] == "Deutschland")]
|
||||||
|
info = stadt_de_esp[["Population", "Flaeche"]]
|
||||||
|
print(info)
|
||||||
|
print(info.sum())
|
||||||
|
|
||||||
25
src/T08_WorldCities.py
Normal file
25
src/T08_WorldCities.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import pandas
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
world_cities = pd.read_excel("../data/worldcities.xlsx")
|
||||||
|
print(world_cities)
|
||||||
|
print(world_cities.columns)
|
||||||
|
print(f"{world_cities['city']}")
|
||||||
|
|
||||||
|
# conda install openpyxl
|
||||||
|
# 1) Wie viele Einwohner haben alle Deutschen Städte?
|
||||||
|
# XYZ
|
||||||
|
|
||||||
|
# 2) Wie viele Einwohner leben auf der nördlichen/Südlichen Halbkugel
|
||||||
|
|
||||||
|
# 3) Welche Städte sind nördlich von Berlin und größer (Einwohner) als Berlin?
|
||||||
|
# New-York
|
||||||
|
# Istanbul
|
||||||
|
# Rom
|
||||||
|
|
||||||
|
# funktion
|
||||||
|
# -> raise
|
||||||
|
# -> assert
|
||||||
|
|
||||||
|
val = world_cities[(world_cities["city"] == "Berlin") & (world_cities["country"] == "Germany")]["population"].iloc[0]
|
||||||
|
print(type(val))
|
||||||
Loading…
Reference in New Issue
Block a user