Göm meny
Gäller för: VT24

Laboration 3: Hämta och presentera information från webben

Laboration 3 består av två delar:

  • Del 1: Pythonuppgifter 3.
    • Behandlar dictionaries, nästlade strukturer och rekursion.
    • Pythonuppgifter som automaträttas. Se till att göra pythonuppgifterna först då de går igenom det mesta ni behöver fär att lösa uppgiften i del 2.
  • Del 2: Pokémon-information från webben (redovisas).
    • Tillämpningsövning på det ni gjort i Pythonuppgifterna.
    • Hämtning av JSON-data via web API:et PokeApi.
    • Omvandling av JSON-data (text-sträng) till dictionary i Python med modulen requests.

Övningarna som hör ihop med lektion 3 bör göras som förberedelse för Del 2, om inte annat så måste modulen requests installeras.

Redovisning, inlämning och kompletteringar

  • Information om den muntliga redovisningen, samt eventuella kompletteringar kan ni läsa om sidan Redovisning.
  • Information om inlämning av Pythonuppgifter hittar ni på sidan Inlämningar.

Checklista för redovisning

  • Demonstrera att er slutgiltiga version av pokedex-skriptet fungerar. Om ni gjorde den frivilliga uppgiften, visa den.
    • pokedex-skriptet ska köras från terminal, t.ex. : ./pokedex.py bulbasaur dvs att skriptet fungerar enligt körexemplen.
  • Peka ut i er kod där ni använder ett dictionary och förklara hur ni använder datatypen.
  • Beskriv översiktligt programflödet för hur programmet hittar URL:en till en ability. Gå inte igenom varje rad i koden, utan peka ut vilka rader som körs. Försök att beskriva vad koden gör snarare än hur koden gör det.
  • Beskriv programflödet för hur programmet hittar textbeskrivningen som hör ihop med en ability givet att den redan vet vilken URL den ska hämta informationen från.

Del 1: Pythonuppgifter 3

Börja med Pythonuppgifter 3 innan ni börjar på Del 2. Pythonuppgifter 3 går igenom det mesta ni behöver för att lösa uppgiften i del 2.

Del 2: Pokémon-information från webben

Den här uppgiften går ut på att skriva ett Python-skript som skriver ut information om Pokémons genom att hämta data från webbtjänsten https://pokeapi.co.

För att inte använda deras bandbredd finns dock datat tillgängligt på https://www.ida.liu.se/~TDDE44/pokeapi/api/v2/ som ni ska använda er av i denna laboration.

I lektionen finns övningar som ni bör ha gjort innan ni påbörjar Del 2. Övningarna går igenom hur ni hämtar JSON-data från en URL och introducerar PokeAPI:et. Mer information om PokeAPI och övriga begrepp som du behöver förstå för att genomföra laborationen hittar du via länkarna nedan.

Innan du kan börja med Del 2 av Laboration 3 behöver du installera paketet requests. Se information på sidan för lektion 3 för hur du gör detta.

Förkunskaper

Du kommer behöva använda det du lärde dig genom tidigare laborationer, samt övningarna från lektion 3 för att utföra Del 2. Hur man gör en fil med pythonkod till ett körbart skript gicks igenom i Del 3 av laboration 1.

  • skapa och använda körbara Python-skript (Laboration 1, Del 3).
  • hur ett pythonskript kan ta emot argument från terminalen (Laboration 1, Del 3)

Beskrivning av slutgiltiga skriptets funktionalitet

Nedan visas ett exempel på användning av skriptet som ni ska skriva i del 2:

$ ./pokedex.py squirtle
squirtle has 2 abilities.

Ability 'rain-dish':
The Pokémon gradually regains HP in rain.

Ability 'torrent':
Powers up Water-type moves when the Pokémon’s
HP is low.
$ ./pokedex.py python
No information about 'python' was found.

Förslag på tillvägagångssätt

Istället för att skriva t.ex. en enda lång funktion som utför alla delar en uppgift, är det vanligt att man bryter ner uppgiften i deluppgifter. Genom att ha funktioner som jobbar med delproblem kan man testa och felsöka ett delproblem i taget.

Nedan ser ni ett (icke-komplett) exempel på kod till uppgiften som anropar funktioner som löser delproblem.

I anropen skickas den information som funktionerna behöver för att genomföra sin deluppgift. När funktionen utfört uppgiften returneras ett resultat som sedan kan användas i efterföljande steg.

def main():

    # hämta information från Pokeapi. get_pokeapi_data() returnerar ett dictionery
    pokemon_info = get_pokemon_info()

    # hämta namnen på pokemonens förmågor
    ability_names = get_pokemon_abilities(pokemon_info)

    # för varje förmåga, hämta informationen för den förmågan
    ability_data = []
    for ability_name in ability_names:
        ability_info = get_ability_data(ability_name)
        ability_data.append(ability_info)

Felsökning med spårutskrifter

Något man kan vilja veta när man felsöker är vilka värden en funktion får in när den anropas. Ett sätt att ta reda på detta är att använda spårutskrifter och skriva ut innehållet i argumenten t.ex.

def process_data(data, arg1, arg2):
    print(f"Kör process_data: {data=}, {arg1=}, {arg2=}")
    # resten av funktionen nedan

I exemplet ovan används en f-sträng för att smidigt visa vad variablerna data, arg1 och arg2 refererar till. Likhetstecknet, =, efter variabelnamnet kommer lägga till variabelnamn= innan värdet i den “färdiga” strängen. Utan = får vi bara värdet på variabeln.

Man kan även skriva godtyckliga uttryck innanför måsvingarna:

value = 5
f"blabla {value}" -> 'blabla 5'
f"blabla {value=}" -> 'blabla value=5'
f"blabla {5+5}" -> 'blabla 10'
f"blabla {5+5=}" -> 'blabla 5+5=10'
f"blabla {len('hej')}" -> 'blabla 3'
f"blabla {len('hej')=}" -> "blabla len('hej')=3"

Uppgifter

Förberedelseuppgifter

Funktionerna som ni får i uppgift att skriva i dessa förberedelseuppgifter kommer ni sedan att använda er av i huvuduppgiften. Vissa av dessa uppgifter, eller varianter av dessa uppgifter har ni gjort på lektionen.

Förberedelse 0

För att kunna testa din kod på ett smidigt sätt kan du använda en kodsnutt likt den nedan (det är en bild med flit). Om du har ditt huvudprogram i en separat funktion kan du snabbt växla mellan att testa funktionen du jobbar med just nu och hela programmet.

Öppna en texteditor, skriv in ovanstående och spara filen under namnet pokedex.py

Förberedelse 1

För att slippa skriva URL:en till API:et om och om igen, kan vi använda oss av en global variabel.

# ha med nedanstående variabel högt upp i koden
API_SERVER = "https://www.ida.liu.se/~TDDE44/pokeapi"

Normalt avråder vi från att använda globala variabler eftersom att det lätt leder till lösningar som är svåra att felsöka eftersom det är svårt att ha kolla på var och när de globala variablerna ändras. I detta fall används variabeln som en konstant, dvs vi ändrar aldrig på den, så den gör det därför inte svårare att felsöka. (Python har inget inbyggt stöd för konstanter - nåja, inte på den här grundläggande nivån - utan istället är det kutym att variabler vars värde aldrig förändras skrivs med VERSALER. Tanken är att man ska hajja till och inse att man nog försöker göra något dumt om man någonsin försöker ändra värdet i en variabel skriven helt i versaler.)

Förberedelse 2

Skriv funktionen get_json_as_dict(url) som får en URL som är tänkt att gå till JSON-data. Om statuskoden vid hämtning av data från URL:en är 200 (dvs OK), returnera det dictionary som ni får från JSON-datat. Om statuskoden inte är 200, returnera None.

Tanken bakom att returnera None är att kunna titta på resultatet och se om det gick bra eller inte. Om returvärdet är None, vet vi att något gick fel och kan hantera det.

För att underlätta felsökning, se också till att funktionen skriver ut vilken URL den är på väg att besöka.

Testa din kod innan du går vidare.

Förberedelse 3

Skriv funktionen get_pokemon_url(pokemon_name) som får in ett namn på en pokemon som sträng och returnerar dess fullständiga URL som en sträng.

Förberedelse 4

Skriv funktionen get_pokemon(pokemon_name) som får in ett namn på en pokemon som sträng och returnerar ett dictionary med pokemoninformation som hämtats från PokeAPI (på IDA).

Du kan använda dig av de två funktionerna som du skrivit innan för att göra det lättare!

Testa din kod innnan du går vidare.

Uppgift 1

Gör så att du har ett skript som tar emot namnet på en pokemon och skriver ut hur många färdigheter den har. Om det inte går att hitta information om det användaren skrivit in som pokémon-namn, skriv ut ett felmeddelande.

Exempel

$ ./pokedex.py pidgey
pidgey has 3 abilities.
$ ./pokedex.py python
No information about 'python' was found.

Uppgift 2

Gör så att ditt skript tar emot namnet på en pokemon och skriver ut namnen på dess färdigheter.

Exempel

$ ./pokedex.py pidgey
pidgey has 3 abilities.

big-pecks
tangled-feet
keen-eye

Uppgift 3

Gör så att ditt skript tar emot namnet på en pokemon och skriver ut vilka färdigheter den har och beskrivningarna av dessa färdigheter (använd texten under "flavor_text_entries", inte "effect_entries"). Det är inte säkert att det första elementet är en text på engelska dock.

Exempel

$ ./pokedex.py pidgey
pidgey has 3 abilities.

Ability 'big-pecks':
Protects the Pokémon from
Defense-lowering effects.

Ability 'tangled-feet':
Raises evasion if the Pokémon is confused.

Ability 'keen-eye':
Keen eyes prevent other Pokémon from lowering this
Pokémon’s accuracy.

Uppgift 4 (frivillig)

Ändra i dina funktioner och gör så att man kan ändra språk som används på namnen på färdigheterna och beskrivningarna av färdigheterna.

Exempel

$ ./pokedex.py pidgey ja
pidgey has 3 abilities.

Ability 'はとむね':
防御を 下げる
効果を 受けない。

Ability 'ちどりあし':
こんらん状態の ときは
回避率が アップする。 

Ability 'するどいめ':
鋭い 目の おかげで
命中率を 下げられない。
$ ./pokedex.py pidgey it
pidgey has 3 abilities.

Ability 'Pettinfuori':
Evita che la Difesa diminuisca.

Ability 'Intricopiedi':
Se il Pokémon è confuso, ne aumenta l’elusione.

Ability 'Sguardofermo':
La vista acuta del Pokémon impedisce che la sua
precisione diminuisca.

Sidansvarig: Johan Falkenjack
Senast uppdaterad: 2024-02-05