OHJ-1010 Tietotekniikan perusteet 4 op Syksy 2012 Luento 11: Ohjelmointi Tekijät: Antti Virtanen, Timo Lehtonen, Matti Kujala, Kirsti Ala-Mutka, Petri M. Gerdt et al.
Luennon aiheet Ohjelmoinnin historia Algoritmin käsite Algoritmin esittäminen Ohjelmointikielet Ohjelmien oikeellisuus Ohjelmistoprosessi
Ohjelmoinnin varhaishistoria Ensimmäisen ohjelmoitavan laitteen kehitteli muslimitutkija Al-Jazari vuonna 1206 Primitiivinen rumpukone soitti esiohjelmoitua musiikkia Joseph Marie Jacquard kehitti reikäkorteilla ohjelmoitavat kangaspuut 1801 (Jacquard Loom) Reiät saivat kangaspuut kutomaan erilaisia kuvioita Englantilainen matemaatikko Charles Babbage suunnitteli ensimmäisen modernin tietokoneen, Analytical Enginen vuonna 1837 (->) Analytical Engineä ei koskaan rakennettu Voimaa höyrykoneesta, koko 20 x 10 metriä Olisi ollut edellä 1940-luvun tietokoneita toteutuessaan
Ohjelmoinnin historiaa 1900-luvulla Alan Turing kehitti laskennan mallin, Turingin koneen vuosina 1936-1937 Kykenee suorittamaan joukon talletettuja käskyjä Matemaatikko von Neumann kehitti Turingin koneen perusteella modernin tietokonearkkitehtuurin Puhutaan von Neumann -arkkitehtuurista Keskusmuisti, ohjausyksikkö, ALU... Tietokoneita alettiin käyttää 1940-luvulla Todella kookkaita Hitaita ja primitiivisiä nykykoneisiin verrattuna Varhaiset tietokoneet ohjelmoitiin reikäkorteilla
Reikäkortti
Ohjelmointi 1900-luvun loppupuolella Ensimmäinen varsinainen ohjelmointikieli oli Fortran vuodelta 1954 Fortran = The IBM Mathematical Formula Translating System Fortranin ensimmäinen versio sisälsi 32 käskyä Käskykanta laajeni kielen myöhemmissä versioissa Fortran on edelleen käytössä Uusin standardi on Fortran 2008 Muita ohjelmointikieliä 1960-luku: Simula, Lisp 1970-luku: Prolog, Smalltalk, C, Pascal 1980-luku: C++, Ada 1990-luku: Java, Perl 2000-luku: PHP, Python, C#
Algoritmi Äärellinen joukko hyvin määriteltyjä ohjeita jonkin tehtävän suorittamiseksi Algoritmi alkaa jostakin tilasta Algoritmi päättyy, kun tehtävä on suoritettu Kakkuresepti on eräänlainen algoritmi Alkutilana on tiettyjen aineiden olemassaolo Resepti kertoo vaihe vaiheelta kuinka kakun osat sekoitetaan, jne. Resepti päättyy siihen, kun kakku on valmis
Origami-algoritmi
Musiikkialgoritmi
Pikkujoulualgoritmi
Algoritmin esittäminen Algoritmin esitystavan on oltava yksikäsitteinen Sopiva esitystapa riippuu käyttötarkoituksesta, algoritmista ja tulkitsijasta Ihmisen tulkittavaksi tarkoitetut algoritmit voidaan esittää epätarkasti tai epämuodollisesti, monitulkintaisuus ole iso ongelma pidä kakkua uunissa kunnes se on kypsä Tietokone vaatii täsmällisen ja yksityiskohtaisen esitystavan, koska se ei tee mitään tulkintaa Ohjelmointikielet ovat keino ilmaista algoritmit yksiselitteisesti
Algoritmit ovat hankalia (kuva 020202 reittipalvelusta)
Algoritmit ovat hankalia muillekin..
Kielten ominaisuuksia Luonnollinen kieli on monitulkintaista Luonnolliset kielet ovat ihmisten käyttämiä kieliä Joskus monitulkintaisuus on itsetarkoitus Joskus monitulkintaisuutta pyritään välttämään, esimerkiksi lakitekstissä Kielillä on syntaksi ja semantiikka Kielen syntaksi kertoo missä järjestyksessä kielen sanoja voi yhdistellä Kielen semantiikka kertoo mitä sanat tarkoittavat Ihmiset tulkitsevat puhuttua ja kirjoitettua kieltä ymmärtääkseen mitä ne merkitsevät
Syntaksi Värillinen puoli paperista Käännä paperi ks. esimerkki Semantiikka Erottaa paperin eri puolet toisistaan, ks. esimerkki Esittää taitoksen sisäpuolta esim. tarkoittaa Esittää taitoksen ulkopuolta Esim. tarkoittaa Taita vastakkain niin että tuottaa Paina sisään niin että tuottaa
Algoritmistä ohjelmaksi Miten tietokone saadaan toimimaan jonkin algoritmin mukaisesti? Algortimi on esitettävä tietokoneen ymmärtämässä muodossa Luonnollinen kieli soveltuu huonosti algoritmien esittämiseen tietokoneelle Algoritmejä voi kyllä välittää toisille ihmisille luonnollisella kielellä Ohjelmointikielet ovat keinotekoisia kieliä, joita ymmärtävät sekä ihmiset että tietokoneet Ohjelmointikielien syntaksi ja semantiikka on yksiselitteisesti määritelty Tästä syystä ohjelmointi onkin hankalaa: eksakti ilmaus on ihmiselle usein vierasta
Puolitushakualgoritmi ihmistä varten Tehtävä: etsi nimi puhelinluettelosta ja soita numeroon 1) Jos luetteloa on jäljellä, 1) niin avaa puhelinluettelo puolesta välistä. Lue nimi. 2) muuten homma lopetetaan ja todetaan että nimeä ei ole luettelossa 2) Jos nimi on se mitä etsitään, homma on valmis, mene soittamaan 3) Jos etsitty nimi on aakkosissa ennen tätä puolesta välistä löytynyttä nimeä, 1) niin poista luettelon loppuosa ja jatka kohdasta 1. 2) muuten poista luettelon alkuosa ja jatka kohdasta 1.
Puolitushakualgoritmi tietokonetta varten public int interpolationsearch(int[] sortedarray, int tofind){ // Returns index of tofind in sortedarray, or -1 if not found int low = 0; int high = sortedarray.length - 1; int mid; while (sortedarray[low] < tofind && sortedarray[high] >= tofind) { mid = low + ((tofind - sortedarray[low]) * (high - low)) / (sortedarray[high] - sortedarray[low]); if (sortedarray[mid] < tofind) low = mid + 1; else if (sortedarray[mid] > tofind) high = mid - 1; else return mid; } if (sortedarray[low] == tofind) return low; else return -1; // Not found } Puolitushakualgoritmin toteutus Java-kielellä, noudettu Wikipediasta 3.9.2007
Korkean ja matalan tason ohjelmointikielet Matalan tason ohjelmointikielet ovat lähempänä tietokoneen bittiesitystä Konekieli ilmaisee ohjelman bitteinä Symbolinen konekieli korvaa osan biteistä symboleilla Esimerkiksi muistiosoitteita kirjotetaan koodin sekaan Konekielet ovat usein sidottu tiettyyn tietokonetoteutukseen Korkean tason ohjelmointikielet (lausekielet) ovat lähempänä luonnollisia kieliä Ohjelma ilmaistaan varattujen sanojen kautta Muistiosoitteiden sijaan käytetään muuttujia Korkean tason kielet käännetään konekielelle kääntäjäohjelmalla Korkean tason ohjelmaa voi käyttää eri tietokoneissa, jos on olemassa sopiva kääntäjä
Esimerkki matalan tason ohjelmoinnista
Esimerkki korkean tason ohjelmoinnista (*1*) program NelionAla (input,output); (*2*) var s: real; (*3*) begin (*4*) repeat (*5*) write ('Anna neliön sivu: '); (*6*) readln (s) (*7*) until s > 0; (*8*) writeln('neliön ala on ', s * s) (*9*) end. Lähde: http://www.cs.joensuu.fi/~saja/var_roles/stud_vers/stud_pascal_fin_v2.html (9.3.2007)
Pelkistys tietokoneen toiminnasta ohjelmien kannalta Syöteaineisto Ohjelma Tulosaineisto Kun ohjelmaa muutetaan tai se korvataan täysin eri ohjelmalla, muuttuu myös samasta syöteaineistosta saatava tulosaineisto
Miten (korkean tason kielillä) ohjelmoidaan? Aluksi tehdään suunnitelma siitä, mitä ohjelman tulee tehdä Mitä syötteitä ohjelmalle annetaan ja miten Mitä ohjelma tulostaa milläkin syötteellä Suunnitelma muotoillaan algoritmiksi Algoritmin voi ajatella suunnitelman täsmälliseksi esitykseksi Ohjelma kirjoitetaan tekstitiedostoon jollakin tekstieditorilla Ohjelma syötetään kääntäjä-ohjelmalle, joka muodostaa tekstitiedostosta tietokoneen ymmärtämän bittiesityksen Suorituskelpoisen tiedoston, ohjelman konekieliesityksen... sitten tutkitaan toimiiko ohjelma niinkuin suunniteltiin
Termistö Ohjelmointikieli Kääntäjä Konekieli Entäs sitten tulkki?
Aliohjelmat Aliohjelmat ovat korkeamman tason ohjelmointikielten tapa jakaa ohjelma järkevän kokoisiin palasiin Itsenäinen osa ohjelmakoodia, joka suorittaa tietyn tehtävän Aliohjelmia kutsutaan myös, funktioksi, proseduureiksi ja metodeiksi Edellä mainituilla on pieniä toiminnallisia eroja eri kielissä Ohjelmoija voi käyttää aliohjelmia tarvisematta tietää niiden tarkkaa toimintaa Miten taskulaskin laskee sin(50)? Aliohjelmalla on nimi, parametrit ja lopputulos Vertaa: konekäskyt ja komentotulkille annettavat käskyt Valmiita aliohjelmia löytyy esimerkiksi aliohjelmakirjastoista ja käyttöjärjestelmästä
Aliohjelmaesimerkki C++ -kielellä #include <iostream> double KeskiArvo(double luku1, double luku2) { double tulos = 0; tulos = (luku1 + luku2) / 2; return tulos; } int main() { std::cout << KeskiArvo(3, 5) << std::endl; return 0; }
Aliohjelmaesimerkki C++ -kielellä #include<iostream> Aliohjelma, C++:ssa funktio double KeskiArvo(double luku1, double luku2) { double tulos = 0; tulos = (luku1 + luku2) / 2; return tulos; } void main() { cout << KeskiArvo(3, 5); } Lähde: http://www.nic.funet.fi/c++opas/funktiot.html (3.9.2007)
Aliohjelmaesimerkki C++ -kielellä #include<iostream> Aliohjelman nimi Aliohjelman parametrit double KeskiArvo(double luku1, double luku2) { double tulos = 0; tulos = (luku1 + luku2) / 2; return tulos; } void main() Aliohjelman palautusarvo { cout << KeskiArvo(3, 5); } Lähde: http://www.nic.funet.fi/c++opas/funktiot.html (3.9.2007)
Aliohjelmaesimerkki C++ -kielellä #include<iostream> double KeskiArvo(double luku1, double luku2) { double tulos = 0; tulos = (luku1 + luku2) / 2; return tulos; } void main() { cout << KeskiArvo(3, 5); } Pääohjelma Lähde: http://www.nic.funet.fi/c++opas/funktiot.html (3.9.2007)
Aliohjelmaesimerkki C++ -kielellä #include<iostream.h> double KeskiArvo(double luku1, double luku2) { double tulos = 0; tulos = (luku1 + luku2) / 2; return tulos; Aliohjelman kutsu } void main() { cout << KeskiArvo(3, 5); } Pääohjelma Lähde: http://www.nic.funet.fi/c++opas/funktiot.html (3.9.2007)
Algoritmin (ohjelman) oikeellisuus (1/2) Algoritmia on yleisesti ottaen mahdotonta todistaa oikeaksi Rajoitetussa tapauksessakin se on hyvin vaativaa Esimerkiksi nettikasinot julkaisevat yleensä algoritmin, jolla virtuaalinen korttipakka sekoitetaan Kolmas osapuoli tarkistaa algoritmin oikeellisuuden ja oikean toteutuksen Sekoitusalgoritmin toiminnasta saa empiiristä aineistoa pelaamalla tai seuraamalla pelejä Silti vuodesta toiseen osa pelaajista epäilee algoritmin toimintaa?
Algoritmin (ohjelman) oikeellisuus (2/2) Yleensä käytetään erilaisia heuristisia menetelmiä ja luotetaan siihen, ettei vakavia virheitä testaamisen jälkeen oli Heuristinen tarkoittaa epäformaalia, esimerkiksi niin sanottu akateeminen veikkaus Käytännössä kaikissa monimutkaisissa algoritmeissa on virheitä Aina tämä ei kuitenkaan haittaa
Ohjelman (algoritmin) testaus ja debuggaus Ohjelman oikeellisesta toiminnasta varmistutaan testaamalla ohjelman toimintaa Annetaan ohjelmalle mahdollisimman kattavasti erilaisia mahdollisia syötteitä Tarkistetaan tuottaako ohjelma oikeanlaisen tulosteen syötteisiin nähden Jos ohjelma antaa väärän tulosteen tietyllä syötteellä, niin silloin on löydetty virhe Testausta tulisi jatkaa niin pitkään, että virheitä ei enää löydy Testaus lopetetaan käytännössä silloin, kun aika ja/tai rahat loppuvat... Ohjelmavirheiden korjaamista nimitetään debuggaukseksi Bug = ötökkä englanniksi, debuggaus = ötököiden poistoa
Esimerkki bugista ohjelmassa Ensimmäinen dokumentoitu bugi, havaittu 9.9.1947. Lähde: http://en.wikipedia.org/wiki/computer_bug (3.9.2007)
Visuaalista ohjelmointia Visuaalista ohjelmointia käytetään esimerkiksi teollisuusautomaatios sa ja reaktiivisissa järjestelmissä Visuaalinen paradigma ei ole (toistaiseksi) saavuttanut kovin suurta suosiota Kuva: Labview-ohjelma, Antti Siiskonen
Eräajo Eräajossa (batch processing) ohjelmille laaditaan syöte etukäteen ja kone raksuttelee tuloksen käyttäjän ollessa kahvilla Ajastetusti toimivat ohjelmat (varmuuskopiointi) Raskas laskenta (sääennuste) tai muuten suuren tietomäärän käsittely (10000 jpeg-kuvan pakkaussuhteen muuttaminen) Työ (ohjelma) Käyttäjä Tulokset Työjono Suoritus
Interaktiiviset ohjelmat Interaktiivinen = vuorovaikutteinen Interaktiivisissa ohjelmissa ihminen ja ohjelma keskustelevat keskenään Käyttäjä Ohjelma A Ohjelma B Suoritus Suoritus
Kuinka algoritmejä kehitellään? Esimerkkiongelma: Suunnittele algoritmi, joka järjestää aakkosjärjestykseen nimet David, Alice, Carol, Gail, Bob Miten teksti esitettiin tietokoneen muistissa? Millainen olisi yleinen ratkaisu? Entä millainen olisi kätevä manuaalinen järjestysalgoritmi tenttipapereiden lajitteluun opiskelijanumeron perusteella? Usein lähestymistapana käytetään ongelman jakamista osaongelmiin Ohjelmistojen suunnittelussa suuri ongelma itsessään onkin, kuinka alkuperäinen tehtävä saadaan parhaiten jaettua osatehtäviin
Kuinka algoritmejä kehitellään? Eri tyyppisten ratkaisujen tehokkuus voi vaihdella suuresti erilaisilla syöteaineistoilla, esimerkiksi suuri vs. pieni aineisto järjestyksessä oleva vs. järjestämätön aineisto keskimääräinen tehokkuus, pahin tapaus ja paras tapaus voivat erota paljonkin. Yleensä arvioidaan pahinta tapausta vrt. selaushakua ja puolitushakua 1000 nimen puhelinluettelossa
Kuinka algoritmejä kehitellään? Algoritmin suunnittelun jälkeen tulisi aina arvioida ratkaisun oikeellisuutta ja soveltuvuutta alkuperäiseen ongelmaan valitettavasti tietokoneiden parissa ohjelmien 100% oikeellisuuskaan ei välttämättä riitä virheitä voi tulla myös laitteiston taholta suoritusvaiheessa
Tehokkuus suhteessa aineiston kokoon