# coding: cp852
import os,sys
from glob     import *

#=======================================================================================[ TloadCSV ]=======
class TloadCSV:
  '''Klasa wczytywania danych z CSV.'''
  _SEP=';'									# Domylnie sepatatorem jesy znak ";".
  _DATA={}									# Pojemnik na dane.
  _KFN=''									# (K)ey(F)ield(N)ame - nazwa pola kluczowwego.
  _ENCODING='cp852'								# Domylnie pliki s kodowane w OEM.


#------------------------------------ INIT -------------------------------------------
#---============================[ __init__ ]==========================================[]
  def __init__(self,FN,KFN,SEP=';',**P):
    '''Inicjacja z nazw pliku (FN), Nazw pola klucza (KFN) i ew. separatorem (SEP) - domylnie ";".
       P[CODE] - kodowanie pliku - domylnie "cp852" (OEM).'''
    self._DATA={}								# Przygotowuje pusty pojemnik na dane.
    self._KFN=KFN								# Zapamituje nazwe pola klucza.
    self._SEP=SEP								# Zapamituje separator.
    self._ENCODING=P.get('CODE','cp852')					# Pobiera kodowanie - domylnie OEM.
    self._loadDATA(FN)								# Z Pliku o nazwie (F)ile(N)ame aduje dane do pojemnika.

#------------------------------------ I/O -------------------------------------------
#---============================[ _loadDATA ]==========================================[]
  def _loadDATA(self,FN):
    '''Z pliku o nazwi e(F)ile(N)ame aduje dane do pojemnika. adowanie wg pola klucza (K)ey(F)ield(N)ame, Jeli plik lub pole nie istnieje RAISE.'''
    if not os.path.isfile(FN):							# Jeli nie ma danego pliku.
      raise Exception(f'Nie znaleziono pliku o nazwie "{FN}"!')			          #!!! BULBA !!!
    with open(FN,encoding=self._ENCODING) as F: 				# Otwiera plik o nazwi eFN z kodowaniem wlocie na odpowiedni kod.
      for i,A in enumerate([l.strip('\n\r').split(self._SEP) for l in F.readlines()]): # Pobiera kolejne linie i po oczyszczeniu ze znakw kocw linii dzieli je wg znaku SEP na listy danych. Numeruje wczytane linie.
        if i==0:								# Pierwsza linia pliku - powinna zawiera nagwki pl.
          N=A									# Zapamituje nagwki jako N.
          if not self._KFN in N:						# Jelinie ma pola klucza pord pl nagwka.
            print(f'{N=}')
            raise Exception(f'W pliku "{FN}" nie znaleziono pola o nazwie "{self._KFN}"!') #!!! BULBA !!!
        else:									# Kolejn linia - linia danych.
          R=dict(zip(N,A))							# Tworzy record przez potraktowanie jako sownika(dict) listy par: (PoleNagwka,PoleDanych)- (zip).
          K=R[self._KFN]							# Pobiera zawarto pola klucza.
          self._DATA[K]=R							# Zapamituje record pod kluczem K. !!! Moe zamazywa inne rekordy o takim samym kluczu!!!

#------------------------------------ TECH -------------------------------------------
#---============================[ COUNT ]==========================================[]
  def COUNT(self):		
    '''Zwraca ilo rekordow w pojemniku.'''
    return len(self._DATA)

#------------------------------------ ACCESS -------------------------------------------
#---============================[ FIELDS ]==========================================[]
  def FIELDS(self):
    '''Zwraca nazwy pl.'''
    if not self._DATA:                         					# Nie ma adnych danych.
      raise Exception(f'Brak wczytanych danych!')				          #!!! BULBA !!!
    for f in self._DATA[0]:							# Nazwy pl s we wszystkich rekordach (wic bierze "pierwszy z brzegu"). Dla wszystkich nazw pl		
      yield f									# Zwraca nazw ze wznawianiem.
#---============================[ KEYS ]==========================================[]
  def KEYS(self):
    '''Zwraca klucze danych.'''
    return [k for k in self._DATA]						# Zwraca list kluczy.
    	
#---============================[ __contains__ ]==========================================[]
  def __contains__(self,N):
    '''Zwraca informaj, czy w pojemniku jest rekord o kluczu N.'''
    return N in self._DATA							# W prostym znaczeniu.

#---============================[ __iter__ ]==========================================[]
  def __iter__(self):
    '''Zwraca kolejne klucze z pojemnika.'''
    for k in self.DATA:								# Dla kolejnych kuczy. 
      yield k									# Zwraca je - ze wznawianiem.

#---============================[ __getitem__ ]==========================================[]
  def __getitem__(self,k):
    '''Pobranie rekordu dla klucza Klunb w przypadkiu podania klucz i nazwy pola - pola z takiego rekordu.'''
    F=None									# Zakada, e nie bdzie pobierapola, lecz rekord.
    if type(k)==tuple:								# Podano wicej elementw identyfikujcych.
      if len(k)!=2:								# Dopuszczalne s tylko dwa elemanty: klucz, nazwa pola. 
        raise Exception(f'Mona pobiera dane caego recordu - podajc jego kucz lub pola rekordyu podajc jego nazw. Zadano podania danych <{k}>!')          #!!! BULBA !!!
      (k,F)=k      								# Rozkada krotke na klucz(waciwy) i nazw pola.
    if not k in self._DATA:							# Nie ma podanego klucza w pojemniku danych.
      raise Exception(f'Wrd rekordw brak rekordu o kluczu "{k}"!')		          #!!! BULBA !!!
    R=self._DATA[k]								# Pobiera rekord o podanym kluczu.
    if F and not F in R:							# Nie ma pola o podanej nazwie w rekordzie.
      raise Exception(f'Wrd pl rekordw brak pola o nazzwie "{F}"!')		          #!!! BULBA !!!
    if not F:									# Nie ma dania pobrania wartoci pola.
      return R									# Zwraca record.
    return R[F]									# Zwraca wskazane pole recordu.



#---============================[ __name__ ]==========================================[]
if __name__=="__main__":
  DB=TloadCSV('TOWARY.dat','Nazwa','\t')
  for k  in sorted(DB.KEYS()):
    print(f'{k} => {DB[k]}')
  k='liwka'
  print(f"{k}->{DB[k,'Cena']}")



	  
		