INF.04-01-25.06-SGCzerwiec 2025 · 32 kroki · ok. 82 min · 32 kryteria z klucza
Rozwiązanie krok po kroku: Loteria liczbowa i wzornik RGB (Python + Tkinter)
Rozwiązanie dotyczy arkusza z loterią liczbową i wzornikiem kolorów w wersji Python + Tkinter - cały egzamin w jednym języku. W konsoli program, który wczytuje liczbę losowań, buduje listę zestawów po sześć różnych liczb z zakresu 1-49, wyświetla je i zlicza wystąpienia każdej liczby, a w okienku zbudowanym biblioteką Tkinter (jest w każdej instalacji Pythona na Windows) trzy suwaki R, G, B zmieniające kolor dużego prostokąta i przycisk „Pobierz”, który zapamiętuje kolor w małym prostokącie. Do tego dokumentacja funkcji według listingu 1, zrzuty i plik egzamin.
Kroki idą zdanie po zdaniu za treścią arkusza - każdy zaczyna się poleceniem z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Kod od początku jest pisany tak, jak w prawdziwych projektach; na końcu dwa kroki porównują ten wariant z rozwiązaniem w C# i WPF (druga zakładka) i podpowiadają, co wybrać na egzaminie.
Co widać w podglądzie. Program konsolowy z każdego kroku jest naprawdę uruchamiany (Python 3.12, z wpisaną liczbą 11 jak na obrazie 1 arkusza). Okno to symulacja w przeglądarce, ale jej układ nie jest zgadywany: program z kroku uruchomiłem w prawdziwym Tkinterze i odczytałem położenie, rozmiar, kolor i tekst każdej kontrolki. Suwaki i przycisk działają tak, jak funkcje z kodu kroku - scenariusz z obrazów 3-5 sprawdziłem w symulacji i w prawdziwym oknie Tk z tym samym wynikiem, a w kroku ze zrzutami jest prawdziwy zrzut okna.
Jak liczą się punkty. Klucz ma 32 kryteria (R.1.1 - R.4.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 24 punkty - można stracić 8 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Przygotowanie
Krok 1 · po tym etapie masz 0 z 32 kryteriów (pkt)
Krok 1: Folder zdającego i trzy podfoldery
ok. 2 min
Polecenie z arkusza
Utwórz folder i nazwij go numerem zdającego. W folderze utwórz podfoldery: konsolowa, desktopowa, dokumentacja. Po wykonaniu każdej aplikacji, jej pełny kod (cały folder projektu) spakuj do archiwum. Następnie pozostaw w podfolderze jedynie skopiowane z projektu pliki źródłowe, których treść była modyfikowana, plik wykonywalny, jeśli jest to możliwe, oraz spakowane archiwum.
Na pulpicie zakładasz folder z numerem PESEL, a w nim konsolowa, desktopowa i dokumentacja. Arkusz nie ma załącznika - wszystko piszesz od zera. Oba projekty zakładasz w PyCharm (każdy w osobnym folderze: konsola i desktopowa), a na koniec pakujesz je i kopiujesz do podfolderów razem z plikami main.py. Python jest językiem interpretowanym, więc pliku wykonywalnego nie ma - arkusz wymaga go tylko „jeśli jest to możliwe”.
Etap 2: Aplikacja konsolowa
Kroki 2-10 · po tym etapie masz 14 z 32 kryteriów (pkt)
Krok 2: Projekt konsola w PyCharm i funkcja main
ok. 3 min
Polecenie z arkusza
Zastosowany obiektowy język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym: C++ lub C#, lub Java, lub Python. W podejściu strukturalnym nie można stosować zmiennych globalnych.
Wybierasz Pythona i podejście strukturalne (same funkcje). W PyCharm: New Project, nazwa konsola, interpreter zainstalowany na stanowisku, bez skryptu powitalnego; w projekcie tworzysz plik main.py.
Arkusz zabrania zmiennych globalnych. W Pythonie każda zmienna utworzona poza funkcją - na „najwyższym poziomie” pliku - jest właśnie globalna. Dlatego program główny od razu zamykasz w funkcji main(), a jej wywołanie stawiasz pod warunkiem if __name__ == "__main__": (prawdziwym, gdy plik uruchomiono, a nie zaimportowano). Zmienne programu głównego będą wtedy lokalnymi zmiennymi main. Słowo pass to pusta instrukcja - ciało funkcji nie może być puste; za chwilę ją zastąpisz.
konsola/main.pyPythonnowy plik
defmain():passif__name__ == "__main__": main()
Wynik programu po tym kroku
> python main.py
Krok 3: Wczytanie liczby losowań z klawiatury
Kryteria: , ,
R.1.5 Zastosowane typy pasujące do problemu, np. tablica lub kolekcja liczb całkowitych, dane wczytywane jako typ całkowity
R.1.7 Program podejmuje zrozumiałą komunikację z użytkownikiem: komunikaty są znaczące, np. "ile losowań?" itp.
R.1.4 Użyte polskie lub angielskie nazewnictwo pól lub zmiennych. Nazewnictwo jest znaczące. Wyjątkami od reguły są zmienne bufor, tmp, iteratory pętli. Kryterium nie jest spełnione tylko wtedy, gdy zmienne nie istnieją lub ich nazwy nic nie znaczą, np. x, tab, tablica, foo, kolekcja
ok. 2 min
Polecenie z arkusza
Program wczytuje z klawiatury ile zestawów należy wylosować. Program powinien podejmować zrozumiałą komunikację z użytkownikiem.
Funkcja input(...) wypisuje pytanie i czeka na tekst zakończony Enterem. Zwraca zawsze napis - nawet gdy wpiszesz cyfry - dlatego otaczasz ją int(...), które zamienia tekst na liczbę całkowitą (R.1.5). Wynik trafia do zmiennej count z czytelną nazwą (R.1.4). W podglądzie wpisano 11, jak na obrazie 1 arkusza.
Typowe błędy
count = input(...) bez int zostawia napis „11” - przy range(count) Python zgłosi TypeError, bo pętla potrzebuje liczby.
R.2.1 Program składa się z programu głównego oraz co najmniej dwóch funkcji lub metod (mogą być niedokończone lub zawierać błędy). Po wyjściu z funkcji / metody losującej dane nie zostały utracone (w podejściu strukturalnym nie można stosować zmiennych globalnych)
R.2.2 Do przechowywania danych zastosowana tablica dwuwymiarowa lub inna kolekcja o dynamicznym rozmiarze dostosowanym do ilości danych
R.1.3 Użyte polskie lub angielskie nazewnictwo funkcji lub metod. Nazewnictwo jest znaczące
ok. 3 min
Polecenie z arkusza
Do przechowywania wyników losowań należy użyć dwuwymiarowej tablicy liczb całkowitych składającej się z n wierszy i 6 kolumn (n – liczba wczytana z klawiatury) lub innej dowolnej kolekcji pasującej do problemu. W programie należy zdefiniować przynajmniej dwie funkcje: Wypełniającą tablicę lub kolekcję danymi losowań.
Python nie ma wbudowanej tablicy dwuwymiarowej - jej odpowiednikiem jest lista list: zewnętrzna lista draws ma po jednym elemencie na losowanie, a każdy element to lista draw na sześć liczb. Arkusz dopuszcza wprost „inną kolekcję pasującą do problemu”, a lista rośnie do tylu wierszy, ile wpisał użytkownik (R.2.2).
Listę buduje osobna funkcja draw_numbers(count) i zwraca ją przez return; main zapisuje wynik w swojej zmiennej draws. Dane nie giną po wyjściu z funkcji, a żadna zmienna nie jest globalna (R.2.1). import random na górze pliku - moduł do losowania przyda się w następnym kroku. Na razie każdy zestaw jest pusty.
konsola/main.pyPythonzmienione: 12 linii
import randomdefdraw_numbers(count): draws = []for _ in range(count): draw = [] draws.append(draw)return drawsdefmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)if__name__ == "__main__": main()
Krok 5: Wypełnienie zestawów liczbami z zakresu 1-49
Kryteria: , , ,
R.2.3 Do losowania liczb zastosowany generator liczb pseudolosowych, losowane są liczby z przedziału od [1, 49] (+/- 1 z każdej strony przedziału)
R.2.4 Program wypełnia tablicę lub kolekcję danymi, pętla obsługuje rzeczywistą liczbę losowań
R.1.1 Kod źródłowy zapisany w sposób czytelny: instrukcje w osobnych liniach, stosowane spacje pomiędzy operatorami, konsekwentnie stosowana wybrana konwencja dla nawiasów klamrowych instrukcji blokowej
R.1.2 Kod zapisany z wcięciami dla zagnieżdżeń bloków
ok. 3 min
Polecenie z arkusza
Program generuje podaną liczbę zestawów składających się z sześciu losowanych liczb całkowitych ze zbioru <1, 49>. W programie należy użyć funkcji do generowania liczb pseudolosowych.
random.randint(1, 49) zwraca liczbę pseudolosową od 1 do 49 - w Pythonie obie granice wchodzą do zakresu (R.2.3), inaczej niż w C# (Next(1, 50)). append dokleja liczbę na koniec listy zestawu. Zewnętrzna pętla wykonuje się count razy - tyle zestawów, ile wpisał użytkownik (R.2.4), wewnętrzna sześć razy.
Podkreślnik _ to umowna nazwa zmiennej pętli, której nie używasz - klucz dopuszcza takie nazwy pomocnicze. Wcięcie o 4 spacje wyznacza w Pythonie, co należy do której pętli, więc jest częścią składni (R.1.1, R.1.2).
Typowe błędy
random.randrange(1, 49) wygląda podobnie, ale górnej granicy NIE obejmuje - 49 nigdy nie padnie. Klucz toleruje przesunięcie o 1 (R.2.3), ale dobrze znać różnicę: randint(a, b) to randrange(a, b + 1).
konsola/main.pyPythonzmienione: 2 linie
import randomdefdraw_numbers(count): draws = []for _ in range(count): draw = []for _ in range(6): draw.append(random.randint(1, 49)) draws.append(draw)return drawsdefmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)if__name__ == "__main__": main()
Krok 6: Funkcja print_draws: wyświetlenie wszystkich losowań
Kryteria: , ,
R.2.5 Program wyświetla zawartość tablicy lub kolekcji za pomocą pętli. Wyświetlone wszystkie losowania (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie)
R.2.1 Program składa się z programu głównego oraz co najmniej dwóch funkcji lub metod (mogą być niedokończone lub zawierać błędy). Po wyjściu z funkcji / metody losującej dane nie zostały utracone (w podejściu strukturalnym nie można stosować zmiennych globalnych)
R.1.3 Użyte polskie lub angielskie nazewnictwo funkcji lub metod. Nazewnictwo jest znaczące
ok. 3 min
Polecenie z arkusza
Zestawy są wyświetlone na ekranie. W programie należy zdefiniować przynajmniej dwie funkcje: Wyświetlającą wyniki wszystkich losowań na ekranie.
Druga funkcja dostaje listę jako parametr i tylko wypisuje - niczego nie zwraca. Pętla po liście z enumerate(draws, start=1) daje naraz numer (od 1, bo tak liczy użytkownik) i sam zestaw.
W print gwiazdka przed listą (*draw) rozpakowuje ją: sześć liczb trafia do print jako sześć osobnych argumentów, a ten rozdziela je spacjami - „Losowanie 1: 34 25 36 26 13 20” jak na obrazie 1. Bez gwiazdki wypisałaby się lista z nawiasami: [34, 25, 36, ...].
W wydruku zdarza się zestaw z tą samą liczbą dwa razy - losowania jeszcze się nie sprawdzają. Naprawisz to w następnym kroku.
konsola/main.pyPythonzmienione: 7 linii
import randomdefdraw_numbers(count): draws = []for _ in range(count): draw = []for _ in range(6): draw.append(random.randint(1, 49)) draws.append(draw)return drawsdefprint_draws(draws):for number, draw in enumerate(draws, start=1):print(f"Losowanie {number}:", *draw)defmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)print("Zestawy wylosowanych liczb:") print_draws(draws)if__name__ == "__main__": main()
R.2.6 Program implementuje losowanie przynajmniej jednego zestawu sześciu liczb bez powtórzeń
R.1.2 Kod zapisany z wcięciami dla zagnieżdżeń bloków
ok. 3 min
Polecenie z arkusza
W jednym zestawie liczby nie mogą się powtarzać.
Zamiast sześciu obrotów pętli for piszesz pętlę while len(draw) < 6 - kręci się, dopóki zestaw nie ma sześciu liczb. W każdym obrocie losujesz liczbę i dopisujesz ją tylko wtedy, gdy jeszcze jej nie ma: operator not in sprawdza, czy elementu nie ma na liście. Powtórzona liczba po prostu przepada, a pętla losuje ponownie (R.2.6).
Typowe błędy
Pętla for _ in range(6) z warunkiem if number not in draw (bez while) przy trafieniu na powtórkę zostawi zestaw z pięcioma liczbami - obrót się „zmarnuje”.
konsola/main.pyPythonzmienione: 4 linie
import randomdefdraw_numbers(count): draws = []for _ in range(count): draw = []whilelen(draw) < 6: number = random.randint(1, 49)if number not in draw: draw.append(number) draws.append(draw)return drawsdefprint_draws(draws):for number, draw in enumerate(draws, start=1):print(f"Losowanie {number}:", *draw)defmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)print("Zestawy wylosowanych liczb:") print_draws(draws)if__name__ == "__main__": main()
R.2.7 Program zlicza wystąpienia wszystkich liczb od 1 do 49 w losowaniach, są one wyświetlane na ekranie (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie, dopuszcza się wyświetlenie tylko niezerowych wystąpień)
ok. 3 min
Polecenie z arkusza
Program zlicza we wszystkich zestawach ile jest wystąpień każdej liczby od 1 do 49, co zostaje wyświetlone na ekranie.
Liczniki trzymasz w liście [0] * 50 - pięćdziesiąt zer - i indeksem jest sama liczba: wystąpienia siódemki są w occurrences[7]. Element 0 zostaje nieużywany, za to nie trzeba niczego przeliczać. Dwie pętle przechodzą przez wszystkie zestawy i wszystkie liczby, a occurrences[number] += 1 zwiększa licznik wylosowanej liczby. Wyświetlenie dopiszesz w następnym kroku.
konsola/main.pyPythonzmienione: 9 linii
import randomdefdraw_numbers(count): draws = []for _ in range(count): draw = []whilelen(draw) < 6: number = random.randint(1, 49)if number not in draw: draw.append(number) draws.append(draw)return drawsdefprint_draws(draws):for number, draw in enumerate(draws, start=1):print(f"Losowanie {number}:", *draw)defcount_occurrences(draws): occurrences = [0] * 50for draw in draws:for number in draw: occurrences[number] += 1return occurrencesdefmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)print("Zestawy wylosowanych liczb:") print_draws(draws) occurrences = count_occurrences(draws)if__name__ == "__main__": main()
R.2.7 Program zlicza wystąpienia wszystkich liczb od 1 do 49 w losowaniach, są one wyświetlane na ekranie (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie, dopuszcza się wyświetlenie tylko niezerowych wystąpień)
R.1.7 Program podejmuje zrozumiałą komunikację z użytkownikiem: komunikaty są znaczące, np. "ile losowań?" itp.
ok. 2 min
Polecenie z arkusza
Program powinien podejmować zrozumiałą komunikację z użytkownikiem.
range(1, 50) daje liczby od 1 do 49 - górna granica range nie wchodzi (odwrotnie niż w randint). f-napisf"Wystąpienia liczby {number}: ..." wstawia w miejsca w klamrach wartości zmiennych - forma jak na obrazie 1. Klucz dopuszcza też pokazanie tylko liczb, które padły (R.2.7). Program jest kompletny: suma wszystkich liczników to zawsze 6 × liczba losowań, tu 66.
konsola/main.pyPythonzmienione: 6 linii
import randomdefdraw_numbers(count): draws = []for _ in range(count): draw = []whilelen(draw) < 6: number = random.randint(1, 49)if number not in draw: draw.append(number) draws.append(draw)return drawsdefprint_draws(draws):for number, draw in enumerate(draws, start=1):print(f"Losowanie {number}:", *draw)defcount_occurrences(draws): occurrences = [0] * 50for draw in draws:for number in draw: occurrences[number] += 1return occurrencesdefprint_occurrences(occurrences):for number in range(1, 50):print(f"Wystąpienia liczby {number}: {occurrences[number]}")defmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)print("Zestawy wylosowanych liczb:") print_draws(draws) occurrences = count_occurrences(draws) print_occurrences(occurrences)if__name__ == "__main__": main()
Wynik programu po tym kroku
> python main.py
Ile wygenerować losowań? 11
Zestawy wylosowanych liczb:
Losowanie 1: 46 27 15 36 31 22
Losowanie 2: 44 31 9 24 35 37
Losowanie 3: 38 24 32 10 31 3
Losowanie 4: 36 4 32 15 44 38
Losowanie 5: 26 18 6 1 9 2
Losowanie 6: 8 32 9 30 46 14
Losowanie 7: 36 37 12 40 17 49
Losowanie 8: 35 14 1 33 37 29
Losowanie 9: 12 32 47 1 3 11
Losowanie 10: 43 21 27 29 3 13
Losowanie 11: 6 15 46 2 11 31
Wystąpienia liczby 1: 3
Wystąpienia liczby 2: 2
Wystąpienia liczby 3: 3
Wystąpienia liczby 4: 1
Wystąpienia liczby 5: 0
Wystąpienia liczby 6: 2
Wystąpienia liczby 7: 0
Wystąpienia liczby 8: 1
Wystąpienia liczby 9: 3
Wystąpienia liczby 10: 1
Wystąpienia liczby 11: 2
Wystąpienia liczby 12: 2
Wystąpienia liczby 13: 1
Wystąpienia liczby 14: 2
Wystąpienia liczby 15: 3
Wystąpienia liczby 16: 0
Wystąpienia liczby 17: 1
Wystąpienia liczby 18: 1
Wystąpienia liczby 19: 0
Wystąpienia liczby 20: 0
Wystąpienia liczby 21: 1
Wystąpienia liczby 22: 1
Wystąpienia liczby 23: 0
Wystąpienia liczby 24: 2
Wystąpienia liczby 25: 0
Wystąpienia liczby 26: 1
Wystąpienia liczby 27: 2
Wystąpienia liczby 28: 0
Wystąpienia liczby 29: 2
Wystąpienia liczby 30: 1
Wystąpienia liczby 31: 4
Wystąpienia liczby 32: 4
Wystąpienia liczby 33: 1
Wystąpienia liczby 34: 0
Wystąpienia liczby 35: 2
Wystąpienia liczby 36: 3
Wystąpienia liczby 37: 3
Wystąpienia liczby 38: 2
Wystąpienia liczby 39: 0
Wystąpienia liczby 40: 1
Wystąpienia liczby 41: 0
Wystąpienia liczby 42: 0
Wystąpienia liczby 43: 1
Wystąpienia liczby 44: 2
Wystąpienia liczby 45: 0
Wystąpienia liczby 46: 3
Wystąpienia liczby 47: 1
Wystąpienia liczby 48: 0
Wystąpienia liczby 49: 1
Krok 10: Folder konsolowa: archiwum i źródło
Kryteria:
R.4.9 Na płycie wszystkie wykonane projekty są spakowane oraz umieszczone pliki źródłowe i pliki wykonywalne (jeśli istnieją) na zewnątrz archiwów
ok. 3 min
Polecenie z arkusza
Kod aplikacji przygotuj do nagrania na płytę. W folderze konsolowa powinno znaleźć się archiwum całego projektu o nazwie konsola.zip, skopiowany z projektu plik z kodem źródłowym programu oraz plik wykonywalny, jeżeli istnieje.
Najpierw dopisujesz dokumentację funkcji z części III (krok niżej) - archiwum ma zawierać kod z komentarzem. Potem pakujesz cały folder projektu konsola do konsola.zip (w Eksploratorze: prawy przycisk → Kompresuj do pliku ZIP), a obok kopiujesz main.py. Pliku wykonywalnego w Pythonie nie ma; folder .venv, jeśli PyCharm go utworzył, można przed spakowaniem usunąć - to kopia interpretera, nie twój kod.
Kroki 11-25 · po tym etapie masz 21 z 32 kryteriów (pkt)
Krok 11: Projekt desktopowa: okno Tkinter
ok. 3 min
Polecenie z arkusza
Za pomocą dostępnego na stanowisku egzaminacyjnym środowiska programistycznego wykonaj aplikację desktopową wybierania kolorów z palety RGB.
Aplikację okienkową w Pythonie budujesz biblioteką Tkinter - jest częścią standardowej instalacji, nic nie trzeba doinstalowywać. W PyCharm zakładasz drugi projekt, desktopowa, z plikiem main.py. Trzy linie wystarczą na okno:
import tkinter as tk - importujesz bibliotekę pod krótką nazwą tk,
root = tk.Tk() - tworzysz okno główne; wszystkie kontrolki będą jego „dziećmi”,
root.mainloop() - pętla zdarzeń: okno czeka na kliknięcia i ruchy myszy, aż je zamkniesz. Musi być ostatnią linią programu - kod pod nią wykona się dopiero po zamknięciu okna.
W Tkinterze nie ma projektanta okien jak w Visual Studio - cały wygląd zapisujesz w kodzie. Podgląd pokazuje puste okno z domyślnym tytułem „tk”.
desktopowa/main.pyPythonnowy plik
import tkinter as tkroot = tk.Tk()root.mainloop()
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 12: Tytuł i rozmiar okna
Kryteria:
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
ok. 2 min
Polecenie z arkusza
Opis wyglądu aplikacji: Tytuł okna „Wzornik kolorów RGB. Wykonał” dalej wstawiony numer zdającego.
Metoda title okna ustawia napis na pasku tytułu. Na egzaminie po „Wykonał” wpisujesz numer PESEL - tu stoi autor rozwiązania, Bartosz Bryniarski. Plik zapisany w UTF-8 (domyślnie w PyCharm), więc polskie litery tytułu wyświetlają się poprawnie.
Od razu nadajesz oknu rozmiar: geometry("600x330") - szerokość × wysokość w pikselach, z małą literą x pomiędzy. Domyślne puste okno Tkintera ma 200 × 200 pikseli i z tak długiego tytułu zostałyby na pasku dwie litery. (Gdy rozmiaru nie podasz, a w oknie są już kontrolki, Tkinter dopasuje okno do nich - przy kilku kontrolkach byłoby wąskie, a suwaki krótkie.)
desktopowa/main.pyPythonzmienione: 2 linie
import tkinter as tkroot = tk.Tk()root.title("Wzornik kolorów RGB. Wykonał Bartosz Bryniarski")root.geometry("600x330")root.mainloop()
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 13: Tło okna Cornsilk
Kryteria:
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
ok. 1 min
Polecenie z arkusza
Tło okna: Cornsilk (#FFF8DC).
configure(bg="#FFF8DC") ustawia tło okna (bg to skrót od background). Tkinter zna też nazwy kolorów, więc bg="cornsilk" daje to samo - wpisujesz kod z arkusza, wtedy nie ma wątpliwości.
desktopowa/main.pyPythonzmienione: 1 linia
import tkinter as tkroot = tk.Tk()root.title("Wzornik kolorów RGB. Wykonał Bartosz Bryniarski")root.geometry("600x330")root.configure(bg="#FFF8DC")root.mainloop()
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 14: Duży biały prostokąt
Kryteria: ,
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
R.3.2 W stanie początkowym: - prostokąty są koloru białego, mały wyświetla wartość 255, 255, 255, - przynajmniej jeden suwak przyjmuje wartości od 0 do 255, - przynajmniej jeden suwak i odpowiadająca mu etykieta mają wartość 255
ok. 2 min
Polecenie z arkusza
Duży prostokąt o białym kolorze tła.
Prostokątem może być dowolna kontrolka z tłem (klucz, R.3.1). Bierzesz tk.Frame - pustą ramkę: pierwszy argument root mówi, w czym leży, bg="white" to białe tło, height=60 - wysokość.
Utworzona kontrolka jest jeszcze niewidoczna - trzeba ją ułożyć w oknie. Robi to menedżer układu pack: układa kontrolki jedna pod drugą, w kolejności wywołań. fill="x" rozciąga ramkę na całą szerokość, padx=20 odsuwa ją od lewej i prawej krawędzi, a pady=(20, 0) - para wartości - daje 20 pikseli odstępu od góry i 0 od dołu. Nazwa zmiennej color_rectangle przyda się, gdy kod będzie zmieniał kolor prostokąta.
Typowe błędy
Kontrolka bez pack() (albo grid()) istnieje w pamięci, ale nie pokazuje się w oknie - to najczęstszy powód „pustego okna” w Tkinterze.
desktopowa/main.pyPythonzmienione: 3 linie
import tkinter as tkroot = tk.Tk()root.title("Wzornik kolorów RGB. Wykonał Bartosz Bryniarski")root.geometry("600x330")root.configure(bg="#FFF8DC")color_rectangle = tk.Frame(root, bg="white", height=60)color_rectangle.pack(fill="x", padx=20, pady=(20, 0))root.mainloop()
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 15: Napis nad suwakami
Kryteria:
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
ok. 1 min
Polecenie z arkusza
Napis: „Dobierz kolor suwakami i zapisz przyciskiem:”
Napis to tk.Label z treścią w text. Etykieta ma własne tło - domyślnie szare - więc podajesz mu kolor okna, inaczej pod napisem byłby szary pasek. anchor="w" w pack przykleja etykietę do lewej krawędzi (w = west, zachód); bez tego pack stawia kontrolki na środku.
desktopowa/main.pyPythonzmienione: 3 linie
import tkinter as tkroot = tk.Tk()root.title("Wzornik kolorów RGB. Wykonał Bartosz Bryniarski")root.geometry("600x330")root.configure(bg="#FFF8DC")color_rectangle = tk.Frame(root, bg="white", height=60)color_rectangle.pack(fill="x", padx=20, pady=(20, 0))info_label = tk.Label(root, text="Dobierz kolor suwakami i zapisz przyciskiem:", bg="#FFF8DC")info_label.pack(anchor="w", padx=20, pady=(15, 5))root.mainloop()
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 16: Trzy suwaki 0-255 w siatce grid
Kryteria: ,
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
R.3.2 W stanie początkowym: - prostokąty są koloru białego, mały wyświetla wartość 255, 255, 255, - przynajmniej jeden suwak przyjmuje wartości od 0 do 255, - przynajmniej jeden suwak i odpowiadająca mu etykieta mają wartość 255
ok. 4 min
Polecenie z arkusza
Trzy suwaki, każdy o wartości początkowej 255 oraz zakresie wartości od 0 do 255.
Suwak ma po lewej literę, a po prawej wartość - to tabela 3 × 3. Wstawiasz więc ramkę sliders, a w niej układasz kontrolki drugim menedżerem układu, grid: row i column (liczone od 0) wskazują komórkę. columnconfigure(1, weight=1) każe kolumnie 1 zajmować całe wolne miejsce, a sticky="we" rozciąga suwak od lewej (w) do prawej (e) krawędzi komórki. W jednej ramce nie mieszasz pack i grid - dlatego siatka siedzi w osobnej ramce.
Suwak to tk.Scale: zakres from_=0 (z podkreśleniem, bo from jest w Pythonie słowem zarezerwowanym) i to=255, orient="horizontal" - poziomo. Wartość początkową ustawia set(255) (R.3.2). showvalue=False wyłącza liczbę rysowaną nad uchwytem - arkusz chce wartości w osobnej etykiecie po prawej. highlightthickness=0 usuwa ramkę zaznaczenia wokół suwaka.
Wartości Scale są całkowite (krok 1), więc nie trzeba niczego zaokrąglać.
Typowe błędy
tk.Scale(..., from=0, ...) to błąd składni - słowo from jest zarezerwowane (from ... import). Tkinter przyjmuje ten parametr jako from_.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 17: Etykiety R, G, B po lewej
Kryteria:
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
ok. 1 min
Polecenie z arkusza
Z lewej strony suwaków kolejno etykiety: R, G, B.
Trzy etykiety w kolumnie 0, po jednej w każdym wierszu. Ich treści nic nie zmienia, więc nie zapisujesz ich w zmiennych - grid wywołujesz od razu na utworzonej etykiecie. (Uwaga: tk.Label(...).grid(...) zwraca None, więc zapisanie takiego wyniku do zmiennej nic by nie dało - przy kontrolkach, które kod zmienia, tworzenie i układanie piszesz w dwóch liniach.)
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 18: Etykiety z wartością suwaków po prawej
Kryteria: ,
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
R.3.2 W stanie początkowym: - prostokąty są koloru białego, mały wyświetla wartość 255, 255, 255, - przynajmniej jeden suwak przyjmuje wartości od 0 do 255, - przynajmniej jeden suwak i odpowiadająca mu etykieta mają wartość 255
ok. 1 min
Polecenie z arkusza
Z prawej strony suwaków etykiety z aktualną wartością suwaka, początkowo ustawione na 255.
Kolumna 2 - etykiety z tekstem 255, każda w zmiennej (red_value, green_value, blue_value), bo kod będzie zmieniał ich treść. width=4 ustala szerokość w znakach: etykieta ma zawsze miejsce na trzy cyfry, więc gdy wartość zmieni się z 255 na 7, suwaki nie „podskoczą” w bok. Na razie ruch suwaka niczego tu nie zmienia.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 19: Przycisk Pobierz w kolorze Peru
Kryteria:
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
ok. 1 min
Polecenie z arkusza
Przycisk „Pobierz” koloru Peru ( #CD853F).
tk.Button z napisem w text i tłem #CD853F. width=20 to szerokość w znakach - przycisk jest wyraźnie szerszy niż napis, jak na obrazie 2. pack bez fill stawia go na środku okna. Obsługi kliknięcia jeszcze nie ma.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 20: Mały prostokąt z napisem 255, 255, 255
Kryteria: ,
R.3.1 W oknie zdefiniowane wszystkie kontrolki (etykiety, suwaki, przycisk) oraz ich układ jest zgodny z obrazem 2 w arkuszu egzaminacyjnym (prostokąty mały i duży mogą być dowolną kontrolką, która daje efekt przedstawiony na obrazie 2)
R.3.2 W stanie początkowym: - prostokąty są koloru białego, mały wyświetla wartość 255, 255, 255, - przynajmniej jeden suwak przyjmuje wartości od 0 do 255, - przynajmniej jeden suwak i odpowiadająca mu etykieta mają wartość 255
ok. 1 min
Polecenie z arkusza
Etykieta z pobraną wartością suwaków, domyślnie „255, 255, 255” o kolorze tła białym (mały prostokąt).
Mały prostokąt to etykieta z białym tłem i tekstem „255, 255, 255”, tej samej szerokości co przycisk, więc też na środku. Zmienna saved_color - kod zmieni jej kolor i tekst. Wygląd okna odpowiada obrazowi 2 (R.3.1, R.3.2).
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 21: Funkcja update_color: wartości przy suwakach
Kryteria: ,
R.3.4 Zmiana położenia przynajmniej jednego suwaka powoduje wyświetlenie aktualnej wartości suwaka po jego prawej stronie (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie)
R.1.3 Użyte polskie lub angielskie nazewnictwo funkcji lub metod. Nazewnictwo jest znaczące
ok. 4 min
Polecenie z arkusza
Działanie aplikacji: Zmiany położenia suwaków powodują zmianę wartości RGB po prawej stronie suwaka.
Kod reagujący na ruch suwaka to zwykła funkcja Pythona, przekazana kontrolce w parametrze command=update_color - bez nawiasów, bo przekazujesz samą funkcję, a Tkinter wywoła ją przy każdej zmianie wartości. Jedna funkcja obsługuje wszystkie trzy suwaki, bo i tak odczytuje komplet wartości.
Scale przy wywołaniu przekazuje nową wartość jako argument, dlatego funkcja musi mieć parametr (value) - nawet jeśli z niego nie korzysta. W środku metodą get() odczytujesz liczbę z każdego suwaka, a config(text=...) podmienia treść etykiety (R.3.4). Funkcja stoi nad root = tk.Tk(), bo musi istnieć, zanim przekażesz ją suwakom.
Przesuń suwak w podglądzie - liczba po prawej zmienia się razem z nim. A dlaczego funkcja nie wywraca się na starcie, choć set(255) czerwonego suwaka pada, gdy zielonego jeszcze nie ma? Tkinter wywołuje command dopiero w pętli zdarzeń, czyli po zbudowaniu całego okna. (W WPF ten sam układ wymaga sprawdzenia IsLoaded.)
Typowe błędy
command=update_color() z nawiasami wywoła funkcję raz, w chwili tworzenia suwaka (gdy etykiet jeszcze nie ma - błąd NameError), a suwakowi przekaże jej wynik, czyli None. Druga pułapka: funkcja bez parametru def update_color(): - każdy ruch suwaka kończy się błędem TypeError w konsoli PyCharm.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 22: Kolor dużego prostokąta z suwaków
Kryteria: ,
R.3.5 Zmiana położenia każdego z trzech suwaków powoduje zmianę koloru dużego prostokąta. Kolor odpowiada wartościom RGB ustawionym na suwakach (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie)
R.1.5 Zastosowane typy pasujące do problemu, np. tablica lub kolekcja liczb całkowitych, dane wczytywane jako typ całkowity
ok. 3 min
Polecenie z arkusza
Zmiany położenia suwaków powodują ustawienie koloru dużego prostokąta na wartość RGB odpowiadającą suwakom (obraz 3).
Tkinter przyjmuje kolor jako napis #RRGGBB - trzy składowe zapisane szesnastkowo, po dwie cyfry. Składasz go f-napisem: w klamrach format :02x zamienia liczbę na zapis szesnastkowy (x) z co najmniej dwiema cyframi i zerem z przodu (02) - 66 to 42, 7 to 07, 255 to ff. Dla 66, 113, 183 powstaje #4271b7. config(bg=...) ustawia tło prostokąta (R.3.5). Przesuń dowolny suwak - prostokąt od razu zmienia kolor.
Typowe błędy
f"#{red:x}{green:x}{blue:x}" bez 02 dla wartości 7 daje jedną cyfrę - napis ma wtedy mniej niż 6 znaków i Tkinter zgłasza błąd unknown color name albo pokazuje zupełnie inny kolor.
R.3.3 Zdefiniowana metoda obsługująca kliknięcie przycisku
R.3.6 Tylko po kliknięciu przycisku zmienia się kolor małego prostokąta. Kolor odpowiada wartościom RGB ustawionym na suwakach (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie)
ok. 3 min
Polecenie z arkusza
Po wciśnięciu przycisku „Pobierz” mały prostokąt na dole okna ma ustawiony kolor oraz tekst odpowiadający aktualnemu RGB (obraz 4).
Przycisk też dostaje funkcję w parametrze command=fetch_color (R.3.3) - przycisk wywołuje ją bez argumentów, więc tu parametru nie ma. Funkcja odczytuje suwaki tak samo jak update_color i ustawia tło małego prostokąta. Ten kod wykonuje się wyłącznie po kliknięciu - dlatego dalsze ruchy suwakami nie zmieniają już pobranego koloru (obraz 5, R.3.6). Ustaw kolor, kliknij „Pobierz”, potem przesuń suwak: duży prostokąt się zmienia, mały - nie.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 24: Przycisk Pobierz: tekst z wartościami RGB
Kryteria:
R.3.7 Po kliknięciu przycisku zmienia się tekst w małym prostokącie, odpowiada on wartościom suwaków (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie)
ok. 2 min
Polecenie z arkusza
Po wciśnięciu przycisku „Pobierz” mały prostokąt na dole okna ma ustawiony kolor oraz tekst odpowiadający aktualnemu RGB (obraz 4). Mały prostokąt nie zmienia się, jego zmianę może wywołać dopiero przyciśnięcie przycisku „Pobierz”.
Treść etykiety składasz f-napisem z trzech liczb rozdzielonych przecinkiem i spacją - jak „66, 113, 183” na obrazie 4 (R.3.7). Tym razem bez formatu :02x, bo użytkownik ma zobaczyć liczby dziesiętne. Aplikacja jest kompletna - przejdź w podglądzie obrazy 3, 4 i 5.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 25: Folder desktopowa: archiwum i źródło
Kryteria:
R.4.9 Na płycie wszystkie wykonane projekty są spakowane oraz umieszczone pliki źródłowe i pliki wykonywalne (jeśli istnieją) na zewnątrz archiwów
ok. 2 min
Polecenie z arkusza
Kod aplikacji przygotuj do nagrania na płytę. W folderze desktopowa powinno znaleźć się archiwum całego projektu o nazwie desktopowa.zip, skopiowane z projektu pliki źródłowe, które były modyfikowane w czasie egzaminu (interfejs użytkownika i logika aplikacji) oraz plik wykonywalny, jeżeli istnieje.
Pakujesz folder projektu do desktopowa.zip i kopiujesz obok main.py. W Tkinterze wygląd i logika są w jednym pliku - arkusz pisze o plikach interfejsu i logiki z myślą o środowiskach takich jak WPF (.xaml i .xaml.cs); tu jeden plik spełnia oba warunki. Pliku wykonywalnego nie ma.
Kroki 26-29 · po tym etapie masz 32 z 32 kryteriów (pkt)
Krok 26: Dokumentacja funkcji draw_numbers
Kryteria: , , , ,
R.4.1 Dla dowolnej funkcji lub metody zapisany nagłówek w postaci komentarza zgodnego z Listingiem 1 z arkusza egzaminacyjnego (nie należy brać pod uwagę liczby gwiazdek) , komentarz może być wieloliniowy lub kilka jednoliniowych, lub Docstrings (potrójny cudzysłów) - w tym przypadku opis znajduje się pod nazwą funkcji
R.4.2 W komentarzu umieszczona nazwa funkcji / metody oraz opisane jej działanie
R.4.3 W komentarzu umieszczone wszystkie argumenty funkcji / metody: nazwy i krótki opis lub "brak", gdy nie ma argumentów
R.4.4 W komentarzu umieszczona nazwa typu zwracanego i krótki opis co jest zwracane lub "brak", gdy funkcja nie zwraca wartości
R.4.5 W komentarzu umieszczony numer zdającego
ok. 4 min
Polecenie z arkusza
W kodzie źródłowym aplikacji konsolowej za pomocą komentarza utwórz nagłówek jednej dowolnej funkcji/metody, według wzoru z listingu 1. Komentarz powinien znaleźć się nad lub pod nazwą funkcji. W miejscu nawiasów <> należy podać odpowiednie opisy. W miejscu autor należy podać numer zdającego.
W Pythonie opis funkcji zapisuje się jako docstring - napis w potrójnym cudzysłowie zaraz pod linią def. Klucz dopuszcza go wprost (R.4.1, „Docstrings (potrójny cudzysłów) - w tym przypadku opis znajduje się pod nazwą funkcji”). Wypełniasz pola z listingu 1 zgodnie z kodem: nazwa i działanie (R.4.2), parametr count z opisem (R.4.3), zwracany typ list z opisem (R.4.4) i autor (R.4.5) - na egzaminie numer PESEL, tu Bartosz Bryniarski.
Docstring to nie tylko ozdoba: PyCharm pokazuje go w podpowiedzi po najechaniu na nazwę funkcji, a help(draw_numbers) wypisuje go w konsoli.
Typowe błędy
Docstring wstawiony NAD def nie jest już docstringiem, tylko luźnym napisem - Python go zignoruje. Komentarz nad funkcją pisze się wtedy znakami # w każdej linii.
konsola/main.pyPythonzmienione: 7 linii
import randomdefdraw_numbers(count):""" nazwa funkcji: draw_numbers opis funkcji: losuje zestawy po 6 różnych liczb z zakresu 1-49 parametry: count - liczba zestawów do wylosowania zwracany typ i opis: list - lista count list, każda z 6 wylosowanymi liczbami autor: Bartosz Bryniarski """ draws = []for _ in range(count): draw = []whilelen(draw) < 6: number = random.randint(1, 49)if number not in draw: draw.append(number) draws.append(draw)return drawsdefprint_draws(draws):for number, draw in enumerate(draws, start=1):print(f"Losowanie {number}:", *draw)defcount_occurrences(draws): occurrences = [0] * 50for draw in draws:for number in draw: occurrences[number] += 1return occurrencesdefprint_occurrences(occurrences):for number in range(1, 50):print(f"Wystąpienia liczby {number}: {occurrences[number]}")defmain(): count = int(input("Ile wygenerować losowań? ")) draws = draw_numbers(count)print("Zestawy wylosowanych liczb:") print_draws(draws) occurrences = count_occurrences(draws) print_occurrences(occurrences)if__name__ == "__main__": main()
Wynik programu po tym kroku
> python main.py
Ile wygenerować losowań? 11
Zestawy wylosowanych liczb:
Losowanie 1: 11 29 4 43 10 37
Losowanie 2: 16 44 10 21 13 8
Losowanie 3: 40 43 46 41 45 42
Losowanie 4: 14 4 22 31 48 3
Losowanie 5: 34 21 30 14 41 16
Losowanie 6: 29 6 26 20 38 18
Losowanie 7: 21 18 17 30 10 33
Losowanie 8: 33 35 42 41 21 9
Losowanie 9: 49 29 25 4 14 35
Losowanie 10: 32 7 8 25 9 38
Losowanie 11: 8 33 15 43 44 12
Wystąpienia liczby 1: 0
Wystąpienia liczby 2: 0
Wystąpienia liczby 3: 1
Wystąpienia liczby 4: 3
Wystąpienia liczby 5: 0
Wystąpienia liczby 6: 1
Wystąpienia liczby 7: 1
Wystąpienia liczby 8: 3
Wystąpienia liczby 9: 2
Wystąpienia liczby 10: 3
Wystąpienia liczby 11: 1
Wystąpienia liczby 12: 1
Wystąpienia liczby 13: 1
Wystąpienia liczby 14: 3
Wystąpienia liczby 15: 1
Wystąpienia liczby 16: 2
Wystąpienia liczby 17: 1
Wystąpienia liczby 18: 2
Wystąpienia liczby 19: 0
Wystąpienia liczby 20: 1
Wystąpienia liczby 21: 4
Wystąpienia liczby 22: 1
Wystąpienia liczby 23: 0
Wystąpienia liczby 24: 0
Wystąpienia liczby 25: 2
Wystąpienia liczby 26: 1
Wystąpienia liczby 27: 0
Wystąpienia liczby 28: 0
Wystąpienia liczby 29: 3
Wystąpienia liczby 30: 2
Wystąpienia liczby 31: 1
Wystąpienia liczby 32: 1
Wystąpienia liczby 33: 3
Wystąpienia liczby 34: 1
Wystąpienia liczby 35: 2
Wystąpienia liczby 36: 0
Wystąpienia liczby 37: 1
Wystąpienia liczby 38: 2
Wystąpienia liczby 39: 0
Wystąpienia liczby 40: 1
Wystąpienia liczby 41: 3
Wystąpienia liczby 42: 2
Wystąpienia liczby 43: 3
Wystąpienia liczby 44: 2
Wystąpienia liczby 45: 1
Wystąpienia liczby 46: 1
Wystąpienia liczby 47: 0
Wystąpienia liczby 48: 1
Wystąpienia liczby 49: 1
Krok 27: Zrzut konsola1
Kryteria: , , ,
R.2.8 Program uruchamia się w konsoli, co jest udokumentowane zrzutem ekranu
R.1.6 Podjęta próba uruchomienia, co jest udokumentowane zrzutem przedstawiającym uruchomiony program lub jego kompilację
R.4.6 Zapisany przynajmniej jeden zrzut ekranu z uruchomienia lub kompilacji aplikacji konsolowej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja
R.2.5 Program wyświetla zawartość tablicy lub kolekcji za pomocą pętli. Wyświetlone wszystkie losowania (w uruchomionej aplikacji lub na zrzucie i obowiązkowo w kodzie)
ok. 3 min
Polecenie z arkusza
Wykonaj zrzuty ekranu dokumentujące uruchomienie aplikacji utworzonych podczas egzaminu. Zrzuty powinny obejmować cały obszar ekranu monitora z widocznym paskiem zadań. Jeżeli aplikacja uruchamia się, na zrzucie należy umieścić okno z wynikiem działania programu oraz otwarte środowisko programistyczne z projektem lub okno terminala z kompilacją projektu. Aplikacja konsolowa – dowolna liczba zrzutów nazwanych konsola1, konsola2, ...
Uruchamiasz main.py w PyCharm (zielona strzałka albo Shift+F10), w panelu Run wpisujesz liczbę losowań i robisz zrzut całego ekranu (Print Screen) z PyCharm i paskiem zadań - konsola1.png w folderze dokumentacja. Lista wystąpień jest długa; drugi zrzut (konsola2.png) po przewinięciu panelu pokaże jej koniec. Podgląd to prawdziwy wynik programu z dokumentacją.
R.3.8 Program uruchamia się w oknie, co jest udokumentowane zrzutem ekranu (wymagana przynajmniej jedna kontrolka w oknie)
R.4.7 Zapisany przynajmniej jeden zrzut ekranu z uruchomienia lub kompilacji aplikacji desktopowej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja
ok. 4 min
Polecenie z arkusza
Wykonać należy tyle zrzutów, ile interakcji podejmuje aplikacja (np. stan początkowy, po wybraniu przycisków itd.). Aplikacja desktopowa – dowolna liczba zrzutów nazwanych desktop1, desktop2, ...
Uruchamiasz aplikację w PyCharm i robisz cztery zrzuty całego ekranu, tak jak obrazy 2-5 arkusza: desktop1.png - stan początkowy, desktop2.png - po przesunięciu suwaków, desktop3.png - po kliknięciu „Pobierz”, desktop4.png - po kolejnym przesunięciu suwaków (mały prostokąt bez zmian). Na każdym ma być okno aplikacji i PyCharm.
Podgląd to prawdziwy zrzut obszaru okna tej aplikacji (Tkinter, Windows 11) w stanie 4: pobrany kolor 66, 113, 183, a suwaki przestawione dalej - na 188, 87, 179, jak na obrazie 5.
Typowe błędy
Zrzut samego okna aplikacji (Alt+Print Screen) nie spełnia R.4.7 - na zrzucie ma być widać środowisko, w którym powstała aplikacja.
Okno aplikacji po tym kroku
Krok 29: Plik egzamin
Kryteria:
R.4.8 Dokumentacja zawiera: nazwę systemu operacyjnego, nazwy środowisk programistycznych, nazwy języków programowania (stosowanych przez zdającego)
ok. 2 min
Polecenie z arkusza
Utwórz plik z dokumentacją i nazwij go egzamin. Dokument powinien zawierać informacje o narzędziach wykorzystanych na egzaminie: Nazwę systemu operacyjnego, Nazwy środowisk programistycznych, Nazwy języków programowania. Zrzuty ekranu i dokument umieść w folderze dokumentacja.
Plik egzamin w folderze dokumentacja: system, środowisko i język - to, czego naprawdę użyto. Tkinter to biblioteka, nie osobny język, ale warto ją wymienić obok Pythona.
egzamin.txtTekstnowy plik
System operacyjny: Windows 11Środowisko programistyczne: PyCharm Community (aplikacja konsolowa i desktopowa)Języki programowania: Python (obie aplikacje), biblioteka Tkinter (aplikacja desktopowa)
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Etap 5: Porównanie z wariantem C# + WPF
Kroki 30-31 · po tym etapie masz 32 z 32 kryteriów (pkt)
Krok 30: Konsola: lista list w Pythonie, tablica int[,] w C#
ok. 3 min
Polecenie z arkusza
Do przechowywania wyników losowań należy użyć dwuwymiarowej tablicy liczb całkowitych składającej się z n wierszy i 6 kolumn (n – liczba wczytana z klawiatury) lub innej dowolnej kolekcji pasującej do problemu.
Ten sam program w obu językach różni się w kilku miejscach, na które łatwo stracić punkt przy przesiadce:
kolekcja - w C# prawdziwa tablica dwuwymiarowa int[,] o stałym rozmiarze count × 6, w Pythonie lista list, która rośnie przez append (obie spełniają R.2.2),
zakres losowania - random.randint(1, 49) obejmuje 49, random.Next(1, 50) w C# nie obejmuje górnej granicy, stąd 50,
powtórki - w Pythonie wystarcza not in, w C# trzeba było napisać pętlę sprawdzającą wypełnione kolumny (IsInDraw),
typy - C# wymaga ich wszędzie (int[,], static void), w Pythonie typ wynika z wartości; dlatego int(input(...)) jest tu jedynym miejscem, gdzie typ trzeba zadbać ręcznie.
Python ma też gotowe random.sample(range(1, 50), 6) - sześć różnych liczb w jednej linii. Na egzaminie lepiej pokazać własną pętlę: R.2.6 sprawdza, czy program implementuje losowanie bez powtórzeń, a gotowa funkcja może zostać uznana za obejście zadania.
Krok 31: Okno: Tkinter a WPF - co wybrać na egzaminie
ok. 3 min
Polecenie z arkusza
Za pomocą dostępnego na stanowisku egzaminacyjnym środowiska programistycznego wykonaj aplikację desktopową wybierania kolorów z palety RGB.
Najważniejsze różnice wobec wariantu WPF:
wygląd - w WPF zapisany osobno w XAML (z projektantem okien), w Tkinterze w tym samym pliku co logika, przez pack i grid; nie ma podglądu w trakcie pisania, więc częściej uruchamiasz program,
zdarzenia - WPF wiąże je w XAML (ValueChanged="..."), Tkinter przez parametr command= przy tworzeniu kontrolki,
kolory - WPF potrzebuje pędzla (new SolidColorBrush(Color.FromRgb(...))), Tkinter przyjmuje napis #RRGGBB,
start okna - WPF wywołuje ValueChanged już przy budowaniu okna (stąd IsLoaded), Tkinter wywołuje command dopiero w pętli zdarzeń,
wartości suwaka - Scale w Tkinterze daje od razu liczby całkowite, Slider w WPF - liczby zmiennoprzecinkowe (trzeba IsSnapToTickEnabled i rzutowania na byte).
Co wybrać? Jeśli najpewniej czujesz się w Pythonie, Tkinter pozwala zrobić cały egzamin w jednym języku i jest na każdym stanowisku z Pythonem - sprawdź tylko przed egzaminem, czy w PyCharm na stanowisku import tkinter działa. WPF daje projektant okna i plik .exe, ale wymaga znajomości C# i XAML. Punkty za aplikację desktopową (R.3) są w obu technologiach te same.
Krok 32 · po tym etapie masz 32 z 32 kryteriów (pkt)
Krok 32: Nagranie płyty
Kryteria:
R.4.9 Na płycie wszystkie wykonane projekty są spakowane oraz umieszczone pliki źródłowe i pliki wykonywalne (jeśli istnieją) na zewnątrz archiwów
ok. 5 min
Polecenie z arkusza
UWAGA: Nagraj płytę z rezultatami pracy. W folderze z numerem zdającego powinny się znajdować podfoldery desktopowa, dokumentacja, konsolowa. W folderze desktopowa: spakowany cały projekt aplikacji desktopowej, pliki ze źródłami interfejsu i logiki, opcjonalnie plik wykonywalny. W folderze dokumentacja: pliki ze zrzutami oraz plik egzamin. W folderze konsolowa: spakowany cały projekt aplikacji konsolowej, pliki źródłowe, opcjonalnie plik wykonywalny.
konsolowa: konsola.zip (z dokumentacją funkcji), main.py.
Oba pliki nazywają się main.py, ale leżą w różnych folderach, więc się nie nadpiszą. Projekty spakowane, źródła obok archiwów (R.4.9). Nagrywasz, sprawdzasz odczyt płyty, opisujesz ją numerem zdającego. Pusta lub nieczytelna płyta to zero punktów za wszystkie rezultaty.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.
Autor rozwiązania: Bartosz Bryniarski. Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.