﻿class Koszyk:
    """
    Klasa reprezentująca koszyk sklepowy zachowująca się jak wbudowana kolekcja.
    Demonstruje użycie protokołów kolekcji: len() oraz operatora 'in'.
    """
    def __init__(self):
        # Enkapsulacja: chronimy wewnętrzną listę produktów 
        # i umożliwiamy interakcję tylko poprzez określone metody.
        self._produkty = []

    def dodaj_produkt(self, produkt: str) -> None:
        """
        Dodaje nazwę produktu do wewnątrznego pojemnika.
        """
        self._produkty.append(produkt)

    def __len__(self) -> int:
        """
        Metoda wywoływana przy użyciu funkcji len(koszyk).
        Zwraca rozmiar kolekcji. Kiedy długość wynosi 0, instrukcje warunkowe
        zinterpretują to jako wartość logiczną False.
        """
        return len(self._produkty)

    def __contains__(self, item: str) -> bool:
        """
        Odpowiada za poprawne i logiczne działanie operatora przynależności 'in' 
        (np. 'Mleko' in koszyk). 
        Implementacja czyni wyszukiwanie niewrażliwym na wielkość liter.
        """
        if not isinstance(item, str):
            return False
            
        szukany = item.lower()
        # Iterujemy i sprawdzamy przy użyciu małych liter
        for p in self._produkty:
            if p.lower() == szukany:
                return True
        return False

    def __str__(self) -> str:
        """
        Generuje przyjazne i czytelne zestawienie kupionych artykułów.
        """
        if not self._produkty:
            return "Koszyk jest całkowicie pusty."
        
        # Wykorzystujemy len(self) by użyć przeciążonego przed chwilą operatora __len__
        opis = f"Twój koszyk zawiera {len(self)} produktów:\n"
        for i, produkt in enumerate(self._produkty, start=1):
            opis += f"  {i}. {produkt}\n"
        return opis.strip()

if __name__ == "__main__":
    k = Koszyk()
    
    print("--- Weryfikacja wartości logicznej koszyka (False gdy len == 0) ---")
    if not k:
        print("Test: Prawidłowo wykryto pusty koszyk bez używania innej metody.")

    print("\n--- Wypełnianie koszyka ---")
    k.dodaj_produkt("Mleko")
    k.dodaj_produkt("Chleb wieloziarnisty")
    k.dodaj_produkt("Masło")
    
    print(k)
    
    print("\n--- Testowanie protokołu __len__ ---")
    print(f"Wynik len(k): {len(k)}")

    print("\n--- Testowanie protokołu __contains__ ('in') ---")
    print("Mleko in k        :", "Mleko" in k)  # Powinno być True
    print("mleko in k        :", "mleko" in k)  # Powinno być True (wielkość znaków niewrażliwa)
    print("Cukier in k       :", "Cukier" in k) # Powinno być False
    
    # Przykładowa instrukcja warunkowa
    towar = "chleb wieloziarnisty"
    if towar in k:
        print(f"\nSuper, {towar.capitalize()} już jest na Twojej liście.")
