1    # Takze, uz je to dlouho, zopakujeme co jsme vlastne delali:
   2    
   3    # Prvni ukol je nejjednoduzsi. Napsat funkci, ktera vrati True pokud dany prvek
   4    # se v seznamu vyskytuje vice nez 1x, jinak vrati False:
   5    
   6    def isMultipleItem(seznam,prvek):
   7      """ Vrati True, jestlize se prvek v seznamu vyskytuje alespon 2x, jinak vrati False."""
   8      pocet=0 # tady si pamatujeme kolikrat jsme uz prvek nalezli 
   9      for p in seznam: # ted projedeme vsechny prvky v seznamu
  10        if (p==prvek): # jestli je aktualni prvek stejny jako hledany prvek
  11          pocet=pocet+1 # tak vime ze jsme ho nasli o jednu vic nez doted
  12          if (pocet>1): # a kdyz uz jsme ho nasli vic nez 1x muzeme skoncit
  13            return True # takze skoncime a vratime True
  14      return False # kdyz projede cely cyklus for bez toho aby skoncil, tedy se dostane az sem
  15                   # vime ze tam prvek vic nez 1x neni a tak vratime False
  16        
  17        
  18    # ted tezsi ukol... Uz nas nezajima konkretni prvek, ale chceme vedet jestli
  19    # v seznamu existuje nejaky prvek co je v nem vic nez jednou
  20    
  21    # nejdriv jednoducha fungujici vec:
  22        
  23    def hasMultipleItem(seznam):
  24      """ Funkce vrati True, jestlize nejaky prvek ze seznamu se v nem vyskytuje alespon 2x."""
  25      for p in seznam: # pro vsechny prvky v seznamu
  26        if (isMultiple(seznam,p)): # zkusime jestli tam ten prvek je aspon 2x
  27          return True # a jestli je vratime True
  28      return False # kdyz se dostaneme sem, ani jeden prvek neni 2x -> vratime False
  29    
  30    # jenze tenhle pristup je nevyhodny... Jako prvni by vas mohlo napadnout ze je to
  31    # protoze stejne prvky testujeme vice nez jednou. To ale neni pravda, protoze
  32    # pokud bychom nejaky prvek testovali vic nez 1x znamena to, ze je v seznamu vic
  33    # nez jednou a tedy by uz jeho prvni testovani vratilo True.
  34    # co je ale problem je, ze jak postupne "odskrtavame" prvky co uz jsme zkusili
  35    # prochazime je stejne dal kdyz hledame jestli jiny prvek se nevyskytuje 2x,
  36    # a pritom vime ze se uz v tehle nemuze vyskytovat:
  37    #
  38    # treba seznam 1 2 3 4 5 6 7
  39    # zkusili jsme 1 2 3
  40    # a zkousime 4... Vime ze na 0,1,2 indexu byt nemuze (kdyby byla, tak by byla
  41    # v seznamu 2x a ani bychom se sem nedostali)
  42    # tedy je muzeme preskocit...
  43    #
  44    # Jednou z moznosti jak toho docilit je prvek ktery zkontrolujeme ze seznamu
  45    # odebrat:
  46    
  47    def hasMultipleItem(seznam):
  48      """ Funkce vrati True, pokud v seznamu existuje nejaky prvek alespon 2x."""
  49      while (len(seznam)>0): # postupne zkusime prvek a kdyz neni v seznamu aspon 2x
  50                             # tak ho odebereme ze seznamu. Cyklus tedy jede dokud
  51                             # je v seznamu alespon nejaky prvek (tedy je co testovat)
  52        if (isMultipleItem(seznam,seznam[0])): # jestli je prvni prvek seznamu vicenasobny
  53          return True # vratime True
  54        del seznam[0] # kdyz neni, tak ho ze seznamu vymazeme.
  55                      # tedy druhy prvek v poradi se dostane na jeho misto, atd.
  56      return False # kdyz jsme projeli cely seznam a zadny prvek v nem nebyl aspon 2x
  57                   # tak vratime False
  58                   
  59    # ted udelame drobnou upravu funkce isMultiple() aby nam nevracela True nebo False,
  60    # ale cetnost zvoleneho prvku:
  61                   
  62    def cetnost(seznam,prvek):
  63      pocet=0 # zase si pamatujeme pocet
  64      for p in seznam: # a zkontrolujeme kazdy prvek v seznamu
  65        if (p==prvek): # kdyz je to hledany prvek
  66          pocet+=1 # zvedneme mu cetnost o jednicku
  67      return pocet # a na konci cetnost vratime
  68      
  69    # tuhle funkci ted vyuzijeme pro funkci ktera vezme seznam a vrati nam seznam
  70    # cetnosti prvku. tedy pokud i-ty prvek ve vstupnim seznamu byl v seznamu x-krat
  71    # pak i-ty prvek vraceneho seznamu bude mit hodnotu x.
  72    #
  73    # pr: Vstup   1 2 4 2 3 4 1 5
  74    #     Vystup  2 2 2 2 1 2 2 1 
  75      
  76    def cetnosti(seznam):
  77      """ Funkce vrati seznam obsahujici cetnosti prvku v puvodnim seznamu, tedy: result[i]= poce
  78      t seznam[i] prvku v seznamu."""
  79      result=[] # vysledek je prazdny seznam
  80      for p in seznam: # pro kazdy prvek v seznamu
  81        result.append(cetnost(seznam,p)) # zjistime jeho cetnost v seznamu a pridame ji do vysledku
  82      return result  # kdyz projdeme cely seznam, vratime vysledek (seznam vyslednych hodnot)
  83    
  84    # tahle funkce je samozrejme neefektivni... Jako bonusovy domaci ukol zkuste prijit na to, jak
  85    # ji napsat aby byla lepsi a nepocitala zbytecne nektere veci navic...
  86    # Pokud to popisete slovne spravne tak 1 bod, kdyz i v pythonu tak 2 body