Pythons standardbibliotek Python 3 skall, enligt standarddokumenten http://docs.python.org/py3k/library/index.html ha stöd för vissa funktioner, typer och datastrukturer Så länge man håller sig till detta dokument har man garanti för att programmet fungerar oavsett vilken plattform man använder, Unix/Linux, Windows eller Mac. Vi skall titta på valda delar och har redan nämnt lite av det. En del extra bibliotek finns för t.ex. matematik. Sådana bibliotek måste man importera till sitt program när man vill använda dem. Det sker genom att man anger import math innan man anropar funktioner från bibliotektet DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 1 / 22
Standardfunktioner i Python, subjektivt urval abs(x) skickar tillbaka absolutvärdet av x om x är int eller float och magnituden om x är ett komplext tal ( x ) all(sekvens) Ger True om alla element i sekvensen ger True och False annars. D.v.s. all([1, 2, None]) ger False och (varning!) det gör all([1, 2, 0]) också! medan all([1, 2, 3]) ger True any(sekvens) Ger True om minst ett element i sekvensen ger True och False annars. bool([x]) OBS! notationen som säger att argumentet x är valfritt att skicka med. bool ger False om man inte skickar med ett argument eller man skickar med ett argument som (beräknas till) 0, False, tomma strängen eller någon tom sekvens eller tomma mängden. chr(i) Ger en sträng som är ett tecken lång och vars teckenkod är i. Hamnar man utanför [0..1114111] får man ett fel (ValueError) DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 2 / 22
Standardfunktioner... Python complex([real[, imag]]) Ger ett komplext tal, 0j om inget argument skickas med. Om första arg är en sträng måste den gå att tolka som ett komplext tal och då får man inte skicka med ett andra arg. Andra arg får aldrig vara en sträng dict([arg]) Skapar ett dictionary, en samling med (nyckel:värde)-par. Se www.nada.kth.se/kurser/su/da2001/sudata11/lankar/pythondict.php för en utförligare beskrivning. divmod(a, b) ger ett par (a // b, a % b) som resultat. Om man skickar med flyttal får man paret (q, a % b) där q = math.floor(a / b). float([x]) Om x skickas med måste det gå att tolka x som ett flyttal. Det kan vara en teckensträng, ett uttryck som ger ett tal tillbaka eller någonting som ger oändligheten eller nan som resultat. Det kan inte vara ett komplext tal. DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 3 / 22
Standardfunktioner... Python input([prompt]) Om man angivit en prompt så skrivs den ut utan radbyte. input läser sedan in hela den rad (utan radbrott) man skriver efter prompten och återsänder denna. int([number string[, base]]) Skapar en int (ett heltal) från ett tal eller en teckensträng om argumentet kan tolkas som ett tal. len(s) Återsänder antalet element i s om s är antingen en teckensträng, en tupel, en lista eller ett lexikon (dict). Om s är av annan typ får man ett TypeError list([iterable]) Återsänder en tom lista om man inte skickar med ett argument, annars försöker list tillverka en lista av iterable, t.ex.: list( hej ) [ h, e, j ] list((1, 2, 3)) [1, 2, 3] DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 4 / 22
Standardfunktioner... map(function, iterable,...) map tar en funktion (function) och applicerar funktionen på varje element i iterable. Om man har mer än en iterable måste funktionen ta ett argument för varje. Ett problem är att man får ett map -objekt tillbaka och inte samma typ av iterable som man en gång började med. Man kan naturligtvis konvertera sultatet till något användbart,ex.: in_x = input( mata in ett antal tal ) tmp_x = in_x.split( ) x = list(map(int, tmp_x)) Med inmatningen 1 2 3 får in_x värdet 1 2 3 och x värdet [1, 2, 3] max(x) Om x är en sekvens av något slag skickar max(x) ut det största värdet. Men max() kan mer än så: max([1, 2, 3] ger 3 max( a, b, c ) ger c min(x) Motsvarar max(x) men skickar ut minsta värdet i x DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 5 / 22
Standardfunktioner... Python ord(c) Om c är en teckensträng med ett tecken i så återsänds teckenkoden för c (c s plats i unicode-tabellen print([x,...], *, sep=, end= \n, file=sys.stdout) har vi redan pratat om en hel del. range([start], stop[, step]) skapar numeriska intervall, mest använda i for-loopar. list(range(5)) ger [0, 1, 2, 3, 4] list(range(1, 7, 2)) ger [1, 3, 5] round(x[, n]) round(3.5) ger 4 men med ett extra argument kan round() avrunda till ett visst antal decimaler. round(3.1415926, 6) ger 3.141593 Kan ibland ge konstiga resultat eftersom bråkdelar oftast inte kan representeras exakt. round(round(2.675, 2) ger t.ex. 2.67 DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 6 / 22
Standardfunktioner... Python set([x]) Skapar en mängd av x om det går. Enstaka värden fungerar inte utan det måste vara en sekvens av något slag. Varianten frozenset([x]) skapar en konstant mängd. str([x]) Skapar en strängrepresentation av x. Det finns möjlighet att specificera kodning sum(x[, start]) summerar start och elementen i x. Utelämnas start fungerar det som om start = 0 tuple([x]) Skapar en tupel (en ordnad sekvens) av x om det går. Kan inte ändras när den väl är skapad. DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 7 / 22
Operatorer på tal Python Det finns flera standardfunktioner men vi pratar om dem då vi stöter på dem. Om man vill ha mer än de vanligaste matematiska operatorerna måste man importera math-biblioteket. De vanligaste operatorerna är: x + y x - y x * y x / y x // y x % y -x abs(x) c.conjugate() vanlig division heltalsdivision resten vid division konjugatet av (komplexa talet) c divmod(x, y) paret (x // y, x % y) x ** y x y DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 8 / 22
Sanningsvärden Python Vilket objekt som helst kan användas som sanningsvärde. Då betraktas som osant (False) dels konstanterna None och False och dels alla värden som i någon mening betyder noll eller tom, d.v.s. alla numeriska 0, tomma sekvenser och lexikon (dictionaries). Alla andra värden betraktas som sanna (True) De booleska operatorerna or, and och not fungerar som vanliga men är kortslutande : x or y x and y not x if x then true else false if x then y else false if x then true else false DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 9 / 22
Jämförelser Python De aritmetiska jämförelseoperatorerna fungerar för alla ordnade typer (alltså inte för komplexa tal): < strikt mindre än <= mindre än eller lika med > strikt större än >= större än eller lika med == lika med!= skilt ifrån DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 10 / 22
Exempel: Fibonaccitalen Python Programmerade vi i scheme som (översatt till Python 3) def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2) n = input( n? ) print (fib(n)) Men det går inget vidare för stora n (testa inte, python kommer frysa ) DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 11 / 22
En svansrekursiv variant Python def fib(n, f1, f2): if n == 0: return f1 elif n == 1: return f2 else: return fib(n-1, f2, f1+f2) n = input( n? ) print (fib(n, 0, 1)) En stor vinst men ännu bättre att eliminera rekursionen helt och utnyttja Pythons tupler: DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 12 / 22
Exempel Python def fib(n): if n == 0: return 0 if n == 1: return 1 for i in range(1, n): f1, f2 = f2, f1 + f2 return f2 n = input( n? ) print (fib(n)) DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 13 / 22
Lite påpekanden, varningar och tips Kontroll av att indata är korrekta kan man få genom att initiera till None Ex.: i = None count = 0 while count < 3 and not i: try: count += 1 x = input( Mata in ett heltal: ) i = int(x) except ValueError: print(" " + x + " är inte ett heltal!") if not i: print("sorry 3 felinmatningar! Bye!") exit()... Gör inte så om du testkör i IDLE, eftersom du då avslutar IDLE DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 14 / 22
Exempel med lite påpekanden och varningar 1 Vanligt att man försöker hantera globala variabler men: globalx = 0.0 dictx = { x : 0} def change(globalx, d): print( enter change:, globalx, d[ x ]) globalx = 3.0 d[ x ] = 3.0 print( exit change:, globalx, d[ x ]) return print( before change:, globalx, dictx[ x ]) change(globalx, dictx) print( after change:, globalx, dictx[ x ]) before change: 0.0 0 enter change: 0.0 0 exit change: 3.0 3.0 after change: 0.0 3.0 Så vissa värden påverkas men inte andra. Lär er vilka! DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 15 / 22
Exempel med lite påpekanden och varningar... 2 globalx = 0.0 dictx = { x : 0} def change(): global globalx, dictx print( enter change:, globalx, dictx[ x ]) globalx = 3.0 dictx[ x ] = 3.0 print( exit change:, globalx, dictx[ x ]) return print( before change:, globalx, dictx[ x ]) change() print( after change:, globalx, dictx[ x ]) before change: 0.0 0 enter change: 0.0 0 exit change: 3.0 3.0 after change: 3.0 3.0 Hmmm... DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 16 / 22
Exempel med lite påpekanden och varningar... 3 Men Pythons funktioner kan sända ut mer än ett värde (som en tupel): x, y, z = 0.0, 0.0, 0.0 def change(x, y, z): print( enter change:, x, y, z) x, y, z = 3.0, 4.0, 5.0 print( exit change:, x, y, z) return x, y, z print( before change:, x, y, z) x, y, z = change(x, y, z) print( after change:, x, y, z) before change: 0.0 0.0 0.0 enter change: 0.0 0.0 0.0 exit change: 3.0 4.0 5.0 after change: 3.0 4.0 5.0 DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 17 / 22
Newton-Raphson i Python EPS = 10e-8 def main(): xin = input( Ange initial gissning på x: ) try: x = float(xin) except ValueError: print(" " + xin + " är inte ett tal!") else: x, c = newton(x, f) print( Fann nollställe, x =, x, efter, c, iterationer ) def f(x): return x * x - 3 * x - 3 def fprim(f, x): return float((f(x + EPS) - f(x - EPS)) / (2 * EPS)) def good_enough(x, nextx): return abs(x-nextx) < EPS DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 18 / 22
Newton-Raphson i Python... def next_x(x, f): return float(x - f(x) / fprim(f, x)) def newton(x, f, count): nextx = next_x(x, f) if count < 50 and not good_enough(x, nextx): return newton(nextx, f, count + 1) return nextx, count main() Men Python-funktioner kan skicka tillbaka funktioner DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 19 / 22
Newton-Raphson i Python... Ändra def main(): xin = input( Ange initial gissning på x: ) try: x = float(xin) except ValueError: print(" " + xin + " är inte ett tal!") else: fp = fprim(f) x, c = newton(x, f, fp, 0) print( Fann nollställe, x =, x, efter, c, iterationer ) def f(x): return x * x - 3 * x - 3 def fprim(f): def fp (x): return float((f(x + EPS) - f(x - EPS)) / (2 * EPS)) return fp DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 20 / 22
Newton-Raphson i Python... def good_enough(x, nextx): return abs(x-nextx) < EPS def next_x(x, f, fprim): return float(x - f(x) / fprim(x)) def newton(x, f, fp, count): nextx = next_x(x, f, fp) if count < 50 and not good_enough(x, nextx): return newton(nextx, f, fp, count + 1) return nextx, count main() DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 21 / 22
Newton-Raphson i Python... Men vi kan också eliminera rekursionen: def newton(x, f, fp): count = 0 nextx = next_x(x, f, fp) while abs(x-nextx) > EPS and count < 50: x = nextx nextx = next_x(x, f, fp) count += 1 return nextx, count och måste då naturligtvis ändra lite i main Eftersom Python inte kan eliminera svansrekursion är det alltid bäst att hitta iterativa lösningar. DA2001 (Föreläsning 11) Datalogi 1 Hösten 2011 22 / 22