INF.04-01-23.06-SGCzerwiec 2023 · 28 kroków · ok. 79 min · 30 kryteriów z klucza
Rozwiązanie krok po kroku: Aplikacja konsolowa i desktopowa (C# + WPF)
Rozwiązujemy arkusz z sitem Eratostenesa i okienkiem do nadawania przesyłek w wersji C# + WPF: w konsoli pseudokod z arkusza przepisany na funkcję wykreślającą wielokrotności w tablicy logicznej, a w aplikacji desktopowej okno „Nadaj Przesyłkę” z grupą przycisków opcji, obrazem i ceną zależnymi od rodzaju przesyłki oraz sprawdzaniem kodu pocztowego. Do tego dokumentacja funkcji według listingu 1, zrzuty i dokument egzamin.
Kroki idą zdanie po zdaniu za treścią arkusza - każdy zaczyna się cytatem wymagania, a kod pokazuje dokładnie te linie, które je spełniają. Najpierw piszemy najprostszą wersję, której wymaga klucz, a w etapie „Dobre praktyki” poprawiamy to, czego klucz nie sprawdza.
Co widać w podglądzie. Wyniki programu konsolowego pochodzą z prawdziwego uruchomienia kodu z danego kroku (.NET 10), a wypisane liczby porównaliśmy z niezależnie wyznaczoną listą 25 liczb pierwszych do 100. Okno aplikacji to symulacja WPF w przeglądarce zbudowana z XAML danego kroku, z obrazami z archiwum materialy.zip; jej zachowanie odpowiada kodowi C# z kroku. Każdy stan okna sprawdziliśmy na prawdziwym WPF - obraz, cenę i wszystkie trzy komunikaty.
Arkusz pozwala też na C++, Javę albo Pythona i na inne biblioteki okienkowe - ten wariant to jedna z możliwych dróg.
Jak liczą się punkty. Klucz ma 30 kryteriów (R.1.1 - R.4.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 23 punkty - można stracić 7 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.
Krok 1 · po tym etapie masz 0 z 30 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: konsola, desktop, dokumentacja.
Na pulpicie zakładamy folder o nazwie z numerem PESEL, a w nim konsola, desktop i dokumentacja. Zrzuty ekranu i dokument egzamin trafią do folderu dokumentacja.
Etap 2: Aplikacja konsolowa
Kroki 2-7 · po tym etapie masz 11 z 30 kryteriów (pkt)
Krok 2: Projekt konsola w C#
ok. 3 min
Polecenie z arkusza
Program wykonywany w konsoli. Język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym, jeden z: C++, C#, Java, Python.
Wybieramy C#. W Visual Studio: Utwórz nowy projekt → Aplikacja konsolowa, nazwa konsola; w terminalu: dotnet new console -n konsola. W Program.cs zostawiamy klasę Program z pustą metodą Main.
konsola/Program.csC#nowy plik
classProgram{staticvoidMain() { }}
Krok 3: Funkcja FindPrimes: tablica jako argument, bez wartości zwracanej
Kryteria: , , , ,
R.2.1 Program składa się z programu głównego oraz funkcji lub metody. Zawartość funkcji jest zgodna z jej przeznaczeniem. Dopuszcza się niedokończoną funkcję, ale wskazującą na wypełnienie tablicy
R.2.2 Utworzono funkcję lub metodę z argumentem: zmienna typu tablicowego oraz funkcja nie zwraca wartości (np. typ void)
R.1.3 Zastosowano znaczące nazewnictwo funkcji
R.1.4 Zastosowano znaczące nazewnictwo zmiennych. Wyjątkami od reguły są zmienne bufor, tmp, iteratory pętli itp. Kryterium nie jest spełnione tylko wtedy, gdy nazwy zmiennych nic nie znaczą, np. x, a, tab, tablica, fun; dopuszcza się aby tablica była nazwana A - zgodnie z pseudokodem
R.1.5 Zastosowano typy zmiennych pasujące do problemu (np. typ tablicowy jednowymiarowy, typ całkowity dla iteratora pętli) w przypadku Python, tam gdzie jest to wymagane zastosowano jawną konwersję do odpowiednich typów
ok. 3 min
Polecenie z arkusza
Wypełnianie tablicy odbywa się w osobnej funkcji przyjmującej tablicę jako argument i nie zwracającej żadnej wartości.
Funkcja typu void (nie zwraca wartości) przyjmuje tablicę bool[] - jedna wartość logiczna na każdą liczbę (R.2.2, R.1.5). Tablica w C# jest przekazywana przez referencję: funkcja zmienia tę samą tablicę, którą utworzy Main, więc nie musi niczego zwracać.
Pierwszy wiersz pseudokodu: tablica „początkowo wypełniona wartościami true” od indeksu 2 (indeksy 0 i 1 pomijamy). Nazwa isPrime („czy liczba jest pierwsza”) mówi, co znaczy true w danej komórce (R.1.4).
konsola/Program.csC#zmienione: 8 linii
classProgram{staticvoidFindPrimes(bool[] isPrime) {for (int i = 2; i < isPrime.Length; i++) { isPrime[i] = true; } }staticvoidMain() { }}
Krok 4: Program główny: tablica do 100 i wypisanie
Kryteria:
R.1.7 Program po uruchomieniu wyświetla liczby oddzielone dowolnym separatorem oraz wyświetla znaczący komunikat. Jeżeli kod nie uruchamia się z powodu błędów kompilacji - sprawdzić w kodzie aplikacji
ok. 3 min
Polecenie z arkusza
Program szuka liczb w przedziale 2..100 (n = 100). Liczby pierwsze są wyświetlane na ekranie, rozdzielone dowolnym separatorem oraz poprzedzone znaczącym komunikatem.
Tablica ma n + 1 elementów - indeksy od 0 do 100, żeby liczba 100 miała swoją komórkę. Main wywołuje funkcję, a potem wypisuje komunikat i każdy indeks, w którym jest true, oddzielając liczby spacją (R.1.7).
Podgląd: funkcja na razie tylko wypełnia tablicę, więc wypisują się wszystkie liczby od 2 do 100. Wykreślanie dopiszemy w dwóch kolejnych krokach.
konsola/Program.csC#zmienione: 13 linii
classProgram{staticvoidFindPrimes(bool[] isPrime) {for (int i = 2; i < isPrime.Length; i++) { isPrime[i] = true; } }staticvoidMain() {int n = 100;bool[] isPrime = newbool[n + 1]; FindPrimes(isPrime); Console.Write("Liczby pierwsze z przedziału 2.." + n + ": ");for (int i = 2; i <= n; i++) {if (isPrime[i]) { Console.Write(i + " "); } } Console.WriteLine(); }}
R.2.3 Zastosowano algorytm sita Eratostenesa. Pętla zewnętrzna działa na indeksach od 2 do 10
R.1.2 Kod zapisano z wcięciami dla zagłębień bloków
ok. 3 min
Polecenie z arkusza
for i := 2, 3, 4, ..., nie więcej niż √n: if A[i] = true. Wykreślanie powtarzamy do momentu, gdy liczba i, której wielokrotność wykreślamy, będzie większa niż √n.
Pętla zewnętrzna przechodzi od 2 do pierwiastka z n. Zamiast liczyć pierwiastek (Math.Sqrt zwraca liczbę rzeczywistą) porównujemy i * i <= n - to ten sam warunek na liczbach całkowitych. Dla n = 100 pętla działa dla i od 2 do 10 (R.2.3). n w funkcji to ostatni indeks tablicy: isPrime.Length - 1.
Warunek if (isPrime[i]) to drugi wiersz pseudokodu - wielokrotności wykreślamy tylko dla liczb jeszcze niewykreślonych. Wnętrze uzupełnimy w następnym kroku.
konsola/Program.csC#zmienione: 7 linii
classProgram{staticvoidFindPrimes(bool[] isPrime) {for (int i = 2; i < isPrime.Length; i++) { isPrime[i] = true; }for (int i = 2; i * i <= isPrime.Length - 1; i++) {if (isPrime[i]) { } } }staticvoidMain() {int n = 100;bool[] isPrime = newbool[n + 1]; FindPrimes(isPrime); Console.Write("Liczby pierwsze z przedziału 2.." + n + ": ");for (int i = 2; i <= n; i++) {if (isPrime[i]) { Console.Write(i + " "); } } Console.WriteLine(); }}
R.2.4 Zapisano pętlę wewnętrzną, która przypisuje wartości false dla indeksów będących wielokrotnością zmiennej sterującej pętlą zewnętrzną
R.2.5 Program uruchamia się w konsoli, co udokumentowano zrzutem ekranu oraz wypisuje tylko liczby pierwsze: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
R.1.1 Kod źródłowy zapisano w sposób czytelny: instrukcje w osobnych liniach, stosowane spacje pomiędzy operatorami, konsekwentnie stosowana wybrana konwencja dla nawiasów klamrowych instrukcji blokowej
ok. 3 min
Polecenie z arkusza
for j := 2i, 3i, 4*i, ..., nie więcej niż n: A[j] := false. Wyjście: wartości i takie, że A[i] zawiera wartość true.
Pętla wewnętrzna zaczyna od 2 * i i skacze co i (j += i) - przechodzi dokładnie przez wielokrotności i większe od niego samego i każdą oznacza false (R.2.4).
Podgląd to prawdziwe uruchomienie: zostaje 25 liczb pierwszych od 2 do 97 - te same, które wymienia klucz (R.2.5).
konsola/Program.csC#zmienione: 4 linie
classProgram{staticvoidFindPrimes(bool[] isPrime) {for (int i = 2; i < isPrime.Length; i++) { isPrime[i] = true; }for (int i = 2; i * i <= isPrime.Length - 1; i++) {if (isPrime[i]) {for (int j = 2 * i; j <= isPrime.Length - 1; j += i) { isPrime[j] = false; } } } }staticvoidMain() {int n = 100;bool[] isPrime = newbool[n + 1]; FindPrimes(isPrime); Console.Write("Liczby pierwsze z przedziału 2.." + n + ": ");for (int i = 2; i <= n; i++) {if (isPrime[i]) { Console.Write(i + " "); } } Console.WriteLine(); }}
Krok 7: Folder konsola: archiwum, źródło i plik wykonywalny
ok. 2 min
Polecenie z arkusza
Kod aplikacji przygotuj do nagrania na płytę. W podfolderze konsola powinno znaleźć się archiwum całego projektu o nazwie konsola.zip, plik z kodem źródłowym programu oraz plik wykonywalny, jeżeli istnieje.
Folder projektu pakujemy do konsola.zip, obok kopiujemy Program.cs i konsola.exe z bin\Debug\net.... Archiwum robimy na końcu, po dopisaniu nagłówka funkcji z części III.
Kroki 8-21 · po tym etapie masz 21 z 30 kryteriów (pkt)
Krok 8: Nowy projekt WPF desktop i obrazy z archiwum
ok. 3 min
Polecenie z arkusza
Za pomocą środowiska programistycznego dostępnego na stanowisku egzaminacyjnym, wykonaj aplikację desktopową będącą fragmentem aplikacji do obsługi poczty. Wykorzystaj umieszczone na pulpicie materiały o nazwie materialy.zip zabezpieczone hasłem: %Twoj@Paczka&
W Visual Studio: Utwórz nowy projekt → Aplikacja WPF, nazwa desktop. Wygląd okna piszemy w MainWindow.xaml, logikę w MainWindow.xaml.cs. Archiwum materialy.zip rozpakowujemy hasłem z arkusza - są w nim trzy obrazy: pocztowka.png, list.png i paczka.png. Dołączymy je do projektu za chwilę.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 9: Tytuł okna i szerokość dopasowana do kontrolek
Kryteria:
R.3.1 Oknu aplikacji nadano nazwę "Nadaj Przesyłkę" wraz z numerem zdającego. Szerokość okna jest dopasowana do kontrolek wewnątrz
ok. 2 min
Polecenie z arkusza
Okno dialogowe o nazwie „Nadaj Przesyłkę” i szerokości dopasowanej do kontrolek wewnątrz. W nazwie okna należy wstawić także numerem zdającego.
Tytuł to „Nadaj Przesyłkę” i numer zdającego - na egzaminie numer PESEL, tu stoi Bartosz Bryniarski. Zamiast sztywnych Width i Height ustawiamy SizeToContent="WidthAndHeight" - WPF dopasuje rozmiar okna do zawartości, którą zaraz dodamy (R.3.1). Puste okno ma na razie minimalny rozmiar.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 10: Grupa Rodzaj przesyłki z polami radio
Kryteria: ,
R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, etykieta Cena: jest pogrubiona i napisana większą czcionką niż pozostałe napisy
R.3.6 Aplikacja uruchamia się, co udokumentowano zrzutem ekranu, układ kontrolek jest zgodny z Obrazem 1, stan początkowy to: zaznaczone pole Pocztówka, wyświetlony obraz pocztowka.png , pola radio są zgrupowane i jednocześnie można zaznaczyć tylko jedno z nich
ok. 3 min
Polecenie z arkusza
Grupa pól radio: Pocztówka, List, Paczka; pola są zgrupowane w dowolny dostępny element grupujący (np. GroupBox), w stanie początkowym zaznaczone jest pole Pocztówka. Pola radio działają w grupie, jednocześnie może być wybrane tylko jedno pole.
Okno dzielimy Grid-em na dwie kolumny (lewa na przesyłkę, prawa na adres) i dwa wiersze (na dole przycisk „Zatwierdź”). Kolumny mają stałe szerokości - od nich SizeToContent liczy szerokość okna.
W lewej kolumnie ramka GroupBox z podpisem i trzy RadioButton - w WPF przyciski opcji w jednym kontenerze tworzą jedną grupę, więc zaznaczenie jednego odznacza pozostałe. IsChecked="True" przy „Pocztówka” to stan początkowy (R.3.6). Klikaj opcje w podglądzie.
Typowe błędy
CheckBox zamiast RadioButton pozwala zaznaczyć kilka rodzajów naraz.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 11: Grupa Dane adresowe: trzy pola z etykietami
Kryteria:
R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, etykieta Cena: jest pogrubiona i napisana większą czcionką niż pozostałe napisy
ok. 3 min
Polecenie z arkusza
Trzy pola edycyjne poprzedzone etykietami o treści „Ulica z numerem”, „Kod pocztowy”, „Miasto”; zgrupowane w dowolny dostępny element grupujący.
Prawa kolumna (Grid.Column="1"): drugi GroupBox, a w nim pionowy StackPanel z parami etykieta - pole. Pole kodu jest węższe, jak na obrazie 1. Każde pole ma nazwę; z postalCodeTextBox skorzystamy przy zatwierdzaniu.
desktop/MainWindow.xamlXAMLzmienione: 10 linii
<Windowx:Class="desktop.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:desktop"mc:Ignorable="d"Title="Nadaj Przesyłkę, Bartosz Bryniarski"SizeToContent="WidthAndHeight"><GridMargin="40,10,40,10"><Grid.ColumnDefinitions><ColumnDefinitionWidth="230"/><ColumnDefinitionWidth="310"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinitionHeight="Auto"/><RowDefinitionHeight="Auto"/></Grid.RowDefinitions><StackPanel><GroupBoxHeader="Rodzaj przesyłki"Width="205"HorizontalAlignment="Left"><StackPanelMargin="10,5"><RadioButtonx:Name="postcardRadioButton"Content="Pocztówka"IsChecked="True"Margin="0,5"/><RadioButtonx:Name="letterRadioButton"Content="List"Margin="0,5"/><RadioButtonx:Name="parcelRadioButton"Content="Paczka"Margin="0,5"/></StackPanel></GroupBox></StackPanel><GroupBoxGrid.Column="1"Header="Dane adresowe"><StackPanelMargin="10,5"><LabelContent="Ulica z numerem"/><TextBoxx:Name="streetTextBox"Height="24"/><LabelContent="Kod pocztowy"Margin="0,8,0,0"/><TextBoxx:Name="postalCodeTextBox"Height="24"Width="115"HorizontalAlignment="Left"/><LabelContent="Miasto"Margin="0,8,0,0"/><TextBoxx:Name="cityTextBox"Height="24"Margin="0,0,0,10"/></StackPanel></GroupBox></Grid></Window>
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: Przycisk Sprawdź Cenę
Kryteria:
R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, etykieta Cena: jest pogrubiona i napisana większą czcionką niż pozostałe napisy
ok. 1 min
Polecenie z arkusza
Przycisk o treści „Sprawdź Cenę”.
Przycisk pod grupą przesyłek, tej samej szerokości co ramka. Obsługę kliknięcia dopiszemy po ułożeniu wszystkich kontrolek.
desktop/MainWindow.xamlXAMLzmienione: 1 linia
<Windowx:Class="desktop.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:desktop"mc:Ignorable="d"Title="Nadaj Przesyłkę, Bartosz Bryniarski"SizeToContent="WidthAndHeight"><GridMargin="40,10,40,10"><Grid.ColumnDefinitions><ColumnDefinitionWidth="230"/><ColumnDefinitionWidth="310"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinitionHeight="Auto"/><RowDefinitionHeight="Auto"/></Grid.RowDefinitions><StackPanel><GroupBoxHeader="Rodzaj przesyłki"Width="205"HorizontalAlignment="Left"><StackPanelMargin="10,5"><RadioButtonx:Name="postcardRadioButton"Content="Pocztówka"IsChecked="True"Margin="0,5"/><RadioButtonx:Name="letterRadioButton"Content="List"Margin="0,5"/><RadioButtonx:Name="parcelRadioButton"Content="Paczka"Margin="0,5"/></StackPanel></GroupBox><ButtonContent="Sprawdź Cenę"Width="205"HorizontalAlignment="Left"Margin="0,8,0,0"/></StackPanel><GroupBoxGrid.Column="1"Header="Dane adresowe"><StackPanelMargin="10,5"><LabelContent="Ulica z numerem"/><TextBoxx:Name="streetTextBox"Height="24"/><LabelContent="Kod pocztowy"Margin="0,8,0,0"/><TextBoxx:Name="postalCodeTextBox"Height="24"Width="115"HorizontalAlignment="Left"/><LabelContent="Miasto"Margin="0,8,0,0"/><TextBoxx:Name="cityTextBox"Height="24"Margin="0,0,0,10"/></StackPanel></GroupBox></Grid></Window>
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: Obraz pocztowka.png z zasobów aplikacji
Kryteria: ,
R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, etykieta Cena: jest pogrubiona i napisana większą czcionką niż pozostałe napisy
R.3.6 Aplikacja uruchamia się, co udokumentowano zrzutem ekranu, układ kontrolek jest zgodny z Obrazem 1, stan początkowy to: zaznaczone pole Pocztówka, wyświetlony obraz pocztowka.png , pola radio są zgrupowane i jednocześnie można zaznaczyć tylko jedno z nich
ok. 3 min
Polecenie z arkusza
Obraz w stanie początkowym wyświetlający obraz pocztowka.png. Pliki obrazów zapisane w zasobach aplikacji.
Trzy obrazy z archiwum kopiujemy do folderu projektu i oznaczamy jako zasoby (w Visual Studio: Właściwości pliku → Akcja kompilacji: Resource; w pliku projektu <Resource Include="*.png" />). Zasób zostaje wbudowany w plik .exe - aplikacja nie szuka obrazów na dysku i działa po skopiowaniu w inne miejsce.
Kontrolka Image z Source="pocztowka.png" pokazuje obraz pocztówki od razu po starcie (R.3.6). Obraz ma nazwę parcelImage - będziemy go podmieniać w kodzie.
Typowe błędy
Obraz dodany do projektu z akcją None nie trafia do aplikacji - okno pokazuje pustą kontrolkę.
desktop/MainWindow.xamlXAMLzmienione: 3 linie
<Windowx:Class="desktop.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:desktop"mc:Ignorable="d"Title="Nadaj Przesyłkę, Bartosz Bryniarski"SizeToContent="WidthAndHeight"><GridMargin="40,10,40,10"><Grid.ColumnDefinitions><ColumnDefinitionWidth="230"/><ColumnDefinitionWidth="310"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinitionHeight="Auto"/><RowDefinitionHeight="Auto"/></Grid.RowDefinitions><StackPanel><GroupBoxHeader="Rodzaj przesyłki"Width="205"HorizontalAlignment="Left"><StackPanelMargin="10,5"><RadioButtonx:Name="postcardRadioButton"Content="Pocztówka"IsChecked="True"Margin="0,5"/><RadioButtonx:Name="letterRadioButton"Content="List"Margin="0,5"/><RadioButtonx:Name="parcelRadioButton"Content="Paczka"Margin="0,5"/></StackPanel></GroupBox><ButtonContent="Sprawdź Cenę"Width="205"HorizontalAlignment="Left"Margin="0,8,0,0"/><StackPanelOrientation="Horizontal"Margin="0,10,0,0"><Imagex:Name="parcelImage"Source="pocztowka.png"Width="110"/></StackPanel></StackPanel><GroupBoxGrid.Column="1"Header="Dane adresowe"><StackPanelMargin="10,5"><LabelContent="Ulica z numerem"/><TextBoxx:Name="streetTextBox"Height="24"/><LabelContent="Kod pocztowy"Margin="0,8,0,0"/><TextBoxx:Name="postalCodeTextBox"Height="24"Width="115"HorizontalAlignment="Left"/><LabelContent="Miasto"Margin="0,8,0,0"/><TextBoxx:Name="cityTextBox"Height="24"Margin="0,0,0,10"/></StackPanel></GroupBox></Grid></Window>
desktop/desktop.csprojProjekt C#zmienione: 4 linie
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 14: Etykieta Cena pogrubiona i większa
Kryteria:
R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, etykieta Cena: jest pogrubiona i napisana większą czcionką niż pozostałe napisy
ok. 2 min
Polecenie z arkusza
Etykieta o treści „Cena: ”, o cechach: napis pogrubiony i czcionka widocznie większa względem pozostałych napisów.
Label obok obrazu: FontWeight="Bold" pogrubia, a FontSize="16" powiększa napis - domyślny rozmiar czcionki w WPF to 12 (R.3.2). Nazwa priceLabel pozwoli wpisać cenę z kodu.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 15: Przycisk Zatwierdź na całą szerokość
Kryteria: ,
R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, etykieta Cena: jest pogrubiona i napisana większą czcionką niż pozostałe napisy
R.3.6 Aplikacja uruchamia się, co udokumentowano zrzutem ekranu, układ kontrolek jest zgodny z Obrazem 1, stan początkowy to: zaznaczone pole Pocztówka, wyświetlony obraz pocztowka.png , pola radio są zgrupowane i jednocześnie można zaznaczyć tylko jedno z nich
ok. 2 min
Polecenie z arkusza
Przycisk o treści: „Zatwierdź”.
Drugi wiersz siatki; Grid.ColumnSpan="2" rozciąga przycisk na obie kolumny, jak na obrazie 1. Wszystkie kontrolki są na miejscu - porównaj podgląd z obrazem 1.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 16: Sprawdź Cenę: pocztówka
Kryteria: ,
R.3.3 Po wciśnięciu przynajmniej jednego przycisku wywołana jest funkcja lub metoda
R.3.4 W funkcji / metodzie obsługującej sprawdzanie ceny pobrano stan przycisków typu radio i zastosowano instrukcję podejmującą akcję w zależności od wyboru (wystarczy instrukcja pobrania oraz zapisany dowolny zgodny ze składnią warunek / wybór)
ok. 3 min
Polecenie z arkusza
Po wybraniu przycisku „Sprawdź cenę” aplikacja sprawdza, które pole radio jest zaznaczone i zależnie od wyboru wyświetla odpowiedni dla pola obraz oraz cenę, odpowiednio: pole radio Pocztówka: obraz pocztowka.png, „Cena: 1 zł”.
W XAML wiążemy kliknięcie z metodą CheckPriceButton_Click (R.3.3). W metodzie pytamy przycisk opcji, czy jest zaznaczony: IsChecked ma typ bool? (może być też null), dlatego porównujemy z true (R.3.4).
Obraz zmieniamy, przypisując do Source nowy BitmapImage z adresem pliku z zasobów - adres względny "pocztowka.png" (UriKind.Relative) wskazuje zasób w aplikacji. Cenę wpisujemy do Content etykiety. Kliknij „Sprawdź Cenę” przy zaznaczonej pocztówce.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 17: Sprawdź Cenę: list
Kryteria: ,
R.3.7 Po wybraniu przycisku do sprawdzania ceny, aplikacja wyświetla napisy: „Cena: 1 zł” dla pocztówki, „Cena: 1,5 zł” dla listu, „Cena: 10 zł” dla paczki
R.3.8 Po wybraniu przycisku do sprawdzania ceny, aplikacja wyświetla odpowiednio obrazy: pocztowka.png , list.png, paczka.png
ok. 2 min
Polecenie z arkusza
Pole radio List: obraz list.png, „Cena: 1,5 zł”.
Kolejna gałąź else if - sprawdzana tylko wtedy, gdy pocztówka nie jest zaznaczona. Cenę piszemy z przecinkiem, tak jak w arkuszu: to tekst etykiety, nie liczba. Zaznacz w podglądzie „List” i kliknij „Sprawdź Cenę” - obraz 1.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 18: Sprawdź Cenę: paczka
Kryteria: ,
R.3.7 Po wybraniu przycisku do sprawdzania ceny, aplikacja wyświetla napisy: „Cena: 1 zł” dla pocztówki, „Cena: 1,5 zł” dla listu, „Cena: 10 zł” dla paczki
R.3.8 Po wybraniu przycisku do sprawdzania ceny, aplikacja wyświetla odpowiednio obrazy: pocztowka.png , list.png, paczka.png
ok. 2 min
Polecenie z arkusza
Pole radio Paczka: obraz paczka.png, „Cena: 10 zł”.
Trzecia gałąź dla paczki. Teraz każdy wybór daje swój obraz i cenę (R.3.7, R.3.8). Sprawdź w podglądzie wszystkie trzy opcje.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 19: Zatwierdź: kod pocztowy musi mieć 5 znaków
Kryteria: , ,
R.3.3 Po wciśnięciu przynajmniej jednego przycisku wywołana jest funkcja lub metoda
R.3.5 W funkcji / metodzie obsługującej zatwierdzenie okna pobrano wartość z pola kodu pocztowego oraz zaimplementowano sprawdzenie czy w polu wpisano 5 znaków za pomocą odpowiedniej instrukcji
R.3.9 Po zatwierdzeniu okna dialogowego, gdy kod pocztowy składa się z pięciu cyfr wyświetlany jest komunikat „Dane przesyłki zostały wprowadzone”, gdy jest mniej lub więcej niż 5 znaków - „Nieprawidłowa liczba cyfr w kodzie pocztowym”
ok. 3 min
Polecenie z arkusza
Po wybraniu przycisku „Zatwierdź” jest walidowane pole kodu pocztowego oraz wyświetlany komunikat. Dla uproszczenia zadania należy przyjąć, że kod składa się tylko z 5 cyfr (bez znaku '-'). Komunikat dla poprawnego kodu pocztowego: „Dane przesyłki zostały wprowadzone”. Komunikat, gdy jest mniej lub więcej niż 5 znaków: „Nieprawidłowa liczba cyfr w kodzie pocztowym”.
Pobieramy tekst z pola kodu do zmiennej postalCode i sprawdzamy jego długość - Length to liczba znaków (R.3.5). Komunikat pokazuje MessageBox.Show. Wpisz w podglądzie 651 i kliknij „Zatwierdź”, potem 65124.
Na razie każdy napis z pięciu znaków uznajemy za poprawny - także „65a24”. Sprawdzenie cyfr dopisujemy w następnym kroku.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 20: Zatwierdź: kod pocztowy z samych cyfr
Kryteria: ,
R.3.9 Po zatwierdzeniu okna dialogowego, gdy kod pocztowy składa się z pięciu cyfr wyświetlany jest komunikat „Dane przesyłki zostały wprowadzone”, gdy jest mniej lub więcej niż 5 znaków - „Nieprawidłowa liczba cyfr w kodzie pocztowym”
R.3.10 Po zatwierdzeniu okna dialogowego, gdy przynajmniej jeden znak nie jest cyfrą „Kod pocztowy powinien się składać z samych cyfr”
ok. 3 min
Polecenie z arkusza
Komunikat, gdy przynajmniej jeden znak nie jest cyfrą: „Kod pocztowy powinien się składać z samych cyfr”.
Pętla foreach przechodzi przez każdy znak kodu; char.IsDigit odpowiada, czy znak jest cyfrą. Wystarczy jeden znak niebędący cyfrą, żeby flaga onlyDigits zmieniła się na false (R.3.10).
Sprawdzamy w kolejności z arkusza: najpierw długość, potem cyfry. Przetestuj w podglądzie 651, 65a24 i 65124 - trzy różne komunikaty (R.3.9, R.3.10).
desktop/MainWindow.xaml.csC#zmienione: 17 linii
using System.Windows;using System.Windows.Media.Imaging;namespace desktop;/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>publicpartialclassMainWindow : Window{publicMainWindow() { InitializeComponent(); }privatevoidCheckPriceButton_Click(object sender, RoutedEventArgs e) {if (postcardRadioButton.IsChecked == true) { parcelImage.Source = new BitmapImage(new Uri("pocztowka.png", UriKind.Relative)); priceLabel.Content = "Cena: 1 zł"; }elseif (letterRadioButton.IsChecked == true) { parcelImage.Source = new BitmapImage(new Uri("list.png", UriKind.Relative)); priceLabel.Content = "Cena: 1,5 zł"; }elseif (parcelRadioButton.IsChecked == true) { parcelImage.Source = new BitmapImage(new Uri("paczka.png", UriKind.Relative)); priceLabel.Content = "Cena: 10 zł"; } }privatevoidConfirmButton_Click(object sender, RoutedEventArgs e) {string postalCode = postalCodeTextBox.Text;if (postalCode.Length != 5) { MessageBox.Show("Nieprawidłowa liczba cyfr w kodzie pocztowym"); }else {bool onlyDigits = true;foreach (char sign in postalCode) {if (!char.IsDigit(sign)) { onlyDigits = false; } }if (onlyDigits) { MessageBox.Show("Dane przesyłki zostały wprowadzone"); }else { MessageBox.Show("Kod pocztowy powinien się składać z samych cyfr"); } } }}
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 21: Folder desktop: archiwum i pliki źródłowe
ok. 2 min
Polecenie z arkusza
Kod aplikacji przygotuj do nagrania na płytę. W podfolderze desktop powinno znaleźć się archiwum całego projektu o nazwie desktop.zip oraz plik (lub pliki) z kodem źródłowym modyfikowanym w czasie egzaminu.
Pakujemy folder projektu (z obrazami) do desktop.zip, obok kopiujemy MainWindow.xaml, MainWindow.xaml.cs i desktop.csproj - zmieniony o zasoby.
Kroki 22-25 · po tym etapie masz 30 z 30 kryteriów (pkt)
Krok 22: Nagłówek funkcji FindPrimes według listingu 1
Kryteria: , , , ,
R.4.1 Zapisano nagłówek dla funkcji z aplikacji konsolowej, utworzony w postaci komentarza zgodny z Listingiem 1 z arkusza egzaminacyjnego, umieszczony w komentarzu wieloliniowym lub kilku jednoliniowych
R.4.2 W komentarzu ujęto nazwę funkcji
R.4.3 W komentarzu ujęto nazwę i opis parametru wejściowego funkcji
R.4.4 W komentarzu zapisano opis wartości zwracanej oraz w informacjach zapisano np. "wyznaczenie liczb pierwszych, sito Eratostenesa" lub podobne zapisy
R.4.5 W komentarzu ujęto numer zdającego
ok. 4 min
Polecenie z arkusza
W kodzie źródłowym aplikacji konsolowej utwórz nagłówek funkcji wypełniającej tablicę, według wzoru. Nagłówek powinien znaleźć się w kodzie źródłowym nad funkcją. W miejscu nawiasów <> należy podać nazwę funkcji, nazwy parametrów (lub słowo „brak”) oraz zwięzłe informacje (co realizuje funkcja?) – zgodnie z listingiem 1. W miejscu autor należy podać numer zdającego.
Komentarz wieloliniowy /* ... */ nad funkcją, z polami listingu 1 w tej samej kolejności (R.4.1): nazwa funkcji (R.4.2), parametr isPrime z opisem, co przechowuje (R.4.3), wartość zwracana - „brak”, bo funkcja jest typu void - i informacje o sicie Eratostenesa (R.4.4), autor (R.4.5). Na egzaminie w polu autor wpisujemy numer PESEL - tu stoi Bartosz Bryniarski. Komentarz nie zmienia działania programu.
konsola/Program.csC#zmienione: 10 linii
classProgram{/* ******************************************************* nazwa funkcji: FindPrimes parametry wejściowe: isPrime - tablica logiczna; po wykonaniu funkcji isPrime[i] ma wartość true, gdy liczba i jest pierwsza (indeksy od 2 do n) wartość zwracana: brak - funkcja wypełnia przekazaną tablicę informacje: wyznacza liczby pierwsze z przedziału 2..n algorytmem sita Eratostenesa autor: Bartosz Bryniarski ***************************************************** */staticvoidFindPrimes(bool[] isPrime) {for (int i = 2; i < isPrime.Length; i++) { isPrime[i] = true; }for (int i = 2; i * i <= isPrime.Length - 1; i++) {if (isPrime[i]) {for (int j = 2 * i; j <= isPrime.Length - 1; j += i) { isPrime[j] = false; } } } }staticvoidMain() {int n = 100;bool[] isPrime = newbool[n + 1]; FindPrimes(isPrime); Console.Write("Liczby pierwsze z przedziału 2.." + n + ": ");for (int i = 2; i <= n; i++) {if (isPrime[i]) { Console.Write(i + " "); } } Console.WriteLine(); }}
R.1.6 Podjęto próbę uruchomienia kodu, co udokumentowano obrazem przedstawiającym wykonywany program lub próbę jego uruchomienia
R.4.6 Zapisano przynajmniej jeden zrzut ekranu z uruchomienia lub kompilacji aplikacji konsolowej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja
ok. 2 min
Polecenie z arkusza
Wykonaj zrzuty ekranu dokumentujące uruchomienie aplikacji utworzonych podczas egzaminu. Zrzuty powinny obejmować cały obszar ekranu z widocznym paskiem zadań. Dowolna liczba zrzutów ekranowych z aplikacji konsolowej nazwane konsola1, konsola2 itd.
Uruchamiamy program z Visual Studio i robimy zrzut całego ekranu z oknem konsoli i środowiskiem - konsola1.png w folderze dokumentacja (R.1.6, R.4.6). Program nie wczytuje danych, więc jeden zrzut pokazuje całe jego działanie.
R.4.7 Zapisano przynajmniej jeden zrzut ekranu z uruchomienia lub kompilacji aplikacji desktopowej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja lub okno z kompilowaną aplikacją
ok. 4 min
Polecenie z arkusza
Dowolna liczba zrzutów ekranowych z aplikacji desktopowej nazwane desktop1, desktop2 itd.
Zrzuty całego ekranu ze środowiskiem: desktop1 - stan początkowy, desktop2 - wybrany „List” i „Sprawdź Cenę” (obraz 1), desktop3 - „Paczka”, desktop4 i desktop5 - komunikaty o złej liczbie znaków i o znaku spoza cyfr, desktop6 - poprawny kod (R.4.7). Podgląd obok to aplikacja z poprzedniego etapu.
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Krok 25: Dokument egzamin
Kryteria:
R.4.8 W dokumentacji zapisano: nazwę systemu operacyjnego, nazwy użytych przez zdającego środowisk, nazwy języków programowania
ok. 4 min
Polecenie z arkusza
W edytorze tekstu pakietu biurowego utwórz plik z dokumentacją i nazwij go egzamin. Dokument powinien zawierać podpisane zrzuty ekranu, a następnie zapisane informacje: nazwę systemu operacyjnego, na którym pracował zdający, nazwy środowisk programistycznych, z których zdający korzystał na egzaminie, nazwy języków programowania użytych podczas tworzenia aplikacji, opcjonalnie komentarz do wykonanej pracy.
W Wordzie albo Writerze dokument egzamin w folderze dokumentacja: najpierw wklejone zrzuty, każdy z podpisem („desktop2 - wybrany list i sprawdzona cena”), potem trzy informacje o narzędziach (R.4.8). Plik obok to treść tekstowa dokumentu.
egzamin.txtTekstnowy plik
Zrzuty ekranu: konsola1 - wynik programu konsolowego; desktop1 - desktop6 - stany aplikacji desktopowejSystem operacyjny: Windows 11Środowisko programistyczne: Visual Studio 2022 (aplikacja konsolowa i desktopowa)Języki programowania: C# (aplikacja konsolowa), C# i XAML - WPF (aplikacja desktopowa)
Kroki 26-27 · po tym etapie masz 30 z 30 kryteriów (pkt)
Krok 26: Konsola: stała n i lista bez separatora na końcu
ok. 3 min
Polecenie z arkusza
Liczby pierwsze są wyświetlane na ekranie, rozdzielone dowolnym separatorem oraz poprzedzone znaczącym komunikatem.
Dwie drobne poprawki:
const int n = 100 - granica przedziału nie zmienia się w trakcie programu, więc oznaczamy ją jako stałą; kompilator nie pozwoli jej przypadkiem nadpisać,
liczby zbieramy do listy List<int> i łączymy string.Join(", ", primes) - przecinek stoi tylko między liczbami, bez separatora po ostatniej, a komunikat i wynik wypisujemy jednym napisem interpolowanym $"...".
Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
konsola/Program.csC#zmienione: 6 linii
classProgram{/* ******************************************************* nazwa funkcji: FindPrimes parametry wejściowe: isPrime - tablica logiczna; po wykonaniu funkcji isPrime[i] ma wartość true, gdy liczba i jest pierwsza (indeksy od 2 do n) wartość zwracana: brak - funkcja wypełnia przekazaną tablicę informacje: wyznacza liczby pierwsze z przedziału 2..n algorytmem sita Eratostenesa autor: Bartosz Bryniarski ***************************************************** */staticvoidFindPrimes(bool[] isPrime) {for (int i = 2; i < isPrime.Length; i++) { isPrime[i] = true; }for (int i = 2; i * i <= isPrime.Length - 1; i++) {if (isPrime[i]) {for (int j = 2 * i; j <= isPrime.Length - 1; j += i) { isPrime[j] = false; } } } }staticvoidMain() {constint n = 100;bool[] isPrime = newbool[n + 1]; FindPrimes(isPrime); List<int> primes = new List<int>();for (int i = 2; i <= n; i++) {if (isPrime[i]) { primes.Add(i); } } Console.WriteLine($"Liczby pierwsze z przedziału 2..{n}: {string.Join(", ", primes)}");// Console.Write("Liczby pierwsze z przedziału 2.." + n + ": ");// for (...) Console.Write(i + " "); }}
Krok 27: Okno: jedna metoda do obrazu i ceny, cyfry 0-9
ok. 4 min
Polecenie z arkusza
Aplikacja powinna być zapisana czytelnie, z zachowaniem zasad czystego formatowania kodu, należy stosować znaczące nazwy zmiennych i funkcji
Trzy poprawki, które skracają kod i zamykają drobne luki:
trzy gałęzie powtarzały te same dwie linie - wyciągamy je do metody ShowParcel(obraz, cena), a gałęzie tylko ją wywołują; zmiana sposobu wyświetlania ceny to teraz jedno miejsce,
Trim() usuwa przypadkową spację przed albo po kodzie - „65124 ” nie jest już „złą liczbą cyfr”,
char.IsAsciiDigit przepuszcza wyłącznie cyfry 0-9; char.IsDigit uznaje za cyfry także np. cyfry arabskie. postalCode.All(char.IsAsciiDigit) (metoda LINQ) sprawdza warunek dla każdego znaku i zastępuje pętlę z flagą.
Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.
desktop/MainWindow.xaml.csC#zmienione: 11 linii
using System.Windows;using System.Windows.Media.Imaging;namespace desktop;/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>publicpartialclassMainWindow : Window{publicMainWindow() { InitializeComponent(); }privatevoidCheckPriceButton_Click(object sender, RoutedEventArgs e) {if (postcardRadioButton.IsChecked == true) { ShowParcel("pocztowka.png", "1 zł"); }elseif (letterRadioButton.IsChecked == true) { ShowParcel("list.png", "1,5 zł"); }elseif (parcelRadioButton.IsChecked == true) { ShowParcel("paczka.png", "10 zł"); } }privatevoidShowParcel(string imageName, string price) { parcelImage.Source = new BitmapImage(new Uri(imageName, UriKind.Relative)); priceLabel.Content = "Cena: " + price; }privatevoidConfirmButton_Click(object sender, RoutedEventArgs e) {string postalCode = postalCodeTextBox.Text.Trim();if (postalCode.Length != 5) { MessageBox.Show("Nieprawidłowa liczba cyfr w kodzie pocztowym"); }else {if (postalCode.All(char.IsAsciiDigit)) { MessageBox.Show("Dane przesyłki zostały wprowadzone"); }else { MessageBox.Show("Kod pocztowy powinien się składać z samych cyfr"); } } }}
Okno aplikacji po tym kroku
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
Etap 6: Oddanie pracy
Krok 28 · po tym etapie masz 30 z 30 kryteriów (pkt)
Krok 28: Nagranie płyty
ok. 5 min
Polecenie z arkusza
Nagraj płytę z rezultatami pracy. W folderze z numerem zdającego powinny się znajdować podfoldery: konsola, desktop, dokumentacja. Po nagraniu płyty sprawdź poprawność nagrania.
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). Treść arkusza i klucza oceniania pochodzi z CKE.