diff options
Diffstat (limited to 'python/problems/functions/functions_sl.html')
-rw-r--r-- | python/problems/functions/functions_sl.html | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/python/problems/functions/functions_sl.html b/python/problems/functions/functions_sl.html new file mode 100644 index 0000000..1bd0a25 --- /dev/null +++ b/python/problems/functions/functions_sl.html @@ -0,0 +1,587 @@ +<!DOCTYPE html> +<html lang="sl"> +<head> + <meta charset="utf-8" /> + <title></title> + <link rel="stylesheet" type="text/css" href="/css/codeq.css" /> + <link rel="stylesheet" type="text/css" href="../../style.css" /> +</head> +<body> + +<h1> Kako definiramo funkcije? </h1> + +<p>Funkcije smo si doslej predstavljali kot škatlice: nekaj gre noter +(temu smo in bomo rekli <em>argument</em>), nekaj pride ven (temu se reče + rezultat funkcije), vmes pa se lahko še kaj opaznega dogaja, recimo + izpisuje. Primer funkcije, ki je počela vse to, je <code>input</code>: kot +argument smo ji povedali, kaj naj vpraša uporabnika; kot rezultat je vrnila, +kar je vtipkal uporabnik; vmes se je zgodilo to, da je funkcija nekaj vprašala +uporabnika in počakala, da je le-ta odgovoril. Druga funkcija, ki smo jo +srečali, je bila <code>sqrt</code>, ki dobi kot argument neko število in vrne +njegov koren. Vmes se ne dogaja nič opaznega, funkcija le "neopazno" naredi, +kar mora narediti.</p> + +<p>S tem, kako delujejo funkcije in kako kaj naredijo, se doslej nismo +ukvarjali. Te stvari so za nas napisali drugi (hvala, hvala) in mi jih lahko +uporabljamo, ne da bi nas vznemirjalo vprašanje, kako so napisane. S tem, kako +so napisane funkcije, ki so jih naredili drugi, se tudi v prihodnje ne bomo +ukvarjali. Pač pa se bomo danes naučili pisati svoje.</p> + + +<h2>Popolna števila</h2> + +<p>Število je <em>popolno</em>, če je enako vsoti svojih deliteljev. 28 je +deljivo z 1, 2, 4, 7 in 14 ter je popolno, saj je 1+2+4+7+14 ravno 28. Napišimo +program, ki sestavi seznam vseh popolnih števil do 1000.</p> + +<h3>Delitelji števila</h3> + +<p>Znamo napisati program, ki sestavi seznam vseh deliteljev nekega števila + <em>n</em>?</p> + +<pre> +n = int(input("Vnesi število: ")) + +s = [] +for i in range(1, n): + if n % i == 0: + s.append(i) + +print(s)</pre> + +<p>Najprej naredimo prazen seznam, nato gremo prek vseh števil od 1 do n in +če število deli <code>n</code>, ga dodamo v <code>s</code>.</p> + +<p>Kaj ne bi bilo lepo, če bi imel Python kar funkcijo <code>delitelji</code>, +ki bi jo lahko uporabili? Potem bi lahko napisali kar</p> + +<pre> +stevilka = int(input("Vnesi število: ")) +s = delitelji(stevilka) +print(s)</pre> + +<p>Napišimo si takšno funkcijo, da jo bomo lahko klicali.</p> + +<pre>def delitelji(n): + s = [] + for i in range(1, n): + if n % i == 0: + s.append(i) + return s</pre> + +<p>Definicijo funkcije začnemo z <code>def</code>; to je rezervirana beseda, ki +pomeni, da to, kar sledi, ni "program, ki ga je treba takoj izvesti", temveč +funkcija. Z drugimi besedami, <code>def delitelji</code> pomeni: "<em>kadar bo +kdo poklical funkcijo <code>delitelji</code>, naredi naslednje:</em>".</p> + +<p>Imenu sledijo oklepaji, v katerih navedemo <em>imena argumentov +funkcije</em>. V našem primeru bo funkcija zahtevala en argument. Torej, ta, +ki bo poklical funkcijo, bo moral v oklepaje napisati eno reč (upamo, da bo +napisal število, sicer pa naj si sam pripiše posledice).</p> + +<p>Tista reč, ki jo bomo ob klicu funkcije podali kot argument, se bo znotraj +funkcije pojavila kot spremenljivka z imenom <code>n</code>. Takšno ime smo +namreč uporabili v prvi vrstici, v "glavi" funkcije. Vrednosti ji ne bomo +priredili: ko bo nekdo poklical funkcijo, bo Python tej "spremenljivki" kar sam +od sebe priredil vrednost, ki jo bo "klicatelj" napisal kot argument funkcije. +Če torej nekdo pokliče + +<pre>s = delitelji(35)</pre> + +bo imel <code>n</code> vrednost 35 in če pokliče + +<pre>s = delitelji(13)</pre> + +bo imel <code>n</code> vrednost 13. <code>n</code> ima vrednost argumenta.</p> + +<p>Za <code>def delitelji(n)</code> sledi dvopičje in zamik. Vse, kar sledi +takole zamaknjeno, je koda funkcije. Kaj mora narediti le-ta? No, tisto, kar +pač dela funkcija: sestaviti seznam deliteljev <code>n</code>. To pa ne le +znamo narediti, temveč smo celo ravno prejle tudi zares naredili in lahko le +skopiramo.</p> + +<p>Na koncu (ali tudi že kje vmes - bomo že videli primer) funkcija pove, kaj +naj klicatelj dobi kot rezultat. To stori s stavkom <code>return s</code>.</p> + +<h3>Geometrija</h3> + +<p>Napišimo funkcijo, ki dobi kot argument dolžine stranic trikotnika in vrne + njegovo ploščino. Ta funkcija bo imela tri argumente; poimenujmo jih + <code>a</code>, <code>b</code> in <code>c</code>. + + +<pre>from math import * +def ploscina_trikotnika(a, b, c): + s = (a + b + c) / 2 + return sqrt(s * (s - a) * (s - b) * (s - c))</pre> + +<p>Ko smo pri tem, napišimo še funkcijo funkcijo za obseg trikotnika ter za + obseg in ploščino kroga.</p> + +<pre>from math import * + +def obseg_trikotnika(a, b, c): + return a + b + c + +def ploscina_kroga(r): + return pi * r ** 2 + +def obseg_kroga(r): + return 2 * pi * r</pre> + +<h3>Vsota števil v seznamu</h3> + +<p>Zdaj napišimo drugo funkcijo: funkcijo, ki dobi seznam števil in izračuna +njihovo vsoto.</p> + +<pre>def vsota(s): + vsota = 0 + for e in s: + vsota += e + return vsota</pre> + +<p>Funkcija ima spet en argument, tokrat smo ga poimenovali <code>s</code>. +Ta argument bo seznam števil, ki jih je potrebno sešteti. Funkcija gre - z +zanko <code>for</code> - prek tega seznama in sešteva, kot smo počeli že +prejšnji teden, le brez funkcij. Na koncu rezultata ne izpiše +(<code>print</code>), kot smo delali doslej, temveč ga vrne +(<code>return</code>).</p> + +<p>(Mimogrede povejmo še, da nam funkcije <code>vsota</code> ne bi bilo +potrebno napisati, saj obstaja: imenuje se <code>sum</code>.)</p> + + +<h4>Za napredno misleče</h4> + +<p>Nekateri se sprašujejo, kako funkcija ve, kakšnega tipa bodo argumenti, +ki jih bo dobila. Nekateri se zdaj, ko so izvedeli, da se nekateri sprašujejo +o tem, sprašujejo, zakaj bi se kdo to spraševal.</p> + +<p>Vsebina tega razdelka je namenjena samo prvim. Kasneje bo vse, kar pišemo +tu, postalo samoumevno, ne da bi bilo potrebno razlagati. Tule pa povejmo +zaradi tistih, ki prihajajo iz drugih jezikov.</p> + +<p>V nekaterih jezikih je potrebno za vsako spremenljivko, preden jo uporabimo, +povedati, kakšnega tipa bo. Python ni eden izmed teh "nekaterih jezikov". +Podobno je z argumenti funkcij. V nekaterih jezikih bi morali povedati, +kakšnega tipa bodo argumenti funkcije in kakšen bo rezultat. Tudi takšen +Python ni. Funkcija sprejme, kar sprejme in vrača, kar vrača.</p> + +<p>Za primer vzemimo preprostejšo funkcijo <code>vsota</code>, ki ji podamo dva + argumenta, funkcija pa vrne njuno vsoto.</p> + +<pre>def vsota(a, b): + return a + b</pre> + +<p>Če jo pokličemo z <code>vsota(2, 5)</code>, vrne <code>2 + 5</code>, torej + <code>7</code>. Če jo pokličemo z <code>vsota("Ana", "Marija")</code> vrne + <code>"Ana" + "Marija"</code>, torej <code>"AnaMarija"</code>. Če jo + pokličemo z <code>vsota(2, "Ana")</code>, poskuša izračunati + <code>2 + "Ana"</code> in vrne napako, ker se ne da seštevati števil in + nizov.</p> + +<p>Jezikom, ki delajo tako, pravimo dinamično tipizirani jeziki. Stvar deluje +(približno) tako, da Python, ko pride do <code>a + b</code>, reče objektoma +<code>a</code> in <code>b</code>, naj se seštejeta. Če se znata, je to v redu, +če ne, pa javita napako in Python jo izpiše. Python v resnici ne zna seštevati, +seštevati (se) znajo objekti.</p> + +<p>Vrnimo se k prvi funkciji <code>vsota</code>, oni od prej. Kaj bi se + zgodilo, če bi dali funkciji namesto seznama kaj drugega, recimo + terko ali kaj podobnega? No, preskusimo jo nekoliko.</p> + +<pre> vsota([1, 5, 3]) +9 +>>> vsota((1, 5, 3)) +9 +>>> vsota(range(4)) +6</pre> + +<p>S seznamom dela. Prvi klic pomeni isto, kot če bi napisali: +<pre>s = [1, 5, 3] +v = 0 +for e in s: + v += e</pre> + +Drugi klic je podoben, le da je <code>s</code> zdaj terka <code>(1, 5, 3)</code>, +torej dobimo + +<pre>v = 0 +for e in (1, 5, 3): + v += e</pre> + +Tretji klic pa je isto, kot če bi rekli + +<pre>v = 0 +for e in range(4): + v += e</pre> +</p> + +<p>Kaj pa, če bi namesto seznama celih števil podali seznam necelih?</p> + +<pre>>>> vsota([1.3, 2.2, 3.1]) +6.6</pre> + +<p>Dela, jasno. Zakaj pa ne bi?</p> + +<p>Kaj pa, če bi dali seznam nizov? Poglejmo, poučno bo.</p> + +<pre>>>> vsota(["Ana", "Berta", "Cilka"]) +Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "<stdin>", line 4, in vsota +TypeError: unsupported operand type(s) for +=: 'int' and 'str'</pre> + +<p>Zgodi se tole. Najprej je <code>v</code> enak 0. V prvem koraku zanke +poskuša izračunati <code>0 + "Ana"</code>, kar se ne da.</p> + +<p>Funkcijo je mogoče popraviti, da bo delovala tudi za nize. </p> + +<pre>def vsota(s): + v = None + for e in s: + if v == None: + v = e + else: + v += e + return v</pre> + +<p>(<br/>Komur se mozga, naj razmisli, zakaj dela tudi naslednja (grda) + različica funkcije:</p> +<pre>def vsota(s): + v = None + for e in s: + v = v and v + e or e + return v</pre> +<p>.)</p> + +<p>Tule smo torej naleteli na <code>None</code>. Tole je kar tipična situacija, + v kateri ga uporabimo. <code>v</code>-ju moramo bo v začetku dati neko + vrednost, ki bo povedala, da še nima nobene vrednosti. <code>None</code> je + idealna konstanta, s katero povemo kaj takega. V zanki preverimo, ali je + <code>v</code> še vedno nič in mu v tem primeru priredimo <code>e</code>, + sicer mu prištejemo <code>e</code>.</p> + +<p>Razlika je v tem, da <code>v</code>-ju zdaj ne priredimo vrednosti že pred +zanko, temveč jo dobi šele pri prvem elementu zanke. Tako bo gotovo pravega +tipa. Zdaj zna seštevati vse živo.</p> + +<pre>>>> vsota([1, 2, 3]) +6 +>>> vsota(["Ana", "Benjamin", "Cilka"]) +'AnaBenjaminCilka'</pre> + +<p>Kaj pa tole?</p> + +<pre>>>> vsota("Benjamin") +'Benjamin'</pre> + +<p>Zanka <code>for</code> gre prek niza in sešteje njegove črke. Rezultat je, +seveda, spet isti niz.</p> + +<p>Pač pa funkcija ne deluje, če ji damo seznam, ki vsebuje reči, ki jih ni +mogoče sešteti.</p> + +<pre>>>> vsota([1, "a"]) +Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "<stdin>", line 8, in vsota +TypeError: unsupported operand type(s) for +=: 'int' and 'str'</pre> + + + +<h3>Popolno število</h3> + +<p>Vrnimo se k popolnim številom. Rekli smo, da je število popolno, če je enako + vsoti svojih deliteljev. Lahko bi torej rekli</p> + +<pre>stevilo = int(input("Vnesi število: ")) +d = delitelji(stevilo) +v = vsota(d) +if v == d: + print("Število", stevilo, "je popolno") +else: + print("Število", stevilo, "ni popolno")</pre> + +<p>vendar ne bomo. Napisali bomo funkcijo, ki vrne <code>True</code>, če je +število popolno in <code>False</code>, če ni.</p> + +<pre>def popolno(n): + d = delitelji(n) + v = vsota(d) + return v == n</pre> + +<p>Pazite, tule nismo pisali</p> + +<pre>def popolno(n): + d = delitelji(n) + v = vsota(d) + if v == n: + return True + else: + return False</pre> + +<p>Lahko bi, vendar bi bilo smešno. Pač pa lahko funkcijo še skrajšamo (in +navadno bi jo tudi res), takole</p> + +<pre>def popolno(n): + return vsota(delitelji(n)) == n</pre> + +<p>Končno ostane še program, ki bo z uporabo gornje funkcije sestavil seznam +vseh popolnih števil manjših od 1000. +V njem z zanko <code>for</code> preštejemo do 1000, za vsako število posebej +preverimo, ali je popolno in če je, ga dodamo na seznam.</p> + +<pre>s = [] +for i in range(1, 1001): + if popolno(i): + s.append(i) + +print(s)</pre> + +<p>Lepo prosim, ne pišite <code>if popolno(i) == True:</code>. Smo že povedali, +zakaj, ne?</p> + +<h2>Klici funkcij</h2> + +<p>Najprej zberimo vse skupaj:</p> + +<pre>def delitelji(n): + s = [] + for i in range(1, n): + if n % i == 0: + s.append(i) + return s + +def vsota(s): + v = 0 + for e in s: + v += e + return v + +def popolno(n): + d = delitelji(n) + v = vsota(d) + return v == n + + +s = [] +for i in range(1, 1001): + if popolno(i): + s.append(i) + +print(s)</pre> + +<p>Kako se izvaja tako napisan program? Malo drugače, kot smo vajeni. Začetek +programa - vse do mesta <code>s = []</code>, so definicije funkcij. Python tega +dela programa ne izvede, le zapomni si funkcije, da jih bo kasneje lahko +poklical. Stvari se začnejo zares dogajati šele, pri <code>s = []</code>. Ko +program pride do klica funkcije <code>popolno</code>, skoči v to funkcijo -- +vendar si zapomni, odkod je skočil, tako da se bo kasneje lahko vrnil na to +mesto.</p> + +<p>Prav. Zdaj smo v funkciji <code>popolno</code> in <code>n</code> je neka +številka (najprej 1, naslednjič bo 2 in tako naprej). Že takoj, v prvi +vrstici skoči izvajanje v funkcijo <code>delitelji</code>. Ta sestavi seznam +deliteljev in ga vrne - tistemu, ki jo je poklical, funkciji +<code>popolno</code>. Nato se nadaljuje izvajanje funkcije <code>popolno</code>: +ta v naslednji vrsti pokliče funkcijo <code>vsota</code>. Funkcija +<code>vsota</code> izračuna in vrne vsoto. Spet smo v funkciji +<code>popolno</code>, ki izračuna vrednost izraza <code>v == n</code>; +vrednost izraza je <code>True</code> ali <code>False</code>. Funkcija +<code>popolno</code> ga vrne tistemu, ki jo je klical, se pravi oni zanki +na koncu skripte. Če je rezultat <code>True</code>, dodamo število v seznam, +sicer ne.</p> + +<p>Ta program je lep zato, ker je pregleden. Razdelili smo ga na tri funkcije, +vsaka opravlja svoje delo. Ko pišemo eno funkcijo, se ne ukvarjamo +s celo sliko, temveč le s tem, kar počne ta funkcija. Če mislimo +le na eno stvar naenkrat, nam bo lažje programirati in manj se bomo motili.</p> + +<h2>Rezultat sredi funkcije</h2> + +<p>Napišimo funkcijo, ki pove, ali je dano število praštevilo. Vrnila bo +<code>True</code> (je) ali <code>False</code> (ni).</p> + +<p>Prejšnjič smo v te namene spoznali <code>break</code> - <code>break</code> + je bil ukaz, s katerim smo lahko prekinili zanko. No, prekinemo jo lahko + tudi z <code>return</code>.</p> + +<pre>def prastevilo(n): + for i in range(2, n): + if n % i == 0: + return False + return True +</pre></p> + +<p>Prvi <code>return</code> je znotraj stavka <code>if</code>. Če odkrijemo, +da kakšno število med 2 in n-1 deli n (se pravi, če je ostanek po deljenju +<code>n</code> z <code>i</code> enak 0), dano število ni praštevilo in vrnemo +<code>False</code>. S tem se izvajanje funkcije prekine, funkcija vrne +rezultat in konec. Nobenega <code>break</code> ali česa podobnega ne +potrebujemo. <code>return</code> vedno konča izvajanje funkcije. Do drugega +<code>return</code>a tako pridemo le, če se ni izvedel prvi +<code>return</code>. To pa seveda pomeni, da ni bilo nobenega števila, ki bi +delilo dano število <code>n</code>.</p> + + +<h2>Funkcije (navadno) vračajo rezultate, ne izpisujejo</h2> + +<p>Iz neznanega razloga so študentom - kot opažam na izpitih in v domačih +nalogah - veliko bolj pri srcu funkcije, ki nekaj izpišejo, kot funkcije, +ki vračajo rezultat. Tako bi jih mikalo, recimo, funkcijo za <code>vsoto</code> +napisati tako, da bi na koncu namesto <code>return v</code> pisalo +<code>print(v)</code>.</p> + +<p>Vendar to ni prav! S takšno funkcijo si nimamo kaj pomagati! Ne potrebujemo +funkcije, ki <em>izpiše</em> vsoto; potrebujemo funkcijo, ki <em>vrne</em> +vsoto, da bomo lahko s to vsoto še kaj počeli. Če jo bomo hoteli izpisati, bomo +pač poklicali funkcijo in izpisali, kar vrne. Funkcija naj jo le izračuna. Si +predstavljate, kako neuporabna bi bila funkcija <code>sin</code>, če bi le +izpisala sinus, namesto da ga vrne? Bi si lahko pri programiranju topov z njo +sploh kaj pomagali?</p> + +<p>To seveda ne pomeni, da funkcije ne smejo ničesar izpisovati. Smejo; nekatere +so pač namenjene temu. Najbolj očiten primer takšne funkcije je očitno kar +<code>print</code>.</p> + +<h2>Funkcije, ki ne vračajo ničesar</h2> + +<p>Vse funkcije v Pythonu vračajo rezultat. Če funkcija ne vrača ničesar, vrača + nič, torej <code>None</code>. To se bo zgodilo, kadar funkcija nima + <code>return</code> ali kadar se ta ne izvede.</p> + +<p>Napišimo, na primer, funkcijo, ki kot argument dobi seznam in vrne prvo sodo + število v njem.</p> + +<pre>def prvo_sodo(s): + for e in s: + if e % 2 == 0: + return e</pre> + +<p>In zdaj jo preskusimo: +<pre>>>> prvo_sodo([1, 2, 3, 4, 5]) +2 +>>> prvo_sodo([1, 3, 5]) +>>> print(prvo_sodo([1, 3, 5])) +None</pre> + +<p>Prvi klic je jasen: funkcija vrne 2. V drugem primeru pa nikoli ne pride do + <code>return</code>a, zato funkcija pač ne vrne ničesar. Ko smo jo + poklicali, se tudi ni nič izpisalo, saj Python, kadar ga poganjamo v + načinu za čvekanje, ne izpiše <code>None</code> ... razen, kadar ga k temu + prisilimo s <code>print</code>, kot smo storili v zadnji vrstici.</p> + +<p>Konstanta <code>None</code> se šteje za neresnično. To je praktično, saj jo +lahko uporabljamo v pogojnih stavkih. Imejmo nek seznam <code>s</code> in +izpišimo prvo sodo število ali pa povejmo, da v seznamu ni sodih števil.</p> + +<pre>sodo = prvo_sodo(s) +if sodo: + print("Prvo sodo število je", sodo) +else: + print("V seznamu ni sodih števil.")</pre> + +<p>Vendar moramo biti pri takšnem početju majčkeno previdni. Kaj, če je prvo sodo +število v seznamu 0? Ker je tudi 0 neresnično, bo program v tem primeru napisal, +da ni sodih števil. Pravilno bi bilo torej</p> + +<pre>sodo = prvo_sodo(s) +if sodo != None: + print("Prvo sodo število je", sodo) +else: + print("V seznamu ni sodih števil.")</pre> + +<p>Iz nekega razloga, ki ga bomo pojasnili čez dva tedna, pa običajno pišemo</p> + +<pre>sodo = prvo_sodo(s) +if sodo is not None: + print("Prvo sodo število je", sodo) +else: + print("V seznamu ni sodih števil.")</pre> + + +<h2>Več rezultatov</h2> + +<p>Funkcija lahko vrača tudi "več rezultatov", tako kot tale funkcija, ki vrne, +kvadrat in kub števila.</p> + +<pre>def kk(x): + return x ** 2, x ** 3</pre> + +<p>Pokličemo jo lahko takole.</p> + +<pre>kvad, kub = kk(5)</pre> + +<p>Pozoren študent je najbrž že spregledal mojo laž. V resnici funkcija +vrača en sam rezultat, namreč terko in ob klicu funkcije to terko razpakiramo. +Vendar nam o tem, tehničnem vidiku zadeve, ni potrebno razmišljati. Mirno se +lahko vedemo, kot da smo dobili dve vrednosti.</p> + +<p>V tem primeru navadno ne pišemo oklepajev okrog terk. Funkcija bo delovala +tudi, če pišemo <code>return (x ** 2, x ** 3)</code>, vendar to ni običajen +zapis za vračanje dveh vrednosti.</p> + +<h2>Več returnov</h2> + +<p>Funkcija ima seveda lahko več <code>return</code>ov. Izvede se tisti, na + katerega naleti. En primer smo že videli (določanje praštevilskosti). + Naredimo še enega: funkcijo, ki vrne absolutno vrednost danega števila.</p> + +<pre>def abs(x): + if x < 0: + return -x + else: + return x +</pre> + +<p>Funkcija ima torej dva <code>return</code>. Eden se izvede, če je število + negativno in drugi, če pozitivno.</p> + + +<h2>Funkcije brez argumentov</h2> + +<p>Funkcija je lahko tudi brez argumentov. Tule je funkcija, ki nima argumentov, + vrne pa 42. Vedno.</p> + +<pre>def odgovor(): + return 42 +</pre> + +<p>Tako funkcijo je potrebno tudi poklicati s praznim seznamov argumentov - +oklepajev pa vseeno ne smemo pozabiti.</p> + +<pre>koliko = odgovor()</pre> + +<p>Malo pametnejši primer funkcije brez argumentov bi bila funkcija, ki + uporabniku zastavi račun in pove (s <code>True</code> ali + <code>False</code>), ali ga je pravilno rešil.</p> + +<pre>def uganka(): + a = randint(2, 10) + b = randint(2, 10) + c = int(input("Koliko je {}x{}? ".format(a, b))) + return a * b == c</pre> + +<p>Z njo postane rešitev lanske domače naloge precej preglednejša.</p> + +<pre>from random import * +from time import * + +konec = time() + 20 +tock = 0 +while time() < konec: + if uganka(): + print("Pravilno.") + tock += 1 + else: + print("Napačno.") +print("Dosegli ste", tock, "tock")</pre> + +<p>Zdaj, ko znamo definirati funkcije, bo postalo naše življenje veliko lažje +in preglednejše. Naši programi so, z vsem kar znamo, začeli postajati +dolgi in razvlečeni. Zdaj jih bomo lahko razsekali v posamezne funkcije in se +v njih tako lažje znašli.</p> + +</body> +</html> |