1    #!/usr/bin/env python
   2    # Takze tohle je zhruba co jsme delali dneska. Je to kluci i holky dohromady, ale
   3    # vrele doporucuju si celej ten kod procist a naucit se ho na pisemku.
   4    # Kdyz nebudete chapat co dela kazdej z tehle programu, bude to u pisemky vazne
   5    # tezky.
   6    
   7    # nejdriv jsme delali program co scital vsechny cisla co uzivatel zadal. Kdyz
   8    # napsal nulu, skoncili jsme a kdyz napsal zaporny cislo, tak jsme zarvali
   9    # a zeptali se znova.
  10    # tenhle program jde udelat nekolika ruznejma zpusobama, z nich si nektery
  11    # ukazeme (jakejkoli z nich je automaticky 100% z pisemky pokud je teda funkcni)
  12    
  13    r=0
  14    while (True):
  15      x=input("Zadej kladny cislo: ") # ekvivalentni int(raw_input(msg))
  16      if (x==0):
  17        break # jestlize uzivatel zadal nulu, skoncime
  18      if (x>0):
  19        r=r+x # jestlize uzivatel zadal kladny cislo, pricteme ho k mezivysledku
  20      else: # tady staci else, vime uz ze x neni nula a ani neni vetsi nez nula
  21        print "Asi sem rikal kladny cislo, ne?" # zarveme
  22      # tady konci cyklus -> vratime se na radek 14 zacatek cyklu a zeptame se znova na cislo
  23    print "Vysledek je ", r
  24    
  25    # dalsi moznost:
  26    
  27    r=0
  28    x=1 # tady musime nastavit x abychom napoprve vlezli do cyklu na radce 29
  29    while (x!=0):
  30      x=input("Zadej kladny cislo: ")
  31      if (x>0):
  32        r=r+x # kdyz je x vetsi, proste pricteme k vysledku
  33      if (x<0): # tady uz nemuzeme else, x muze byt i nula
  34        print "Asi sem rikal kladny cislo, ne?" # zase zarveme
  35    print "Vysledek je ", r
  36    
  37    # a jeste treti moznost
  38    
  39    r=0
  40    x=1 # zase abychom se dostali napoprve do cyklu dal
  41    while (x>0):
  42      x=-1 # ted zase abychom se dostali do dalsiho cyklu
  43      while (x<0):
  44        x=input("Zadej kladny cislo: ")
  45        if (x<0): # kdyz zada uzivatel zaporny cislo zarveme
  46          print "Asi sem rikal kladny cislo, ne?"
  47      # konec vnitrniho cyklu co se postara o to, abychom dostali jen kladna cisla
  48      # to je nutne diky podmince while (x>0)
  49      r=r+x # kdyz je x nula tak je to jedno
  50    print "Vysledek je ", r
  51    
  52    # takze tim mame vycerpany moznosti zhruba jak to udelat. Vsechny tyhle tri
  53    # programy jsou uplne ekvivalentni... Delaji naprosto to same a za vsechny v
  54    # pisemce dostanete 100%
  55    
  56    # ale jde to udelat lip, s pomoci funkci. Zlate pravidlo rika: definujte
  57    # funkce vsude tam, kde to jde. Lepsi zbytecne vic funkci, nez jedna zrudofunkce
  58    # co dela vsechno dohromady. Ted se to nezda, ale treba vase semestralka bude
  59    # mit v pohode i 1000 radku... Tohle napsat do jedny funkce by vazne bolelo
  60    
  61    # kdyz pouzivate funkce, muzete totiz kazdou funkci odladit, tedy se presvedcit
  62    # ze vazne funguje a program tak dekomponujete (vzpomente si na prvni hodinu;-)
  63    # na spoustu malych a snadno resitelnych problemu, ktere jen date dohromady pak
  64    
  65    # takze udelame si prvni funkci, ktera se pta uzivatele na cislo dokud nezada
  66    # kladne nebo nulu:
  67    
  68    def askForPositive(): # funkce si nebere zadny parametry
  69      """ Funkce co se pta uzivatele na cislo, dokud nezada kladne cislo nebo nulu. Hodnotu cisla zadaneho uzivatelem pak funkce
         vrati. """
  70      x=-1 # ted zase abychom se dostali do dalsiho cyklu
  71      while (x<0):
  72        x=input("Zadej kladny cislo: ")
  73        if (x<0): # kdyz zada uzivatel zaporny cislo zarveme
  74          print "Asi sem rikal kladny cislo, ne?"
  75      return x # TOHLE JE DULEZITY: return x rikame, ze konci provadeni funkce a vraci se x
  76    
  77    # a ted pouziti ty funkce v hlavnim programu:
  78    
  79    r=0
  80    x=1 # zase abychom se dostali napoprve do cyklu dal
  81    while (x>0):
  82      x=askForPositive() # vsimnete si, jak se to najednou zjednodusilo
  83      r=r+x # kdyz je x nula tak je to jedno
  84    print "Vysledek je ", r
  85      
  86    # radek 82 rika: do promenne x uloz hodnotu, kterou mi vrati funkce askForPositive()
  87    
  88    # tohle ale neni jedina funkce jak jde delat. Dokonce tahle funkce je hodne
  89    # specificka v tom, ze se pta uzivatele na cislo a dokonce i neco pise.
  90    # tohle vetsinou funkce nedelaji, aby byly univerzalnejsi.
  91    
  92    # u navrhu funkci musite davat vazne pozor na to, co se po vas vlastne chce.
  93    # vetsina funkce spoleha na to, ze program, ktery je vola jim posle vsechna data
  94    # ktera potrebuji (nestaraji se o to, kde je hlavni program sehnal), ony pak
  95    # tyhle data zpracuji a vrati vysledek do volajiciho programu.
  96    
  97    # vyjimecne budete delat funkce co nejak osetruji vstup, nebo vystup. A kdyz jo,
  98    # tak bude vesmes ze zadani funkce naprosto jasny, ze je treba se uzivatele
  99    # na neco zeptat, nebo neco vytisknout, nebo tak.
 100    
 101    # treba zkusime udelat funkci, co vrati maximum ze tri cisel:
 102    
 103    def maxOfThree(x,y,z):
 104      """ Funkce vrati hodnotu maximalniho cisla ze tri vstupnich parametru. """
 105      if ((x>=y) and (x>=y)): # kdyz je x nejvetsi, nebo jedno z nejvetsich
 106        return x # skonci funkci a vrat hodnotu x
 107      if ((y>=x) and (y>=z)): # kdyz je y nejvetsi, nebo jedno z nejvetsich
 108        return y # skonci funkci a vrat hodnotu y
 109      return z # jinak vrat z (kdyz to neni ani x, ani y musi to byt z)
 110    
 111    # hodnoty do promennych x,y a z, ktere plati jen uvnitr dane funkce se zapisou
 112    # tehdy, kdyz ji nekdo vola. Pri volani funkce musite vsechny tyhle parametry
 113    # specifikovat, jinak Python zarve.
 114    
 115    # funkci muzete zavolat napriklad takhle:
 116    
 117    print maxOfThree(1,2,3) # vytiskne maximalni cislo z 1 2 3
 118    
 119    # ale moznosti jak ji zavolat je mnohem vic:
 120    
 121    from math import sin, cos, ln # importujeme (rekneme ze pouzivame) funkce sin, cos, ln
 122    a=input("Zadej cislo: ") # dame cislo do a
 123    print maxOfThree(sin(a),cos(a),ln(a)) # vypiseme jestli je vetsi sin, cos nebo ln od zadaneho cisla
 124    
 125    # nebo:
 126    
 127    a=input("Zadej cislo: ")
 128    b=input("Zadej cislo: ")
 129    c=input("Zadej cislo: ")
 130    print maxOfThree(a,b,c) # vytiskne nejvetsi ze zadanych cisel ulozenych v promennych a b c
 131    
 132    # promenne v hlavnim programu jsou ale uplne jine, nez ty ve funkci, takze se muzou
 133    # klidne jmenovat stejne:
 134    
 135    x=input("Zadej cislo: ")
 136    y=input("Zadej cislo: ")
 137    z=input("Zadej cislo: ")
 138    print maxOfThree(x,y,z) # vytiskne nejvetsi ze zadanych cisel ulozenych v promennych x y z
 139    
 140    # pri volani funkce se totiz vezmou hodnoty promennych pouzitych pri volani funkce,
 141    # zalozi se nove promenne x, y, z (ty co jsou definovany v hlavicce funkce) a hodnoty
 142    # parametru se do nich zkopiruji. Promenne definovane ve funkci plati jen ve funkci
 143    
 144    def pokus1():
 145      w=5 # tahle promenna plati jen ve funkci
 146    
 147    if (w==5): # promenna w zatim v tomhle bloku neexistuje -> chyba 
 148      print "w je 5"
 149      
 150    # promenne ve funkci jsou tedy kopiemi promennych ve volajicim programu
 151    # zmena hodnoty promenne ve funkci proto nijak neovlivni hodnotu promenne ve
 152    # volajicim programu:
 153    
 154    def setW(w):
 155      w=6 # w jako parametr funkce nastavime na 6
 156      return w # a jeho hodnotu vratime
 157      
 158    w=5 # tady jsme w v hlavnim programu nastavili na 5
 159    print w # vytiskne 5
 160    setW(w) # ted zavolame funkci s w, jenze w ve funkci je jina promenna
 161    print w # proto zmena w ve funkci nezmeni w v hlavnim programu a tady se vytiskne 5
 162    w=setW(w) # tady ale rikame, do w v hlavnim programu uloz co vrati funkce setW, ta vrati 6
 163    print w # proto tady vytiskneme 6
 164    
 165    # muzeme nejenom upravovat parametry vstupni funkce, ale vyslednou hodnotu, co
 166    # funkce vrati je taky mozny rovnou pouzit nejak dal (tedy jako vstupni
 167    # parametr jiny funkce).
 168    # napriklad tenhle kod se zepta uzivatele na 3 cisla a pak vypise sinus z hodnoty
 169    # nejvetsiho z kosinu tech tri cisel
 170    
 171    x=input("Zadej cislo: ")
 172    y=input("Zadej cislo: ")
 173    z=input("Zadej cislo: ")
 174    print cos(maxOfThree(sin(x),sin(y),sin(z))) 
 175    
 176    # funkce muzete pouzit a volat i v ramci jine funkce a takhle je slucovat
 177    # dohromady. Setrite tim velikost kodu, a delate tak kod i citelnejsim
 178    # napriklad chceme udelat funkci, ktera nacte tri cisla. Kdyz je jejich soucet
 179    # vetsi nez nula, vrati ten soucet, jinak vrati nejvetsi z tech 3 cisel.
 180    # s tim ze uz mame funkci maxOfThree() muzeme ji s vyhodou pouzit:
 181    
 182    def sumOrMax(x,y,z):
 183      """ Pokud je soucet zadanych cisel vetsi nez 0, vrati soucet, jinak vrati nejvetsi ze zadanych cisel. """
 184      if (x+y+z>0): # jestli je soucet vetsi nez 0
 185        return (x+y+z) # vrat ten soucet
 186      return maxOfThree(x,y,z) # jinak vrat to, co vrati funkce maxOfThree z tech cisel x,y,z
 187      
 188    # !!!! Aby se Vase funkce pustila, musite ji zavolat z hlavniho programu (tedy z toho bloku
 189    # co jako jediny neni odsazeny:
 190    
 191    print sumOrMax(1,2,-8)
 192    
 193    
 194    
 195