Inf109 – Programmering for realister

Inf109 – Programmering for realister
Uke 3 – Andre dag
I denne leksjonen skal vi gjøre oss ferdig med streng-behandling samt se på hvordan vi kan
lese og skrive til en ekstern fil.
a) Formatert utskrift
Ofte er det nyttig å kunne kontrollere hvordan ting blir skrevet ut. For eksempel ser det langt
bedre ut om man skriver at prisen er kr 4.50 istedenfor kr 4.500000000123. Måten dette
gjøres på i Python 3 er at man bruker en metode format som formatterer en tekst-streng som
inneholder såkalte formatteringsfelt. Dette kan best forklares med noen enkle eksempler. For
mer informasjon, se læreboken (2. utgave, s. 149) , eller eventuelt Python manualet.
'Heltallene ti:{1} og ni:{0} og igjen ti: {1}'.format(9,10)
'Heltallet ti med lengde på fem: {:5d}'.format(5+5)
'Pi med tre desimaler: {0:.3f} og med fem: {0:.5f}'.format(math.pi)
'Pi med tre desimaler og med lengde på ni: {:9.3f}'.format(math.pi)
'Strengen «abcdefgh» med lengde ti: {:10s}'.format('abcdefgh')
Merk at metode-kallene over returnerer strenger som kan skrives ut med funksjonen print på
vanlig måte. Generelt kan formatteringsfelt se ut som:
{<parameternummer>:<bredde>.<presisjon><type>}
Man kan utelate infomasjon som Python ikke trenger, for eksempel, dersom det bare er en
parameter i format-kallet. Hvordan utskriften vil se ut bestemmes som følger:
<bredde> gir antall tegn som blir reservert til utskriften. Utskriften kommer høyrejustert på
de reserverte plassene (et minustegn foran bredde gjør den venstrejustert). Dersom
<bredde> utelates vil utskriften bruke så mange plasser som den trenger.
<presisjon> angir hvor mange desimaler som blir tatt med i utskrift av flyt-tall.
<type> angir hvilke type uttrykk som skal skrives ut. Mulige verdier er ”f” - flyt-tall, ”d” heltall, ”s” - streng (kan ofte utelates). Prøv:
>>> print('Prisen er kr {:5.2f}'.format(4.5))
>>> print('Prisen er kr {:15.10f}'.format(9/2.0))
Merk at uttrykket 9/2.0 regnes om til en verdi før den settes inn i utskriften. Man kan også
bruke variabler i utrykket. Dersom man vil ha flere ting satt inn i en utskrift kan de plasseres i
den rekkefølgen de skal brukes. Prøv:
>>> print("Kjære {}, du oppnådde {} poeng i kurset {} og får dermed karakteren
{}.".format ('Bezem', 1, 'Inf109', 'F'))
 Lag en metode som spør etter radiusen til en sirkel og som deretter skriver ut omkrets og
areal til sirkelen. Alle tall som skrives ut skal ha to desimaler.
b) Konvertering mellom streng og tall
Av og til kan det være nyttig å lese inn data som en streng og så selv konvertere strengen til
tall-verdier. Funksjonen eval(streng) tolker streng som om det var en tallverdi eller et
matematisk uttrykk og returnerer den numeriske verdien. Prøv:
1
>>> eval('3.14')
>>> x = 4
>>> eval('x + 3')
Omvendt gjør funksjonen str(uttrykk) verdien til uttrykk om til en tekst-streng.
 Lag en metode der du først setter x = 5, y = 7 og z = 3. Deretter spør du brukeren om å
skrive et matematisk uttrykk som inneholder x, y og z. Metoden skal så skrive ut
uttrykket samt svaret. Hvis brukeren f.eks. skrev 3*x + y – 2*z skal det skrives ut
3*x + y – 2*z = 16
 Et person-nummer er et ellevesifret nummer som brukes for å identifisere personer i
Norge. Det er på formen: [d1 d2 m1 m2 å1 å2 i1 i2 i3 k1 k2]. Her angir [d1 d2 m1 m2 å1
å2] dag, måned og år da man ble født mens [i1 i2 i3] deles ut fortløpende for alle som er
født på denne dagen (etter visse regler, bl.a. er i3 jevnt for kvinner og odde for menn).
[k1 k2] er kontroll-siffer som skal fange opp om man skriver noe feil. Reglene for å
beregne k1 og k2 er gitt ved følgende formler:
x1 = 3×d1 + 7×d2 + 6×m1 + 1×m2 + 8×å1 + 9×å2 + 4×i1 + 5×i2 + 2×i3
k1 = (11 - (x1 mod 11)) mod 11
x2 = 5×d1 + 4×d2 + 3×m1 + 2×m2 + 7×å1 + 6×å2 + 5×i1 + 4×i2 + 3×i3 + 2×k1
k2 = (11 - (x2 mod 11)) mod 11
Lag et program som leser inn de 9 første sifrene i et person-nummer. Tallene skal gies som en
sammenhengende streng, som i 123456789. Deretter skal programmet regne ut og skrive ut
hele nummeret.
c) Filbehandling
Til nå har vi lest inn data til programmene våre ved at brukeren har skrevet de inn fortløpende
på tastaturet og alle resultater fra programmene har blitt skrevet ut til skjermen. Ved å bruke
filer for å lagre data oppnår vi at vi kan håndtere større datamengder samt at vi kan ta vare på
resultatene. Filene vi skal bruke er tekst-filer. Dvs. at du kan åpne en fil i en editor og se på
innholdet og sannsynligvis forstå hva som står der. Dette er i motsetning til binære filer som
bruker en egen koding for å representere data (f.eks .exe og .doc filer).
Vi har to hovedoperasjoner: lesing fra fil og skriving til fil. Men før vi kan gjøre noe med en
fil så må vi ha en måte å få tilgang til filen i programmet. Det gjør vi med et kall til
open(navn,kontroll) funksjonen. Her er navn en tekst-streng som gir navnet til filen vi vil
bruke og kontroll er ett tegn som angir hva vi vil gjøre med filen. Dersom kontroll = ”r”
kan vi lese fra den og hvis kontroll = ”w” kan vi skrive til den. Eksempel på bruk kan være:
fil1 = open(”inndata”,”r”)
Her blir variabelen fil1 satt til å være en fil-peker som gir oss tilgang til filen inndata. Merk
at denne filen må befinne seg i samme katalog som programmet ditt (eventuelt, hvis du kjører
interaktivt, samme katalog som du kjører Python-skallet fra), ellers får du en feilmelding.
Dersom man åpner en fil for skriving (kontroll = ”w”) vil filen bli opprettet dersom den ikke
allerede finnes. Hvis den finnes ved programmets start vil alt opprinnelig innhold i den bli
slettet.
2
Når vi leser inn fra en fil bruker vi fil-pekeren. Denne peker til en hver tid til et bestemt sted i
filen (akkurat som markøren i en editor) og det er derifra vi leser. Etter kall til open() peker
fil-pekeren til det første tegnet i filen. Etter hvert som vi leser inn vil fil-pekeren bli flyttet
fremover. Vi har tre ulike funksjoner for å lese inn fra en fil:
fil1.read()
Returnerer en streng som inneholder alt innhold i filen fra og med der
hvor fil1 peker. Etter denne operasjonen vil fil1 peke på slutten av
filen (og kan ikke brukes mer).
fil1.readline() Returnerer en streng med den neste linjen i filen som fil1 peker på
Etter denne operasjonen vil fil1 peke på den påfølgende
linjen i filen.
fil1.readlines()
Returnerer en liste med tekststrenger der hver streng er en linje
fra filen fil1 peker på. Bare linjer fra og med der hvor fil1
peker blir tatt med. Etter utførelse vil fil1 peke på slutten av filen.
For å gå igjennom en fil og behandle en og en linje kan man også skrive
for linje in fil1:
print(linje) # eller noe annet som man ville hatt gjort med linje
Utskrift til en fil gjøres med
fil1.write(”streng”)
der strengen er en tekst-streng som blir skrevet ut på samme måte som ved bruk av print. Etter
at man er ferdig med å behandle en fil bør man lukke den. Det sørger for at andre program
kan få tilgang til filen. Lukking av en fil gjøres med kommandoen
fil1.close()
●
Last ned tekstfilen bt.tekst.txt fra http://www.ii.uib.no/~matthew/INF1092014 og lagre
den i samme katalogen som programmet ditt. Lag en metode som leser inn hele filen i en
operasjon og som skriver den ut til skjermen. Lag deretter en metode som leser inn en og
en linje og skriver ut. Ser utskriftene make ut? Hva kan du eventuelt gjøre for at den siste
metoden skriver ut filen på samme måte som den første?
●
Modifiser et av programmene fra foregående oppgave slik at det spør etter navnet til en ny
fil og deretter skriver ut til denne.
Hvis du får tid:
●
I denne oppgaven skal du videreutvikle programmet ditt for å løse et kode-kryssord.
Programmet skal nå lese inn den kodete meldingen fra filen kode.data.txt. Denne består
av et ord per linje der hver bokstav har blitt byttet ut med et tall i intervallet [0,28]. Andre
tegn enn bokstaver er uforandret. Alle tall i den opprinnelige filen har blitt skrevet med
bokstaver dersom de var mindre enn 30.
Ditt program skal gi brukeren mulighet til å bytte ut ett og ett tall med bokstaver og for
hvert tall som blir byttet ut skal det skrive ut alle ordene med de byttene som er foretatt til
nå. Prøv først programmet på kjente data slik at du vet at det fungerer. Last så ned filen
kode.data.txt fra http://www.ii.uib.no/~matthew/INF1092014 og se om du klarer å løse
denne. Filen er laget fra en tekst i Dagbladet.
3