diff options
author | Martin Možina <martin.mozina@fri.uni-lj.si> | 2016-10-11 14:39:50 +0200 |
---|---|---|
committer | Martin Možina <martin.mozina@fri.uni-lj.si> | 2016-10-11 14:39:50 +0200 |
commit | 29bc34810cb1d1fbd208f6b5f2dad73188ca7f12 (patch) | |
tree | 0501d9274c6f87aa8a0aa4d273c364f0923d9063 /python/problems/while_and_if/loops_sl.html | |
parent | 8fd61c5d99aee8bf08871d306f1392b1bebd97aa (diff) |
- new exercises on recursion
- added text (lectures) on conditions and loops
Diffstat (limited to 'python/problems/while_and_if/loops_sl.html')
-rw-r--r-- | python/problems/while_and_if/loops_sl.html | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/python/problems/while_and_if/loops_sl.html b/python/problems/while_and_if/loops_sl.html new file mode 100644 index 0000000..17d89c4 --- /dev/null +++ b/python/problems/while_and_if/loops_sl.html @@ -0,0 +1,179 @@ +<!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>Zanka <code>while</code></h1> + +<h2>Naša prva zanka</h2> + +<p>Najprej malo refleksije. Kaj znamo narediti doslej: znamo napisati program, + ki kaj vpraša, kaj računa in kaj izpiše. Naši programi se izvajajo od + začetka do konca, s tem da lahko vmes preskočijo kak blok ukazov, ki se + nahajajo znotraj kakega <code>if</code>, <code>else</code> ali + <code>elif</code>. Večino časa pa smo preživeli ob tem, kako napisati + pogoj, se pravi, izraz, katerega vrednost je lahko resnično ali neresnično, + <code>True</code> ali <code>False</code>. Zdaj pa se bomo naučili napisati + programe, v katerih se del programa ponavlja.</p> + +<p>V večini programskih jezikov to naredimo z nečim, čemur mi rečemo zanka, + Avstralci (razen aboriginov) pa <em>loop</em>. Jeziki imajo navadno več + vrst zank, navadno tri. Python premore samo dve in danes bomo spoznali prvo + od njiju: zanko <em>while</em>.</p> + +<p>Tisočletna tradicija veleva, da mora biti začetnikov prvi program z zanko + program, ki šteje do deset. V Pythonu je videti takole +<pre>x = 1 +while x <= 10: + print(x) + x = x + 1 +print('Pa sva preštela')</pre> + +<p>Zanka <code>while</code> je po svoje podobna stavku <code>if</code>. Medtem + ko se stavki znotraj <code><b>if</b></code> izvedejo, <b>če</b> je pogoj + resničen, se stavki znotraj <code><b>while</b></code> ponavljajo, + <b>dokler</b> je pogoj resničen. "If" je "če" in "while" je "dokler", to + vedo celo učiteljice angleščine. (Mimogrede, če že štejemo, + <code>while</code> je zadnja, enajsta rezervirana beseda danes. Smo že na + tretjini!) Gornji program lahko torej kar dobesedno prevedemo iz Pythona v + slovenščino: + +<pre> +postavi x na 1 +dokler je x manjši ali enak 10: + izpiši vrednost x + povečaj x za 1 +izpiši 'Pa sva preštela' +</pre> + +<p>K temu ni potrebna več nobena razlaga, ne?</p> + +<p>Trenutek je tako dober kot katerikoli drugi, morda pa še boljši: tale + <code>x = x + 1</code> smo "prevedli" v "povečaj x za 1". V resnici nismo + napisali tega, računalniku smo naročili, naj izračuna, koliko je + <code>x + 1</code> in to shrani nazaj v <code>x</code>. Ker pa to reč + tolikokrat potrebujemo in ker je lepo, da se stvar napiše tako, kot se + misli - misli pa se "povečaj x za 1" -, obstaja tudi praktičnejši zapis: + <code>x += 1</code>. Točneje, napisali smo "k x prištej 1". Rečemo lahko + tudi, <code>x += 6</code> ali <code>x += 1.13</code>; kaj to pomeni, je + menda jasno. Podobno moremo pisati tudi <code>x -= 1</code> (zmanjšaj + <code>x</code> za 1) ali, recimo <code>x *= 2</code>, podvoji + <code>x</code> in <code>x /= 10</code>, zdesetkaj <code>x</code>. + Pazite: <code>+=</code> (in vse druge kombinacije) se štejejo kot ena + beseda in med znaka <code>+</code> in <code>=</code> ne smemo napisati + presledka.</p> + +<p>Tisti, ki veste še kaj več: <code>x++</code> boste v Pythonu zaman iskali. + Nima ga, iz več razlogov, ki pa so malo pregloboki za nas tule.</p> + +<h2>Kaj je domneval Collatz</h2> + +<p>Vzemimo poljubno število in z njim počnimo tole: če je sodo, ga delimo z 2, +če je liho, pa ga pomnožimo s 3 in prištejmo 1. To ponavljamo, dokler ne dobimo +1.</p> + +<p>Za primer vzemimo 12. Ker je sodo, ga delimo z 2 in dobimo 6. 6 je sodo, +torej ga delimo z 2 in dobimo 3. 3 je liho, torej ga množimo s 3 in prištejemo +1 - rezultat je 10. 10 je sodo, zato ga delimo z 2 in dobimo 5... Celotno +zaporedje je 12, 6, 3, 10, 5, 16, 8, 4, 2, 1. Ko pridemo do 1, se ustavimo.</p> + +<p>Matematiki, ki vedno radi počnejo koristne reči, si belijo glavo z +vprašanjem, ali se reč vedno izteče ali pa se lahko kdaj tudi zacikla tako, da +se zaporedje ponavlja in ponavlja v nedogled. Lothar Collatz, konkretno je že od +leta 1937 +<a href="https://en.wikipedia.org/wiki/Collatz_conjecture">domneval</a>, da se +zaporedje vedno izteče. Kot pravi njegov +<a href="https://en.wikipedia.org/wiki/Lothar_Collatz">življenjepis</a>, se je +njegovo domnevanje končalo leta 1990, matematiki pa domnevajo domnevo še naprej. +Eden sicer najbolj neustrašnih matematikov 20. stoletja, +<a href="https://en.wikipedia.org/wiki/Paul_Erd%C5%91s#Personality">couch + surfer Erdos</a>, je na to temo rekel, da matematika za takšna vprašanja še + ni zrela.</p> + +<p>Naši cilji bodo skromnejši: napisali bomo program, ki mu bo uporabnik vpisal +število in program bo izpisal zaporedje, kot je bilo gornje.</p> + +<p>Najprej povejmo kar po slovensko:</p> + +<pre>stevilo = kar vpiše uporabnik +dokler stevilo != 1: + če je število sodo: + deli število z 2 + sicer: + pomnoži število s 3 in prištej 1</pre> + +<p>Tole skoraj že znamo prevesti v Python (prevod bo pravzaprav dobeseden), + odkriti moramo le, kako preveriti, ali je število sodo. Če kdo misli, da + tudi za to obstaja funkcija, se, izjemoma, moti. Pač pa znamo izračunati + ostanek po deljenju, konkretno, ostanek po deljenju z 2. Če je enak 0, je + število sodo.</p> + +<p>Prevedimo torej one slovenske besede v pythonovske.</p> + +<pre>n = int(input("Vnesi število: ")) +while n != 1: + print(n) + if n % 2 == 0: + n //= 2 + else: + n = n * 3 + 1 +print(1)</pre> + +<p>Ne spreglejte, da smo uporabili celoštevilsko deljenje. Če bi uporabili +navadnega, <code>n /= 2</code>, bi se <code>n</code> spremenil v necelo število +(<code>float</code>) in v izpisu bi se pojavile zoprne decimalke (za vsakim +številom bi pisalo še .0).</p> + +<p>Popaziti je potrebno, da izpišemo tako prvo kot zadnje število, zato bomo +potrebovali še en <code>print</code> izven zanke: po zanki izpišemo še zadnji +člen zaporedja, 1. Namesto <code>print(1)</code> bi lahko napisali tudi +<code>print(n)</code> - tako ali tako vemo, da je <code>n</code> enak 1, saj +program sicer ne bi prišel do tam, do koder je prišel, namreč onstran zanke, ki +teče, dokler je <code>n</code> različen od 1.</p> + +<p>Dodajmo še nekaj: na koncu naj se izpiše, koliko členov ima zaporedje.</p> + +<pre>n = int(input("Vnesi število: ")) +clenov = 1 +while n != 1: + clenov += 1 + print(n) + if n % 2 == 0: + n //= 2 + else: + n = n * 3 + 1 +print(1) +print("Zaporedje, ki se začne z", n, "ima", clenov, "členov")</pre> + +<p>Ups. V zanki smo pokvarili <code>n</code>, spremenil smo ga v 1. To bomo +rešili tako, da shranimo začetno število v še eno spremenljivko.</p> + +<pre>zac = n = int(input("Vnesi število: ")) +clenov = 1 +while n != 1: + clenov += 1 + print(n) + if n % 2 == 0: + n //= 2 + else: + n = n * 3 + 1 +print(1) +print("Zaporedje, ki se začne z", zac, "ima", clenov, "členov")</pre> + +<p>Število smo si zapomnili v prvi vrstici, shranili smo ga v +<code>zac</code>. (V tem programu tudi prvič vidimo, da lahko prirejanja kar +nizamo - pisati smemo <code>a = b = c = 42</code>.) Ustrezno popravimo še +izpis v zadnji vrsti.</p> + +<script type="text/javascript"> + SyntaxHighlighter.config.tagName = "xmp"; + SyntaxHighlighter.defaults["gutter"] = false; + SyntaxHighlighter.all() +</script> +</body> +</html> |