Ohjelmoinnin peruskurssien laaja oppimäärä

Samankaltaiset tiedostot
Ohjelmoinnin peruskurssien laaja oppimäärä

Scheme-kesäkurssi luento 1

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Scheme-kesäkurssi luento 3

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Scheme-kesäkurssi luento 5

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Scheme-kesäkurssi luento 2

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

Luento 5. Timo Savola. 28. huhtikuuta 2006

Tieto- ja tallennusrakenteet

Ohjelmoinnin peruskurssien laaja oppimäärä

A TIETORAKENTEET JA ALGORITMIT

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 5: Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Ohjelmoinnin peruskurssi Y1

Java-kielen perusteet

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Ohjelmoinnin perusteet Y Python

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

815338A Ohjelmointikielten periaatteet

Ohjelmoinnin perusteet Y Python

Java-kielen perusteet

Ohjelmoinnin peruskurssi Y1

Algoritmit 1. Luento 3 Ti Timo Männikkö

Harjoitustyö: virtuaalikone

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin jatkokurssi, kurssikoe

Java-kielen perusteita

7/20: Paketti kasassa ensimmäistä kertaa

15. Ohjelmoinnin tekniikkaa 15.1

Ohjelmoinnin perusteet Y Python

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Ohjelmoinnin perusteet Y Python

Olio-ohjelmointi Syntaksikokoelma

Scheme-kesäkurssi luento 4

Java-kielen perusteet

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

18. Abstraktit tietotyypit 18.1

Tutoriaaliläsnäoloista

Lyhyt kertaus osoittimista

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

13. Loogiset operaatiot 13.1

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Taulukot. Jukka Harju, Jukka Juslin

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Kielioppia: toisin kuin Javassa

Hakemistojen sisällöt säilötään linkitetyille listalle.

Zeon PDF Driver Trial

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Jakso 4 Aliohjelmien toteutus

Loppukurssin järjestelyt

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Loppukurssin järjestelyt C:n edistyneet piirteet

1. Omat operaatiot 1.1

Transkriptio:

Ohjelmoinnin peruskurssien laaja oppimäärä Luento 4: Symbolit, derivojaesimerkki, kierroksen 1 ratkaisut (mm. SICP 2.32.3.2) Riku Saikkonen 1. 11. 2011

Sisältö 1 Symbolit ja sulkulausekkeet 2 Lisää Schemestä: tietotyypit ja apuproseduurit listoista hakemiseen 3 Derivoijaesimerkki 4 Kierroksen 1 tehtävien ratkaisut

Symbolit (SICP 2.3.1) symboli (symbol) on Schemen tietotyyppi, joka käyttäytyy melkein kuin vakiomerkkijono tai joidenkin muiden kielien enumeraatio symbolia ei voi muuttaa kahta symbolia on nopeaa (vakioaikaista) verrata toisiinsa symbolin sisältöä (mikä on kolmas merkki?) ei ole tarkoitus tutkia symboli tulostetaan pelkällä sen nimellä, esim. foo symboleita voi tuottaa Schemessä quote-nimisellä primitiivillä: 'foo tai (quote foo) foo symbolien vertailu: (eq? 'foo 'foo) #t (eli tosi) symboleita käytetään Schemessä usein enumeraatioina, erikoistapauksina proseduurien argumenteissa ja paluuarvoissa sekä kun ohjelma käsittelee Scheme-koodin näköistä syötettä

Listojen tekeminen quote:lla (SICP 2.3.1) 'foo tai (quote foo) siis tuottaa symbolin foo samalla tavalla voi tehdä myös listoja: '(1 2 3) tai (quote (1 2 3)) tuottaa samanlaisen listan kuin (list 1 2 3) tämä selittää tyhjän listan merkinnän '() toimii myös symboleille: '(a b) on 2-alkioinen lista, jonka alkioina ovat symbolit a ja b quote tai ' tekee vakiolistoja: sen sisällä olevia koodin näköisiä osia ei suoriteta esim. (define a 3):n jälkeen '(1 2 a 4) tuottaa listan (1 2 a 4), jonka kolmas alkio on symboli a se ei siis hae muuttujan a arvoa (list 1 2 a 4) hakisi muuttujan arvon eli (1 2 3 4) ja (list 1 2 'a 4) (1 2 a 4) eli listassa on symboli a

Esimerkki symbolien käytöstä Pieni pinolaskin rpncalc.scm (define (run program stack) (if (null? program) stack (let ((x (car program))) (cond ((eq? x 'pop) (run (cdr program) (cdr stack))) ((eq? x 'add) (run (cdr program) (cons (+ (car stack) (cadr stack)) (cddr stack)))) ((eq? x 'mul) (run (cdr program) (cons (* (car stack) (cadr stack)) (cddr stack)))) (else (run (cdr program) (cons x stack))))))) Testiajoja: (run '(1 2 add 3 add 4 add) '()) (10) (run '(1 2 3 4 mul add add) '()) (15) (run '(1 2 pop 3 4 5 mul pop add) '()) (4)

Koodi on dataa: sulkulausekkeet sulkulauseke (S-expression, symbolic expression): suluista, symboleista, numeroista yms. rakennettu lauseke tai siitä tehty listarakenne sulkulausekkeen voi tulkita koodina tai listarakenteena esim. (+ (* 3 x) y) voi ajatella joko Scheme-koodina tai 3-alkioisena listana, joka sisältää symbolit + ja y sekä alilistan samoin (if (= x y) 0 1) on joko koodia tai 4-alkioinen lista Scheme-kielessä toki (+ (* 3 x) y) laskee yhteenlaskun ja '(+ (* 3 x) y) tuottaa listarakenteen Schemen näköistä koodia (tai muuta sulkusyntaksia käyttävää kieltä) voi siis käsitellä Schemessä suoraan! esim. (car '(if (= x y) 0 1)) symboli if mutta (car (if (= x y) 0 1)) (car 0) tai (car 1) virheilmoitus (if:n palauttama 0 tai 1 ei ole lista) muissa kielissä joutuisi esim. tekemään oman luokan jokaiselle kielen syntaksin osalle (If-luokka, While-luokka, jne.)

Koodi on dataa: read ja write (read) lukee käyttäjältä sulkulausekkeen ja tekee siitä listarakenteen (write x) tulostaa listarakenteen x sulkulausekkeena melkein kuin display, mutta tulostaa muutaman asian eri tavalla read lukee sitä mitä write kirjoittaa yleisemmin: minkä tahansa ohjelmointikielen koodi on vain dataa (esim. merkkijono tai listarakenne), jota ohjelmointikielen toteutus osaa tulkita koodiksi ja ajaa myös tavallisen ohjelman muistissa oleva data voi olla samalla tavalla älykästä kuin ohjelman oma koodi esim. ohjelma voisi tallettaa merkkijonoon Python-koodia ja myöhemmin antaa sen Python-tulkille suoritettavaksi tai ohjelma voi sisältää jonkin oman ohjelmointikielen toteutuksen

Koodi on dataa: quote (SICP 2.3) Scheme-koodissa (quote (+ (* x y) 3)) tai lyhyemmin '(+ (* x y) 3) siis tuottaa listarakenteen (if (= 2 1) 4 3) on ehtolause (palauttaa kokonaisluvun 3), '(if (= 2 1) 4 3) palauttaa linkitetyn listan, jonka ensimmäinen alkio on symboli if quote:n sisällä olevaa koodia ei koskaan ajeta (vaikka se näyttäisikin Schemeltä) koodissa 'x palauttaa symbolin x, pelkkä x hakee muuttujan x arvon; esim. (if (eq? x 'x)...) tavallisilla listankäsittelyoperaatioilla voi käsitellä myös näin tuotettuja listoja joten Scheme-koodin näköisiä lausekkeita (sulkulausekkeita) on helppo käsitellä Schemessä on myös quasiquote eli `, jolla voi tuottaa listarakenteita, joissa tietyt osat muuttuvat (ei tarvita kursilla)

Sisältö 1 Symbolit ja sulkulausekkeet 2 Lisää Schemestä: tietotyypit ja apuproseduurit listoista hakemiseen 3 Derivoijaesimerkki 4 Kierroksen 1 tehtävien ratkaisut

Perus-Schemen tietotyypit numero (kokonaisluku 1, rationaaliluku 1/3, liukuluku 1.2, kompleksiluku 1+3i, epätarkka luku #i1/3; toteutuksessa ei tarvitse olla kaikkia) linkitetty lista (1 2 3) tarkemmin pari (1. 2) tai tyhjä lista () totuusarvo #t tai #f symboli foo merkkijono foo merkki #\a vektori eli yksiulotteinen taulukko #(1 2 3) proseduuri (primitiivi tai itsemääritelty) portti (esim. avatulle tiedostolle) arvon tietotyyppiä voi kysyä: number? (ja tarkempia), pair? ja null?, boolean?, symbol?, string?, char?, vector?, procedure? sekä port?

Yhtäsuuruudet Schemessä on monta eri yhtäsuuruusvertailua: eq? on tarkin ja nopein vertailufunktio (osoittaa samaan alkioon?, kuten Javan/C:n == ja Pythonin is) eqv? toimii myös mm. numeroille (käytetään harvoin) equal? käy listan, vektorin tai merkkijonon läpi rekursiivisesti ja käyttää eqv?:ta yksittäisiin alkioihin kuten Pythonin == tai Javan equals-metodi käytetään kun halutaan tietää, onko listoilla tai vektoreilla sama sisältö (vaikka ne olisivat eri listoja) = vain numeroille, string=? vain merkkijonoille ja char=? vain merkeille myös esim. <, >=, string<?, string-ci>=?, char<? yleensä käytetään näitä: eq? symboleille ja listoille (onko sama lista?) equal? listoille (onko samanlainen lista?) = numeroille string=? merkkijonoille

Listoista hakeminen (SICP 2.3.1) Schemen listoista voi etsiä alkioita primitiiveillä memq, memv ja member nämä ovat muuten samanlaisia, mutta käyttävät vertailuun eq?:ta, eqv?:tä ja equal?:ia esim. (memq 'foo '(1 2 b a foo 4)) tosi tarkemmin sanoen nämä palauttavat loppulistan siitä kohdasta eteenpäin, josta alkio löytyi ja totuusarvona käytettäessä mikä tahansa lista on tosi (kaikki arvot paitsi #f ovat tosia) käytännössä: memq etsittäessä symbolia, member etsittäessä alilistaa

Assosiaatiolistat Schemessä voi myös etsiä alkion yhteyteen talletettua alilistaa: (assq 'foo '((a 1) (b 32) (foo 5) (c 3))) (foo 5) primitiivit assq, assv ja assoc toimivat muuten samoin, mutta käyttävät eri primitiiviä vertailuun tällainen lista on nimeltään assosiaatiolista eli alist, sillä se yhdistää avaimia niihin talletettuun dataan tämä on perus-schemen vastine assosiatiiviselle taulukolle tai hajautustaululle (kuten Pythonin dict) assosiaatiolista on esim. hajautustaulua paljon tehottomampi, mutta hieman monikäyttöisempi: sillä voi tutkia mitä tahansa oikean muotoista listarakennetta Scheme-toteutuksissa on yleensä myös hajautustaulu tai vastaava, esim. Gambit-C:ssä table

Sisältö 1 Symbolit ja sulkulausekkeet 2 Lisää Schemestä: tietotyypit ja apuproseduurit listoista hakemiseen 3 Derivoijaesimerkki 4 Kierroksen 1 tehtävien ratkaisut

Symbolinen derivoija (SICP 2.3.2) Miten tekisit ohjelman, joka ottaa aritmeettisen lausekkeen (esim. 2x + 3 eli (+ (* 2 x) 3)) ja muuttujan (x) ja palauttaa derivaatan (2)? Riittää osata summan ja tulon derivointisäännöt: D(x + y) = Dx + Dy Dxy = xy + x y Ja vakion sekä muuttujan derivointisäännöt: d D vakio = 0 x = 1 d y = 0 dx dx Eikä tarvitse sieventää Kuinka paljon työtä tällaisen ohjelman tekemisessä olisi?

Ratkaisu (kokonaan!) deriv1.scm (define (deriv exp var) (cond ((number? exp) 0) ((symbol? exp) (if (eq? exp var) 1 0)) ((and (pair? exp) (eq? (car exp) '+)) (list '+ (deriv (cadr exp) var) (deriv (caddr exp) var))) ((and (pair? exp) (eq? (car exp) '*)) (list '+ (list '* (cadr exp) (deriv (caddr exp) var)) (list '* (deriv (cadr exp) var) (caddr exp)))) (else (error "unknown expression type -- DERIV" exp)))) Ajoesimerkkejä: (deriv 15 'x) 0 (deriv 'x 'x) 1 (deriv 'y 'x) 0 (deriv '(+ x 3) 'x) (+ 1 0) (deriv '(* x y) 'x) (+ (* x 0) (* 1 y)) (deriv '(+ (* 2 x) 3) 'x) (+ (+ (* 2 1) (* 0 x)) 0)

Abstraktimpi ratkaisu (kirjasta) deriv.scm (SICP 2.3.2) (define (deriv exp var) (cond ((number? exp) 0) ((variable? exp) (if (same-variable? exp var) 1 0)) ((sum? exp) (make-sum (deriv (addend exp) var) (deriv (augend exp) var))) ((product? exp) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp)))) (else (error "unknown expression type -- DERIV" exp)))) (define (variable? x) (symbol? x)) (define (same-variable? v1 v2) (and (variable? v1) (variable? v2) (eq? v1 v2))) (define (make-sum a1 a2) (list '+ a1 a2)) (define (sum? x) (and (pair? x) (eq? (car x) '+))) (define (addend s) (cadr s)) (define (augend s) (caddr s)) (define (make-product m1 m2) (list '* m1 m2)) (define (product? x) (and (pair? x) (eq? (car x) '*))) (define (multiplier p) (cadr p)) (define (multiplicand p) (caddr p))

Miksi abstraktioita? miksi kirjassa oli tämä pidempi ja abstraktimpi ratkaisu? se abstrahoi lausekkeiden, muuttujien ja numeroiden esitysmuodon deriv-proseduuria muuttamatta esitysmuodon voisi vaihtaa (jopa niin että lauseke olisi merkkijono eikä lista) pidemmässä esimerkissä tämä olisi olennaisempaa (jos deriv sisältäisi kymmeniä sääntöjä ja esitysmuotoa haluttaisiin muuttaa) ehkä siitä myös näkee helpommin mitä deriv tekee? miten deriv:n palauttamia lausekkeita voisi sieventää? yksi tapa olisi tehdä erillinen kaikenlaisia lausekkeita sieventävä proseduuri ja kutsua sitä deriv:n paluuarvolle kirjassa on yksinkertaisempi tapa: deriv:n kutsumat abstraktiot make-sum ja make-product sieventävät tekemäänsä lauseketta

Sisältö 1 Symbolit ja sulkulausekkeet 2 Lisää Schemestä: tietotyypit ja apuproseduurit listoista hakemiseen 3 Derivoijaesimerkki 4 Kierroksen 1 tehtävien ratkaisut