550 likes | 799 Views
Introduktion til programmering. Uge 43 Computer Science, kap 5 + 8 (minus kap 8.6). . Sidste gang. Funktioner som metode til at skrive anvendelsesorienterede programmer Metoderne i et modul kan tolkes som teknisk implementering når vi læser modulet
E N D
Introduktion til programmering Uge 43 Computer Science, kap 5 + 8 (minus kap 8.6).
Sidste gang • Funktioner som metode til at skrive anvendelsesorienterede programmer • Metoderne i et modul kan tolkes som teknisk implementering når vi læser modulet • Men de kan tolkes som beskrivelser af anvendelsesområdet når vi blot bruger modulet • Indkapsling af implementeringsdetaljer. • Netværk og netværksopbygning • Protokoller, smtp, http, ftp, pop3 osv. • Netværksprogrammering i Python, smtp, http • Operativsystemer (nåede vi ikke), styring af filsystem, multiple processer osv.
Opgaver mm • Når I afleverer opgaver skal jeg have jeres tilrettede databasemodul. • I skal aflevere så meget at jeg kan køre jeres program. • Jeg ved godt at der er problemer med serveren, men det skulle gerne virke nu (håber vi, det gjorde det i går)
Plan • Algoritmer • Definition • Opbygning • Pseudokode (teoretisk) • Analyse • Kompleksitet • Eksempler • Binær søgning • Øvelse 1 • Rekursion (algoritmisk løsningsmodel) • Eksempler • Binær søgning • Generering af tekster • Datastrukturer • Userdefined • ADT (abstract data type) • Eksempler • Enkeltkædede lister, dobbeltkædede lister • Stakke, køer • Træer • Øvelse 2
Algoritmer 1 • Der er forskellige definitioner • Stort set konsensus om at: • En algoritme genererer en ordnet, entydig og endelig sekvens af • operationer der med garanti slutter • Ordnet • Skridt efter hinanden, evt repetitioner • Entydig • Ingen valgfrihed (deterministisk) • Ingen flertydighed • Endelig • Den vil slutte • ... men måske først om 1000 år ... • Kogebøger, strikkeopskrifter, how-to etc. • Muslingeprogrammet er en algoritme
Algoritmer 2 • En algoritme i datalogien er en generel metode til at løse et bestemt problemtype • Eks. søge i en liste, sortere en liste. • “Et program = en algoritme” er noget sludder • Programmer repræsenterer mange algoritmer der virker sammen. • Der findes mange algoritmer til at løse det samme problem • Lineær og binær søgning er to forskellige algoritmer • De løser problemet at finde et element i en liste • Forskellige karakteristika • Tid, plads • Forskellige datatyper • træer, lister
Algoritmer, opbygning • Algoritmer er sproguafhængige • Kan beskrives i mange forskellige sprog rettet mod mange forskellige fortolkere • Kan beskrives på en stiliseret sprogform, pseudokode • Pseudokode er • en notationsform skrevet for en menneskelig fortolker • men orienteret mod omskrivning i et programmeringssprog der kan læses af maskiner • Pseudokode kan Implementeres på mange måder så den kan køre på en maskine • Pseudokode beskriver generel struktur, ikke detailjer
Muslingeeksemplet • Så længe der er muslinger i spanden: • Tag en musling op af spanden • Hvis muslingen er lukket så: • Smid den i gryden • Ellers: • Smid den i affaldsposen • Struktureret dansk • Viser struktur men ingen detaljer • Vælger danske konstruktioner der har en analog til programmeringssprog • Når vi forklarer hvordan et loop fungerer er det også seudokode
Muslingeeksemplet 2 • CS’s notation • Ligner et programmeringssprog lidt mere • () markerer afsnit der skal beskrives mere nøjagtigt • Angiver hvilket input og output algoritmen skal have • Fordel (A, B, C) • Input: en liste A af ting og to tomme lister B og C • Output: A er tom. Tingene er fordelt på B og C • while (der er ting i A) do: • (Tag en ting op af A) • Hvis (tingen er lukket) så: • (Læg den i B) • Ellers: • (Læg den i C)
I Python • def fordel(A,B,C): • while A <> []: • enTing = A[0] • del A[0] • if enTing == 0: • B.append(enTing) • else: • C.append(enTing) • >>> A = [1,0,1,0,1,1,0] • >>> B = [] • >>> C = [] • >>> fordel(A,B,C) • >>> A • [] • >>> B • [0, 0, 0] • >>> C • [1, 1, 1, 1]
I Java • I java ser det noget anderledes ud men det er den samme algoritme vi har implementeret. • Javaprogram
Et endnu mere formelt eks • Finder det største element i en liste • AlgorithmlistMax(A, n): • Input: en liste Amed n ≥1 tal • Output: det største element i A • currentMax←A[0] • fori ←1 ton-1 do • ifcurrentMax< A[i] then • currentMax←A[i] • returncurrentMax
I Python • def listMax(A): • currentMax = A[0] • for i in range(1, len(A)): • if currentMax < A[i]: • currentMax = A[i] • return currentMax • >>> listMax([1,3,2,4,9,4]) • 9 • >>>
Guideline • Udvikl algoritmen i struktureret dansk eller en lidt mere formel pseudokode • Check at logikken er OK • Oversæt til programmeringssprog og test algoritmen på eksempler • Ret fejl • i logik • i implementering • Publicer!
Algoritmer, analyse • Væsentligt område af datalogien • Analyse af korrekthedog udførselstid • Kræver følgende: • Sprog til at beskrive algoritmer • Pseudokode eller struktureret dansk • En model for beregninger • “Primitive operationer” (f.eks. en sammenligning) • En metrik • Store Θ • Hvorfor? • For at være maskinuafhængig
Primitive operationer • Tildelingsoperation • currentMax = A[0] • Metodekald / funktionskald • listMax([1,3,2,4,9,4]) • Aritmetisk operation • A = A+1 • Sammenligning • currentMax < A[i]: • Indeksering • A[i] • Returnere fra en metode • return currentMax
Eksempel ListMax • initialisering : i= 1 • 1 operation • initialisering: currentMax = A[0] • 2 operationer • Sammenligning i<=n • n operationer • Løkken udføres n-1 gange: • currentMax < A[i] • 2 operationer • Muligvis: currentMax = A[i] • 2 operationer • i = i+1 • 2 operationer • Løkken indeholder 4 eller 6 operationer • Returnering af værdi: returncurrentMax • 1 operation def listMax(A,n): i = 1 currentMax = A[i] while i<= n: if currentMax < A[i]: currentMax = A[i] i = i+1 return currentMax X = [1,4,3,5,7,9,10] print listMax(X,len(X)-1)
Kompleksitet • For input n • Best case: Hvis der aldrig sker noget med currentMax • 2+1+n+4(n-1) +1 = 5n • Worst case: Hvis der altid sker noget med CurrentMax • 2+1+n+6(n-1)+1 = 7n-2 • Konstanter smides væk • O(n) • Lineær udførelsestid, tiden vokser med inputtet
Store O • Store O betyder: • En funktion er “mindre end eller lig med” en anden funktion der udvikler sig på en bestemt måde • O(n): den anden funktion er lineær • Logaritmisk: O(log n) - binær søgning • Lineær: O(n) - sekventiel søgning • Kvadratisk: O(n2)
Vi ser kun på den generelle kurve • Lineær: n • Kvadratisk: n2 • Logaritmisk: log2 n
Eksempel: Søgning • Problem: Givet en mængde data, søg efter et element der opfylder et kriterie • Eks: find største element i en liste • Algoritmevalg afhænger af egenskaber ved mængden af data • Usorteret: sekventiel søgning • Sorteret: Binær søgning
Sekventiel søgning • Gennemløber hele mængden (listen) en efter en • Skal se på alle elementer i det værste tilfælde • Lineær • Eks: givet en liste, findes elementet med værdien ‘88’ i listen? • O(n)
Binær søgning • Forudsætter at listen er sorteret!!! • Forudsætter man kan indeksere alle indgange direkte (ikke linked lists) • Halvering af søgeområdet i hvert skridt • O(log n) • antal søgninger hvis der er 1024 elementer er max log2(1024) = 10 fordi 210 = 1024 • 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2
Binær søgning, Pseudokode • procedure binSearch(x, nums): • Input:sorteretlistenums plus et talx som vi vilsøgepå • Output:tallets position i listen hvisdetfindes, ellers -1 • low = 0 • high = (nummeretpå listens sidste element) • while (derstadigernoget at søgei) do: • mid (midtenaf listen afgrænsetved low og high) • item (elementetderliggerimidlten) • if x= item then: • return mid • else if x < item: • high mid – 1 (førstehalvdelaf listen) • else: • low mid + 1 (sidstehalvdelaf listen) • return -1
Binær Søgning, Python • def binSearch(x, nums): • low = 0 • high = len(nums)-1 • while low <= high: • mid = (low + high)/2 • item = nums[mid] • if x == item: • return mid • elif x < item: • high = mid - 1 • else: • low = mid + 1 • return -1 • aList = [1,2,5,7,10, 12, 67, 100] • print binSearch(12,aList) • print binSearch(234,aList) • --- • >>> • 5 • -1 • >>>
Binær søgning def binSearch(x, nums): low = 0 high = len(nums)-1 while low <= high: mid = (low + high)/2 item = nums[mid] #dump variables print nums, low, mid, item, high if x == item: return mid elif x < item: high = mid - 1 else: low = mid + 1 return -1 nums, low, mid, item, high • Søgning efter 12 • [1, 2, 5, 7, 10, 12, 67, 100] 0 3 7 7 • [1, 2, 5, 7, 10, 12, 67, 100] 4 5 12 7 • 5 • Søgning efter 234 • [1, 2, 5, 7, 10, 12, 67, 100] 0 3 7 7 • [1, 2, 5, 7, 10, 12, 67, 100] 4 5 12 7 • [1, 2, 5, 7, 10, 12, 67, 100] 6 6 67 7 • [1, 2, 5, 7, 10, 12, 67, 100] 7 7 100 7 • -1 position position værdi position
Forskellen mellem lineær og binær søgning • Viser sig først ved store datamængder • En liste på 12 000 000 ord • Lineær søgning: • I snit 6 000 000 sammenligninger • Worst case: 12 000 000! • Binær søgning • Worst case: 24 sammenligninger!
Algoritmer tommelfingerregler • Heldigvis er mange af de algoritmer vi skal bruge såsom sortering osv. implementeret i Python så vi ikke selv behøves at gøre det. Eller også er der rig mulighed for at finde eksempler på nettet, så vi ikke skal begynde helt fra bunden • Når vi skal lave vores egne algoritmer skal vi ikke i første omgang tænke på hastighed, men bare at få det til at virke. Vi kan altid erstatte en algoritme med en anden, hvis vi finder ud af at den er for langsom eller at der findes andre til at erstatte den med • Det er typisk kun i arbejdet med store data-sæt vi skal være opmærksomme
Øvelse 1 • Implementer database i MySQL
Rekursion • Det at løse en delopgave efter samme metode som hovedopgaven • Del og hersk • Rejse fra Århus til København • Rejse fra Århus til Æbeltoft • Rejse fra Æbeltoft til Odden • Rejse fra Odden til København • Fortælle en historie • Fortælle om miljø og personer • Fortælle om hovedpersonernes strid • Fortælle om udfaldet • Meget elegant måde at løse et problem på
Syntaktisk specifikation af programmeringssprog • Uddrag fra Pythons specifikation • compound_stmt::= if_stmt| while_stmt | … • if_stmt ::= • "if" expression ":" suite ( "elif" expression ":" suite )* ["else" ":" suite] • suite ::= … |NEWLINE INDENT statement+ DEDENT • statement ::= … |compound_stmt • Notation • ::= betyder ’består af’. • | betyder ’eller’ • [] betyder frivilligt • ()* betyder ’nul eller flere gange’ • ()+ betyder ’en eller flere gange’
Effektiv rekursion • Fremgangsmåde • Basis tilfældet: • Involverer ikke rekursion men kun primitive operationer der umiddelbart kan udføres • Det rekursive tilfælde: • Involverer rekursion men for et simplere problem
Rekursiv binær søgning • def binSearchStart(x, nums): • print 'binary recursive search after ' + str(x) + ' in ' + str(nums) • return binSearchRec(x, nums, 0,len(nums)-1) • def binSearchRec(x, nums,low,high): • if low <= high: • mid = (low + high)/2 • item = nums[mid] • if x == item: #base case • return mid • elif x < item: #recursive case • return binSearchRec(x, nums, low, mid - 1 ) • else: #recursive case • return binSearchRec(x, nums, mid+1, high) • else: #base case • return -1 Basistilfældet: primitiv operation: return True Rekursion 1: en mindre liste Rekursion 2: en mindre liste
Endnu et rekursivt eksempel • Er det givne ord et palindrom? • def palindrome(string): • if(len(string) <= 1): #erlængdennulellerénsåsandt • return True • elif string[0] == string[len(string)-1]: #ellers, er den førsteogsidstekarakterens? • return palindrome(string[1:-1]) #hvisjaskærdemfraogkaldfunktionenigen • else: • return False • if __name__ == "__main__": • print palindrome("aibohphobia") >>>True Saippuakivikauppias, Finnish for "soap-stonevendor"
Rekursiv generering af sætninger • S ::= N VP • NP ::= N | N som VP | at S • VP ::= VT NP | VI • N ::= Anders | Bent | Christina • VT ::= så | hørte | forstod • VI ::= løb | sov | lo • Kommer som opgave i uge 45 Syntaks: rekursivt tilfælde S Ordbog: basistilfælde VP NP
Eksempler • Anders så Bent • Christina løb • Bent hørte Bent • Anders så Bent som hørte Bent • Anders sov • Christina lo • Christina forstod Christina som lo • Bent så Bent • Christina sov • Christina opdagede Bent som så Anders • Bent sov • Anders så at Anders forstod at Christina sov • Anders lo • Anders så Bent som forstod at Anders lo • Anders forstod Bent • Bent opdagede Anders • Bent forstod Anders • Anders hørte at Bent løb • Anders løb • Bent hørte Christina som løb • Bent forstod Anders som løb • Anders opdagede Anders som sov • Anders hørte Christina som forstod Bent • Anders forstod Christina som løb • Bent forstod Christina som sov
Mulig implementering • kategori ::= mulighed1 | mulighed2 | … mulighedn • def kategori(): • choice = random.randint(1,n) • if choice == 1: • return mulighed1 • elif choice == 2: • return mulighed2 • … • else: • return mulighedn
Eksempel import random Random tilbyder en række funktioner der har med tilfældighed at gøre • Regel: • NP ::= N | N som VP | at S • Implementering: • def NP(): • choice = random.randint(1,3) • if choice == 1: • return N() • elif choice == 2: • return N()+ ' som' + VP() • else: • return ' at' + S() • Eksempler • Anders løb • Christina så at Christina løb • Anders opdagede Bent som sov • Anders løb • Bent så Anders Basistilfælde Rekursivt tilfælde Rekursivt tilfælde
Datatyper • Datatyper er • Mulige værdier, samt • relaterede operationer • Eks. Integers (heltal) • Værdier: alle hele tal fra -∞ til ∞ • Reelt: begrænset af maskinen • Operationer: +, -, *, / etc. • Typesystemet kan udvides • Brugerdefinerede typer: sammensatte værdier (og operatoroverloading) • Konto:ejer, indestående, renteprocent • ADT, Abstrakte Data Typer: brugerdefinerede typer + operationer • Konto:ejer, indestående, renteprocent (og) hæve, indsætte, rentetilskrivning • Klasser og objekter: ADT + nedarvning • I python ligner typer klasser • Moduler indeholder ofte klasser man kan bruge
Definition af klasser • class Konto: • def __init__(self,navn, indestaaende, rentesats): • self.navn = navn • self.indestaaende = indestaaende • self.rentesats = rentesats • def indsaet(self,beloeb): • self.indestaaende += beloeb • def haev(self,beloeb): • self.indestaaende -= beloeb • def tilSkrivRenter(self): • self.indestaaende += self.indestaaende * self.rentesats/100 • def udSkrivSaldo(self): • print 'Saldo for ' + self.navn • print self.indestaaende
Brug af klasser • >>> minKonto = Konto('Peter Vahlstrup',1000,5) • >>> minKonto.udSkrivSaldo() • Saldo for Peter Vahlstrup • 1000 • >>> minKonto.indsaet(200) • >>> minKonto.udSkrivSaldo() • Saldo for Peter Vahlstrup • 1200 • >>> minKonto.haev(100) • >>> minKonto.udSkrivSaldo() • Saldo for Peter Vahlstrup • 1100 • >>> minKonto.tilSkrivRenter() • >>> minKonto.udSkrivSaldo() • Saldo for Peter Vahlstrup • 1155 • >>> minKonto UML Navn Attributter minKonto.indestaaende Metoder minKonto.indsaet()
Lister • Værdi: • nul eller flere elementer • Operationer: • append(...) • count(...) • extend(...) • index(...) • insert(...) • pop(...) • remove(...) • Reverse (...) • sort(...) • Man skriver navnet på objektet, ’.’, plus operationen • x.append(7) Repræsentamen X x.operation() Objekt listeelementer operationer
Typer og instanser • Eksperiment • >>> type(1) • <type 'int'> • >>> type(int) • <type 'type‘> • >>> type(type) • <type 'type'> • >>> type(Konto) • <type 'classobj'> • >>> type(minKonto) • <type 'instance'> • Typer og deres medlemmer er forskellige objekter. • Forskellen mellem en kageform og en kage. • 1 er en instans (er medlem) af typen int. • Int er ikke selv en instans of int men af typen type. • (men Type er selv en instans of typen Type!)
Bruger-definerede typer • Eksempler • Enkelt-trådede lister • Dobbelt-trådede lister • Stakke • Køer • Træer • Skal implementeres ved hjælp af eksisterende operationer • Disse skjules for brugeren af typen
Enkelt-trådede lister • Skal ikke forveksles med python lister [] • En liste er en række elemeter der er kædet sammen. Hvert element indeholder en variabel, next, der peger på næste element i listen, og vil desuden ofte indeholde en anden værdi med data • Vi har “adgang” til det første element i listen, og derigennem det næste (Egon Olesen fører til James Bond, der fører til Rambo) • Men vi kan ikke gå baglæns (Dirty Harry fører ikke til noget)
Dobbelt-trådede lister • Data, next og prev • Her kan vi gå begge veje
Stak • LIFO • Har følgende metoder: • push(elem) -> nil: påtag dig ny opgave og udsæt den nuværende • pop() -> elem (sletter): afslut nuværende og genoptag afbrudt opgave • top() -> elem (sletter ikke): hvad var det jeg var i gang med • isEmpty() -> boolean: er jeg færdig for i dag? • size() -> integer: hvor mange ting venter?
Kø • En kø er FIFO • Har følgende metoder: • enqueue(elem) -> nil: stil dig i kø • dequeue() -> elem at front: betal ved kassen • size() -> integer: hvor mange kunder venter? • isEmpty() -> boolean: er køen tom?
Træer • En datastruktur bestående af en række knuder (noder) • En node kan have nul eller flere børn og nul eller én forælder • En node uden børn kaldes et blad. Rod Direktør Knude Mellemleder Mellemleder Mellemleder Arbejder Arbejder Arbejder Arbejder Arbejder Arbejder Arbejder Blad