Spis zadań w tym module

  1. Licznik populacji pracowników (Atrybuty klasy)
  2. Fabryka dat z formatu tekstowego (@classmethod)
  3. Walidator dokumentów tożsamości (@staticmethod)
  4. Centralny system konfiguracji (Zarządzanie stanem klasy)
  5. Uniwersalny konwerter jednostek IT (Klasa narzędziowa)

1. Atrybuty instancji vs Atrybuty klasy

Atrybuty instancji są unikalne dla każdego obiektu (np. imię pracownika). Atrybuty klasy są definiowane bezpośrednio wewnątrz bloku class i są dzielone przez wszystkie instancje. Zmiana atrybutu klasy wpływa na wszystkie obiekty, które go używają, co jest idealne do przechowywania stałych lub liczników.

2. Zliczanie obiektów

Najczęstszym zastosowaniem atrybutów klasy jest monitorowanie liczby stworzonych instancji. Robimy to poprzez modyfikację zmiennej klasowej wewnątrz konstruktora __init__.

01
Licznik populacji pracowników (Atrybuty klasy)
Czego student się nauczy

Deklarowania atrybutów klasy, rozróżniania dostępu przez self i nazwę klasy oraz implementacji globalnego licznika instancji.

Scenariusz

Jako kierownik działu IT w dynamicznie rozwijającej się korporacji, musisz przygotować narzędzie do monitorowania zasobów ludzkich. Firma zatrudnia setki osób w różnych oddziałach, dlatego kluczowe jest posiadanie globalnego licznika wszystkich aktywnych etatów. Twoim zadaniem jest stworzenie klasy, która przy każdym wywołaniu konstruktora automatycznie zaktualizuje wspólną zmienną przechowywaną na poziomie definicji klasy. Takie rozwiązanie pozwoli na błyskawiczne sprawdzenie aktualnej liczebności załogi bez konieczności ręcznego przeszukiwania bazy danych czy list obiektów. Musisz zadbać o to, aby dostęp do licznika był ujednolicony i odbywał się poprzez dedykowaną metodę informacyjną. Dzięki temu unikniesz błędów związanych z przypadkowym nadpisaniem wartości przez pojedyncze instancje pracowników. Gotowy moduł będzie stanowił podstawę dla systemu kadrowego, ułatwiając planowanie budżetu i rekrutacji na kolejne kwartały.

Wymagania techniczne
  • Zdefiniuj klasę Pracownik posiadającą wspólny dla wszystkich instancji atrybut klasy licznik.
  • Zainicjalizuj wartość licznik na poziomie 0 bezpośrednio w ciele klasy.
  • Opracuj konstruktor __init__ przyjmujący dane personalne pracownika (imię i nazwisko).
  • Zaimplementuj mechanizm automatycznego zwiększania wartości Pracownik.licznik przy każdym utworzeniu nowego obiektu.
  • Stwórz metodę klasy @classmethod o nazwie wyswietl_liczbe_pracownikow() do odczytu stanu licznika.
  • Upewnij się, że metoda poprawnie odwołuje się do atrybutu klasy poprzez parametr cls.
  • Wyświetl sformatowany komunikat informujący o aktualnej liczbie zarejestrowanych pracowników.
  • Przetestuj działanie licznika, tworząc kilka obiektów i sprawdzając wynik przed oraz po ich dodaniu.
Wskazówki wykonania
  • Zadeklaruj zmienną licznik = 0 bezpośrednio pod nagłówkiem class Pracownik:.
  • Odwołuj się do niej wewnątrz konstruktora za pomocą pełnej nazwy klasy: Pracownik.licznik += 1.
  • Unikaj używania self.licznik do inkrementacji, aby nie stworzyć lokalnej kopii atrybutu dla każdego obiektu.
  • Dekorator @classmethod umieść bezpośrednio nad definicją metody wyświetlającej.
  • Pamiętaj, że pierwszym argumentem metody klasowej jest cls, a nie self.
  • Wewnątrz metody klasowej pobierz wartość za pomocą cls.licznik.
  • Do wyświetlania informacji użyj funkcji print() z czytelnym opisem stanu.
  • Przetestuj działanie, wywołując metodę Pracownik.wyswietl_liczbe_pracownikow() przed stworzeniem obiektu.
  • Stwórz dwa obiekty i ponownie sprawdź stan licznika, aby potwierdzić jego poprawną aktualizację.
  • Pamiętaj o zachowaniu wcięć charakterystycznych dla definicji metod wewnątrz klasy.
Przykładowy ekran
>>> p1 = Pracownik("Jan", "Kowalski") >>> p2 = Pracownik("Anna", "Nowak") >>> Pracownik.wyswietl_liczbe_pracownikow() Aktualna liczba pracowników: 2
Wnioski do opracowania
  • Wyjaśnij kluczową różnicę w zachowaniu atrybutu klasy (wspólny dla wszystkich) a atrybutu instancji (unikalny).
  • Opisz mechanizm przesłaniania (shadowing) w sytuacji użycia self.licznik += 1 zamiast Pracownik.licznik.
  • Omów zalety stosowania @classmethod do bezpiecznego odczytu stanu współdzielonego przez wszystkie obiekty.
  • Przeanalizuj, co dzieje się z licznikiem w pamięci podczas usuwania obiektów (brak automatycznej dekrementacji).
  • Zastanów się, jak zaimplementować mechanizm zmniejszania licznika przy niszczeniu obiektu za pomocą metody __del__.
  • Wnioskuj o bezpieczeństwie danych przy bezpośrednim dostępie do zmiennej klasowej z zewnątrz bez metod pośredniczących.
  • Porównaj użycie zmiennej klasowej do monitorowania zasobów z trzymaniem tych samych danych w zewnętrznej liście.
  • Opisz znaczenie parametru cls jako dynamicznego odniesienia do aktualnej klasy, na której wywołano metodę.
  • Sprawdź eksperymentalnie, czy ręczna zmiana Pracownik.licznik = 100 wpłynie na nowo tworzone instancje pracowników.

Rozwiązanie

3. Metody klasowe (@classmethod)

Metody te są oznaczone dekoratorem @classmethod. Zamiast self, ich pierwszym parametrem jest cls, reprezentujący samą klasę. Używamy ich głównie do tworzenia alternatywnych konstruktorów (fabryk).

02
Fabryka dat z formatu tekstowego (@classmethod)
Czego student się nauczy

Wykorzystywania metod klasowych jako alternatywnych sposobów tworzenia obiektów oraz pracy z parametrem cls.

Scenariusz

Pracujesz nad integracją dwóch systemów informatycznych, które wymieniają dane o terminach ważności umów w różnych formatach. Jeden z systemów przesyła daty jako tradycyjne zestawy liczb, natomiast drugi generuje surowe ciągi znaków oddzielone myślnikami. Twoim celem jest stworzenie elastycznej klasy kalendarza, która poradzi sobie z obydwoma sposobami inicjalizacji danych. Wykorzystaj metodę klasową, aby stworzyć tak zwaną fabrykę, zdolną do samodzielnego przetworzenia napisu na pełnoprawny obiekt daty. Mechanizm ten musi sprawnie podzielić tekst, wyodrębnić z niego dzień, miesiąc oraz rok, a następnie zwrócić poprawnie skonfigurowaną instancję. Dzięki takiemu podejściu, Twój kod stanie się bardziej odporny na zmiany w specyfikacji protokołów komunikacyjnych i znacznie łatwiejszy w obsłudze. Gotowa klasa powinna również umożliwiać estetyczną prezentację daty w formie zrozumiałej dla użytkownika końcowego.

Wymagania techniczne
  • Stwórz klasę MojaData z klasycznym konstruktorem przyjmującym trzy liczby całkowite: dzień, miesiąc i rok.
  • Zaimplementuj metodę klasową @classmethod o nazwie z_stringa() służącą jako alternatywny konstruktor.
  • Dodaj logikę dzielenia (parsowania) ciągu znaków wejściowego przy użyciu separatora (np. myślnika).
  • Przekonwertuj wyodrębnione fragmenty tekstu na liczby całkowite przed przekazaniem ich do konstruktora.
  • Wykorzystaj parametr cls(...) do zwrócenia nowej, poprawnie zainicjalizowanej instancji klasy.
  • Opracuj metodę instancji prezentuj() do czytelnego wyświetlania daty w formacie tekstowym.
  • Dodaj wewnątrz metody prezentuj() słowne nazwy miesięcy dla poprawy estetyki wyjścia.
  • Zademonstruj użycie obu sposobów tworzenia obiektów daty i porównaj ich reprezentację w konsoli.
Wskazówki wykonania
  • Konstruktor __init__ powinien przyjmować trzy standardowe argumenty: dzien, miesiac, rok.
  • Metodę klasową oznacz dekoratorem @classmethod, aby miała dostęp do obiektu klasy przez parametr cls.
  • Jako argument metody z_stringa przyjmij jeden parametr typu tekstowego (np. data_str).
  • Wykorzystaj wbudowaną metodę tekstową split('-'), aby rozbić ciąg znaków na listę fragmentów.
  • Pamiętaj o konwersji typów – dane z split() są napisami, użyj int(), aby zamienić je na liczby.
  • Możesz wykorzystać rozpakowywanie list: d, m, r = [int(x) for x in lista_fragmentow].
  • Metoda musi kończyć się instrukcją return cls(d, m, r), co wywoła standardowy konstruktor klasy.
  • W metodzie prezentuj() użyj słownika lub listy do mapowania numeru miesiąca na jego polską nazwę.
  • Sprawdź działanie fabryki poprzez wywołanie: MojaData.z_stringa("10-12-2024").
  • Upewnij się, że zwracany obiekt ma wszystkie atrybuty instancji zainicjalizowane poprawnie.
Przykładowy ekran
>>> d1 = MojaData(1, 1, 2024) >>> d2 = MojaData.z_stringa("15-05-2026") >>> d2.prezentuj() Data: 15 maja 2026 roku
Wnioski do opracowania
  • Wyjaśnij koncepcję "alternatywnego konstruktora" w kontekście zastosowania metod klasowych z dekoratorem @classmethod.
  • Opisz proces techniczny parsowania tekstu za pomocą split() i konwersji typów jako fundamentu działania fabryki.
  • Omów zalety użycia cls(...) zamiast sztywnej nazwy klasy MojaData(...) w kontekście dziedziczenia klas.
  • Przeanalizuj, jak fabryka obiektów upraszcza kod klienta, który otrzymuje dane w niejednolitych formatach (np. JSON czy CSV).
  • Zastanów się i zaproponuj, jak obsłużyć błędy w metodzie z_stringa, gdy wejściowy tekst ma nieprawidłowy format.
  • Wnioskuj o przydatności struktur danych (np. słowników) do mapowania numerów miesięcy na ich nazwy w metodach prezentacji.
  • Porównaj czytelność i czystość kodu przy tworzeniu daty standardowo oraz poprzez dedykowaną fabrykę tekstową.
  • Opisz rolę instrukcji return w przekazywaniu nowo stworzonej instancji klasy do kodu wywołującego metodę fabryczną.
  • Sprawdź, czy obiekt stworzony przez fabrykę posiada pełny dostęp do wszystkich metod instancyjnych i atrybutów klasy.

Rozwiązanie

4. Metody statyczne (@staticmethod)

Metody statyczne nie potrzebują dostępu do danych klasy ani instancji. Są to funkcje pomocnicze, które logicznie należą do klasy (np. walidatory, konwertery), ale działają niezależnie.

03
Walidator dokumentów tożsamości (@staticmethod)
Czego student się nauczy

Tworzenia metod statycznych i rozumienia ich roli jako niezależnych narzędzi zamkniętych wewnątrz przestrzeni nazw klasy.

Scenariusz

W ramach budowy bezpiecznego systemu rejestracji klientów bankowych, musisz zaimplementować mechanizm wstępnej weryfikacji tożsamości. Jednym z kluczowych elementów jest sprawdzenie poprawności numeru PESEL, zanim jakiekolwiek dane zostaną trwale zapisane w pamięci serwera. Ponieważ reguły walidacji numeru identyfikacyjnego są uniwersalne i nie zależą od stanu konkretnego obiektu, idealnym rozwiązaniem będzie zastosowanie metody statycznej. Metoda ta powinna działać jako niezależny ekspert, oceniający czy podany ciąg znaków spełnia wymogi formalne, takie jak odpowiednia długość i obecność wyłącznie cyfr. Twoja klasa powinna automatycznie korzystać z tego narzędzia podczas tworzenia każdej nowej instancji klienta, blokując próby wprowadzenia błędnych informacji. Takie podejście gwarantuje wysoką jakość danych w systemie i zapobiega powstawaniu konfliktów w bazach danych. Dzięki izolacji logiki sprawdzającej, będziesz mógł łatwo aktualizować zasady weryfikacji w przyszłości, nie zmieniając przy tym struktury samej klasy.

Wymagania techniczne
  • Zdefiniuj klasę Klient przechowującą dane osobowe oraz unikalny numer identyfikacyjny PESEL.
  • Zaimplementuj metodę statyczną @staticmethod o nazwie czy_poprawny_pesel() do weryfikacji formalnej.
  • Sprawdź wewnątrz walidatora, czy podany ciąg znaków składa się wyłącznie z cyfr za pomocą isdigit().
  • Dodaj warunek weryfikujący poprawną długość numeru PESEL, która musi wynosić dokładnie 11 znaków.
  • Zwróć wartość logiczną (True lub False) jako wynik działania metody statycznej.
  • Wykorzystaj walidator wewnątrz konstruktora __init__ do wstępnego sprawdzenia danych klienta.
  • Przerwij proces tworzenia obiektu i wyświetl komunikat błędu, jeśli walidacja PESEL zakończy się niepowodzeniem.
  • Przetestuj system, próbując utworzyć klienta z poprawnym oraz celowo błędnym numerem identyfikacyjnym.
Wskazówki wykonania
  • Metody statyczne oznaczaj dekoratorem @staticmethod; nie przyjmują one parametrów self ani cls.
  • Metoda czy_poprawny_pesel(pesel) powinna zwracać typ logiczny bool (True/False).
  • Wykorzystaj len(pesel) == 11 jako pierwszy, podstawowy warunek poprawności numeru.
  • Drugim warunkiem powinno być pesel.isdigit(), co sprawdzi obecność wyłącznie cyfr w ciągu.
  • W konstruktorze __init__ użyj instrukcji if do wywołania walidatora przed przypisaniem danych do self.
  • Wywołaj metodę statyczną poprzez nazwę klasy: Klient.czy_poprawny_pesel(pesel).
  • Jeśli walidacja zwróci False, wyświetl błąd i przerwij dalsze operacje w konstruktorze.
  • Możesz rzucić wyjątek lub po prostu ustawić atrybuty na wartości puste (dla uproszczenia użyj print).
  • Przetestuj walidator samodzielnie wywołaniem: print(Klient.czy_poprawny_pesel("123")).
  • Upewnij się, że metoda statyczna nie próbuje odwoływać się do żadnych atrybutów instancji self.
Przykładowy ekran
>>> Klient.czy_poprawny_pesel("12345678901") True >>> k1 = Klient("Jan", "123") Błąd: Niepoprawny numer PESEL!
Wnioski do opracowania
  • Wyjaśnij kryteria decyzyjne: kiedy metoda powinna być statyczna (@staticmethod) zamiast klasowej lub instancyjnej.
  • Opisz całkowity brak powiązania metody statycznej ze stanem konkretnego obiektu (brak dostępu do self i cls).
  • Omów korzyści z grupowania funkcji walidacyjnych wewnątrz klasy tematycznej zamiast stosowania luźnych funkcji w module.
  • Przeanalizuj sposób bezpiecznego wywoływania walidatora wewnątrz __init__ jeszcze przed faktycznym przypisaniem atrybutów.
  • Zastanów się nad scenariuszem współdzielenia walidatora PESEL między zupełnie różnymi klasami w tym samym systemie.
  • Wnioskuj o poprawie czytelności kodu, w którym walidacja formatu danych jest odizolowana od logiki biznesowej samej klasy.
  • Porównaj techniczne różnice między metodami statycznymi a klasowymi – kiedy jedna z nich jest obiektywnie lepszym wyborem?
  • Opisz, jak metoda statyczna ułatwia przeprowadzanie testów jednostkowych (unit testing) bez konieczności tworzenia instancji.
  • Sprawdź, jakie błędy wystąpią, gdy spróbujesz odwołać się do self wewnątrz metody oznaczonej jako @staticmethod.

Rozwiązanie

5. Przestrzeń nazw (Namespace)

Python szuka atrybutów w określonej kolejności: najpierw w obiekcie, potem w klasie, a na końcu w klasach nadrzędnych. Zrozumienie tej hierarchii pozwala na świadome zarządzanie danymi.

6. Wykorzystanie cls w fabrykach

Użycie cls zamiast nazwy klasy sprawia, że metody klasowe są bezpieczne przy dziedziczeniu – zawsze stworzą obiekt tej klasy, na której zostały wywołane.

04
Centralny system konfiguracji (Zarządzanie stanem klasy)
Czego student się nauczy

Zarządzania globalnymi ustawieniami aplikacji za pomocą atrybutów klasy oraz modyfikowania ich przez dedykowane metody klasowe.

Scenariusz

Wyobraź sobie, że tworzysz skomplikowaną aplikację wielomodułową, która musi zachowywać spójne ustawienia we wszystkich swoich częściach składowych. Kluczowe parametry, takie jak wersja oprogramowania czy tryb diagnostyczny, powinny być zdefiniowane w jednym, centralnym punkcie dostępu. Twoim zadaniem jest opracowanie klasy konfiguracyjnej, która będzie zarządzać tymi danymi bez konieczności tworzenia jej licznych instancji. Wykorzystaj atrybuty i metody klasowe, aby umożliwić globalną zmianę ustawień, która zostanie natychmiast odnotowana przez wszystkie moduły systemu. Takie rozwiązanie eliminuje ryzyko niespójności danych, które często pojawia się przy stosowaniu rozproszonych zmiennych globalnych. Musisz zapewnić bezpieczny interfejs do modyfikacji trybu pracy aplikacji, aby programiści mogli łatwo przełączać się między środowiskiem testowym a produkcyjnym. Dzięki temu zyskasz pełną kontrolę nad zachowaniem aplikacji i ułatwisz jej późniejszą konserwację oraz rozwój o nowe funkcjonalności.

Wymagania techniczne
  • Opracuj klasę Config działającą jako centralny punkt zarządzania ustawieniami Twojej aplikacji.
  • Zdefiniuj atrybuty klasy version oraz debug_mode reprezentujące globalny stan systemu.
  • Zaimplementuj metodę klasową @classmethod o nazwie set_debug() do modyfikacji trybu pracy.
  • Upewnij się, że zmiana atrybutu klasy wpływa na cały system bez konieczności tworzenia obiektów.
  • Stwórz metodę klasową get_info() generującą podsumowanie aktualnych parametrów konfiguracyjnych.
  • Wykorzystaj parametr cls do bezpiecznego dostępu do danych na poziomie definicji klasy.
  • Przeprowadź test zmiany ustawień, wywołując metody bezpośrednio z nazwy klasy (bez instancji).
  • Wyświetl raport końcowy potwierdzający poprawną aktualizację wersji i trybu diagnostycznego.
Wskazówki wykonania
  • Zdefiniuj Config jako klasę, która nie wymaga wywoływania Config() (tworzenia instancji).
  • Atrybuty klasy version = "1.0" oraz debug_mode = False umieść na samym początku definicji klasy.
  • Metoda set_debug(cls, status) powinna być oznaczona jako @classmethod.
  • Wewnątrz set_debug wykonaj bezpośrednie przypisanie nowej wartości: cls.debug_mode = status.
  • Metoda get_info(cls) powinna drukować aktualny stan wszystkich parametrów systemowych.
  • Odwołuj się do danych wyłącznie przez parametr cls, co zapewni spójność przy ewentualnym dziedziczeniu.
  • Przetestuj działanie, zmieniając tryb debugowania i sprawdzając, czy informacja została zaktualizowana globalnie.
  • Spróbuj odczytać wartość Config.version bez tworzenia jakiegokolwiek obiektu tej klasy.
  • Pamiętaj, że metody klasowe są idealne do operacji, które dotyczą całej kategorii obiektów.
  • Unikaj używania metod statycznych tam, gdzie potrzebujesz zmodyfikować lub odczytać wspólny stan klasy.
Przykładowy ekran
>>> Config.get_info() Wersja: 1.0, Debug: False >>> Config.set_debug(True) >>> Config.get_info() Wersja: 1.0, Debug: True
Wnioski do opracowania
  • Wyjaśnij, dlaczego centralna klasa z atrybutami statycznymi jest bezpieczniejszym rozwiązaniem niż zestaw rozproszonych zmiennych globalnych.
  • Opisz, w jaki sposób zmiana cls.debug_mode natychmiast wpływa na zachowanie wszystkich części systemu korzystających z tego pola.
  • Omów znaczenie stosowania metod klasowych do kontrolowanego i autoryzowanego modyfikowania globalnego stanu aplikacji.
  • Przeanalizuj scenariusz dziedziczenia klasy Config – czy podklasa powinna współdzielić ustawienia, czy posiadać własną kopię?
  • Zastanów się, jak można by zabezpieczyć krytyczne atrybuty konfiguracyjne przed przypadkowym usunięciem w czasie pracy programu.
  • Wnioskuj o przydatności posiadania jednego "źródła prawdy" dla konfiguracji w dużych i skomplikowanych systemach informatycznych.
  • Porównaj bezpośredni odczyt danych z klasy (np. Config.version) do tworzenia niepotrzebnego obiektu-pośrednika.
  • Opisz rolę metody get_info() jako uniwersalnego narzędzia raportującego o aktualnym stanie środowiska wykonawczego.
  • Sprawdź, czy ustawienia zmienione w jednym module kodu są natychmiastowo widoczne w innych modułach importujących tę samą klasę.

Rozwiązanie

7. Klasy narzędziowe

Czasami klasa służy jedynie jako kontener na powiązane tematycznie funkcje (metody statyczne). Nie tworzymy wtedy instancji takiej klasy.

8. Uważaj na atrybuty mutowalne

Atrybuty klasy będące listami lub słownikami są zdradliwe – dodanie elementu do listy klasowej przez jeden obiekt spowoduje zmianę widoczną dla wszystkich!

9. Kolejność wyszukiwania (MRO)

Python najpierw patrzy na słownik __dict__ obiektu. Jeśli tam nie ma klucza, zagląda do __dict__ klasy. To dlatego atrybuty klasy są "widoczne" przez instancję.

10. Podsumowanie poziomu Klasy

Nauczyłeś się zarządzać danymi wspólnymi dla wszystkich obiektów. Wiesz już, jak tworzyć inteligentne fabryki obiektów i jak izolować logikę pomocniczą w metodach statycznych. To fundament pod zaawansowane wzorce projektowe.

05
Uniwersalny konwerter jednostek IT (Klasa narzędziowa)
Czego student się nauczy

Budowania czystych klas narzędziowych opartych wyłącznie na metodach statycznych oraz formatowania danych wyjściowych.

Scenariusz

Jako inżynier zajmujący się optymalizacją zasobów w centrum danych, codziennie stajesz przed wyzwaniem przeliczania ogromnych ilości bajtów na bardziej czytelne jednostki. Ręczne wykonywanie takich obliczeń jest żmudne i podatne na błędy, dlatego postanowiłeś stworzyć profesjonalną bibliotekę narzędziową. Twoja klasa powinna pełnić rolę kontenera na zestaw metod statycznych, które w sposób ujednolicony obsłużą konwersję między gigabajtami a megabajtami. Kluczowym elementem projektu jest inteligentna funkcja formatująca, która samodzielnie dobierze najbardziej odpowiednią jednostkę miary na podstawie wielkości podanej w bajtach. Musisz pamiętać o zachowaniu standardów informatycznych, gdzie jeden kilobajt odpowiada tysiącu dwudziestu czterem bajtom. Precyzja wyników jest istotna, dlatego zadbaj o odpowiednie zaokrąglanie wartości po przecinku przed ich wyświetleniem. Gotowy konwerter będzie doskonałym przykładem klasy narzędziowej, która nie wymaga tworzenia obiektów do poprawnego działania.

Wymagania techniczne
  • Stwórz klasę narzędziową ITConverter służącą wyłącznie do operacji na jednostkach pamięci.
  • Zaimplementuj metodę statyczną @staticmethod o nazwie to_gb() przeliczającą bajty na gigabajty.
  • Dodaj metodę statyczną to_mb() do szybkiej konwersji rozmiaru danych na megabajty.
  • Przyjmij w obliczeniach standard binarny, gdzie jeden kilobajt równa się dokładnie 1024 bajtom.
  • Opracuj inteligentną metodę format_size(), która automatycznie dobiera jednostkę (B, KB, MB, GB).
  • Zastosuj zaokrąglanie wyników do dwóch miejsc po przecinku dla zachowania czytelności raportów.
  • Zabezpiecz metody przed obsługą wartości ujemnych, zwracając stosowny komunikat o błędzie.
  • Przetestuj działanie konwertera na różnych wielkościach plików, wywołując metody statyczne bez tworzenia obiektów.
Wskazówki wykonania
  • Wszystkie metody w klasie ITConverter powinny być statyczne (użyj dekoratora @staticmethod).
  • Metoda to_gb(bajty) powinna dzielić wartość przez 1024**3 w celu konwersji na gigabajty.
  • Metoda to_mb(bajty) powinna dzielić wartość przez 1024**2 w celu uzyskania megabajtów.
  • Wyniki operacji matematycznych zaokrąglaj za pomocą wbudowanej funkcji round(wynik, 2).
  • W metodzie format_size(bajty) zastosuj serię instrukcji if/elif, aby wybrać najczytelniejszą jednostkę.
  • Zacznij sprawdzanie od największych jednostek (GB), potem MB, KB i na końcu surowe bajty.
  • Do każdej zwracanej wartości liczbowej doklej odpowiedni symbol jednostki tekstowej (np. " GB").
  • Dodaj prostą walidację na początku metod: if bajty < 0: return "Błąd danych".
  • Wywołuj metody bezpośrednio z klasy narzędziowej: ITConverter.to_gb(5000000000).
  • Zwróć uwagę, że klasa narzędziowa pomaga utrzymać porządek w kodzie poprzez grupowanie funkcji tematycznych.
Przykładowy ekran
>>> ITConverter.to_mb(1048576) 1.0 MB >>> ITConverter.format_size(1500) 1.46 KB
Wnioski do opracowania
  • Wyjaśnij cel projektowania klas, których intencjonalnie nie zamierzamy nigdy instancjonować (tzw. klasy narzędziowe / utility classes).
  • Opisz logikę metody format_size jako zestawu reguł decyzyjnych służących do optymalizacji prezentacji danych numerycznych.
  • Omów znaczenie zachowania precyzji matematycznej (użycie potęg liczby 1024) w obliczeniach profesjonalnych systemów pamięci.
  • Przeanalizuj zalety stosowania @staticmethod w czystych narzędziach matematycznych, statystycznych i konwerterach jednostek.
  • Zaproponuj kierunki rozbudowy konwertera o obsługę większych jednostek, takich jak terabajty (TB) czy petabajty (PB).
  • Wnioskuj o poprawie czytelności kodu, w którym nazwa klasy ITConverter pełni rolę logicznej przestrzeni nazw (namespace).
  • Porównaj wydajność wywołań metod statycznych do metod instancyjnych (brak narzutu związanego z alokacją pamięci dla obiektu).
  • Opisz znaczenie rygorystycznej walidacji wartości wejściowych, szczególnie w kontekście blokowania ujemnych rozmiarów danych.
  • Sprawdź, czy zaokrąglanie wyników do dwóch miejsc po przecinku zapewnia wystarczającą dokładność dla bardzo małych plików.

Rozwiązanie