729G04 Programmering och diskret matematik Python 6: Abstrakta datatyper
Dagens föreläsning Nya verktyg: IPython, Texteditorer Ny datatyp: Dictionary Muddycards Abstraktion: text, datastrukturer
IPython + Texteditor Labb 6, 7, 8: Texteditor och IPython Varför? För att prova på en annan miljö. Vanligare att använda en text-editor/annan IDE för att Python IPython är en bättre interaktiv miljö än Python-skalet i IDLE.
IPython Bläddra bland tidigare kommandon med piltangenterna Tab-komplettering av anrop/variabler Tillgång till kommandon för att navigera i kataloger Magiska kommandon, börjar med tecknet %. T.ex. %run %run -i %reset %paste
IDLE vs Texteditor + IPython IDLE: 1. Öppna filen/skriv filen i IDLE 2. Tryck F5 i IDLE 3. Kör eventuell funktion Texteditor + IPython 1. Öppna filen/skriv filen i texteditorn 2. Skriv %run -i filnamn.py i IPython 3. Kör eventuell funktion
Texteditor d.v.s. program för att redigera textfiler
Vad gör en texteditor Redigerar textfiler (plain text) Saknar formatering och layoutfunktionalitet (paragrafjustering, fetstil, understruket, kursivt stil etc) Funktioner & verktyg för redigering av kod- eller datafiler
Exempel på funktionalitet redigera en kolumn använda regex-uttryck för sök och ersätt indenteringshjälp automatisk syntaxmarkering förslag på kompletteringar - variabler, funktioner stöd för olika teckenkodningar: läsa och skriva stöd för olika radbryt
Exempel på texteditorer SU-PUL Windows Mac Gratis emacs vim gedit kate Sublime Text Notepad++ Jedit Textwrangler
Menu Accessories
Texteditorer är viktiga för programmerare
xkcd: real programmers
IPython och texteditorer i PUL Starta IPython: skriv ipython3 i skalfönster. Texteditorer: Välj t.ex. gedit eller kate. Hittas via "startmenyn" under Accessories.
Tips: pep8 kontroll $ pep8 tree.py tree.py:3:1: E302 expected 2 blank lines, found 1 tree.py:27:21: W292 no newline at end of file $ I terminalen kan ni använda verktyget pep8 för att kontrollera era pythonfiler mot PEP8. Dock kollar den inte kommentarer.
Texteditor + IPython Demonstration
Dictionaries Innan vi går vidare ska vi lära oss om datatypen dictionary.
Dictionaries Ett dictionary har element precis som en lista, men istället för index, kommer man åt elementen med via nycklar. Alla datatyper som är oföränderliga (immutable) kan användas som nycklar, t.ex. numeriska värden, strängar och tupler. Till skillnad från en lista, finns det ingen bestämd ordning på nyckel-värde-paren i ett dictionary.
Dictionaries - en mängd nycklar och värden # Ett dictionary omges av {} och består av nycklar och värden: # { nyckel_1:värde1, # nyckel_2:värde2, #..., # nyckel_n:värde_n } # Exempel dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", (3):54 } Ett dictionary används för att lagra värden med associativ åtkomst, dvs att en nyckel kan användas för att komma åt ett värde. Som en lista, men med nycklar istället för index. Som nyckel kan alla oföränderliga (immutable) datatyper användas. Alla datatyper kan vara värden.
Istället för index använder vi nyckeln In [1]: dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", (3):54 } In [2]: dictionary1["nyckel1"] Out[2]: 'värde 1' In [3]: dictionary1[345] Out[3]: 'värde 2' In [4]: dictionary1[(3)] Out[4]: 54 In [5]: Jämfört med en lista så använder vi nyckeln istället för index för att "komma åt" värdena.
Vi kan ändra värden genom att använda nyckeln In [5]: dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", (3):54 } In [6]: dictionary1["nyckel1"] Out[6]: 'värde 1' In [7]: dictionary1["nyckel1"] = 1024 In [8]: dictionary1["nyckel1"] Out[8]: 1024 Precis som att man kan ange ett index vid tilldelning av ett värde på ett element i en lista, så kan man ange en nyckel vid tilldelning av ett associerat värde i en dictionary.
Vi kan lägga till element till ett dictionary In [9]: dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", (3):54 } In [10]: dictionary1["ny nyckel"] = "nytt värde" In [11]: dictionary1["böcker"] = ["bok 1", "bok 2", "bok 3"] In [12]: dictionary1["ny nyckel"] Out[12]: 'nytt värde' In [13]: dictionary1["böcker"] Out[13]: ['bok 1', 'bok 2', 'bok 3'] Till skillnad från att använda index som är större än längden på listan, så kan man lägga till nya värden i ett dictionary genom att använda en ny nyckel.
Vi kan loopa genom nycklar i ett dictionary # loopa genom nycklar, explicit (ingen _bestämd_ ordning finns) for key in dictionary1.keys(): print("key: " + key) print("value: " + dictionary1[key]) # loopa genom nycklar, implicit (ingen _bestämd_ ordning finns) for key in dictionary1: print("key: " + key) print("value: " + dictionary1[key]) Vi kan komma åt alla nycklar antingen implicit eller explicit. Operatorn in kan också användas på nycklarna implicit: if key_i_am_looking_for in dictionary1
Vi kan loopa genom värden i ett dictionary # loopa genom värden, explicit (ingen _bestämd_ ordning finns) for value in dictionary1.values(): print("value: " + value) dict.values(), precis som dict.keys() ger en struktur (ett view objekt) som beter sig som en lista (men det är ingen riktig lista). Se https://docs.python.org/release/3.3.0/library/stdtypes.html#dict-views för mer information.
Vi kan loopa genom par av nycklar och värden # loopa genom par av nycklar och värden explicit (ingen _bestämd_ # ordning finns) for key, value in dictionary1.items(): print("key: " + key) print("value: " + value) # en lista av tupler med två element per tupel kan loopas igenom på # samma sätt list_of_tuples = [("ett", 1), ("två", 2), ("tre", 3)] for word, number in list_of_tuples: print("word: " + word) print("number" + str(number)) dict.items() returnerar en struktur som kan användas som en lista av tupler med två element per tupel.
Codela m. dictionaries https://www.ida.liu.se/codela/as/729g04f/dictionaries1
Abstraktion
Abstraktion handlar om att lyfta blicken. Vi pratar om skogen istället för träden.
Övning 1. Rita en tabell som är 4x4 stor. 2. Skriv siffrorna 1-3 i de tre första cellerna på första raden. 3. Skriv siffrorna 4-6 i de tre första cellerna på andra raden. 4. Skriv siffrorna 7-9 i de tre första cellerna på tredje raden. 5. Använd den fjärde kolumnen för att skriva summan av varje rad (rad 1-3). 6. Använd den fjärde kolumnen för att skriva summan av varje kolumn (kolumn 1-3).
Facit 1 2 3 6 4 5 6 15 7 8 9 24 12 15 18
Ni har tillämpat abstraktion!
Övning - utan tabell-abstraktion 1. Rita fem lika långa, parallella och horisontella streck under varandra med lika mycket utrymme mellan varje. Rita sedan fem lika långa, parallella och vågräta streck. Det första börjar på samma punkt som det första horisontella strecket. Alla streck slutar på det sista horisontella strecket och har lika mycket utrymme mellan sig. 2. I den lilla fyrkanten högst upp till vänster, skriv siffran 1. I rutan till höger om den, skriv siffran 2. I rutan till höger om den, skriv siffran 3. 3.... 4.... 5. I rutan högst upp till höger, skriv summan av siffrorna 1, 2 och 3. I rutan nedanför den, skriv summan av siffrorna 4, 5 och 6.... 6....
Abstrakt datatyp ADT
Abstrakt datatyp: tabell Datastruktur: en lista med listor. Alla nästlade listor är lika långa tabell_adt = [ lista_1, lista_2,..., lista_n ] längd(lista_1) == längd(lista_2),..., längd(lista_n-1) == längd(lista_n) Låt oss kalla denna datastruktur för en tabell. Låt oss beteckna den första kolumnen som kolumn 1. Låt oss beteckna den första raden som rad 1. Om tabellens bredd är b och dess höjd är h, så är betecknas den sista raden som rad b och den sista kolumnen som kolumn h
Hjälpfunktioner till ADT för tabell Från matematiken: f : A B skapa_tabell : bredd, höjd tabell create_table(width, height) sätt_värde : tabell, rad, kolumn, värde tabell set_value(table, row, column, value) hämta_värde : tabell, rad, kolumn värde get_value(table, row, column) summera_horisontellt : tabell, rad, startkolumn, slutkolumn värde sum_h(table, row, start_column, end_column) summera_vertikalt : tabell, kolumn, startrad, slutrad värde sum_v(table, column, start_row, end_row)
Hjälpfunktioner i Python def create_table(width, height): """Skapa en tabell med bredden width och höjden height.""" table = [] # created table tmp_row = [] # temporary list for creating rows # Skapa height antal tomma rader (dvs listor) där alla element == None. for h in range(height): # Skapa en rad som är width lång där alla element == None. for w in range(width): tmp_row.append(none) table.append(tmp_row) tmp_row = [] return table def set_value(table, row, column, value): """Ändra ett värde i en cell i en tabell. Returnerar tabellen.""" table[row-1][column-1] = value return table def get_value(table, row, column): """Returnera värdet av en cell i en tabell.""" return table[row-1][column-1]
Hjälpfunktioner i Python, forts. def sum_h(table, row, start_column, end_column): """Returnera summan av celler i en rad. Start- och slutkolumn anges.""" the_sum = 0 # Observa att vi använder hjälpfunktionen för att hämta tabellvärde for current_column in range(start_column, end_column+1): the_sum += get_value(table, row, current_column) return the_sum def sum_v(table, column, start_row, end_row): """Returnera summan av celler i en kolumn. Start- och slutrad anges.""" the_sum = 0 current_row = start_row for current_row in range(start_row, end_row+1): # Observa att vi använder hjälpfunktionen för att hämta tabellvärde the_sum += get_value(table, current_row, column) current_row += 1 return the_sum
Abstrakta datatyper Datastuktur: vi använder inbyggda datatyper för att representera en typ av data som inte finns inbyggd Hjälpfunktioner: vi använder hjälpfunktioner för att lättare hantera vår egenkonstruerade datastruktur. Abstrakt datatyp (ADT): datastruktur + hjälpfunktioner
Textfilen programmerarens digitala material
Textfiler Hur lagras text på fil egentligen? Låt varje tecken representeras av en siffra. Som ett schiffer: a = 1 b = 2...
Hur blir detta på en dator?
Representation i en dator: ettor och nollor, på eller av 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 1 0 0 0 1 1 0 0 0 1 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1
Binära, oktala, decimala och hexadecimala talsystem Binärt: 0, 1 Oktalt: 0, 1, 2, 3, 4, 5, 6, 7 Decimalt: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Hexadecimalt: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
De 16 första talen: 0 till 15 P.S. dec 24 = oct 30 bin okt dec hex 0000 0 0 0 0001 1 1 1 0010 2 2 2 0011 3 3 3 0100 4 4 4 0101 5 5 5 0110 6 6 6 0111 7 7 7 1000 10 8 8 1001 11 9 9 1010 12 10 A 1011 13 11 B 1100 14 12 C 1101 15 13 D 1110 16 14 E 1111 17 15 F
Representation i en dator, 8 bitar = 1 byte 1 1 1 1 1 1 1 0 = 254 = FE 1 0 1 1 0 0 1 0 = 178 = B2 1 1 0 0 0 1 0 1 = 197 = C5 0 1 0 0 0 1 1 0 = 70 = 46 0 0 1 1 1 0 1 0 = 58 = 3A 1 0 0 1 1 1 0 0 = 156 = 9C 1 0 0 0 0 1 1 0 = 134 = 86 0 0 0 0 0 1 1 1 = 7 = 07
Text Låt en byte representera ett tecken. Som ett chiffer där vi kan representera 256 olika tecken.
Fast i början var man snål och tänkte att det räckte med 128 tecken, dvs 7 bitar per byte.
ASCII - American Standard Code for Information Exchange
Men om man vill skriva åäö då?
ISO-8859-1 (Latin-1) och Windows Code Page 1252 (CP-1252) 256 tecken innehåller åäö dock inte riktigt samma schiffer, t.ex. finns inte med i Latin-1 þ finns inte med i CP-1252
Но мы не используем латинские буквы!
و ما از راست به چپ ارسال.
Unicode FTW!
Unicode Mer än 110 000 tecken (plats för 1 112 064 st) Varje tecken har ett nummer, en code point. Det heter så för att tabellen som listar alla tecken heter code page. Unicode inbegriper även regler för sortering, dvs vilken bokstav kommer före vilken.
Unicode Förrutom de vanligaste skriftsystemen finns även Diverse pilar Diverse matematiska symboler Braille Kilskrift Runskrift Emoji diverse symboler:
Men en byte kan bara representera ett tal mellan 0-255!?
Vi får använda fler bytes helt enkelt.
Vi har 10 siffror [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] men kan skriva vilket tal som helst!
Encoding: representation av en code point i en fil Exempel med UTF-8 som encoding code point U+0041 = 'A' kodas med en byte: 41 code point U+0061 = 'a' kodas med en byte: 61 Exempel med UTF-8 som behöver två bytes code point U+00C5 = 'Å' kodas med två bytes: C5 85 code point U+00F6 = 'ö' kodas med två bytes: C3 B6
Så vad har detta med Python att göra?
Python 3 antar att textfilen använder sig av UTF-8 om inget annat anges
Ange encoding i början av filen (PEP 0263) # coding=utf-8 eller # -*- coding:utf-8 -*-
Slut.