﻿class Produkt:
    """Klasa pomocnicza reprezentująca pojedynczy produkt w magazynie."""
    def __init__(self, nazwa: str, cena: float):
        self.nazwa = nazwa
        self.cena = cena
        
    def __str__(self):
        return f"{self.nazwa} (Cena: {self.cena})"

class Magazyn:
    """
    Klasa Magazyn integrująca protokół iteratora.
    Ukrywa wewnętrzną listę produktów, eksponując jedynie iterator (generator),
    z dołączoną logiką biznesową odfiltrowującą darmowe produkty.
    """
    def __init__(self):
        # Prywatna lista produktów, hermetyzacja danych
        self._produkty = []
        
    def dodaj(self, nazwa: str, cena: float):
        """Dodaje produkt do wewnętrznej kolekcji."""
        self._produkty.append(Produkt(nazwa, cena))
        
    def __len__(self):
        """Dopełnienie interfejsu kolekcji, umożliwiające szybkie sprawdzenie liczby elementów."""
        return len(self._produkty)
        
    def __iter__(self):
        """
        Metoda magiczna __iter__ zamieniona w generator za pomocą słowa yield.
        Implementuje logikę filtrowania (pomija produkty darmowe - cena <= 0)
        i zwraca sformatowany tekst opisu zamiast obiektu Produkt.
        """
        for produkt in self._produkty:
            if produkt.cena > 0: # Logika biznesowa - filtrujemy darmowe produkty
                # Zamiast pełnego obiektu, wydajemy sformatowany ciąg znaków
                yield f"Produkt: {produkt.nazwa}, Cena: {produkt.cena}"

if __name__ == "__main__":
    m = Magazyn()
    m.dodaj("Kawa", 25)
    m.dodaj("Cukier", 0)       # Produkt darmowy, powinien zostać odfiltrowany
    m.dodaj("Herbata", 15.50)
    m.dodaj("Kubek promocyjny", 0) # Darmowy, ominięty
    
    print(f"Wszystkich produktów w bazie (z darmowymi): {len(m)}")
    
    print("\nPrzegląd zawartości magazynu (w pętli for):")
    # Używamy bezpośrednio obiektu klasy Magazyn, niewołając jawnie listy
    for p in m:
        print(p)
        
    print("\nUżycie systemowej funkcji list() na magazynie:")
    # Python wywołuje __iter__ i gromadzi wszystkie wyemitowane przez yield wartości do listy
    lista_produktow = list(m)
    print(lista_produktow)
