Python code bij Turtle

De code is ook als Python Notebook te downloaden

Turtle

Inhoud

  1. Beschrijving van Turtle
  2. Belangrijke commando's
  3. Programma: Het opvullen van een figuur
  4. Programma: Spiraal
  5. Programma: Pythagoras Olympiade opgave 374
  6. Programma: Gebruik van een achtergrondplaatje
  7. Programma: Moderne kunst
  8. Programma: Zelf tekenen
  9. Programma: toegift
  10. Programma: Fractal
  11. Programma: Woordl
  12. Slotopmerkingen

1. Beschrijving van Turtle

Turtle (Schildpad) is een pakket dat kan worden gebruikt om op een eenvoudige manier te kunnen tekenen. De oorsprong van Turtle ligt in 1948. Toen werd er een robot ontwikkeld die geprogrammeerd kon worden om een bepaald patroon af te leggen. Het werd later een speeltje voor kinderen. In de programmeertaal Logo werd het iets om kinderen iets uit te leggen over programmeren. Inmiddels is het ook overgenomen door Python.

De basis is onveranderd gebleven. De robot in 1948 had de vorm van een schildpad. Deze schildpad kon vooruit en achteruit, en daarnaast in een willekeurige hoek draaien. Dat zijn eigenlijk alle ingredienten.

Er wordt een apart scherm geopend waarop een klein driehoekje zichtbaar is. Dit is de schildpad. Vervolgens zie je de schildpad bewegen.

2. Belangrijke commando's

  • turtle.forward(Lengte): Over de afstand Lengte gaat de schildpad vooruit.
  • turtle.backward(Lengte): Over de afstand Lengte gaat de schildpad achteruit.
  • turtle.left(Hoek): Over de hoek Hoek draait de schildpad naar links. De hoek wordt uitgedrukt in graden.
  • turtle.right(Hoek): Over de hoek Hoek draait de schildpad naar rechts.
  • turtle.begin_fill() t/m turtle.end_fill(): Het gebied waar de schildpad omheen gelopen is wordt gekleurd.
  • turtle.color(LijnKleur[, VullingKleur]): Hiermee kun je de lijn die de schildpad een kleur meegeven. Gebieden die worden opgevuld krijgen een tweede kleur. Je kunt gebruik maken van een standaard bibliotheek met kleurnamen zoals 'black', 'blue', 'green', 'pink', 'red', 'white', 'yellow', ... We hebben een overzicht met kleuren op de site staan. Je kunt ook gebruik maken van de RGB-code:
  • turtle.colormode(mode): Er zijn verschillende manieren om met RGB-codes kleuren in te voeren. Als mode = None dan kan gebruik worden gemaakt van de hexadecimale invoer. De invoer voor rood is "#FF0000". Als mode = 255, dan kunnen voor R, G en B drie getallen tussen 0 en 255 worden ingevoerd. In dit geval wordt rood gerepresenteerd door (255,0,0). Tenslotte kan mode = 1 zijn. Dan liggen deze drie getallen tussen 0 en 1. Nu is rood (1,0,0). We zullen veelal turtle.colormode(255) gebruiken.
  • turtle.pencolor(r,g,b): Alleen de kleur van de lijn/rand wijzigen.
  • turtle.penup() en turtle.pendown(): Tijdelijk de pen van het papier halen.
  • turtle.fillcolor(r,g,b): Alleen de kleur van de vulling wijzigen.
  • turtle.position(): Hiermee krijg je informatie waar de pen zich bevindt.
  • turtle.goto(x,y): Hiermee kun je de pen laten bewegen naar (x,y).
  • turtle.speed(): Varieert van 1 (langzaam) tot 10 (snel), of 0, in dit geval zal de snelheid zo hoog mogelijk zijn.
  • turtle.done(): Ter afsluiting van de module. Hierna pas kan het aparte scherm worden afgesloten.
  • turtle.setworldcoordinates(x1,y1,x2,y2): Hiermee kun je (vooraf) je eigen scherm creeren waarop de schildpad actief is.
  • turtle.exitonclick(): Programma wordt afgesloten bij aanklikken van scherm.
  • turtle.bgpic: Je kunt op de achtergrond een plaatje zetten.
  • turtle.TurtleScreen._RUNNING=True: Voor gebruikers van Notebook is dit een belangrijke regel. Zonder deze regel (helemaal bovenaan) werkt het programma niet (een bug).

Op internet staat een uitgebreidere lijst met commando's. Je kunt ook naar de website https://docs.python.org/3/library/turtle.html gaan.

3. Programma: Het opvullen van een figuur

# Turtle
# 3a: Het opvullen van een figuur. Standaard Turtle voorbeeld.
# Hoek kan worden gevarieerd.
# Kies Hoek uit bijvoorbeeld 135, 150, 160, 170, 175
import turtle

Hoek = 135
turtle.TurtleScreen._RUNNING=True
turtle.title('Standaard Turtle voorbeeld')
turtle.speed(0)
turtle.color('red', 'aqua')
turtle.begin_fill()
while True:
    turtle.forward(200)
    turtle.left(Hoek)
    if abs(turtle.pos()) < 1:
        break
turtle.end_fill()
turtle.done()
# Turtle
# 3b: Het opvullen van een figuur
# Je kunt zelf Hoek1 en Hoek2 varieren.
import turtle
turtle.TurtleScreen._RUNNING=True

Lengte = 300
Hoek1 = 160
Hoek2 = 100
turtle.title("Programma 1: Opvullen van een figuur")
turtle.color('green', 'cornsilk')
turtle.speed(10)
turtle.begin_fill()
count = 0
while count < 500:
    turtle.forward(Lengte)
    turtle.left(Hoek1)
    turtle.forward(Lengte)
    turtle.left(Hoek2)
    if abs(turtle.pos()) < 1:
        break
    count += 1
turtle.end_fill()
turtle.done()
# Turtle
# 4: Het opvullen van figuren
# Achtereenvolgens twintighoek, negentienhoek, ..., driehoek
import turtle
turtle.TurtleScreen._RUNNING=True
turtle.title("Programma 2: twintighoek, negentienhoek, ..., driehoek")
turtle.speed(9)
turtle.right(90)
turtle.penup()
turtle.forward(300)
turtle.right(90)
turtle.forward(50)
turtle.pendown()
turtle.left(180)
turtle.pencolor('blue')
turtle.colormode(255)
for nhh in range(18):
    nh = 20 - nhh
    h = 360/nh
    turtle.fillcolor(255,nh*12,nh*12)
    turtle.begin_fill()
    for k in range(nh):
        turtle.forward(100)
        turtle.left(h)
    turtle.end_fill()
turtle.done()

4. Programma: Spiraal

# Turtle
# 5: Spiraal
# Hoeken en Ronden kan worden gevarieerd.
import turtle
turtle.TurtleScreen._RUNNING=True
turtle.title("Programma 3: Spiraal")

turtle.color('black', 'yellow')
turtle.speed(0)
Hoeken = 6
Ronden = 20
Start = 30
Delta = max(Start // (Hoeken+2), 2)
Size = Start
turtle.begin_fill()
for k in range(Hoeken*Ronden):
    turtle.forward(Size)
    turtle.left(360/Hoeken)
    Size += Delta
turtle.goto(0,0)
turtle.end_fill()
turtle.done()

5. Programma: Pythagoras Olympiade opgave 374

# Turtle
# Pythagoras Olympiade opgave 374 (Jaargang 57/4, Oplossing Jaargang 58/1)
# Hieronder is een schets met twee regelmatige achthoeken en 
# twee gelijkzijdige driehoeken. Je kunt je voorstellen dat je 
# dit patroon herhaalt. Kom je dan precies bij het begin uit? 
# Bonuspunt
# Voor welke regelmatige n-hoek (n > 6) kun je een patroon 
# creeren waarbij je precies terugkeert bij het begin.

# Klik steeds op het rode vierkant in het midden om verder te gaan
# (1) Plaatje schetsen horende bij deze opgave
# (2) Plaatje oplossing schetsen horende bij deze opgave
# (3) Andere oplossingen schetsen
# Voor de uitwerking van deze opgave zie 
# https://www.pyth.eu/oplossingen-pythagoras-olympiade-57-4

import turtle

DATA = [(100, 150, 8, 24, 2), (60, 250, 8, 24, 12), 
        (40, 270, 7, 42, 21), (60, 180, 9, 18, 9), 
        (50, 100, 12, 12, 6), (50, 80, 15, 10, 5), (40, 50, 24, 8, 4),
        ]
MAXCNT = 6

def RedButton():
    # Tekenen van rode button in het midden
    turtle.color('black', 'red')
    turtle.penup()
    turtle.goto(-50,-50)
    turtle.pendown()
    turtle.begin_fill()
    for m in range(4):
        turtle.forward(100)
        turtle.left(90)
    turtle.end_fill()
    turtle.penup()
    turtle.goto(0,0)
    return

def Draw(x, y):
    global cnt
    (Lengte, InitialisatieLengte, Hoeken1, Hoeken2, Herhalingen) = DATA[cnt]
    turtle.clear()
    RedButton()
    # Turtle wordt naar juiste positie verplaatst
    turtle.pendown()
    turtle.left(90)
    turtle.penup()
    turtle.forward(InitialisatieLengte)
    turtle.left(90)
    turtle.forward(Lengte/2)
    turtle.pendown()
    turtle.left(180)
    # Tekenen van figuur
    for m in range(Herhalingen):
        turtle.color('black', 'cornsilk')
        turtle.begin_fill()
        for k in range(Hoeken1):
            turtle.forward(Lengte)
            turtle.left(360/Hoeken1)
        turtle.end_fill()
        turtle.forward(Lengte)
        turtle.right(360/Hoeken2)
        turtle.color('black', 'aqua')
        turtle.begin_fill()
        for k in range(3):
            turtle.forward(Lengte)
            turtle.left(120)
        turtle.end_fill()
        turtle.forward(Lengte)
        turtle.right(360/Hoeken2)
    # Turtle wordt weer terug geplaatst
    turtle.penup()
    turtle.goto(0,0)
    turtle.pendown()
    turtle.setheading(0)
    # Gereed maken van doorgaan of stoppen
    if (abs(x) < 50) & (abs(y) < 50):
        if cnt == MAXCNT:
            turtle.exitonclick()
        else:
            cnt += 1
    return
    
cnt = 0
turtle.TurtleScreen._RUNNING=True
turtle.title("Programma 4: Pythagoras Olympiade opgave 374")
screen = turtle.Screen()
turtle.speed(0)
RedButton()
### (1) Plaatje schetsen horende bij deze opgave
### (2) Plaatje oplossing schetsen horende bij deze opgave
### (3) Andere oplossingen schetsen (bonus opgave)
screen.listen(0,0)
screen.onclick(Draw, btn = 1, add=None)
screen.mainloop()

6. Programma: Gebruik van een achtergrondplaatje

# Turtle
# Gebruik van achtergrondplaatje
# Zorg er voor dat FILENAME wel op de goede plaats staat.
# Gebruik van exitonclick

import turtle
turtle.TurtleScreen._RUNNING=True
FILENAME = "./Pythagoraslogo.png"

turtle.shape("turtle")
turtle.bgpic(FILENAME)
turtle.forward(250)

turtle.exitonclick()

7. Programma: Moderne kunst

# Moderne kunst
turtle.TurtleScreen._RUNNING=True
i = 1
turtle.tracer(n=2, delay=0.1)
Doorgaan = True
while Doorgaan:
    try:
        turtle.forward(1+i/3)
        turtle.right(30+i/6)
        i += 1
        if i == 1500:
            Doorgaan = False
    except turtle.Terminator:
        break
turtle.done()

8. Programma: zelf tekenen

# Hiermee kun je zelf tekenen
# Bron: https://www.bhutanpythoncoders.com/

from turtle import *
turtle.TurtleScreen._RUNNING=True
shape("turtle")
color("blue")
shapesize(2)
speed(10)
pensize(3)
 
def draw(x,y):
 
    # stop backtracking
    ondrag(None)
 
    # drawing as per the x and y
    # coordinates of mouse movement
    goto(x, y)
     
    # Call fun again
    ondrag(draw)
 
ondrag(draw)
 
# take screen in mainloop
mainloop()

9. Programma: toegift

# Toegift. Bron: onbekend
# Kies Hoeken tussen 10 en 60
import turtle
import math
turtle.TurtleScreen._RUNNING=True
turtle.tracer(n=2, delay=0.1)
Hoeken = 10
Basis = 600/Hoeken
T = 2*math.cos(math.pi/Hoeken)
Size = Basis/T
for k1 in range(Hoeken):
    turtle.forward(Size)
    turtle.left(360/Hoeken)
    for k2 in range(2*Hoeken):
        turtle.left(180/Hoeken)
        turtle.forward(Basis)
turtle.done()

10. Programma: Fractals

# tientallen fractals zijn te vinden op: 
# https://pythonturtle.academy/t-square-fractal-with-python-turtle-source-code/
import turtle
turtle.TurtleScreen._RUNNING=True
screen = turtle.Screen()
screen.title('T-square Fractal - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
screen.tracer(0,0)
turtle.speed(0)
screen.bgcolor('white')
turtle.hideturtle()
turtle.pencolor('white')

def stacksquares(x,y,length,n):
    if n==0: return
    stacksquares(x-length/2,y-length/2,length/2,n-1)
    stacksquares(x+length/2,y+length/2,length/2,n-1)
    stacksquares(x-length/2,y+length/2,length/2,n-1)
    stacksquares(x+length/2,y-length/2,length/2,n-1)
    
    turtle.up()
    turtle.goto(x-length/2,y-length/2)
    turtle.down()
    turtle.seth(0)
    turtle.begin_fill()
    for _ in range(4):
        turtle.fd(length)
        turtle.left(90)
    turtle.end_fill()

turtle.up()
turtle.goto(-800,-800)
turtle.begin_fill()
turtle.fillcolor('black')
for _ in range(4):
    turtle.fd(1600)
    turtle.left(90)
turtle.end_fill()
turtle.fillcolor('white')
stacksquares(0,0,800,7)
screen.update()
turtle.done()

11. Programma: Woordl

# Woordl omgeving, ook te vinden bij PythonTurtle.Academy
# De rollen zijn omgekeerd: de computer raadt een woord dat jij 
# in gedachten hebt. Het programma is niet zo geweldig. Er zijn diverse
# woorden waarvoor dit programma meer dan 6 beurten nodig heeft, en dan heb
# je een foutmelding.
# Let op: je hebt wel een bestand nodig met woorden.
# Bijvoorbeeld: ./woorden5.txt, zie bij woordl.

import random
import turtle
from tkinter import * 
from tkinter import messagebox

turtle.TurtleScreen._RUNNING=True
screen = turtle.Screen()
screen.setup(1000,1000)
screen.title("Wordle Solver - PythonTurtle.Academy")
turtle.speed(0)
turtle.hideturtle()
screen.tracer(0,0)
screen.bgcolor('black')
turtle.color('white')

gs = 0
state = []
for i in range(6):
  state.append([-1]*5)

def getwords(words, cs, count=False):
  res = []
  cnt = 0
  for w in words:
    t = list(w)
    flag = True
    cnt = dict()
    # first loop checks only positions are set
    for l,p in cs:
      if p<0: continue
      if cs[(l,p)] > 0:
        if t[p] == l:
          t[p] = '*'
          if l in cnt: cnt[l] += 1
          else: cnt[l] = 1
        else:
          flag = False
          break
      else:
          if t[p] == l:
              flag = False
              break
    if (not flag): continue
    # second loop checks only positions are not set
    for l,p in cs:
      if p!=-1: continue
      v = 0 if l not in cnt else cnt[l]
      for _ in range(cs[(l,p)]-v):
          try:
              p = t.index(l)
              t[p] = '*'
          except ValueError:
              flag = False
              break
      if (not flag): break
    if (not flag): continue
    # third loops checks non-existent letter
    for l,p in cs:
      if p!=-2: continue
      if l in t:
        flag = False
        break
    
    if flag: 
        if count: cnt += 1
        else: res.append(w)
  if count: return cnt
  else: return res

def guess_random(words):
  return random.choice(words)
        
def draw_square(coord,s,fc='black'):
  turtle.up()
  x = coord[0]
  y = coord[1]
  turtle.goto(x-s/2,y-s/2)
  turtle.seth(0)
  turtle.down()
  turtle.fillcolor(fc)
  turtle.begin_fill()
  for _ in range(4):
    turtle.fd(s)
    turtle.left(90)
  turtle.end_fill()

def get_coord(i,j):
  return -200+100*j, 300-100*i

def draw_board():
  turtle.pencolor('dark gray')
  for i in range(6):
    for j in range(5):
      draw_square(get_coord(i,j),80)

def display_word(w):
  turtle.up()
  turtle.color('white')
  for i in range(5):
    x,y = get_coord(gs,i)
    turtle.goto(x,y-23)
    turtle.write(w[i].upper(),align='center',font=('Arial',40,'bold'))

def update_cell(i,j):
  global w,state
  x, y = get_coord(i,j)
  turtle.pencolor('dark gray')
  if state[i][j] == 0:
    fc = 'dark gray'
  elif state[i][j] == 1:
    fc = 'goldenrod'
  else: fc = 'green'
  draw_square(get_coord(i,j),80,fc)
  turtle.up()
  turtle.color('white')
  turtle.goto(x,y-23)
  turtle.write(w[j].upper(),align='center',font=('Arial',40,'bold'))
  screen.update()
  
def play(x,y):
  flag = False
  for i in range(6):
    if flag: break
    for j in range(5):
      cx, cy = get_coord(i,j)
      if (cx-x)**2 + (cy-y)**2 < 1600:
        flag = True
        ci = i
        cj = j
        break
  if not flag: return
  if ci != gs: return
  state[ci][cj] = (state[ci][cj] + 1) % 3
  update_cell(ci,cj)

def submit():
  global state
  global gs
  global w,words

  for i in range(5):
    if state[gs][i] == -1: return

  cs = dict()
  for i in range(5):
    if state[gs][i] == 0: # letter doesn't exist
      cs[(w[i],-2)] = 1
    else:
      if (w[i],-1) not in cs:
        cs[(w[i],-1)] = 1
      else:
        cs[(w[i],-1)] += 1
      if state[gs][i] == 1: cs[(w[i],i)] = 0
      else: cs[(w[i],i)] = 1
  words = getwords(words,cs)
  print("Aantal mogelijkheden:", len(words))
  w = guess_random(words)
  gs += 1
  display_word(w)
  if len(words) == 1:
    messagebox.showinfo("Done", "Congratulations!")
    turtle.bye()

  #screen.update()

orig_words = []
FILENAME = './woorden5.txt'
f = open(FILENAME,'r')
for w in f:
  orig_words.append(w.strip())

cs = dict()
words = getwords(orig_words,cs)
w = guess_random(words)
w = 'woord'
draw_board()
display_word(w)
screen.update()
screen.onclick(play)
screen.onkey(submit, 'Return')
screen.listen()
screen.mainloop()
#turtle.done()
#turtle.exitonclick()

12. Slotopmerkingen

Je kunt heel veel doen met Turtle. Op de Pythagoras site kun je het programma downloaden. Er zijn diverse onderdelen waarmee je mooie plaatjes kunt maken, maar er is ook aandacht voor andere zaken. Onder andere kun je Turtle gebruiken om zelf spelletjes te programmeren. Twee spelletjes noemen we hier: Wordle en Snake.