Własny zakres iterowalny
Treść zadania
Zaprojektuj klasę Zakres — własny odpowiednik wbudowanej funkcji range() — po której obiektach można iterować pętlą for:
- Konstruktor
__init__(self, start, stop, krok=1)zapamiętuje parametry. Jeślikrokjest równy 0, zgłasza wyjątekValueError("Krok nie może być równy 0."). - Metoda
__iter__()jest generatorem — kolejne elementy zwraca instrukcjąyield:- dla kroku dodatniego: $start, start + krok, start + 2 \cdot krok, \dots$ — dopóki element jest mniejszy od $stop$,
- dla kroku ujemnego: $start, start + krok, \dots$ — dopóki element jest większy od $stop$.
Nie używaj w klasie wbudowanej funkcji range() — kolejne elementy wylicz samodzielnie.
Program dla każdego zapytania start stop krok tworzy obiekt Zakres i wypisuje jego elementy oraz ich sumę. Każde przejście pętlą for (a także wywołanie sum()) uruchamia generator od nowa, więc po jednym obiekcie można iterować wiele razy.
Dane wejściowe
- 1. linia: liczba zapytań $q$
- kolejne $q$ linii: trzy liczby całkowite
start stop krokoddzielone spacjami
Dane wyjściowe
Dla każdego zapytania jedna linia:
<elementy oddzielone spacjami> (suma: <suma>),pusty (suma: 0)— jeśli zakres nie zawiera żadnego elementu,Błąd: Krok nie może być równy 0.— jeśli konstruktor zgłosił wyjątek.
Ograniczenia
- $1 \le q \le 20$
- $-1000 \le start, stop, krok \le 1000$
Uwagi
- Pętla
for x in obiekt:wywołuje najpierwiter(obiekt), czyli metodęobiekt.__iter__(), a potem pobiera z otrzymanego iteratora kolejne elementy. - Funkcja (lub metoda), która zawiera
yield, jest generatorem: jej wywołanie nie wykonuje od razu kodu, tylko zwraca iterator. Każdeyield„oddaje” jeden element i wstrzymuje funkcję do czasu, aż pętla poprosi o następny:
```python
def odliczanie(n):
while n > 0:
yield n
n -= 1
for x in odliczanie(3):
print(x) # 3, 2, 1 (w osobnych liniach)` - Wyjątek zgłoszony w konstruktorze przechwytuje program główny w bloku
try/except(zob. zadanie „Konto bankowe”).
Przykład
4 1 10 2 10 0 -3 5 5 1 0 5 0
1 3 5 7 9 (suma: 25) 10 7 4 1 (suma: 22) pusty (suma: 0) Błąd: Krok nie może być równy 0.
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 0 1 1
0 (suma: 0)
Test 2
Nie uruchomiono2 -5 5 5 3 -3 -2
-5 0 (suma: -5) 3 1 -1 (suma: 3)
Test 3
Nie uruchomiono3 1 5 -1 7 7 -1 0 -4 0
pusty (suma: 0) pusty (suma: 0) Błąd: Krok nie może być równy 0.
Test 4
Nie uruchomiono2 0 20 7 -1 -10 -4
0 7 14 (suma: 21) -1 -5 -9 (suma: -15)
Test 5
Nie uruchomiono1 100 0 -25
100 75 50 25 (suma: 250)