Uke 6 - Lister ============== Les https://automatetheboringstuff.com/2e/chapter4/ frem til "EXCEPTIONS TO INDENTATION RULES IN PYTHON"-boksen. Eksempler --------- Denne uken skal vi se på noen eksempler på lister og hva man kan gjøre med dem. Eksempel: Basics ................ Last ned filen her: :download:`eksempel_basic_lists.py ` og kjør koden. Prøv å gjøre endringer i listene og se hva som skjer. .. literalinclude:: eks/eksempel_basic_lists.py Eksempel: Indeks ................ Hvert element i en liste har et tilsvarende indeks, dette tilsvarer elementets posisjon i listen. Det første elementet har indeks 0, neste har indeks 1, etc. Vi kan bruke indeks for å få ut/endre verdien på en viss posisjon i listen. Vi kan bruke ``slice``-notasjon for å få ut en delliste. Last ned filen her: :download:`eksempel_index.py ` og kjør koden. Skjønner du hvordan indeks fungerer? .. literalinclude:: eks/eksempel_index.py .. note :: I Python kan vi bruke asterisk (*) for å pakke og utpakke flere verdier i lister. Dette er en litt mer avansert måte å bruke Python og du må ikke bruke det selv, men noen ganger kan det være veldig praktisk. Last ned filen her: :download:`eksempel_asterisk.py ` og prøv å kjøre koden. .. literalinclude:: eks/eksempel_asterisk.py Eksempel: Lister av lister .......................... Lister kan også inneholde andre lister. Da må vi bruke to tall for å indeksere dem. Last ned eksempelet her :download:`eksempel_2D_lists.py `. Hva tror du den vil skrive ut? Var det riktig? .. literalinclude:: eks/eksempel_2D_lists.py Lister av lister kalles ofte 2-dimensjonale (2D) lister fordi du kan tenke på dem som et 2D koordinatsystem .. code-block:: python grid = [["00", "01", "02"], ["10", "11", "12"], ["20", "21", "22"]] print(grid[2][1]) # printer "21" Eksempel: Listefunksjoner ......................... Her er noen ulike metoder man kan bruke på lister. Du kan finne ut mer på https://docs.python.org/3/tutorial/datastructures.html#more-on-lists Last ned filen her: :download:`eksempel_list_functions.py ` og kjør koden. Skjønner du hva som skjer? Prøv de ulike metodene selv. .. literalinclude:: eks/eksempel_list_functions.py .. note:: Ingen av disse funksjonene har en returverdi. Alle endrer på listen direkte, slik at det er forskjell på listen før og etter at du brukt funksjonen. Eksempel: Input i lister ........................ I dette eksemplet spør vi brukeren om positive tall, og siden beregnes maksimum av tallene på to måter. Last ned filen her: :download:`eksempel_input.py ` og kjør koden. Skjønner du hvordan while-løkken fungerer? Hvordan blir den avsluttet? Hva gjør den siste raden i den løkken? Om du er usikker kan du gå igjenom noen iterasjoner av løkken med papir og penn og se hva som skjer. Skjønner du hvordan for-løkken fungerer? .. literalinclude:: eks/eksempel_input.py I dette eksemplet lagrer vi tallene fra brukeren i en liste. Det er fordi vi ikke vet hvor mange tall vi kommer til å få fra brukeren. En liste i Python kan vi gjøre så lang som vi trenger. Vi må ikke vite på forhånd hvor lang den skal være. Eksempel: Vanlige løkkestrukturer ................................. Følgende er noen eksempler på en vanlig løkkestruktur når vi jobber med lister. Last ned filen her: :download:`eksempel_common_loops.py ` og kjør koden. Kommer du på flere problemer man kan løse med denne strukturen? .. literalinclude:: eks/eksempel_common_loops.py Eksempel: Strings og lister ........................... Her er noen eksempler på metodene ``split()`` og ``join()`` som vi bruker for å konvertere en streng i en liste av strenger og motsatt. Last ned filen her: :download:`eksempel_strings.py ` og kjør koden. Hvordan fungerer ``split()``? Hvordan fungerer ``join()``? Hva gjør for-løkken? .. literalinclude:: eks/eksempel_strings.py Eksempel: List Comprehension ............................ Her er et eksempel på list comprehension (listeinklusjon). Det er en litt mer avansert syntaks og du må ikke bruke dette selv, men det kan være veldig praktisk ibland. Listeinklusjon er en rask måte å lage nye lister fra verdiene til en eksisterende liste. Det er egentlig bare en annen måte å skrive en spesiell type for-løkke. Det går alltid å skrive om en listeinklusjon til en for-løkke. Sammenlign eksemplene nedenfor og forklar forskjellene til en venn. .. literalinclude:: eks/eksempel_list_comp.py Leseforståelse: Polynomer ......................... I dette eksempelet lager vi en funksjon ``poly_string()`` som gjør den samme ting som funksjonen med samme navn i `Eksempel 4, uke 5 `_ men med forskjellen at funksjonen tar en liste med koeffisienter som argument, sånn at polynomet kan være av hvilken grad som helst. Vi lager også en funksjon ``poly_val()`` som beregner verdien av et polynom i en punkt. Argumenten til funksjonen er en liste med koeffisienter og et tall. Kan du forstå hva programmet gjør uten å kjøre det? Last ned filen her: :download:`eksempel_poly.py `. .. literalinclude:: eks/eksempel_poly.py Eksempel: ``in`` ................ Her er et eksempel på bruk av ``in`` med lister. Last ned filen her: :download:`eksempel_in.py `. Før du kjører koden, hva tror du output blir? Kjør koden. Var det riktig? .. literalinclude:: eks/eksempel_in.py Eksempel: turtle ................ Her er et eksempel til bruk av lister med turtle. Vi tegner en spiral ut fra to lister, en med vinkler og en med lengder. Vi bruker python-funksjonen ``exit()`` et sted for å avslutte programmet om listene ikke har den samme lengden. Last ned filen her: :download:`turtle_ex.py `. .. literalinclude:: eks/turtle_ex.py Eksempel: Feil .............. Her er et eksempel på ting som kan gå galt med lister. Last ned filen her: :download:`eks/errors_1.py`. Før du kjør koden, se om du finner alle feil. Prøv å kjøre koden. Endre sånn at koden går å kjøre. .. literalinclude:: eks/errors_1.py :linenos: Koden i slutten skal beregne vekslepenger som skal returneres ved en betaling. Det finnes 20-kr, 10-kr, 5-kr og 1-kr. Den skal returnere slik at man får så få mynter som mulig. For eksempel, om prisen er 24 kr og betalingen er 50 kr skal den returnere én 20-kr, én 5-kr og én 1-kr. Men noe er feil med koden sånn at den ikke gjør helt som den skal. Kan du endre sånn at den fungerer som den skal? Ekstra øving: ............. For å sjekke hva du har lært kan du gjøre 'practice questions' 1-10 i `kapittel 4 i Automate the Boring Stuff `_. Oppgaver -------- .. note:: Alle oppgavene er obligatoriske denne uken! Oppgave 1 ......... I filen ``uke_o6_oppg_1.py`` skal du definere følgende funksjoner: * ``remove_fives()``: tar en liste og returnerer samme liste men med alle forekomster av tallet :math:`5` fjernet. Eksempelkjøring: .. code-block:: python >>> remove_fives([0, 5, 95, 25, 50, 7, 20, 11]) [0, 95, 25, 50, 7, 20, 11] * ``every_third()``: tar en liste og returnerer en liste med kun hvert tredje element. Eksempelkjøring: .. code-block:: python >>> every_third(['a', 1, 'b', 'c', 2, 6, 'g', 4, 'p', 'q']) ['a', 'c', 'g', 'q'] .. note:: **TIPPS**: bruk ``slice``-notasjon * ``reverse()``: tar en liste og snur rekkefølgen på den. Eksempelkjøring: .. code-block:: python >>> reverse([5, 6, 7, 8, 9, 10]) [10, 9, 8, 7, 6, 5] * ``halve_values()``: tar en liste med tall og returnerer listen hvor alle tallene i listen halveres. Eksempelkjøring: .. code-block:: python >>> halve_values([1, 2, 3, 4]) [0.5, 1.0, 1.5, 2.0] .. note:: **TIPPS**: bruk ``append()`` eller list comprehension. * ``unique_values()``: tar en liste og returnerer en liste hvor alle multiple forekomster av verdiene er fjernet (i den rekkefølge verdiene først dukker opp). Eksempelkjøring: .. code-block:: python >>> unique_values([3, 1, 6, 10, 30, 30, 30, 3, 0, 6]) [3, 1, 6, 10, 30, 0] .. note:: **TIPPS**: Du kan enten lage en ny liste med ``append()`` eller så kan du bruke ``remove()`` med den opprinnelige listen. * Skriv din egen versjon av den innbygde funksjonen len, med navnet ``my_len()``. Den skal returnere lengden av en liste eller en streng, slik som len. Du kan ikke kalle på andre funksjoner inne i ``my_len()``. Eksempelkjøring: .. code-block:: python >>> my_len([]) 0 >>> my_len("123") 3 Oppgave 2 ......... Gitt en liste med koordinater i formen ``(x,y)``, i filen ``uke_06_oppg_2.py`` skriv funksjonen ``find_highest()`` som ta som input 2D-listen og går gjennom listen for å returnere **indeksen** som inneholder den høyeste verdien for ``y``. Eksempelkjøring: .. code-block:: python >>> find_highest([[96, 33], [20, 96], [30, 69], [59, 9], [22, 93]]) 1 Oppgave 3 ......... En DNA-sekvens (f.eks ``ATAGCAGT``) sammensettes av 4 ulike "baser", som beskrives med ``A``, ``T``, ``G`` og ``C``. Under replikasjon av sekvensen kan hver base settes sammen med eksakt én av de andre. ``A`` med ``T``, og ``C`` med ``G`` .. code-block:: text original -------> ATAGCAGT |||||||| TATCGTCA <------- complement Slik får man en "komplementstreng" av den opprinnelige DNA-sekvensen. Det vanlig å skrive ned komplementstrenger **baklengs**, slik at i vårt eksempel sier vi at komplementstrengen til ``ATAGCAGT`` er ``ACTGCTAT`` (ikke ``TATCGTCA``). I filen ``uke_06_oppg_3.py`` lag en funksion som heter ``complement()`` og som returnerer komplementstrengen av en DNA-sekvens. Funksjonen skal ta inn én streng som argument, og skal returnere én streng. Du kan anta at alle input-strenger er gyldige DNA-sekvenser. Oppgave 4 ......... I filen ``uke_06_oppg_4.py`` skal du lage en funksjon som heter ``render_histogram()`` som tar en liste med positive heltall og returnerer et histogram som bruker stapler av ``"*"`` for verdiene i listen. For eksempel, ``print(render_histogram([5, 4, 2, 7, 0, 3, 10]))`` skal gi følgende output: .. code-block:: text * * * * * * * * * * ** * * ** * ** **** ** **** ** .. note:: **TIPPS**: Du kan starte med versjonen av ``render_histogram`` som finnes i eksemplene ovenfor. Pytest-filer ------------ Pytest-filene vi bruker på Codegrade: :download:`uke_06_tests.zip`