729G04 Programmering och diskret matematik Föreläsning 7
Föreläsningsöversikt Information Interaktion via text Läsa från fil Skriva till fil Spara och läsa abstrakta datatyper från fil
Information Felaktigt datum för omtentamen på kurshemsidan! Rätt datum för omtentamen: 5 februari 14-18 Prova datortentamiljön: 4 dec 15-17. Anmälan senast 2 dec i webreg: https://www.ida.liu.se/webreg3/729g04-2015-1/ OVN1 Kort om labb 7
Textgränssnitt
Textgränssnitt I ett textgränssnitt skriver användaren ett kommando och datorn försöker tolka det och utföra det. Exempel: terminalen, konsolen i minecraft m.m. I de flesta fall, frågar programmet efter ett nytt kommando efter att det processat ett.
Textgränssnitt import random while True: command = input("kommando: ") if command.lower() == "avsluta": break elif command.lower() == "rnum": print(random.random()) elif command.lower() == "dikt": skapa_dikt() else: print("okänt kommando.") Vi kan implementera ett textgränssnitt i python genom att använda en while-loop, funktionen input() och villkorssatser.
Filer med python
Öppna och stänga en fil Använd funktionen open(name[, mode]) som returnerar ett filobjekt. Vi stänger filen efter att ha läst/skrivit färdigt med file.close() name: namnet på filen (sträng) mode: 'r', read (läsa) - default 'w', write (skriva från början av filen) 'a', append (lägga till)
En rad definieras som en textsträng som avslutas med ett radbryt
Läsa från fil # öppna en fil. open() returnerar ett filobjektet som vi # tilldelar till variabeln file file = open("pep20.txt", "r") # vi kan använda for-loopen för att läsa en rad i taget från # filen en rad i taget läses då in for line in file: # strängmetoden rstrip() tar bort all whitespace från # slutet av strängen. print(line.rstrip()) # efter vi har läst klart så stänger vi filen file.close()
Läsa från fil # öppna en fil. open() returnerar ett filobjektet som vi # tilldelar till variabeln file file = open("pep20.txt", "r") # vi kan också använda metoden read() för att läsa hela filen på # en gång file_content = file.read() # efter vi har läst klart så stänger vi filen file.close() # skriv ut innehållet print(file_content)
Läsa från fil # öppna en fil. open() returnerar ett filobjektet som vi # tilldelar till variabeln file file = open("pep20.txt", "r") # metoden readline() läser en rad. om readline() returnerar '' så # har vi nått slutet av filen file_content = "" while True: line = file.readline() if line!= '': print(next_line.rstrip()) else: break # efter vi har läst klart så stänger vi filen file.close()
Läsa från fil och ha koll på radnummer # öppna filen data_file = open("data.txt") # skriv ut varje rad i filen line_number = 1 for line in data_file: print(str(line_number) + ": " + line.rstrip()) line_number += 1 # stäng filen data_file.close()
Skriva till fil Använd metoden write(sträng) för att skriva till fil. write(sträng) lägger inte till radbryt. Om du behöver ha radbryt i filen, måste du ha med '\n' i strängen.
Skriva till fil # öppna fil för att skriva till (OBS! Detta skriver över allt # tidigare innehåll) file = open("tmp.txt", 'w') # vi skriver lite till filen file.write("hej, detta är den första raden\n") file.write("detta är rad två.") file.write("detta är också rad två, utan mellanslag mellan meningar.") # vi stänger filen file.close()
Skriva till fil import random # Öppna filen för skrivning. Observera att 'w' betyder # att allt existerande innehåll ersätts med det vi skriver nu. data_file = open("data.txt", 'w') # skriv ett gäng slumpmässiga siffror till filen for counter in range(1000): data_file.write(str(random.random())) # radbryt var 10:de siffra if counter%10 == 0: date_file.write("\n") # stäng filen data_file.close()
Demonstration
Tokenisering ~ "att dela upp en sträng"
Dela upp en sträng vid ett visst tecken >>> my_string = "hej jag heter ada" >>> my_list = my_string.split(" ") >>> my_list ['hej', 'jag', 'heter', 'ada'] Om my_string är en sträng, returnerar strängmetoden my_string.split(separator) en lista av strängar. Elementen i listan är de som i strängen my_string skiljs åt av strängen separator.
Felhantering
Felhantering Varför? Undvik att programmet kraschar. Ge användaren feedback om något går fel. Hur? Kontrollera indata från användaren. Kontrollera data som en funktion får - det är inte bara användaren som gör fel. Gör något vettigt om det blir fel. Ibland kan det vettiga vara att avsluta programmet - när?
Felhantering Kolla så att funktioner får in argument av rätt datatyp. Kolla så att det användaren skriven in är ok.
Felhantering (forts) # Kolla om sträng if type(variabel) == str: print("variabel är en sträng") # Kolla om lista if type(variabel) == list: print("variabel är en lista") # Kolla om dictionary if type(variabel) == dict: print("variabel är ett dictionary") # Kolla om en nyckel finns med i en dictionary if nyckel in my_dictionary: print("nyckeln '" + str(nyckel) + "' finns i dictionaryt")
Repetition - ADT
Abstrakta datatyper (ADT) Abstrakta datatyper + hjälpfunktioner gör koden lättare att utöka och att underhålla. Vi behöver inte veta exakt hur data lagras, bara hur vi manipulerar det.
Grundläggande hjälpfunktioner för abstrakta datatyper create_adt(): En funktion som skapar och returnerar en instans av den abstrakta datatypen get_adt_value(): En funktion som returnerar värdet på ett attribut hos en instans av den abstrakta datatypen. set_adt_value(): En funktion som används för att ändra värdet på ett attribut hos en instans av den abstrakta datatypen.
Abstrakta datatyper (ADT) forts. Abstrakta datatyper + manipulerande funktioner gör koden lättare att uttöka och att underhålla. Vi behöver inte veta exakt hur data lagras eller hur vi kommer åt det, bara hur vi manipulerar det. För en enkel "bokdatabas" istället för "skapa en lista med tre element, titel i första, författare i andra och årtal i tredje" - create_book(title, author, year)
Konventioner Anta att vi definierat den abstrakta datatypen person som en lista med två element, namn och ålder, t.ex. ["Ginny", 42] När vi säger att en variabel innehåller en person, menar vi att den innehåller en datastruktur enligt vår ADT-definition. I detta fall, en lista med två element, en sträng och ett heltal. Strängen "Ginny", är inte en person i detta fall.
Exempel på ADT med filer
Livsmedelsdatabas Att göra: ADT för livsmedel: namn, innehållsdeklaration Bestämma filformat Skriva livsmedel till fil Ladda livsmedel från fil Steg 1: Hjälpfunktioner och ADT create_food(name) som skapar en mat ADT add_food(db, food) som lägger till food till vår databas add_fact(food, content, amount), som lägger till fakta om vår mat. Steg 2: Vi skriver vår livsmedelsdatabas till fil: write_db_to_file() Steg 3: Vi läser livsmedel från filen och använder add_food() för att lägga till livsmedel.
ADT för livsmedel
Exempel på ADT för livsmedel # Våra livsmedel har namn och innehållsdeklaration. # food ADT, som en lista med två element. I listan är name är en # sträng och contents är ett dictionary med strängar som nycklar # och heltal som värden. Nycklarna i dictionaryt är namn på # innehåll och dess värden är mängden av den ingrediensen. # # [name, contents] # # Exempel: ["havregrynsgröt", {"vatten": 1, "havregryn": 1}]
Filformat
Filformat Ett livsmedel per rad Vi använder semikolon ';' som avgränsningstecken (andra tecken som inte används i text går också bra) Det första elementet på raden är namnet. Resten är par av innehållsnamn+mängd mat.txt: jordgubbsmilkshake;mjölk;1;glass;2;bär;1 havregrynsgröt;havre;1;vatten;1
Hjälpfunktioner
Hjälpfunktionerna def create_food(name): """Skapa en som skapar en ADT för mat med innehåll""" return[name, {}] def add_food(db, food): """Lägger till food till vår "databas" som är en lista""" db.append(food) def add_content(food, ingredient, amount): """Lägg till ingrediens av en specificerad mängd i food ADTn""" food[1][ingredient] = amount
Spara ner livsmedel till fil
Skriva data till fil Öppna fil att skriva till Gör om vår livsmedels ADT till en sträng Skriv strängen till filen
Spara ner livsmedel till fil # Exempel på fil # jordgubbsmilkshake;mjölk;1;glass;2;bär;1 # havregrynsgröt;havre;1;vatten;1 def write_db_to_file(db, filename): db_file = open(filename, 'w') for food in db: db_file.write(food_as_string(food) + "\n") db_file.close() def food_to_string(food): """Returnera en strängrepresentation av vår food ADT""" food_as_string = food[0] + ";" # vi lägger innehållet i en lista för att kunna använda # str.join() senare contents = [] for key, value in food[1].items(): contents.append(key) contents.append(value) # gör om listan över innehåll till en sträng med ';' som avskiljare food_as_string += ";".join(contents) # returnera strängrepresentationen return food_as_string
Ladda in livsmedel från fil
Läsa data från fil Öppna fil för läsning Läs in en rad och tolka informationen för att skapa en ADTdatastruktur med innehåll från raden Stoppa in vår ADT-instans i "databasen" Fortsätt tills vi har läst alla rader i filen och stäng filen.
Läsa livsmedel till fil # Exempel på fil # jordgubbsmilkshake;mjölk;1;glass;2;bär;1 # havregrynsgröt;havre;1;vatten;1 def read_file_to(db, filename): db_file = open(filename, 'r') for row in db_file: food = string_to_food(row.rstrip()) add_food(db, food) db_file.close() def string_to_food(food_text): """Returnera en food ADT givet en sträng-representation""" tokens = food_text.split(';') # skapa instans av food ADT med namn i food = create_food(tokens[0]) # lägg till ingredienser och mängd for index in range(1, len(tokens), 2): # vi måste göra om mängden som sträng till ett heltal add_content(food, tokens[index], int(tokens[index+1])) # returnera färdig ADT return food
Finare utskrifter
Använd en loop för att skriva ut en ADT på ett fint sätt def print_food(food): print("name: " + get_name(food)) contents = "Contents: " tmp_list = [] for key, value in food[1]: tmp_list.append(key + " (" + value + ")") contents += ", ".join(tmp_list) print(contents)
Referenser till värden kontra värden
Referenser Variabler som står för datatyper som är oföränderliga innehåller ett värde. Variabler som står för datatyper som är föränderliga innehåller en referens.
Referenser i1 = 5 l1 = [1, 2, 3] i2 = i1 l2 = l1 i1 i2 l1 l2 5 5 1 2 3