Lektion 3: Sköldpaddsvärlden#

Syfte: Öva villkors- och iterationssatser.

Begrepp som introduceras: Objekt

Arbetsform: Arbeta gärna tillsammans med någon men skriv egen kod. Diskutera med varandra!

Arbetstid: 2 timmar

Redovisning: Ingen obligatorisk redovisning, men diskutera med handledare om det är något du är osäker på!


Turtle-världen och dess invånare#

Med standarddistributionen av Python kommer en modul turtle. Med den kan man rita upp en värld med objekt (”sköldpaddor”) som kan röra sig och rita figurer. Det är huvudsakligen tänkt som ett pedagogiskt hjälpmedel men kan även användas för att rita t.ex. grafer, kurvor och diagram.

Vi börjar med att skriva vid kommando-promptern >>> (antingen i ett terminalfönster där du startat python3 eller i IDLEs kommandoruta).

../../_images/firstWindow.png
  1. Importera turtle-modulen:

    >>> import turtle
    
  2. Skapa en padda:

    >>> t = turtle.Turtle()
    

Denna sats öppnar ett fönster och placerar en liten ”padda” i mitten. Fönstret har ett (tänkt) koordinatsystem med origo i mitten (där paddan står) och x- och y-axlarna på vanligt sätt åt höger respektive uppåt.

Variabeln t refererar nu till en padda. En padda har ett antal metoder som man kan använda för att ”beordra” den att göra olika saker. En metod är en funktion som är kopplad till ett speciellt objekt (paddan i detta fall). För att använda en metod använder man punktnotation. Jämför med metoden append för listobjekt!

Exempel: Vi kan be paddan att anta ett mer sköldpaddslikt utseende med kommandot

>>> t.shape('turtle')

Prova följande satser i tur och ordning efter >>>:

  1. >>> t.forward(100)
    
  2. >>> t.left(90)
    
  3. >>> t.forward(100)
    
  4. >>> t.circle(100)
    

Skapa nu en ny fil (starta först en IDE, t.ex. Idle eller VS Code, om du inte redan har gjort det).

Klistra in denna kod som illustrerar en lite mer avancerad figur:

import turtle

t = turtle.Turtle()
t.hideturtle()
t.color('blue', 'light blue')
t.begin_fill()
for i in range(36):
    t.forward(200)
    t.left(170)
t.end_fill()

Spara och kör! Prova att ändra färgerna (gissa namnen!) samt längden (200) och vinkeln (170) och se vilka effekter det får!

Paddorna har många metoder. För att se alla metoder kan man (under förutsättning att man importerat turtle-modulen) få en förteckning med kommandot

>>> dir(turtle)

För att få information om en speciell metod kan man använda kommandot help. Exempel:

help(turtle.forward)

De viktigaste metoderna finns samlade i minilektionen om turtlegrafik. Det finns också en officiell dokumentation.

Vi ska nu använda paddorna för att exemplifiera och öva på det vi hittills gått igenom, bl.a. if- och while-satser.

Tips: Om du kör Python i t.ex. VS Code brukar fönstret som paddan ritar i stängas så fort programmet avslutas. För att fönstret ska stanna kvar kan du avsluta ditt program med raden

turtle.done()

vilket gör att programmet väntar på att fönstret med paddan stängs innan det går vidare. Notera att du då kommer behöva stänga fönstret innan du kan köra programmet en gång till.

Övningar#

Koden för dessa uppgifter ska lagras på en fil och testas.

  1. Skriv ett program som frågar användaren efter en längd och sedan ritar en liksidig triangel med detta värde som sidlängd.

    Svar
    import turtle
    
    side = int(input("Sidlängd: "))
    t = turtle.Turtle()
    
    for i in range(3):
        t.forward(side)
        t.left(120)
    

    Bättre med en loop än så kallad ”rakkod”:

    t.forward(side)
    t.left(120)
    t.forward(side)
    t.left(120)
    t.forward(side)
    
  2. Modifiera koden så att den fyller triangeln med röd färg. (Metoderna fillcolor, begin_fill och end_fill)

    Svar
    import turtle
    
    side = float(input("Sidlängd: "))
    
    t = turtle.Turtle()
    t.fillcolor('red')
    t.begin_fill()
    for i in range(3):
        t.forward(side)
        t.left(120)
    t.hideturtle()      # Mer estetiskt utan paddan
    t.end_fill()
    
  3. Modifiera koden så att den också frågar efter färg. Färgen ska skrivas som white, red, blue,…

    Svar
    import turtle
    
    side = float(input("Sidlängd: "))
    t = turtle.Turtle()
    color = input("Färg: ")  # color får typen string
    t.fillcolor(color)  # som kan användas som indata till fillcolor
    t.begin_fill()
    for i in range(3):
        t.forward(side)
        t.left(120)
    t.hideturtle()
    t.end_fill()
    
  4. Skriv kod som, med hjälp av forward och left i en for-sats (100 steg) ritar en spiral.

    Tips: För att få en spiral behöver man variera vinkeln och/eller sträckan. Prova båda!

    ../../_images/spiral.png
    Svar

    Figuren är gjord med denna kod:

    t = turtle.Turtle()
    for i in range(100):
        t.forward(i)
        t.left(30 - i/10)
    
  5. Modifiera spiralkoden så att den avbryter när avståndet till origo är större än 200. Använd turtle-metoden distance (tips: använd help för att ta reda på hur distance fungerar).

    Svar
    t = turtle.Turtle()
    i = 0
    while t.distance(0, 0) < 200:
        t.forward(i)
        t.left(30 - i/10)
        i += 1
    
  6. Skriv kod som ritar två perioder av en sinuskurva enligt vidstående figur.

    Tips 1: Använd turtle-metoden goto.

    Tips 2: Sambandet \(y = A \displaystyle \sin \left( \frac{2 \pi x}{L} \right)\) svarar mot en sinuskurva med amplitud \(A\) och period \(L\).

    Tips 3: Fyllnadsfärgen som använts i bilden är "SkyBlue". Denna sida visar vilka färger man kan välja mellan.

    ../../_images/sinus.png
    Svar
    import turtle
    import math
    
    t = turtle.Turtle()
    t.speed(0)
    t.hideturtle()
    t.fillcolor('SkyBlue')
    
    L = 100 # Längden av en period i x-led
    A = 100 # Sinuskurvans amplitud
    dx = 1  # Avstånd i x-led mellan varje utritad punkt på kurvan
    
    t.begin_fill()
    for x in range(-L, L+1, dx): # Loop över alla x-koordinater att rita för
        
        # Givet en x-koordinat, räkna ut motsvarande y-koordinat
        y = A*math.sin(2*math.pi*x/L)
    
        # Flytta paddan till position (x, y).
        t.goto(x, y)
    
    t.goto(0, 0) # Gå tillbaka till origo
    t.end_fill()
    
  7. Skriv kod som ritar den franska flaggan mitt i rutan. Ränderna är 100 breda och 200 höga vilket ger flaggan rätt proportioner.

    Ledning: Själva ritandet behöver inte ta mer än 10 rader men det krävs att man har en yttre iteration över rektanglarna och att dessa görs med en iteration över sidorna. Det krävs alltså två nästlade loopar.

    Bra övning att läsa och försöka förstå lösningsförslaget!

    ../../_images/tricolore.png
    Svar
    import turtle
    
    t = turtle.Turtle()
    size = 100
    t.penup()
    t.goto(-size*1.5, -size)    # Gå till nedre vänstra hörnet
    t.pendown()
    t.hideturtle()
    
    colors = ['blue', 'white', 'red']
    sides = [size, 2*size, size, 2*size]
    for c in colors:            # iterera över färgerna
        t.fillcolor(c)
        t.begin_fill()
        for side in sides:      # iterera över sidorna
            t.forward(side)
            t.left(90)
        t.end_fill()
        t.forward(size)     # Gå till nästa färgrand