Egzamin praktyczny: konsola, aplikacja webowa, mobilna i desktopowa
Każdy arkusz praktyczny INF.04 zaczyna się od aplikacji konsolowej. Można ją napisać w C++, C#, Javie albo Pythonie. Ten kurs prowadzi przez wszystkie konsolowe zadania z 21 arkuszy z lat 2021–2026 w Pythonie, razem z dokumentacją i testami, których wymaga część III. W części II cztery arkusze mają aplikację webową, dziesięć mobilną i sześć desktopową. Te zadania też tu są: webowe w React, mobilne w Android Studio z Kotlinem, desktopowe w WPF z C#.
Kod piszesz i uruchamiasz na tej stronie. Przycisk „Uruchom” wykonuje program i pokazuje konsolę, a „Sprawdź” puszcza testy: wywołują twoje funkcje i klasy z różnymi danymi i mówią, co się nie zgadza. W zadaniach webowych „Uruchom” pokazuje działającą aplikację, a testy klikają w nią i wypełniają formularze. W zadaniach mobilnych i desktopowych strona rysuje ekran telefonu albo okno programu z twojego pliku znaczników, a testy czytają układ i kod, bez uruchamiania.
Co jest w kursie
| Część | Zawartość |
|---|---|
| Python od zera | Jedenaście lekcji: od print i input, przez listy, funkcje i losowanie, po klasy, dziedziczenie i pliki. Każda uczy dokładnie tego, o co pytają arkusze. |
| Dokumentacja i testy | Nagłówek funkcji w komentarzu, czytelny kod, zrzuty ekranu, plik egzamin, test w programie głównym i testy jednostkowe w unittest. |
| Arkusze: algorytmy | Jedenaście zadań: sortowania, wartownik, sito Eratostenesa, NWD, PESEL, kości, loteria, szyfr Cezara, generator haseł, narzędzia do napisów. |
| Arkusze: klasy | Dziewięć zadań: Osoba, Film, dwie Notatki, Tablica, urządzenia domowe, Kość, Pytanie, albumy z pliku. |
| Aplikacja webowa: React | Pięć lekcji: komponent i JSX, stan i zdarzenia, listy i warunki, formularze oraz klasy Bootstrapa. Projekt powstaje w Vite. |
| Arkusze: aplikacja webowa | Cztery zadania z części II: zapisy na kursy, formularz filmu, galeria zdjęć, menedżer haseł. |
| Aplikacja mobilna: Android i Kotlin | Cztery lekcje: projekt i układ XML, wygląd, Kotlin i zdarzenia, lista, suwak i pola radio. |
| Arkusze: aplikacja mobilna | Dziesięć zadań z części II: rejestracja konta, licznik polubień, dwie listy notatek, suwak czcionki, weterynarz, dwie gry w kości, urządzenia domowe, quiz. |
| Aplikacja desktopowa: WPF i C# | Cztery lekcje: projekt i okno w XAML, siatka i grupy, C# i zdarzenia, lista rozwijana, suwak, obrazy i pliki. |
| Arkusze: aplikacja desktopowa | Sześć zadań z części II: dane pracownika, nadanie przesyłki, dane paszportowe, przeglądarka albumów, wzornik RGB, szyfr w oknie. |
Jak wygląda egzamin praktyczny
Na wykonanie zadania jest 180 minut. Żeby zdać część praktyczną, trzeba zdobyć co najmniej 75% punktów. Arkusz ma zawsze trzy części, a ocenie podlegają cztery rezultaty.
| Część arkusza | Co robisz | Rezultat w ocenie |
|---|---|---|
| I. Aplikacja konsolowa | Algorytm albo klasa z programem głównym, który ją sprawdza. C++, C#, Java lub Python. | „Aplikacja konsolowa” oraz „Implementacja, kompilacja, uruchomienie programu” |
| II. Aplikacja z interfejsem | Mobilna (Android Studio lub .NET MAUI), desktopowa albo webowa (Angular lub React). | „Aplikacja mobilna / desktopowa / webowa” |
| III. Dokumentacja lub testy | Nagłówek w komentarzu, zrzuty ekranu, plik egzamin. W nowszych arkuszach zamiast tego albo dodatkowo testy jednostkowe. | „Dokumentacja aplikacji” albo „Testy aplikacji” |
Rezultat „Implementacja, kompilacja, uruchomienie”
To punkty za sposób napisania kodu konsolowego, niezależnie od tego, czy algorytm działa. Klucze oceniania powtarzają te same kryteria:
- Każda instrukcja w osobnej linii, spacje wokół operatorów, wcięcia dla zagnieżdżonych bloków.
- Znaczące nazwy klas, metod i funkcji, polskie albo angielskie.
- Znaczące nazwy pól i zmiennych. Wyjątkiem są liczniki pętli i zmienne pomocnicze typu
tmp. Nazwy takie jakx,fun,foo,tabnie spełniają kryterium, chyba że arkusz wyraźnie na nie pozwala. - Typy pasujące do danych. W Pythonie typ wynika z przypisanej wartości: stan to
True/False, licznik to liczba całkowita. - Program rozmawia z użytkownikiem zrozumiale: pyta komunikatem i opisuje to, co wypisuje.
- Jest zrzut ekranu z uruchomienia programu albo z próby uruchomienia.
Co oddajesz
Tworzysz folder nazwany numerem zdającego (PESEL), a w nim podfoldery wskazane w arkuszu. Nazwy zmieniały się między sesjami, więc przepisuj je z arkusza litera po literze.
00000000000/ konsolowa/ konsola.zip (cały projekt), plik .py z kodem mobilna/ mobilna.zip, plik układu XML i plik z kodem (gdy część II jest mobilna) webowa/ web.zip, zmieniane pliki źródłowe (gdy część II jest webowa) desktopowa/ archiwum projektu, plik okna XAML i plik z kodem (gdy część II jest desktopowa) dokumentacja/ konsola1.png, mobilna1.png, ..., egzamin.txt testy/ tylko gdy arkusz wymaga testów jednostkowych
.py, nic więcej nie trzeba.Pliki na pulpicie
Część arkuszy korzysta z archiwum, które leży na pulpicie konta Egzamin. Jest zabezpieczone hasłem podanym w treści arkusza. W zadaniach konsolowych takie pliki wystąpiły dwa razy: Data.txt z albumami (czerwiec 2024) i znaki.txt z polskimi literami (czerwiec 2026). Pozostałe archiwa zawierają obrazy i dane do części II.
Pierwszy program: wypisz, wczytaj, policz
Program w Pythonie to instrukcje wykonywane od góry do dołu, po jednej w linii. Nie ma średników ani nawiasów klamrowych. Trzy rzeczy wystarczą na początek.
print("Witaj w programie") # wypisuje tekst i przechodzi do nowej linii
imie = input("Podaj imię: ") # czeka na tekst z klawiatury
wiek = int(input("Podaj wiek: ")) # input zawsze daje napis, int() robi z niego liczbę
print("Imię:", imie) # po przecinku print wstawia spację
print(f"{imie} ma {wiek} lat") # f-napis: w klamrach wartości zmiennych
Zmienna powstaje w chwili przypisania. Typu się nie deklaruje, wynika on z wartości: "Ola" to napis (str), 17 to liczba całkowita (int), 3.5 to liczba rzeczywista (float), True i False to wartości logiczne (bool).
| Zapis | Wynik | Uwagi |
|---|---|---|
7 + 2, 7 - 2, 7 * 2 | 9, 5, 14 | |
7 / 2 | 3.5 | Zawsze liczba rzeczywista. |
7 // 2 | 3 | Dzielenie całkowite. |
7 % 2 | 1 | Reszta z dzielenia (modulo). |
"3" + "4" | "34" | Napisy się skleja. Dlatego liczby z input trzeba zamienić przez int(). |
str(5) + " zł" | "5 zł" | Liczbę doklejasz do napisu przez str() albo f-napis. |
input ma mieć komunikat, a każda wypisana wartość opis. Samo input() i gołe print(wynik) to utrata punktu za komunikację z użytkownikiem.Warunki i pętle
Blok kodu wyznacza wcięcie, zwyczajowo cztery spacje. Linia, po której zaczyna się blok, kończy się dwukropkiem.
if punkty >= 30:
print("Zdane")
elif punkty >= 20:
print("Blisko")
else:
print("Niezdane")
Warunki łączy się słowami and, or, not. Równość to ==, różność !=.
while: dopóki warunek jest prawdziwy
Używasz jej, gdy nie wiesz, ile będzie powtórzeń. Typowy przypadek z arkuszy to pytanie o daną tak długo, aż będzie poprawna.
liczba = int(input("Podaj liczbę od 1 do 12: "))
while liczba < 1 or liczba > 12:
liczba = int(input("Poza zakresem. Podaj liczbę od 1 do 12: "))
for: znana liczba powtórzeń
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(1, 6): # 1, 2, 3, 4, 5 (koniec nie wchodzi do zakresu)
print(i)
for i in range(10, 0, -2): # 10, 8, 6, 4, 2 (trzecia liczba to krok)
print(i)
break przerywa pętlę, continue przechodzi do następnego obrotu.
range(1, 10) kończy się na 9. Jeśli mają być liczby od 1 do 10, pisz range(1, 11).Listy, czyli tablice
Arkusze mówią „tablica”. W Pythonie jest nią lista. Arkusz ze stycznia 2025 pisze to wprost: „ma być tradycyjną tablicą, a w Python listą”.
liczby = [4, 9, 2] # lista z trzema elementami pusta = [] zera = [0] * 10 # dziesięć zer print(liczby[0]) # 4, indeksy liczy się od zera print(liczby[-1]) # 2, ostatni element print(len(liczby)) # 3 liczby[1] = 7 # zmiana elementu liczby.append(5) # dopisanie na końcu liczby.pop() # usunięcie ostatniego
Po liście przechodzi się na dwa sposoby. Pierwszy daje same wartości, drugi indeksy, potrzebne do zamiany elementów i do wypisywania numerów.
for liczba in liczby:
print(liczba)
for i in range(len(liczby)):
print(i, liczby[i])
Wczytywanie z klawiatury i wypisywanie
liczby = []
for i in range(10):
liczby.append(int(input(f"Podaj liczbę nr {i + 1}: ")))
# elementy oddzielone przecinkami: join skleja napisy, więc liczby zamieniamy przez str
print("Tablica:", ", ".join(str(liczba) for liczba in liczby))
Szukanie największego elementu i zamiana miejscami
Te dwie czynności są w każdym algorytmie sortowania. Arkusze zabraniają gotowych funkcji max(), sort() i sorted(), więc trzeba je umieć napisać w pętli.
indeks_max = 0
for i in range(1, len(liczby)):
if liczby[i] > liczby[indeks_max]:
indeks_max = i
tmp = liczby[0] # zamiana przez zmienną pomocniczą
liczby[0] = liczby[indeks_max]
liczby[indeks_max] = tmp
zestawy = [[0] * 6 for wiersz in range(n)]. Element czytasz przez dwa indeksy: zestawy[2][0].Funkcje
Prawie każdy arkusz wymaga, żeby algorytm był w osobnej funkcji, a program główny tylko ją wywoływał. Funkcję definiuje słowo def.
def pole_prostokata(bok_a, bok_b):
return bok_a * bok_b # wynik wraca do miejsca wywołania
wynik = pole_prostokata(3, 4)
print("Pole:", wynik)
Arkusze opisują funkcje zawsze tym samym językiem. Warto umieć go przełożyć na kod.
| Arkusz mówi | W Pythonie |
|---|---|
| „funkcja o dwóch argumentach” | def nwd(a, b): |
| „zwraca wartość” | Kończy się instrukcją return wynik. |
| „nie zwraca wartości” | Nie ma return z wartością. Funkcja zmienia przekazaną listę albo coś wypisuje. |
| „funkcja nie może zawierać operacji wejścia-wyjścia” | W środku nie ma input ani print. Dane dostaje w argumentach, wynik oddaje przez return. |
| „nie może korzystać ze zmiennych globalnych” | Wszystko, czego funkcja potrzebuje, dostaje w argumentach. |
| „argumentem jest tablica” | def sortuj(liczby): Funkcja dostaje tę samą listę, a nie kopię. |
Lista jako argument
Gdy funkcja zmienia elementy przekazanej listy, zmiany widać po powrocie w programie głównym. Dlatego funkcja sortująca „nie zwraca wartości”: sortuje tablicę, którą dostała.
def wyzeruj_ujemne(liczby):
for i in range(len(liczby)):
if liczby[i] < 0:
liczby[i] = 0
pomiary = [3, -1, 5, -8]
wyzeruj_ujemne(pomiary)
print(pomiary) # [3, 0, 5, 0]
Program główny
Definicje funkcji i klas stoją na górze pliku. Pod nimi, bez wcięcia, jest program główny: wczytuje dane, wywołuje funkcje i wypisuje wyniki. To on jest „testem działania”, o którym piszą arkusze.
Napisy i znaki
Napis zachowuje się jak lista znaków, której nie da się zmieniać. Można go indeksować, mierzyć i przechodzić po nim pętlą. Nowy napis buduje się przez doklejanie.
tekst = "Ala ma kota"
print(len(tekst)) # 11
print(tekst[0]) # A
print("kot" in tekst) # True
bez_spacji = ""
for znak in tekst:
if znak != " ":
bez_spacji = bez_spacji + znak
Python nie ma osobnego typu znakowego. „Typ znakowy o wartości 'K' lub 'M'” to po prostu napis długości 1.
Kody znaków
Szyfr Cezara i generator haseł wymagają przeliczania liter na liczby. ord() daje kod znaku, chr() znak o podanym kodzie. Małe litery łacińskie mają kody od 97 (a) do 122 (z).
print(ord("a")) # 97
print(chr(100)) # d
numer = ord("c") - 97 # 2, czyli numer litery w alfabecie liczony od zera
litera = chr(numer + 97) # z powrotem "c"
Przydatne operacje
| Zapis | Co robi |
|---|---|
znak in "aeiouy" | Sprawdza, czy znak należy do zestawu. |
"0123456789"[cyfra] | Znak z zestawu o podanym indeksie. Tak losuje się znak do hasła. |
int(pesel[9]) | Cyfra z napisu zamieniona na liczbę. |
tekst.upper(), tekst.lower() | Wielkie i małe litery. |
tekst.strip() | Usuwa spacje i znak końca linii z obu końców. |
tekst.split(";") | Dzieli napis na listę części. |
"; ".join(lista_napisow) | Skleja listę napisów separatorem. |
None. Warunek if not tekst: jest prawdziwy w obu przypadkach.Liczby losowe
Losowanie jest w co trzecim arkuszu: tablica do posortowania, rzut kością, zestaw liczb w loterii, znaki hasła. Służy do tego moduł random, który trzeba zaimportować na górze pliku.
import random
oczka = random.randint(1, 6) # liczba całkowita od 1 do 6, oba końce wchodzą
print("Wyrzucono:", oczka)
liczby = []
for i in range(100):
liczby.append(random.randint(0, 1000))
randint(a, b) to jedyna funkcja, jakiej potrzebujesz. Losowy element zestawu bierzesz przez losowy indeks:
cyfry = "0123456789" znak = cyfry[random.randint(0, len(cyfry) - 1)]
Losowanie bez powtórzeń
W zestawie loterii liczby nie mogą się powtarzać. Losujesz w pętli while i dopisujesz liczbę tylko wtedy, gdy jeszcze jej nie ma.
zestaw = []
while len(zestaw) < 6:
liczba = random.randint(1, 49)
if liczba not in zestaw:
zestaw.append(liczba)
random.sample() i random.shuffle() zrobiłyby to w jednej linii, ale arkusze często zastrzegają, że algorytm ma być napisany samodzielnie. Pętla z randint jest bezpieczna zawsze.Klasy i obiekty
Połowa arkuszy każe napisać klasę. Klasa to opis: jakie dane ma obiekt (pola) i co potrafi (metody). Obiekt to konkretny egzemplarz.
class Film:
def __init__(self, tytul): # konstruktor, wykonuje się przy tworzeniu obiektu
self.tytul = tytul # pola powstają przez przypisanie do self
self.liczba_wypozyczen = 0
def wypozycz(self): # metoda
self.liczba_wypozyczen = self.liczba_wypozyczen + 1
def opis(self):
return f"{self.tytul}: {self.liczba_wypozyczen} wypożyczeń"
film = Film("Rejs") # utworzenie obiektu
film.wypozycz()
print(film.opis()) # Rejs: 1 wypożyczeń
Zasady, które wystarczą na egzamin:
- Konstruktor nazywa się zawsze
__init__, z dwoma podkreślnikami z każdej strony. - Pierwszym parametrem każdej metody jest
self, czyli obiekt, na którym metodę wywołano. Przy wywołaniu się go nie podaje. - Do pól i metod własnego obiektu sięgasz zawsze przez
self.. Samotytulwewnątrz metody to zwykła zmienna lokalna. - Pola deklaruje się w konstruktorze. Klucze oceniania przyjmują to wprost: „deklaracja pól w konstruktorze przez self”.
self. „Konstruktor dwuargumentowy” to __init__(self, pierwszy, drugi). Klucz oceniania mówi, że self nie wlicza się do liczby parametrów.Widoczność pól i pola statyczne
Arkusze bardzo dokładnie opisują, kto ma dostęp do pola. W C# i Javie służą do tego słowa private, protected i public. Python ich nie ma, a widoczność oznacza się podkreślnikami przed nazwą.
| Arkusz mówi | Znaczenie | W Pythonie |
|---|---|---|
| „ogólnodostępne”, „widzialne poza klasą” | public | self.tytul |
| „dostęp ma jedynie klasa, klasy potomne również” | protected | self._tytul (jeden podkreślnik) |
| „dostęp ma jedynie klasa, klasy potomne nie mają”, „dostępne tylko w tej klasie” | private | self.__tytul (dwa podkreślniki) |
Klucz oceniania potwierdza ten zapis: „w języku Python, dla pola typu private, dwa podkreślniki przed nazwą”. Pole z dwoma podkreślnikami jest naprawdę ukryte: próba odczytu obiekt.__tytul spoza klasy kończy się błędem AttributeError.
Getter i setter
Skoro pole jest ukryte, klasa udostępnia metody do odczytu i zmiany.
class Film:
def __init__(self):
self.__tytul = ""
def ustaw_tytul(self, tytul): # setter
self.__tytul = tytul
def pobierz_tytul(self): # getter
return self.__tytul
Pole statyczne
Pole statyczne należy do klasy, a nie do pojedynczego obiektu. Wszystkie obiekty widzą tę samą wartość. W arkuszach służy do liczenia utworzonych obiektów. Definiuje się je w ciele klasy, poza metodami, a zmienia przez nazwę klasy.
class Osoba:
liczba_osob = 0 # pole statyczne
def __init__(self, imie):
self.__imie = imie
Osoba.liczba_osob = Osoba.liczba_osob + 1 # przez nazwę klasy, nie przez self
print(Osoba.liczba_osob) # 0
pierwsza = Osoba("Ala")
druga = Osoba("Jan")
print(Osoba.liczba_osob) # 2
self.liczba_osob += 1 nie zmienia pola klasy. Tworzy w obiekcie nowe, własne pole o tej samej nazwie, a licznik klasy zostaje na zerze.Kilka konstruktorów i metody statyczne
W C# i Javie klasa może mieć kilka konstruktorów o różnej liczbie parametrów. Python pozwala tylko na jeden __init__. Arkusze o tym wiedzą i zawierają osobne uwagi dla Pythona.
Wartości domyślne
Konstruktor „bezparametrowy” i „z dwoma parametrami” zastępuje jeden konstruktor, w którym parametry mają wartości domyślne.
class Osoba:
def __init__(self, id=0, imie=""):
self.__id = id
self.__imie = imie
nikt = Osoba() # jak konstruktor bezparametrowy: id 0, imię puste
ala = Osoba(7, "Ala") # jak konstruktor z dwoma parametrami
Domyślne None
Gdy konstruktor bez argumentu ma zrobić coś innego niż konstruktor z argumentem (na przykład wylosować wartość), parametr dostaje wartość domyślną None, a konstruktor sprawdza, czy ją dostał.
import random
class Kosc:
def __init__(self, oczka=None):
if oczka is None:
self.oczka = random.randint(1, 6)
else:
self.oczka = oczka
Kopiowanie
Zamiast konstruktora kopiującego arkusz każe napisać metodę, która przepisuje dane z innego obiektu. Wewnątrz klasy wolno czytać prywatne pola innego obiektu tej samej klasy.
def kopiuj(self, inna):
self.__id = inna.__id
self.__imie = inna.__imie
Metoda statyczna
Klasa-biblioteka nie tworzy obiektów, tylko grupuje funkcje. Jej metody są statyczne: nie mają self, poprzedza je @staticmethod, a wywołuje się je przez nazwę klasy.
class Przelicznik:
@staticmethod
def na_minuty(godziny):
return godziny * 60
print(Przelicznik.na_minuty(2)) # 120, bez tworzenia obiektu
Dziedziczenie i klasy abstrakcyjne
Klasa potomna przejmuje pola i metody klasy bazowej i dokłada własne. Nazwę klasy bazowej podaje się w nawiasie.
class Urzadzenie:
def komunikat(self, tresc):
print(tresc)
class Lampa(Urzadzenie): # Lampa dziedziczy po Urzadzenie
def __init__(self):
self.__swieci = False
def wlacz(self):
if not self.__swieci:
self.__swieci = True
self.komunikat("Lampa włączona") # metoda odziedziczona
lampa = Lampa()
lampa.wlacz()
lampa.komunikat("Koniec") # metodę bazową widać też z zewnątrz
Konstruktor klasy bazowej
Jeśli klasa bazowa ma konstruktor z parametrami, klasa potomna musi go wywołać przez super().__init__(...). Arkusz zapisuje to słowami „konstruktor wywołuje konstruktor klasy, po której dziedziczy”.
class Pojazd:
def __init__(self, marka):
self._marka = marka # jeden podkreślnik: widoczne w klasach potomnych
class Rower(Pojazd):
def __init__(self, marka, liczba_biegow):
super().__init__(marka)
self.__liczba_biegow = liczba_biegow
Klasa abstrakcyjna
„Klasa, której obiekt nie może być powołany” to klasa abstrakcyjna. Dziedziczy po ABC i ma co najmniej jedną metodę oznaczoną @abstractmethod, która nie ma treści. Klasa potomna musi tę metodę napisać.
from abc import ABC, abstractmethod
class Zwierze(ABC):
@abstractmethod
def glos(self):
pass # brak domyślnej implementacji
class Pies(Zwierze):
def glos(self):
return "Hau"
pies = Pies() # działa
zwierze = Zwierze() # TypeError: nie można utworzyć obiektu klasy abstrakcyjnej
Czytanie pliku tekstowego
Arkusz z czerwca 2024 każe wczytać dane z pliku Data.txt. Plik otwiera funkcja open. Blok with sam go zamyka.
with open("Data.txt", encoding="utf-8") as plik:
linie = plik.readlines() # lista linii, każda kończy się znakiem nowej linii
for linia in linie:
print(linia.strip()) # strip usuwa znak końca linii
Arkusz sam podpowiada parametr encoding="utf-8". Bez niego polskie litery mogą się wczytać jako krzaczki. Plik musi leżeć w folderze, z którego uruchamiasz program, najprościej obok pliku .py.
Rekordy o stałej liczbie linii
Dane w plikach egzaminacyjnych są ułożone w rekordy: kilka linii z kolejnymi polami, potem pusta linia. Jeśli rekord ma 5 pól i pustą linię, kolejne rekordy zaczynają się co 6 linii.
def wczytaj_albumy(nazwa_pliku):
with open(nazwa_pliku, encoding="utf-8") as plik:
linie = plik.readlines()
albumy = []
numer_linii = 0
while numer_linii + 4 < len(linie):
wykonawca = linie[numer_linii].strip()
rok = int(linie[numer_linii + 3].strip()) # liczby trzeba zamienić z napisu
albumy.append([wykonawca, rok])
numer_linii = numer_linii + 6
return albumy
Arkusz wymaga, żeby program wczytał wszystkie rekordy, także te, które ktoś później dopisze. Dlatego pętla idzie do końca listy linii, a nie do sztywno wpisanej liczby.
encoding="utf-8-sig". W tym kursie plik takiego znaku nie ma.Dokumentacja: nagłówek, zrzuty, plik egzamin
Część III większości arkuszy to dokumentacja. Jest powtarzalna i daje pewne punkty, o ile zrobisz dokładnie to, co napisano.
Nagłówek funkcji lub metody
Arkusz podaje wzór i każe wstawić go w komentarzu nad funkcją albo pod jej nazwą. Wzór nie ma znaków komentarza, bo są różne w różnych językach. W Pythonie komentarz zaczyna znak #.
# **********************************************
# nazwa funkcji: nwd
# opis funkcji: wyznacza największy wspólny dzielnik metodą Euklidesa
# parametry: a - pierwsza liczba całkowita dodatnia
# b - druga liczba całkowita dodatnia
# zwracany typ i opis: int - największy wspólny dzielnik liczb a i b
# autor: 00000000000
# **********************************************
def nwd(a, b):
while a != b:
if a > b:
a = a - b
else:
b = b - a
return a
- Etykiety przepisz ze wzoru w arkuszu co do słowa. W jednych arkuszach jest „nazwa funkcji”, w innych samo „nazwa”.
- W polu „autor” wpisujesz numer zdającego, czyli PESEL, a nie imię.
- Gdy funkcja nie ma parametrów albo nic nie zwraca, wpisujesz „brak”.
- Arkusz wskazuje, którą funkcję opisać. Czasem jest to „dowolna funkcja”, czasem konkretna, na przykład „funkcja wyznaczająca NWD” albo „metoda klasy bazowej”.
Dla klasy wzór jest inny: „nazwa klasy”, „pola”, „metody”, „informacje”, „autor”. Też trafia do komentarza nad klasą.
Zrzuty ekranu
- Cały ekran, z widocznym paskiem zadań. Wycięte okno nie spełnia wymagania.
- Na zrzucie ma być wynik działania programu oraz otwarte środowisko programistyczne albo terminal.
- Jeśli program się nie uruchamia, zrzut ma pokazywać listę błędów. To nadal punkt za „podjętą próbę uruchomienia”.
- Tyle zrzutów, ile interakcji podejmuje program. Nazwy dokładnie z arkusza:
konsola1,konsola2i tak dalej.
Plik egzamin
Krótki dokument tekstowy z informacjami o narzędziach. Arkusz wymienia, co ma zawierać. Zwykle są to:
System operacyjny: Windows 11 Środowiska programistyczne: PyCharm 2024, Android Studio Emulator: Pixel 5 API 33 Języki programowania: Python 3.12, Kotlin
git log oraz git config user.name i git config user.email, wykonane w folderze projektu po zrobieniu kilku commitów.Testy: w programie głównym i jednostkowe
Arkusze znają dwa rodzaje testów. Starszy to zwykły program główny, który wywołuje funkcje i wypisuje wyniki. Nowszy to testy jednostkowe napisane w bibliotece do testów.
Test w programie głównym
Arkusz wymienia kroki, na przykład: wypisz licznik, utwórz obiekt, wywołaj metodę, wypisz licznik jeszcze raz. Wykonujesz je po kolei i każdy wynik opisujesz komunikatem.
film = Film()
print("Tytuł po utworzeniu:", film.pobierz_tytul())
film.ustaw_tytul("Rejs")
print("Tytuł po ustawieniu:", film.pobierz_tytul())
print("Wypożyczenia przed:", film.pobierz_liczbe_wypozyczen())
film.inkrementuj()
print("Wypożyczenia po:", film.pobierz_liczbe_wypozyczen())
Testy jednostkowe w unittest
Python ma bibliotekę unittest w standardzie. Testy pisze się w osobnym pliku, który importuje testowaną funkcję z pliku z programem.
import unittest
from konsola import szyfruj # z pliku konsola.py bierzemy funkcję szyfruj
class TestSzyfrCezara(unittest.TestCase):
def test_klucz_dodatni_przesuwa_litery(self):
self.assertEqual(szyfruj("abc", 3), "def")
def test_zawijanie_na_koncu_alfabetu(self):
self.assertEqual(szyfruj("xyz", 3), "abc")
unittest.main()
- Klasa z testami dziedziczy po
unittest.TestCase. - Każdy przypadek testowy to osobna metoda. Jej nazwa musi zaczynać się od
test_, inaczej biblioteka jej nie uruchomi. - Nazwa ma mówić, co jest sprawdzane. Arkusz tego wymaga: „nazwy metod testujących należy dobrać tak, aby wyrażały cel danego testu”.
- Wynik sprawdza asercja. Najczęściej
assertEqual(otrzymane, oczekiwane).
| Asercja | Przechodzi, gdy |
|---|---|
self.assertEqual(a, b) | a == b |
self.assertNotEqual(a, b) | a != b |
self.assertTrue(warunek) | warunek jest prawdziwy |
self.assertFalse(warunek) | warunek jest fałszywy |
self.assertIn(element, lista) | element jest na liście |
if __name__ == "__main__": Jeśli plik konsola.py ma program główny z input, to przy imporcie w pliku z testami ten program też się wykona. Żeby tego uniknąć, program główny umieszcza się pod tą instrukcją. Wtedy działa tylko przy bezpośrednim uruchomieniu pliku.Komponent i JSX
W czterech arkuszach część II to aplikacja webowa typu front-end. Arkusz pozwala wybrać framework Angular albo bibliotekę React. Ten kurs używa Reacta. Wymagania się powtarzają: jeden komponent, formularz albo lista ze stylami Bootstrapa i reakcja na kliknięcie.
Projekt na egzaminie
Projekt tworzysz w terminalu narzędziem Vite. Arkusz ze stycznia 2025 nazywa folder projektu egzamin.
npm create vite@latest egzamin -- --template react tworzy folder egzamin z projektem React cd egzamin npm install pobiera biblioteki projektu npm install bootstrap dodaje Bootstrap npm run dev uruchamia aplikację pod adresem localhost:5173
Jeśli wpiszesz samo npm create vite@latest, Vite zapyta po kolei o nazwę projektu, bibliotekę (wybierz React) i wariant (wybierz JavaScript). Adres aplikacji terminal wypisuje po starcie. Zmiany w kodzie widać w przeglądarce od razu po zapisaniu pliku.
| Miejsce w projekcie | Do czego służy |
|---|---|
src/App.jsx | Komponent aplikacji. Arkusze wymagają jednego komponentu, więc cały twój kod trafia tutaj. Zawartość z szablonu usuwasz. |
src/App.css | Własne style, na przykład body { padding: 20px; }. |
src/index.css | Style szablonu Vite. Wyczyść ten plik i App.css, bo gotowe reguły zmieniają wygląd strony. |
src/main.jsx | Plik startowy, który wstawia komponent App na stronę. Nie zmieniasz go. |
public/assets | Obrazy z archiwum. W kodzie odwołujesz się do nich jako assets/obraz1.jpg. |
Komponent to funkcja, która zwraca JSX
JSX wygląda jak HTML wpisany w JavaScript. W nawiasach klamrowych wstawiasz wartości z kodu.
Tablica jest zwykłą stałą w komponencie. Nagłówek bierze liczbę z kursy.length, więc po dopisaniu kursu zmieni się sam. Arkusz z czerwca 2022 wymaga właśnie tego.
Czym JSX różni się od HTML
| W HTML | W JSX | Uwagi |
|---|---|---|
class="btn" | className="btn" | class jest słowem kluczowym JavaScriptu. |
for="imie" | htmlFor="imie" | Z tego samego powodu. |
<input>, <img>, <br> | <input />, <img />, <br /> | Każdy znacznik musi być domknięty. |
| kilka elementów obok siebie | jeden element główny | Całość obejmij w <div> albo w pusty znacznik <> … </>. |
src="assets/obraz1.jpg" | src={"assets/" + zdjecie.filename} | Wartość z kodu idzie w klamrach, bez cudzysłowu. |
style="margin: 5px" | style={{ margin: 5 }} | Styl jest obiektem. Prościej dać klasę i napisać regułę w pliku CSS. |
<!-- komentarz --> | {/* komentarz */} |
className zamiast class, htmlFor zamiast for i domknięte wszystkie znaczniki.npm install bootstrap dołączasz go linią import 'bootstrap/dist/css/bootstrap.css'; na górze pliku. Arkusz podaje tę linię w tabeli pomocy. Wszystkie klasy potrzebne na egzaminie zbiera lekcja „Bootstrap”.Stan i zdarzenia
React rysuje stronę, wywołując funkcję komponentu. Żeby po kliknięciu narysował ją ponownie, zmieniana wartość musi być stanem. Zwykłej zmiennej React nie obserwuje.
useState(35)tworzy stan o wartości początkowej 35 i zwraca parę: aktualną wartość oraz funkcję, która ją zmienia.- Funkcję zmieniającą nazywa się zwyczajowo
seti nazwa stanu. - Stanu nie zmienia się przypisaniem.
liczbaPobran = liczbaPobran + 1skończy się błędem, bo to stała. Zawsze wywołujesz funkcję zmieniającą. - Po jej wywołaniu React uruchamia funkcję
Appjeszcze raz i poprawia na stronie to, co się zmieniło.
Zdarzenia
W atrybucie zdarzenia podajesz funkcję, a nie jej wywołanie. Nazwy zdarzeń pisze się z wielką literą w środku.
| Zdarzenie | Gdzie | Kiedy się dzieje |
|---|---|---|
onClick | przycisk | kliknięcie |
onChange | pole tekstowe, lista rozwijana, pole wyboru | zmiana wartości |
onSubmit | formularz | zatwierdzenie przyciskiem albo klawiszem Enter |
document.getElementById, albo podpina zdarzenia jak w zwykłym HTML: onclick="fun()". Wartości trzymasz w stanie, a zdarzenia podpinasz przez onClick={fun}.this.state i this.setState. Oba zapisy są poprawnym Reactem. Kurs trzyma się funkcji i useState, bo kodu jest mniej.Listy i warunki
Arkusze wymagają, żeby lista powstawała z tablicy „niezależnie od jej wymiaru”. W React robi to metoda map: z każdego elementu tablicy tworzy kawałek JSX.
Każdy element wygenerowany w pętli dostaje atrybut key o wartości, która się nie powtarza. Dla napisów wystarczy sam napis, dla obiektów pole id. Bez klucza aplikacja działa, ale React wypisuje ostrzeżenie w konsoli.
Wyświetlanie warunkowe
Trzeci sposób to funkcja z instrukcją if, która zwraca JSX albo null. Klucz do arkusza ze stycznia 2025 opisuje właśnie taką funkcję.
Zmiana elementu tablicy w stanie
Tablica w stanie też jest zmieniana przez funkcję zmieniającą. Podajesz jej nową tablicę, w której jeden obiekt jest podmieniony.
Zapis { ...zdjecie, downloads: … } tworzy kopię obiektu z jednym polem zmienionym.
zdjecie.downloads++ zmienia obiekt, ale React się o tym nie dowiaduje i liczba na stronie zostaje stara. Zmiana ma przejść przez setZdjecia.Formularze
Trzy z czterech arkuszy webowych to formularz. Szkielet ze stylami Bootstrapa arkusz podaje w tabeli pomocy po angielsku, w zwykłym HTML. Twoja praca to przepisać go na JSX, nadać polom znaczące identyfikatory i połączyć je ze stanem.
Pole jest połączone ze stanem w obie strony: value pokazuje wartość ze stanu, a onChange zapisuje do stanu to, co wpisał użytkownik. Dzięki temu w chwili zatwierdzenia wszystkie dane masz już w zmiennych.
| Kontrolka | Wartość ze stanu | Zapis do stanu w onChange |
|---|---|---|
<input type="text">, type="number", type="password" | value={imie} | setImie(event.target.value) |
<select> | value={rodzaj} na znaczniku select | setRodzaj(event.target.value) |
<input type="checkbox"> | checked={ulgowe} | setUlgowe(event.target.checked) |
Zatwierdzenie formularza
event.preventDefault()zatrzymuje domyślne zachowanie przeglądarki. Bez tej linii strona się przeładuje, stan wróci do początku, a konsola zostanie wyczyszczona.- Wartość z pola jest zawsze napisem, także z pola
type="number". Przed liczeniem zamień ją przezNumber(). Inaczej"3" + 1da"31". console.logwypisuje do konsoli przeglądarki (klawisz F12). Dwa arkusze każą pokazać wynik właśnie tam i udokumentować to zrzutem ekranu.
Pole nieaktywne i podpowiedź
Atrybut disabled dostaje wartość logiczną ze stanu. Gdy pole wyboru jest zaznaczone, pole hasła jest wyszarzone. Tak działa menedżer haseł z czerwca 2026.
id i htmlFor jest osobne kryterium. Nie jest spełnione, gdy nazwa jest przepisana z pomocy w arkuszu (exampleInputEmail1) albo nic nie znaczy (input1, x).useRef, w klasach React.createRef). Jest poprawny, ale pole wyboru sterujące innym polem i tak wymaga stanu, więc kurs używa stanu wszędzie.Bootstrap: gotowe klasy zamiast własnego CSS
Bootstrap to arkusz stylów z gotowymi klasami. Nie piszesz reguł CSS, tylko dopisujesz elementom nazwy klas. Każdy arkusz webowy wymaga Bootstrapa i ma na końcu tabelę pomocy po angielsku z fragmentami jego dokumentacji. W kluczach oceniania konkretne klasy są osobnymi kryteriami, więc literówka w nazwie klasy to stracony punkt.
Dołączenie do projektu
npm install bootstrap w terminalu, w folderze projektu
Kilka klas wpisujesz w jednym atrybucie, oddzielone spacjami. Kolejność nie ma znaczenia.
main.jsx, różnice między HTML a JSX oraz menu i okna modalne sterowane stanem zamiast skryptu Bootstrapa.Formularz
| Klasa | Na czym | Co robi |
|---|---|---|
form-group | div wokół etykiety i pola | Grupuje jedną pozycję formularza. Klucze wymagają jej wprost. |
form-control | input, select, textarea | Pole na całą szerokość, z ramką, zaokrągleniem i podświetleniem po kliknięciu. |
form-label | label | Odstęp pod etykietą. Arkusze jej nie wymagają. |
form-select | select | Lista rozwijana ze strzałką w stylu Bootstrapa 5. Arkusz z 2023 roku używa dla listy form-control. |
form-group istnieje tylko w wersji 4. W wersji 5 nic nie zmienia w wyglądzie, ale klucz i tak jej szuka, więc ją wpisz. Odstęp między polami dodasz wtedy klasą mb-3 albo m-4, jak w szablonie z 2026 roku.Pole wyboru i przełącznik
form-checkto blok,form-check-inputpole,form-check-labeletykieta. Te trzy klasy zawsze idą razem.- Dopisanie
form-switchdo bloku zamienia kwadracik w przełącznik. To nadalinput type="checkbox". form-check-inlinena bloku ustawia kilka pól w jednym rzędzie.
Przyciski
Przycisk ma zawsze dwie klasy: btn i klasę koloru. Sama klasa koloru bez btn nie działa.
| Klasa koloru | Kolor | W arkuszach |
|---|---|---|
btn-primary | niebieski | „Zapisz do kursu”, „Dodaj”, „Zapisz” |
btn-success | zielony | „Pobierz” w galerii |
btn-secondary | szary | |
btn-danger | czerwony | |
btn-warning | żółty | |
btn-info | błękitny | |
btn-light, btn-dark | jasny, ciemny |
Arkusz zwykle nie podaje nazwy klasy, tylko kolor: „przycisk jest koloru niebieskiego za sprawą odpowiedniej klasy Bootstrap”. Te same końcówki działają dla tekstu (text-primary, text-danger) i tła (bg-primary, bg-light).
Odstępy
Nazwa klasy składa się z trzech części: litera właściwości, opcjonalnie litera strony, myślnik i rozmiar od 0 do 5.
| Część nazwy | Znaczenie |
|---|---|
m | margines zewnętrzny (margin) |
p | margines wewnętrzny (padding) |
t, b | góra, dół |
s, e | lewa, prawa strona |
x, y | lewa i prawa, góra i dół |
| bez litery strony | wszystkie cztery strony |
| Rozmiar | Wartość | W pikselach |
|---|---|---|
0 | 0 | 0 |
1 | 0,25 rem | 4 |
2 | 0,5 rem | 8 |
3 | 1 rem | 16 |
4 | 1,5 rem | 24 |
5 | 3 rem | 48 |
Przykłady: p-2 to margines wewnętrzny 0,5 rem ze wszystkich stron, m-4 to zewnętrzny 1,5 rem, mt-3 to odstęp 1 rem od góry, px-5 to margines wewnętrzny 3 rem z lewej i prawej.
p-2. Siatka nie ma każdej wartości: marginesu 5 pikseli z galerii nie da się uzyskać klasą, bo m-1 to 4 piksele. Taki styl zapisujesz w pliku CSS.Tekst i obrazy
| Klasa | Co robi |
|---|---|
lead | Tekst wiodący: większy i lżejszy akapit. |
text-primary, text-success, text-danger | Kolor tekstu: niebieski, zielony, czerwony. |
text-start, text-center, text-end | Wyrównanie tekstu do lewej, do środka, do prawej. |
text-nowrap | Tekst nie łamie się na kolejne linie. |
text-capitalize, text-uppercase | Każde słowo wielką literą, wszystko wielkimi literami. |
fw-bold | Pogrubienie. |
rounded, rounded-circle | Zaokrąglone rogi, kształt koła. |
img-fluid | Obraz nie wychodzi poza szerokość bloku. |
Układ
| Klasa | Co robi |
|---|---|
container | Wyśrodkowany blok o ograniczonej szerokości z odstępem po bokach. |
row i col | Wiersz i kolumny równej szerokości. col-4 to kolumna na 4 z 12 części wiersza. |
d-flex, flex-wrap | Elementy obok siebie, z przechodzeniem do nowego rzędu, gdy brakuje miejsca. |
gap-2 | Odstęp między elementami w układzie d-flex. Rozmiary jak w odstępach. |
d-inline-block | Blok, który stoi w jednej linii z sąsiadami. |
Bloki zdjęć w galerii ze stycznia 2025 staną obok siebie, gdy ich wspólny rodzic dostanie d-flex flex-wrap albo każdy blok d-inline-block.
Jak czytać pomoc w arkuszu
| Zdanie z tabeli pomocy | Co z niego wynika |
|---|---|
| Textual form controls are styled with the .form-control class | Każde pole dostaje className="form-control". |
| Add modifier classes as btn-primary, btn-secondary, btn-success to btn class | Przycisk ma dwie klasy: btn i kolor. |
| A switch has the markup of a custom checkbox but uses the .form-switch class | Przełącznik to pole wyboru w bloku form-check form-switch. |
| The classes are used in the format {property}-{size} | Odstępy: m albo p, myślnik, rozmiar od 0 do 5. |
| In React render method use className instead of class; htmlFor instead of for | Przykłady w pomocy są w zwykłym HTML i trzeba je przepisać na JSX. |
Projekt i układ ekranu w XML
W dziesięciu arkuszach część II to aplikacja mobilna. Arkusz pozwala na Android Studio albo .NET MAUI. Ten kurs używa Android Studio z językiem Kotlin. Aplikacja składa się z dwóch plików, które sam piszesz: układu ekranu w XML i kodu w Kotlinie.
Nowy projekt
- W Android Studio wybierz New Project, a potem szablon Empty Views Activity. Szablon „Empty Activity” bez słowa Views tworzy projekt w Jetpack Compose, bez pliku XML, a arkusz wymaga interfejsu w języku znaczników.
- Język: Kotlin. Nazwę projektu przepisz z arkusza, jeśli ją podaje.
- Po utworzeniu poczekaj, aż Gradle skończy pobierać i budować. Trwa to kilka minut i warto zacząć od tego kroku.
| Plik | Do czego służy |
|---|---|
app/res/layout/activity_main.xml | Układ ekranu. Przełącz widok z Design na Code i pisz XML ręcznie. |
app/java/…/MainActivity.kt | Kod: reakcje na kliknięcia i zmiany. |
app/res/drawable | Obrazy z archiwum. Nazwa pliku może mieć tylko małe litery, cyfry i podkreślnik. W XML piszesz @drawable/obraz, w kodzie R.drawable.obraz, bez rozszerzenia. |
Układ liniowy
Szablon wstawia do pliku układ ConstraintLayout. Arkusze wymagają rozkładu liniowego, więc zamieniasz go na LinearLayout. Układa on elementy jeden pod drugim albo jeden obok drugiego.
| Atrybut | Wartości | Znaczenie |
|---|---|---|
android:layout_width, android:layout_height | match_parent, wrap_content, 150dp | Obowiązkowe w każdym elemencie. Cała szerokość rodzica, tyle ile zajmuje treść albo konkretny rozmiar. |
android:orientation | vertical, horizontal | Kierunek układu liniowego. Bez tego atrybutu układ jest poziomy. |
android:id | @+id/poleEmail | Nazwa, po której kod znajdzie element. Dajesz ją każdemu elementowi, którego używa kod. |
android:text | napis | Treść napisu albo przycisku. |
android:hint | napis | Podpowiedź w pustym polu edycyjnym. |
android:inputType | textPassword, number, time, textEmailAddress | Rodzaj danych w polu: ukryte hasło, same cyfry, godzina, adres e-mail. |
| Arkusz mówi | Znacznik |
|---|---|
| napis, etykieta, pole tekstowe | TextView |
| pole edycyjne | EditText |
| przycisk | Button |
| obraz | ImageView |
| suwak | SeekBar |
| lista, widok listy | ListView |
| pola radio | RadioGroup z elementami RadioButton |
| linia horyzontalna | View o wysokości 1dp z kolorem tła |
Rozmiary podaje się w dp, a rozmiar czcionki w sp. Arkusze piszą samo „marginesy 20” albo „wysokość 150”. Wpisujesz wtedy 20dp i 150dp.
main: kod z szablonu odwołuje się do głównego układu przez R.id.main. Jeśli przy zamianie na LinearLayout skasujesz android:id="@+id/main", projekt przestanie się kompilować. Zostaw ten identyfikator albo usuń z MainActivity.kt fragment z setOnApplyWindowInsetsListener.Wygląd: kolory, czcionki, odstępy
Większość punktów za układ to konkretne cechy wyglądu wymienione w „Założeniach aplikacji”: kolor tła, kolor i rozmiar czcionki, marginesy, wyśrodkowanie. Klucz sprawdza je w kodzie XML, jedną po drugiej.
| Arkusz mówi | Atrybut |
|---|---|
| kolor tła Teal (#008080) | android:background="#008080" |
| kolor tła przycisku | android:backgroundTint="#DC143C" |
| biały kolor czcionki | android:textColor="#FFFFFF" |
| czcionka większa od pozostałych, rozmiar 40 | android:textSize="40sp". Domyślny rozmiar napisu to 14sp. |
| czcionka pogrubiona | android:textStyle="bold" |
| margines wewnętrzny 10 | android:padding="10dp", z jednej strony android:paddingTop="20dp" |
| margines zewnętrzny 10 | android:layout_margin="10dp", z jednej strony android:layout_marginBottom="20dp" |
| przezroczystość 50% | android:alpha="0.5" |
android:background go nie zmienia. Działa android:backgroundTint. Arkusz podaje kolor nazwą i kodem, na przykład Crimson (#DC143C). W XML wpisujesz kod.Wyśrodkowanie i wyrównanie
Są dwa podobne atrybuty i łatwo je pomylić.
| Atrybut | Co ustawia | Przykład |
|---|---|---|
android:layout_gravity | Położenie elementu w jego rodzicu. | Przycisk na środku ekranu: layout_gravity="center" na przycisku. |
android:gravity | Położenie treści wewnątrz elementu. | Napis na całą szerokość z tekstem do prawej: gravity="end". Na układzie: wszystkie jego dzieci na środku. |
Układ w układzie i podział szerokości
Elementy obok siebie wymagają poziomego układu liniowego włożonego w pionowy. Arkusze mówią o „zagłębionym rozkładzie horyzontalnym”.
Para layout_width="0dp" i layout_weight="1" oznacza „weź całe wolne miejsce”. Pole edycyjne rozciąga się, a przycisk zajmuje tyle, ile potrzebuje. Gdy wagę dostanie pięć obrazów, podzielą szerokość po równo.
Obraz i linia
adjustViewBounds dopasowuje wysokość obrazu do jego proporcji, gdy szerokość jest rozciągnięta na cały ekran.
Kotlin: kod i zdarzenia
Kotlin jest podobny do Pythona bardziej, niż wygląda. Różnice, które mają znaczenie w arkuszach, mieszczą się w jednej tabeli.
| Python | Kotlin | Uwagi |
|---|---|---|
licznik = 0 | var licznik = 0 | var to zmienna, val to stała. Typ wynika z wartości. |
f"{licznik} polubień" | "$licznik polubień" | Znak dolara wstawia wartość zmiennej. Dla wyrażenia: "${a + b}". |
if x > 0: | if (x > 0) { … } | Warunek w nawiasach, blok w klamrach. |
elif, and, or, not | else if, &&, ||, ! | |
for i in range(5): | for (i in 0..4) { … } | Zakres 0..4 zawiera oba końce. |
["a", "b"] | arrayOf("a", "b") | Lista, do której można dodawać: arrayListOf("a", "b"). |
len(lista) | lista.size | |
random.randint(1, 6) | (1..6).random() | |
int(tekst), str(liczba) | tekst.toInt(), liczba.toString() | toIntOrNull() zwraca null zamiast błędu, gdy tekst nie jest liczbą. |
def nazwa(a): | fun nazwa(a: Int): Int { … } | Parametry i wynik mają podany typ. |
Dostęp do elementów ekranu
Cały kod piszesz w funkcji onCreate, pod linią setContentView. Element z układu pobierasz po identyfikatorze, podając jego typ.
findViewById<TextView>(R.id.napisLicznika)zwraca element o identyfikatorzenapisLicznika. Typ w nawiasach ostrych musi zgadzać się ze znacznikiem w XML.setOnClickListener { … }podpina kod do kliknięcia. Działa na przyciskach, obrazach i napisach.- Zmienna, która ma przetrwać między kliknięciami, jest polem klasy: stoi nad
onCreate, a nie w środku bloku kliknięcia. - Każdy użyty typ wymaga linii
importna górze pliku. Android Studio dopisuje ją samo po wciśnięciu Alt+Enter na czerwonej nazwie.
| Co chcesz zrobić | Zapis |
|---|---|
| Zmienić napis | komunikat.text = "Hasła się różnią" |
| Odczytać tekst z pola edycyjnego | val email = poleEmail.text.toString() |
| Odczytać liczbę z pola | val numer = poleNumeru.text.toString().toIntOrNull() |
| Sprawdzić, czy napis zawiera znak | email.contains("@") |
| Zmienić rozmiar czcionki | napisCytatu.textSize = 30f |
| Podmienić obraz | obrazKosci.setImageResource(R.drawable.kosc4) |
| Ustawić przezroczystość | obrazKosci.alpha = 0.5f |
setOnClickListener i jeden findViewById, nawet gdy reszta logiki nie działa.Lista, suwak, pola radio
Trzy kontrolki wracają w arkuszach i każda ma własny sposób obsługi w kodzie.
Lista: kolekcja, adapter, odświeżenie
Widok listy sam nie przechowuje danych. Dane są w kolekcji w kodzie, a adapter zamienia jej elementy na wiersze listy.
arrayListOf(…)tworzy listę, do której można dodawać. Zwykła tablicaarrayOfma stałą długość.android.R.layout.simple_list_item_1to gotowy wygląd wiersza z systemu: jeden napis.- Po każdej zmianie kolekcji wołasz
adapter.notifyDataSetChanged(). Bez tego lista na ekranie się nie zmieni. Klucz z czerwca 2026 wymienia tę metodę z nazwy. - Gdy kolekcja przechowuje obiekty własnej klasy, wiersz pokazuje wynik jej metody
toString(). - Kliknięcie wiersza obsługuje
setOnItemClickListener { _, _, pozycja, _ -> … }. Trzeci parametr to numer klikniętego wiersza.
android:divider="#DC143C". Samo to ją ukrywa, bo po zmianie koloru kreska ma wysokość 0. Trzeba dodać android:dividerHeight="2dp".Suwak
W XML suwak ma wartość maksymalną android:max i początkową android:progress. W kodzie reakcja na przesunięcie to obiekt z trzema metodami. Wszystkie trzy muszą być wpisane, choć potrzebna jest zwykle pierwsza.
Parametr progress jest liczbą całkowitą, czego arkusze wymagają. Rozmiar czcionki jest liczbą rzeczywistą, stąd toFloat(). Wartość maksymalną zmienia się w kodzie przez suwak.max = 18.
Pola radio
Pola włożone do RadioGroup wykluczają się: zaznaczone może być tylko jedno. W kodzie poleOdpowiedzi.isChecked mówi, czy pole jest zaznaczone, a grupaOdpowiedzi.clearCheck() odznacza wszystkie.
Tablica obrazów
Gdy obraz zależy od liczby, na przykład od liczby oczek, identyfikatory grafik wkłada się do tablicy i wybiera indeksem.
Projekt WPF i okno w XAML
W sześciu arkuszach część II to aplikacja desktopowa, czyli zwykłe okno systemu Windows z kontrolkami. Arkusz nie narzuca technologii. Ten kurs używa WPF z językiem C# w Visual Studio. Budowa jest taka sama jak w aplikacji mobilnej: wygląd okna opisuje plik znaczników, a działanie plik z kodem.
Nowy projekt
- W Visual Studio wybierz Utwórz nowy projekt, a potem szablon Aplikacja WPF dla języka C#. Nie myl go z „Aplikacją Windows Forms” ani z biblioteką WPF.
- Nazwij projekt tak, jak każe arkusz. W tym kursie projekt nazywa się
Egzamin. - Uruchamiasz klawiszem F5.
| Plik | Do czego służy |
|---|---|
MainWindow.xaml | Wygląd okna: tytuł, rozmiar, kolor i wszystkie kontrolki. |
MainWindow.xaml.cs | Kod: metody wywoływane po kliknięciu i innych zdarzeniach. |
| obrazy z archiwum | Przeciągasz je do projektu i we właściwościach pliku ustawiasz „Akcja kompilacji: Zasób”. Bez tego obraz widać w projektancie, a w działającym programie już nie. |
Okno i panel
Znacznik Window opisuje okno. Jego atrybuty to tytuł, rozmiar i tło. W środku może być tylko jeden element, więc wkłada się tam panel, a kontrolki do panelu. Najprostszy panel to StackPanel: układa elementy jeden pod drugim.
| Arkusz mówi | Znacznik | Gdzie jest treść |
|---|---|---|
| etykieta, napis | Label albo TextBlock | Content w etykiecie, Text w bloku tekstu |
| pole edycyjne | TextBox | Text |
| przycisk | Button | Content |
| pole wyboru | CheckBox | Content, zaznaczenie IsChecked="True" |
| pole radio, pole opcji | RadioButton | Content, zaznaczenie IsChecked="True" |
| lista rozwijalna | ComboBox z elementami ComboBoxItem | Content każdego elementu |
| suwak | Slider | Minimum, Maximum, Value |
| obraz | Image | Source="pocztowka.png" |
| grupa kontrolek | GroupBox | podpis ramki w Header |
- Nazwę kontrolki nadaje
x:Name="poleImie". Pod tą nazwą kontrolka jest od razu dostępna w kodzie, bez żadnego wyszukiwania. - Atrybuty piszesz wielką literą i bez przedrostka:
Width,Margin,Content. Rozmiary są samymi liczbami. - W
StackPanelkontrolka zajmuje całą szerokość. Gdy podasz jejWidth, staje na środku.
Title.Układ okna: siatka, grupy, kolory
Okna z arkuszy mają etykiety obok pól i ramki z podpisem wokół grup kontrolek. Do pierwszego służy siatka Grid, do drugiego GroupBox.
Siatka
- Najpierw opisujesz wiersze i kolumny, potem każdej kontrolce podajesz jej miejsce:
Grid.RowiGrid.Column, liczone od zera. - Rozmiar
Autooznacza „tyle, ile potrzebuje treść”, gwiazdka*„całe pozostałe miejsce”, a liczba konkretny rozmiar. Grid.ColumnSpan="2"rozciąga kontrolkę na dwie kolumny. Tak ustawia się przycisk „Zatwierdź” pod dwiema grupami.- Kontrolka bez podanego miejsca trafia do wiersza 0 i kolumny 0. Dwie takie kontrolki nakładają się na siebie.
Grupa z podpisem
GroupBox, tak jak okno, przyjmuje jeden element, więc w środku znów jest panel. Pola radio włożone do jednego panelu działają jako grupa: zaznaczone może być tylko jedno.
Wygląd
| Arkusz mówi | Atrybut |
|---|---|
| tło koloru LightSteelBlue (#B0C4DE) | Background="LightSteelBlue" albo Background="#B0C4DE" |
| biały kolor czcionki | Foreground="White" |
| czcionka większa, rozmiar 50 | FontSize="50". Domyślny rozmiar to 12. |
| napis pogrubiony, pochylony | FontWeight="Bold", FontStyle="Italic" |
| odstęp od sąsiadów | Margin="10", osobno dla stron Margin="lewy,górny,prawy,dolny" |
| przycisk wyraźnie dłuższy, wysokość obrazu 180 | Width="260", Height="180" |
| wyrównanie w komórce albo panelu | HorizontalAlignment="Left", VerticalAlignment="Center" |
| obramowanie z zaokrąglonymi rogami | <Border BorderBrush="AntiqueWhite" BorderThickness="3" CornerRadius="15"> wokół elementu |
| szerokość okna dopasowana do kontrolek | SizeToContent="Width" w znaczniku Window |
Background, a prostokąta Rectangle atrybut Fill.C#: kod i zdarzenia
C# ma nawiasy klamrowe i średniki, a każda zmienna ma podany typ. Poza tym instrukcje są te same co w Pythonie.
| Python | C# | Uwagi |
|---|---|---|
licznik = 0 | int licznik = 0; | Typy: int, double, string, bool, char. Każda instrukcja kończy się średnikiem. |
"Witaj " + imie | "Witaj " + imie | Liczbę można dokleić do napisu bez zamiany: "Cena: " + cena. |
if x > 0: | if (x > 0) { … } | Dalej else if i else. |
and, or, not | &&, ||, ! | |
for i in range(5): | for (int i = 0; i < 5; i++) { … } | |
for znak in tekst: | foreach (char znak in tekst) { … } | |
len(tekst), len(lista) | tekst.Length, lista.Count | Tablica też ma Length. |
int(tekst) | int.Parse(tekst) | int.TryParse(tekst, out liczba) zwraca fałsz zamiast błędu, gdy tekst nie jest liczbą. |
random.randint(0, 9) | generator.Next(10) | Wcześniej Random generator = new Random();. Górna granica nie wchodzi do zakresu. |
def nazwa(a): | private string Nazwa(string a) { … } | Przed nazwą typ wyniku, void gdy metoda nic nie zwraca. |
Kliknięcie przycisku
Zdarzenie łączysz z kodem w dwóch miejscach. W XAML przycisk dostaje atrybut Click z nazwą metody, a w pliku z kodem piszesz metodę o tej nazwie.
- Nagłówek metody jest zawsze taki sam:
private void Nazwa(object sender, RoutedEventArgs e). Visual Studio wpisze go samo, gdy w XAML poClick=wybierzesz „Nowy program obsługi zdarzeń” albo dwa razy klikniesz przycisk w projektancie. - Nazwa w XAML i nazwa metody muszą być identyczne. Gdy metoda zniknie z kodu, a atrybut zostanie, projekt się nie skompiluje.
- Kontrolki są dostępne po nazwach z
x:Name:poleImie.Text,napisPowitania.Content. - Zmienna, która ma przetrwać między kliknięciami albo być wspólna dla dwóch metod, jest polem klasy: stoi nad konstruktorem, poza metodami.
| Co chcesz zrobić | Zapis |
|---|---|
| Odczytać i zmienić tekst pola edycyjnego | poleImie.Text |
| Zmienić treść etykiety albo przycisku | napisCeny.Content = "Cena: 1 zł"; |
| Sprawdzić pole wyboru albo pole radio | if (poleCyfry.IsChecked == true) |
| Pokazać okienko z komunikatem | MessageBox.Show("Wprowadź dane"); |
| Sprawdzić, czy pole jest puste | if (poleImie.Text == "") |
| Sprawdzić, czy znak jest cyfrą | char.IsDigit(znak) |
== true: pole IsChecked ma trzy możliwe wartości: prawda, fałsz i brak wartości. Dlatego samo if (poleCyfry.IsChecked) się nie skompiluje.Lista rozwijana, suwak, obrazy i pliki
Lista rozwijana
Tekst wybranej pozycji daje w kodzie listaStanowisk.Text, a jej numer listaStanowisk.SelectedIndex. Gdy nic nie wybrano, tekst jest pusty, a numer wynosi -1.
Suwak
Suwak zgłasza zdarzenie ValueChanged. Jego metoda ma inny drugi parametr niż metoda kliknięcia.
Valuejest liczbą rzeczywistą. Liczbę całkowitą dostajesz przez rzutowanie:(int)suwak.Value, a dla składowej koloru(byte)suwak.Value.- Jedną metodę można podpiąć pod kilka suwaków. Wystarczy w każdym wpisać tę samą nazwę w
ValueChanged.
Value="255", zdarzenie ValueChanged zachodzi już podczas budowania okna. Kontrolki zapisane niżej w pliku jeszcze wtedy nie istnieją i program kończy się błędem zaraz po uruchomieniu. Linia if (!IsLoaded) return; na początku metody pomija te przedwczesne wywołania.Kolor z trzech składowych
Tło i kolor czcionki to w kodzie pędzle. Dla gotowych kolorów wystarczy Brushes.Red. Te typy wymagają linii using System.Windows.Media; na górze pliku.
Zmiana obrazu w kodzie
Początek adresu pack://application:,,,/ oznacza „z zasobów tej aplikacji”. Typ BitmapImage wymaga linii using System.Windows.Media.Imaging;. Gdy takiego zasobu nie ma, powstaje wyjątek, który można złapać blokiem try i catch i wtedy wyczyścić obraz przez obraz.Source = null;.
Inne zdarzenia i pliki
| Arkusz mówi | W XAML | W kodzie |
|---|---|---|
| po opuszczeniu pola edycyjnego | LostFocus="PoleNumeru_LostFocus" na polu | metoda z parametrami jak przy kliknięciu |
| po załadowaniu okna | Loaded="Window_Loaded" w znaczniku Window | metoda z parametrami jak przy kliknięciu |
| wczytuje dane z pliku | string[] linie = File.ReadAllLines("Data.txt"); | |
| okno dialogowe do zapisu pliku | SaveFileDialog, potem File.WriteAllText(okno.FileName, tekst); | |
| pole wielowierszowe z zawijaniem | AcceptsReturn="True" TextWrapping="Wrap" |
Klasa File wymaga using System.IO;, a SaveFileDialog wymaga using Microsoft.Win32;. Plik z danymi musi leżeć obok programu: we właściwościach pliku ustaw „Kopiuj do katalogu wyjściowego: Kopiuj, jeśli nowszy”.
Wszystkie arkusze
Dwadzieścia jeden arkuszy z lat 2021–2026. Arkusz ze stycznia 2022 jest powtórzeniem arkusza z czerwca 2021, więc różnych zadań jest dwadzieścia. Kolumna „Pliki” mówi, co jest w archiwum z pulpitu. Hasło do archiwum jest zawsze w treści arkusza. Arkusze z aplikacją webową i mobilną mają w kolumnie „Część II” przycisk do ćwiczenia.
Arkusze, klucze oceniania i archiwa pochodzą z serwisu zawodowe.edu.pl. Archiwum Web1.7z do arkusza z czerwca 2026 pochodzi z repozytorium Gierak/INF.04_Rozwiazania.
Ściąga: język arkusza a Python, React, Android i WPF
Klasy
| Arkusz mówi | W Pythonie |
|---|---|
| konstruktor | def __init__(self, ...): |
| konstruktor bezparametrowy i z parametrami | jeden konstruktor z wartościami domyślnymi: def __init__(self, id=0, imie=""): |
| konstruktor bezargumentowy, który losuje | def __init__(self, wartosc=None): i warunek if wartosc is None: |
| konstruktor kopiujący | metoda kopiuj(self, inny) przepisująca pola |
| pole ogólnodostępne | self.pole |
| pole dostępne w klasie i klasach potomnych | self._pole |
| pole dostępne tylko w klasie | self.__pole |
| pole statyczne | w ciele klasy: licznik = 0, zmiana przez Klasa.licznik += 1 |
| metoda statyczna | @staticmethod nad metodą bez self |
| getter, setter | metody pobierz_...(self) i ustaw_...(self, wartosc) |
| klasa potomna | class Pralka(Urzadzenie): |
| wywołanie konstruktora klasy bazowej | super().__init__(...) |
| klasa, której obiektu nie można utworzyć | class Pytanie(ABC): z metodą @abstractmethod |
| typ logiczny | True, False |
| typ znakowy | napis długości 1: "K" |
| null | None |
| typ przechowujący datę | datetime.date.today() po import datetime |
Funkcje i dane
| Co chcesz zrobić | Zapis |
|---|---|
| Wczytać liczbę całkowitą | liczba = int(input("Podaj liczbę: ")) |
| Pytać do skutku | while liczba < 3 or liczba > 10: i ponowne input w pętli |
| Wylosować liczbę od 1 do 6 | random.randint(1, 6) |
| Wypisać listę po przecinku | print(", ".join(str(liczba) for liczba in liczby)) |
| Zamienić dwa elementy | przez zmienną tmp |
| Kod znaku i znak z kodu | ord("a") daje 97, chr(97) daje "a" |
| Reszta z dzielenia | suma % 10 |
| Tablica wartości logicznych | [True] * (n + 1) |
| Tablica n wierszy po 6 kolumn | [[0] * 6 for wiersz in range(n)] |
| Otworzyć plik | with open("Data.txt", encoding="utf-8") as plik: |
Aplikacja webowa w React
| Arkusz mówi | W React |
|---|---|
| jeden komponent | funkcja App w src/App.jsx, na końcu export default App; |
| nowy projekt | npm create vite@latest egzamin -- --template react, potem npm install i npm run dev |
| zastosuj bibliotekę Bootstrap | npm install bootstrap i w komponencie import 'bootstrap/dist/css/bootstrap.css'; |
| klasa i etykieta z pomocy w arkuszu | className zamiast class, htmlFor zamiast for, domknięte <input /> |
| liczba elementów tablicy | {kursy.length} |
| lista generowana automatycznie | {kursy.map((kurs) => <li key={kurs}>{kurs}</li>)} |
| element wyświetlany warunkowo | {warunek && <p>…</p>} albo filter przed map |
| wartość, która zmienia się na stronie | const [liczba, setLiczba] = useState(0); |
| kliknięcie przycisku | onClick={pobierz}, z argumentem onClick={() => pobierz(id)} |
| pole edycyjne | value={imie} onChange={(event) => setImie(event.target.value)} |
| pole wyboru, przełącznik | checked={kwiaty} onChange={(event) => setKwiaty(event.target.checked)} |
| pole nieaktywne | disabled={generujHaslo} |
| zdarzenie zatwierdzenia formularza | <form onSubmit={zapisz}>, a w funkcji najpierw event.preventDefault(); |
| wyświetla w konsoli przeglądarki | console.log(imie); |
| liczba z pola formularza | Number(numerKursu) |
| zmiana jednego obiektu w tablicy | setZdjecia(zdjecia.map((z) => z.id === id ? { ...z, downloads: z.downloads + 1 } : z)); |
| Klasy Bootstrapa z arkuszy | Do czego |
|---|---|
form-group, form-control | blok z etykietą i polem, samo pole |
form-check form-switch, form-check-input, form-check-label | przełącznik: blok, pole wyboru, etykieta |
btn btn-primary, btn btn-success | przycisk niebieski, przycisk zielony |
p-2, m-4 | margines wewnętrzny 0,5 rem, zewnętrzny 1,5 rem |
btn-secondary, btn-danger, btn-warning | przycisk szary, czerwony, żółty |
mt-3, mb-3, px-5 | odstęp od góry 1 rem, od dołu 1 rem, wewnętrzny z boków 3 rem |
lead, text-primary, rounded | tekst wiodący, niebieski tekst, zaokrąglone rogi |
text-center, fw-bold, text-nowrap | tekst na środku, pogrubiony, bez łamania linii |
container, d-flex flex-wrap, d-inline-block | blok strony, elementy obok siebie z zawijaniem, blok w linii |
Aplikacja mobilna: układ w XML
| Arkusz mówi | W pliku activity_main.xml |
|---|---|
| rozkład liniowy wertykalny | <LinearLayout android:orientation="vertical"> |
| zagłębiony rozkład horyzontalny | drugi LinearLayout w środku, z android:orientation="horizontal" |
| rozciągnięty na całą szerokość | android:layout_width="match_parent" |
| elementy dzielą szerokość po równo | android:layout_width="0dp" i android:layout_weight="1" |
| kolor tła, kolor tła przycisku | android:background="#008080", android:backgroundTint="#DC143C" |
| kolor czcionki, rozmiar, pogrubienie | android:textColor, android:textSize="24sp", android:textStyle="bold" |
| margines wewnętrzny, zewnętrzny | android:padding="10dp", android:layout_margin="10dp" |
| element wyśrodkowany | android:layout_gravity="center" na elemencie albo android:gravity="center" na jego układzie |
| napis wyrównany do prawej | szerokość match_parent i android:gravity="end" |
| podpowiedź, ukrywanie hasła, same liczby | android:hint, android:inputType="textPassword", android:inputType="number" |
| obraz z archiwum | plik w res/drawable, w układzie android:src="@drawable/obraz" |
| linia horyzontalna | <View android:layout_height="1dp" android:background="#808080" /> |
| suwak o wartości maksymalnej 40 | <SeekBar android:max="40" /> |
| widoczny separator listy | android:divider="#DC143C" i android:dividerHeight="2dp" |
| tylko jedno pole radio naraz | pola RadioButton w znaczniku RadioGroup |
Aplikacja mobilna: kod w Kotlinie
| Co chcesz zrobić | Zapis |
|---|---|
| Pobrać element z układu | val komunikat = findViewById<TextView>(R.id.komunikat) |
| Obsłużyć kliknięcie | przycisk.setOnClickListener { … } |
| Zmienić napis, odczytać pole | komunikat.text = "Witaj $email", poleEmail.text.toString() |
| Liczba z pola edycyjnego | pole.text.toString().toIntOrNull() |
| Licznik między kliknięciami | pole klasy nad onCreate: private var licznik = 0 |
| Losowa liczba od 1 do 6 | (1..6).random() |
| Podmienić obraz, ustawić przezroczystość | obraz.setImageResource(R.drawable.kosc4), obraz.alpha = 0.5f |
| Lista z kolekcji | ArrayAdapter(this, android.R.layout.simple_list_item_1, notatki) przypisany do lista.adapter |
| Odświeżyć listę po dodaniu | adapter.notifyDataSetChanged() |
| Kliknięcie wiersza listy | lista.setOnItemClickListener { _, _, pozycja, _ -> … } |
| Zmiana suwaka | setOnSeekBarChangeListener z metodami onProgressChanged, onStartTrackingTouch, onStopTrackingTouch |
| Pole radio zaznaczone, odznacz wszystkie | pole.isChecked, grupa.clearCheck() |
Aplikacja desktopowa: okno w XAML
| Arkusz mówi | W pliku MainWindow.xaml |
|---|---|
| okno o nazwie … z numerem zdającego | Title="Dodaj pracownika 00000000000" w znaczniku Window |
| okno ma tło koloru … | Background="LightSteelBlue" w znaczniku Window |
| szerokość okna dopasowana do kontrolek | SizeToContent="Width" |
| kontrolki jedna pod drugą, obok siebie | StackPanel, StackPanel Orientation="Horizontal" |
| etykieta obok pola | Grid z RowDefinitions i ColumnDefinitions, miejsce przez Grid.Row i Grid.Column |
| grupa kontrolek z podpisem | <GroupBox Header="Dane Pracownika"> z jednym panelem w środku |
| pole domyślnie zaznaczone | IsChecked="True" |
| lista rozwijalna z elementami | ComboBox z elementami <ComboBoxItem Content="Tester" /> |
| suwak od 0 do 255 o wartości 255 | <Slider Minimum="0" Maximum="255" Value="255" /> |
| tło, kolor czcionki, rozmiar | Background, Foreground, FontSize |
| pogrubiony, pochylony | FontWeight="Bold", FontStyle="Italic" |
| przycisk wypełniony grafiką | <Button><Image Source="obraz2.png" Height="70" /></Button> |
| obramowanie z zaokrąglonymi rogami | <Border BorderBrush="…" BorderThickness="3" CornerRadius="15"> |
| pole wielowierszowe z zawijaniem | AcceptsReturn="True" TextWrapping="Wrap" |
| kliknięcie, zmiana suwaka, opuszczenie pola, załadowanie okna | Click, ValueChanged, LostFocus, Loaded z nazwą metody |
Aplikacja desktopowa: kod w C#
| Co chcesz zrobić | Zapis |
|---|---|
| Metoda kliknięcia | private void Zatwierdz_Click(object sender, RoutedEventArgs e) { … } |
| Metoda suwaka | drugi parametr RoutedPropertyChangedEventArgs<double> e, na początku if (!IsLoaded) return; |
| Tekst pola, treść etykiety | poleImie.Text, napisCeny.Content = "Cena: 1 zł"; |
| Pole wyboru albo radio zaznaczone | if (poleCyfry.IsChecked == true) |
| Okienko z komunikatem | MessageBox.Show("Wprowadź dane"); |
| Tekst wybrany z listy rozwijalnej | listaStanowisk.Text |
| Liczba z pola, bez błędu przy złym tekście | int.TryParse(poleKlucza.Text, out klucz) |
| Losowy znak z napisu | litery[generator.Next(litery.Length)] |
| Kolor z suwaków | new SolidColorBrush(Color.FromRgb(czerwony, zielony, niebieski)) |
| Zmiana obrazu | obraz.Source = new BitmapImage(new Uri("pack://application:,,,/list.png")); |
| Wczytanie pliku, zapis pliku | File.ReadAllLines("Data.txt"), File.WriteAllText(nazwa, tekst) |
| Systemowe okno zapisu | SaveFileDialog, ShowDialog() == true, FileName |
Zanim oddasz pracę
- Nazwy funkcji, klas i pól coś znaczą. Żadnych
x,fun,tab. - Każde
inputma komunikat, każdy wynik opis. - Nie ma gotowych funkcji, których arkusz zabrania:
sort,sorted,max,min. - Funkcja, która „nie zawiera operacji wejścia-wyjścia”, nie ma w środku
printaniinput. - Nad wskazaną funkcją jest nagłówek w komentarzu z numerem zdającego.
- Zrzuty obejmują cały ekran i mają nazwy z arkusza.
- W folderze jest archiwum całego projektu i osobno plik
.py. - W aplikacji webowej nie ma
getElementByIdanionclick="…", a identyfikatory pól nie są przepisane z pomocy. - W folderze
webalbowebowajestweb.zipz całym projektem i osobno zmieniane pliki źródłowe. - W aplikacji mobilnej każdy element używany w kodzie ma
android:id, a napisy i kolory zgadzają się z arkuszem co do znaku. - W folderze
mobilnajestmobilna.zipz całym projektem oraz osobnoactivity_main.xmliMainActivity.kt. - W aplikacji desktopowej tytuł okna ma numer zdającego, a każda metoda wpisana w XAML istnieje w kodzie.
- Obrazy w projekcie WPF mają akcję kompilacji „Zasób”, a plik z danymi kopiuje się do katalogu wyjściowego.
Quiz
Pytania o to, jak wymagania z arkuszy zapisać w Pythonie, w React, w Android Studio i w WPF. Po kliknięciu odpowiedzi zobaczysz wyjaśnienie.