Iteration - Sm.luth.se
Iteration - Sm.luth.se
Iteration - Sm.luth.se
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
INTRODUKTION TILL PROGRAMMERING<br />
S Y S T E M T E K N I K<br />
D 0 0 0 9 E<br />
Multipel tilldelning<br />
Introduktion till programmering<br />
D0009E<br />
Föreläsning 6: “<strong>Iteration</strong>”<br />
Helt ok att tilldela en variabel flera gånger:<br />
bruce = 5<br />
print bruce,<br />
bruce = 7<br />
print bruce<br />
Output:<br />
5 7<br />
Som tillståndsdiagram:<br />
bruce<br />
5<br />
7<br />
1<br />
2<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Kom ihåg<br />
while-sat<strong>se</strong>n<br />
Tilldelningen = är ett kommando som tvingar fram likhet,<br />
inte en matematisk utsaga, ej heller ett test<br />
Pga denna "destruktiva" egenskap hos tilldelningssat<strong>se</strong>n kan<br />
likheter som tidigare gällde plötsligt sluta gälla:<br />
a = 5<br />
# a är lika med 5 efter denna sats<br />
b = a<br />
# b är lika med a efter denna sats<br />
a = 3<br />
# b är inte lika med a efter denna sats<br />
Varför vill man kunna skriva sådant krångel i Python?<br />
Svar 1: det vill man oftast inte! Använd därför multipel tilldelning<br />
väldigt sparsamt<br />
Svar 2: man kan vilja repetera samma sats flera gånger!<br />
Ny sats, som upprepar (itererar) sin kropp så länge<br />
huvudets uttryck är sant<br />
while uttryck:<br />
satslista<br />
För att denna sats ska bli meningsfull måste uttryck<br />
kunna anta olika värden olika varv, och satslista måste<br />
kunna påverka detta<br />
Det vill säga: uttryck måste innehålla (minst) en variabel<br />
som kan ändras av satslista efter hand – multipel<br />
tilldelning!<br />
3<br />
4<br />
5<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
En gammal bekant:<br />
def countdown(n):<br />
while n>0:<br />
print n<br />
n = n-1<br />
print "Blastoff!"<br />
Exempel med while-sats<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Ob<strong>se</strong>rvera hur variabeln (parametern) n både testas och<br />
tilldelas på nytt varje varv i snurran<br />
Notera också hur n förekommer i tilldelningens<br />
högerled. Korrekt tolkning:<br />
Låt det nya värdet av n bli det gamla värdet minus ett<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
Med while-snurra:<br />
def countdown(n):<br />
while n>0:<br />
print n<br />
n = n-1<br />
print "Blastoff!"<br />
6<br />
Snurror kontra rekursion<br />
Vilken stil är "bäst"?<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Med rekursion:<br />
def countdown(n):<br />
if n>0:<br />
print n<br />
countdown(n-1)<br />
el<strong>se</strong>:<br />
print "Blastoff!"<br />
1
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
INTRODUKTION TILL PROGRAMMERING<br />
S Y S T E M T E K N I K<br />
D 0 0 0 9 E<br />
Snurror kontra rekursion<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
INTRODUKTION TILL PROGRAMMERING<br />
S Y S T E M T E K N I K<br />
D 0 0 0 9 E<br />
Stackdiagram för countdown(3)<br />
Ob<strong>se</strong>rvation 1: Allt som kan uttryckas med en snurra<br />
kan också uttryckas med rekursion, men inte tvärtom<br />
Rekursion är alltså kraftfullare än snurror<br />
Ob<strong>se</strong>rvation 2: Enkla problem kan ofta uttryckas väldigt<br />
enkelt med snurror<br />
Ob<strong>se</strong>rvation 3: Svårare problem tenderar att uttryckas<br />
felaktigt med hjälp av snurror<br />
Ob<strong>se</strong>rvation 4: Snurror återanvänder minne varje varv,<br />
medan rekursion medför en ständigt växande stack<br />
Snurra:<br />
countdown<br />
n<br />
3<br />
2<br />
1<br />
0<br />
-toplevel-<br />
Rekursion:<br />
-toplevelcountdown<br />
countdown n 3<br />
n 2<br />
countdown n 1<br />
countdown n 0<br />
7<br />
8<br />
9<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
Terminering<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Hur vet man om while-snurrans test någonsin blir<br />
falskt, så att snurran stannar?<br />
Svar: det vet man inte generellt! Programmeraren måste<br />
övertyga sig om detta från fall till fall<br />
Oändlig snurra (provkör gärna):<br />
while True:<br />
pass<br />
Jämför med rekursion som aldrig når (eller saknar) sitt<br />
basfall<br />
Hur vet vi egentligen att countdown(n) terminerar<br />
(båda versionerna)? Hur är det med countdown(-1)?<br />
10<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
Ett svårt fall<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Terminerar denna funktion för alla positiva värden på<br />
n?<br />
def <strong>se</strong>quence(n):<br />
while n != 1:<br />
print n,<br />
if n%2 == 0:<br />
n = n/2<br />
el<strong>se</strong>:<br />
n = n*3+1<br />
Svar: både bevis och motbevis saknas!<br />
(Vanligen förekommande snurror är dock mycket<br />
enklare att resonera om!)<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Exempel<br />
Exempel<br />
11<br />
Utskrift av logaritmtabell:<br />
x = 1.0<br />
while x < 10.0:<br />
print x, '\t', math.log(x, 2)<br />
x = x + 1.0<br />
Resultat:<br />
1.0 0.0<br />
2.0 1.0<br />
3.0 1.58496250072<br />
4.0 2.0<br />
5.0 2.32192809489<br />
6.0 2.58496250072<br />
7.0 2.80735492206<br />
8.0 3.0<br />
9.0 3.16992500144<br />
Strängen '\t' är en s k<br />
escape-<strong>se</strong>kvens som<br />
(i detta fall) betyder<br />
tabulator-tecknet<br />
Andra vanliga tecken:<br />
\n nyrad<br />
\r vagnretur<br />
\v vertikal tab<br />
\\ \ (på riktigt!)<br />
\xnn ASCII nn<br />
12<br />
En variant som bara stegar igenom 2-poten<strong>se</strong>r:<br />
x = 1.0<br />
while x < 100.0:<br />
print x, '\t', math.log(x, 2)<br />
x = x * 2.0<br />
Resultat:<br />
1.0 0.0<br />
2.0 1.0<br />
4.0 2.0<br />
8.0 3.0<br />
16.0 4.0<br />
32.0 5.0<br />
64.0 6.0<br />
2
13<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
Ett större exempel<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Låt oss ge oss i kast med ett program som skriver ut<br />
multiplikationstabeller!<br />
Vi kommer att bygga programmet stegvis, och på vägen<br />
illustrera två viktiga begrepp inom programutveckling:<br />
• Generali<strong>se</strong>ring – att ersätta specifika värden med<br />
variabler och på så vis göra koden mer allmängiltig<br />
• Inkapsling - att göra om fritt flytande variabler till<br />
funktionsparametrar och på så vis göra koden mer<br />
oberoende av övrig kod<br />
14<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
Ett första steg<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Skriv ut några multipler av 2 (en bit ur "tvåans tabell")<br />
i = 1<br />
while i
19<br />
L U L E Å T E K N I S K A U N I V E R S I T ET<br />
S Y S T E M T E K N I K<br />
Ett femte steg<br />
INTRODUKTION TILL PROGRAMMERING<br />
D 0 0 0 9 E<br />
Låt oss generali<strong>se</strong>ra printTable så att den skriver ut high<br />
rader i stället för 6<br />
def printTable(high):<br />
i = 1<br />
while i