Introduktion till programmering D0009E. Föreläsning 5: Fruktbara funktioner



Relevanta dokument
Introduktion till programmering SMD180. Föreläsning 5: Fruktbara funktioner

Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion

Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E. Föreläsning 4: Villkor och rekursion. Modulus-operatorn.

BEGREPP HITTILLS FÖRELÄSNING 2 SAMMANSATTA UTTRYCK - SCHEME DATORSPRÅK

Multipel tilldelning. Introduktion till programmering D0009E. Föreläsning 6: Iteration. while-satsen. Kom ihåg. Snurror kontra rekursion

Föreläsning 2 Programmeringsteknik och C DD1316

FÖRELÄSNING 2, TDDC74, VT2018 BEGREPP PROBLEMLÖSNING MED HJÄLP AV FALLANALYS PROBLEMLÖSNING MED HJÄLP AV REKURSION

Imperativ och Funktionell Programmering i Python #TDDD73. Fredrik Heintz,

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Språket Python - Del 1 Grundkurs i programmering med Python

DD1361 Programmeringsparadigm. Carina Edlund

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Tentamen i Introduktion till programmering

Grundläggande datalogi - Övning 1

Procedurer och villkor. Rekursiva procedurer. Exempel: n-fakultet

Procedurer och villkor

Introduktion till programmering SMD180. Föreläsning 9: Tupler

Kurslitteraturen. C-nivå Villkorssatser [kap 8] if & elif & else and & or Loopar [kap 9] for

Introduktion till programmering D0009E. Föreläsning 9: Tupler och dictionaries

Laboration: Whitebox- och blackboxtesting

Introduktion till programmering SMD180. Föreläsning 3: Funktioner

Algoritmer och datastrukturer H I HÅKAN S T R Ö M B E R G N I C K L A S B R A N D E F E L T

Programmering I Tobias Wrigstad fredag, 2009 augusti 28

729G04 Programmering och diskret matematik. Python 2: Villkorssatser, sanningsvärden och logiska operatorer

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

Metodanrop - primitiva typer. Föreläsning 4. Metodanrop - referenstyper. Metodanrop - primitiva typer

Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret Lektion 4

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?

Uppgifter teknik HT17 (uppdaterad v. 40)

FÖRELÄSNING 1 PERSONAL TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017 SYFTE EXAMINATION ORGANISATION

Rekursion. Att tänka rekursivt Att programmera rekursivt i Java Exempel. Programmeringsmetodik -Java 254

Sätt att skriva ut binärträd

Problemlösning och funktioner Grundkurs i programmering med Python

Föreläsning 5 Mer om funktioner, villkor

Föreläsning 4 Programmeringsteknik DD1310. Felhantering. Syntax. try och except är reserverade ord som används för hantering av exekverings fel.

Språket Python - Del 2 Grundkurs i programmering med Python

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk

Bakgrund. Bakgrund. Bakgrund. Håkan Jonsson Institutionen för systemteknik Luleå tekniska universitet Luleå, Sverige

Föreläsning 5-6 Innehåll

Kort om klasser och objekt En introduktion till GUI-programmering i Java

Föreläsning 3 Programmeringsteknik och Matlab DD1315. Importering av moduler. randrange

Introduktion till programmering SMD180. Föreläsning 12: Klasser och objekt

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata.

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

Hur man programmerar. TDDC66 Datorsystem och programmering Föreläsning 3. Peter Dalenius Institutionen för datavetenskap

Introduktion till programmering SMD180. Föreläsning 2: Variabler, uttryck och satser

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python TDDE24 Funktionell och imperativ programmering del 2

Rekursion och induktion för algoritmkonstruktion

JavaScript del 3 If, Operatorer och Confirm

Repetition i Python 3. Exemplen fac. Exemplen fac motivering. Exemplen fac i Python

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Föreläsning 13. Rekursion

Variabler och konstanter

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Föreläsning 6: Introduktion av listor

Föreläsning 13. Dynamisk programmering

Tekniska Högskolan i Linköping Institutionen för Datavetenskap (IDA) Torbjörn Jonsson Plot och rekursion

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

Övningshäfte 2: Induktion och rekursion

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017

Våra enkla funktioner eller procedurer

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

Platser för att skriva och testa kod online. Workshop om programmering i matematikkurser, version 0.7 senast sparat

729G74 IT och programmering, grundkurs. Tema 2, Föreläsning 2 Jody Foo,

Hej Då, Karel! Programmering. Vårt första Javaprogram. hh.se/db2004. Java. Grundtyper, variabler och arrayer

Föreläsning 3-4 Innehåll

Introduktion till programmering SMD180. Föreläsning 8: Listor

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Introduktion till programmering D0009E. Föreläsning 1: Programmets väg

Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Numeriska Metoder och Grundläggande Programmering för P1, VT2014

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

Funktionens deklaration

Ordlistor, filhantering och ut på webben. Linda Mannila

Föreläsning 6 Innehåll. Rekursion. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursiv problemlösning. Rekursion. Rekursivt tänkande:

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

Pythons standardbibliotek

C++ Slumptalsfunktioner + switch-satsen

Extramaterial till Matematik Y

Grundläggande datalogi - Övning 3

Funktioner. Linda Mannila

Föreläsning 10. Pekare (Pointers)

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

Programmeringsteknik med C och Matlab

Programmering i C, 7,5 hp

Kort om programmering i Python

v. 42 Python HT17 En introduktion Oscar Bergqvist

Kodexempel från Programmering 2 Tobias Wrigstad, Ph.D.

Funktioner forts. F3: Funktioner (kap. 5) Parametrar. findgear.m forts

EDAA20 Programmering och databaser. Mål komprimerat se kursplanen för detaljer. Om att lära sig programmera. Föreläsning 1-2 Innehåll.

HI1024 Programmering, grundkurs TEN

MMA132: Laboration 2 Matriser i MATLAB

Användarhandledning Version 1.2

Användar- och systemdokumentation

Transkript:

Introduktion till programmering D0009E Föreläsning 5: Fruktbara funktioner 1

Retur-värden Funktioner kan både orsaka en effekt och returnera ett resultat. Hittills har vi ej definierat några egna funktioner med resultat, däremot har vi ogenerat använt sådana funktioner: result = math.log( x ) print math.sin( radians ) Egna funktioner med resultat ("fruktbara funktioner") definieras med hjälp av en variant av return-satsen: def area( radius ): temp = math.pi * radius**2 return temp 2

return-satsen return-satsen finns alltså i två varianter: med eller utan retur-värde return return uttryck Båda varianterna avbryter aktuellt funktionsanrop. Kod som därmed aldrig kan exekvera kallas död kod: return -x print "This can never get printed" Det förra exemplet kan skrivas mer kortfattat som def area( radius ): return math.pi * radius**2 3

return-satsen En funktion kan innehålla flera return-satser: def absolutevalue(x): if x < 0: return -x else: return x Notera att denna funktion inte innehåller någon död kod! 4

return-satsen En funktion som når slutet av sin kropp returnerar automatiskt None. Betrakta följande funktion: def absolutevalue(x): if x < 0: return -x elif x > 0: return x Definitionen är helt korrekt enligt Python, men antagligen inte det som programmeraren tänkt sig! >>> print absolutevalue(0) None 5

Om rekursiva definitioner Rent circulär definition (dvs nonsens): äger (av äga) [v] modeord beskrivande företeelse eller person som äger Meningsfull rekursiv definition: fakultetsfunktionen! 0! = 1 n! = n*(n-1)! Exempel: 3! = 3*2! = 3*2*1! = 3*2*1*0! = 3*2*1*1 = 6 Så varför är detta inte nonsens? Svar: för att det finns ett basfall som inte är cirkulärt! 6

Fakultetsfunktionen i Python I stället för n! skriver vi i Python factorial(n) def factorial(n): if n==0: return 1 else: recurse = factorial(n-1) result = n * recurse return result Nyhet: en rekursiv funktion som returnerar ett resultat Basfallet identifieras genom att vi testar argumentet n 7

Programflödet för factorial(3) Eftersom n (dvs 3) inte är 0 tar vi else-grenen och beräknar factorial(n-1), dvs factorial(2) Eftersom n (dvs 2) inte är 0 tar vi else-grenen och beräknar factorial(n-1), dvs factorial(1) Eftersom n (dvs 1) inte är 0 tar vi else-grenen och beräknar factorial(n-1), dvs factorial(0) Eftersom n (dvs 0) är 0 tar vi basfallet och returnerar 1 omedelbart Variabeln recurse (som fått värdet 1) multipliceras med n (dvs 1) och resultatet 1 returneras Variabeln recurse (som fått värdet 1) multipliceras med n (dvs 2) och resultatet 2 returneras Variabeln recurse (som fått värdet 2) multipliceras med n (dvs 3) och resultatet 6 returneras 8

factorial(3) som stackdiagram -toplevelfactorial factorial factorial factorial n 3 recurse 2 result 6 n 2 recurse 1 result 2 n 1 recurse 1 result 1 n 0 6 2 1 1 9

I mer kompakt form def factorial(n): if n==0: return 1 else: return n * factorial(n-1) Denna variant är enklare i betydelsen mer koncis, men gör å andra sidan programflödet något svårare att följa Utmaningen är att kunna släppa fokus på programflödet, och börja se funktionsanrop och deras resultat som helt enkelt samma sak att "våga språnget" 10

Basfall och rekursionsfall Basfall ingen rekursion rekursionen stoppar Rekursionsfall ett steg närmare basfallet man måste närma sig basfallet (på något sätt!) Rekursionsantagande Rekursionsanropet löser sitt problem vi struntar i hur Vad återstår at göra? det sista steget från rekursionsanropet, till den färdiga lösningen? 11

Basfall och rekursionsfall def factorial(n): if n==0: return 1 Basfall else: return n * factorial(n-1) Rekursionsfall Rekursionsantagande: factorial(n-1) beräknar fakultetsfunktionen för (n-1) Fråga (man ställer sig): Om jag har fakulteten av (n-1), vad behövs då för att få fakulteten av n? 12

Den s k Fibonacci-funktionen 13 def fibonacci(n): if n==0 or n==1: return 1 else: return fibonacci(n-1) + fibonacci(n-2) Försök följa programflödet för t ex fibonacci(10), och huvudet börjar snurra... Men om vi i stället vågar språnget kan vi se ett mönster: n: 0 1 2 3 4 5 6 7 8 9 10... fibonacci(n): 1 1 2 3 5 8 13 21 34 55 89... Varje Fibonacci-tal är summan av de två föregående!

Inkrementell programutveckling Hur bygger man större funktioner än våra enkla exempel? Genom att bara "se" lösningen framför sig? Inkrementell programutveckling är en teknik som främjar stegvist byggande och testande av program, en liten detalj i taget Som exempel ska vi försöka implementera följande matematiska formel i Python: distance = ) 2 + ( ) 2 2 1 2 1 ( x x y y 14

Steg 1 Hitta rätt syn på programmet som helhet. Ska programmet utföra en beräkning som vi vill kunna upprepa med olika indata? I så fall pratar vi om att bygga en funktion I vårt fall ska vi beräkna avståndet mellan två punkter. Låt oss kalla funktionen för distance Vad är programmets indata? Dessa blir funktionens parametrar. I vårt fall vill vi kunna köra beräkningen med olika värden på x, y, x och y. Funktionens 1 1 2 2 huvud måste alltså bli def distance( x1, y1, x2, y2 ): 15

Steg 1 Eftersom programmets resultat ska vara ett decimaltal kan vi bygga en grov approximation till vår funktion genom att helt enkelt returnera värdet 0.0: def distance( x1, y1, x2, y2 ): return 0.0 Denna funktion är naturligtvis inte en korrekt lösning, men vi kan redan nu testa den för att elliminera eventuella syntaxfel i funktionshuvudet Om Python accepterar koden ska vi kunna köra >>> distance( 1, 2, 4, 6 ) 0.0 16

Steg 2 Här gäller det att identifiera några intressanta delresultat som är enkla att beräkna. I vårt fall är differenserna och y lämpliga kandidater x2 x 1 2 y1 Vi fångar dessa delresultat som lokala variabler som vi som en del av testningen skriver ut: def distance( x1, y1, x2, y2 ): dx = x2 - x1 dy = y2 - y1 print "dx is", dx print "dy is", dy return 0.0 17

Steg 2 Vi kan nu testköra igen: >>> distance( 1, 2, 4, 6 ) dx is 3 dy is 4 0.0 Viktig fråga: är denna output den förväntade? Att veta vad programmet borde göra är A och O vid testning Här har vi möjlighet att elliminera typiska slarvfel som att t ex skriva x1 där vi menar x2 18

Steg 3 Vi identifierar ytterligare ett delresultat: summan av de tidigare delresultaten i kvadrat def distance( x1, y1, x2, y2 ): dx = x2 - x1 dy = y2 - y1 dsquared = dx*dx + dy*dy print "dsquared is", dsquared return 0.0 Observera att de tidigare testutskrifterna är borta nu då de inte längre behövs I stället verifierar vi att samma körning som tidigare visar att dsquared får det förväntade värdet (dvs 25) 19

Steg 4 Vi är nu mycket nära en komplett lösning, endast en ny operation behöver utföras på det senaste delresultatet: def distance( x1, y1, x2, y2 ): dx = x2 - x1 dy = y2 - y1 dsquared = dx*dx + dy*dy result = math.sqrt( dsquared ) return result Här behövs ingen extra testutskrift, i och med att vi testar det slutliga beräkningsresultatet: >>> distance( 1, 2, 4, 6 ) 5.0 20

Tekniken i ett nötskal Skapa ett körbart program redan från början, även om allt väsentligt arbete återstår att göra Använd lokala variabler för delresultat, då blir de enklare att skriva ut vid testning Definiera en uppsättning testexempel där du redan vet vad det förväntade resultatet ska bli Testa varje steg i utvecklingen innan du går vidare När allt fungerar kan koden gärna komprimeras genom att spårutskrifter och tas bort och deluttryck sätts samman till större enheter 21

Vi har: Sammansatta uttryck en funktion som beräknar en cirkels area givet radien en funktion som beräknar avståndet mellan 2 punkter Om vi känner till centrum (xc, yc) av en cirkel och en punkt på kanten (xp, yp) kan vi skriva: radius = distance( xc, yc, xp, yp ) result = area( radius ) Som ett sammansatt uttryck: result = area( distance(xc,yc,xp,yp) ) Hur kan vi göra denna kod lite mer generell? 22

Funktionsinkapsling I stället för att bara anta att indata finns i några variabler, och bara lämna resultatet i en annan variabel, kan vi kapsla in vår beräkning som en funktion: def area2( xc, yc, xp, yp ): result = area( distance(xc,yc,xp,yp) ) return result Observera att namnen xc, yc, xp, yp och result nu är helt lokala de behöver inte kännas till (och kan inte kommas åt) av någon annan del av vårt program Dataflödet in och ut ur funktionen sker i stället helt via argument och returvärde: kalle = area2(i,j,i+1,j+1) 23

Boolska funktioner Funktioner som returnerar sanningsvärden, oftast resultat av tester (ja/nej-frågor): def isdivisible(x, y): if x%y == 0: return True else: return False Kan skrivas mer koncist: def isdivisible(x, y): return x%y == 0 24

Boolska funktioner Typisk användning är i if-satser: if isdivisible(x, y): print "x is divisible by y" else: print "x is not divisible by y" Korrekt, men onödigt krånglig variant: if isdivisible(x, y) == True: print "x is divisible by y" else: print "x is not divisible by y" 25

Djärvt påstående Det vi sett hittills av Python räcker för att uttrycka alla beräkningar som kan utföras av en dator! (variant av Turings tes, 1936) Om detta är sant, vad hände i så fall med byggstenen repetition (kap. 1)? Svar: vi har redan smugit in den byggstenen i och med att funktioner kan anropa varandra rekursivt! En annan fråga är hur bekvämt det är att utrycka saker och ting med endast nuvarande Python-delmängd... här är vårt motiv att fortsätta kursen (trots Alan Turings tes!) Men låt oss titta lite närmare på rekursion igen... 26