Wymagania formalne:
W rozwiązaniach zadań domowych z Modułu 5, student powinien wykazać się umiejętnością zabezpieczania kodu przed nieoczekiwanymi danymi wejściowymi. Każde rozwiązanie musi wykorzystywać odpowiednie kolekcje generyczne (List, Dictionary, Stack itp.) dopasowane do charakteru problemu. Dokumentacja powinna zawierać opisy przechwytywanych wyjątków oraz zrzuty ekranu prezentujące poprawne przesyłanie/filtrowanie danych w aplikacjach.
D5.1
Menedżer Eksportu Danych (Obsługa wyjątków IO)
Cel

Utworzenie narzędzia odpornego na błędy systemowe związane z dostępem do zasobów zewnętrznych (np. dysku). Student uczy się wykorzystywać bloki try-catch do przechwytywania specyficznych wyjątków biblioteki System.IO oraz gwarantować bezpieczeństwo operacji.

Scenariusz

Budujesz prosty edytor tekstowy, który musi potrafić zapisać tekst notatki do pliku na dysku. Proces ten jest obciążony wieloma ryzykami: użytkownik może podać błędną ścieżkę, plik może być aktualnie używany przez inny program lub dysk może być chroniony przed zapisem. Twoim zadaniem jest stworzenie metody ZapiszDoPliku(string sciezka, string tresc), która zostanie w całości otoczona blokiem bezpiecznego dostępu. Musisz obsłużyć co najmniej trzy rodzaje błędów: błąd braku uprawnień (UnauthorizedAccessException), błąd niepoprawnego formatu ścieżki oraz ogólny błąd wejścia/wyjścia (IOException). System nie może po prostu przestać działać - musi poinformować użytkownika, dlaczego zapis się nie udał, i pozwolić na poprawienie nazwy pliku. Program w konsoli symuluje interakcję z dyskiem, wyświetlając status operacji. To zadanie uczy, jak ważna jest rola wyjątków przy komunikacji z systemem operacyjnym. Finalnie, nawet przy błędzie, program powinien zwolnić wszystkie zasoby pomocnicze (blok finally). Precyzyjna informacja diagnostyczna jest kluczem do zadowolenia użytkownika końcowego aplikacji.

Sugerowane kroki do wykonania
  1. Poproś użytkownika o podanie nazwy pliku (sciezki) oraz tekstu notatki.
  2. Otwórz blok try na całą logikę wywołania systemowego.
  3. Wykorzystaj klasę File z System.IO do wykonania zapisu (np. File.WriteAllText).
  4. Zidentyfikuj i dodaj blok catch dla UnauthorizedAccessException (brak uprawnień).
  5. Dodaj blok catch dla ArgumentException (pusta nazwa pliku).
  6. Dodaj blok catch (IOException), aby przechwycić inne błędy dyskowe.
  7. W każdym bloku catch wyświetl czytelny komunikat o przyczynie problemu.
  8. Dodaj blok finally, który wypisze komunikat o zakończeniu próby zapisu dokumentu.
  9. Przetestuj program podając jako nazwę pliku niedozwolone znaki (np. * , ?).
  10. Zasymuluj udany zapis i sprawdź, czy plik rzeczywiście powstał w wybranej lokalizacji.
D5.2
Słownik Polsko-Angielski (Dictionary)
Cel

Zaimplementowanie dwukierunkowej bazy słów z wykorzystaniem mechanizmu Dictionary<TKey, TValue>. Student uczy się optymalizować operacje wyszukiwania tekstowego oraz zarządzać unikalnością kluczy w z zbiorach danych.

Scenariusz

Budujesz małe narzędzie edukacyjne ułatwiające naukę słówek z języka angielskiego. System powinien przechowywać bazę danych, w której polskie słowo jest kluczem, a jego angielski odpowiednik jest wartością. Użytkownik ma mieć możliwość dodawania nowych par słówek oraz błyskawicznego tłumaczenia wyrazów wpisanych w konsoli. Musisz zadbać o to, aby system informował, jeśli dane słowo zostało już wcześniej dodane do bazy, i uniemożliwiał nadpisanie go bez wiedzy operatora. Program powinien również oferować funkcję wyświetlenia całego aktualnie posiadanego słownictwa w formie sformatowanej tabeli. Dzięki zastosowaniu słownika, Twoja aplikacja będzie działać niezwykle szybko nawet przy setkach wpisów, co jest przewagą nad zwykłą listą. Co więcej, system powinien być odporny na wielkość liter (ignorowanie case) podczas wyszukiwania. Takie rozwiązanie symuluje działanie profesjonalnych aplikacji językowych i baz terminologicznych. Program kończy pracę na życzenie użytkownika po wyświetleniu statystyk Twojej aktualnej wiedzy.

Sugerowane kroki do wykonania
  1. Zainicjalizuj Dictionary<string, string> dla swojego słownika.
  2. Stwórz pętlę menu z opcjami: Dodaj słowo, Tłumacz, Wyświetl wszystko, Wyjdź.
  3. Użyj metody ContainsKey() przed dodaniem nowej pary, aby uniknąć duplikatów.
  4. Zastosuj .ToLower() na kluczach, aby wyszukiwanie nie zależało od wielkości liter.
  5. Przy poleceniu tłumaczenia, spróbuj pobrać wartość skojarzoną z kluczem i wyświetl ją.
  6. Jeśli słowa nie ma w bazie, zaproponuj użytkownikowi jego dodanie.
  7. Użyj pętli foreach do wypisania całej zawartości słownika w formacie: "PL -> EN".
  8. Dodaj informację o łącznej liczbie słówek znajdujących się w Twojej bazie danych.
  9. Przetestuj dodanie słowa "Kot" i spróbuj przetłumaczyć "kot" (małymi literami).
  10. Spróbuj usunąć wybrane słowo z bazy przy użyciu metody Remove().
D5.3
Rejestr Wykroczeń Drogowych (List + LINQ)
Cel

Przetwarzanie rozbudowanych zbiorów obiektów z wykorzystaniem mocy obliczeniowej LINQ. Student uczy się łączyć filtrowanie, sortowanie oraz zaawansowaną agregację danych w kilku liniach czytelnego kodu.

Scenariusz

Pracujesz nad systemem wspomagającym pracę drogówki, który przechowuje listę zarejestrowanych mandatów karnych (klasa Mandat z polami: Kierowca, PunktyKarne, Kwota, Miasto). Twoim zadaniem jest stworzenie bazy mandatów opartej na List<Mandat> i wypełnienie jej kilkunastoma przykładowymi pozycjami. Następnie system musi wygenerować kilka bardzo konkretnych raportów analitycznych przy użyciu zapytań LINQ. Pierwszy raport powinien listować tylko te mandaty, które zostały wystawione w Krakowie na kwotę powyżej 500 zł. Drugi raport ma wyliczyć sumę wszystkich punktów karnych zgromadzonych przez konkretnego kierowcę (filtrowanie po nazwisku). Trzecia analiza powinna znaleźć kierowcę, który zapłacił najwyższy mandat w całej bazie danych. Zastosowanie LINQ pozwoli Ci uniknąć pisania skomplikowanych i błędotwórczych pętli warunkowych. Dzięki temu Twój kod będzie wyglądał nowocześnie i profesjonalnie. Program musi wyświetlić wyniki raportów w przejrzysty sposób, stosując formatowanie walutowe dla kwot pieniężnych. Jest to świetna okazja do poćwiczenia metod takich jak Where(), Select(), Sum() oraz Max(). Finalnie system powinien podać ogólną sumę wpływów z mandatów zarejestrowanych w systemie.

Sugerowane kroki do wykonania
  1. Zdefiniuj klasę Mandat z odpowiednimi właściwościami (w tym miasto i kwota).
  2. Utwórz listę List<Mandat> i dodaj do niej 10 różnorodnych rekordów.
  3. Użyj LINQ Where(), aby odfiltrować mandaty z konkretnego miasta i powyżej pewnej kwoty.
  4. Wywołaj Sum(), aby obliczyć łączną kwotę kar w całej bazie.
  5. Zastosuj Max(m => m.Kwota) do odnalezienia najwyższej grzywny.
  6. Zastosuj OrderByDescending(), aby posortować mandaty od najbardziej dotkliwych punktowo.
  7. Wyświetl wyniki każdego z pytań analitycznych w oddzielnej sekcji konsoli.
  8. Użyj Any(), aby sprawdzić czy w bazie istnieje chociaż jeden kierowca o podanym nazwisku.
  9. Wypisz średnią wartość mandatu w systemie korzystając z metody Average().
  10. Opisz w sprawozdaniu, jak LINQ upraszcza operacje na zbiorach danych w porównaniu do pętli for.
D5.4
Magazyn Artykułów Papierniczych (Stack<T>)
Cel

Zapoznanie z działaniem stosu (LIFO – Last In, First Out) jako specyficznej formy kolekcji. Student uczy się modelować procesy, w których ostatnio dodany element jest pobierany jako pierwszy (np. układanie towaru w wysokich stosach).

Scenariusz

Zaprojektuj system zarządzania wysokim stosem materiałów w magazynie papirusów. Ze względu na budowę regałów, pracownicy mogą dokładać towar tylko na górę stosu i tylko z góry go zdejmować – idealnie odzwierciedla to struktura Stack<string>. Twoja aplikacja powinna oferować funkcję "Przyjmij towar" (Push), która kładzie nową ryzę papieru na szczyt stosu, oraz "Wydaj towar" (Pop), która pobiera element z samej góry. Dodatkowo musisz zaimplementować funkcję sprawdzenia, jaki towar znajduje się obecnie na wierzchu bez jego zdejmowania (Peek). Bardzo ważne jest zabezpieczenie programu przed próbą wydania towaru, gdy stos jest całkowicie pusty – musisz obsłużyć ten przypadek, sprawdzając właściwość Count lub stosując blok try-catch dla InvalidOperationException. Użytkownik w konsoli symuluje pracę magazyniera, wpisując nazwy przyjmowanych partii materiału. Wyświetlaj na bieżąco stan stosu, pokazując co jest aktualnie „pod ręką”. Zadanie to uczy rozumienia struktur pamięciowych i ich wpływu na logikę biznesową procesów logistycznych. Finalnie program powinien wyświetlić, ile pozycji pozostało w magazynie po serii wydań towaru.

Sugerowane kroki do wykonania
  1. Zadeklaruj kolekcję generyczną: Stack<string> stosArtykulow = new Stack<string>().
  2. Stwórz menu obsługi: 1-Dołóż, 2-Zdejmij, 3-Podgląd, 4-Koniec.
  3. Użyj Push(nazwa) do dodania nazwy artykułu na górę stosu.
  4. Użyj Pop() do pobrania i wyświetlenia elementu z wierzchu.
  5. Zastosuj instrukcję if, aby zweryfikować czy stos nie jest pusty przed wykonaniem Pop().
  6. Użyj Peek() do wyświetlenia nazwy przedmiotu na górze bez jego pobierania.
  7. Wypisz całą zawartość stosu (pamiętaj o kolejności wyświetlania w foreach dla stosu).
  8. Dodaj informację o liczbie elementów (Count) po każdej udanej operacji.
  9. Zasymuluj odłożenie 3 różnych książek na stos i zdejmij je wszystkie po kolei.
  10. Zaobserwuj w konsoli odwróconą kolejność zdejmowania względem kładzenia.
D5.5
Analityk Wyników Egzaminacyjnych (Agregacja LINQ)
Cel

Wykorzystanie zaawansowanych operatorów grupowania i selekcji LINQ do analizy jakościowej zbiorów danych. Student uczy się wyciągać wnioski statystyczne z surowych list obiektów o różnorodnych atrybutach.

Scenariusz

Zostałeś poproszony przez dziekanat o przygotowanie szybkiej analizy wyników sesji egzaminacyjnej. Posiadasz listę obiektów Student (pola: Imię, Nazwisko, Ocena, Przedmiot), zapisaną w List<Student>. Twoim celem jest użycie LINQ do wygenerowania raportu sukcesu dla poszczególnych przedmiotów. Musisz obliczyć średnią ocen z Matematyki, znaleźć studenta z najwyższą oceną z Informatyki oraz podać, ile osób łącznie zdało egzamin (ocena >= 3.0). Dodatkowo Twoim wyzwaniem jest użycie metody GroupBy(), aby pogrupować studentów według ocen i sprawdzić, która ocena pojawiała się najczęściej. Dzięki technologii LINQ wszystkie te skomplikowane operacje wykonasz szybko i przy minimalnej ilości kodu. Program w konsoli powinien wyświetlić przejrzyste zestawienie punktowe dla każdego przedmiotu oddzielnie. To zadanie uczy, jak w profesjonalny sposób przetwarzać dane edukacyjne i biznesowe w nowoczesnym środowisku programistycznym. Wykaż w sprawozdaniu, jak łatwo można zmienić kryteria analizy (np. liczenie średniej tylko dla kobiet), zmieniając jedynie warunek w zapytaniu .Where(). Program kończy pracę po wyświetleniu komunikatu o pomyślnej archiwizacji wyników. Jest to przykład praktycznego zastosowania C# w administracji i analityce.

Sugerowane kroki do wykonania
  1. Zdefiniuj klasę Student z właściwościami: Imie, Nazwisko, Ocena (double) oraz Przedmiot.
  2. Wypełnij List<Student> danymi dla 15 różnych osób i 3 różnych przedmiotów.
  3. Użyj Average(s => s.Ocena) po przefiltrowaniu (Where) dla konkretnego przedmiotu.
  4. Zastosuj metodę Max(s => s.Ocena) do odnalezienia rekordu sesji.
  5. Wywołaj Count() z warunkiem oceny pozytywnej (>= 3), aby policzyć zdawalność.
  6. Spróbuj użyć selekcji: Select(s => s.Nazwisko) do wypisania samej listy nazwisk osób promowanych.
  7. Zastosuj OrderBy() do posortowania wyników na końcowym raporcie.
  8. Wyświetl statystyki dla każdego przedmiotu z osobna w oddzielnych blokach tekstowych.
  9. Upewnij się, że formatowanie liczb zmiennoprzecinkowych używa dwóch miejsc po przecinku.
  10. Podsumuj moduł lekcyjny własnymi wnioskami o wydajności operacji na listach generycznych.