lauantai 27. syyskuuta 2014

Opettajien Racket - kurssi osa 1

Lielahden koululle kokoontui viime keskiviikkona 10 innokasta opettajaa eri puolilta Tamperetta. Vietimme 3h Racket:in ihmeellisessä maailmassa. Ennen kurssia olin vähän huolissani siitä, että osa kurssille tulijoista oli jo kokeneita ohjelmoijia ja osa ei ollut koodannut ollenkaan. Kurssi sujui tästä huolimatta erittäin hyvin ja näytti sieltä, että onnistumisen kokemuksia tuli jokaiselle.

Kolmen tunnin aikan kävimme läpi paljon asioita, peruslaskut, piirtotyökalut, funktiot, listat jne. Tässä jakamani materiaali itseopiskeluun, kertaukseen tai vaikkapa luokassa käytettäväksi:

Lataa Racket - kurssi (osa 1) materiaali.

Tämänkin kurssin punainen lanka on koodaushaasteet, kun saa itse keksiä ratkaisun homma tuntuu mielekkäältä.

Kurssin toinen osa on kahden viikon päästä.

Koodasimme kurssilla mm. tällaiset autojonot

sunnuntai 21. syyskuuta 2014

Koodauksen ABC: 5. oppitunti

Nyt kun kaikilla oli yhteen suuntaan liikkuva pacman käsissään, oli helppo lähteä kokeilemaan pacmanin liikuttelua eri suuntiin. Annoin oppilaille tehtäväksi etsiä koodista ne kohdat, jotka pitäisi muuttaa että pacman saataisiin kulkemaan oikealta vasemmalle, ylhäältä alas ja alhaalta ylös. Tämä harjoitus lämmitti matematiikan opettajan sydäntäni, koska tässä tuli niin selväksi käsitteet muuttuja ja vakio. Jos mennään vasemmalta oikealle tai oikealta vasemmalle, x on muuttuja. Jos mennään ylhäältä alas tai alhaalta ylös, y on muuttuja. Nyt piti muuttaa myös big-bang:ille annettavaa lähtötilaa (tähän asti ollut 0). Piti muuttaa myös yhteenlaskuja vähennyslaskuiksi siirrä-pacman - funktiossa. Ja tietysti lopetusehtoakin piti hieman rukata (moni pacman jumiutui vanhalla lopetusehdolla paikoilleen).

Kun pacmanin liikuttelu oli saatu hanskaan, ryhdyimme yhdessä miettimään miten olisi mahdollista tehdä pacman, joka voisi liikkua vapaasti sekä ylös, alas, vasemmalle että oikealle. Nythän se oli mahdollista vain yhteen suuntaan kerrallaan. Mitä tietoja tilaan pitäisi tallentaa x-koordinaatin lisäksi?
Mitä tietoa pitää tallentaa?

Oppilaat löysivät helposti y-koordinaatin, mutta vaikeampaa oli jo tajuta, että myös suunta, johon pacman on liikkumassa pitäisi olla tallessa tilamuuttujana.

Tästä pääsimmekin hyvin siihen, että nämä kolme tietoa pitäisi saada tallennettua yhteen "säiliöön"  joten esittelin heille tietorakenteen nimeltä struct.
Tallensimme tiedot sijainti-nimiseen structiin

Jotta struct:in käsite tulisi oppilaille selväksi, demonstroin sitä luokassa olleella muovilaatikolla ja paperin paloilla. Muovilaatikko oli struct, paperit laatikossa olivat kenttiä. Yksi paperi oli nimeltään x ja siihen kirjoitin (= tallensin) 0 jne.

Aloitimme helpoimmaista päästä. Teimme definellä ensin LÄHTÖ-nimisen structin, johon tallensimme pacmanin lähtötilan.

(define LÄHTÖ (make-sijainti 0 0 OIKEALLE))

Myöskään piirrä-pacman - funktiota ei ollut vaikea muuttaa, muutimme sen ottamaan suunnan, x- ja y-koordinaatin ulos tila - muuttujasta

;; piirrä-pacman : sijainti -> kuva
(define (piirrä-pacman tila)
        (place-image 
              (anna-pacman (sijainti-suunta tila))
              (sijainti-x tila) 
              (sijainti-y tila)
               KENTTÄ))

Suurin työmaa olikin sitten siirrä-pacman - funktion muutoksissa. Vaikka siinä käytettiin "vanhaa tuttua" cond:ia, ehdimme tehdä vain ensimmäisen ehdon kuntoon, ja osalla jäi vielä bugeja koodiin korjattavaksi seuraavalla kerralla.

Pacmanin toimintalogiikka

Onneksi muutama oppilas sai pacmanin kaikesta huolimatta taas liikkeelle. Tämä oppitunti kului siis muutoksiin, jotka eivät sinällään lisänneet mitään näkyvää toiminnallisuutta mutta tekivät jatkon mahdolliseksi. Tätä se usein on koodarin elämä...

Seuraavalla kerralla pääsemme ehkäpä liikuttelemaan pacmania jo nuolinäppäimillä?

Koodauksen ABC: 4. oppitunti

Koska edellisellä oppitunnilla tuli niin paljon uutta asiaa, olin päättänyt että tällä tunnilla vain kertaisimme vanhoja asioita koodaushaasteen avulla. Haaste olisi saada pacman liikkumaan vasemmalta oikealle eli soveltaa edellisen tunnin oppeja ufon laskeutumisesta.

Ja vaikka olin päättänyt, että mitään uutta tällä tunnilla ei tule niin otin kaikesta huolimatta cond - lauseen esiin. cond:ia ei sinänsä olisi tarvittu pacmanin liikuttamiseen mutta ajattelin, että voisi olla hyvä harjoitella vielä funktion kirjoittamista yhden apufunktion avulla. Eli teimme anna-pacman - funktion, joka palauttaa oikeaan suuntaan katsovan pacman-hahmon (kuvan). Parametrina oli tietysti suunta (YLÖS, ALAS, OIKEALLE, VASEMMALLE).

cond - lauseen avulla saadaan tehtyä koodihaaroja
Ehtolauseet olivat yksinkertaisesti (equal? suunta OIKEALLE) ja jos näin oli palautettiin oikealle katsova pacman jne. else - haaraan laitoimme pelkän PÄÄ:n ilman suuta. Tätäkin funktiota testattiin heti eri suunnan arvoilla ennen kuin jatkoimme eteenpäin.

Vaikka tarkoituksena oli tehdä aivan samaa kuin viime kerrallakin, oppilaiden oli vaikea ryhtyä työhön. Selvästikään funktion ja sen paluuarvon käsittettä ei oltu vielä ymmärretty riittävän hyvin. Siksi kysyin oppilailta kysymyksiä heidän koodistaan, missä oppilaat toimivat "funktioina" ja "kutsuin" heitä eri parametreillä. Tällaisia kyselin:
             - mitä annat minulle kun sanon "(piirrä-ufo 100)"?  - kuvan
             - mitä annat minulle kun sanon "(siirrä-ufo 150)"?  - 160 (ASKEL oli 10)
             - mitä annat minulle kun sanon "(maassa? 350)"?   - true (MAANPINTA oli 300)

Tämän kyselykierroksen jälkeen suurin osa tuntui ymmärtävän funktion käsitteen niin hyvin, että funktioiden kirjoittaminen lähti liikkeelle. Teimme siis uudelleen lähes samat funktiot kuin viime kerrallakin nyt vain eri nimisinä: piirrä-pacman, siirrä-pacman, reunalla? Ainoa ero  oli se, että piirrä-pacman kutsui anna-pacman - apufunktiota saadakseen oikeanlaisen pacmanin. big-bang oli myös aivan samanlainen. Lopputunnista kaikilla oli liikkuva pacman - koodi valmiina.

tiistai 2. syyskuuta 2014

Koodauksen ABC: 3. oppitunti

Kolmannella oppitunnilla opettelimme miten ufon saa laskeutumaan ruudun yläreunasta alas ja  pysähtymään ruudun alareunaan. Teimme koodin yhdessä pala palalta ja vaikka olin tehnyt aikaisemmin ohjeet ufon laskeutumiselle, huomasin meneväni asioita aivan erilailla kuin ohjeessa (Lataa ufo-animaation ohje).

Lähdin liikkeelle siitä, että selitin miten Racketin 2htdp/universe - kirjaston big-bang toimii. Tähänastihan olimme tehneet vain ohjelmanpätkiä, jotka tekevät jotain ja lopettavat toimintansa heti eli niissä ei ole ollut ns. message loop:ia, joka jäisi kuuntelemaan käyttäjän näppäinten painalluksia tai tietokoneen kellon "tikitystä". big-bang - funktio käynnistää tällaisen loopin. 

big-bang:in avulla voi tehdä interaktiivisia ohjelmia
Jotta big-bang tietäisi mitä milloinkin pitää tehdä, ohjelmoijan on kirjoitettava muutama funktio. Aloitimme kirjoittamalla ainoan pakollisen funktion, eli sen miten näyttöä päivitetään, kun vuorossa on toiminto to-draw. Koska tehtävänä oli saada ufo laskeutumaan ruudun yläreunasta alaspäin, kirjoitimme piirrä-ufo - funktion. 
Tämä oli ensimmäinen oppilaiden itsensä kirjoittama funktio, joten käytimme ensin aikaa muuttuja - käsitteen sisäistämiseen. Harjoittelimme ufon laskeuttamista ns. "manuaaliohjauksella" eli määrittelimme ensin define:llä muutaman vakion (KORKEUS, LEVEYS, KENTTÄ) sekä ufon kuvan (UFO) ja sitten kirjoitimme DrRacketin alempaan ikkunaan rivin koodia, joka piirsi UFO:n kentälle. Tehtävänä oli ajaa koodirivi uusilla parametreilla niin kauan kunnes ufo pääsi maanpinnalle. 




Nyt olikin jo paljon helpompaa miettiä, mikä voisi olla piirrä-ufo - funktion muuttuja. Valitsimme muuttujan nimeksi tila, ja kirjoitimme ensimmäisen funktion. Sitä myös testattiin heti kutsumalla sitä eri muuttujan arvoilla DrRacketin alemmasta ikkunasta. Ja sehän toimi! Tämän jälkeen kirjoitimme funktiolle myös kuvauksen kommenttiriville. Funktiota on jatkossa helpompi käyttää, kun merkitsee tällä tavalla funktion nimen (piirrä-ufo), parametrien tyypit (numero) ja paluuarvon tyypin (kuva). 

;; piirrä-ufo : numero -> kuva
(define (piirrä-ufo tila)
        (place-image UFO 250 tila KENTTÄ))

Kokeilimme tätä funktiota big-bang:in kanssa. Ja tietenkään ufo ei liikahtanutkaan.

(big-bang 0 
         (to-draw piirrä-ufo))

Pienen mietinnän jälkeen oli selvää, että kukaan tai mikään ei koskaan muuta tilaa, ja näin pääsimme tekemään siirrä-ufo - funktiota. Tämä on se funktio, jota big-bang kutsuu on-tick:llä, eli se toteutaa asioita, jotka muuttuvat ajan funktiona. Tässä vaiheessa piti miettiä miten tila ufon laskeutuessa muuttuikaan, ja päädyimme yhteenlaskuun (y-koordinaatithan kasvavat alaspäin kuljettaessa Racket:issa):

;; siirrä-ufo : numero -> numero
(define (siirrä-ufo tila)
        (+ tila ASKEL))

Lisäsimme uuden rivin big-bangiin ja nyt ufo lähti tosiaan liikkeelle mutta katosi maanpinnan alle!

(big-bang 0 
         (to-draw piirrä-ufo)
         (on-tick siirrä-ufo))

Viimeinen uusi asia tällä tunnilla oli big-bang:in lopetusehdon kirjoittaminen eli stop-when. Funktion nimeksi valittiin  maassa?. Nimessä oleva kysymysmerkki kertoo siitä, että se palauttaa ns. boolean arvon. Vaikka boolean - arvot eivät olleet entuudestaan tuttuja, oppilaiden tuntui olevan melko helppo ymmärtää, että jokin matemaattinen lauseke voi olla true tai false. Tällainen lopetusehdosta tuli:

;; maassa? : numero -> boolean
(define (maassa? tila)
            (>= tila MAANPINTA))

Ja big-bangiin lisättiin taas yksi uusi rivi:

(big-bang 0 
         (to-draw piirrä-ufo)
         (on-tick siirrä-ufo)
         (stop-when maassa?))

Nyt ufo saatiin laskeutumaan maanpinnalle. Jokaisella oppilaalla oli hieman eri kokoinen KENTTÄ, joten he saivat itse etsiä sopivan arvon MAANPINTA-vakiolleen.

Tässä kaksoistunnissa oli hirveästi asiaa, ja tunnin lopuksi oppilaat olivat hieman pyörällään päästä. Ehkäpä jatkossa pitäisi yrittää tehdä pienempiä kokonaisuuksia :-)

Laskujärjestysharjoituksia Racketilla

Harjoittelimme 7. luokkalaisten kanssa Racketin peruslaskutoimituksia sekä laskujärjestyssääntöjä tekemällä tätä harjoitusta:

Lataa Racket - tiedosto.

Heti alussa huomasin, että ennen tehtävää pitää käydä tietysti läpi aivan peruslaskutoimitukset Racketillä, joten teimme oheiset peruslaskut yhdessä ennen varsinaisia tehtäviä.

Tunnin alussa oppilaille annetut ohjeet
Laskujärjestys osoitetaan Racket:ille käyttämällä sisäkkäisiä sulkulausekkeita