class Osoba:
    def __init__(self, imie, nazwisko, wiek):
        self.imie = imie
        self.nazwisko = nazwisko
        self.wiek = wiek

    def __str__(self):
        return f'{self.imie} {self.nazwisko} ({self.wiek} lat)'

    def przedstaw_sie(self):
        print(f'Nazywam się {self.imie} {self.nazwisko} i mam {self.wiek} lat.')

    def jest_pelnoletnia(self):
        return self.wiek >= 18


class Student(Osoba):
    def __init__(self, imie, nazwisko, wiek, rok, kierunek):
        # Podczas inicjowania obiektu Student powinniśmy wywołać init z klasy Osoba i przekazać do niego wymagane parametry.
        super().__init__(imie, nazwisko, wiek)
        self.rok = rok
        self.kierunek = kierunek
        self.oceny = []

    # Klasa podrzędna może:
    # a) niczego nie zmieniać w odziedziczonej metodzie - np. nie zmieniamy "jest_pelnoletnia"

    # b) dodać nowe metody - obsługa ocen
    def dodaj_ocene(self, ocena):
        self.oceny.append(ocena)

    def srednia_ocen(self):
        import statistics
        if not self.oceny:
            return None
        return statistics.mean(self.oceny)

    # c) nadpisać (override) metodę, czyli zmienić jej implementację na inną
    def przedstaw_sie(self):
        # możliwe jest: super().przedstaw_sie()
        print(f'Hej, tu {self.imie} {self.nazwisko}, studiuję {self.kierunek}.')


class Sklep:
    def __init__(self, nazwa):
        self.nazwa = nazwa
        self.cennik = {}
        self.kasa = 0

    def zdefiniuj_produkt(self, produkt, cena):
        self.cennik[produkt] = cena

    def sprzedaj(self, produkt, klient, sztuk=1):
        if produkt not in self.cennik:
            print(f'Nieznany produkt: {produkt}')
        elif produkt in {'piwo'} and not klient.jest_pelnoletnia():
            print(f'Osobom niepełnoletnim nie sprzedajemy {produkt}')
        else:
            koszt = self.cennik[produkt] * sztuk
            print(f'Kliencie {klient.imie}, za swoje zakupy płacisz {koszt}')
            self.kasa += koszt


osoba = Osoba('Ala', 'Kowalska', 40)
student = Student('Bartek', 'Nowakowski', 20, 1, 'medycyna')
print('osoba:', osoba, 'typu', type(osoba))
print('student:', student, type(student))

# Zarówno obiekt osoba, jak i student, mają te atrybuty, które były zdefiniowane w klasie Osoba.
# Tylko obiekt typu Student posiada atrybuty dodane w klasie Student.
print('dane osoby:', osoba.imie, osoba.nazwisko)
#ERR print('dane osoby:', osoba.imie, osoba.nazwisko, osoba.kierunek)
print('dane studenta:', student.imie, student.nazwisko, student.kierunek)

# Tylko obiekty klasy Student posiadają dodatkową metodę srednia_ocen
#ERR print('średnia ocen osoby:', osoba.srednia_ocen())
student.dodaj_ocene(5)
student.dodaj_ocene(4)
student.dodaj_ocene(4)
print('średnia ocen studenta:', student.srednia_ocen())
print()

osoba.przedstaw_sie()
student.przedstaw_sie()

print('Przedstawimy studenta w taki sposób, jak przedstawia się osoba:')
Osoba.przedstaw_sie(student)
