perjantai 6. helmikuuta 2015

Racket-turtle 7.luokan matikan tunneilla

Tällä viikolla olemme koodanneet 7. luokkalaisten kanssa geometrisia kuvioita Racket-turtlella. Olimme juuri opiskelleet erilaisten monikulmioiden nimiä, joten nyt pääsimme hyödyntämään tietojamme. Näytin oppilaille ensin miten Turtlelle annetaan ohjeet neliön piirtämiseksi. Tämän jälkeen he saivat tehtäväksi piirtää tasasivuisen kolmion, säännöllisen kuusikulmion, suunnikkaan tai neljäkkään, ympyrän sekä itse keksimänsä kuvion. Lopuksi kuviot piti saada piirtymään samaan kuvaan eri väreillä.

Osa oppilaista keksi nopeasti miten Turtlea ohjataan, osalla kesti hieman kauemmin, mutta jokainen sai ensimmäisen tunnin jälkeen vähintäänkin kolmion valmiiksi (myös yksi ympyrä ilmestyi jo ensimmäisellä tunnilla). Toisella tunnilla nopeimmat pääsivät jo yhdistämään kuvioitansa. 
Ohjelmointi vaikutti innostavalta, koska jälleen kerran kun kello soi, useampi oppilas jäi vielä koodaamaan kuvioitansa ja lopuksi minulta kysyttiin: kai me jatketaan näitä vielä?

Tunnin jälkeen parantelin Racket-Turtle koodiani, koska tulin siihen tulokseen, että yksinkertaisuuden vuoksi on kuitenkin helpompaa, että ohjeissa sallitaan sittenkin sisäkkäiset listat (eli ohjeiden antajan ei tarvitse osata käyttää "append:ia" tai "cons":ia, pelkkä "list" toimii). Rajoitin piirtämistä myös niin, että vain piirtoalueelle osuvat viivat piirretään (jotta animaatio ei sekoaisi liian isojen kuvien kanssa). Oppilaiden oli myös vaikea hahmottaa mihin kohtaan tiedostoa omat ohjeet kirjoitettiin, joten laitoin Racket-turtle-koodin omaan tiedostoonsa (teachpacks/racket_turtle.rkt), esimerkit omaansa (turtle_esimerkit.rkt) ja tehtävät kolmanteen (turtle_harjoitukset_1.rkt).

Jos haluat kokeilla oppilaittesi kanssa Racket-turtle: lataa racket_turtle.zip. Pura paketti esim. kotihakemistoosi ja tutustu turtle_esimerkit.rkt - tiedostoon. Avaa sitten turtle_harjoitukset_1.rkt ja koodaa ohjeen mukaiset kuviot (kuva alla). Zip-paketti sisältää kaiken tarvittavan (paitsi itse DrRacket:iä).
Racket-turtle:lla piirretty harjoitus 1 (yksi mahdollinen ratkaisu)

Näillä matematiikan tunneilla Racket-turtlen käytössä pääpaino oli kuvioiden piirtämisessä. Pohdimme kuvioiden geometrisia ominaisuuksien kuten vaatimuksia sivujen pituuksille sekä kulmien suuruuksille. En edes yrittänyt ottaa esille ns. ohjelmointiteknisiä juttuja, kuten sitä että turhaa toistoa pitäisi välttää (en puuttunut siihen, että kuusikulmiossa oli kuusi kertaa sama koodin pätkä). Toki otimme esille repeat:in käytön, mutta vasta ympyrän kohdalla, koska ympyrän piirtämisessä tarvittava toistojen määrä olisi ollut järjetöntä koodata käsin. Myös siirtymät kirjoitettiin jokainen erikseen: siirtymä1, siitymä2 jne. vaikka siirtymäkoodi olisi toki järkevämpää kirjoittaa funktion muodossa, jossa annetaan käännöksen suuruus, siirtymän pituus ja uuden kuvion väri. Ehkä seuraava askel voisi olla oman funktion kirjoittaminen?

keskiviikko 4. helmikuuta 2015

Koodauskerho robottien kimpussa

Kevät on lähtenyt liikkeelle vauhdikkaasti koodauskerhossa. Blender 3D-mallinnuksen ja Racket-koodauksen lisäksi kerhossa on rakennettu ja ohjelmoitu Lego NXT ja EV3 robotteja. Ensimmäisenä kerhossa valmistui perusrobotti, joka ohjelmoitiin ajamaan kuusikulmion muotoista reittiä. Keksimme laittaa sille kynän kiinni "takapuoleen" ja saimme hienon "robottitaideteoksen" luokan seinälle.
Kerhomme ensimmäinen robotti
Toinen robotti syntyi EV3:n ohjeilla ja sille ohjelmoitiin "tutka"-toiminto, ettei se törmäilisi esteisiin.

EV3 - robotti
Tässä kuvaa "tutka-ajosta":


Tällä viikolla saimme käyttöömme myös sumo-pelilaudan ja tottakai sitä piti päästä heti testaamaan. Tässä kerhomme ensimmäinen sumorobotti kokeili pelilaudalla pysymistä, ja hyvinhän se siinä pysyi!


Kolmantena robottina valmistui Joulupukki ja poro näillä ohjeilla.

Koodauksen ABC: 11. oppitunti

Tällä kerralla laitoimme pacman:ille namut valmiiksi labyrinttiin. Koska oppilailla oli jo valmiina seinien sijainnit, pohdimme yhdessä miten saisimme kaikkiin muihin ruutuihin namuja. Päädyimme tekemään namut kaikkiin mahdollisiin ruutuihin ja poistamaan ne namut, jotka osuivat seinän kanssa samaan ruutuun.
Koska olimme tehneet jo pari rekursiivista funktiota, teimme tämänkin rekursiivisesti. Suunnitelma oli käydä pelikenttä läpi rivi kerrallaan ja tehdä kokonaisen rivin namut yhdellä iteraatiokierroksella ja samalla kerätä valmista listaa "paikat"-muuttujaan.

;; tee-namut : numero tyhjä-lista -> paikka-lista
(define (tee-namut rivi paikat)
  (if (> rivi PELIN-KORKEUS)
      paikat
      (tee-namut (add1 rivi) 

                 (append (map (tee-paikka rivi) leveys-lista)  
                          paikat)))) 

Tällaisia rekursiivisia funktioita olimme jo tehneet, mutta jotta saimme kätevästi koko rivillisen namuja, teimme sen suoraan käyttämällä map-funktiota (ks. koodin sininen osa). Map ottaa parametrina funktion tee-paikka ja ajaa sen jokaiselle leveys-listan alkiolle. Leveys-lista sisältää x-koordinaatit pelikentän leveydeltä, ja teimme sen näin:

(define leveys-lista (map add1 (build-list PELIN-LEVEYS values)))   

Tee-paikka - funktio oli myöskin uusi ilmestys, koska se ei ollutkaan ns. tavallinen funktio. Kun sitä kutsuu, se palauttaa funktion. Tämän selittäminen oppilaille olikin aika vaikeaa, mutta ilmeisesti ohjelmoinnissa on niin monta "outoa" asiaa, ettei tämä herättänyt sen kummempaa vastustusta.

;; tee-paikka : numero -> funktio
(define (tee-paikka y)
  (lambda (x) (make-paikka x y)))


Testasimme REPL:issä length:in avulla, että oikea määrä namuja syntyi (PELIN-LEVEYS * PELIN-KORKEUS):

> (length (tee-namut 1 '()))

Nyt poistimme tästä listasta ne, jotka osuivat seinän kanssa samaan ruutuun. Tähän käytimme remove*-funktiota.

(define namu-lista
  (remove* seinä-lista (tee-namut 1 '()) paikka=?))


Remove* - funktio tarvitsee parametrina apufunktion, joka kertoo milloin kaksi paikka ovat "samat". Jouduimme kirjoittamaan tätä varten paikka=? - funktion. Selitin, että tätä kutsutaan "predikaatiksi", mutta sillä ei ole äidinkielen predikaatin kanssa mitään tekemistä. Funktion toiminta oli helppo perustella: kaksi paikkaa ovat samat, jos niiden x-koordinaatit ovat samat JA niiden y-koordinaatit ovat samat. Tätä käyttäisimme myös jatkossa hyväksi kun testaamme onko pacman törmäämässä seinään tai syömässä namua.

;; paikka=? : paikka paikka -> boolean
(define (paikka=? p1 p2)
  (and (equal? (paikka-x p1)
               (paikka-x p2))
       (equal? (paikka-y p1)
               (paikka-y p2))))

 
Lopuksi teimme piirtofunktiot namujen piirtämiselle. Otimme mallia viime viikon vastaavista funktioista, joilla piirsimme seinäpalat pelipohjalle. 
  
(define SEINÄT (foldl piirrä-seinäpala PELIPOHJA SEINÄ-LISTA))

(define NAMU (circle (/ RUUTU 3) "solid" "red"))

;; piirrä-namupala : paikka kuva -> kuva
(define (piirrä-namupala p k)
  (place-image NAMU (skaalaa (paikka-x p)) (skaalaa (paikka-y p)) k))

(define TESTI (foldl piirrä-namupala SEINÄT namu-lista))  


 Ja tätä kun testasi niin voilà labyrintti täyttyi namuista!

Keltaiset namut
Punaiset namut
Tämän oppitunnin asiat olivat kyllä jokseenkin vaikeita, enkä tiedä kunka moni oikeasti ymmärsi mistä oli kyse kun käytimme map, foldl ja remove* - funktioita saati sitten lambdaa. Kun joululomalla itse tein pacman-pelin tein sen aivan eri tavalla. Nyt yritin tehdä sen yksinkertaisemmin ja välttelin sisäkkäistä rekursiota viimeiseen asti (rekursiivista funktiota, joka kutsuu toista rekursiivista funktiota). En nyt lopultakaan tiedä, oliko tämä valinta sitten yhteään parempi, koska jouduin vetämään esiin map:in ja lambdan. Ensi viikolla pacman pääsee syömään herkkuja, eli yritämme integroida syksyllä tehdyn koodin kevään koodiin. Katsotaan miten siinä käy.

keskiviikko 28. tammikuuta 2015

Koodauksen ABC: 10. oppitunti

Tällä viikolla palasimme takaisin pacman-pelin suunnitteluun. Aloitimme suunnittelemalla pelikentän labyrintin ruutupaperille. Jokainen teki omanlaisensa pelikentän:

Suunnitelmat
Jotta saisimme peliä hieman yksinkertaisemmaksi, siirryimme tässä vaiheessa ajattelemaan peliä ruudukkona, jossa jokainen ruutu on joko seinää tai käytävää. Käytäväruudussa voi olla, joko pacman, namu ja/tai haamu. Tästä eteenpäin koordinaatit eivät enää olisikaan suoraan pikseleitä ruudulla vaan loogisia sijainteja "grid":ssä ja skaalaisimme loogiset koordinaatit pikseleiksi skaalaa-apufunktion avulla. Tätä varten määritimme RUUTU-vakion, jota käytettiin skaalaa-funktiossa (grid-ruudun koko pikseleissä):

(define RUUTU 40)

(define (skaalaa x)
  (* RUUTU x))


Sitten mietimme miten voisimme tallentaa seinien sijainnit. Koska tähän asti olemme opiskelleet vasta struct:in ja listan niin eipä ollut vaikea keksiä, että mitäpä jos seinäpalojen koordinaatit tallennettaisiin "paikka"-structiin ja näistä tehtäisiin lista. Aluksi teimme kokeeksi listan, jossa oli vain kolme paikkaa, jos tämä toimisi, paikkoja voisi kirjoittaa helposti lisää.

(define-struct paikka (x y))

(define SEINÄ-LISTA
  (list (make-paikka 2 3)
        (make-paikka 3 3)
        (make-paikka 4 3)))


Sitten piti vain kirjoittaa koodi yhden seinäpalan piirtämiselle ruudulle eli määrittelimme piirrä-seinäpala-funktion:

(define SEINÄPALA (rectangle RUUTU RUUTU "solid" "black"))

;; piirrä-seinäpala : paikka kuva -> kuva
(define (piirrä-seinäpala p tausta)
  (place-image SEINÄPALA (paikka-x p) (paikka-y p)  tausta))


Tässä vaiheessa piti kerrata syksyltä struct:in käyttö sekä funktion parametrien tyypit ja paluuarvo. Tämä asia näytti olevan edelleen vaikeaa ymmärtää.

Ja viimeisenä teimme rivin joka piirsi kaikki seinäpalat pelikentälle. foldl-funktio ottaa parametrina piirtofunktion (piirrä-seinäpala), tyhjän pelikentän (PELIPOHJA) sekä listan seinäpalojen paikka-structeja (SEINÄ-LISTA). Se käsittelee listan alkioit yksi kerrallaan eli kutsuu piirrä-seinäpala-funktiota niin monta kertaa kuin annetussa listassa on alkioita. Annettu parametri PELIPOHJA on ns. lähtötilanne ja se annetaan niin ikään parametrina piirrä-seinäpala:lle. Syntyvä kuva siis ikäänkuin "laskostuu" alkutilanteen päälle, eli tämä on taas yksi tapa tehdä loop ja käyttää "akkumulaattoria". En tiedä ymmärsikö yksikään oppilas tätä mutta koodi oli lyhyt kirjoittaa ja se toimi hyvin :-)

(foldl piirrä-seinäpala PELIPOHJA SEINÄ-LISTA)

PELIPOHJA:aan teimme kiinteät reunat laittamalla empty-scene:llä tehdyn värillisen pohjan päälle valkoisen suorakulmion.

(define PELIN-LEVEYS 18)
(define PELIN-KORKEUS 9)

(define POHJA
  (empty-scene (skaalaa (add1 PELIN-LEVEYS))
               (skaalaa (add1 PELIN-KORKEUS))
               "black"))

(define PELIPOHJA
  (overlay (rectangle (skaalaa PELIN-LEVEYS) 

                      (skaalaa PELIN-KORKEUS) 
                      "solid" "white") 
           POHJA))

PELIPOHJA valmiina (siniset ruudut on lisätty selkeyden vuoksi)

Ja tässä kuvaa siitä miltä pelikentän koodausnäytti:

Pelikentän koodausta DrRacketillä

Teimme myös kuvat namuille ja latasimme haamut tästä linkistä, mutta emme ehtineet asettelemaan niitä vielä pelikentälle. Niitä ihmettelemme ensiviikolla. 

tiistai 20. tammikuuta 2015

Koodauksen ABC: 9. oppitunti

Jatkoimme Racket-Turtlen kanssa opiskelua. Kerroin että tehdäksemme tämän squiral-kuvion, tarvitsimme rekursiota:
Motivaatio rekursion käytölle...
Oppilaiden oli helppo nähdä tästä, että kuvio syntyisi, jos Turtle liikkuisi jokaisella kierroksella hieman pidemmän matkan kuin edellisellä.

Koodi tehtiin samanlaisella "akkumulaattori"-tekniikalla kuin edellisen tunnin merkkijonoja käyttänyt toista-hokema, eli keräsimme rekursiivisesti käskylistaa Turtlelle yhteen parametriin.Toteutimme tämän silmukka-kuvio-funktion käyttämällä sivu-ja-kulma-apufunktiota, joka teki ohjeet yhden sivun piirtämiseen.

(define (sivu-ja-kulma s k)
  (list (forward s) (turn-left k)))

(define (silmukka-kuvio s k kerrat ohjeet)
  (if (<= kerrat 0)
      ohjeet
      (silmukka-kuvio (+ s 5) k (sub1 kerrat) (append ohjeet (sivu-ja-kulma s k))))) 


Ja tätä kutsuttiin REPL:stä näin:

(piirrä (silmukka-kuvio 1 90 20 '()))

Ja nyt vasta aukesikin ovi Racket-Turtle-leikille. Ryhmä piirteli innoissaan erilaisia Turtle-taideteoksia, joissa monimutkaisimmissa oli jopa 5000 viivanpätkää!

Tässä ryhmäni aikaansaannoksia!











P.S. Sateenkaaren värit saatiin aikaan käyttämällä random-funktiota eli arpomalla make-color:ille uudet RGB arvot:

(change-color (make-color (random 255) (random 255) (random 255)))
 

Koodauksen ABC: 8. oppitunti

Pienen tauon jälkeen koodariryhmä palasi taas kurssille ja aloitimme valmistautumisen pacman-pelin uusiin vaiheisiin opiskelemalla listoja. Ajattelin, että jos listat ja rekursio olisivat jollakin tapaa ymmärretty (edes pinnallisesti), niiden lisääminen peliin olisi helpompaa.

Harjoittelimme ensin listan luomista list-komennon avulla ja jokainen oppilas teki listan kavereidensa nimistä tähän tyyliin:

(define KAVERIT (list "Antti" "Tomi" Timo" "Pasi" "Kalle"))

Sitten kokeilimme palauttaa ensimmäisen kaverin nimen listasta first-komennolla, ja samalla huomasimme, että myös second ja third toimivat! Listan lopun (kaikki muut paitsi ensimmäisen) listasta sai otettua rest-komennolla, joten haasteeksi tuli palauttaa listan viimeinen nimi sisäkkäisillä kutsuilla:

(first (rest (rest (rest (rest KAVERIT)))))

Teimme toisenkin listan KOULUKAVERIT, ja yhdistimme nämä käyttämällä appendia ja lopuksi selitin vielä miten yksittäisiä kavereita voi lisäillä käyttämällä cons:ia (tässä yhteydessä olisi pitänyt tietysti käsitellä myös kavereiden poistaminen listasta remove:lla mutta eipä tullut mieleen siinä tunnilla).

(append KAVERIT KOULUKAVERIT)
(cons "Ville" KAVERIT)

Toinen tavoite oli rekursion ymmärtäminen. Selitin ensin, että rekursio tarkoittaa sitä, kun funktio kutsuu itse itseään eli syntyy silmukka. Kerroin, että silmukan tekemisessä melko oleellista oli miettiä millä ehdolla se lopetta toimintansa. Teimme sitten tällaisen rekursiivisen funktion, joka kerää "tekstiä" yhteen parametriin jokaisella kierroksella:

(define (toista-hokema hokema kerrat koko-teksti)
  (if (<= kerrat 0)
      (string-append koko-teksti " Kiitos ja loppu.")
      (toista-hokema hokema
                     (sub1 kerrat)
                     (string-append " " (number->string kerrat) ". kerta " hokema koko-teksti))))


Tätä voitiin kutsua REPL:stä vaikka näin:

(toista-hokema "Pehmeet touhuu." 10 "")

Nämä kaksi harjoitusta johdattivat meidän Racket-Turtlen pariin ja toisen tunnin ajan oppilaat laativatkin käskylistoja Racket-Turtlelle. Ensimmäinen tehtävä oli piirtää Turtlella tasasivuinen kolmio. Kaikki saivat tämän tehtyä melko kivuttomasti, tutkimalla miten neliön koodi oli tehty. Tässä välissä keskustelimme hieman "The Total Turtle Trip Theorem":sta (Pappert, Mindstorms) eli siitä kuinka monta astetta Turtlen pitää yhteensä kääntyä, että se saa piirrettyä monikulmion. Ja pienen pohdinnan jälkeen löytyi vastauskin: täydet 360-astetta.

Tämän jälkeen neuvoin, että repeat - käskyllä voisi tehdä monikulmioita hiemän älykkäämmin ilman saman koodin kopioimista. Tämäkin onnistui useimmilta ja yksi oppilas hoksasi samalla, että kun riittävästi pienentää askelta ja kulmaa niin monikulmio näyttääkin jo ympyrältä. Repeat avasi yllättäen myös mahdollisuudet tehdä Turtlella hyvinkin monimutkaisia kuvioita, joten tästä eteenpäin vain ihmettelin mitä kaikkea oppilaat saivatkaan piirrettyä. 

lauantai 3. tammikuuta 2015

Seymour Papert:in Turtlet

Ostin itselleni joululahjaksi Seymour Papert:in klassikkokirjan "Mindstorms: Children, Computers, and Powerful Ideas". Vaikka kirja on ilmestynyt ensimmäisen kerran vuonna 1980, se on silti hämmästyttävän ajankohtainen ja ajatuksia herättelevä. Erityisesti Papertin kritiikki "koulumatematiikkaa" ja "koulufysiikkaa" kohtaan osui ja upposi. Ne todellakin ovat historian muovaamia konstruktioita, aihepiirejä joitka ovat valikoituneet mukaan sen mukaan mitä on perinteisesti voitu opettaa ja oppia niillä välineillä, joita kouluissa on ollut saatavilla: kynä, kumi, paperi, viivoitin ja harppi. Papert näki jo 1980, että tietokoneita käytettiin opetuksessa aivan väärin, niiden avulla yritettiin opettaa näitä "kuolleita kynä-plus-paperi-ajan taitoja". Hänen mielestään on jo lähtökohtaisesti väärin ohjelmoida drillaavia opetusohjelmia, jotka "ohjelmoivat" oppilaita toimimaan tietyllä tavalla. Hänen mielestään asian pitäisi olla täysin päinvastainen eli oppilaiden pitäisi päästä ratkomaan oikeita "aikuisten" ongelmia eli ohjelmoimaan tietokoneita. Tämä on Papertin mukaan ainoa tapa saada kuollut (paperille kirjoitettu) koulumatematiikka palautettua elävien kirjoihin.

Papertin ratkaisu tähän oli LOGO-ohjelmointikieli ja turtle-geometria, joita en itse lapsena valitettavasti päässyt kokeilemaan. Omassa peruskoulussani/lukiossani ei 1980-luvulla ollut tarjolla kuin konekirjoitusta. Heti kirjan luettuani halusin päästä kokeilemaan Turtlen ohjaamista, joten koodasin itselleni sellaisen Racket:illä. Halusin seurata kirjan "design principles"-ohjeita, ja tehdä niiden pohjalta oman versioni klassikosta. Jos Lego Mindstorms:in, Scratch:in sekä Turtle-Roy:n kehittäjät ovat seuranneet Papertin jalanjälkiä, niin aion minäkin. Ja kivastihan siinä lomapäivä vierähtikin...

Olin toki aikaisemminkin piirrellyt "turtle-geometrisia"-kuvioita Scratch:illä, joten periaate oli sinänsä tuttu. Miksi halusin tehdä vastaavan Racket:illä, johtui siitä että olemme jo käyttäneet oppilaideni kanssa Racket:iä, joten saman välineen kanssa jatkaminen tuntuisi paremmalta idealta kuin eri ympäristöjen välillä sinkoilu. 7. luokan koulugeometrian opettamisen lisäksi, mietin samalla miten voisin opettaa listojen ja rekursion käyttöä KoodauksenABC-kurssilaisilleni. Ja aina kannattaa käyttää tilaisuus hyväksi: koodaamista oppii vain itse koodaamalla :-)

Racket-turtle:a ohjataan periaatteessa samalla tavalla kuin esikuvaansa LOGO-Turtlea, mutta komennot annetaan listana. Esim. tämä koodin pätkä määrittelee Turtle-komentolistan neliön piirtämiselle:

(define neliö
  (list (forward 100)
        (turn-left 90)
        (forward 100)
        (turn-left 90)
        (forward 100)
        (turn-left 90)
        (forward 100)))


Varsinainen piirtäminen tehdään kutsumalla "piirrä"-funktiota tai "piirrä-osissa"-funktiota, joka piirtää kuvan pala palalta, kun jotain näppäintä painetaan. Eli näin piirrettäisiin neliö:

(piirrä neliö) TAI
(piirrä-osissa neliö)
Ensimmäinen Racket-turtlella piirretty kuvio
Kynän väri on oletuksena sininen ja se on aina laskettuna, mutta kynää voi halutessaan ohjailla myös näillä komennoilla:

(pen-up)
(pen-down)
(change-color "red")
(change-color (make-color 255 0 0))

Jos haluaa tehdä neliönsä älykkäämmin käyttäen toistorakennetta, sekin onnistuu repeat:in avulla:

(define sivu
  (list (forward 100)
        (turn-left 90)))

(define toisto-neliö
  (repeat 4 sivu))


(piirrä toisto-neliö)

Jos haluaa tehdä samaan kuvaan kaksi kuviota, komentolistat voi yhdistään käyttämällä append:a:

(define siirry
  (list (pen-up)
        (forward 100)
        (pen-down)
        (change-color "red")))

(define kaksi-neliötä
  (append neliö
          siirry
          toisto-neliö))

Yhdistelmäkuvio

Koska Racket on oikea ohjelmointikieli, sillä voi koodata myös funktioita, jotka tekevät komentolistoja eri kokoisille tai värisille kuvioille. Nämä funktiot yhdessä piirtävät halutun kokoisen ja värisen neliön:

(define (sivu2 pituus kulma)
  (list (forward pituus)
        (turn-left kulma)))

(define (neliö2 pituus väri)
  (cons (change-color väri)
        (repeat 4 (sivu2 pituus 90))))


(piirrä (neliö2 50 "red"))
Neliö muuttuvalla sivun pituudella sekä värillä
Yllä olevan sivu2-koodin avulla voi rakentaa funktioita myös muille säännöllisille monikulmioille. Huomaa, että neliö2:ssa on käytetty cons:ia list:in tilalla, koska repeat palauttaa kokonaisen listan ja (change-color väri) on pelkkä lista-alkio (list vaatisi kaksi lista-alkiota ja append puolestaan kaksi listaa). Racket-turtlen yksi tarkoitus on opettaa listojen käsittelyä, ja listojen käsittelyssä on pidettävä mielessä listan ja alkion ero. Seuraava dia selventänee list, cons ja append - funktioiden käyttöä:

Mitä eroa on list, cons ja append - funktioilla

Kun sain Racket-turtleni toimimaan, mopo karkasi välittömästi lapasista ja huomasin leikkiväni sillä  kuin pieni lapsi. Illan aikana tuli piirrettyä mm. nämä Papertin kirjan innoittamat kuviot:
Ympyrä-kukka


Random-kukat (random koko, random väri)
Vino "squiral"
Ja tässä vielä video Racket-turtlen toiminnasta (melko hypnoottista):


Jos haluat itse kokeilla Racket-turtlea niin lataa tästä tiedosto ja avaa se DrRacket:iin. Kirjoita tiedoston loppussa olevien esimerkkien tilalle omat komentosi. Pidä hauskaa!

Videolla näkyvä "squiral" on toteutettu rekursion avulla. Jos haluat kokeilla sitä itse niin tässä on koodi, joka generoi tarvittavan komentolistan Racket-turtlelle:

(define (squiral pituus kerrokset)
  (if (<= kerrokset 0)
      '()
      (append (list (forward (* 5 pituus)) 

                    (turn-left 90)) 
              (squiral (add1 pituus) (sub1 kerrokset)))))