TDP002 - Imperativ programmering Algoritmer Pontus Haglund Institutionen för datavetenskap Anpassatt från material ursprungligen av: Eric Elfving
1 Datatyper Tal UTF-8 2 Procedurell abstraktion Repetition av funktioner Exempel: spel Polymorfism Funktioner är objekt 3 Högre ordningens funktioner Funktioner som parametrar Lambda Returnera funktionsobjekt Map
1 Datatyper Tal UTF-8 2 Procedurell abstraktion Repetition av funktioner Exempel: spel Polymorfism Funktioner är objekt 3 Högre ordningens funktioner Funktioner som parametrar Lambda Returnera funktionsobjekt Map
3 / 23 Fysisk representation av tal Tal representeras fysiskt av datorn som binära tal. Dec: 26 Bin: 00011010
4 / 23 Räkna olika talbaser För alla talbaser gäller: x*y**z x är siffran y är talbasen z är positionen från höger med start 0 Binära talet 101 är: 1*2**2 + 0*2**1 + 1*2**0 = 4+0+1 = 5 (dec) Oktala talet 275: 2*8**2 + 7*8**1 + 5*8**0 = 128 + 56 + 5 = 189 (dec) Decimala talet 235: 2*10**2 + 3*10**1 + 3*10**0 = 200 + 30 + 5 = 236 (dec)
5 / 23 Literaler och fysisk representation >>> 0o352 234 >>> 0xEA 234 >>> 0xEA + 0o352 468 0o352 är literalen av en oktalt tal Fysisk representation är fortfarande binärt
6 / 23 Tecken >>> ' ' # ange tecken: att föredra >>> '\u00a3' # anger unicode tecknet >>> '\N{POUND SIGN} # samma som ovan >>> '\xa3' # UTF kodningen direkt, platforms beroende
7 / 23 Varför? Unicode en global teckenmängd men igen datorrepresentation specifierat U+xyzu där xyzu är hexadecimalt tal (16 bit) Exportera till specifik kodning vid I/O istället Unicode nivån är bättre än konkret teckenkodning
1 Datatyper Tal UTF-8 2 Procedurell abstraktion Repetition av funktioner Exempel: spel Polymorfism Funktioner är objekt 3 Högre ordningens funktioner Funktioner som parametrar Lambda Returnera funktionsobjekt Map
9 / 23 Repetition av funktioner En kontrollstruktur Namngivet källkodsblock deklareras (nästan) som en variabel vi anropar funktionen vi kan skicka med parametrar returnerar när vi är klara Kallas även subritiner (subroutine) Finns i de flesta språken
10 / 23 Varför använda? Lösa det sammantagna problemet på abstraktare nivå (genom anrop) Samma kod kan återanvändas Lättare att läsa och underhålla Delproblem Kan göra ändringar utan att nödvändigtvis förstå helheten (!)
11 / 23 Lättläst, säkert, enkelt(?) Ett spel med 6 rader kod? board = load_board('level1.txt') while(game_not_over(board)): direction = input('enter direction (w,a,s,d): ') board = move_player(board, direction) display_board(board) print(`game over `) Uppgift 1: Ändra så att spelet startar om när det är slut. Uppgift 2: Ändra så att spelaren får välja nivå.
12 / 23 Polymorfism Generella funktioner ger kod som är återanvändbar Exempelvis: print(...) len(...) in
13 / 23 Exempel def intersect(list_a, list_b): res=[] for el in list_a: if el in list_b: res.append(el) return res Använding: intersect[[1,2,3,4],[0,2,4,6]] ==> [2, 4] intersect[[1,2,3,4],(0,2,4,6)] ==> [2, 4] intersect[['a','b','c','d'],'acdfgh'] ==> ['c', 'd']
14 / 23 Funktioner är objekt Minns du att funktioner är namngivna källkodsblock? ret_one är variabeln som innehåller funktionen Funktioner är speciella, de kan evalueras med call-funktionen Kan tilldela funktioner till andra variabler Vi kan skicka funktioner som parametrar! def ret_one(): return 1 print(ret_one) <function ret_one..> print(ret_one()) 1
15 / 23 Exempel: Funktionsobjekt def add_one(x): return x + 1 fn = add_one print( fn(3) ) print( add_one(3) )
1 Datatyper Tal UTF-8 2 Procedurell abstraktion Repetition av funktioner Exempel: spel Polymorfism Funktioner är objekt 3 Högre ordningens funktioner Funktioner som parametrar Lambda Returnera funktionsobjekt Map
17 / 23 Högre ordningens funktioner Funktioner som hanterar funktionsobjekt... Två sätt Funktionsobjekt som parametrar till funktion Funktionsobjekt som returneras av funktion Python har stöd för detta Referenser till funktionsobjekt via namnet (som vanliga variabler) Lambda - skapa nya funktionsobjekt direkt på en rad Inbyggda HO-funktioner för listor: map, filter...
18 / 23 Funktioner som parametrar Ser ganska lika ut... def add_all(li): result = 0 for i in li: result = result + i return result def sub_all(li): result = 0 for i in li: result = result 1 i return result li = [1,2,3] print( add_all(li) ) ==> 6 print( sub_all(li) ) ==> -6 Vad hette den där regeln igen...
19 / 23 Funktioner som parametrar DRY Funktioner kan skickas som parametrar och göra kod mer generell Detta är en användning av HO-funktioner def sum_all(li, fun): result = 0 for i in li: result = fun(result,i) return result def add(x, y): return(x+y) def sub(x, y): return(x-y) li = [1, 2, 3] print(sum_all(li, add)) => 6 print(sum_all(li, sub)) => -6
20 / 23 Lambda Men Pontus, det är jobbigt att skriva dom där funktionerna! Lambda-funktioner är anonyma funktioner som kan defineras direkt när vi behöver dem De är uttryck inte satsblock (skillnad från vanlig funktion) #Skrivs på formatet: lambda <param -1>, <param -2>...<param -n>: <uttryck > lambda x, y: x + y
21 / 23 Exempel: Lambda Används i princip som vanliga funktionsobjekt Returnerar resultatet av uttrycket automatiskt add = lambda x, y: x+y li = [1, 2, 3] print(sum_all(li, add)) ===> 6 print(sum_all(li, lambda x, y: x-y)) ===> -6
22 / 23 Returnera funktionsobjekt Eftersom vi kan skicka funktioner som parametrar är det rimligt att vi kan skicka tillbaka dem som returnvärden def inc(number): return lambda x: x + number inc_one = inc(1) inc_two = inc(2) print( inc_one(4) ) ==> 5 print( inc_two(4) ) ==> 6 print( inc(4)(3) ) ==>?
23 / 23 Inbyggda funktionen map [el_1, el_2,... el_n] [f(el_1), f(el_2),... f(el_n)] add_one = lambda x: x + 1 li = [1, 2, 3, 4] list(map(add_one, li)) # [2, 3, 4, 5] li_1 = [1, 2, 3, 4] li_2 = [2, 3, 4, 5] add_pair = lamda x, y: x + y list(map(add_pair, li_1, li_2)) # [3, 5, 7, 9] Applicerar funktionen på varje element i listan Kan ta flera listor och köra genom parallellt Antal argument till funktionen är antal listor Måste vara samma antal element Ger tillbaka ett objekt (konvertera till lista)
www.liu.se