Introduktion till programmering Föreläsning 4: Villkor och rekursion 1 1
Några inbyggda funktioner (med resultat!) Konverterar mellan de grundläggande typerna: >>> int("32") 32 >>> int(3.999) 3 >>> float(32) 32.0 >>> str(32) "32" >>> int("spam") ValueError: invalid literal for int(): Spam 2 2
Modulus-operatorn 7 delat med 3 är 2 (heltalsdivision) samt resten 1 Uttrycks i Python med / och modulus-operatorn % >>> quotient = 7 / 3 >>> print quotient 2 >>> remainder = 7 % 3 >>> print remainder 1 Användningsexempel: x % y är 0 om x är delbart med y x % 10 ger entalssiffran för talet x 3 3
Boolska uttryck För att kunna avgöra om x är delbart med y måste vi kunna testa om värdet av uttrycket x % y är lika med 0 Likhetstest uttrycks i Python med operatorn ==, dvs vårt delbarhetstest blir x%y == 0 Utfallet av detta test är ett utav de två sanningsvärdena True eller False Uttryck som resulterar i sanningsvärden kallas boolska (efter logikern George Boole) Observera skillnaden: x = y är ett kommando som tvingar fram likhet x == y är ett uttryck som undersöker eventuell likhet 4 4
Fler boolska uttryck Andra Python-operatorer som genererar sanningsvärden: x!= y är True om x inte är lika med y x>y är True om x är större än y x<y är True om x är mindre än y x >= y är True om x är större eller lika med y x <= y är True om x är mindre eller lika med y Exempel: >>> 5 == 5 True >>> math.pi <= 2.7 False 5 5
Logiska operatorer Vi kan räkna vidare med sanningsvärden med hjälp av de logiska operatorerna and, or och not Är n delbart med 2 eller 3? n%2 == 0 or n%3 == 0 Ligger x i intervallet 0..10? x >= 0 and x <= 10 Alternativt sätt att uttrycka x!= y not (x == y) Liten sidnotis: De logiska operatorerna accepterar även numeriska värden, där 0 behandlas som False och övriga värden som True 6 6
Villkorlig exekvering En huvuduppgift för boolska uttryck är att styra exekveringen av satser. Exempel: if x > 0: print "x is positive" Generellt mönster: if uttryck: satslista Betydelse: beräkna uttryck, kör sedan satslista ifall resultatet blev True 7 7
Alternativ exekvering En variant på if-satsen, nu med två grenar (branches): if x%2 == 0: print x, "is even" else: print x, "is odd" Ytterligare en variant, med en kedja av villkor: if x < y: print x, "is less than", y elif x > y: print x, "is greater than", y else: print x, "and", y, "are equal" 8 8
Yterligare alternativ Fler än tre grenar: if choice == 'A': functiona() elif choice == 'B': functionb() elif choice == 'C': functionc() else print "Invalid choice" Regel: en elif-kedja måste inledas med en if 9 9
Nästlade villkor Formen elif är strängt taget inte nödvändig: if x < y: print x, "is less than", y else: if x > y: print x, "is greater than", y else print x, "and", y, "are equal" Läsbarheten försvinner dock snabbt om man på detta sätt nästlar if-satser i många nivåer 10 10
Mer nästling I stället för den logiska operatorn and: if 0 < x: if x < 10: print "x is a positive single digit" Följande är dock att föredra: if 0 < x and x < 10: print "x is a positive single digit" Python har faktiskt ett speciellt "syntaktiskt socker" för just denna form av jämförelser: if 0 < x < 10: print "x is a positive single digit" 11 11
Notera Ett ofta återkommande syntaktiskt mönster i Python: huvud: satslista Huvuden vi sett: def namn( parameterlista ) elif uttryck if uttryck else För satslistan (den omgivande satsens kropp) gäller: Varje sats skrivs på ny rad Indenteringen är viktig, den avgör var listan slutar Det måste finnas minst 1 sats, ingen övre gräns Om tom lista önskas, använd den triviala satsen pass 12 12
return-satsen Avbryter en funktion omedelbart. Exempel: def printlogarithm(x): if x <= 0: print "Positive number only, please" return result = math.log(x) print "The logarithm of x is", result return-satsen kan bara förekomma inuti en funktion Satsen medför att programmet omedelbart fortsätter där den aktuella funkktionen blev anropad 13 13
Om synlighet Vilka andra funktioner är synliga (dvs anropbara) inuti funktionen f? def a(): satser def f():? satser def b(): satser Svar: både a och b. Den inbördes ordningen mellan funktionsdefinitioner spelar alltså ingen roll Följdfråga: kan f i så fall också anropa sig själv? 14 14
Självanrop = rekursion Exempel: def countdown( n ): if n == 0: print "Blastoff!" else: print n countdown( n-1 ) Vad som händer om vi anropar countdown(0) är självklart... Men vad händer om vi skriver countdown(3)? 15 15
countdown(3) Exekveringen av countdown börjar, med n = 3, och eftersom 3 inte är 0 så skrivs 3 ut och countdown(2) anropas Exekveringen av countdown börjar, med n = 2, och eftersom 2 inte är 0 så skrivs 2 ut och countdown(1) anropas Exekveringen av countdown börjar, med n = 1, och eftersom 1 inte är 0 så skrivs 1 ut och countdown(0) anropas Exekveringen av countdown börjar, med n = 0, men eftersom 0 är lika med 0 så skrivs "Blastoff!" ut och countdown(0) returnerar countdown(1) returnerar countdown(2) returnerar countdown(3) returnerar 16 16
countdown(3) Själva utskriften blir alltså >>> countdown( 3 ) 3 2 1 Blastoff! >>> 17 17
countdown(3) Stackdiagram som visar tillståndet just när "Blastoff!" skrivs ut: -toplevelcountoff n 3 countoff n 1 countoff n 2 countoff n 0 Observera att vi har fyra olika variabler som alla kallas n i detta läge! 18 18
Mer rekursion Vi har tidigare definierat def newline(): print def threelines(): newline() newline() newline() Inte så flexibelt... vi kanske vill skriva ut 11 nyrader... 19 19
Mer rekursion Med hjälp av rekursion kan vi i stället skriva: def nlines( n ): if n > 0: print nlines( n-1 ) Vad som händer om vi skriver nlines(0) är uppenbart (ingenting skrivs ut!) Effekten av nlines(1) är att en nyrad skrivs, följt av effekten av nlines(0) Effekten av nlines(2) är att en nyrad skrivs, följt av effekten av nlines(1)... 20 20
Oändlig rekursion Notera att våra rekursiva funktioner båda har ett basfall (en alternativ exekveringsväg) som inte innehåller något självanrop Detta basfall visar sig vara nödvändigt. För vad händer om det utelämnas? def recurse(): recurse() recurse() Anropen fortsätter i all oändlighet (dvs tills datorns minne tar slut!) Vi återkommer till fler aspekter av rekursion längre fram 21 21
Om input När vi kör interpretatorn interaktivt ger vi vanligen input till våra funktioner direkt när de anropas: >>> printlogarithm(10) The logarithm of x is 2.3025850929940459 >>> printlogarithm(0) Only positive numbers, please Ett script kan hitta eventuell input från operativsystemets kommandorad i variabeln argv i modulen sys (mer om denna detalj senare) Större/moderna program har dock ofta möjligheten att själva kommunicera med omgivningen interaktivt... 22 22
Interaktiva program Ett interaktivt program är ett program som under tiden det körs har förmåga att stanna upp och vänta på input från omgivningen input som inte nödvändigtvis existerade när programmet en gång startade Stora interaktiva program är i allmänhet mycket komplexa, ofta med flera input-källor som kan ge indata samtidigt. Hur man konstruerar sådana program är ett viktigt ämne i senare kurser Vi ska här bara snabbt beröra en enkel metod att skriva små interaktiva program: den inbyggda funktionen raw_input() 23 23
raw_input() Exempel: >>> str = raw_input() Bla bla >>> print str Bla bla Observera att den andra raden är text som vi matar in, anropet till raw_input() har då alltså inte avslutats än Variant av funktionen som skriver ut en promt: >>> str = raw_input("say something! ") Say something! Bla bla >>> print "You said:", str You said: Bla bla 24 24
Input av heltal Om bara heltal förväntas som input kan man skriva: >>> n = input("enter your number: ") Enter your number: 23 >>> print n Detta program stannar dock med ett runtime-fel om man matar in en sträng som inte kan konverteras till ett heltal. Säkrast är att använda raw_input och konvertera själv (eller ge sig till tåls tills vi introducerar exceptions!) Att minnas: med raw_input() kan man lägga in "vilopunkter" i programmet där körningen stannar upp i väntan på input från tangentbordet 25 25