Wypłaty pracowników

Zadanie 6 z 7 · rozdział 19Trudność: 2 z 3dziedziczeniepolimorfizmfabryka

Treść zadania

Zaprojektuj hierarchię klas pracowników:

  • Pracownik — klasa bazowa. Konstruktor __init__(self, imie) zapamiętuje imię. Metoda wyplata() zgłasza wyjątek NotImplementedError (każda klasa potomna musi ją nadpisać). Metoda opis() zwraca napis
    <imię> (<rodzaj>): <wypłata>, gdzie <rodzaj> to atrybut klasy rodzaj, a wypłata jest wypisana z dokładnością do 2 miejsc po przecinku. Metoda opis() jest zdefiniowana tylko w klasie Pracownik.
  • Etatowy(imie, pensja) — rodzaj = "etatowy"; wypłata to stała miesięczna pensja.
  • Godzinowy(imie, stawka, godziny) — rodzaj = "godzinowy"; za pierwsze 160 godzin płacimy zwykłą stawkę, a za każdą godzinę powyżej 160 (nadgodziny) — stawkę 1,5 razy wyższą:
    $w = s \cdot g$ dla $g \le 160$ oraz $w = 160 s + 1.5 s (g - 160)$ dla $g > 160$.
  • Stazysta(imie) — rodzaj = "stażysta"; wypłata to stałe stypendium 1500 zł, takie samo dla każdego stażysty.

Napisz też funkcję-fabrykę utworz_pracownika(linia), która na podstawie jednej linii wejścia tworzy i zwraca obiekt odpowiedniej klasy.

Program wczytuje listę pracowników, wypisuje opis każdego z nich (w kolejności z wejścia) i sumę wszystkich wypłat.

Dane wejściowe

  • 1. linia: liczba pracowników $n$
  • kolejne $n$ linii, każda w jednej z postaci:
    • etatowy IMIĘ PENSJA
    • godzinowy IMIĘ STAWKA GODZINY
    • stazysta IMIĘ

Imię to jedno słowo, pensja i stawka to liczby rzeczywiste, a liczba godzin to liczba całkowita $\ge 0$.

Dane wyjściowe

  • $n$ linii — wynik metody opis() dla kolejnych pracowników,
  • ostatnia linia: Suma wypłat: <suma> (z dokładnością do 2 miejsc po przecinku).

Ograniczenia

  • $1 \le n \le 50$
  • $0 \le pensja \le 100000$, $0 \le stawka \le 1000$, $0 \le godziny \le 400$

Uwagi

  • Funkcja-fabryka ukrywa przed resztą programu, jak powstają obiekty: program tylko woła utworz_pracownika(linia) i dostaje gotowy obiekt, a dalej korzysta wyłącznie z metod wspólnych dla wszystkich pracowników (opis(), wyplata()). Dodanie nowego rodzaju pracownika wymaga wtedy zmian tylko w nowej klasie i w fabryce.
  • raise NotImplementedError w klasie bazowej to umowny sposób zapisania: „ta metoda musi zostać nadpisana w klasie potomnej”.

Przykład

Wejście
4
etatowy Anna 5200
godzinowy Bartek 40 170
stazysta Celina
godzinowy Darek 35.5 100
Wyjście
Anna (etatowy): 5200.00
Bartek (godzinowy): 7000.00
Celina (stażysta): 1500.00
Darek (godzinowy): 3550.00
Suma wypłat: 17250.00

Bartek przepracował 10 nadgodzin: $160 \cdot 40 + 10 \cdot 1.5 \cdot 40 = 6400 + 600 = 7000$.

Zasady obowiązujące w rozdziale 19

Zadania w tym rozdziale uczą dziedziczenia: klasa potomna przejmuje atrybuty i metody klasy bazowej, może je nadpisać (override) albo rozszerzyć, wywołując wersję z klasy bazowej przez super(). Dzięki polimorfizmowi ten sam kod (np. pętla po liście obiektów) wywołuje metodę odpowiednią dla konkretnej klasy obiektu. Dziedziczenie przydaje się też przy wyjątkach: własne wyjątki to klasy dziedziczące po Exception, które można układać w hierarchie.

Konwencje wspólne:

  • Każde zadanie to osobny program: czyta standardowe wejście i wypisuje wynik na standardowe wyjście.
  • W każdym zadaniu dostajesz kod startowy ze szkieletami klas i gotowym wczytywaniem danych. Twoim zadaniem jest uzupełnienie klas — wynik programu zależy od tego, jak działają Twoje klasy.
  • Nazwy klas i metod podane w treści są obowiązkowe (kod startowy z nich korzysta). Nazwy w kodzie piszemy bez polskich znaków, np. Kolo, Czlowiek.
  • „Z dokładnością do 2 miejsc po przecinku” oznacza dokładnie dwie cyfry po kropce, np. f"{x:.2f}" (3.00, 4.50).
  • Program nie wypisuje komunikatów typu „Podaj liczbę:”.

Zadanie pochodzi z otwartego zbioru Nauka-Programowania (z rozwiązaniami wzorcowymi). Zgłoś błąd w treści lub testach.

Python uruchomi się w przeglądarce przy pierwszym teście.

Kod zapisuje się automatycznie w tej przeglądarce. Tab wstawia wcięcie; aby opuścić edytor klawiaturą, naciśnij Esc, a potem Tab.

Testy

Program dostaje „Wejście” przez input() i musi wypisać „Oczekiwane wyjście”. Liczby porównywane są z tolerancją 0,01, a tekst podany w input("…") nie jest sprawdzany.

Test 1

Nie uruchomiono
Wejście
1
stazysta Ewa
Oczekiwane wyjście
Ewa (stażysta): 1500.00
Suma wypłat: 1500.00

Test 2

Nie uruchomiono
Wejście
1
godzinowy Filip 30 160
Oczekiwane wyjście
Filip (godzinowy): 4800.00
Suma wypłat: 4800.00

Test 3

Nie uruchomiono
Wejście
2
godzinowy Gosia 50 161
etatowy Henryk 4321.50
Oczekiwane wyjście
Gosia (godzinowy): 8075.00
Henryk (etatowy): 4321.50
Suma wypłat: 12396.50

Test 4

Nie uruchomiono
Wejście
3
godzinowy Igor 28.40 0
stazysta Jola
etatowy Kamil 7000
Oczekiwane wyjście
Igor (godzinowy): 0.00
Jola (stażysta): 1500.00
Kamil (etatowy): 7000.00
Suma wypłat: 8500.00

Test 5

Nie uruchomiono
Wejście
3
godzinowy Lena 22.5 200
godzinowy Marek 22.5 150
stazysta Nina
Oczekiwane wyjście
Lena (godzinowy): 4950.00
Marek (godzinowy): 3375.00
Nina (stażysta): 1500.00
Suma wypłat: 9825.00
Uruchom z własnymi danymi