Haskell 98. Puhdasta funktionalismia nonstriktissä paketissa. Antti-Juhani Kaijanaho

Koko: px
Aloita esitys sivulta:

Download "Haskell 98. Puhdasta funktionalismia nonstriktissä paketissa. Antti-Juhani Kaijanaho"

Transkriptio

1 Haskell 98 Puhdasta funktionalismia nonstriktissä paketissa Antti-Juhani Kaijanaho

2 Haskell 98: Puhdasta funktionalismia nonstriktissä paketissa Antti-Juhani Kaijanaho Copyright 1999 Antti-Juhani Kaijanaho Tätä esitystä saadaan levittää ja kopioida vapaasti. Muutettuja versioita saadaan myös levittää ja kopioida vapaasti, kunhan sekä alkuperäisen että muutetun tekstin tekijät mainitaan asianmukaisesti, ja muutettuja versioita ei voida erehdyksessä luulla alkuperäiseksi esitykseksi. Esitys on julkaistu Internetissä. (http://www.iki.fi/gaia/tekstit/ohjsem99/)

3 Luku 1 Johdanto Haskell on nonstrikti, puhtaasti funktionaalinen ohjelmointikieli (non-strict purely functional programming language). Tunnetuista ohjelmointikielistä sitä lähimpänä lienevät Lisp-sukuiset kielet, vaikka eroavaisuuksia onkin paljon. Haskell on hyvin erilainen kuin C, Pascal, C++ tai Java. Haskellissa voidaan esimerkiksi manipuloida funktioita ja aktioita (esimerkiksi merkin lukeminen tiedostosta, ikkunan avaaminen ja kahvin keittäminen) täysivaltaisina arvoina. Haskellissa on mahdollista periä rajapintoja vaan ei tyyppejä. Tyypit voivat olla rekursiivisia ja tietorakenteet äärettömiä; nonstriktiyden ansiosta vain tarpeellinen (useimmiten äärellinen) osa tietorakenteesta joudutaan todella konstruoimaan muistiin. Muuttujia ei ole; sen sijaan on olemassa funktiot (myös nollan argumentin funktiot eli vakiot) ja niiden parametrit. Silmukointirakenteita ei ole, vaan käytetään rekursiota, joka ei aina edes tarvitse päättymisehtoa! Onko Haskell sitten toivottoman hidas ja muistisyöppö? Nykyiset kääntäjät kykenevät tuottamaan koodia, joka on riittävän nopeaa melkein kaikkiin tarkoituksiin. Vain kovat reaaliaikasovellukset vaativat liikaa Haskellilta. Muistia Haskell-ohjelma vie enemmän kuin vastaava tyypillinen käsin koodattu C-ohjelma, mutta useimmissa tapauksissa sillä ei ole käytännön merkitystä. Joskus jopa nonstriksti laskenta voi vähentää muistin kulutusta, kun koko välitulosta ei tarvitse pitää muistissa. Haskell luotiin vonna 1987 yhtenäistämään nonstriktien puhtaiden funktionaalisten kielten joukot. Tuolloin nimittäin joka tutkijalla oli oma kielensä ja yhteisen sävelen löytäminen oli hankalaa. Nimi valittiin loogikko Haskell B. Curryn kunniaksi. Tavoite onnistui, ja kieli kehittyi huimaa vauhtia ottaen mukaan muutamia tutkimuksen viimeisimpiä tuloksia 1. Vuonna 1997 päätettiin luoda vakaa versio kielestä, Haskell 98, joka säilyisi samana ja joka toteutettaisiin laajasti, samalla kun tutkimusja kehitystyö keskittyy uuteen Haskell 2:een. Tarkoituksena oli, että Haskell 98 olisi standardoitu kieli, jota käyttäjät uskaltaisivat käyttää ilman muuttuvan kielen aiheuttamia murheita. Haskell 98 valmistui lopulta keväällä 1999 ja kolme neljästä tärkeimmästä Haskell-toteutuksesta tukevat sitä olennaisin osin. Haskell ei ole oliokieli, joten alityyppien luominen perimällä ei ole mahdollista. Sen sijaan monet asiat, jotka voidaan toteuttaa olioilla, voidaan kirjoittaa suunnilleen yhtä helposti käyttäen hyväksi Haskellin parametrisoitua polymorfismia, tyyppiluokkien perintää ja Haskell 98 -standardiin kuulumatonta mutta yleisesti toteutettua toisen kertaluvun polymorfismia ja sen tuomia eksistentialistisesti parametrisoituja tyyppejä. Toisaalta on olemassa kieli nimeltä O Haskell (http://www.cs.chalmers.se/~nordland/ohaskell/) sekä sen toteutus O Hugs, jotka laajentavat Haskellia niin, että olio-ohjelmointikin on mahdollista. Haskellista on olemassa neljä tärkeää toteutusta: Glasgow Haskell Compiler (GHC, saatavissa verkosta (http://www.haskell.org/ghc/)), Hugs (alunperin lyhenne sanoista Haskell Users Gofer System, myös saatavissa verkosta (http://www.haskell.org/hugs/)), Nearly a Haskell Compiler (NHC, saatavissa verkosta (http://www.cs.york.ac.uk/fp/nhc98/)) ja Haskell-B Compiler (HBC, saatavissa 1 Esimerkiksi monadinen I/O on alle kymmenen vuotta vanha tekniikka, ja sen ottivat ensimmäisten joukossa käyttöön Haskell-kielen kehittäjät. 3

4 Luku 1 Johdanto verkosta (http://www.cs.chalmers.se/~augustss/hbc/hbc.html)). Näistä kolme ensimmäistä tukevat Haskell 98:aa. Viimeksi mainittu on vielä vanhemman Haskell 1.4:n toteutus. Toteutuksista Hugs on kielen opiskeluun sekä nopeaan kehitystyöhön tarkoitettu tulkki, muut ovat optimoivia kääntäjiä: NHC on optimoitu minimoimaan tilavaatimukset (sekä ohjelmatiedoston koon että työmuistin osalta), GHC puolestaan optimoi lähinnä nopeutta. HBC on ainoa toteutus, joka tukee Unicode-merkistöä, kuten kielen määrityksen mukaan kuuluisi (muut käyttävät edelleen Latin 1 -merkistöä). Kaikki neljä toteutusta ovat vapaita ohjelmia. Tämä esitys perustuu määrityksen (http://www.haskell.org/definition) mukaiseen Haskell 98:een. Kaikkien täydellisten esimerkkiohjelmien on tarkoitus toimia kaikissa Haskell 98 -toteutuksissa. Osittaiset esimerkkiohjelmat toimivat sellaisenaan Hugs-tulkissa, jossa pääohjelma ei ole koskaan pakollinen. Ohjelmat on testattu vain Hugsissa, ja kun ohjelmointiympäristöä käsitellään, puhutaan vain Hugsista. Haskell-aiheista lukemista löytyy ihan kohtuudella. Kielen määrittelevät raportit Haskell 98: A Non-strict, Purely Functional Language ja Standard Libraries for Haskell 98 (toimittaneet Simon Peyton Jones ja John Hughes) ovat saatavilla verkosta (http://www.haskell.org/definition). Ne eivät kuitenkaan sovellu kielen opetteluun. Kohtuullinen opus opettelemista ajatellen on A Gentle Introduction to Haskell (http://www.haskell.org/tutorial/) (Paul Hudak, John Peterson ja Joseph H. Fasel). Erittäin hyvä johdatus funktionaaliseen ohjelmointiin on Richard Birdin ja Philip Wadlerin kirja Introduction to Functional Programming using Haskell, joka on uudistettu laitos myös erinomaisesta mutta jo hieman vanhasta samojen tekijöiden kirjasta Introduction to Functional Programming. Viimeksi mainittu teos löytyy Mattilanniemen kirjastosta. Kattava kirjallisuusluettelo (http://www.haskell.org/bookshelf/) löytyy Haskell-sivuston kautta. 4

5 Luku 2 Hello World Tässä on Haskell-kielellä kirjoitettu Hello World: {- hello.hs -} main :: IO () main = putstrln "Hello World!" Ohjelman voi ajaa kirjoittamalla komentoriville runhugs hello.hs (runhugs on Hugsin sellainen versio, joka lukee ohjelman sisäänsä ja ajaa sen suoraan; tällöin ei päädytä Hugsin normaaiin interaktiiviseen tilaan). Nyt siis pitäisi ruudulla näyttää jotakuinkin tältä: % runhugs hello.hs Hello World! % Vaihtoehtoisesti tämän ohjelman voi ladata interaktiiviseen Hugs-tulkkiin sanomalla hugs hello.hs Esiin tulee paljon tekstiä ja lopulta kehoite, johon pitää kirjoittaa main. Siihen voisi kirjoittaa minkä tahansa funktionnimen (tai itse asiassa minkä tahansa lausekkeen), mutta tiedostomme hello.hs määrittelee vain yhden: main. Sanomme siis main. Lopulta voi kirjoittaa :q, jolloin pääsee pois tulkista. Tämän kaiken pitäisi näyttää suurin piirtein tältä: % hugs hello.hs Hugs 98: Based on the Haskell 98 standard Copyright (c) World Wide Web: Report bugs to: Version: May 1999 Haskell 98 mode: Restart with command line option -98 to enable extensions Reading file "/usr/share/hugs98/lib/prelude.hs": Reading file "hello.hs": Hugs session for: /usr/share/hugs98/lib/prelude.hs hello.hs Type :? for help Main> main Hello World! Main> :q [Leaving Hugs] % 5

6 Luku 3 Funktionaalisesta ohjelmoinnista Funktionaalisessa ohjelmointityylissä tärkeä abstraktiokeino on sellaisten funktioiden rakentaminen ja käyttö, jotka operoivat funktioilla. On myös olennaisen tärkeää osata käyttää hyväksi nonstriktiyttä, joka mahdollistaa aika yllättävienkin ongelmien jakamisen osiin. Tarkastelemme muutamaa esimerkkiongelmaa, jossa sekä Haskell-kielen että funktionaalisen tyylin perusteet tulevat hyvin esille. Summa, tulo ja foldr Aloitetaan yksinkertaisella ongelmalla: On annettu lista lukuja. Laske niiden summa. Imperatiivisesti ajatteleva ohjelmoija saattaisi ajatella for-silmukkaa. Matemaatikko puolestaan määrittelisi tämän Σ-funktion rekursiivisesti. Haskellissa ei for-silmukoita ole, joten ainoaksi vaihtoehdoksi jää matemaatikon rekursiivinen versio. Tämä ei ole niin paha asia kuin rekursion pahuuteen tottuneen imperaatikon korvin kuulostaa: nonstrikti laskenta ja häntärekursion poisto muuttavat tilannetta olennaisesti. Esimerkki 3-1 Summausfunktio {- sum.hs -} sum [] = 0 sum (x:xs) = x + sum xs Summafunktio vie vain kaksi riviä koodia (katso Esimerkki 3-1). Ensimmäisellä rivillä määritellään rekursion päättymisehto: tyhjän listan summa on nolla. Toinen rivi on funktion yleinen tapaus. Se sanoo, että laskeaksesi epätyhjän listan summan laske yhteen listan ensimmäinen alkio ja lopun listan summa. Haskellissa funktio määritellään rajoitettujen yhtälöiden avulla. Yhtälön oikea puoli voi olla mikä tahansa lauseke, mutta vasemmalle puolelle on asetettu rajoituksia, jottei kääntäjän tarvitsisi toimia myös yleisten yhtälöiden ratkaisukoneena. Vasen puoli tulkitaan monimutkaisten pattern matching -sääntöjen avulla. Lyhyesti sanoen vasemman puolen tulee sisältää määriteltävän funktion nimi sekä sen parametrien kuvaukset. Yleensä funktion nimi on koko vasemman puolen ensimmäinen asia ja sen jälkeen tulevat parametrit, yksi kerrallaan. Parametrin paikalle voidaan laittaa joko muuttuja tai konstruktorilauseke. Edellä summausfunktion määritelmässä [] on tyhjää listaa esittävä listakonstruktori, ja x : xs on konstruktorilauseke, joka liittää muuttujan x arvoksi argumenttina annetun listan ensimmäisen alkion ja muuttujan xs arvoksi listan loppuosan. Varsinainen konstruktori tässä on lausekkeen keskellä oleva kaksoispiste (nimeltään cons), joka jäsennetään kuin se olisi infix-operaattori. Sen "parametrit"ovat tässä muuttujia, mutta ne voisivat ihan yhtä hyvin olla toisia konstruktorilausekkeita. Sulut ovat tarpeen, koska cons sitoo heikommin kuin funktion parametrien esittelyoperaattori (joka on pelkkää tyhjää tilaa). Kuten havaitaan, argumenttiarvot voidaan ikään kuin dekonstruoida jo parametrinvälityksessä: koko parametrille ei tarvitse antaa nimeä, jos tarvitaan vain sen osia. Jos argumentti ei täsmää 6

7 Luku 3 Funktionaalisesta ohjelmoinnista parametrilistan kanssa, yritetään seuraavaa saman funktion määrittävää yhtälöä: ensimmäinen, jola täsmää, on se, jota käytetään. Huomaa: Yhtälön oikealla puolella konstruktoreita voidaan käyttää luomaan uusia olioita. Siinä missä x : xs purkaa vasemmalla puolella listan palasiksi, kokoaa oikealla puolella 5 : [] uuden listan laittamalla tyhjän listan alkuun viitosen. 1 Periaatteessa siis viiden kokonaisluvun listan voisi kirjoittaa 5 : 4 : 3 : 2 : 1 : [], koska cons sitoo oikealta vasemmalle, mutta parempi lienee kuitenkin käyttää yksinkertaisempaa kielioppimakeista [5, 4, 3, 2, 1]. Seuraava ongelma on listan lukujen kertominen keskenään. Innokkaasti voisi joku kirjoittaa leikkaa-liimaa-korvaa-tekniikalla sum -funktiota muistuttavan toteutuksen (ks. Esimerkki 3-2). Esimerkki 3-2 Tulofunktio {- prod.hs -} prod [] = 1 prod (x:xs) = x * prod xs Tähän liittyy kuitenkin hyvin tunnettuja ylläpito-ongelmia. Niinpä olisikin parempi jollakin tavalla abstrahoida summa- ja tulofunktioille yhteinen rekursiokaava ja käyttää sitä näiden funktioiden kirjoittamiseen. Ratkaisu on kirjoittaa funktio, joka ottaa parametrinaan itse listan lisäksi tyhjän listan kuvan sekä rekursiotapauksessa käytettävän operaattorin. Esimerkki 3-3 määrittelee tällaisen funktion, jonka perinteinen nimi on foldr. Esimerkki 3-3 Funktio foldr {- foldr.hs -} foldr _ e [] = e foldr op e (x:xs) = x op foldr op e xs Funktion nimi tulee englannin kielen sanoista fold right. Tämä viittaa siihen, että funktio ikäänkuin laskostaa listan niin, että ennen niin pitkästä listasta tulee yksi naseva tulos, ja siihen, että jos rekursio kirjoitetaan auki, niin sulut kasautuvat lausekkeen oikeaan reunaan. On myös olemassa funktio foldl, joka toimii muuten samoin paitsi että se kasaa sulut vasempaan reunaan. Lisäksi foldl on häntärekursiivinen, mikä saattaa joissakin tilanteissa pienentää ohjelman tilavaatimusta. Huomaa: Funktioiden sum, prod ja foldr nimissä todella on heittomerkki. Se siis on osa näiden funktioiden nimeä. Näin siksi, että kielen standardikirjastoon kuuluu jo funktiot sum ja foldr, joiden nimet menisivät näin päällekäin itsestäänselvien nimiehdokkaiden kanssa. Siispä esimerkkifunktioille täytyy valita jokin toinen nimi, ja heittomerkin lisääminen funktion nimen perään on tällaisissa tapauksissa melko tavallinen ratkaisu. 1 Koska lista yleensä toteutetaan yhteen suuntaan linkittämällä, on cons nopea operaatio (O(1)). 7

8 Luku 3 Funktionaalisesta ohjelmoinnista Edellisessä esimerkissä näkyy eräs Haskellin mukava piirre: jokainen kahden muuttujan funktio voidaan muuttaa binääriseksi operaattoriksi laittamalla funktion nimi graaviaksenttien ("takahipsujen") sisään. Vastaavasti voidaan mikä tahansa binäärinen operaattori muuttaa kahden muuttujan funktioksi laittamalla se yksinään sulkeiden sisään (ks. Esimerkki 3-4). Tässä mielessä funktiot ja operaattorit ovat aivan sama asia. Vertaapa muuten mainitun esimerkin summa- ja tulofunktioiden määrittelyjä aiempiin: tässä esimerkissä ei ole yhtään ylimääräisyyksiä! Esimerkki 3-4 Funktiot sum ja prod toteutettuna foldr:lla {- sumprod.hs -} sum = foldr (+) 0 prod = foldr (*) 1 Funktiota foldr sanotaan korkean kertaluvun funktioksi, koska se operoi funktioilla (tässä tapauksessa yhteenlasku- tai kerto-opreraattorilla). korkean kertaluvun funktiot ovat funktionaalisen ohjelmoinnin kulmakivi, ja niitä kannattaa opetella käyttämään. Esimerkiksi Esimerkki 3-5 määrittelee erään toisen korkean kertaluvun funktion, ja Kuva 3-1 kokoaa muutamien standardikirjastoon kuuluvien funktioiden määrittelyjä. Määrittelyjen lukeminen ja niiden ymmärtäminen on hyvä harjoitustehtävä, erityisesti pisteoperaattori ja funktio map olisi hyvä ymmärtää kunnolla. Esimerkki 3-5 Funktio filter {- filter.hs -} filter _ [] = [] filter p (x:xs) p x = x : filter p xs otherwise = filter p xs Funktion filter määrittelyssä esiintyy eräs uusi kielirakenne. Määrittelevän yhtälön oikea puoli voidaan valita mielivaltaisten loogisten väittämien avulla. Väittämät käydään läpi järjestyksessä, ja ensimmäisen väitteen, jonka totuusarvo on tosi, mukainen oikea puoli valitaan. (Nollan muuttujan funktio otherwise palauttaa aina arvon tosi.) Jokaisen väitteen eteen laitetaan tässä rakenteessa pystyviiva. Tämä rakenne on olennaisesti jonkinlainen if-then-elseif-elseif-else, ja usein ohjelmat ovat helppolukuisempia, kun tätä rakennetta käytetään iffin (joka kielestä silti löytyy) sijasta. Funktio filter kuuluu standardikirjastoon. Haskellissa on voimassa ns. asemointisääntö (layout rule eli offside rule), jonka vuoksi täytyy ohjelmaa kirjoittaessa olla tarkkana siitä, mistä kohtaa riviä mikin ohjelmarivi alkaa. Nyrkkisäännöllä "enemmän oikealle jatkaa edellistä alikohtaa, sama kohta aloittaa uuden alikohdan, takaisin vasemmalle lopettaa"pärjää jonkin aikaa, mutta vakavasti Haskellista kiinnostuneen on parasta tutustua kielen määrittelyn luvun 2.7. antamaan tarkkaan kuvaukseen. Esimerkiksi funktion filter määrittelyssä alikohtia ovat väittämä oikea puoli -parit, joten ne kaikki sisennetään yhtä paljon oikealle funktion määrittelyn alusta alkaen. 8

9 Luku 3 Funktionaalisesta ohjelmoinnista Kuva 3-1 Standardikirjaston (prelude) korkean kertaluvun funktioita {- prelhofs.hs -} (.) f g x = f (g x) {- käytetään: (f. g) x -} flip f x y = f y x curry f x y = f (x,y) {- (, ) on parin konstruktori -} uncurry f (x,y) = f x y until p f x p x = x otherwise = until p f (f x) map _ [] = [] map f (x:xs) = f x : map f xs Huomaa: Funktion määrittelevän yhtälön vasemmalla puolella alaviiva täsmää mihinkä tahansa, mutta siihen ei voi viitata yhtälön oikealla puolella. Sitä on siis hyvä käyttää silloin, kun jonkin parametrin arvo on täysin yhdentekevä. Eratostheneen seula Seuraava ongelma liittyy alkulukuihin: Toteuta Eratostheneen seula, ja kirjoita funktio, joka palauttaa kaikki annettua lukua pienemmät alkuluvut, sekä funktio, joka palauttaa halutun monta ensimmäistä alkulukua. Olisi toivottavaa, että funktiot käyttävät yhteistä seulan toteutusta, jottei leikkaa-liimaa-syndrooma alkaisi vaivaamaan. Osoittautuu, että nonstriktiyden ansiosta tämä on helppoa. Haskell on nonstrikti kieli: se laskee vain sen, mitä se välttämättä tarvitsee. Esimerkiksi C lähtee laskemaan lausekkeen arvoa jäsennyspuun lehdistä käsin: vapaasti kerrottuna se laskee ensin sulkulausekkeet, sitten kertolaskut ja lopulta yhteenlaskut. Samoin C aina laskee funktion argumentit valmiiksi ennen kuin funktiota edes kutsutaan. Haskell sen sijaan lähtee jäsennyspuun juuresta. Se huomaa ensin yhteenlaskut ja toteaa tarvitseansa yhteenlaskun argumenttien arvoja; tällöin se rupeaa laskemaan niitä. Jos Haskell joskus huomaa, että se tietää jo tarpeeksi voidakseen laskea koko lausekkeen arvon, se jättää laskematta kaiken sen, mitä se ei ole siitä lausekkeesta vielä laskenut. C:ssä nonstriktiyttä tavataan kaiketi vain loogisten konnektiivien yhteydessä: jos ja-lausekkeen vasen puoli on epätosi, ei oikeaan puoleen edes katsota. Haskell toimii tällä lailla kaikkialla. Esimerkiksi, jos Haskellissa kutsutaan vakiofunktiota, ei funktion parametria koskaan lasketa. Tästä on paljon iloa, esimerkiksi äärettömät tietorakenteet käyvät mahdollisiksi. Triviaali esimerkki äärettömästä tietorakenteesta on loputon ykkösten jono ones: 9

10 Luku 3 Funktionaalisesta ohjelmoinnista {- ones.hs -} ones = 1 : ones Tätä lienee helpointa ajatella nollan funktion rekursiivisena funktiona, josta puuttuu päättymisehto. Se siis tuottaa, kuten sanottu, loputtoman ykkösten jonon. Huomattava on, että koska ones ei ota yhtään argumenttia ja koska Haskellissa funktioilla ei ole sivuvaikutuksia, voidaan koko sen tuottama lista esittää koneen sisällä äärellisenä, vakiokokoisena syklinä. Jos joku erehtyy pyytämään funktion ones arvoa, koko ohjelma ei välttämättä juutu umpiluuppiin. Nonstriktiys tarkoittaa, että vain välttämätön lasketaan (tai vaikka laskettaisiinkin enemmän, niin ylimääräisyyksiä ei huomioida). Jos siis joku pyytää tuon äärettömän listan viittä ensimmäistä alkiota, ei loppulistaa yritetä laskea. Näin ollen lauseke take 5 ones (funktion take toteuttaminen on harjoitustehtävä) palauttaa listan [1,1,1,1,1]. Sen sijaan listan viimeistä alkiota etsivä last jäisi tätä listaa käsitellessään etsimään omaa häntäänsä vaikka maailmanloppuun asti. Kokeile vaikka! Äärettömiä listoja konstruoi myös standardifunktio iterate, joka iteroi annettua funktiota annetulla alkuarvolla loputtomiin. Funktion määrittelee Esimerkki 3-6. Määritelmässä on huomattava uusi where-avainsana, jolla voidaan sitä edeltävään lausekkeeseen määritellä lokaaleja funktioita. Avainsanan jälkeen tulee yksi tai useampia funktiomäärittelyjä, jotka voivat olla keskenään rekursiivisia. Esimerkki 3-6 Funktio iterate {- iterate.hs -} iterate f x = xs where xs = x : map f xs Palataanpa alkulukuongelmaan. Nonstriktiä laskentaa ja äärettömiä listoja voi käyttää tässä aika jännällä tavalla hyväksi: konstruoidaan ensin lista kaikista alkuluvuista ja otetaan siitä vain se osa, mitä tarvitaan. Jos alkulukulistan konstruoi nollan muuttujan funktio alkuluvut, niin edellä esitettyihin kysymyksiin "mitkä ovat n ensimmäistä alkulukua"ja "mitkä ovat n:ää pienemmät alkuluvut"vastaavat lausekkeet take n alkuluvut ja takewhile (<n) alkuluvut. (Funktion takewhile määritteleminen on harjoitustehtävä.) Huomaa: Funktion viimeisen argumentin voi aina jättää pois (kunhan laittaa syntyneen lausekkeen sulkeiden sisään). Tällaisen lausekkeen arvo on yhden muuttujan funktio. Tämä uusi funktio palauttaa sen, minkä alkuperäinen funktio olisi palauttanut, jos argumentti laitettaisiin listan viimeiseksi. Toisin sanoen: (f a b c) d == f a b c d. Vastaavasti voidaan operaattoria leikata antamalla sille vain toinen operandi ja laittamalla tämä koko lause sulkeiden sisään. Tuloksena on jälleen yhden muuttujan funktio. Esimerkiksi (2*) on funktio, joka ottaa yhden parametrin ja joka palauttaa tämän parametrin kaksinkertaisena; siis (2*) 5 == 10. Jäljelle jää nyt vain itse alkulukujonon konstruointi, minkä tekee Esimerkki 3-7. Merkintä [2..] tarkoittaa ääretöntä listaa kaikista kokonaisluvuista kakkosesta ylöspäin. 10

11 Luku 3 Funktionaalisesta ohjelmoinnista Esimerkki 3-7 Alkulukujonon konstruointi {- primes.hs -} alkuluvut = map hd (iterate seula [2..]) where hd (x:_) = x seula (p:xs) = filter (not. (p jakaa )) xs p jakaa q = q mod p == 0 Esimerkin lukemista auttanee Eratostheneen seulan perusperiaatteen muistaminen: otetaan luettelo kaikista kokonaisluvuista kakkosesta ylöspäin, tiputetaan siitä ensin pois kakkosen monikerrat, sitten kolmosen monikerrat, ja niin edelleen tiputtamalla lopulta kaikki alkulukujen monikerrat pois. Lopputulos on alkulukujen luettelo. 11

12 Luku 4 Tyypeistä Haskellin tietotyyppijärjestelmä on rikas. Se on huomattavasti C:n tai Pascalin tyyppijärjestelmää ilmaisuvoimaisempi ja (yhdessä Haskellin tyyppiluokkien kanssa) pystyy ilmaisemaan monet olio-ohjelmoinnin tyyppikonstruktiot jopa ilman täydellistä oliotukea. Haskell on pääosin staattisesti tyypitetty kieli, joka hallitsee myös hallitun funktioiden kuormituksen. Tässä luvussa tarkastellaan esimerkein Haskellin tyyppijärjestelmän peruspiirteitä. Haskellissa kaikki valmiiksi määritellyt tyypit kokonaisluvut, merkit, listat, merkkijonot, totuusarvot, parit, änniköt, rationaaliluvut, liukuluvut, kompleksiluvut, mielivaltaisen suuret kokonaisluvut, taulukot, funktiot ja niin edelleen voidaan teoriassa konstruoida kielen keinoin, vaikka monet niistä varmasti toteutetaankin primitiivityyppeinä tehokkuuden vuoksi. Osalla niistä on erityissyntaksia, joita ei voi toteuttaa kielen keinoin, mutta mikään niistä ei lisää kielen ilmaisuvoimaa: kaikki asiat voidaan toteuttaa ilmankin tällaisia kielioppimakeisia. Kaiken pohjalla on periaatteessa enumeraatiotyypit. Esimerkiksi totuusarvojen tyyppi määritellään seuraavasti: data Bool = True False Uusien tietotyyppien määritelmä alkaa avainsanalla data, jota seuraa tietotyypin nimi (joka alkaa aina isolla kirjaimella) ja yhtäsuuruusmerkki. Oikealla puolella luetellaan tyypin konstruktorit (tässä tapauksessa vakioarvojen nimet), jotka kirjoitetaan aina isolla alkukirjaimella. Konstruktoreiden väliin laitetaan pystyviiva. Konstruktorien käyttöä kuvannee hyvin Esimerkki 4-1, jossa määritellään eräs tunnettu looginen konnektiivi. Esimerkki 4-1 Looginen konnektiivi and {- andornot.hs -} and True True = True and True False = False and False True = False and False False = False Kuten totuusarvojen tyyppi, myös kokonaislukujen tyyppi Int ja merkkien tyyppi Char voidaan toteuttaa luettelemalla kaikki lailliset arvot (konstruktorit). Nyt vain sattuu olemaan niin, että nämä konstruktorit kirjoitetaan epätavalliseen tapaan: 42 ja p. Listatyyppiä ei voi määritellä edellä esitettyyn tapaan. Lista on polymorfinen astia: se sisältää useita tietoja, jotka ovat samantyyppisiä, mutta eri listoissa voi tämä tyyppi olla eri. Tätä varten tyypin nimen jälkeen kirjoitetaan tyyppimäärittelyssä yksi tai useampiatyyppiparametreja (pienellä kirjaimella alkava nimi); myös konstruktorien jälkeen voidaan kirjoittaa nolla tai useampi tyypin nimen yhteydessä mainittu parametri: data List a = Nil Cons a (List a) Tässä tyypin ja konstruktorien nimet on valittu tavalliseen tapaan. Sisäänrakennettu listatyyppi käyttää samoista asioista nimiä [a] (listatyyppi, List a), [] (tyhjän listan konstruktori, Nil) ja a 12

13 Luku 4 Tyypeistä : [a] (cons-konstruktori, Cons a [a]). Parametrisoidun tyypin konkreettinen esiintymä kirjoitetaan tyyliin List Char, (eli tässä tapauksessa myös [Char]). Tällaisen tyypin parametrisoituja konstruktoreita myös käytetään niin, että parametrin tilalle laitetaan parametria vastavan tyypin arvo, esimerkiksi Cons a Nil (ts. a : []). Merkkijonot ovat yksinkertaisesti merkkilistoja, joten ei tarvita erillistä merkkijonotyyppiä. Siitä huolimatta on kiva käyttää siitä nimeä String, joten määritellään tyyppisynonyymi: type String = [Char] Huomaa uusi avainsana. Jokaisen lausekkeen ja jokaisen funktion tyyppi voidaa kirjoittaa ohjelmaan näkyviin. Joskus se on välttämätöntä, ja funktioiden tapauksessa se on yleensä hyvä idea vaikkapa vain varmistamaan, että funktion tyyppi on se, minkä ohjelmoija kuvittelee sen olevan (sillä tulkki tai kääntäjä valittaa, jos funktion esitelty tyyppi ja todellinen tyyppi eivät ole yhteensopivia). Lausekkeen tyyppi esitellään laittamalla tyyppi lausekkeen perään kahden kaksoipisteen jälkeen. On varminta pistää lauseke tätä ennen sulkeisiin, vaikka se ei kaikissa tilanteissa olekaan välttämätöntä. Funktion tyyppi esitellään suurin piirtein samaan tapaan; tosin kahden kaksoispisteen eteen laitetaan vain funktion nimi. Yhden muuttujan funktion tyyppi kirjoitetaan A -> B, kuten matematiikassakin. Tässä A on argumentin tyyppi ja B on paluuarvon tyyppi. Koska kahden muuttujan funktio on oikeastaan vain yhden muuttujan funktio, joka palauttaa yhden muuttujan funktion (ts. pätee f x y = (f x) y), voidaan kahden muuttujan funktion tyyppi kirjoittaa A -> (B -> C). Tavallisesti juuri samasta syystä on tapana jättää tästä sulkeet pois, joten A -> B -> C on kahden muuttujan funktion tyyppi. Tästä saadaan induktiivisesti kolmen muuttujan funktion tyyppi A -> B -> C -> D ja neljän muuttujan funktion tyyppi A -> B -> C -> D -> E ja niin edelleen. Jos funktio ottaa funktioparametrin, laitetaan parametrifunktion tyyppi sulkeisiin (joita ei voi jättää pois), esimerkiksi näin: Char -> (Char -> String) -> String, joka kuvaa kahden muuttujan funktiota, jonka ensimmäinen parametri on merkki ja toinen parameri on merkin merkkijonoksi muuttava funktio ja joka palauttaa merkkijonon. Funktion tai lausekkeen tyyppi voi olla polymorfinen; tällöin tyypinesittelyssä esiintyy tyyppinimien ja -lausekkeiden seassa pienellä alkukirjaimella kirjoitettuja tyyppiparametreja. Tällöin funktion aktuaalinen tyyppi annetussa tilanteessa riippuu siitä, minkätyyppiset parametrit sille annetaan ja mitä sen halutaan siinä paikassa palauttavan. Tällöin kukin tyyppiparametri saa yhden konkreettisen tyyppiarvon ja nämä arvot ovat voimassa koko tyyppikuvauksessa siinä tilanteessa. Jos esimerkiksi funktion id tyyppi on a -> a, ja sille annetaan parametriksi kokonaisluku, on funktion tämän ilmentymän tyyppi Integer -> Integer. Samassa ohjelmassa ja mahdollisesti jopa samassa lausekkeessa saatetaan samaa funktiota kutsua yhteydessä, jossa se voi palauttaa vain merkkijonoja; tässä tilanteessa sen ilmentymän tyyppi on String -> String. Parametrisoidut tyypit ja polymorfiset funktiot Haskellissa muistuttavat mm. C++:n template-tyyppejä ja -funktioita, ja näiden muistaminen voi auttaa Haskellin ymmärtämistä. Polymorfiset funktiot ja lausekkeet eivät välttämättä kelpuuta mitä tahansa tyyppiä tyyppiparametrinsa arvoksi: esimerkiksi voi olla välttämätöntä, että parametrityypin arvoja täytyy voida vertailla. Tämä vaatimus esitetään tyyppikuvauksessa laittamalla sen alkuun rajoitelauseke ja tämän perään =>. Rajoitelauseke voi koostua vain yhdestä rajoitteesta, tai sitten sulkeiden sisään 13

14 Luku 4 Tyypeistä laitetusta jonosta useita rajoitteita, jotka on erotettu pilkuilla. Kukin rajoite on muotoa Ord a, missä Ord on rajoitteen tyyppiluokka ja a on se tyyppiparametri, jota rajoite koskee. Esimerkiksi Eq a => tarkoittaa, että a:n arvojen yhtäsuuuruutta pitää voida verrata (==)-operaattorilla; vastaavasti (Ord a, Ord b) => tarkoittaa, että sekä a:n että b:n arvoja pitää voida verrata erisuuruusoperaattoreilla (<) yms. Esimerkki 4-2 Binäärinen hakupuu Seuraavassa pätkässä on kirjoitettu Haskellia literate programming -tyyliin, jossa oletuksena kaikki on kommenttia ja jokainen koodirivi täytyy aloittaa vasemmassa reunassa olevalla suurempi kuin -merkillä. {- bintree.lhs -} Binäärinen hakupuu on parametrisoitu rekursiivinen tietotyyppi. Puu voi olla tyhjä. Toisaalta se voi sisältää jonkin tiedonpalasen sekä kaksi alipuuta. > data BinaryTree a = EmptyTree > NonEmptyTree a (BinaryTree a) (BinaryTree a) > deriving (Show) Määrittelyn lopussa olevasta deriving-lauseesta ei kannata välittää, sillä se on mukana vain varmistamassa, että Hugs osaa tulostaa ruudulle tarvittaessa binääripuun. Binäärisen hakupuun syvyys määritellään seuraavasti: - tyhjän puun syvyys on 0 - epätyhjän puun syvyys on yksi enemmän kuin suurempi alipuiden syvyyksistä > depth :: BinaryTree a -> Integer > depth EmptyTree = 0 > depth (NonEmptyTree _ tl tr) = 1 + max (depth tl) (depth tr) Binääripuussa on voimassa seuraavanlaiset ehdot: Kaikki puun vasemmassa alipuussa olevat tiedot ovat aidosti pienempiä kuin puun (juuren) tieto. Kaikki puun oikeassa alipuussa olevat tiedot ovat aidosti suurempia kuin puun (juuren) tieto. Lisäys seuraa näistä ehdoista kohtuullisen helposti. > addtotree :: Ord a => a -> BinaryTree a -> BinaryTree a > addtotree d EmptyTree = NonEmptyTree d EmptyTree EmptyTree > addtotree d (NonEmptyTree d tl tr) > d < d = NonEmptyTree d (addtotree d tl) tr > d == d = error "Puussa on jo tämä alkio!" 14

15 Luku 4 Tyypeistä > d > d = NonEmptyTree d tl (addtotree d tr) Puusta etsiminen ja siitä poistaminen ovat harjoitustehtäviä. Jos funktion tyyppiä ei kirjoiteta näkyviin, tulkit ja kääntäjät olettavat tyypiksi suppeimman mahdollisen, joka kattaa kaikki mahdolliset funktion käytöt. Tietyissä tapauksissa funktion tyyppi on pakko kirjoittaa näkyviin. 15

16 Luku 5 I/O Syöttö ja tulostus ja yleensäkin kaikki ulkomaailman kanssa leikkiminen tehdään Haskellissa monadien avulla. Lisää tästä myöhemmin tällä ja seuraavilla sivuilla. IO-monadi on abstrakti parametrisoitu tietotyyppi, joka ilmaisee tietyntyyppistä tekemistä: merkkijonon lukemista, tekstin tulostamista, merkkijonon lukemista ja sen muokatun version tulostamista ja niin edelleen. Tämä vaatii yleensä imperatiivista ohjelmointia harrastaneelta ohjelmoijalta hieman totuttelua, joten kaikki se, mitä tässä luvussa sanotaan, voi aluksi tuntua täysin käsittämättömältä. Jokaisessa Haskell-ohjelmassa tulee olla funktio nimeltä main. Tämä funktio ei koskaan ota parametreja, ja se palauttaa IO a -tyyppisen arvon (missä a on mikä tahansa tyyppi, tavallisesti triviaali tyyppi, C:n void-tyyppiä vastaava ()). Tämän funktion paluuarvo kuvaa jotakin aktiota, tekemistä, ja tämä aktio toteutetaan, kun main on palannut. On äärimmäisen tärkeää ymmärtää, että Haskell-ohjelma suoritetaan vasta kuin main on palannut: koko "ohjelmakoodi"on vain tulkille tai kääntäjälle tarkoitettu kuvaus siitä, minkälainen varsinainen ohjelma on, ja tämä ohjelma palautetaan main-funktion paluuarvona. Yksinkertaisin teko, minkä voi tehdä, on olla tekemättä mitään. Tämän teon (puutteen) kuvauksen palauttaa return, jonka ainoa argumentti kertoo, minkä arvon tämä teko tuottaa: tässä tapauksessa se tuottaa ei-mitään, siis triviaalin tyypin () ainoan arvon (). Siipä maailman yksinkertaisin toimiva Haskell-ohjelma on {- trivial.hs -} main :: IO () main = return () joka ei tee yhtikäs mitään. Muistakaamme, että Luku 2 tarkastelee perinteistä yksinkertaista ohjelmaa, sellaista, joka tervehtii maailmaa. Sen main palauttaa teon, joka tulostaa ruudulle tervehdyksen. Tällaisen teon tuottaa funktio putstrln, jonka ainoa argumentti on tulostettava merkkijono. Kuten nimestä voi päätellä, tulostetaan rivinvaihto merkkijonon perään. Tässä Hello World uudestaan: {- hello.hs -} main :: IO () main = putstrln "Hello World!" Ohjelma voi myös pyytää käyttäjää kirjoittamaan jotain ruudulle. Tämän teon kuvaa funktio getline, joka ei huomaa! palauta käyttäjän kirjoittamaa riviä vaan kirjoittamispyyntöä kuvaavan abstraktin arvon. Tässä vaiheessa osaame vain palauttaa sen pääohjelman paluuarvona, mutta pian pääsemme myös itse riviin käsiksi. Seuraava ohjelma kysyy käyttäjältä rivin, muttei tee saamallaan tiedolla mitään. {- ask.hs -} main :: IO String main = getline 16

17 Luku 5 I/O Ei riitä, että osataan tehdä yksi asia; tekoja pitää voida yhdistää. Operaattori (>>) tuottaa aktion, joka ensin tekee vasemmanpuoleisen ja sitten oikeanpuoleisen teon. Se siis yhdistää nämä jonoksi tekoja. Seuraava ohjelma tulostaa ensin pyynnön kirjoittaa jotain, lukee rivin käyttäjältä ja tulostaa lopuksi kiitoksen. {- ask1.hs -} main :: IO () main = putstrln "Kirjoittaisitko jotain?" >> getline >> putstrln "Kiitos." Jotkin teot tuottavat tuloksenaan tietoa esimerkki tällaisesta on funktion getline palauttama teko. Tähän tulokseen päästään käsiksi operaattorin (>>=) avulla. Sen vasen operandi on jokin teko, joka tuottaa tiedon. Oikea puoli on funktio, jonka argumentiksi tämä tieto kelpaa ja joka palauttaa toisen aktion. Operaattori tuotta aktion, joka ensin tekee vasemman argumentin kertoman teon, antaa tämän tuloksen oikeanpuoleiselle funktiolle argumentiksi ja tekee lopuksi tämän palauttaman teon. {- pallo.hs -} main :: IO () main = putstrln "Minkä muotoinen pallo on?" >> getline >>= vastaus where vastaus rivi = putstrln ("Pallo on " ++ rivi ++ ".") Useimmiten oikeanpuolen funktioita tulee paljon, joten nimien keksiminen käy hankalaksi. Tämän (ja monen muunkin asian) vuoksi Haskellissa on olemassa lambda-abstraktioksi kutsuttu rakenne, joka määrittelee nimettömän funktion lennossa. Rakenne alkaa kenoviivalla, jonka jälkeen tulee parametrien kuvaukset ja lopulta nuoli ->. Funktion määrittely jatkuu tästä niin pitkälle kuin se on mahdollista. Äskeinen ohjelma voidaan nyt kirjoittaa helpommin: {- pallolambda.hs -} main :: IO () main = putstrln "Minkä muotoinen pallo on?" >> getline >>= \rivi -> putstrln ("Pallo on " ++ rivi ++ ".") Huomaa, että sopivalla vaakatilan käytöllä näin kirjoitettu ohjelma alkaa olla helppolukuinen: operaattori (>>) on kuin puolipiste muissa kielissä, ja rakenne >>= \x -> on kuin sijoituslause. Tähän havaintoon perustuu erittäin mukava syntaksimakeinen, jota sanotaan do-rakenteeksi avainsanansa mukaan. Sen käyttö muistuttaa päällisin puolin kovasti imperatiivista ohjelmointia, vaikka se on mekaanisesti ja vieläpä helposti muutettavissa edellä kuvatuiksi funktionaalisiksi rakenteiksi. Do-rakenne alkaa avainsanalla do, jota seuraa yksi tai useampi alikohta. Kukin alikohta on kahta mutoa: se voi koostua pelkästä lausekkeesta, tai sitten se voi koostua muuttujannimestä, nuolesta <- ja lausekkeesta. Edellisessä tapauksessa lausekkeen tuottama teko liitetään yhteen muun do-rakenteen kanssa (»)-operaattorilla. Jälkimmäinen, muotoa muuttuja <- lauseke 17

18 Luku 5 I/O oleva alikohta muutetaan muotoon lauseke >>= \muuttuja -> Näin pallo-ohjelma voidaan kirjoittaa seuraavasti: {- pallodo.hs -} main :: IO () main = do putstrln "Minkä muotoinen pallo on?" rivi <- getline putstrln ("Pallo on " ++ rivi ++ ".") Do-notaatiolla useimmat simppelit I/O-toiminnot onnistuvat helposti. Sen etu on, että sen kanssa voi useimmiten ajatella imperatiivisesti. Sen haittapuolena on se, että monet itsestäänselvältä tuntuvat muunnokset eivät ole sallittuja; esimerkiksi do l <- getline putstrln l ei ole sama asia kuin do putstrln getline Itse asiassa tämä jälkimmäinen ohjelmanpätkä ei edes mene tulkista tai kääntäjästä läpi! (Miksi? Ajattele tyyppejä.) Näin esoteerinen I/O-kieli on itse asiassa hyvä asia. Puhtaasti funktionaalisessa kielessä sivuvaikutukset ovat kiellettyjä, koska ne rikkovat viittausten läpinäkyvyyden (referential transparency). Esimerkiksi C:ssä tarpeettomalta näyttävää funktiokutsua ei saa poistaa, ellei kääntäjä näe, miten tuo on määritelty; tällaisen poistaminen voisi rikkoa koko ohjelman, koska jokin tärkeä muuttuja jäisi päivittymättä. Haskellissa ja muissa puhtaasti funktionaalisissa kielissä tämä ei ole ongelma: on taattua, että kaikki funktiokutsut, jotka "näyttävät samalta"(so. samaa funktiota kutsutaan samoilla argumenteilla), palauttavat aina saman tuloksen eikä niillä ole muita huomioonotettavia vaikutuksia. Näin kääntäjä voi järjestellä, poistella ja yhdistellä funktiokutsuja mielensä mukaan. Koska Haskellissa sivuvaikutukset kuvataan ohjelman aikana arvoina, jotka toteutetaan vasta ohjelman "päätyttyä", säilyy viittausten läpinäkyvyys. Koska syöttö- ja tulostus teot ovat täysivaltaisia arvoja, voidaan niitä käsitellä monin tavoin. Esimerkiksi teot voidaan tallettaa listaan ja niitä voi antaa funktiolle argumentteina. Esimerkki 5-1 sisältää hauskan ohjelman, joka tulostaa ruudulle erään juomalaulun sanat. Katso myös 99 Bottles of Beer, 227 Computer Beer Styles (http://www.ionet.net/~timtroyr/funhouse/beer.html). Esimerkki 5-1 Ninety-nine bottles of beer on the wall {- bottles.hs -} beer :: Integer -> IO () beer n = putstrln (bottles n ++ " bottles of beer on the wall,") >> putstrln (bottles n ++ " bottles of beer.") >> 18

19 Luku 5 I/O putstrln ("Take " ++ one n ++ " down and pass it around,") >> putstrln (bottles (n-1) ++ " bottles of beer on the wall.") >> putstrln where bottles 0 = "No bottles" bottles 1 = "One bottle" bottles 2 = "Two bottles" bottles 3 = "Three bottles" bottles 4 = "Four bottles" bottles 5 = "Five bottles" bottles 6 = "Six bottles" bottles 7 = "Seven bottles" bottles 8 = "Eight bottles" bottles 9 = "Nine bottles" bottles 10 = "Ten bottles" bottles 11 = "Eleven bottles" bottles 12 = "Twelve bottles" bottles n = show n ++ " bottles" one 1 = "it" one _ = "one" main :: IO () main = foldl (>>) (return ()) (map beer (reverse [1..99])) Huomaa, kuinka ohjelmassa ei näy silmukkaa eikä rekursiota. Tämän abstrahoi pois funktio foldl, joka tässä tapauksessa muuttaa listan aktioita uudeksi aktioksi, joka tekee nuo teot järjestyksessä. Tämän listan konstruoi map, joka tässä kuvaa kunkin luvun 99 1 yhden säkeistön tuottavaksi teoksi. Luettelo luvuista saadaan kääntämällä luettelo luvuista 1 99 ylösalaisin. 19

20 Liite A Lopuksi Jos et Haskellista muista mitään muuta, muista nämä asiat: Funktiot ovat arvoja siinä missä kaikki muutkin. Tietorakenteet voivat olla äärettömiä. Osa-algoritmin ei tarvitse pysähtyä, kunhan koko ohjelma käyttää tuloksesta vain äärellisessä ajassa laskettavissa olevan osan. Teot ovat arvoja siinä missä kaikki muutkin. Sivuvaikutuksia ei ole. Tietorakenteita ei voi muuttaa. Haskell on hauska kieli, vaikka sen oppiminen vaatiikin aikansa. 20

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, Vakio Tiedon merkkipohjainen tulostaminen Ohjelmointi (ict1tx006) Tunnus (5.3) Javan tunnus Java-kirjain Java-numero

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset 815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

Luku 3. Listankäsittelyä. 3.1 Listat

Luku 3. Listankäsittelyä. 3.1 Listat Luku 3 Listankäsittelyä Funktio-ohjelmoinnin tärkein yksittäinen tietorakenne on lista. Listankäsittely on paitsi käytännöllisesti oleellinen aihe, se myös valaisee funktio-ohjelmoinnin ideaa. 3.1 Listat

Lisätiedot

Johdatus Ohjelmointiin

Johdatus Ohjelmointiin Johdatus Ohjelmointiin Syksy 2006 Viikko 2 13.9. - 14.9. Tällä viikolla käsiteltävät asiat Peruskäsitteitä Kiintoarvot Tiedon tulostus Yksinkertaiset laskutoimitukset Muuttujat Tiedon syöttäminen Hyvin

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia.

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia. Ohjelmointitaito (ict1td002, 12 op) Kevät 2008 Raine Kauppinen raine.kauppinen@haaga-helia.fi 1. Java-ohjelmoinnin alkeita Tietokoneohjelma Java-kieli ja Eclipse-ympäristö Java-ohjelma ja ohjelmaluokka

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin. 2. Ohjausrakenteet Ohjausrakenteiden avulla ohjataan ohjelman suoritusta. peräkkäisyys valinta toisto Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 11 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Listakomprehensio Uusi tapa luoda (ja muokata) listoja: [ lauseke

Lisätiedot

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

Lisätiedot

Tietotyypit ja operaattorit

Tietotyypit ja operaattorit Tietotyypit ja operaattorit Luennossa tarkastellaan yksinkertaisten tietotyyppien int, double ja char muunnoksia tyypistä toiseen sekä esitellään uusia operaatioita. Numeeriset tietotyypit ja muunnos Merkkitieto

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Java-kielen perusteita

Java-kielen perusteita Java-kielen perusteita valintalauseet 1 Johdantoa kontrollirakenteisiin Tähän saakka ohjelmissa on ollut vain peräkkäisyyttä eli lauseet on suoritettu peräkkäin yksi kerrallaan Tarvitsemme myös valintaa

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 28.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 28.2.2011 1 / 46 Ohjelmointiprojektin vaiheet 1. Määrittely 2. Ohjelman suunnittelu (ohjelman rakenne ja ohjelman

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 25.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 25.2.2009 1 / 34 Syötteessä useita lukuja samalla rivillä Seuraavassa esimerkissä käyttäjä antaa useita lukuja samalla

Lisätiedot

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo 15.2.2006

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo 15.2.2006 TURUN YLIOPISTO DEMO III Informaatioteknologian laitos tehtävät Olio-ohjelmoinnin perusteet / Salo 15.2.2006 1. Tässä tehtävässä tarkastellaan erääntyviä laskuja. Lasku muodostaa oman luokkansa. Laskussa

Lisätiedot

Z-skeemojen animointi Haskellilla

Z-skeemojen animointi Haskellilla Z-skeemojen animointi Haskellilla Antti-Juhani Kaijanaho 6. toukokuuta 2001 Sisältö 1 Johdanto 2 2 Joitakin funktionaalisen ohjelmoinnin käsitteitä 3 2.1 Imperatiivinen funktionaalinen ohjelmointi 3 2.2

Lisätiedot

Tietorakenteet ja algoritmit - syksy 2015 1

Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 2 Tietorakenteet ja algoritmit Johdanto Ari Korhonen Tietorakenteet ja algoritmit - syksy 2015 1. JOHDANTO 1.1 Määritelmiä

Lisätiedot

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin Raimo Nikkilä Aalto-yliopiston sähkötekniikan korkeakoulu - Automaation tietotekniikan tutkimusryhmä 17. tammikuuta 2013

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 16.2.2010 1 / 41 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

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

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen Metodit Metodien määrittely Metodin parametrit ja paluuarvo Metodien suorittaminen eli kutsuminen Metodien kuormittaminen 1 Mikä on metodi? Metodi on luokan sisällä oleva yhteenkuuluvien toimintojen kokonaisuus

Lisätiedot

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari 1 1. JOHDANTO 1.1 Määritelmiä 1.2 Tietorakenteen ja algoritmin valinta 1.3 Algoritmit ja tiedon määrä 1.4 Tietorakenteet ja toiminnot 1.5 Esimerkki:

Lisätiedot

14.1 Rekursio tyypitetyssä lambda-kielessä

14.1 Rekursio tyypitetyssä lambda-kielessä Luku 14 Rekursiiviset tyypit Edellisessä luvussa esitetyt tietue- ja varianttityypit eivät yksinään riitä kovin mielenkiintoisten tietorakenteiden toteuttamiseen. Useimmissa ohjelmissa tarvitaan erilaisia

Lisätiedot

Kielioppia: toisin kuin Javassa

Kielioppia: toisin kuin Javassa Object Pascal Pascal kielen oliolaajennus (Inprise/Borland:n oma) luokat Voit uudelleenkäyttää luomiasi objekteja esim. komponentteja Periytyminen Kielioppia: toisin kuin Javassa Ei eroa isojen ja pienien

Lisätiedot

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python 8. marraskuuta 2010 Ohjelmointi Perusteet Peruskäsitteitä Olio-ohjelmointi Pythonin alkeet Esittely Esimerkkejä Muuttujat

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 7.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 7.2.2011 1 / 39 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Harjoitus 1 -- Ratkaisut

Harjoitus 1 -- Ratkaisut Kun teet harjoitustyöselostuksia Mathematicalla, voit luoda selkkariin otsikon (ja mahdollisia alaotsikoita...) määräämällä soluille erilaisia tyylejä. Uuden solun tyyli määrätään painamalla ALT ja jokin

Lisätiedot

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille: Merkkijonot C-kielessä merkkijono on taulukko, jonka alkiot ovat char -tyyppiä. Taulukon viimeiseksi merkiksi tulee merkki '\0', joka ilmaisee merkkijonon loppumisen. Merkkijono määritellään kuten muutkin

Lisätiedot

Prolog kielenä Periaatteet Yhteenveto. Prolog. Toni ja Laura Fadjukoff. 9. joulukuuta 2010

Prolog kielenä Periaatteet Yhteenveto. Prolog. Toni ja Laura Fadjukoff. 9. joulukuuta 2010 kielenä 9. joulukuuta 2010 Historia kielenä Historia Sovelluksia kehitettiin vuonna 1972 Kehittäjinä ranskalaiset Pääkehittäjä Alain Colmerauer Philippe Roussel programmation en logique Robert Kowalski

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2011 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2011 1 / 39 Kertausta: tiedoston avaaminen Kun ohjelma haluaa lukea tai kirjoittaa tekstitiedostoon, on ohjelmalle

Lisätiedot

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4) 2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Kirjoita jokaiseen palauttamaasi konseptiin kurssin nimi, kokeen päivämäärä, oma nimi ja opiskelijanumero. Vastaa kaikkiin tehtäviin omille konsepteilleen.

Lisätiedot

12 Mallit (Templates)

12 Mallit (Templates) 12 Mallit (Templates) Malli on määrittely, jota käyttämällä voidaan luoda samankaltaisten aliohjelmien ja luokkien perheitä. Malli on ohje kääntäjälle luoda geneerisestä tyyppiriippumattomasta ohjelmakoodista

Lisätiedot

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

Lisätiedot

Automaatit. Muodolliset kielet

Automaatit. Muodolliset kielet Automaatit Automaatit ovat teoreettisia koneita, jotka käsittelevät muodollisia sanoja. Automaatti lukee muodollisen sanan kirjain kerrallaan, vasemmalta oikealle, ja joko hyväksyy tai hylkää sanan. Täten

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

11.4. Context-free kielet 1 / 17

11.4. Context-free kielet 1 / 17 11.4. Context-free kielet 1 / 17 Määritelmä Tyypin 2 kielioppi (lauseyhteysvapaa, context free): jos jokainenp :n sääntö on muotoa A w, missäa V \V T jaw V. Context-free kielet ja kieliopit ovat tärkeitä

Lisätiedot

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma:

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma: Kerta 2 Kerta 3 Kerta 4 Kerta 5 Kerta 2 1. Toteuta Pythonilla seuraava ohjelma: 2. Tulosta Pythonilla seuraavat luvut allekkain a. 0 10 (eli, näyttää tältä: 0 1 2 3 4 5 6 7 8 9 10 b. 0 100 c. 50 100 3.

Lisätiedot

Olio-ohjelmointi Javalla

Olio-ohjelmointi Javalla 1 Olio-ohjelmointi Javalla Olio-ohjelmointi Luokka Attribuutit Konstruktori Olion luominen Metodit Olion kopiointi Staattinen attribuutti ja metodi Yksinkertainen ohjelmaluokka Ohjelmaluokka 1 Olio-ohjelmointi

Lisätiedot

Funktio-ohjelmoinnin hyödyntäminen peliohjelmoinnissa

Funktio-ohjelmoinnin hyödyntäminen peliohjelmoinnissa Simo Rinne Funktio-ohjelmoinnin hyödyntäminen peliohjelmoinnissa Tietotekniikan kandidaatintutkielma 28. huhtikuuta 2015 Jyväskylän yliopisto Tietotekniikan laitos Tekijä: Simo Rinne Yhteystiedot: simo.e.rinne@student.jyu.fi

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

Lisätiedot

Taulukot. Jukka Harju, Jukka Juslin 2006 1

Taulukot. Jukka Harju, Jukka Juslin 2006 1 Taulukot Jukka Harju, Jukka Juslin 2006 1 Taulukot Taulukot ovat olioita, jotka auttavat organisoimaan suuria määriä tietoa. Käsittelylistalla on: Taulukon tekeminen ja käyttö Rajojen tarkastus ja kapasiteetti

Lisätiedot

Bootstrap / HTDP2 / Realm of Racket. Vertailu

Bootstrap / HTDP2 / Realm of Racket. Vertailu Bootstrap / HTDP2 / Realm of Racket Vertailu Bootstrap http://www.bootstrapworld.org/ Tarkoitettu yläkoululaisille (12-15v) Ohjelmointi on integroitu matematiikan opetukseen Materiaalina tuntisuunnitelmat

Lisätiedot

Merkkijonot ja C++ Antti-Juhani Kaijanaho. 5. maaliskuuta 2001. 1 Vanhojen C++-kääntäjien käyttäjät, huomio! 2 Merkkijonojen perusteet

Merkkijonot ja C++ Antti-Juhani Kaijanaho. 5. maaliskuuta 2001. 1 Vanhojen C++-kääntäjien käyttäjät, huomio! 2 Merkkijonojen perusteet Merkkijonot ja C++ Antti-Juhani Kaijanaho 5. maaliskuuta 2001 1 Vanhojen C++-kääntäjien käyttäjät, huomio! Tämä kirjoitus perustuu vuonna 1998 julkistettuun C++-kielen kansainväliseen ISO-standardiin.

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 21.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 21.9.2015 1 / 25 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python 31. tammikuuta 2009 Ohjelmointi Perusteet Pythonin alkeet Esittely Esimerkkejä Muuttujat Peruskäsitteitä Käsittely

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 2.2.2011 1 / 37 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 3.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 3.2.2010 1 / 36 Esimerkki: asunnon välityspalkkio Kirjoitetaan ohjelma, joka laskee kiinteistönvälittäjän asunnon

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PUURAKENTEET, BINÄÄRIPUU, TASAPAINOTETUT PUUT MIKÄ ON PUUTIETORAKENNE? Esim. Viereinen kuva esittää erästä puuta. Tietojenkäsittelytieteessä puut kasvavat alaspäin.

Lisätiedot

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include 15: 16: int main() 17: {

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: { Osa I 2. oppitunti C++-ohjelman osat Ennen kuin menemme yksityiskohtaisemmin sisälle C++-luokkiin, -muuttujiin jne, katsokaamme ensin, millaisista osista C++-ohjelma koostuu. Tämän tunnin aikana opit seuraavat

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 11.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 11.2.2009 1 / 33 Kertausta: listat Tyhjä uusi lista luodaan kirjoittamalla esimerkiksi lampotilat = [] (jolloin

Lisätiedot

Hahmon etsiminen syotteesta (johdatteleva esimerkki)

Hahmon etsiminen syotteesta (johdatteleva esimerkki) Hahmon etsiminen syotteesta (johdatteleva esimerkki) Unix-komennolla grep hahmo [ tiedosto ] voidaan etsia hahmon esiintymia tiedostosta (tai syotevirrasta): $ grep Kisaveikot SM-tulokset.txt $ ps aux

Lisätiedot

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

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b Pythonin Kertaus Cse-a1130 Tietotekniikka Sovelluksissa Versio 0.01b Listat 1/2 esimerkkejä listan peruskäytöstä. > lista=['kala','kukko','kissa','koira'] ['kala','kukko','kissa','koira'] >lista.append('kana')

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 1 1 Matemaattisesta päättelystä Matemaattisen analyysin kurssin (kuten minkä tahansa matematiikan kurssin) seuraamista helpottaa huomattavasti, jos opiskelija ymmärtää

Lisätiedot

Luento 5. Timo Savola. 28. huhtikuuta 2006

Luento 5. Timo Savola. 28. huhtikuuta 2006 UNIX-käyttöjärjestelmä Luento 5 Timo Savola 28. huhtikuuta 2006 Osa I Shell-ohjelmointi Ehtolause Lausekkeet suoritetaan jos ehtolausekkeen paluuarvo on 0 if ehtolauseke then lauseke

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 3: SICP kohdat 2.22.3, 33.1 ja 3.33.3.2 Riku Saikkonen 8. 11. 2010 Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan

Lisätiedot

Datatähti 2009 -alkukilpailu

Datatähti 2009 -alkukilpailu Datatähti 2009 -alkukilpailu Ohjelmointitehtävä 1/3: Hissimatka HUOM: Tutustuthan huolellisesti tehtävien sääntöihin ja palautusohjeisiin (sivu 7) Joukko ohjelmoijia on talon pohjakerroksessa, ja he haluavat

Lisätiedot

Java kahdessa tunnissa. Jyry Suvilehto

Java kahdessa tunnissa. Jyry Suvilehto Java kahdessa tunnissa Jyry Suvilehto Ohjelma Ohjelmointiasioita alkeista nippelitietoon n. 45 min Tauko 10 min Oliot, luokat ja muut kummajaiset n. 45 min Kysykää Sisältöä ei oikeasti ole 2x45 min täytteeksi,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 24.1.2011 T-106.1208 Ohjelmoinnin perusteet Y 24.1.2011 1 / 36 Luentopalaute kännykällä alkaa tänään! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti Vast

Lisätiedot

Kesälukio 2000 PK2 Tauluharjoituksia I Mallivastaukset

Kesälukio 2000 PK2 Tauluharjoituksia I Mallivastaukset Kesälukio 2000 PK2 Tauluharjoituksia I Mallivastaukset 2000-08-03T10:30/12:00 Huomaa, että joihinkin kysymyksiin on useampia oikeita vastauksia, joten nämä ovat todellakin vain mallivastaukset. 1 Logiikkaa

Lisätiedot

TIEA241 Automaatit ja kieliopit, syksy 2015. Antti-Juhani Kaijanaho. 3. joulukuuta 2015

TIEA241 Automaatit ja kieliopit, syksy 2015. Antti-Juhani Kaijanaho. 3. joulukuuta 2015 TIEA241 Automaatit ja, syksy 2015 Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 3. joulukuuta 2015 Sisällys Formaalisti Määritelmä Nelikko G = (V, Σ, P, S) on kontekstiton kielioppi (engl. context-free

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 26.1.2009 T-106.1208 Ohjelmoinnin perusteet Y 26.1.2009 1 / 33 Valintakäsky if syote = raw_input("kerro tenttipisteesi.\n") pisteet = int(syote) if pisteet >=

Lisätiedot

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukot C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukon muuttujilla (muistipaikoilla) on yhteinen nimi. Jokaiseen yksittäiseen

Lisätiedot

JFO: Johdatus funktionaaliseen ohjelmointiin

JFO: Johdatus funktionaaliseen ohjelmointiin JFO: Johdatus funktionaaliseen ohjelmointiin Matti Nykänen Tietojenkäsittelytieteen laitos, Itä-Suomen yliopisto matti.nykanen@uef.fi Lukuvuosi 2010-11, IV periodi Sisältö 1 Johdanto 1 1.1 Historiaa.....................................

Lisätiedot

Zeon PDF Driver Trial

Zeon PDF Driver Trial Matlab-harjoitus 2: Kuvaajien piirto, skriptit ja funktiot. Matlabohjelmoinnin perusteita Numeerinen integrointi trapezoidaalimenetelmällä voidaan tehdä komennolla trapz. Esimerkki: Vaimenevan eksponentiaalin

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015

815338A Ohjelmointikielten periaatteet 2014-2015 815338A Ohjelmointikielten periaatteet 2014-2015 X Skriptiohjelmointi Sisältö 1. Johdanto 2. Skriptikielten yleispiirteitä 3. Python 815338A Ohjelmointikielten periaatteet, Skriptiohjelmointi 2 X.1 Johdanto

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.2.2010 1 / 46 Merkkijonot Merkkijonojen avulla ohjelmassa voi esittää tekstitietoa, esim. nimiä, osoitteita ja

Lisätiedot

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011 TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 31. maaliskuuta 2011 Sisällys Sisällys Chomskyn hierarkia kieli säännöllinen kontekstiton kontekstinen rekursiivisesti

Lisätiedot

811312A Tietorakenteet ja algoritmit, 2014-2015, Harjoitus 7, ratkaisu

811312A Tietorakenteet ja algoritmit, 2014-2015, Harjoitus 7, ratkaisu 832A Tietorakenteet ja algoritmit, 204-205, Harjoitus 7, ratkaisu Hajota ja hallitse-menetelmä: Tehtävä 7.. Muodosta hajota ja hallitse-menetelmää käyttäen algoritmi TULOSTA_PUU_LASKEVA, joka tulostaa

Lisätiedot

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu Taulukot Taulukon määrittely ja käyttö Taulukko metodin parametrina Taulukon sisällön kopiointi toiseen taulukkoon Taulukon lajittelu esimerkki 2-ulottoisesta taulukosta 1 Mikä on taulukko? Taulukko on

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PERUSTIETORAKENTEET LISTA, PINO, JONO, PAKKA ABSTRAKTI TIETOTYYPPI Tietotyyppi on abstrakti, kun se on määritelty (esim. matemaattisesti) ottamatta kantaa varsinaiseen

Lisätiedot

Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu.

Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu. Rekursiosta ja iteraatiosta Oletetaan että meillä on aluksi yksi vastasyntynyt kanipari, joista toinen on uros ja toinen naaras. Kanit saavuttavat sukukypsyyden yhden kuukauden ikäisinä. Kaninaaraan raskaus

Lisätiedot

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: Harjoitus 7 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: class Lintu //Kentät private int _siivenpituus; protected double _aivojenkoko; private bool _osaakolentaa; //Ominaisuudet public int

Lisätiedot

plot(f(x), x=-5..5, y=-10..10)

plot(f(x), x=-5..5, y=-10..10) [] Jokaisen suoritettavan rivin loppuun ; [] Desimaalierotin Maplessa on piste. [] Kommentteja koodin sekaan voi laittaa # -merkin avulla. Esim. #kommentti tähän [] Edelliseen tulokseen voi viitata merkillä

Lisätiedot

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti: 1 (7) Tiedon lukeminen näppäimistöltä Scanner-luokan avulla Miten ohjelma saa käyttöönsä käyttäjän kirjoittamaa tekstiä? Järjestelmässä on olemassa ns. syöttöpuskuri näppäimistöä varten. Syöttöpuskuri

Lisätiedot

v 8 v 9 v 5 C v 3 v 4

v 8 v 9 v 5 C v 3 v 4 Verkot Verkko on (äärellinen) matemaattinen malli, joka koostuu pisteistä ja pisteitä toisiinsa yhdistävistä viivoista. Jokainen viiva yhdistää kaksi pistettä, jotka ovat viivan päätepisteitä. Esimerkiksi

Lisätiedot

Ohjausjärjestelmien jatkokurssi. Visual Basic vinkkejä ohjelmointiin

Ohjausjärjestelmien jatkokurssi. Visual Basic vinkkejä ohjelmointiin Ohjausjärjestelmien jatkokurssi Visual Basic vinkkejä ohjelmointiin http://www.techsoft.fi/oskillaattoripiirit.htm http://www.mol.fi/paikat/job.do?lang=fi&jobid=7852109&index=240&anchor=7852109 Yksiköt

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 27.1.2010 T-106.1208 Ohjelmoinnin perusteet Y 27.1.2010 1 / 37 If-käsky toistokäskyn sisällä def main(): HELLERAJA = 25.0 print "Anna lampotiloja, lopeta -300:lla."

Lisätiedot

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne.

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne. Proseduurit Proseduuri voi olla 1) Funktio, joka palauttaa jonkin arvon: real function sinc(x) real x sinc = sin(x)/x... y = sinc(1.5) 2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma

Lisätiedot

Perinteiset tietokoneohjelmat alkavat pääohjelmasta, c:ssä main(), jossa edetään rivi riviltä ja käsky käskyltä.

Perinteiset tietokoneohjelmat alkavat pääohjelmasta, c:ssä main(), jossa edetään rivi riviltä ja käsky käskyltä. TIETOKONEOHJELMIEN RAKENNE Perinteiset tietokoneohjelmat alkavat pääohjelmasta, c:ssä main(), jossa edetään rivi riviltä ja käsky käskyltä. Teollisuusautomaation ohjelmiin on lainattu runsaasti perinteisen

Lisätiedot

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi 1 Javan perusteet Ohjelmointi IPO-malli Java lähdekoodista suoritettavaksi ohjelmaksi Vakio Muuttuja Miten Javalla näytetään tietoa käyttäjälle, miten Javalla luetaan käyttäjän antama syöte Miten Javalla

Lisätiedot

Kokeellista matematiikkaa SAGE:lla

Kokeellista matematiikkaa SAGE:lla Kokeellista matematiikkaa SAGE:lla Tutkin GeoGebralla 1 luonnollisen luvun jakamista tekijöihin 2. GeoGebran funktio Alkutekijät jakaa luvun tekijöihin ja tuottaa alkutekijät listana. GeoGebrassa lista

Lisätiedot

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet A271117, Tietokannat Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: Leon Atkinson: core MySQL Ari Hovi: SQL-opas TTY:n tietokantojen perusteet-kurssin

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet String-merkkijonoluokka 1 Ohjelmointikielten merkkijonot Merkkijonot ja niiden käsittely on välttämätöntä ohjelmoinnissa Valitettavasti ohjelmointikielten tekijät eivät tätä ole ottaneet

Lisätiedot

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4 Sisällys 12. Näppäimistöltä lukeminen Arvojen lukeminen näppäimistöltä yleisesti. Arvojen lukeminen näppäimistöltä Java-kielessä.. Luetun arvon tarkistaminen. Tietovirrat ja ohjausmerkit. Scanner-luokka.

Lisätiedot

3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö

3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö 3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö Yhtälön (tai funktion) y = a + b + c, missä a 0, kuvaaja ei ole suora, mutta ei ole yhtälökään ensimmäistä astetta. Funktioiden

Lisätiedot

1. Algoritmi 1.1 Sisällys Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. Muuttujat ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.2 Algoritmin määritelmä Ohjelmointi

Lisätiedot

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Liite E - Esimerkkiprojekti E Esimerkkiprojekti Olet lukenut koko kirjan. Olet sulattanut kaiken tekstin, Nyt on aika soveltaa oppimiasi uusia asioita pienen, mutta täydellisesti muotoiltuun, projektiin.

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 16.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 16.9.2015 1 / 26 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla:

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla: KERTAUSTEHTÄVIÄ Tietue Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla: struct henkilotiedot char nimi [20]; int ika; char puh [10]; ; Edellä esitetty kuvaus määrittelee

Lisätiedot

LUMA Suomi kehittämisohjelma 8.10.2015 14:53 Joustava yhtälönratkaisu Matemaattinen Ohjelmointi ja Yhtälönratkaisu

LUMA Suomi kehittämisohjelma 8.10.2015 14:53 Joustava yhtälönratkaisu Matemaattinen Ohjelmointi ja Yhtälönratkaisu (MOJYR) Sisällysluettelo (MOJYR)... 1 1. Taustaa... 1 2. MOJYR-ohjelma... 2 2.1 Ohjelman asentaminen... 2 2.2 Käyttöliittymä... 2 3. Puumalli... 3 4. MOJYR-ohjelman ominaisuudet... 5 4.1 Yhtälön muodostaminen...

Lisätiedot

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys Loogisia operaatioita - esimerkkejä Tänään on lämmin päivä ja perjantai Eilen satoi ja oli keskiviikko tai tänään on tiistai. On perjantai ja kello on yli 13 Ei ole tiistai tai ei sada. Ei pidä paikkaansa,

Lisätiedot

TT00AA12-2016 - Ohjelmoinnin jatko (TT10S1ECD)

TT00AA12-2016 - Ohjelmoinnin jatko (TT10S1ECD) TT00AA12-2016 - Ohjelmoinnin jatko (TT10S1ECD) Ohjelmointikäytännöt 21/3/11 Mikko Vuorinen Metropolia Ammattikorkeakoulu 1 Sisältö 1) Mitä on hyvä koodi? 2) Ohjelmointikäytäntöjen merkitys? 3) Koodin asettelu

Lisätiedot

etunimi, sukunimi ja opiskelijanumero ja näillä

etunimi, sukunimi ja opiskelijanumero ja näillä Sisällys 1. Algoritmi Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.1 1.2 Algoritmin määritelmä Ohjelmointi

Lisätiedot

Outoja funktioita. 0 < x x 0 < δ ε f(x) a < ε.

Outoja funktioita. 0 < x x 0 < δ ε f(x) a < ε. Outoja funktioita Differentiaalilaskentaa harjoitettiin miltei 200 vuotta ennen kuin sen perustana olevat reaaliluvut sekä funktio ja sen raja-arvo määriteltiin täsmällisesti turvautumatta geometriseen

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

Sisällys. 3. Pseudokoodi. Johdanto. Johdanto. Johdanto ja esimerkki. Pseudokoodi lauseina. Kommentointi ja sisentäminen.

Sisällys. 3. Pseudokoodi. Johdanto. Johdanto. Johdanto ja esimerkki. Pseudokoodi lauseina. Kommentointi ja sisentäminen. Sisällys 3. Pseudokoodi Johdanto ja esimerkki. Pseudokoodi lauseina. Kommentointi ja sisentäminen. Ohjausrakenteet: Valinta if- ja if--rakenteilla. oisto while-, do-while- ja for-rakenteilla. 3.1 3.2 Johdanto

Lisätiedot

5.2 Ensimmäisen asteen yhtälö

5.2 Ensimmäisen asteen yhtälö 5. Ensimmäisen asteen ytälö 5. Ensimmäisen asteen yhtälö Aloitetaan antamalla nimi yhtälön osille. Nyt annettavat nimet eivät riipu yhtälön tyypistä tai asteesta. Tarkastellaan seuraavaa yhtälöä. Emme

Lisätiedot