Introduktion till programmering Föreläsning 7: Strängar 1 1
En sammansatt datatyp En sträng är ett enhetligt värde, som kan lagras i variabler och fungera som operand eller funktionsargument en datastruktur bestående av enskilda tecken, som i sig är värden Vilket synsätt som är lämpligast beror på sammanhanget Att plocka ut ett enskilt tecken ur en sträng: >>> fruit = "orange" >>> letter = fruit[1] >>> print letter r 2 2
Indexering Operationen stränguttryck[heltalsuttryck] kallas indexering, där heltalsuttrycket är ett index Det första tecknet i en sträng har index 0 minnesregel: hur gammal är en människa under sitt första levnadsår? >>> fruit = "orange" >>> print fruit[0] o Den inbyggda funktionen len ger längden av en sträng: >>> len(fruit) 6 3 3
Indexering Att plocka ut det sista tecknet i en sträng: >>> length = len(fruit) >>> last = fruit[length-1] >>> print last e Bekvämt alternativ: >>> last = fruit[-1] Vanligt misstag: >>> length = len(fruit) >>> last = fruit[length] IndexError: string index out of range 4 4
Om index Det är lämpligt att tänka sig att index pekar mellan de enskilda tecknen i en sträng: o r a n g e för sta åre Jämför: 6 t and ra å ret tre dje fjär året de fem året te å sjät ret te å ret index: 0 1 2 3 4 5-6 -5-4 -3-2 -1 År man fyller: 0 1... 2 3 4 5 6 5 5
Strängsegment Delsegment av en sträng (slices) pekas ut av två index: >>> fruit = "orange" >>> print fruit[0:2] or >>> print fruit[3:6] nge Underförstådda index: >>> print fruit[:2] or >>> print fruit[3:] nge >>> print fruit[:] orange 6 6
Mer om index Vad är egentligen ett tecken för sorts värde? Svar: ett tecken är en sträng av längden 1! (Python skiljer sig här från de flesta andra språk, som har olika typer för tecken och strängar) Enkel indexering kan därmed ses som en förkortning: sträng[index] betyder delsträngen sträng[index:index+1] Dock med ett viktigt undantag: >>> len(fruit[6:7]) 0 >>> len(fruit[6]) IndexError: string index out of range 7 7
Strängtraversering Skriv ut varje tecken på en rad för sig: index = 0 while index < len(fruit): letter = fruit[index] print letter index = index+1 Att på detta sätt stega igenom varje tecken i en sträng kan uttryckas mer kompakt med hjälp av for-snurran: for letter in fruit: print letter Denna nya sats kan också användas till annat än strängar 8 8
Ett for-exempel till Genererar namn lämpliga för ankor: prefixes = "JKLMNOPQ" suffix = "ack" for letter in prefixes: print letter + suffix, Output: Jack Kack Lack Mack Nack Oack Pack Qack 9 9
Strängjämförelse Likhet: if word == "banana": print "Yes, we have no bananas!" Olikhet (alfabetisk ordning): if word < "banana": print "Your word,", word, "comes before banana." elif word > "banana": print "Your word,", word, "comes after banana." else: print "Yes, we have no bananas!" OBS: alfabetisk ordning betyder egentligen ASCII-ordning 10 10
ASCII Förkortning av American Standard Code for Information Interchange Tabell ("alfabet") innehållande alla tecken på en amerikansk skrivmaskin och deras bitmönster-kodning: Siffror 0-9 Bokstäver A-Z samt a-z Symbolerna!"#$%&\'()*+,-./:;<=>?@[\]^_`{ }~ Styrtecken typ nyrad, tabulator, form feed, bell,... Finns i diverse platttformsberoende utvidgningar (åäö...) samt den komplexa Unicode Transformation Format (UTF) 11 11
ASCII-tabellen 0 1 2 3 4 5 6 0 7 8 9 10 11 12 13 \a \b \t \n \v \f \r 14 15 1 2! " # $ % & ' ( ) * +, -. / 3 0 1 2 3 4 5 6 7 8 9 : ; < = <? 4 @ A B C D E F G H I J K L M N O 5 P Q R S T U V W X Y Z [ \ ] ^ _ 6 ` a b c d e f g h i j k l m n o 7 p q r s t u v w x y z { } ~ platsnummer = rad*16+kolumn 12 12
ASCII-tabellen Naturligtvis lär sig ingen vettig människa hela tabellen utantill... Istället använder man inbygda funktioner (i den mån man alls behöver bry sig om ASCII-värden): ord(ch) ger platsnumret i tabellen för tecknet ch chr(n) ger tecknet på plats n i tabellen Viktigt att minnas: operatorn < på strängar jämför endast tecknens plats i tabellen. Exempel: '*' < '?' och 'Z' < 'a' är båda uttryck som evaluerar till True, av den enkla anledningen att ord('*) < ord('?') och ord('z') < ord('a') 13 13
Strängar och tilldelning Vi känner redan till effekten av multipel tilldelning: >>> greeting = "Hello, world!" >>> greeting = "Jello, world!" >>> print greeting Jello, world! Är följande kod ett möjligt alternativ? >>> greeting = "Hello, world!" >>> greeting[0] = 'J' Svar: Nej! Strängar är icke muterbara i Python Jämför: skulle vi vilja mutera värdet 7093 till (säg) 8093, om vi kunde? 14 14
I stället för mutation Så hur gör man om man har en strängvariabel greeting och absolut vill "ändra" dess första tecken till 'J' men bevara alla andra? Svar: man bygger det nya strängvärde man är ute efter! >>> newgreeting = 'J' + greeting[1:] Jämför att bygga ett nytt heltalsvärde: >>> newint = 8000 + oldint%1000 Jämför också med att binda om variabler till nya värden: >>> greeting = 'J' + greeting[1:] >>> i = i+1 Detta till trots är mutation ett viktigt begrepp inom programmering, vilket vi ska se redan nästa föreläsning! 15 15
Exempel Sök rätt på det index där tecknet ch förekommer första gången i strängen str: def find(str, ch): index = 0 while index < len(str): if str[index] == ch: return index index = index + 1 return -1 Notera det s k Eureka-mönstret: en return-sats inuti en snurra. När denna sats exekveras termineras både snurran och den omgivande funktionen omedelbart 16 16
Ytterligare ett exempel Räkna hur många gånger tecknet 'a' förekommer i strängen "banana": fruit = "banana" count = 0 for char in fruit: if char == a : count = count + 1 print count Kan denna kod generaliseras och inkapslas? (Självklart svar: ja! Se övningar kap 7) 17 17
Modulen string Importeras på vanligt sätt: import string Innehåller bl a en variant på vår funktion find: >>> string.find("banana", 'a') 1 Denna find accepterar även söksträngar av längd > 1: >>> string.find("banana", 'na') 2 (Kom ihåg: tecken är identiska med strängar av längden 1 i Python, och att både " och ' kan omsluta strängar) OBS: string.find är också en metod mer om det i kap 14! 18 18
Teckenklasser Användbara namn definierade i modulen string: >>> print string.lowercase abcdefghijklmnopqrstuvwxyz >>> print string.uppercase ABCDEFGHIJKLMNOPQRSTUVWXYZ >>> print string.digits 0123456789 >>> print string.punctuation!"#$%&\'()*+,-./:;<=>?@[\\]^_`{ }~ Också användbar, men kanske inte just för utskrift: >>> print string.whitespace 19 >>> 19
Att analysera tecken Är tecknet ch ett siffertecken? def isdigit(ch): return string.find(string.digits, ch)!= -1 Samma sak kan skrivas med den inbyggda operatorn in: def isdigit(ch): return ch in string.digits Ytterligare ett alternativ (drar nytta av att ASCII-tabellen håller ihop siffertecknen som ett intervall): def isdigit(ch): return '0' <= ch <= '9' 20 20
Konvertering Från sträng till heltal: def strtoint(str): num = 0 i=0 while i < len(str) and isdigit(str[i]): num = num*10 + ord(str[i]) - ord('0') i = i+1 return num Den inbyggda funktionen int(str) är en variant av denna, fast utökad till att klara ävev flyttal och andra data som argument 21 21
Konvertering Från heltal till sträng: def inttostr(num): if num==0: return "0" str = "" while num!=0: str = chr(num%10 + ord('0')) + str num = num/10 return str Den inbyggda funktionen str(num) är en variant av denna, fast utökad till att klara även flyttal och andra data som argument 22 22
Något om Laborationsrapporter Man bör sträva efter ett gott språk. Bra tumregel: Någon ska läsa det du skriver. Biblioteket har en språkverkstad med resurser http://www.luth.se/depts/lib/utbildning/sprakverkstad.shtml Särskilt bra är Rapportskrivning - en introduktion http://www.luth.se/depts/lib/rapport/index.html Rapporterna i den här kursen skall inte vara särskilt anspråksfulla, i omfattning ungefär en sida, plus källkod. Rapporterna skall vara ren text eller PDF. Skicka till någon av laborationsledarna med ärenderaden - lab N. 23 23
En rapports beståndsdelar Information om vem som har skrivit den. Information om vilken uppgift som är löst. Det viktigaste är att beskriva vilka val som har gjorts, vilka beslut som du har tagit. Beskriv lösningen översiktligt, och förklara nyckelavsnitten i ditt program. Nämn även problem eller begränsingar. 24 24