Przejdź do głównej treści
INF.04-01-23.01-SGStyczeń 2023 · 30 kroków · ok. 83 min · 32 kryteria z klucza

Rozwiązanie krok po kroku: NWD i generator hasła (C# + WPF)

Rozwiązujemy arkusz z algorytmem Euklidesa i oknem „Dodaj pracownika” w wersji C# + WPF: w konsoli funkcja wyznaczająca największy wspólny dzielnik dokładnie według schematu blokowego z arkusza (odejmowanie, nie reszta z dzielenia), a w aplikacji desktopowej okno z dwiema grupami kontrolek, które generuje hasło o podanej długości (z wielką literą, cyfrą i znakiem specjalnym zależnie od pól wyboru) i pokazuje zebrane dane pracownika w oknie komunikatu. Do tego dokumentacja funkcji według wzoru z arkusza, 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” przerabiamy ją na kod z prawdziwych projektów.

Co widać w podglądzie. Wyniki programu konsolowego pochodzą z prawdziwego uruchomienia kodu z danego kroku (.NET 10) z liczbami wpisanymi z klawiatury. Okno aplikacji to symulacja WPF w przeglądarce zbudowana z XAML danego kroku, a jej zachowanie odpowiada kodowi C# z kroku - przycisk zaczyna działać dopiero w kroku, który dopisuje jego obsługę. Każdy stan okna sprawdziliśmy na prawdziwym WPF (generowane hasła i treść okien komunikatów).

Arkusz pozwala też na C++, Javę albo Pythona w konsoli i na inne biblioteki okienkowe - ten wariant to jedna z możliwych dróg.

Jak liczą się punkty. Klucz ma 32 kryteria (R.1.1 - R.4.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 24 punkty - można stracić 8 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Przygotowanie

    Krok 1 · po tym etapie masz 0 z 32 kryteriów (pkt)

    Krok 1: Folder zdającego i trzy podfoldery

    ok. 2 min
    Polecenie z arkusza

    Utwórz folder i nazwij go numerem zdającego. W folderze utwórz podfoldery: konsola, desktopowa, dokumentacja.

    Na pulpicie zakładamy folder o nazwie z numerem PESEL, a w nim konsola, desktopowa i dokumentacja (w tym arkuszu folder nazywa się konsola, nie konsolowa). Arkusz nie ma archiwum z materiałami - wszystko piszemy od zera. Projekty możemy trzymać w domyślnych folderach Visual Studio, a na koniec spakować je i skopiować do podfolderów.

  2. Etap 2: Aplikacja konsolowa

    Kroki 2-7 · po tym etapie masz 12 z 32 kryteriów (pkt)

    Krok 2: Projekt konsola w C#

    ok. 3 min
    Polecenie z arkusza

    Obiektowy język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym: C++ lub C#, lub Java, lub Python.

    Wybieramy C#. W Visual Studio: Utwórz nowy projekt → Aplikacja konsolowa, nazwa konsola (stąd archiwum konsola.zip); w terminalu to samo daje dotnet new console -n konsola. W Program.cs zastępujemy przykładowy kod klasą Program z metodą Main, od której zaczyna się program.

    konsola/Program.cs C# nowy plik
    class Program
    {
        static void Main()
        {
        }
    }
  3. Krok 3: Funkcja Nwd z dwoma argumentami bez znaku

    Kryteria: ,

    R.2.1 W programie zdefiniowano funkcję, która pobiera jako argumenty dwie liczby, typem funkcji jest liczba całkowita bez znaku (dopuszcza się w języku Java ze znakiem, w Python bez typu) oraz zastosowano instrukcję return

    R.1.5 Zastosowano typy pól pasujące do problemu, typ zmiennych a i b jest naturalny - w zależności od języka programowania kwalifikator unsigned lub typ bez znaku np. uint (jeżeli nie zastosowano typu bez znaku, sprawdzono warunkiem czy obie zmienne są dodatnie) w przypadku Python zastosowano jawną konwersję do odpowiednich typów

    ok. 2 min
    Polecenie z arkusza

    Szukanie NWD zaimplementowane w funkcji o dwóch argumentach i zwracanej wartości największego wspólnego dzielnika. Funkcja nie może zawierać operacji wejścia - wyjścia. Liczby a i b należą do zbioru liczb całkowitych dodatnich (odpowiedni typ lub kontrola poprawności wpisanej liczby).

    Szkielet funkcji: dwa parametry o nazwach a i b - dokładnie jak na schemacie (klucz tego wymaga, R.1.4) - i zwracana wartość. Typ uint to liczba całkowita bez znaku: nie przyjmie liczby ujemnej, więc spełnia warunek „liczby całkowite dodatnie” typem, bez dodatkowego sprawdzania (R.1.5). Ten sam typ ma wynik.

    static - funkcję wywołamy z Main bez tworzenia obiektu. Funkcja tylko liczy: żadnego Console w środku, jak każe arkusz.

    konsola/Program.cs C# zmienione: 5 linii
    class Program
    {
        static uint Nwd(uint a, uint b)
        {
            return a;
        }
    
        static void Main()
        {
        }
    }
  4. Krok 4: Pętla: dopóki a ≠ b

    Kryteria:

    R.2.2 Funkcja stosuje pętlę while lub do while, która jest wykonywana tak długo jak a i b są różne

    ok. 2 min
    Polecenie z arkusza

    Implementacja algorytmu w pełni zgodna z przedstawionym na schemacie algorytmem.

    Pierwszy romb schematu („czy a ≠ b”) z powrotem strzałki nad siebie to pętla while: warunek sprawdzany przed każdym obrotem. != to w C# „różne”. Gałąź „Nie” schematu prowadzi do „Wyświetl a” - u nas to wyjście z pętli i return a. Pętla jest jeszcze pusta - na razie nie wywołujemy funkcji, bo dla różnych liczb kręciłaby się bez końca.

    konsola/Program.cs C# zmienione: 3 linie
    class Program
    {
        static uint Nwd(uint a, uint b)
        {
            while (a != b)
            {
            }
            return a;
        }
    
        static void Main()
        {
        }
    }
  5. Krok 5: Odejmowanie mniejszej liczby od większej

    Kryteria: , ,

    R.2.3 W pętli znajduje się porównanie a i b, jeżeli a > b jest wykonywane a = a - b w przeciwnym wypadku b = b - a (warunki mogą być odwrócone)

    R.2.4 Funkcja zwraca wartość równą a (możliwe też za pomocą innej zmiennej równej a)

    R.1.2 Kod zapisano z wcięciami dla zagłębień bloków

    ok. 3 min
    Polecenie z arkusza

    Implementacja algorytmu w pełni zgodna z przedstawionym na schemacie algorytmem: czy a > b - Tak: a := a-b, Nie: b := b-a.

    Drugi romb to if ... else: gdy a jest większe, odejmujemy od niego b, w przeciwnym razie odejmujemy a od b. Każde odjęcie zmniejsza jedną z liczb, więc w końcu zrównają się - i ta wspólna wartość to NWD (np. 48 i 18: 30, 18 → 12, 18 → 12, 6 → 6, 6). To wersja Euklidesa z odejmowaniem, dokładnie ze schematu - nie zamieniamy jej na resztę z dzielenia %, bo klucz sprawdza zgodność ze schematem (R.2.3).

    Typowe błędy

    Algorytm z resztą z dzielenia (a % b) jest szybszy, ale to INNY algorytm niż na schemacie - R.2.2 i R.2.3 wymagają pętli z porównaniem a i b i odejmowaniem.

    konsola/Program.cs C# zmienione: 8 linii
    class Program
    {
        static uint Nwd(uint a, uint b)
        {
            while (a != b)
            {
                if (a > b)
                {
                    a = a - b;
                }
                else
                {
                    b = b - a;
                }
            }
            return a;
        }
    
        static void Main()
        {
        }
    }
  6. Krok 6: Program główny: wczytanie i wynik

    Kryteria: , , , , ,

    R.2.5 W programie głównym następuje wczytanie dwóch liczb z klawiatury

    R.2.6 W konsoli wyświetlona jest obliczona wartość

    R.1.6 Program podejmuje komunikację z użytkownikiem, np. monit o wprowadzenie danych jest znaczący albo wyświetlenie danych opatrzone znaczącym komunikatem

    R.1.3 Użyto znaczące nazewnictwo funkcji

    R.1.4 Użyto nazewnictwo dwóch zmiennych algorytmu: a i b. Dla Pozostałych zmiennych (jeśli istnieją) nazewnictwo jest znaczące. 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, tab, tablica

    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

    Program główny testuje działanie funkcji i zawiera operacje wejścia - wyjścia. Program powinien być zapisany czytelnie, należy stosować nazwy zmiennych zgodne z nazwami zastosowanymi na schemacie blokowym.

    Console.ReadLine() czyta wiersz z klawiatury, a uint.Parse zamienia go na liczbę bez znaku - wpisanie liczby ujemnej zakończy się błędem, więc do funkcji nie trafi nic spoza zbioru liczb dodatnich (poza zerem - wrócimy do tego w dobrych praktykach). Zmienne w Main też nazywamy a i b, jak na schemacie. Wynik wypisujemy z komunikatem.

    Podgląd to prawdziwe uruchomienie: 48 i 18 dają 6. Drugie uruchomienie z liczbami 17 i 5 (względnie pierwszymi) - wynik 1.

    konsola/Program.cs C# zmienione: 5 linii
    class Program
    {
        static uint Nwd(uint a, uint b)
        {
            while (a != b)
            {
                if (a > b)
                {
                    a = a - b;
                }
                else
                {
                    b = b - a;
                }
            }
            return a;
        }
    
        static void Main()
        {
            Console.Write("Podaj liczbę a: ");
            uint a = uint.Parse(Console.ReadLine());
            Console.Write("Podaj liczbę b: ");
            uint b = uint.Parse(Console.ReadLine());
            Console.WriteLine($"NWD({a}, {b}) = {Nwd(a, b)}");
        }
    }
    Wynik programu po tym kroku
    > konsola.exe
    Podaj liczbę a: 48
    Podaj liczbę b: 18
    NWD(48, 18) = 6
    
    > konsola.exe
    Podaj liczbę a: 17
    Podaj liczbę b: 5
    NWD(17, 5) = 1
  7. 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 folderze konsola powinno znaleźć się archiwum całego projektu o nazwie konsola.zip, plik z kodem źródłowym programu oraz plik uruchomieniowy, 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 pracy, po dopisaniu komentarza dokumentującego z części III.

    Wynik programu bez zmian - taki jak po kroku 6.

  8. Etap 3: Aplikacja desktopowa

    Kroki 8-23 · po tym etapie masz 22 z 32 kryteriów (pkt)

    Krok 8: Nowy projekt WPF desktopowa

    ok. 3 min
    Polecenie z arkusza

    Za pomocą dostępnego na stanowisku egzaminacyjnym środowiska programistycznego wykonaj aplikację desktopową do wprowadzania danych pracownika z możliwością generowania hasła.

    W Visual Studio: Utwórz nowy projekt → Aplikacja WPF (nie Aplikacja WPF (.NET Framework)), nazwa desktopowa. Zmieniamy dwa pliki: MainWindow.xaml - wygląd okna w XAML (znaczniki podobne do HTML) - i MainWindow.xaml.cs - logika w C#. Szablon dopisuje w .cs kilkanaście dyrektyw using; zostawiamy tylko System.Windows, której naprawdę używamy (pozostałe nie szkodzą).

    Podgląd pokazuje puste okno szablonu: tytuł „MainWindow”, rozmiar 800 × 450.

    desktopowa/MainWindow.xaml XAML nowy plik
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
    
        </Grid>
    </Window>
    desktopowa/MainWindow.xaml.cs C# nowy plik
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  9. Krok 9: Tytuł, rozmiar i tło okna

    Kryteria: ,

    R.3.1 Nadano dla okna aplikacji nazwę "Dodaj pracownika" wraz z numerem zdającego oraz umieszczono w nim dwie grupy „Dane Pracownika” oraz „Generowanie hasła”

    R.3.3 Nadano dla okna tło koloru LightSteelBlue (#B0C4DE) oraz dla przycisków tło koloru SteelBlue (#4682B4) i biały kolor czcionki

    ok. 2 min
    Polecenie z arkusza

    Okno o nazwie „Dodaj pracownika”. W nazwie okna należy wstawić także numer zdającego. Okno ma tło koloru LightSteelBlue (#B0C4DE).

    • Title - napis na pasku okna; na egzaminie po „Dodaj pracownika” wpisujemy numer PESEL, tu stoi autor rozwiązania, Bartosz Bryniarski,
    • Height i Width - rozmiar jak na obrazie 1 (ok. 650 × 300),
    • Background="#B0C4DE" - kod podany w arkuszu; Background="LightSteelBlue" działa tak samo, bo XAML zna nazwy kolorów.
    desktopowa/MainWindow.xaml XAML zmienione: 2 linie
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
    
        </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ć.

  10. Krok 10: Układ: dwie grupy obok siebie

    Kryteria:

    R.3.1 Nadano dla okna aplikacji nazwę "Dodaj pracownika" wraz z numerem zdającego oraz umieszczono w nim dwie grupy „Dane Pracownika” oraz „Generowanie hasła”

    ok. 3 min
    Polecenie z arkusza

    Kontrolki rozmieszczone zgodnie z obrazem 1. Kontrolki w grupie „Dane Pracownika”. Kontrolki w grupie „Generowanie hasła”.

    Grid dzielimy na dwie równe kolumny (ColumnDefinition bez szerokości = po połowie) i dwa wiersze: górny zajmuje resztę miejsca, dolny (Height="Auto") dopasuje się do przycisku „Zatwierdź”. W górnym wierszu stoją dwie GroupBox - ramki z podpisem w Header. Druga dostaje Grid.Column="1" (kolumny liczymy od 0). Margin w kolejności lewo, góra, prawo, dół odsuwa ramki od krawędzi.

    desktopowa/MainWindow.xaml XAML zmienione: 12 linii
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
            </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ć.

  11. Krok 11: Etykieta Imię i pole edycyjne

    Kryteria:

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    ok. 3 min
    Polecenie z arkusza

    Kontrolki w grupie „Dane Pracownika”: pole edycyjne poprzedzone etykietą o treści „Imię”.

    W ramce własny Grid: kolumna 100 px na etykiety i druga na pola, trzy wiersze Auto (każdy tak wysoki jak jego zawartość). Label to etykieta, TextBox - pole edycyjne. Polu nadajemy nazwę x:Name="firstNameTextBox" - po niej odczytamy wpisany tekst w C#.

    desktopowa/MainWindow.xaml XAML zmienione: 13 linii
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
            </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ć.

  12. Krok 12: Etykieta Nazwisko i pole edycyjne

    Kryteria:

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne poprzedzone etykietą o treści „Nazwisko”.

    To samo w drugim wierszu (Grid.Row="1"), z nazwą lastNameTextBox.

    desktopowa/MainWindow.xaml XAML zmienione: 2 linie
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
            </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ć.

  13. Krok 13: Lista rozwijana Stanowisko

    Kryteria: ,

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    R.3.4 Zdefiniowano cztery elementy dla listy rozwijalnej: Kierownik, Starszy programista, Młodszy programista, Tester

    ok. 2 min
    Polecenie z arkusza

    Lista rozwijalna podpisana „Stanowisko” z elementami: Kierownik, Starszy programista, Młodszy programista, Tester.

    Lista rozwijana to ComboBox, a jej pozycje - znaczniki ComboBoxItem z tekstem w Content. Na obrazie 1 nic nie jest wybrane, więc nie ustawiamy SelectedIndex. Rozwiń listę w podglądzie.

    desktopowa/MainWindow.xaml XAML zmienione: 7 linii
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
            </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ć.

  14. Krok 14: Etykieta Ile znaków? i pole edycyjne

    Kryteria:

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    ok. 2 min
    Polecenie z arkusza

    Kontrolki w grupie „Generowanie hasła”: pole edycyjne poprzedzone etykietą o treści „Ile znaków?”.

    W tej grupie kontrolki stoją jedna pod drugą, więc wystarczy StackPanel (pionowy). Pierwszy wiersz to poziomy StackPanel (Orientation="Horizontal") z etykietą i polem lengthTextBox obok siebie.

    desktopowa/MainWindow.xaml XAML zmienione: 6 linii
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
                <StackPanel Margin="10">
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,5">
                        <Label Content="Ile znaków?" Width="100" />
                        <TextBox x:Name="lengthTextBox" Width="120" Height="22" />
                    </StackPanel>
                </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ć.

  15. Krok 15: Trzy pola wyboru, pierwsze zaznaczone

    Kryteria: ,

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    R.3.10 Aplikacja kompiluje się i uruchamia, co udokumentowano zrzutem ekranu, jej układ po uruchomieniu jest zgodny z obrazem 1 w arkuszu egzaminacyjnym. Zaznaczone jest pierwsze pole wyboru

    ok. 2 min
    Polecenie z arkusza

    Trzy pola wyboru podpisane: „Małe i wielkie litery”, „Cyfry”, „Znaki specjalne”. Pierwsze pole jest domyślnie zaznaczone.

    Pole wyboru to CheckBox z podpisem w Content. IsChecked="True" zaznacza pierwsze pole od startu (R.3.10). Każde pole ma nazwę - sprawdzimy je w kodzie.

    desktopowa/MainWindow.xaml XAML zmienione: 3 linie
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
                <StackPanel Margin="10">
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,5">
                        <Label Content="Ile znaków?" Width="100" />
                        <TextBox x:Name="lengthTextBox" Width="120" Height="22" />
                    </StackPanel>
                    <CheckBox x:Name="lettersCheckBox" Content="Małe i wielkie litery" IsChecked="True" Margin="5" />
                    <CheckBox x:Name="digitsCheckBox" Content="Cyfry" Margin="5" />
                    <CheckBox x:Name="specialCheckBox" Content="Znaki specjalne" Margin="5" />
                </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ć.

  16. Krok 16: Przycisk Generuj hasło

    Kryteria: ,

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    R.3.3 Nadano dla okna tło koloru LightSteelBlue (#B0C4DE) oraz dla przycisków tło koloru SteelBlue (#4682B4) i biały kolor czcionki

    ok. 2 min
    Polecenie z arkusza

    Przycisk o treści „Generuj hasło”. Przyciski mają tło koloru SteelBlue (#4682B4) i biały kolor czcionki.

    Button z napisem w Content. Width="90" - szerokość jak na obrazie 1 (w pionowym StackPanel przycisk o stałej szerokości stoi na środku). Kolory: Background (tło) i Foreground (tekst). Obsługi kliknięcia jeszcze nie ma.

    desktopowa/MainWindow.xaml XAML zmienione: 1 linia
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
                <StackPanel Margin="10">
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,5">
                        <Label Content="Ile znaków?" Width="100" />
                        <TextBox x:Name="lengthTextBox" Width="120" Height="22" />
                    </StackPanel>
                    <CheckBox x:Name="lettersCheckBox" Content="Małe i wielkie litery" IsChecked="True" Margin="5" />
                    <CheckBox x:Name="digitsCheckBox" Content="Cyfry" Margin="5" />
                    <CheckBox x:Name="specialCheckBox" Content="Znaki specjalne" Margin="5" />
                    <Button Content="Generuj hasło" Width="90" Margin="5" Background="#4682B4" Foreground="White" />
                </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ć.

  17. Krok 17: Przycisk Zatwierdź pod grupami

    Kryteria: ,

    R.3.2 Okno zawiera wszystkie kontrolki widoczne na Obrazie 1 arkusza egzaminacyjnego, przycisk zatwierdzenia jest dłuższy niż przycisk do generowania hasła

    R.3.3 Nadano dla okna tło koloru LightSteelBlue (#B0C4DE) oraz dla przycisków tło koloru SteelBlue (#4682B4) i biały kolor czcionki

    ok. 2 min
    Polecenie z arkusza

    Na dole okna znajduje się przycisk „Zatwierdź”, jest on wyraźnie dłuższy niż przycisk do generowania hasła.

    Przycisk w dolnym wierszu (Grid.Row="1"), rozciągnięty na obie kolumny (Grid.ColumnSpan="2") - dzięki temu stoi na środku okna. Szerokość 200 to ponad dwa razy więcej niż „Generuj hasło” (R.3.2). Wygląd okna jest kompletny - porównaj z obrazem 1.

    desktopowa/MainWindow.xaml XAML zmienione: 2 linie
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
                <StackPanel Margin="10">
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,5">
                        <Label Content="Ile znaków?" Width="100" />
                        <TextBox x:Name="lengthTextBox" Width="120" Height="22" />
                    </StackPanel>
                    <CheckBox x:Name="lettersCheckBox" Content="Małe i wielkie litery" IsChecked="True" Margin="5" />
                    <CheckBox x:Name="digitsCheckBox" Content="Cyfry" Margin="5" />
                    <CheckBox x:Name="specialCheckBox" Content="Znaki specjalne" Margin="5" />
                    <Button Content="Generuj hasło" Width="90" Margin="5" Background="#4682B4" Foreground="White" />
                </StackPanel>
            </GroupBox>
            <Button Grid.Row="1" Grid.ColumnSpan="2" Content="Zatwierdź" Width="200" Margin="0,0,0,15"
                    Background="#4682B4" Foreground="White" />
        </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ć.

  18. Krok 18: Pole password i metoda obsługi przycisku

    Kryteria: ,

    R.3.5 Po wciśnięciu przynajmniej jednego przycisku wywoływana jest funkcja

    R.3.8 Hasło oraz zestawy znaków są przechowywane w zmiennych typu napisowego, hasło jest widoczne dla obu metod obsługujących kliknięcia przycisków

    ok. 3 min
    Polecenie z arkusza

    Hasło oraz zestawy znaków są przechowywane w zmiennych typu napisowego.

    • private string password - pole klasy okna, a nie zmienna w metodzie: hasło wygenerowane po kliknięciu „Generuj hasło” musi być dostępne też w metodzie przycisku „Zatwierdź” (R.3.8),
    • Random random - jeden generator liczb losowych dla całego okna,
    • Click="GenerateButton_Click" w XAML wiąże przycisk z metodą o tej nazwie (R.3.5). Visual Studio tworzy ją samo, gdy klikniemy dwukrotnie przycisk w projektancie.

    Metoda jest jeszcze pusta - kliknięcie niczego nie robi.

    desktopowa/MainWindow.xaml XAML zmienione: 2 linie
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
                <StackPanel Margin="10">
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,5">
                        <Label Content="Ile znaków?" Width="100" />
                        <TextBox x:Name="lengthTextBox" Width="120" Height="22" />
                    </StackPanel>
                    <CheckBox x:Name="lettersCheckBox" Content="Małe i wielkie litery" IsChecked="True" Margin="5" />
                    <CheckBox x:Name="digitsCheckBox" Content="Cyfry" Margin="5" />
                    <CheckBox x:Name="specialCheckBox" Content="Znaki specjalne" Margin="5" />
                    <Button Content="Generuj hasło" Width="90" Margin="5" Background="#4682B4" Foreground="White"
                            Click="GenerateButton_Click" />
                </StackPanel>
            </GroupBox>
            <Button Grid.Row="1" Grid.ColumnSpan="2" Content="Zatwierdź" Width="200" Margin="0,0,0,15"
                    Background="#4682B4" Foreground="White" />
        </Grid>
    </Window>
    desktopowa/MainWindow.xaml.cs C# zmienione: 7 linii
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private string password = "";
        private Random random = new Random();
    
        private void GenerateButton_Click(object sender, RoutedEventArgs e)
        {
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  19. Krok 19: Hasło z małych liter i okno komunikatu

    Kryteria: ,

    R.3.6 Po wybraniu przycisku "Generuj hasło" wyświetla się komunikat z wygenerowanym hasłem, liczba znaków hasła jest zgodna z liczbą podaną w polu edycyjnym. Generowanie hasła należy sprawdzić dwa razy (hasła muszą być różne)

    R.3.7 Znaki do hasła są wybierane przy wykorzystaniu generatora liczb pseudolosowych z zestawu znaków, który zawsze obejmuje małe litery a..z oraz gdy wybrano pierwszy checkbox wielkie litery A..Z i gdy wybrano drugi checkbox cyfry: 0..9 oraz gdy wybrano trzeci checkbox znaki specjalne ze zbioru !@#$%^&*()_+-=

    ok. 3 min
    Polecenie z arkusza

    Generowane jest hasło o liczbie znaków określonej w polu edycyjnym. Poszczególne znaki hasła są wybierane losowo z zestawu małych liter. Hasło jest wypisywane jako komunikat zgodnie z obrazem 2 po wybraniu przycisku „Generuj hasło”.

    • int.Parse(lengthTextBox.Text) - liczba znaków z pola edycyjnego,
    • password = "" - każde kliknięcie zaczyna nowe hasło,
    • random.Next(lowercase.Length) losuje indeks od 0 do 25, a lowercase[...] bierze znak spod niego; += dokleja go do hasła,
    • MessageBox.Show(password) wyświetla okno komunikatu z hasłem, jak na obrazie 2.

    Wpisz w podglądzie 5 i kliknij „Generuj hasło” dwa razy - dwa różne hasła z pięciu małych liter.

    Typowe błędy

    new Random() tworzone w pętli przy każdym znaku potrafi (w starszym .NET Framework) dawać ten sam znak kilka razy z rzędu - generator jest jeden, w polu klasy.

    desktopowa/MainWindow.xaml.cs C# zmienione: 8 linii
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private string password = "";
        private Random random = new Random();
    
        private void GenerateButton_Click(object sender, RoutedEventArgs e)
        {
            string lowercase = "abcdefghijklmnopqrstuvwxyz";
            int length = int.Parse(lengthTextBox.Text);
            password = "";
            for (int i = 0; i < length; i++)
            {
                password += lowercase[random.Next(lowercase.Length)];
            }
            MessageBox.Show(password);
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  20. Krok 20: Wielka litera, gdy zaznaczono pierwsze pole

    Kryteria:

    R.3.7 Znaki do hasła są wybierane przy wykorzystaniu generatora liczb pseudolosowych z zestawu znaków, który zawsze obejmuje małe litery a..z oraz gdy wybrano pierwszy checkbox wielkie litery A..Z i gdy wybrano drugi checkbox cyfry: 0..9 oraz gdy wybrano trzeci checkbox znaki specjalne ze zbioru !@#$%^&*()_+-=

    ok. 3 min
    Polecenie z arkusza

    Jeżeli zaznaczono checkbox „Małe i wielkie litery”, jeden ze znaków jest losowany z zestawu wielkich liter. Za zestaw liter przyjmuje się wszystkie litery z klawiatury małe i wielkie alfabetu łacińskiego.

    Arkusz upraszcza zadanie: można przyjąć, że określony znak losujemy z innego zestawu. U nas pierwszy znak (i == 0) jest wielką literą, gdy pole wyboru jest zaznaczone. IsChecked w WPF ma typ bool? (może być też „nieokreślone”), dlatego porównujemy go z true wprost - if (lettersCheckBox.IsChecked) się nie skompiluje.

    desktopowa/MainWindow.xaml.cs C# zmienione: 9 linii
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private string password = "";
        private Random random = new Random();
    
        private void GenerateButton_Click(object sender, RoutedEventArgs e)
        {
            string lowercase = "abcdefghijklmnopqrstuvwxyz";
            string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            int length = int.Parse(lengthTextBox.Text);
            password = "";
            for (int i = 0; i < length; i++)
            {
                if (i == 0 && lettersCheckBox.IsChecked == true)
                {
                    password += uppercase[random.Next(uppercase.Length)];
                }
                else
                {
                    password += lowercase[random.Next(lowercase.Length)];
                }
            }
            MessageBox.Show(password);
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  21. Krok 21: Cyfra i znak specjalny

    Kryteria: ,

    R.3.7 Znaki do hasła są wybierane przy wykorzystaniu generatora liczb pseudolosowych z zestawu znaków, który zawsze obejmuje małe litery a..z oraz gdy wybrano pierwszy checkbox wielkie litery A..Z i gdy wybrano drugi checkbox cyfry: 0..9 oraz gdy wybrano trzeci checkbox znaki specjalne ze zbioru !@#$%^&*()_+-=

    R.3.8 Hasło oraz zestawy znaków są przechowywane w zmiennych typu napisowego, hasło jest widoczne dla obu metod obsługujących kliknięcia przycisków

    ok. 3 min
    Polecenie z arkusza

    Jeżeli zaznaczono checkbox „Cyfry”, jeden ze znaków hasła jest losowany z zestawu cyfr. Jeżeli zaznaczono checkbox „Znaki specjalne”, jeden ze znaków hasła jest losowany z zestawu znaków specjalnych. Dla uproszczenia zadania można przyjąć zawsze określony znak (np. pierwszy), który jest losowany z cyfr. Za zestaw znaków specjalnych przyjmuje się znaki !@#$%^&*()_+-=.

    Drugi znak (i == 1) to cyfra, trzeci (i == 2) - znak specjalny, każdy tylko przy zaznaczonym polu; pozostałe znaki są małymi literami. Łańcuch if ... else if ... else gwarantuje, że na każdej pozycji losujemy dokładnie raz. Zestawy znaków to zmienne string (R.3.8).

    Zaznacz w podglądzie „Cyfry”, wpisz 5 i wygeneruj hasło - wynik w rodzaju „Mb7ri”, jak na obrazie 2.

    desktopowa/MainWindow.xaml.cs C# zmienione: 10 linii
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private string password = "";
        private Random random = new Random();
    
        private void GenerateButton_Click(object sender, RoutedEventArgs e)
        {
            string lowercase = "abcdefghijklmnopqrstuvwxyz";
            string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string digits = "0123456789";
            string special = "!@#$%^&*()_+-=";
            int length = int.Parse(lengthTextBox.Text);
            password = "";
            for (int i = 0; i < length; i++)
            {
                if (i == 0 && lettersCheckBox.IsChecked == true)
                {
                    password += uppercase[random.Next(uppercase.Length)];
                }
                else if (i == 1 && digitsCheckBox.IsChecked == true)
                {
                    password += digits[random.Next(digits.Length)];
                }
                else if (i == 2 && specialCheckBox.IsChecked == true)
                {
                    password += special[random.Next(special.Length)];
                }
                else
                {
                    password += lowercase[random.Next(lowercase.Length)];
                }
            }
            MessageBox.Show(password);
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  22. Krok 22: Zatwierdź: dane pracownika w komunikacie

    Kryteria: , ,

    R.3.5 Po wciśnięciu przynajmniej jednego przycisku wywoływana jest funkcja

    R.3.8 Hasło oraz zestawy znaków są przechowywane w zmiennych typu napisowego, hasło jest widoczne dla obu metod obsługujących kliknięcia przycisków

    R.3.9 Po wybraniu przycisku „Zatwierdź” wyświetla się komunikat w nowym oknie w którym ujęte są: imię, nazwisko, wartość wybrana z listy rozwijalnej oraz wygenerowane wcześniej hasło

    ok. 3 min
    Polecenie z arkusza

    Działanie aplikacji po wybraniu przycisku „Zatwierdź”: wyświetlany jest komunikat z wypełnionymi danymi pracownika oraz wygenerowanym wcześniej hasłem, zgodnie z obrazem 3.

    Druga metoda składa komunikat z tekstu pól, napisu wybranej pozycji listy (positionComboBox.Text) i pola password - tego samego, które ustawiła metoda generowania. Przycisk wiąże z nią Click="ConfirmButton_Click".

    Przejdź w podglądzie scenariusz z obrazu 3: Zofia, Kowalska, Tester, 5 znaków z cyframi, „Generuj hasło”, potem „Zatwierdź” - w komunikacie jest to samo hasło.

    Typowe błędy

    Hasło jako zmienna lokalna w GenerateButton_Click - druga metoda go nie widzi; kod się nie skompiluje albo komunikat pokaże puste hasło.

    desktopowa/MainWindow.xaml XAML zmienione: 1 linia
    <Window x:Class="desktopowa.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:desktopowa"
            mc:Ignorable="d"
            Title="Dodaj pracownika - Bartosz Bryniarski" Height="300" Width="650"
            Background="#B0C4DE">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <GroupBox Header="Dane pracownika" Margin="20,20,20,10">
                <Grid Margin="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Label Content="Imię" Margin="0,5" />
                    <TextBox x:Name="firstNameTextBox" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="1" Content="Nazwisko" Margin="0,5" />
                    <TextBox x:Name="lastNameTextBox" Grid.Row="1" Grid.Column="1" Margin="0,5" Height="22" />
                    <Label Grid.Row="2" Content="Stanowisko" Margin="0,5" />
                    <ComboBox x:Name="positionComboBox" Grid.Row="2" Grid.Column="1" Margin="0,5" Height="22">
                        <ComboBoxItem Content="Kierownik" />
                        <ComboBoxItem Content="Starszy programista" />
                        <ComboBoxItem Content="Młodszy programista" />
                        <ComboBoxItem Content="Tester" />
                    </ComboBox>
                </Grid>
            </GroupBox>
            <GroupBox Grid.Column="1" Header="Generowanie hasła" Margin="20,20,20,10">
                <StackPanel Margin="10">
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,5">
                        <Label Content="Ile znaków?" Width="100" />
                        <TextBox x:Name="lengthTextBox" Width="120" Height="22" />
                    </StackPanel>
                    <CheckBox x:Name="lettersCheckBox" Content="Małe i wielkie litery" IsChecked="True" Margin="5" />
                    <CheckBox x:Name="digitsCheckBox" Content="Cyfry" Margin="5" />
                    <CheckBox x:Name="specialCheckBox" Content="Znaki specjalne" Margin="5" />
                    <Button Content="Generuj hasło" Width="90" Margin="5" Background="#4682B4" Foreground="White"
                            Click="GenerateButton_Click" />
                </StackPanel>
            </GroupBox>
            <Button Grid.Row="1" Grid.ColumnSpan="2" Content="Zatwierdź" Width="200" Margin="0,0,0,15"
                    Background="#4682B4" Foreground="White" Click="ConfirmButton_Click" />
        </Grid>
    </Window>
    desktopowa/MainWindow.xaml.cs C# zmienione: 6 linii
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private string password = "";
        private Random random = new Random();
    
        private void GenerateButton_Click(object sender, RoutedEventArgs e)
        {
            string lowercase = "abcdefghijklmnopqrstuvwxyz";
            string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string digits = "0123456789";
            string special = "!@#$%^&*()_+-=";
            int length = int.Parse(lengthTextBox.Text);
            password = "";
            for (int i = 0; i < length; i++)
            {
                if (i == 0 && lettersCheckBox.IsChecked == true)
                {
                    password += uppercase[random.Next(uppercase.Length)];
                }
                else if (i == 1 && digitsCheckBox.IsChecked == true)
                {
                    password += digits[random.Next(digits.Length)];
                }
                else if (i == 2 && specialCheckBox.IsChecked == true)
                {
                    password += special[random.Next(special.Length)];
                }
                else
                {
                    password += lowercase[random.Next(lowercase.Length)];
                }
            }
            MessageBox.Show(password);
        }
    
        private void ConfirmButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Dane pracownika: " + firstNameTextBox.Text + " " + lastNameTextBox.Text + " "
                + positionComboBox.Text + " Hasło: " + password);
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  23. Krok 23: Folder desktopowa: archiwum, źródła i plik wykonywalny

    ok. 2 min
    Polecenie z arkusza

    Kod aplikacji przygotuj do nagrania na płytę. W folderze desktopowa powinno znaleźć się archiwum całego projektu o nazwie desktopowa.zip, pliki źródłowe, które były modyfikowane (interfejs użytkownika i logika aplikacji) oraz plik uruchomieniowy, jeżeli to możliwe.

    Pakujemy folder projektu do desktopowa.zip, obok kopiujemy MainWindow.xaml (interfejs), MainWindow.xaml.cs (logika) i desktopowa.exe z bin\Debug\net...-windows.

    Okno aplikacji bez zmian - taki jak po kroku 22.

  24. Etap 4: Dokumentacja aplikacji

    Kroki 24-27 · po tym etapie masz 32 z 32 kryteriów (pkt)

    Krok 24: Komentarz dokumentujący funkcję Nwd

    Kryteria: , , , ,

    R.4.1 Dla funkcji wyznaczającej NWD z aplikacji konsolowej zapisano nagłówek w postaci komentarza zgodny z Listingiem 1 z arkusza egzaminacyjnego (nie należy brać pod uwagę liczby gwiazdek), komentarz może być wieloliniowy lub kilku jednoliniowy

    R.4.2 W komentarzu ujęto nazwę funkcji oraz opisano jej działanie, np. "funkcja wyznacza NWD metodą Euklidesa"

    R.4.3 W komentarzu ujęto wszystkie argumenty funkcji: nazwy i krótki opis

    R.4.4 W komentarzu ujęto nazwę typu zwracanego i krótki opis co jest zwracane

    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 wyznaczającej NWD, według wzoru. Nagłówek powinien znaleźć się nad definicją funkcji. W miejscu nawiasów <> należy podać odpowiednie opisy. W miejscu autor należy podać numer zdającego.

    Komentarz wieloliniowy /* ... */ nad funkcją, z polami z listingu 1: nazwa i opis działania (R.4.2), oba parametry z opisem (R.4.3), zwracany typ uint z opisem (R.4.4) i autor (R.4.5). Na egzaminie w polu autor wpisujemy numer PESEL - tu stoi Bartosz Bryniarski. Gwiazdek ma być więcej niż 5.

    konsola/Program.cs C# zmienione: 11 linii
    class Program
    {
        /*
         ******************************************************
         nazwa funkcji:       Nwd
         opis funkcji:        wyznacza największy wspólny dzielnik dwóch liczb algorytmem Euklidesa
                              (odejmuje mniejszą liczbę od większej, aż obie będą równe)
         parametry:           a - pierwsza liczba całkowita dodatnia
                              b - druga liczba całkowita dodatnia
         zwracany typ i opis: uint - największy wspólny dzielnik liczb a i b
         autor:               Bartosz Bryniarski
         ******************************************************
         */
        static uint Nwd(uint a, uint b)
        {
            while (a != b)
            {
                if (a > b)
                {
                    a = a - b;
                }
                else
                {
                    b = b - a;
                }
            }
            return a;
        }
    
        static void Main()
        {
            Console.Write("Podaj liczbę a: ");
            uint a = uint.Parse(Console.ReadLine());
            Console.Write("Podaj liczbę b: ");
            uint b = uint.Parse(Console.ReadLine());
            Console.WriteLine($"NWD({a}, {b}) = {Nwd(a, b)}");
        }
    }
    Wynik programu po tym kroku
    > konsola.exe
    Podaj liczbę a: 48
    Podaj liczbę b: 18
    NWD(48, 18) = 6
  25. Krok 25: Zrzuty konsola1 i konsola2

    Kryteria: , ,

    R.1.7 Podjęto próbę skompilowania kodu, co udokumentowano obrazem przedstawiającym uruchomiony program lub jego kompilację

    R.2.7 Program kompiluje się i uruchamia w konsoli, co udokumentowano zrzutem ekranu

    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. 3 min
    Polecenie z arkusza

    Wykonaj zrzuty ekranu dokumentujące uruchomienie aplikacji. Zrzuty powinny obejmować cały obszar ekranu monitora z widocznym paskiem zadań. Aplikacja konsolowa – zrzuty nazwane: konsola1, konsola2, ...

    Dwa uruchomienia z różnymi liczbami i zrzut całego ekranu z Visual Studio i oknem konsoli: konsola1.png (48 i 18 → 6), konsola2.png (17 i 5 → 1). Zrzuty idą do folderu dokumentacja.

    Wynik programu po tym kroku
    > konsola.exe
    Podaj liczbę a: 48
    Podaj liczbę b: 18
    NWD(48, 18) = 6
    
    > konsola.exe
    Podaj liczbę a: 17
    Podaj liczbę b: 5
    NWD(17, 5) = 1
  26. Krok 26: Zrzuty desktop1 - desktop3

    Kryteria: ,

    R.3.10 Aplikacja kompiluje się i uruchamia, co udokumentowano zrzutem ekranu, jej układ po uruchomieniu jest zgodny z obrazem 1 w arkuszu egzaminacyjnym. Zaznaczone jest pierwsze pole wyboru

    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

    ok. 4 min
    Polecenie z arkusza

    Wykonać należy co najmniej tyle zrzutów, ile interakcji podejmuje aplikacja (np. stan początkowy, po wypisaniu hasła, po wyświetleniu danych itd.). Aplikacja desktopowa – zrzuty nazwane: desktop1, desktop2, ...

    Uruchamiamy aplikację z Visual Studio (F5) i robimy zrzuty całego ekranu ze środowiskiem w tle:

    • desktop1.png - stan początkowy (obraz 1, R.3.10),
    • desktop2.png - komunikat z wygenerowanym hasłem (obraz 2) - klucz sprawdza generowanie dwa razy, więc warto dorobić drugi zrzut z innym hasłem,
    • desktop3.png - komunikat po „Zatwierdź” (obraz 3).

    Podgląd obok to aplikacja z poprzedniego kroku - możesz przejść te stany.

    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  27. Krok 27: Dokument egzamin z podpisanymi zrzutami

    Kryteria:

    R.4.8 Dokumentacja zawiera: nazwę systemu operacyjnego, nazwy ś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 oraz zapisane informacje: nazwę systemu operacyjnego, nazwy środowisk programistycznych, nazwy języków programowania, opcjonalnie komentarz do wykonanej pracy.

    W Wordzie albo Writerze dokument egzamin w folderze dokumentacja: trzy informacje o narzędziach i - w tym arkuszu - także wklejone zrzuty z podpisami (np. „konsola1 - NWD(48, 18)”). Obok jest tekst tej części jako plik tekstowy.

    egzamin.txt Tekst nowy plik
    System operacyjny: Windows 11
    Środowisko programistyczne: Visual Studio 2022 (aplikacja konsolowa i desktopowa)
    Języki programowania: C# (aplikacja konsolowa), C# i XAML - WPF (aplikacja desktopowa)
    Zrzuty: konsola1, konsola2, desktop1, desktop2, desktop3 - wklejone poniżej z podpisami.

    Okno aplikacji bez zmian - taki jak po kroku 26.

  28. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 28-29 · po tym etapie masz 32 z 32 kryteriów (pkt)

    Krok 28: Konsola: liczby dodatnie i bez wyjątków

    ok. 4 min
    Polecenie z arkusza

    Liczby a i b należą do zbioru liczb całkowitych dodatnich (odpowiedni typ lub kontrola poprawności wpisanej liczby).

    Typ uint odrzuca liczby ujemne, ale przepuszcza zero - a dla a = 0 i b = 5 pętla odejmowania kręci się w nieskończoność (b - 0 to wciąż b). Do tego uint.Parse przy słowie zamiast liczby przerywa program wyjątkiem.

    Funkcja ReadPositive pyta do skutku: uint.TryParse nie rzuca wyjątku, tylko zwraca false, a warunek number == 0 odrzuca zero. Program główny wczytuje obie liczby tą samą funkcją.

    Na egzaminie wystarczy wersja wcześniejsza - klucz przyjmuje typ bez znaku.

    konsola/Program.cs C# zmienione: 13 linii
    class Program
    {
        /*
         ******************************************************
         nazwa funkcji:       Nwd
         opis funkcji:        wyznacza największy wspólny dzielnik dwóch liczb algorytmem Euklidesa
                              (odejmuje mniejszą liczbę od większej, aż obie będą równe)
         parametry:           a - pierwsza liczba całkowita dodatnia
                              b - druga liczba całkowita dodatnia
         zwracany typ i opis: uint - największy wspólny dzielnik liczb a i b
         autor:               Bartosz Bryniarski
         ******************************************************
         */
        static uint Nwd(uint a, uint b)
        {
            while (a != b)
            {
                if (a > b)
                {
                    a = a - b;
                }
                else
                {
                    b = b - a;
                }
            }
            return a;
        }
    
        static uint ReadPositive(string prompt)
        {
            uint number;
            Console.Write(prompt);
            while (!uint.TryParse(Console.ReadLine(), out number) || number == 0)
            {
                Console.Write("To musi być liczba całkowita większa od zera. " + prompt);
            }
            return number;
        }
    
        static void Main()
        {
            uint a = ReadPositive("Podaj liczbę a: ");
            uint b = ReadPositive("Podaj liczbę b: ");
            Console.WriteLine($"NWD({a}, {b}) = {Nwd(a, b)}");
        }
    }
    Wynik programu po tym kroku
    > konsola.exe
    Podaj liczbę a: 48
    Podaj liczbę b: 18
    NWD(48, 18) = 6
  29. Krok 29: Okno: sprawdzenie liczby znaków

    ok. 3 min
    Polecenie z arkusza

    UWAGA: dla uproszczenia aplikacji nie trzeba sprawdzać czy pole edycyjne jest wypełnione i czy liczba znaków w haśle jest wystarczająca.

    Arkusz zwalnia z tego sprawdzania, ale w prawdziwej aplikacji puste pole „Ile znaków?” kończy się wyjątkiem FormatException i zamknięciem programu. int.TryParse zamienia to na komunikat, a warunek length < 3 pilnuje, żeby w haśle zmieściły się wielka litera, cyfra i znak specjalny (pozycje 0, 1 i 2). Stara linia zostaje w komentarzu.

    Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    desktopowa/MainWindow.xaml.cs C# zmienione: 6 linii
    using System.Windows;
    
    namespace desktopowa;
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private string password = "";
        private Random random = new Random();
    
        private void GenerateButton_Click(object sender, RoutedEventArgs e)
        {
            string lowercase = "abcdefghijklmnopqrstuvwxyz";
            string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string digits = "0123456789";
            string special = "!@#$%^&*()_+-=";
            if (!int.TryParse(lengthTextBox.Text, out int length) || length < 3)
            {
                MessageBox.Show("Podaj liczbę znaków hasła - co najmniej 3.");
                return;
            }
            // int length = int.Parse(lengthTextBox.Text);
            password = "";
            for (int i = 0; i < length; i++)
            {
                if (i == 0 && lettersCheckBox.IsChecked == true)
                {
                    password += uppercase[random.Next(uppercase.Length)];
                }
                else if (i == 1 && digitsCheckBox.IsChecked == true)
                {
                    password += digits[random.Next(digits.Length)];
                }
                else if (i == 2 && specialCheckBox.IsChecked == true)
                {
                    password += special[random.Next(special.Length)];
                }
                else
                {
                    password += lowercase[random.Next(lowercase.Length)];
                }
            }
            MessageBox.Show(password);
        }
    
        private void ConfirmButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Dane pracownika: " + firstNameTextBox.Text + " " + lastNameTextBox.Text + " "
                + positionComboBox.Text + " Hasło: " + password);
        }
    }
    Okno aplikacji po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  30. Etap 6: Oddanie pracy

    Krok 30 · po tym etapie masz 32 z 32 kryteriów (pkt)

    Krok 30: Nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    UWAGA: Nagraj płytę z rezultatami pracy. W folderze z numerem zdającego powinny się znajdować podfoldery desktopowa, dokumentacja, konsola. W folderze dokumentacja: pliki ze zrzutami oraz plik egzamin. W folderze konsola: spakowany cały projekt aplikacji konsolowej, źródło, opcjonalnie plik uruchomieniowy. W folderze desktopowa: spakowany cały projekt aplikacji desktopowej, pliki ze źródłami interfejsu i logiki, opcjonalnie plik uruchomieniowy.

    Sprawdzamy zawartość przed nagraniem:

    • dokumentacja: konsola1.png, konsola2.png, desktop1.png - desktop3.png, egzamin,
    • konsola: konsola.zip (spakowany po dopisaniu komentarza), Program.cs, konsola.exe,
    • desktopowa: desktopowa.zip, MainWindow.xaml, MainWindow.xaml.cs, desktopowa.exe.

    Nagrywamy, sprawdzamy odczyt płyty, opisujemy ją numerem zdającego.

    Okno aplikacji bez zmian - taki jak po kroku 29.

Podgląd

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: . 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.