Datalogi för E Övning 3 Mikael Huss hussm@nada.kth.se AlbaNova, Roslagstullsbacken 35 08-790 62 26 Kurshemsida: http://www.csc.kth.se/utbildning/kth/kurser/2d1343/datae06
Dagens program Att skapa egna funktioner In- och utparametrar Operationer på strängar Strängar som listor Modulen string Sökning i listor Linjär sökning Binär sökning
Funktioner I Python, liksom i andra programmeringsspråk, kan man definiera egna funktioner. I en funktion kan man bunta ihop instruktioner till en enskild enhet. Varför vill man göra det? Några skäl: Vissa delar av programmet måste kanske upprepas flera gånger, och då är det jobbigt att skriva ner dem om och om igen. Det är lättare att samla ihop dem till en funktion som man anropar med ett enda kommando. Ofta kan det vara bra för läsbarheten av programmet att man delar upp det i logiska delar. Ibland kanske man också kan ta en funktion som man skrivit och sätta in den i ett nytt program.
Ett exempel på en funktion Ett exempel på en funktion är: def addera_tal_upp_till(n): summa = 0 for i in range(1,n+1): summa = summa + 1 return summa Sen kan man skriva >>>addera_tal_upp_till(3) 6 n kallas för inparameter och summa kallas för utparameter. När man anropar funktionen skriver man funktionens namn och värden på eventuella inparametrar inom parentes.
Strängar: Inläsning Ord, meningar och texter kallas på datorspråk för strängar. Ja, till och med enstaka tecken kan vara strängar. Hur låter man användaren skriva in en sträng med tangentbordet? >>>a = raw_input( Skriv något: ) Detta kommando utför följande steg: 1. Skriver ut texten Skriv något: på skärmen. 2. Väntar tills användaren har skrivit in något med tangentbordet och avslutat genom att trycka Enter. 3. Lägger den sträng som skrevs in i en variabel som heter a. Funktionen raw_input() behandlar allting som text (strängar). Det finns en annan funktion input som också tar in data från tangentbordet, men den fungerar lite annorlunda och försöker bl a gissa vad det inskrivna värdet har för typ (heltal, flyttal osv).
Operationer på strängar Vad kan man göra med strängar? Bland annat kan man faktiskt lägga ihop och multiplicera strängar, precis som man kan göra med tal. (Man kan dock inte subtrahera eller dividera.) >>> s1= jo >>> s2= visst >>> s3=s1+s2 >>> s3 jovisst >>> s4=s1*2 >>> s4 jojo Man kan också, på många sätt, behandla strängar som listor. Till exempel kan man plocka ut delar av strängar genom att använda samma notation som för listor. >>> s= Kebnekajse >>> s[0] K >>> s[0:4] Kebn >>> s[-3:-1] js
Operationer på strängar Det man dock inte kan göra med strängar (fast man kan det med listor) är att ändra delar av den. >>> s= kebnekajse >>> s[0]= K Traceback (most recent call last): File "<stdin>", line 1, in? TypeError: object does not support item assignment Istället får man skapa en ny sträng som man bygger ihop utifrån den gamla: >>> s2= K +s[1:] >>> s2 Kebnekajse Men man kan faktiskt fuska och kalla den nya strängen för samma namn som den gamla (man skriver alltså över den gamla strängen): >>> s= kebnekajse >>> s= K +s[1:] >>> s Kebnekajse Hur byter man ut första och sista tecknet i en sträng?
Operationer på strängar Man kan jämföra strängar: >>> Beijing == Peking False >>> Beijing == Bei + jing True Man kan kolla en strängs längd: >>> len( En kort mening ) 14 Man kan kolla om en sträng består av enbart siffror (funktionsanropet kanske ser lite konstigt ut, men ni kommer att förstå bättre efter att vi gått igenom klasser och objekt): >>> s1= 12345 >>> s1.isdigit() True >>> s2= 5 i 11 >>> s2.isdigit() False
Operationer på strängar Man kan söka efter delsträngar i en sträng: >>> s= Forskare >>> z=s.find( skare ) >>> z 3 Man får alltså ut indexet där delsträngen börjar. Strängar kan konverteras till versaler eller gemener: >>> s= CrAZy string >>> s.upper() CRAZY STRING >>> s.lower() crazy string
Att loopa över strängar Hur loopar man över en sträng? Det man först tänker på är kanske en for-loop: for i in range(0,len(s)): print s[i] Man kan också använda en while-loop: index=0 while index<len(s): print s[index] index=index+1 Det snyggaste är dock att använda en variant som också fungerar på listor (mer om detta snart): for bokstav in s: print bokstav
Modulen string Det finns en modul som heter string. Med den kan man göra ännu fler olika användbara saker med strängar. Man kan t ex ta en sträng, dela upp den och lägga delarna i en lista. >>> import string >>> s= Tomater, gurka, grillad kyckling >>> l=string.split(s) >>> l [ Tomater,, gurka,, grillad, kyckling ] >>> l=string.split(s,, ) >>> l [ Tomater, gurka, grillad kyckling ] På motsvarande sätt kan man ta en lista och göra om den till en sträng. >>> l=[ Inte, 40, minuter, till ] >>> s=string.join(l) >>> s Inte 40 minuter till
Fler funktioner Ni kan lära er ännu fler strängoperationer genom att gå in i Pythons kommandotolk och skriva help(str) (för att få reda på fler funktioner som alltid finns tillgängliga för strängar) eller help(string) (för att då reda på fler funktioner som finns i modulen string). I allmänhet är det ett bra tips att skriva help(x) om man vill få reda på mer om modulen eller kommandot X i Python.
Slingor och listor Med listor kan man alltid göra slingor som i det föregående exemplet. Om man t ex vill läsa in en lista och kolla om något av elementen är lika med 23 kan man skriva någonting sådant här: def kolla23(lista): found=0 for element in lista: if element==23: found=1 if found>0: print 23 hittades i listan! else: print 23 hittades *inte* i listan! Sedan kan man testa med olika listor: >>> l1=[ Volvo, Alfa Romeo, 23 ] >>> kolla23(l1) 23 hittades *inte* i listan! Varför detta resultat? Testa med en annan lista: >>> l2=[ Stockholm,23, Helsingfors ] >>> kolla23(l2) 23 hittades i listan!
Sökning i listor Hur gör man om man vill söka efter något i en lista? Eftersom vi måste lära oss principerna låtsas vi tills vidare att det inte finns några speciella funktioner för detta i Python. Antag att man har en lista av tal. Det skulle t ex kunna vara resultat för en massa studenter på en tenta. Nu vill vi veta om någon lyckades få full poäng (säg 40p). Spelar det någon roll om listan är huller om buller eller ordnad i storleksordning? Om listan är huller om buller använder vi linjärsökning. Det innebär helt enkelt att vi går igenom listan element för element. (Vi antar att det finns en lista tentaresultat som har utseendet [23,5,16,17,35,...osv]) hittat=0 for p in tentaresultat: if p==40: hittat=1 if hittat==1: print Jo, någon hade full pott. else: print Ingen hade full pott. Är det här effektivt om listan är ordnad (sorterad)?
Binär sökning Nej, om listan är ordnad i storleksordning är det ju korkat att gå igenom alla element. Om vi letar efter maxresultatet är det ju bara att titta på det första eller sista elementet, beroende på om listan är sorterad i stigande eller sjunkande ordning. Men om vi letar efter ett resultat någonstans i mitten, t ex 25? Då kan man använda binärsökning. Det innebär ungefär att man börjar med ett element i mitten av listan och tittar om det tal man letar efter är större eller mindre än det elementet. Då har man lokaliserat talet till en halva av listan. Sedan tittar man på det mellersta elementet i denna halva, och upprepar proceduren tills man hittat talet eller sett att det inte finns med.
Exempelfunktion En (ganska fult skriven) funktion som gör detta skulle kunna vara: def binarsok(lista, tal): stopp=0 min=0 max=len(lista)-1 mitten=-1 index=-1 while(stopp==0): if mitten == (max+min)/2: stopp=1 mitten=(max+min)/2 if (lista[mitten]==tal): stopp=1 index=mitten if (mitten<tal): min = mitten if (mitten>tal): max=mitten if (index==-1): print"talet hittades inte" else: print"talet fanns på index", index
Exempel, forts. Denna funktion kan sedan anropas med en lista och ett tal att leta efter som argument. T ex: >>>l1=[12, 13, 14, 20, 23, 27] >>>binarsok(l1,17) Talet hittades inte >>>l2 = [1,4,9,17,33,40] >>>binarsok(l2,17) Talet hittades, index = 3 Vad skulle då hända om man ville söka efter t ex namn på studenter istället? Jo, i Python kan man faktiskt jämföra storleken på strängar också. Det vill säga, strängar som börjar på en bokstav som kommer senare i alfabetet räknas som större. >>> Torkel > Anna True >>> Torkel > Zandra False Genom att utnyttja detta kan man på samma sätt som för tal söka efter ett visst namn i listan.