Koszyk zakupów (dataclass)
Treść zadania
Zaprojektuj dwie klasy danych (@dataclass):
Produktz polaminazwa: str,cena: float,ilosc: intoraz metodąwartosc(), która zwraca $cena \cdot ilosc$.Koszykz polemprodukty: list, które domyślnie jest pustą listą (field(default_factory=list)), oraz metodami:dodaj(produkt)— jeśli w koszyku jest już produkt o tej samej nazwie, zwiększa jego ilość oprodukt.ilosc; w przeciwnym razie dopisuje produkt na koniec listy,suma()— zwraca łączną wartość wszystkich produktów,wypisz_paragon()— wypisuje paragon (format poniżej).
Program wczytuje kolejne pozycje zakupów, dodaje je do koszyka i wypisuje paragon.
Dane wejściowe
- 1. linia: liczba pozycji $n$
- kolejne $n$ linii:
nazwa cena ilosc— nazwa produktu (bez spacji), cena (liczba rzeczywista z co najwyżej 2 miejscami po przecinku) i ilość (liczba całkowita), oddzielone spacjami
Dane wyjściowe
- Dla każdego produktu w koszyku (w kolejności pierwszego pojawienia się na wejściu) jedna linia, w której kolejno:
- nazwa wyrównana do lewej w polu o szerokości 10 znaków,
- spacja i ilość wyrównana do prawej w polu o szerokości 3,
xi cena z 2 miejscami po przecinku, wyrównana do prawej w polu o szerokości 7,=i wartość z 2 miejscami po przecinku, wyrównana do prawej w polu o szerokości 8.
- Linia złożona z 35 znaków
-. - Linia
Razem: <suma>(suma z 2 miejscami po przecinku).
Ograniczenia
- $1 \le n \le 20$
- Nazwa ma od 1 do 10 znaków. Produkty o tej samej nazwie mają zawsze tę samą cenę.
- $0.01 \le cena \le 999.99$, $1 \le ilosc$, a łączna ilość każdego produktu w koszyku nie przekracza 99.
Uwagi
- Dekorator
@dataclass(z modułudataclasses) sam tworzy konstruktor__init__, metodę__repr__i porównanie__eq__na podstawie pól zapisanych z adnotacją typu:
```python
from dataclasses import dataclass
@dataclass
class Punkt:
x: int
y: int = 0
p = Punkt(3)
print(p) # Punkt(x=3, y=0)
print(p == Punkt(3, 0)) # True` - Pole z listą nie może mieć wartości domyślnej
[]— taka jedna lista byłaby wspólna dla wszystkich obiektów klasy (dlatego@dataclasszgłasza wtedy błąd).field(default_factory=list)sprawia, że każdy nowy obiekt dostaje własną, nową pustą listę. - Szerokość pola i wyrównanie ustawisz w f-stringu:
f"{tekst:<10}"(do lewej, 10 znaków),f"{liczba:>3}"(do prawej, 3 znaki),f"{x:>8.2f}"(do prawej, 8 znaków, 2 miejsca po przecinku).
Przykład
5 chleb 3.50 2 mleko 2.99 3 ser 12.00 1 chleb 3.50 1 jajka 0.89 10
chleb 3 x 3.50 = 10.50 mleko 3 x 2.99 = 8.97 ser 1 x 12.00 = 12.00 jajka 10 x 0.89 = 8.90 ----------------------------------- Razem: 40.37
Dwie pozycje chleb zostały scalone w jedną (2 + 1 = 3 sztuki).
Potrzebujesz teorii?
Zasady obowiązujące w rozdziale 18
Zadania w tym rozdziale uczą projektowania klas: konstruktora __init__, atrybutów, metod, metod statycznych (@staticmethod) oraz metod specjalnych, dzięki którym obiekty można wypisywać (__str__), porównywać (__eq__) i łączyć operatorami (__add__, __sub__, __mul__, …). Ostatnie zadania wprowadzają też wyjątki (raise, try/except), klasy danych (@dataclass) i generatory (yield).
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 szkieletem klasy, a zwykle także z gotowym wczytywaniem danych i wypisywaniem wyników. Twoim zadaniem jest przede wszystkim uzupełnienie metod klasy — wynik programu zależy od tego, jak działa Twoja klasa.
- 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,Prostokat. - „Z dokładnością do 2 miejsc po przecinku” oznacza dokładnie dwie cyfry po kropce, np.
f"{x:.2f}"(3.00,-0.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.
Przywrócono Twój zapisany kod.
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 uruchomiono1 woda 1.99 1
woda 1 x 1.99 = 1.99 ----------------------------------- Razem: 1.99
Test 2
Nie uruchomiono3 kawa 24.99 1 kawa 24.99 2 kawa 24.99 3
kawa 6 x 24.99 = 149.94 ----------------------------------- Razem: 149.94
Test 3
Nie uruchomiono4 banan 0.50 6 jablko 0.75 4 banan 0.50 6 gruszka 1.20 5
banan 12 x 0.50 = 6.00 jablko 4 x 0.75 = 3.00 gruszka 5 x 1.20 = 6.00 ----------------------------------- Razem: 15.00
Test 4
Nie uruchomiono3 czekolada 4.49 2 masło 7.99 1 czekolada 4.49 1
czekolada 3 x 4.49 = 13.47 masło 1 x 7.99 = 7.99 ----------------------------------- Razem: 21.46
Test 5
Nie uruchomiono2 telewizor 999.99 99 kabel 15.00 2
telewizor 99 x 999.99 = 98999.01 kabel 2 x 15.00 = 30.00 ----------------------------------- Razem: 99029.01