1 of 27

DD1319

Programmeringsteknik

Föreläsning 8

Skolan för Datavetenskap och kommunikation

2 of 27

lista av objekt

moduler

3 of 27

idag

  • Läsa från csv-fil
  • Lista av objekt
  • Moduler

exempel i Dropbox

4 of 27

841128-5597,Sumak,Elin,80

991024-7016,André,Erik,0

841002-4155,Edengren,Katarina,57

960327-9196,Viirtanen,Eli,98

850728-7620,Denir,Sarta,100

en fil med elevdata: provdata.csv

  • Filformatet kallas csv (comma-separated values).
  • Separatorn kan vara antingen "," eller ";"

(Excel-filer kan exporteras som csv)

5 of 27

6 of 27

plan för arbetet

Vi vill skriva ett program som läser in alla elevers provresultat, och skriver ut en sorterad lista, med betyg.

  1. Prova att läsa in en rad från filen och dela upp den
  2. Skriv en klass för en Elev och testa den
  3. Skriv en funktion som läser in rader från filen och skapar objekt som sparas i en lista
  4. Gå igenom listan och skriv ut betyg för varje elev

7 of 27

with open("provdata.csv", "r", encoding="utf8") as infil:

for rad in infil:

print(rad)

Personnummer,Efternamn,Förnamn,Poäng

841128-5597,Sumak,Elin,80

991024-7016,André,Erik,0

841002-4155,Edengren,Katarina,57

960327-9196,Viirtanen,Eli,98

850728-7620,Denir,Sarta,100

läsa från filen del 1

8 of 27

with open("provdata.csv", "r", encoding="utf8") as infil:

for rad in infil:

rad = rad.strip()

data = rad.split(",")

print(data)

läsa från filen del 2

['Personnummer','Efternamn','Förnamn','Poäng']

['841128-5597','Sumak','Elin','80']

['991024-7016','André','Erik','0']

['841002-4155','Edengren,Katarina','57']

['960327-9196','Viirtanen','Eli','98']

['850728-7620','Denir','Sarta','100']

9 of 27

with open("provdata.csv", "r", encoding="utf8") as infil:

for rad in infil:

rad = rad.strip()

data = rad.split(",")

pnr = data[0]

efternamn = data[1]

förnamn = data[2]

poäng = data[3]

print(pnr,efternamn,förnamn,poäng)

läsa från filen del 3

Personnummer Efternamn Förnamn Poäng

841128-5597 Sumak Elin 80

991024-7016 André Erik 0

841002-4155 Edengren Katarina 57

960327-9196 Viirtanen Eli 98

850728-7620 Denir Sarta 100

10 of 27

import csv

with open("provdata3.csv", "r", encoding="utf8") as infil:

provfil = csv.DictReader(infil)

for rad in provfil:

print(rad)

läsa från filen del 4

{'Personnummer': '841128-5597', 'Efternamn': 'Sumak', 'Förnamn': 'Elin', 'Poäng': '80'}

{'Personnummer': '991024-7016', 'Efternamn': 'André', 'Förnamn': 'Erik', 'Poäng': '0'}

{'Personnummer': '841002-4155', 'Efternamn': 'Edengren', 'Förnamn': 'Katarina', 'Poäng': '57'}

{'Personnummer': '960327-9196', 'Efternamn': 'Viirtanen', 'Förnamn': 'Eli', 'Poäng': '98'}

{'Personnummer': '850728-7620', 'Efternamn': 'Denir', 'Förnamn': 'Sarta', 'Poäng': '100'}

11 of 27

def elevdata(rad):

"""841128-5597;Sumak;Elin;8"""

rad = rad.strip()

data = rad.split(";")

pnr = data[0]

efternamn = data[1]

förnamn = data[2]

poäng = data[3:13]

return pnr, efternamn, förnamn, poäng

Anrop:

pnr, efternamn, förnamn, poäng = elevdata(rad)

hjälpfunktion för att dela upp raden

12 of 27

def summera(lista):

s = 0

for tal in lista:

s += tal

return s

lista = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]

summa = summera(lista)

print(summa)

summera en lista

13 of 27

class Elev:

def __init__(self, rad):

self.personnummer = rad["Personnummer"]

self.efternamn = rad["Efternamn"]

self.förnamn = rad["Förnamn"]

self.poäng = int(rad["Poäng"])

self.betyg = self.beräkna_betyg()

Elev-klassen: __init__

14 of 27

def __str__(self):

s = self.efternamn + ", "

s += self.förnamn + " "

s += "betyg = " + self.betyg

return s

Elev-klassen: __str__

15 of 27

def __lt__(self, other):

if self.betyg < other.betyg:

return True

else:

return False

__lt__ som jämför betyg

16 of 27

def __lt__(self, other):

if self.efternamn < other.efternamn:

return True

elif self.efternamn == other.efternamn:

return self.förnamn < other.förnamn

else:

return False

...eller __lt__ som jämför namn

17 of 27

Betyget ges av summan av poängen.

def beräkna_betyg(self):

if self.summa < 50:

return "F"

elif self.summa < 60:

return "E"

elif self.summa < 70:

return "D"

elif self.summa < 80:

return "C"

elif self.summa < 90:

return "B"

else:

return "A"

metod beräkna_betyg

18 of 27

def elevlista(filnamn):

lista = []

with open(filnamn, "r", encoding="utf8") as infil:

provfil = csv.DictReader(infil)

for rad in provfil:

nyElev = Elev(rad)

lista.append(nyElev)

return lista

Elev-objekt i lista

841128-5597

Sumak

Elin

80

991024-7016

André

Erik

0

841002-4155Edengren

Katarina

57

960327-9196Viirtanen

Eli

98

850728-7620

Denir

Sarta

100

19 of 27

def main():

lista = elevlista("provdata.csv")

lista.sort()

for elev in lista:

print(elev)

huvudprogram

20 of 27

def main():

lista = elevlista("provdata.csv")

lista.sort()

for elev in lista:

if elev.betyg >="E":

print(elev)

urval - skriv bara ut godkända

21 of 27

moduler

22 of 27

moduler

  • En modul kan hämtas till programmet med en import-sats (bäst!)

import random

x = random.randint(1, 6)

  • Enstaka delar ur modulen kan importeras:

from random import randint

x = randint(1, 6)

  • Alla delar ur modulen kan importeras:

from random import *

x = randrange(10)

23 of 27

csv-modulen

Modulen csv underlättar inläsning från csv-filer

import csv

24 of 27

csv-modulen

Modulen csv underlättar inläsning från csv-filer

Exempel från dokumentationen:

import csv

with open('eggs.csv', newline='') as csvfile:

spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')

for row in spamreader:

print(row)

Variabeln row blir här en lista (som om man gjort split)

https://docs.python.org/3/library/csv.html

25 of 27

DictReader i csv-modulen

Med DictReader kan man få en dictionary istället för en lista

import csv

with open('names.csv', newline='') as csvfile:

reader = csv.DictReader(csvfile)

for row in reader:

print(row['first_name'], row['last_name'])

Variabeln row blir här en dictionary med första raden som nycklar

Använd denna variant i labb 5!

26 of 27

egna moduler

En egen programfil, t ex elevmodul.py, med klasser och funktioner kan importeras på samma sätt

import Elev

27 of 27

testkod i egna moduler

Ofta vill man skriva en main-funktion i modulen för att testa den.

Men den ska bara köras om vi anropar modulen som ett program, inte när den importeras.

if __name__ == "__main__":

main()