Uke 9 - Dict ============ Denne uken skal vi se på en ny datastruktur, *dict*, som er brukt ofte for å lagre strukturert data. Først, les gjennom https://automatetheboringstuff.com/2e/chapter5/ frem til "Pretty Printing", og se på "Practice Questions 1-7" .. Vi skal også lese data fra en fil for første gang her. Se på Section 7.2 og 7.2.1 i Python Tutorial: https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files Eksempler --------- Eksempel 1 .......... Her er et eksempel på en dictionary i Python. I dette eksemplet sier den hvilket husdyr ulike personer har. Last ned filen her: :download:`eksempel_2.py`, og kjør koden. Er navnet 'keys' eller 'values' i ``pet``? Er dyret 'keys' eller 'values' i ``pet``? Hva gjør koden ``pet['Alice']``? Hva gjør koden ``pet['Xavier'] = 'Alien'``? Hvorfor blir det feil i den siste linjen? .. literalinclude:: eksempel_2.py Eksempel 2 .......... Vi kan bruke ``.keys()``, ``.values()`` og ``.items()`` sammen med en for-løkke. Last ned filen her: :download:`eksempel_3.py`, og kjør koden. Hva looper vi over når vi bruker en for-løkke med ``.keys()``? Hva om vi bruker ``.values()``? Hva om vi bruker ``.items()``? Hva skjer i den siste løkken? .. literalinclude:: eksempel_3.py Eksempel 3 .......... Vi kan bruke alle 'immutable data types' som keys i en dictionary. Husker du hvilke datatyper er immutable? I eksemplet her bruker vi heltall. Last ned filen her: :download:`eksempel_4.py`. Hva gjør koden? Kjør koden og se om det var riktig. Hvordan ser ``number_name`` ut på slutten av kjøringen? .. literalinclude:: eksempel_4.py Eksempel 4 .......... En dictionary kan f.eks brukes for å holde rede på hvor mange vi har av forskjellige ting. Her bruker vi dictionaries til å telle hvor mange ganger vi bruker ulike bokstaver og ord i begynnelsen av 'Alice in Wonderland'. Last ned filen her: :download:`eksempel_5.py`, og kjør koden. Skjønner du hva som skjer? Hva gjør ``.setdefault()``? (Du kan lese om den `i Pythons dokumentasjon `_.) I slutten av koden finner vi de 5 vanligste ordene. Prøv å bruk 'option 2' i stedet. Som vanlig kan du finne informasjon om hvordan ``sorted()`` fungerer `i Pythons dokumentasjon `_. .. note:: Husk fra den forrige uken at du kan bruke søkeordargumenter med funksjonene dine og Pythons innbygde funksjoner, f.eks ``sorted()`` Last ned filen her: :download:`eksempel_1.py`, og kjør koden. Denne eksemplen er med lister, men du kan også bruke med dictionarys. .. literalinclude:: eksempel_1.py Se også i koden på variabelen ``sorted_result`` -- dette er en smart bruk av søkeordargumenter for å sortere dictionarien din. .. literalinclude:: eksempel_5.py Oppgaver -------- Oppgave 1 --------- Lag en handleliste og print den. Handlelisten skal være en dict med varer som keys og antall som values. Varene er:: 2 brød 3 pizza 10 poteter 1 kaffe 1 ost 14 epler Skriv ut dictionarien:: {'brød': 2, 'pizza': 3, 'poteter': 10, 'kaffe': 1, 'ost': 1, 'epler': 14} Oppgave 2 --------- I denne oppgaven skal vi jobbe med ``my_dict`` og ``my_list`` definert her:: my_dict = { 0 : 0, 1 : "vafler", "two" : 2, 5 : 4 } my_list = [0, 1, "boller", 4] Skriv ut nøklene, verdiene og nøkkel/verdi-par for ``my_dict``, og listeverdiene og index/verdi par for ``my_list``. Eksempelkjøring:: Dictionary Keys: 0 1 two 5 Dictionary Values: 0 vafler 2 4 Dictionary keys/value: 0 0 1 vafler two 2 5 4 List values: 0 1 boller 4 List indices/value: 0 0 1 1 2 boller 3 4 Oppgave 3 --------- Vi ser for oss at følgende dictionary representerer varebeholdningen i en bokhandel. Nøklene er titler og verdiene er antall bøker:: in_storage = { "Ancillary Justice": 1_046, # vi kan bruke _ i tall, den blir ignorert "The Use of Weapons": 372, "1984": 5_332, "The Three-Body Problem": 523, "A Fisherman of the Inland Sea": 728, } Spør brukeren om en boktittel og bruk ``.get()`` for å finne ut hvor mange eksemplarer av boka vi har. Hvis boka ikke er på lager skal du skrive ut 0. Kjør løkken frem til vi får en tom streng som tittel. Eksempelkjøring:: Tittel: 1984 Vi har 5332 av "1984" Tittel: A Fire Upon the Deep Vi har 0 av "A Fire Upon the Deep" Tittel: Automate the Boring Stuff with Python Vi har 0 av "Automate the Boring Stuff with Python" Tittel: Ha det! Oppgave 4 --------- Bruk funksjonen ``collatz_sequence`` fra uke 8 oppgave 2 til å lage en dictionary med tallene 1-10 som keys og Collatz-sekvensen som verdi. Print resultatet. Her er én løsning på ``collatz_sequence``:: def collatz_sequence(n): sequence = [n] while n > 1: if n % 2 == 0: n = n // 2 else: n = 3*n + 1 sequence.append(n) return sequence Eksempelkjøring:: {1: [1], 2: [2, 1], 3: [3, 10, 5, 16, 8, 4, 2, 1], 4: [4, 2, 1], ...} Oppgave 5 --------- I denne oppgaven skal vi gjøre det samme som i oppgave 3, men litt annerledes. Hvis brukeren spør om en bok som ikke er på lager skal vi "kjøpe inn" 10 og legge til boka i ``in_storage`` med 10 eksemplarer. Eksempelkjøring:: Tittel: 1984 Vi har 5332 av "1984" Tittel: Automate the Boring Stuff with Python Vi har 10 av "Automate the Boring Stuff with Python" **Tips:** bruk `setdefault() `_ Oppgave 6 --------- I denne oppgaven skal vi bruke en dictionary med informasjon om biler:: cars = { "Escort" : { "Brand": "Ford", "Horsepower": 200, "Wheels": 4, "Color": "red" }, "Beetle" : { "Brand": "Volkswagen", "Horsepower": 120, "Wheels": 4, "Color": "blue" }, "Isetta" : { "Brand": "BMW", "Horsepower": 50, "Wheels": 3, "Color": "green" }, } Bruk dette til å skrive ut merket, modellnavn, antall hjul, hestekrefter og farge for hver bil. Eksempelkjøring: .. code-block:: none The Ford Escort has: 4 wheels, 200 horsepowers, and is red The Volkswagen Beetle has: ... Oppgave 7 --------- `Fantasy Game Inventory` fra boken (https://automatetheboringstuff.com/2e/chapter5/) Du lager et fantasy-videospill. Datastrukturen for å modellere spillerens beholdning skal være en dictionary hvor nøklene er strings som beskriver tingene i beholdningen, og verdiene er integers som forteller hvor mange av hver ting som spilleren har. For eksempel, verdiene i dictionary ``{'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}`` betyr at spilleren har 1 rope, 6 torches, 42 gold coins, etc. Begynne med filen :download:`uke09_oppgave_7.py ` og skriv resten av funksjonen ``displayInventory()`` som tar inn alle mulige beholdningene og printer dem som nedenfor. Funksjonen skal også returnere totalt antall. Eksempelkjøring:: Inventory: 1 rope 6 torch 42 gold coin 1 dagger 12 arrow Total number of items: 62 Oppgave 8 --------- `Dragon Hoard` fra boken (https://automatetheboringstuff.com/2e/chapter5/) Skatten til en beseiret drage er representert som en liste med strenger som dette: ``dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']`` Fyll inn funksjonen som heter ``addToInventory(inventory, addedItems)``, hvor ``inventory`` parameteren er en dictionarien av spillerens beholdning og ``addedItems`` parameteren er en liste som f.eks ``dragonLoot``. ``addToInventory()`` funksjonen burde returnere en dictionary som representerer den oppdaterte beholdningen. Merk at listen over tilleggsartikler kan inneholde flere av samme element. Begynne med filen :download:`uke09_oppgave_8.py ` og skriv resten av funksjonen som heter ``addToInventory``. Om du kaller ``displayInventory()`` etter å ha oppdatert beholdingen med ``addToInventory()`` funksjonen skal du få ut likt som nedenfor: Eksempelkjøring:: Inventory: 45 gold coin 1 rope 1 dagger 1 ruby Total number of items: 48 Oppgave 9 - Euler 17 -------------------- https://projecteuler.net/problem=17 If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used? NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage. **Skriv en funksjon number_name(N)** som tar inn et heltall (opp til 1000) som argument ``N`` og returnerer det engelske navnet til tallet som en streng. *Tips:* begynn med dict'et som finnes i eksempel 3, og legge inn flere tall der. Du trenger ikke å ta med alle tallene frem til 1000, siden de fleste kan settes sammen. Gjerne bruk flere funksjoner for å organisere programmet **Skriv en funksjon all_numbernames(N)** som tar inn et heltall (opp til 1000) som argument N og returnerer den summerte lengden av alle navnene fra 1 til N (sjekk eksemplene fra Euler-teksten). Du kan gjenbruke number_name() her. **Skriv en funksjon solve_euler_17()** som returnerer den summerte lengden av alle navnene fra 1 til 1000. Du kan gjenbruke de andre funksjonene.