﻿class Samochod:
    """
    Klasa reprezentująca pojazd z funkcjonalnością symulacji jazdy.
    Pokazuje zaawansowane użycie hermetyzacji (enkapsulacji) przez dekoratory @property.
    """
    def __init__(self, marka: str, model: str):
        self.marka = marka
        self.model = model
        # Używamy atrybutu prywatnego (_przebieg), do którego dostęp kontrolujemy 
        # poprzez dekorator @property (getter) i @przebieg.setter (setter).
        self._przebieg = 0

    # --- UŻYCIE DEKORATORA @property JAKO GETTERA ---
    # Dekorator ten pozwala nam odczytać ukryty atrybut _przebieg, udając, że to zwykłe pole.
    # W praktyce auto.przebieg wywoła tę metodę.
    @property
    def przebieg(self) -> int:
        """Zwraca aktualny przebieg samochodu."""
        return self._przebieg

    # --- UŻYCIE DEKORATORA SETTERA ---
    # Dekorator @nazwa_wlasciwosci.setter pozwala na kontrolowanie procesu przypisywania nowej wartości.
    # Zamiast pozwalać na np. auto.przebieg = -10, puszczamy przypisanie przez poniższą metodę.
    @przebieg.setter
    def przebieg(self, nowa_wartosc: int):
        """Ustawia nowy przebieg po uprzedniej walidacji."""
        if nowa_wartosc < self._przebieg:
            # W prawdziwej grze wyścigowej "cofanie licznika" powinno być zgłaszane jako błąd!
            raise ValueError("Błąd: Dystans (przebieg) nie może maleć ani być ujemny!")
        self._przebieg = nowa_wartosc

    def jedz(self, dystans: int):
        """
        Zwiększa całkowity dystans pokonany przez dany samochód.
        Wykorzystuje walidację, która zapobiega podawaniu nielogicznych, ujemnych dystansów.
        """
        if dystans > 0:
            # Poniższa operacja wywoła naszego settera @przebieg.setter z nową zsumowaną wartością!
            self.przebieg += dystans
        else:
            # Możemy zgłosić komunikat przez print zgodnie ze wskazówkami w zadaniu
            print("Błąd: Dystans nie może być ujemny!")

    def pokaz_przebieg(self):
        """Wypisuje sformatowaną informację o pojeździe i jego stanie licznika."""
        print(f"Pojazd {self.marka} {self.model} ma {self.przebieg} km przebiegu.")


if __name__ == "__main__":
    print("--- ZADANIE 02 ---")
    auto = Samochod("Toyota", "Corolla")
    
    # Próba jazdy
    auto.jedz(150)
    auto.jedz(50)
    auto.pokaz_przebieg()
    
    # Próba jazdy z ujemnym dystansem - wyświetli odpowiedni komunikat błędu z metody jedz()
    auto.jedz(-10)

    # Bezpośrednia próba przypisania ujemnej wartości
    # Nasz setter zabezpiecza stan obiektu przed nielegalną zmianą!
    print("\n[Eksperyment] Próba cofnięcia licznika przez przypisanie: auto.przebieg = 50")
    try:
        auto.przebieg = 50
    except ValueError as e:
        print(f"Wyjątek zatrzymany przez setter: {e}")
