lecture12.ppt · 2010-10-12 · 10/12/2010 2 l u l e Å t e k n i s k a u n i v e r s i t et s y s...
TRANSCRIPT
10/12/2010
1
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
1
Introduktion till programmeringD0009E
Föreläsning 12: “Klasser och funktioner”
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
2
Tid som en Python-klass
� En tämligen enkel klassdefinition:class Time:
hours = 0minutes = 0seconds = 0
� Användning:time = Time()time.hours = 11time.minutes = 59
Notera att både hours och minutes har muterat från ursprungsvärdet0, men vi bryr oss inte längre om att visa variablers historia i våratillståndsdiagram om det inte är absolut nödvändigt
hours 11minutes 59seconds 0
time
� Tillståndsdiagram:
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
Klasser är som typer
3
int float
i x
Klass för tid:
hours (heltal (int))minutes (heltal (int))seconds (heltal (int))
Time
y 103140
113513
tid1 tid2
Enkla typer:
4 6,8 3,7
typ/klass:
värde/instans:
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
4
Summering av tid
� Låt oss definiera en funktion sum(t1, t2), som returnerar summan av tiderna t1 och t2def sum(t1, t2):
t = Time()t.hours = t1.hours + t2.hourst.minutes = t1.minutes + t2.minutest.seconds = t1.seconds + t2.secondsreturn t
� Låt oss vidare anta att vi har en funktion printTime(t) som skriver ut information från ett tidobjekt t på formen hours:minutes:seconds (övning 13.1!)
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
5
Summering av tid
� Vi vill addera tidpunkten 10:15:0 (lektionsstart) och tiden 1:30:0 (längden av en lektion)>>> start = Time()>>> start.hours = 10>>> start.minutes = 15>>> length = Time()>>> length.hours = 1>>> length.minutes = 30>>> stop = sum(start, length)>>> printTime(stop)11:45:0
� Tycks fungera bra. Men vad händer om vi börjar 14:45?
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
6
Summering av tid
� Lektionen rapporteras sluta kl 15:75:0! Ej korrekt!� Rättad version av sum, som tar hänsyn till problemet:def sum(t1, t2):
t = Time()t.hours = t1.hours + t2.hourst.minutes = t1.minutes + t2.minutest.seconds = t1.seconds + t2.secondsif t.seconds >= 60:
t.seconds = t.seconds - 60t.minutes = t.minutes + 1
if t.minutes >= 60:t.minutes = t.minutes - 60t.hours = t.hours + 1
return t
10/12/2010
2
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
7
Summering av tid
� Vår funktion sum(t1,t2) är nu korrekt, men möjligen lite väl lång. Vi ska strax titta på en kortare variant
� Först ska vi dock undersöka ett principiellt annorlunda alternativ till att returnera resultatet som ett nytt objekt: def increment(t, s):
t.seconds = t.seconds + sif t.seconds >= 60:
t.seconds = t.seconds - 60t.minutes = t.minutes + 1
if t.minutes >= 60:t.minutes = t.minutes - 60t.hours = t.hours + 1
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
8
Summering av tid
� Funktionen increment(t, s) returnerar inget resultat, i stället orsakar den en bestående effekt: argumentet tmuterar genom att s sekunder läggs till
� Men vad händer om s > 60? Här behövs en korrigering:def increment(t, s):
t.seconds = t.seconds + swhile t.seconds >= 60:
t.seconds = t.seconds - 60t.minutes = t.minutes + 1
while t.minutes >= 60:t.minutes = t.minutes - 60t.hours = t.hours + 1
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
9
Summering av våra övningar
� Vi har konstruerat två funktioner, sum och increment, som var för sig erbjuder en lösning på problemet att summera tid
� Funktionen sum är en ren funktion – den returnerar ett resultat utan att orsaka några bestående effekter
� Funktionen increment är en modifierare – den orsakar mutation i ett argument, men returnerar inget resultat
� I båda varianterna har vi dessutom gjort konstruktionsmissar som vi sedan fått korrigera
� Och båda funktionerna har fortfarande utrymme för effektivitetsförbättringar...
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
10
Så vilken stil är bäst?
Rent funktionell stil
Är bättre på att avspeglamatematiska begrepp
Undviker alias-problemetgenom att inte mutera data
Resulterar ofta i korrektkod på kort tid
Modifierare
Är bättre på att efterliknabeteenden i verkliga världen
Utnyttjar alias-fenomenettill fullo
Resulterar ofta i effektivaremen ibland mer komplex kod
Frågan i vårt fall är hur vi ser på begreppet tid... Är tid ett matematisktbegrepp, eller ett objekt i den verkliga värden som vi vill simulera?
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
11
Om programutveckling
� I båda våra försök att summera tid utvecklade vi programkoden genom att bygga prototyper –funktioner som vi tyckte var ungefärligen rätt och som vi sedan testade och korrigerade efter hand
� Prototyp-baserad utveckling kan vara mycket effektiv, om man har rätt "känsla" för problemet
� Prototyp-baserad utveckling kan samtidigt leda till kod som är komplicerad och svårbedömd, som ett resultat av ett planlöst lappande och fixande för varje bug...
� Ett komplement till prototyp-baserad utveckling kan därför vara planering, utgående från en djupare förståelse om vad problemet egentligen handlar om
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
12
Summering av tid – planering
� I stället för att rusa iväg och lösa uppgiften utgående från hur tid representeras på ett digitalur...
� ... kan vi konstatera att de flesta av oss uppfattar tid som en en-dimensionell linje!
� Summering av tid är inget annat än förflyttning längs denna linje, vilket inte borde vara så krångligt att uttrycka
� Insikt: tid är egentligen ett en-dimensionellt värde på tidsaxeln som vi väljer att representera som timmar, minuter och sekunder (för att lättare kunna skilja ut de stora dragen från detaljerna)
� Slutsats: vi behöver kunna konvertera mellan dessa former!
10/12/2010
3
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
13
Konverteringsfunktioner
� Låt oss välja att gradera tidsaxeln i sekunder
� Konvertering till denna enhet:def convertToSecs(t):
minutes = t.hours * 60 + t.minutesreturn minutes * 60 + t.seconds
� Konvertering till traditionell representation:def convertToTime(seconds):
t = Time()t.hours = second / 3600t.minutes = (seconds % 3600) / 60t.seconds = seconds % 60return t
L U L E Å T E K N I S K A U N I V E R S I T ETD 0 0 0 9 ES Y S T E M T E K N I K
INTRODUKTION TILL PROGRAMMERING
14
Summering av tid (sista gången!)
� En förbluffande enkel operation:def sum(t1, t2):
seconds = convertToSecs(t1) + convertToSecs(t2)return convertToTime(seconds)
� Som extra bonus kan vi nu enkelt beräkna tidsskillnader:def diff(t1, t2):
seconds = convertToSecs(t1) - convertToSecs(t2)return convertToTime(seconds)
� Samma sak med multiplikation (hur mycket tid är 16 lektioner à 1 timme 30 minuter?)
� Sens moral: ibland kan lösningen bli enklare om man ger sig på ett lite generellare ("svårare") problem än man först hade!