Arkusz egzaminacyjny INF.04. Styczeń 2024
INF 04 egzamin praktyczny Rozwiązanie arkusza styczeń 2024
Część 1. Aplikacja konsolowa: Poprawność numeru PESEL
Za pomocą narzędzi do tworzenia aplikacji konsolowych zaimplementuj program sprawdzający poprawność numeru PESEL. Program powinien sprawdzać płeć i sumę kontrolną według opisu:
Numer PESEL jest to 11-cyfrowy identyfikator numeryczny.
Płeć
Informacja o płci osoby zawarta jest na 10. (przedostatniej) pozycji numeru PESEL.
cyfry 0, 2, 4, 6, 8 (parzyste) - oznaczają płeć żeńską
cyfry 1, 3, 5, 7, 9 (nieparzyste) - oznaczają płeć męską
Cyfra kontrolna i sprawdzanie poprawności numeru
Jedenastą cyfrą numeru PESEL jest cyfra kontrolna umożliwiająca kontrolę poprawności identyfikatora. Jest ona wynikiem działania na pierwszych dziesięciu cyfrach.
Algorytm obliczania cyfry kontrolnej na podstawie kolejnych cyfr numeru:
1. Dla kolejnych 10 cyfr numeru PESEL oblicz iloczyn każdej cyfry i jej wagi na podstawie tabeli:
Pozycja cyfry od lewej 1 2 3 4 5 6 7 8 9 10
Waga cyfry 1 3 7 9 1 3 7 9 1 3
Oznacza to, że pierwszą cyfrę numeru PESEL należy pomnożyć przez 1, drugą cyfrę przez 3, trzecią przez 7 itd.
2. Wszystkie iloczyny zsumuj ze sobą i zapisz w zmiennej S
3. Wykonaj operację modulo 10 na sumie S i zapisz w zmiennej M
4. Gdy wartość zmiennej M jest równa 0, to zmiennej R przypisz wartość 0. W przeciwnym przypadku zmiennej R przypisz wartość różnicy 10 i M (R=10-M)
5. Zmienna R stanowi sumę kontrolną numeru PESEL i musi być równa jedenastej cyfrze numeru PESEL
Założenia aplikacji:
- Zastosowany obiektowy język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym: C++ lub C#, lub Java, lub Python
- Numer PESEL może być przechowywany jako zmienna tekstowa albo tablica 11 liczb całkowitych lub znaków
- Zmienna ta jest zainicjowana numerem PESEL zdającego lub w przypadku jego braku numerem 55030101193
- Sprawdzanie płci należy zaimplementować w osobnej funkcji zwracającej typ znakowy o wartości 'K' dla kobiety oraz 'M' dla mężczyzny
- Sprawdzanie sumy kontrolnej należy zaimplementować w osobnej funkcji zwracającej wartość logiczną true w przypadku zgodności sumy lub false w przeciwnym przypadku
- Parametrem wejściowym obu funkcji jest zmienna przechowująca numer PESEL
- Program główny testuje działanie funkcji i zawiera następujące operacje wejścia - wyjścia
- Wczytanie z klawiatury numeru PESEL
- Wypisanie płci (ustalonej przez funkcję) w postaci napisu: Kobieta lub Mężczyzna w oparciu o wczytany numer PESEL
- Wypisanie informacji o zgodności lub niezgodności sumy kontrolnej w oparciu o wczytany numer PESEL
- Program powinien podejmować zrozumiałą komunikację z użytkownikiem
- W programie może być zastosowane angielskie lub polskie nazewnictwo zmiennych i funkcji
- Program powinien być zapisany czytelnie, z zachowaniem zasad czystego formatowania kodu, należy stosować nazwy zmiennych znaczące oraz zgodne z przedstawionym algorytmem
- Do kodu należy dołączyć dokumentację, która została opisana w części III zadania egzaminacyjnego.
Część 2. Aplikacja mobilna: Dane paszportowe
Za pomocą dostępnego na stanowisku egzaminacyjnym środowiska programistycznego wykonaj aplikację desktopową do wprowadzania danych paszportowych. Do wykonania zadania wykorzystaj znajdujące się na pulpicie archiwum 7-Zip o nazwie materialy.7z zabezpieczone hasłem: p@szporTy%
Na obrazie 1 przedstawiono ideę aplikacji desktopowej. W zależności od użytego środowiska programistycznego wygląd może nieznacznie się różnić.
Opis wyglądu aplikacji
- Okno o nazwie Wprowadzenie danych do paszportu. Wykonał: następnie wstawiony numer zdającego
- Kontrolki rozmieszczone zgodnie z obrazem 1:
- Pole edycyjne poprzedzone etykietą o treści Numer
- Pole edycyjne poprzedzone etykietą o treści Imię
- Pole edycyjne poprzedzone etykietą o treści Nazwisko
- Grupa ?Kolor oczu? zawierająca trzy pola wyboru: ?niebieskie?, ?zielone?, ?piwne?. Pierwsze pole jest domyślnie zaznaczone
- W grupie może być jednocześnie zaznaczone jedno pole
- Przycisk o treści ?OK?
- Dwa obrazy: 000-zdjecie.jpg oraz 000-odcisk.jpg. Obrazy mają tę samą wysokość. W aplikacji, której okno przedstawiono na obrazie 1 zastosowano wysokość równą 180
- Okno ma tło koloru CadetBlue (#5F9EA0)
- Pola edycyjne i przycisk mają tło koloru Azure (#F0FFFF)
Działanie aplikacji po opuszczeniu pola edycyjnego Numer
- Aktualizowane są oba zdjęcia w oknie. Nazwy plików graficznych są utworzone na podstawie wpisanego numeru do pola edycyjnego Numer
- Obraz osoby ma nazwę <numer>-zdjecie.jpg, gdzie <numer> został pobrany z pola edycyjnego, np. po wpisaniu do pola edycyjnego 333 ustawiona nazwa zdjęcia to 333-zdjecie.jpg
- Podobnie, obraz odcisku palca ma nazwę <numer>-odcisk.jpg, gdzie <numer> został pobrany z pola edycyjnego, np. 333-odcisk.jpg (Obraz 3)
- Do testów aplikacji należy wykorzystać wszystkie obrazy z wypakowanego archiwum. W przypadku wpisania numeru (np. 444), który nie odpowiada żadnemu plikowi graficznemu, obraz nie jest wyświetlany.
Działanie aplikacji po wybraniu przycisku OK
- Jeżeli dane zostały wprowadzone do wszystkich pól edycyjnych, wyświetlany jest komunikat zgodny z obrazem 2, o treści: <imie> <nazwisko> kolor oczu <kolor>, gdzie pola w nawiasach <> zostały pobrane z kontrolek
- Jeżeli nie wpisano imienia lub nazwiska, wyświetlany jest komunikat Wprowadź dane
Aplikacja powinna być zapisana czytelnie, z zasadami czystego formatowania kodu, należy stosować znaczące nazwy zmiennych i funkcji.
Podejmij próbę kompilacji i uruchomienia aplikacji. Informacje dotyczące dokumentacji i zrzutu ekranowego umieszczono w części III zadania egzaminacyjnego. Kod aplikacji przygotuj do nagrania na płytę. W folderze desktopowa zapisz 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 istnieje.
Część 3. Dokumentacja aplikacji
Wykonaj dokumentację do aplikacji utworzonych na egzaminie. W kodzie źródłowym aplikacji konsolowej utwórz komentarz do dowolnej funkcji, według wzoru z listingu 1. Komentarz powinien znaleźć się nad funkcją lub pod jej nagłówkiem. W miejscu nawiasów <> należy podać odpowiednie opisy. W miejscu autor należy podać numer zdającego.
UWAGA: Dokumentację należy umieścić w komentarzu (wieloliniowym lub kilku jednoliniowych). Znajdujący się w listingu 1 wzór dokumentacji jest bez znaków początku i końca komentarza, gdyż te są różne dla różnych języków programowania Listing 1. Wzór dokumentacji funkcji (liczba gwiazdek dowolna)
Wykonaj zrzuty ekranu dokumentujące uruchomienie aplikacji utworzonych podczas egzaminu. Zrzuty powinny obejmować cały obszar ekranu monitora z widocznym paskiem zadań. Jeżeli aplikacja uruchamia się, na zrzucie należy umieścić okno z wynikiem działania programu oraz otwarte środowisko programistyczne z projektem lub okno terminala z kompilacją projektu. Jeżeli aplikacja nie uruchamia się z powodu błędów kompilacji, należy na zrzucie umieścić okno ze spisem błędów i widocznym otwartym środowiskiem programistycznym. Należy wykonać tyle zrzutów, ile interakcji podejmuje aplikacja (np. stan początkowy, po wpisaniu numeru i opuszczeniu kontrolki, po wciśnięciu przycisku OK itd.) Wymagane zrzuty ekranu:
- Aplikacja konsolowa ? dokumentująca interakcje dowolna liczba zrzutów o nazwach konsola1, konsola2, ..
- Aplikacja desktopowa ? dokumentująca interakcje dowolna liczba zrzutów o nazwach desktop1, desktop2, ..
W edytorze tekstu pakietu biurowego utwórz plik z dokumentacją i nazwij go egzamin. Dokument powinien zawierać podpisane zrzuty ekranu oraz zapisane informacje dotyczące narzędzi, z których korzystał zdający podczas egzaminu:
- Nazwę systemu operacyjnego
- Nazwy środowisk programistycznych
- Nazwy języków programowania
Rozwiązanie część I. Poprawność numeru PESEL
Warunki rozwiązania zadania nie wymagają zabezpieczeń przed wpisaniem błędnych danych (znaków nie będących cyframi). Stąd też tych zabezpieczeń w kodzie nie ma.
Zgodnie z podanymi warunkami zadania przygotujemy zmienne wynikające z podanego problemu.
Wskazówka:
//graniczna długość znaków w PESEL
const int ILE_ZNAKOW= 11;
//tablica przechowująca kolejne cyfry kodu PESEL
static int[] pesel = new int[ILE_ZNAKOW];
//waga przypisana do pozycji w kodzie PESEL
static int[] waga = {1,3,7,9,1,3,7,9,1,3};
Program będzie działać według kolejności:
- wczytaj cyfry tworzące PESEL
- sprawdź czy podany zestaw cyfr jest poprawnym kodem PESEL
- sprawdź płeć
Funkcja wczytująca cyfry tworzące PESEL może wyglądać jak poniżej
Wskazówka:
static void WczytajPesel()
{
Console.WriteLine("Podaj 11 cyfr kodu PESEL:");
string s = "";
for (int i = 0; i < ILE_ZNAKOW; i++)
{
pesel[i] = int.Parse(Console.ReadLine());
s += pesel[i].ToString();
}
Console.WriteLine("Wczytany PESEL:"+s);
}
Funkcja sprawdzająca poprawność kodu PESEL ma posiadać jeden argument, którym jest PESEL i ma zwracać wartość logiczną true lub false. Jej postać może być zakodowana jak poniżej
Wskazówka:
static bool CzyPESEL(int[] p) {
//sprawdź czy PESEL
int S = 0;
for (int i = 0; i < 10; i++)
S += p[i] * waga[i];
int M=S%10;
int R;
if (M == 0) R = 0;
else R = 10 - M;
//tak to PESEL
if (R == p[10])
{
Console.WriteLine("SUMA KONTROLNA POPRAWNA, TO JEST PESEL");
return true;
}
//nie, to nie PESEL
else
{
Console.WriteLine("SUMA KONTROLNA NIEPOPRAWNA, TO NIE JEST PESEL");
return false;
}
}
Funkcja sprawdzająca płeć ma mieć jeden argument, którym jest PESEL i ma zwracać wartość typu char. Z warunków zadania wiemy, że płeć zakodowana jest na dziesiątej pozycji kody. Gdy cyfra jest parzysta to kobieta, gdy nieparzysta to mężczyzna. Wystarczy, że sprawdzimy parzystość tej cyfry.
Wskazówka:
static char Plec(int[] p)
{
//jeżeli przedostatnia jest parzysta
//to kobieta
if (p[9]%2 == 0) return 'K';
//w przeciwnym wypadku mezczyzna
else return 'M';
}
Wywołanie utworzonych funkcji wykonamy w głównej funkcji Main() programu
Wskazówka:
static void Main(string[] args)
{
WczytajPesel();
CzyPESEL(pesel);
Console.WriteLine("Płeć: "+Plec(pesel));
Console.ReadKey();
}
Wynik działania aplikacji konsolowej
Pełny kod rozwiązania
Wskazówka:
using System;
namespace styczen_2024_problem_1_PESEL
{
internal class Program
{
//graniczna długość znaków w PESEL
const int ILE_ZNAKOW= 11;
//tablica przechowująca kolejne cyfry kodu PESEL
static int[] pesel = new int[ILE_ZNAKOW];
//waga przypisana do pozycji w kodzie PESEL
static int[] waga = {1,3,7,9,1,3,7,9,1,3};
static void WczytajPesel()
{
Console.WriteLine("Podaj 11 cyfr kodu PESEL:");
string s = "";
for (int i = 0; i < ILE_ZNAKOW; i++)
{
pesel[i] = int.Parse(Console.ReadLine());
s += pesel[i].ToString();
}
Console.WriteLine("Wczytany PESEL:"+s);
}
static bool CzyPESEL(int[] p) {
//sprawdź czy PESEL
int S = 0;
for (int i = 0; i < 10; i++)
S += p[i] * waga[i];
int M=S%10;
int R;
if (M == 0) R = 0;
else R = 10 - M;
//tak to PESEL
if (R == p[10])
{
Console.WriteLine("SUMA KONTROLNA POPRAWNA, TO JEST PESEL");
return true;
}
//nie, to nie PESEL
else
{
Console.WriteLine("SUMA KONTROLNA NIEPOPRAWNA, TO NIE JEST PESEL");
return false;
}
}
static char Plec(int[] p)
{
//jeżeli przedostatnia jest parzysta
//to kobieta
if (p[9]%2 == 0) return 'K';
//w przeciwnym wypadku mezczyzna
else return 'M';
}
static void Main(string[] args)
{
WczytajPesel();
CzyPESEL(pesel);
Console.WriteLine("Płeć: "+Plec(pesel));
Console.ReadKey();
}
}
}
Rozwiązanie część II. Dane paszportowe
UWAGA. Po zainicjowaniu projektu rozwiązania przejdź do folderu bin/Debug. Skopiuj do tego folderu dołączone pliki graficzne. Jeżeli tego nie zrobisz, to w kodzie programu musisz podać pełną ścieżkę dostępu do wczytywanego pliku. Ale uważaj, egzaminatorowi może zmienić się symbol dysku.
Najbezpieczniej pliki graficzne jest przechowywać w folderze, w którym będzie zapisany plik wykonywalny *.exe
Tworzymy układ okna formatki aplikacji.
Pamiętaj aby przypisać kontrolkom odpowiedni kolor (podany w arkuszu egzaminacyjnym) oraz tytuł w oknie formatki.
Kontrolkom (PictureBox) do przechowywania obrazu przypisujemy szerokość (140 pikseli) i wysokość (180 pikseli) oraz ustawiamy skalowanie obrazu do pełnego wypełnienia obszaru kontrolki (SizeMode ustaw na StretchImage).
Zmienne w programie
Podane rozwiązanie jest napisane możliwie najprościej. Potrzebujemy tylko jednej zmiennej do przechowywania koloru oczu. Z podanych warunków wynika, że początkowy kolor oczu to niebieski.
Wskazówka:
public partial class Form1 : Form
{
string kolorOczu="niebieskie";
public Form1()
{
InitializeComponent();
}
Funkcja ładująca grafikę
Arkusz egzaminacyjny zawiera informację, że grafika ma być ładowana na podstawie podanego cyfrowego prefiksu, do którego dołączony jest ciąg znaków tworzący rdzeń nazwy plików graficznych. Przy ładowaniu grafiki z pliku może dojść do nie znalezienia pliku, co powoduje zawieszenie aplikacji.
Najprostszym zabezpieczeniem jest zastosowanie wyjątku na przykład: try- catch. Skorzystamy z tego rozwiązania. Jednocześnie wyślemy w formie komunikatu kod błędnego ładowania pliku (nie jest to wymagane w podanych warunkach rozwiązania arkusza egzaminacyjnego)
Wskazówka:
//parametr to odczytany prefiks z TextBoxa
bool LadujGrafike(string p)
{
//przechwyć wyjątek
try
{
pictureBox1.Load(p + "-zdjecie.jpg");
pictureBox2.Load(p + "-odcisk.jpg");
return true;
}
//gdy nie ma pliku graficznego to obsłuż wyjątek
//braku pliku- wyślij komunikat ze ścieżką ładowanego pliku
catch(Exception e)
{
MessageBox.Show($"Brak pliku w lokalizacji\n{e.Message}");
return false;
}
}
Wybór koloru oczu
Kolor oczu ustalany jest na podstawie aktywności kontrolek typu RadioButton. Najłatwiej kontrolki te jest obsłużyć wspólni jednym kodem metody zdarzenia typu CheckedChanged().
Na formatce zaznacz wszystkie trzy kontrolki typu RadioButton (przytrzymaj wciśnięty klawisz SHIFT i wybierz kontrolki kliknięciem myszki)
Przejdź do zakładki Właściwości. W pustym polu metody CheckedChanged dwa razy szybko kliknij. Zainicjujesz wspólne zdarzenie typu CheckedChanged dla tych trzech zaznaczonych kontrolek RadioButton
W kodzie utworzonego zdarzenia wykorzystamy rzutowanie na aktywny obiekt typu RadioButton i jeżeli jest on wybrany, to kolor oczu odczytamy z przypisanego tekstu pola Text
Wskazówka:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
//kolor oczu
RadioButton rb=sender as RadioButton;
//zapamiętaj aktywny kolor oczu
if(rb.Checked)kolorOczu=rb.Text;
}
Obsługa klawisza OK.
Na zakończenie zapiszemy kod zdarzenia kliknięcia w kontrolkę typu Button. W zdarzeniu tym obsłużymy odczyt wprowadzonych danych (imię, nazwisko, prefiks pliku graficznego) z jednoczesnymi komunikatami.
Do przycisku podpinamy metodę zdarzenia kliknięcia. Patrz poniżej
W metodzie kliknięcia wprowadzamy poniższy kod.
Wskazówka:
private void button1_Click(object sender, EventArgs e)
{
//załaduj grafikę
if(LadujGrafike(textBox1.Text)==false)return;
//tresc komunikatu
string tresc = $"{textBox2.Text} {textBox3.Text} kolor oczu {kolorOczu}";
if (textBox2.Text != "" && textBox3.Text != "")
MessageBox.Show(tresc,"Komunikat",MessageBoxButtons.OK);
else
MessageBox.Show("Wprowadź dane","Komunikat",MessageBoxButtons.OK);
}
Skompiluj program i sprawdź efekt działania. Wynik działania aplikacji desktopowej.
Pełny kod rozwiązania
Wskazówka:
using System;
using System.Windows.Forms;
namespace styczen2024paszporty
{
public partial class Form1 : Form
{
string kolorOczu="niebieskie";
public Form1()
{
InitializeComponent();
}
//parametr to odczytany prefiks z TextBoxa
bool LadujGrafike(string p)
{
//przechwyć wyjątek
try
{
pictureBox1.Load(p + "-zdjecie.jpg");
pictureBox2.Load(p + "-odcisk.jpg");
return true;
}
//gdy nie ma pliku graficznego to obsłuż wyjątek
//braku pliku- wyśłij komunikat ze ścieżką ładowanego pliku
catch(Exception e)
{
MessageBox.Show($"Brak pliku w lokalizacji\n{e.Message}");
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
//załaduj grafikę
if(LadujGrafike(textBox1.Text)==false)return;
//tresc komunikatu
string tresc = $"{textBox2.Text} {textBox3.Text} kolor oczu {kolorOczu}";
if (textBox2.Text != "" && textBox3.Text != "")
MessageBox.Show(tresc,"Komunikat",MessageBoxButtons.OK);
else
MessageBox.Show("Wprowadź dane","Komunikat",MessageBoxButtons.OK);
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
//kolor oczu
RadioButton rb=sender as RadioButton;
//zapamiętaj aktywny kolor oczu
if(rb.Checked)kolorOczu=rb.Text;
}
}
}