Ostatnia lekcja kursu: składamy w całość to, co już umiecie.
Specyfikacja: co gra dostaje i co ma wypisać
Losowanie liczby modułem random
Pętla while z licznikiem prób i podpowiedziami
Odporność na literówkę: try i except
Rozgrzewka · 3 minuty
Co pamiętacie z poprzedniej lekcji?
Czym różni się sortowanie bąbelkowe od sortowania przez wstawianie?
Dlaczego oba algorytmy sortowania zapisujemy w pętli, a nie jako ciąg osobnych linijek?
Co robi pętla while i jak policzyć w niej, ile razy się wykonała?
Część 1 · Specyfikacja i lista kroków
Zanim napiszemy pierwszą linijkę
Dane: liczba od 1 do 100 wylosowana przez komputer i kolejne liczby wpisywane przez gracza. Wynik: po każdej próbie podpowiedź „za mało” albo „za dużo”, a po trafieniu liczba prób.
Wylosuj liczbę całkowitą od 1 do 100. Zapamiętaj ją.
Ustaw licznik prób na 0.
Poproś gracza o liczbę.
Jeśli jest mniejsza od wylosowanej, wypisz „za mało”, a jeśli większa, „za dużo”. Wróć do kroku 3.
Gdy liczby są równe, wypisz komunikat o trafieniu i liczbę prób.
Podręcznik Informatyka na czasie 2 (Nowa Era), s. 97–98 (6.3 Tworzymy własne programy użytkowe, specyfikacja i lista kroków)
Część 2 · Moduł random
Komputer losuje liczbę
import random
number = random.randint(1, 100)
print("Wylosowana liczba:", number)
import random wnosi do programu moduł, czyli gotowy zestaw funkcji napisany przez kogoś innego.
random.randint(1, 100) oddaje losową liczbę całkowitą od 1 do 100, razem z obiema granicami. Trzy uruchomienia dały trzy różne liczby.
W praktyce: komputer nie losuje naprawdę. Liczy kolejne liczby z wzoru, który daje ciąg wyglądający na przypadkowy. Dlatego mówi się o generatorze pseudolosowym.
docs.python.org, The Python Tutorial, rozdz. 10.6 (Mathematics)
Część 2 · Pętla i licznik
Pytaj, dopóki nie trafi
number = random.randint(1, 100)
guess = 0
tries = 0
while guess != number:
guess = int(input("Twoja liczba: "))
tries = tries + 1
if guess < number:
print("Za mało.")
elif guess > number:
print("Za dużo.")
print("Trafione! Liczba prób:", tries)
guess = 0 to wartość startowa. Wylosowana liczba jest z zakresu 1–100, więc 0 na pewno nie jest trafieniem i pętla rusza.
Warunek guess != number czyta się „dopóki liczby są różne”.
tries = tries + 1 stoi wewnątrz pętli: rośnie po każdej próbie.
Ostatni print nie ma wcięcia, więc wykona się dopiero po wyjściu z pętli.
Podręcznik Informatyka na czasie 2 (Nowa Era), s. 225 (dodatek 7, pętla while, gra w odgadywanie imienia) · docs.python.org, The Python Tutorial, rozdz. 3.2 (First Steps Towards Programming)
Część 2 · if, elif, else
Jedna próba, trzy możliwe drogi
Trzecia droga nie ma w kodzie żadnego if. Gdy liczby są równe, warunek pętli guess != number przestaje być prawdziwy i pętla po prostu się kończy.
W praktyce: gracz, który za każdym razem podaje środek pozostałego zakresu, trafia liczbę z przedziału 1–100 najpóźniej w siódmej próbie. To wyszukiwanie binarne z lekcji 25.
Podręcznik Informatyka na czasie 2 (Nowa Era), s. 224 (dodatek 7, instrukcja warunkowa) · docs.python.org, The Python Tutorial, rozdz. 4.1 (if Statements)
Część 3 · Błędy wykonania
Gracz wpisuje „osiem”
Funkcja int zamienia napis na liczbę tylko wtedy, gdy napis składa się z cyfr. Napis „osiem” cyfr nie ma, więc Python przerywa program i zgłasza wyjątekValueError.
Twoja liczba: osiem
Traceback (most recent call last):
...
guess = int(input("Twoja liczba: "))
ValueError: invalid literal for int()
with base 10: 'osiem'
Para try i except przechwytuje taki wyjątek: program pisze własny komunikat i gra toczy się dalej.
text = input("Twoja liczba: ")
try:
guess = int(text)
tries = tries + 1
except ValueError:
print("To nie jest liczba.")
Licznik stoi w bloku try, więc literówka nie zużywa próby.
docs.python.org, The Python Tutorial, rozdz. 8.2 (Exceptions) i 8.3 (Handling Exceptions)
Część 3 · Gotowy program
Wszystko razem w jednym pliku
import random
number = random.randint(1, 100)
guess = 0
tries = 0
print("Zgadnij liczbę od 1 do 100.")
while guess != number:
text = input("Twoja liczba: ")
try:
guess = int(text)
tries = tries + 1
if guess < number:
print("Za mało.")
elif guess > number:
print("Za dużo.")
except ValueError:
print("To nie jest liczba, wpisz ją cyframi.")
print("Trafione! Liczba prób:", tries)
Zgadnij liczbę od 1 do 100.
Twoja liczba: 50
Za dużo.
Twoja liczba: 25
Za mało.
Twoja liczba: osiem
To nie jest liczba, wpisz ją cyframi.
Twoja liczba: 37
Za mało.
Twoja liczba: 43
Za dużo.
Twoja liczba: 42
Trafione! Liczba prób: 5
Przebieg dla liczby 42. Wpis „osiem” nie zwiększył licznika.
Podręcznik Informatyka na czasie 2 (Nowa Era), s. 224–225 (dodatek 7, instrukcja warunkowa i pętla while) · docs.python.org, The Python Tutorial, rozdz. 8.3 (Handling Exceptions)
Podsumowanie kursu
Skąd wzięła się każda linijka
Ani jedna instrukcja w tym programie nie jest nowa. Cały projekt to siedem rzeczy, które ćwiczyliście osobno, ustawione w jednej kolejności.
Ćwiczenie · przy komputerze · 12 minut
Ćwiczenie: Wasza wersja gry
Utwórz plik gra.py, przepisz program ze slajdu i uruchom go dwa razy. Za drugim razem wpisz celowo słowo zamiast liczby. Zapisz, co się stało z licznikiem prób.
Dopisz na końcu programu ocenę wyniku: dla siedmiu prób lub mniej pochwałę, w przeciwnym razie wskazówkę, żeby dzielić zakres na pół. Użyj if i else po pętli.
Dodaj podpowiedź „Jesteś bardzo blisko.”, gdy gracz pomylił się najwyżej o 3. Przyda się funkcja abs z lekcji 4, która podaje odległość dwóch liczb.
Jak to sprawdzić
Uruchom program w terminalu poleceniem python3 gra.py. Jeśli zobaczysz IndentationError, popraw wcięcia: każdy poziom to dokładnie cztery spacje, a linie pod try mają dwa poziomy wcięcia. Jeśli gra nigdy się nie kończy, sprawdź, czy w warunku pętli jest !=, a nie ==.
Sprawdzenie
Trzy pytania na koniec
Dlaczego przed pętlą ustawiamy guess = 0?
Gdzie w programie stoi tries = tries + 1 i dlaczego akurat tam?
Co się stanie, gdy gracz wpisze słowo zamiast liczby, i jak temu zapobiegamy?
Podsumowanie
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
try i except wokół int()
Formularz płatności pokazuje „wpisz kwotę cyframi” zamiast strony błędu, gdy ktoś wpisze tekst w pole kwoty
standard w firmach
while, dopóki warunek prawdziwy
Aplikacja ponawia wysyłkę wiadomości, dopóki serwer nie potwierdzi odbioru
codziennie
Licznik prób
Bank blokuje logowanie po trzeciej błędnej próbie hasła
codziennie
random.randint
Sklep losuje zwycięzcę konkursu, a gra mobilna losuje nagrodę ze skrzynki