729G04 PYTHON 5 JODY FOO Department of Computer and Information Science (IDA) Linköping University, Sweden
Föreläsningsöversikt Repetition av listmetoder Scope Defaultvärden Algoritmer & mera rekursion Linjär och binär sökning Flödesdiagram Pseudokod Programmering som problemlösning Kodstil
DEFAULTVÄRDEN FÖR FUNKTIONSARGUMENT
Värde på argument om inget annat anges def greet(name="zorro"): print "Hello " + name + "!" >>> greet() 'Hello Zorro!' >>> greet("el Maco") 'Hello El Maco!' >>> Ibland vill vi kunna säga till en funktion att den ska anta ett visst värde på argumentet om vi inte säger något annat.
Sätt att ange parametrar def eggs(size, colour="red", boiled=true):... # Alla nedanstående anrop är OK! eggs(5) eggs(5, "green", False) eggs(2, boiled=false) eggs(boiled="false", colour="green", size=4) Om man namnger argument får man skicka dem i vilken ordning som helst. Icke namngivna argument måste stå i rätt ordning. Argument utan defaultvärde måste skickas till anropet.
DEMO AV DEFAULTVÄRDEN HTTPS://WWW.IDA.LIU.SE/CODELA/AS/729G04/05DEFAULT
SCOPE
KAN DAVID RÄCKA UPP HANDEN TACK?
Scope - ingen david definierad i detta klassrum! Fråga internet - David? Gå ut på stan och fråga efter David?
Var finns min variabel? Var en variabel definieras påverkar hur "synlig" den är. Variabler i funktioner syns bara i funktionen de definierades i. De är lokala variabler. Variabler som definieras utanför funktioner är globala variabler och kan ses innifrån en funktion. För att tilldela (med =) en global variabel ett annat värde lokalt i en funktion - använd nyckelordet global i funktionen.
Scope - globala och lokala variabler name = "Sam" def greeting_local_name(): name = "Ham" greeting = "Hello" print(greeting, name) def greeting_global_name(): global name name = "Spam" greeting = "Hello" print(greeting, name) def greeting(greeting, name): print greeting + name greeting_local_name() Variabel Värde name "Ham" greeting "Hello" greeting_global_name() Variabel Värde name "Spam" greeting "Hello" greeting() Variabel Värde name lokalt argument greeting lokalt argument
Använda globala variabler treasure_locations = [] def add_treasure_location_to_global(location): global treasure_locations treasure_locations += [location] def add_treasure_location_to_local(location): treasure_locations += [location] Den andra funktionen kommer att resultera i ett felmeddelande eftersom variabeln treasure_locations inte finns definierad i den kontexten.
Block har inga egna lokala variabler my_name_is = "Slim Shady" for i in range(5): my_name_is = my_name_is + " " + str(i) print my_name_is print my_name_is for-blocket har ingen egen lokal variabelrymd, utan delar den med den yttre kontexten.
Tips om debugging Mot slutet på varje kapitel i Think Python finns tips på sätt som man kan debugga sin kod.
ALGORITMER
Algoritmer Beskrivning av systematisk lösning av en specifik uppgift Exempel hur man sorterar en lista hur man söker efter något i en trädstruktur hur man använder ett viss schiffer hur man räknar ut vilken väg som är kortast mellan två platser hur man känner igen termer i en text hur man konvertera ett decimaltal till ett binärt tal
EXEMPEL: VEM ÄR LÄNGST?
Vem är längst? A B C
Vem är längst? 120 100 160 A B C
Vem är längst? A B C D E F G H I 1 2 3 4 5 6
Vem är längst? A B C D E F G H I 1 1 2 71 6 56 5 57 55 84 2 17 89 13 31 22 30 34 65 61 3 69 3 2 62 68 86 8 23 67 4 14 7 2 32 7 11 63 60 16 5 32 2 70 89 3 72 68 59 15 6 53 7 24 8 26 28 67 54 64
Egenskaper hos problem När är ett problem svårt? Var det andra problemet svårare? Hur definierar vi svårt? Hur tar vi egentligen reda på vem som var längst? Vad måste vi göra?
Från "datorns" perspektiv Har datorn en översiktsbild? Kan datorn titta på en hel lista på en gång? Datorn kan "titta" på ett element i taget Vi måste tillhandahålla arbetsminne Datorn kommer inte ihåg något "automatiskt"
Hur datorn "ser" listan [5, 20, 30, 40, 42] Till exempel genom att använda en for-loop
5
20
30
40
42
ATT BESKRIVA EN ALGORITM: PSEUDOKOD OCH FLÖDESDIAGRAM
Pseudokod Nästan kod Fast med lite mer naturligt språk behöver inte ha med alla variabeldeklarationer är programspråksneutral gör det lättare att abstrahera Nivån på psudokoden kan varieras från väldigt kodnära till mer abstrakt (övergripande)
Pseudokodsexempel def plocka_ut_siffror(inputlista): siffror = tom lista Gå igenom alla element i inputlista Spara alla siffror i inputlista till listan siffror Returnera listan siffror.
Flödesdiagram/Flödesschema Visuell notation för att beskriva algoritmer och processer Inte så populär längre, då programmeringsspråken utvecklats (jmf högnivåspråk / lågnivåspråk) http://en.wikipedia.org/wiki/flowchart
Symboler i flödesdiagram Start/Stop Dokument Process Display Input/ Output Manuell Input Beslut
Start Flödesdiagram lista1 fås som argument siffror = [] i = nästa element i lista1 Nej Är i en siffra? Ja lägg till i till listan siffror Nej fler element i lista1? Ja returnera listan siffror Stop
EXEMPEL PÅ PSEUDOKOD OCH FLÖDESDIAGRAM
Start Simple Reflex Agent input: percept load rules state = interpret-input(percept) rule = rule-match(state, percept) action = action from rule return action Stop
Pseudokodsexempel function SIMPLE-REFLEX-AGENT(percept) returns an action presistent: rules, a set of condition-action rules state <- INTEPRET-INPUT(percept) rule <- RULE-MATCH(state, rules) action <- rule.action return action
Katt Start Vakna Knuffa omkull det Sov Nej Finns det något på bordet? Ja
Katt def kattsimulering(): while True: vakna() för alla saker på bordet vält(sak) sov()
LÄNGST?
Algoritm som ger svaret på frågan "Hur lång är den längsta personen?" Sätt er två och två och försök skriva ner algoritmen. Ni får 3 minuter. Anta att ni får en lista med längden på de olika personerna, t.ex. [["a", 6], ["b", 4], ["c", 7], ["d", 5], ["e", 3]] Använd en icke-formell beskrivning, pseudokod eller ett flödesdiagram.
Hur lång är den längsta personen? Initiera högsta uppmätta längdvärde till 0. Gå igenom listan med person-längder en i taget. Om vi stöter på ett längdvärde som är större än det tidigaste längsta värdet kom ihåg det värdet. När vi har gått igenom hela listan, vet vi hur lång den längsta personen är.
Hur lång är den längsta personen? def max_length(height_list): max_length = 0 for person in height_list: if person[1] > max_length: max_length = person[1] return max_length
Rekursiv variant def max_length(values): if len(values) == 1: return values[0][1] else: return max(values[0][1], max_length(values[1:]))
Vem är längst? Observera att frågan "Vem är längst?" och "Hur lång är den längsta personen?" Är två olika frågor. En algoritm som löser det ena problemet löser inte det andra!
Algoritm som ger svaret på frågan "Vem är den längsta personen?" Sätt er två och två och försök skriva ner algoritmen. Ni får 3 minuter. Anta att ni får en lista med längden på de olika personerna och deras längder, t.ex. [["a", 6], ["b", 4], ["c", 7], ["d", 5], ["e", 3]] Använd en icke-formell beskrivning, pseudokod eller ett flödesdiagram.
Vem längsta personen? Gå igenom listan med person-längder en i taget Om vi stöter på en person som är längre än den längsta hittills, kom ihåg den personen (index). När vi har gått igenom hela listan, vet vi vem den längsta personen är.
Vem är längst? def find_tallest(height_list): tallest_person = None for person in height_list: if person[1] > tallest_person[1]: tallest_person = person print "Person " + tallest_person[0] + " is the tallest: " + \ str(tallest_person[1]) + " cm"
Vem längsta personen? - Rekursiv Om listan är tom, returnera den längsta personen Annars, kolla om den första i listan är längre än den nuvarnade längsta personen, om det är fallet, gör ett rekursivt anrop med den första i listan som ny längsta person I alla andra fall, gör ett nytt rekursivt anrop: behåll nuvarande längsta person och sök vidare i listan - alla utom den första.
Vem är längst? - Rekursiv def find_tallest(height_list, tallest_person=["nobody", 0]): if len(height_list) == 0: return tallest_person elif height_list[0][1] > tallest_person[1]: return find_tallest(height_list[1:], height_list[0]) else: return find_tallest(height_list, tallest_person)
REKURSION https://www.ida.liu.se/codela/as/729g04/05a
ALGORITMER: LINJÄR OCH BINÄR SÖKNING
Linjär sökning Linjär sökning innebär att man tittar på varje element i ordning. Kan användas på all data som går att beskriva som en sekvens. T.ex: Vem är längst?
Binär sökning Kan användas när vi har en ordnad sekvens. 1.Titta på det mittersta elementet och jämför med sökkriterierna 2.Givet att sekvensen är ordnad vet vi åt vilket håll vi ska gå, men inte hur långt vi ska gå. 3.Titta på det mittersta elementet i den hälft som vi vet att målet bör finnas inom. 4.Fortsätt att halvera sökområdet tills vi hittar det vi söker efter eller det inte finns någon mer stans att leta.
Mittersta elementet [a], mitten = a [a, b], mitten = b [a, b, c], mitten = b [a, b, c, d], mitten = c
Exempel - leta efter j Finns bokstaven j bland dessa bokstäver? a, b, c, d, e, f, g, h, i, j, k, l
Börja i mitten a b c d e f g h i j k l mitten = g som kommer innan j
Leta på den sida om mitten som innehåller j a b c d e f g h i j k l Vi har hittat ett j!
Exempel - leta efter k Finns bokstaven k bland dessa bokstäver? a, b, c, d, e, f, g, h, i, j, k, l
Börja i mitten a b c d e f g h i j k l mitten = g som kommer innan k
Leta på den sida om mitten som innehåller k a b c d e f g h i j k l j kommer före k
Leta på den sida om mitten som innehåller k a b c d e f g h i j k l l kommer efter k
Leta på den sida om mitten som innehåller j a b c d e f g h i j k l Vi har hittat k!
Exempel - leta efter e Finns bokstaven e bland dessa bokstäver? a, b, c, d, e, f, g, h, i, j, k, l
Börja i mitten a b c d e f g h i j k l mitten = g som kommer efter e
Leta på den sida av mitten som innehåller e a b c d e f g h i j k l mitten = d som kommer innan e
Leta på den sida av mitten som innehåller e a b c d e f g h i j k l mitten = f som kommer efter e
Leta på den sida av mitten som innehåller e a b c d e f g h i j k l vi har hittat e!
Exempel - leta efter m Finns bokstaven m bland dessa bokstäver? a, b, c, d, e, f, g, h, i, j, k, l
Börja i mitten a b c d e f g h i j k l mitten = g som kommer före m
Leta på den sida av mitten som innehåller m a b c d e f g h i j k l mitten = j som kommer före m
Leta på den sida av mitten som innehåller m a b c d e f g h i j k l mitten = l som kommer före m
Sökning avslutas a b c d e f g h i j k l Sekvensen tar slut till höger om vår föregående mitt. Elementet finns inte i sekvensen.
ÖVERGÅNG TILL KOD
Mittersta elementet [a], mitten = a längden är 1. 1/2 = 0. OK [a, b], mitten = b längden är 2. 2/2 = 1. OK [a, b, c], mitten = b längden är 3. 3/2 = 1. OK [a, b, c, d], mitten = c längden är 4. 4/2 = 2. OK
Exempel på binär sökning: j längd: 12 mitten = start + 12/2 = 6 p: "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" 0 1 2 3 4 5 6 7 8 9 10 11 start = 0 p[6] < "j" stop = 11 start = mitten + 1 = 7 längd = stop-start+1 = 12 stop = 11
Exempel på binär sökning: j längd: 5 mitten = start + 5/2 = 9 p: "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" 0 1 2 3 4 5 6 7 8 9 10 11 start = 7 stop = 11 längd = stop-start+1 = 5 p[9] == "j"
Exempel på binär sökning: e längd: 12 mitten = start + 12/2 = 6 p: "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" 0 1 2 3 4 5 6 7 8 9 10 11 start = 0 p[6] > "e" stop = 11 start = 0 längd = stop-start+1 = 12 stop = mitten - 1 = 5
Exempel på binär sökning: e längd: 6 mitten = start + 6/2 = 3 p: "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" 0 1 2 3 4 5 6 7 8 9 10 11 p[3] < "e" start = 0 stop = 5 längd = stop-start+1 = 6 start = mitten + 1 = 4 stop = 5
Exempel på binär sökning: e längd: 2 mitten = start + 2/2 = 5 p: "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" 0 1 2 3 4 5 6 7 8 9 10 11 p[5] > "f" start = 4 stop = 5 längd = stop-start+1 = 2 start = 4 stop = mitten - 1 = 4
Exempel på binär sökning: e längd: 1 mitten = start + 1/2 = 4 p: "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" 0 1 2 3 4 5 6 7 8 9 10 11 p[4] == "e" start = 4 stop = 4 längd = stop-start+1 = 1 Returnera 4
Binär sökning def binary_search(element, sequence): """This function returns the first found position of element in the sequence. If the element is not found, return -1""" start = 0 end = len(sequence) while start!= end: length = end - start + 1 middle = start + length / 2 if sequence[middle] == element: return middle elif sequence[middle] < element: start = middle + 1 else: end = middle - 1 if sequence[middle] == element: return middle else: return -1
När kan man använda binär sökning? När elementen står i sekvensen är sorterade antingen i stigande eller fallande ordning, och vi vet om sorteringsordningen. Stigande ordning: För alla element n, så är n+1 större eller lika med n. Sjunkande ordning: För alla element n, så är n+1 mindre eller lika med n. OBS! Binär sökning berättar inte om det finns fler element med det korrekta värdet.
KODSTIL
PEP PEP stands for Python Enhancement Proposal. A PEP is a design document providing information to the Python community, or describing a new feature for Python or its processes or environment. The PEP should provide a concise technical specification of the feature and a rationale for the feature. PEP 1
Kodstil PEP 8 Style Guide for Python Code http://www.python.org/dev/peps/pep-0008/ PEP 257 Docstring Conventions PEP 8 + PEP 257 ska följas från och med labb 5!
PEP 8 PEP 8 täcker delar av Python som inte täcks av denna kurs Strunta i de delar av PEP 8 som tar upp saker som inte tas upp i denna kurs.
Varför bry sig om kodstil? Ökad läsbarhet - på radnivå Lättare att hitta i koden - disposition Minskad risk för missförstånd Mindre frustration
PEP 8 - områden White Space - olika slags mellanrum i koden namngivning kommentarer disposition - var skrivs vad
PEP 257 - områden Hur skriver man en docstring - den kommentar i koden som dokumenterar vad en funktion gör Kommentarer på en rad Kommentarer som går över flera rader
WHITE SPACE
Indentering Blanda inte indenteringstecken i samma fil. Dvs, använd antingen mellanslag eller tabtecken. Mellanslag föredras. Rekommenderad ökning av antal mellanslag per indenteringsnivå är 4
Rätt # Aligned with opening delimiter foo = long_function_name(var_one, var_two, var_three, var_four) # More indentation included to distinguish this from the rest. def long_function_name( var_one, var_two, var_three, var_four): print(var_one) Fel # Arguments on first line forbidden when not using vertical alignment foo = long_function_name(var_one, var_two, var_three, var_four) # Further indentation required as indentation is not distinguishable def long_function_name( var_one, var_two, var_three, var_four): print(var_one)
Mellanslag Mellanslag mellan operatorer och värden Inga mellanslag innan parenteser i funktionsanrop
Bra: spam(ham[1], {eggs: 2}) Dåligt: spam( ham[ 1 ], { eggs: 2 } ) Bra: if x == 4: print x, y; x, y = y, x Dåligt: if x == 4 : print x, y ; x, y = y, x Bra: spam(1) Dåligt: spam (1)
Radbryt Två tomma rader mellan funktionsdefinitioner (rader med kommentarer räknas inte som tomma rader) Använd inte för många radbryt i funktioner. Du behöver inte en tom rad mellan varje sats. Använd tomma rader för att visa logisk struktur - tänk "nytt stycke"
Radbryt Max radlängd: 79 tecken Python tillåter radbryt inom parenteser. Använd detta. Använd \ för att bryta en rad om det inte finns andra alternativ.
Exempel på radbryt def init (self, width, height, color='black', emphasis=none, highlight=0): if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100): raise ValueError("sorry, you lose") if width == 0 and height == 0 and (color == 'red' or emphasis is None): raise ValueError("I don't think so -- values are %s, %s" % (width, height)) Blob. init (self, width, height, color, emphasis, highlight)
Namngivning
Variabelnamn (PEP 8) små bokstäver _ mellan "ord" beskrivande variabelnamn
Funktionsnamn (PEP 8) små bokstäver _ mellan "ord" beskrivande funktionsnamn
Kommentarer
Funktionskommentarer (PEP 257) Beskriv funktionen i funktionskommentaren. Funktionskommentaren skrivs mellan tre citattecken i början och tre citatattecken i slutet. Om kommentaren sträcker sig över mer än en rad, ska de tre sista citattecknena läggas på en egen rad. Använd 72 som längsta radlängd för funktionskommentarer som går över flera rader.
Kommentarsexempel def add_five(list_of_numbers): """Denna funktion tar in en lista av heltal och ökar värdet på varje element med 5.""" index = 0 while index < len(list_of_numbers): list_of_numbers[index] += 5 index += 1
Kodkommentarer Block-kommenterar Indenterad till samma nivå som efterföljande kod. Inline-kommentar Använd hellre block-kommentarer
Kommentarsexempel def add_five(list_of_numbers): """Denna funktion tar in en lista av heltal och ökar värdet på varje element med 5.""" index = 0 # Gå igenom listan och lägg till 5 till varje element while index < len(list_of_numbers): list_of_numbers[index] += 5 index += 1
IMPORT
import Alla importer sker i början av filen En import per rad