3. Listor och Anrop
Programmeringsteknik
Innehåll |
Listor
Oftast är den som skriver ett program dvs programmeraren inte den som kommer att använda det. Den som skriver programmet har kunskap om programmering men man ställer inga krav om kunskap i programmering för den som ska använda programmet. Detta gör att programmeraren måste skriva programmet på ett sätt så att den kan köras av olika användare med olika förväntningar.
Antag att vi vill skriva ett program som ska läsa in fem stycken namn och när man har matat in alla fem namnen skrivs de ut i omvänd ordning (dvs sista namnet först).
Med den programmeringskunskap du har idag är detta fullt möjligt. Det är bara att använda sig av fem olika variabler för att lagra namnen och sedan skriva ut dem i omvänd ordning, som programmet nedan:
namn1= raw_input("Ange ett namn: ") namn2= raw_input("Ange ett namn: ") namn3= raw_input("Ange ett namn: ") namn4= raw_input("Ange ett namn: ") namn5= raw_input("Ange ett namn: ") print namn5, namn4, namn3, namn2, namn1
Programmeraren har bestämt att 5 och endast 5 namn ska matas in. Programmet fungerar varken för färre eller fler antal namn.
Det vore bättre om programmet ställer en fråga om hur många namn som ska matas in i början av programmet och användarens svar på denna fråga avgör om hur många variabler som ska användas till att lagra alla namn. Men programmeraren kan fortfarande inte veta hur många variabler som ska användas eftersom att olika användare kommer att kunna mata in olika antal namn. Hur ska programmeraren göra?
Lösningen är att använda en lista.
Vad är en lista?
En lista är variabel som kan ha flera värden. Varje värde får ett eget index (nummer) som kan användas för åtkomst eller modifiering av värdet. Om en vanlig variabel fungerar som en stol så fungerar en lista som en bänkrad i en biograf när det är numrerad placering. Telefonnummerlistan i din mobil är ett exempel på en lista.
Hur använder man en lista?
Listor skrivs med hjälp av klamrar []
namnlista=3*[None]
namnlista
blir då en variabel som har plats för 3 olika värden. None betyder att alla platserna ska vara lediga. Om man vill tilldela första platsen i variabeln ett värde t ex talet 47 gör man på följande sätt:
namnlista[0]=47
I ovanstående rad är namnlista namnet på listan. [0] specificerar avsedd plats i listan, 0 är ett index som används för specificera första plats. =47 som vi vet sedan tidigare är en tilldelningssats. Hela raden gör att första plats i listan får värdet 47. Programmerare är lite lustiga på det sättet att 0 betyder första plats i en lista. Detta gäller i flera programspråk, t ex Java och C++.
Om man vill tilldela andra plats i listan ett nytt värde t ex "hej" använder man därför indexet 1:
namnlista[1]="hej"
För att skriva alla värden som finns i listan kan man skriva som nedan:
print namnlista
Om man endast vill skriva ut värdet på en specifik plats i vektorn får man använda sig av klamrar igen:
print namnlista[2]
Raden ovan skrivet ut värdet som finns på tredje platsen i listan.
Hur många platser har följande lista?
bilar = 16*[None]
Svar: 16
Åter till exemplet
Nu när vi har lärt oss lite om listor ska vi försöka skriva programmet som frågar efter ett antal namn och skriver ut dem i omvänd ordning:
1. antal_namn=input("Hur många namn vill du mata in? ") 2. namnlista=antal_namn*[None] 3. i=0 4. while i< antal_namn: 5. namnlista[i]=raw_input("Ange ett namn: ") 6. i += 1 7. j=antal_namn-1 8. while j>=0: 9. print namnlista[j] 10. j -= 1
I rad nr 1 frågar programmet efter ett tal (antal namn) inmatningen lagras i variabeln antal_namn.
I rad 2 skapar vi en lista som har lika många platser som användarens svar från första raden.
I rad 3 använder vi iterationsvariabeln "i" som ska användas i while-slingan som finns i rad 4-6.
Rad 4 -6 är en while-slinga som ska upprepa satsen i rad 5 så länge variabeln i är mindre än antalen namn som ska matas in.
Rad 5 frågar användaren efter ett namn och svaret kommer att lagras på i:te platsen i namnlista. I rad 6 vi ökar det värde som i har med 1.
En sammanfattning av den första while-slingan är att variabeln "i" startar med värdet 0 och i första varvet i slingan kommer att namnlista[i] alltså motsvara namnlista[0] eftersom i är 0. Alltså tilldelas första plats i listan ett nytt värde. Sedan när "i" ökas med 1 så får variabeln i värdet 1. Och i andra varvet kommer namnlista[i] motsvara namnlista[1] dvs andra plats i listan osv.
Detta upprepas tills i blir lika med antal_namn och alla platser i listan har fått ett värde.
När while-slingan i rad 4-6 är klar kommer listan innehålla så många namn som användaren ville mata in. Nu är det dags att programmet skriver ut alla namn i omvänd ordning. För att skriva ut sista namnet först måste vi ta reda på index för den sista namn som matades in.
Vi vet att index för första namnet är 0, index för andra namnet är 1 och index för tredje namnet är 2 osv. Men vad är index för det sista namnet?
Vi vet att antal namn som har matats in är lika många som värdet antal_namn (rad 1 i programmet). Om antal_namn t ex har värdet 10 så ska sista namnet ha placerats i plats nummer 9(=10-1).
I rad nummer 7 vill vi tilldela variabeln j ett startvärde, startvärdet ska vara samma värde som index för sista namnet i listan. Med ovanstående kunskap vet vi att j=antal_namn-1 kommer att vara index för den sista plats i listan.
Rad 8-10 är en while-sats som skriver alla element från namnlista i omvänd ordning.
Så här fungerar den andra while-satsen. Variabeln "j" har ett startvärde som är lika med index för sista platsen. While-satsen ska upprepa print-satsen(rad 9) så länge variabeln "j" har ett värde som är större eller lika med 0. Första varvet i slingan kommer att namnlista[j] motsvara sista namnet som finns i listan eftersom att "j" har just ett värde som är lika stort som index för sista namnet. På rad 10 kommer värdet av variabeln "j" minskas med 1. Alltså "j" kommer att ha samma värde som index för näst sista namnet i listan och därför i andra varvet i slingan kommer att namnlista[j] motsvar näst sista namn i listan osv.
Antag att vi har listan ages med ålder på 50 personer. Vilket av följande är korrekt om man vill komma åt femtonde elementet i listan?
- ages[14]
- ages14
- ages15
- ages, 14
- ages[15]
- ages, 15
Svar: 1. ages[14]
Antag att vi har listan ages
med ålder på 50 personer. Vilket av följande kodexempel summerar alla element i listan ages
?
i=0 sum=0 while i<50: sum += ages + i i += 12.
i=0 sum=0 while i<50: sum += ages[i] i += 13.
summera(ages)4.
i=0 sum=0 while i<50 sum += i i += 1
Svar: kodexempel 2
Moduler
Stora program delar man upp i mindre delar med bland annat funktioner. Funktionerna kan placeras i olika filer. En fil med en samling av funktioner kallas för modul. För att vi ska kunna använda en viss funktion från en viss modul måste vi importera tillhörande modul innan anropet av funktionen. Importeringen kan man göra med en enkel import-sats som vi förklarar nedan.
Man kan ha stort nytta av modularisering i program. Med modularisering kan man återanvända kod vilket gör att man inte behöver lägga tid på och anstränga sig för att skriva en motsvarande kod som redan har skrivits. Dessutom blir stora program med flera tusen rader kod mer överskådliga om de delas upp på ett bra sätt i moduler. I denna kurs tar vi inte upp hur man modulariserar utan vi nöjer oss med att lära hur man anropar funktioner som finns i moduler.
När man installerar Python medföljer en hel del moduler. För att använda en funktion som finns i en modul måste man importera modulen. Detta gör man med hjälp av reserverade orden from, import
och modulnamnet. Information om vilka moduler som följer med och vilka funktioner finns i varje modul kan man hitta på http://docs.python.org/lib/lib.html.
Anta att vi behöver beräkna roten ur 23 i ett program. Vi har från http://docs.python.org/lib/lib.html fått informationen att i modulen math
finns en funktion som heter sqrt(x)
som beräknar roten ur x och returnerar svaret. För att använda funktionen ska man importera modulen genom att skriva följande sats:
from math import *
Först nu efter importeringen kan vi anropa funktionen sqrt
enligt nedan:
sqrt(23)
Observera att import-satsen behöver endast vara med en enda gång för att man ska kunna anropa en funktion flera gånger i ett program. Ett bra ställe för import-satser är därför i början av programmet.
Vad betyder modularisering?
- Dela upp ett program i funktioner.
- Slå ihop två program till ett.
- Slå ihop flera program till två.
- Slå ihop tre program till ett.
Svar: 1
Vad är modularisering bra för?
- För att man ska kunna återanvända kod.
- För att man kommer att höja prestanda hos programmet.
- För att man ska få ett mer överskådligt program.
- Är ett sätt att gömma undan kod så att andra inte ska kunna förstå programmet.
Svar: 1 och 3
Random
Ett exempel på modul man kan importera är random som förser programmeraren med slumptal. Ibland vill vi att det program vi skriver ska vara oförutsägbart. Dvs det ska inte gå att förutse vad som kommer att hända i nästa stund av programmet. Detta beteende är väldigt vanlig i t ex spel där spelet byter strategier eller beter sig olika vid olika tillfällen. T ex ett äventyrsspel där det plötsligt kan dyka upp ett monster. Detta kan man åstadkomma med hjälp av slumpfunktionen random() som finns i modulen random. En modul är en samling med funktioner och annat som kan vara till användning i många program och är ett sätt att organisera funktioner. Information om tillgängliga moduler och tillhörande funktioner finns på webbsidan http://docs.python.org/lib/lib.html.
För att kunna använda funktionen random() måste man ha importerat modulen random i programmet, detta gör man med den enkla import-satsen:
from random import *
Efter denna sats kan man anropa funktionen random() som genererar ett slumptal (decimal) från och med 0 till 1. T ex:
from random import * s_tal=random()
s_tal kommer då att ha ett värde som är mindre än 1 och större eller lika med 0.
Om man vill generera heltal så kan man använda funktionen randrange() som också finns i modulen random.
h_tal=randrange(1,3)
Variabeln h_tal kommer att bli heltalet 1 eller heltalet 2. randrange(a,b) betyder att slumpa ett heltal, heltalet kommer att vara större eller lika med a och mindre än b.
[FRÅGOR]