06.11.2014 Views

Iteration - Sm.luth.se

Iteration - Sm.luth.se

Iteration - Sm.luth.se

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!