Ohjelmoinnin peruskurssi Y1

Samankaltaiset tiedostot
Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Java-kielen perusteet

Ohjelmoinnin perusteet Y Python

TT00AA Ohjelmoinnin jatko (TT10S1ECD)

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla

Ohjelmoinnin perusteet Y Python

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin perusteet, syksy 2006

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Ohjelmoinnin perusteet Y Python

Python-ohjelmointi Harjoitus 2

Ohjelmoinnin peruskurssi Y1

Tutoriaaliläsnäoloista

Harjoitustyö: virtuaalikone

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Java-kielen perusteet

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

14. Hyvä ohjelmointitapa 14.1

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

Ohjelmoinnin perusteet Y Python

Luento 5. Timo Savola. 28. huhtikuuta 2006

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

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

Harjoitus 5 (viikko 48)

Ohjelmoinnin peruskurssi Y1

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Transkriptio:

Ohjelmoinnin peruskurssi Y1 CSE-A1111 19.10.2016 CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 1 / 43

Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute. Tätä kautta on mahdollisuus antaa nimettömänä palautetta luennosta. Jos jokin asia on jäänyt palautteen perusteella epäselväksi, palataan siihen mahdollisuuksien mukaan seuraavalla luennolla. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 2 / 43

Oppimistavoitteet: tämän luennon jälkeen Sinulla on peruskäsitys siitä, mitä hyvällä ohjelmointityylillä tarkoitetaan ja miksi sen käyttäminen on tärkeää. Osaat käsitellä ohjelmassa erilaisia virhetilanteita niin, että ohjelma ei kaadu esimerkiksi silloin, jos käyttäjä antaa pyydetyn luvun sijasta tekstiä. Tiedät, miten ohjelman käsitelemää tietoa voi säilyttää ohjelman suorituskerrasta toiseen käyttämällä hyväksi tiedostoja. Osaat kirjoittaa ohjelman, joka lukee rivejä tekstitiedostosta ja tekee luetuille riveille haluttuja asioita. Lisäksi tämän kerran kalvojen loppuosassa kerrotaan, millaisia vaiheita ohjelman suunnittelussa ja kirjoittamisessa on sekä esitellään lyhyesti niitä periaatteita, joiden mukaan ohjelman rakennetta voi suunnitella. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 3 / 43

Hyvä ohjelmointityyli Ohjelman kirjoittamisen jälkeenkin tulee usein vastaan tilanteita, joissa ihminen (kirjoittaja itse tai joku toinen) joutuu lukemaan ohjelmakoodia, esimerkiksi Ohjelmassa havaitaan virhe, joka pitää korjata. Ohjelman toimintaa halutaan laajentaa tai muuttaa. Ohjelmaa tai sen osaa halutaan käyttää pohjana uutta ohjelmaa tehdessä. Tällöin on tärkeää, että ohjelman kirjoittamisessa on käytetty hyvää ohjelmointityyliä. Silloin ohjelmaa lukevan ihmisen on helppo saada käsitys ohjelman rakenteesta ja toiminnasta. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 4 / 43

Mitä seuraava funktio tekee? def f(t1,t2): i=0 #nollataan i x=0 #nollataan x y=len(t1) #y saa arvokseen t1:n pituuden while i<y: #jatketaan niin kauan, että i on y z=t1[i]-t2[i] #sijoitetaan erotus z:aan x+=z #lisataan z x:aan i+=1 #kasvatetaan i:ta yhdella if y>0: k=x/y #k:n arvoksi tulee x jaettuna y else: k=0.0 #nollataan k return k #palautetaan k:n arvo CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 5 / 43

Sama funktio kirjoitettuna toisin def laske_erojen_keskiarvo(lista1, lista2): i = 0 erojen_summa = 0 alkioiden_lkm = len(lista1) while i < alkioiden_lkm: alkioiden_ero = lista1[i] - lista2[i] erojen_summa += alkioiden_ero i += 1 if alkioiden_lkm > 0: keskiarvo = erojen_summa / alkioiden_lkm else: keskiarvo = 0.0 return keskiarvo Kumpaa funktiota on helpompi ymmärtää? CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 6 / 43

Hyvään ohjelmointityyliin kuuluvia asioita Ohjelman järkevä jako funktioihin. (Katso luentokalvojen loppuosa.) Kuvaavat nimet muuttujilla, parametreilla, funktioilla jne. Järkevä kommentointi. Sisennykset (tulevat Python-ohjelmissa yleensä pakosta oikein). Tyhjien tilan (tyhjät rivit ja välilyönnit) järkevä käyttö. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 7 / 43

Nimistä Muuttujat, parametrit ja funktiot on syytä nimetä niin, että ne kuvaavat mahdollisimman hyvin muuttujan tms. tarkoitusta. Esimerkiksi korkeus on paljon parempi muuttujan nimi kuin luku silloin, kun muuttujan arvoksi annetaan jonkin kappaleen korkeus. Yksikirjaimiset nimet ovat suositeltavia vain erikoistapauksissa: Toistokäskyn kierroslaskureina. Silloin, kun muuuttujan nimi on suoraan sama kuin esim. matematiikan tai fysiikan kaavassa yleisesti käytetty symboli. Muuttujien nimet on syytä kirjoittaa pienellä kirjaimella ja vakioiden nimet isolla kirjaimella. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 8 / 43

Kommentit Selvittävät koodin lukijalle sen rakennetta ja toimintaa. Ohjelmatiedoston alkuun yleiskommentti, jossa kerrotaan ohjelman kirjoittaja ja se, mitä tiedostossa oleva ohjelma tekee. Jokaisen funktion otsikon yhteyteen kommentti, joka kertoo funktion tarkoituksen, parametrien merkityksen sekä funktion palauttaman arvon. Funktioiden sisällä on syytä kommentoida vain suurempia kokonaisuuksia ja epätavallisia ratkaisuja. Älä kommentoi asioita, jotka ovat itsestään selviä jokaiselle Python-kieltä osaavalle, esim. i += 1 #i:ta kasvatetaan yhdella Sen sijaan joissain tilanteissa voi olla järkevää kommentoida, miksi i:tä kasvatetaan. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 9 / 43

Tyhjän tilan käyttö Tyhjien rivien käytöllä helpotetaan sen näkemistä, millaisiin osiin ohjelma jakautuu. Kahden funktion väliin on aina syytä jättää 1 2 tyhjää riviä. Myös pidemmän funktion sisällä voi tyhjillä riveillä selventää, millaisista osista funktio koostuu. Älä kirjoita koodia, jossa joka toinen rivi on tyhjä se vain hankaloittaa ohjelman lukemista. Erota operaattori ja operandit toisistaan välilyönnillä. Tämä helpottaa lausekkeiden hahmottamista. Myös pilkun jälkeen kannattaa yleensä kirjoittaa välilyönti. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 10 / 43

Poikkeukset Ohjelmaa suoritettaessa voidaan törmätä virhetilanteisiin. Osa virheistä johtuu ohjelmointivirheistä, mutta osaan ohjelmoija ei voi vaikuttaa (käyttäjä antaa vääräntyyppisen syötteen, ohjelman pitäisi kirjoittaa tiedostoon, mutta kovalevytila on täynnä). Virhetilanteiden käsittely if else-rakenteen avulla tekee ohjelmasta helposti sekavan. Python tarjoaa virhetilanteiden käsittelyyn oman mekanismin, poikkeukset Poikkeus voidaan käsitellä try except-rakenteen avulla. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 11 / 43

try except-rakenne try: # Jono kaskyja, joista jokin tai jotkin # voivat aiheuttaa poikkeuksen. except poikkeuksen_tyyppi: # Kaskyja, jotka jotenkin selvittavat # virhetilanteen, jos on aiheutunut # poikkeuksen_tyyppi-tyyppinen poikkeus. Try-osassa olevia käskyjä suoritetaan normaalisti. Jos aiheutuu tyypin poikkeuksen_tyyppi poikkeus, hypätään välittömästi except-osaan, eikä enää palata try-osaan. Jos poikkeusta ei aiheudu, except-osan käskyjä ei suoriteta lainkaan. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 12 / 43

Virheelliseen syötteeseen varautuminen Jos käyttäjän antama syöte on väärää tyyppiä (esimerkiksi kirjaimia sisältävä merkkijono, kun pitäisi olla kokonaisluku), aiheutuu ValueError-tyyppinen poikkeus, kun yritetään muodostaa syötettä vastaava luku. Tämä poikkeus voidaan käsitellä try except-rakenteessa. Yksinkertaisimmillaan except-osassa annetaan käyttäjälle selväsanainen virheilmoitus. Toinen vaihtoehto on pyytää käyttäjältä uutta syötettä niin kauan, että hän antaa oikean. Seuraava ohjelma muuntaa käyttäjän nauloina antaman massan kilogrammoiksi. Jos käyttäjä ei anna kokonaislukua, aiheutuu poikkeus. Tällöin ohjelma antaa virheilmoituksen. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 13 / 43

Naulamuunnos, koodi def main(): NAULAKERROIN = 0.4536 print("muutan nauloina annetun massan kilogrammoiksi.") try: syote = input("anna massa nauloina: ") naulat = int(syote) kilot = NAULAKERROIN * naulat print("massa on {:.3f} kg".format(kilot)) except ValueError: print("virhe: et antanut nauloja kokonaislukuna.") main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 14 / 43

Syötteen pyytäminen uudelleen Parempi versio ohjelmasta pyytää käyttäjältä nauloja niin kauan, että hän antaa kokonaisluvun. Uutta pyyntöä ei kuitenkaan sijoiteta except-osaan. (Miksi ei?) Sen sijaan koko try except-osa sijoitetaan toistokäskyn sisään. Toistokäskyn suoritusta jatketaan niin kauan, että on saatu luettua kelvollinen syöte. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 15 / 43

Naulamuunnos: uusi koodi def main(): NAULAKERROIN = 0.4536 print("muutan nauloina annetun massa kilogrammoiksi.") luku_onnistui = False while not luku_onnistui: try: syote = input("anna massa nauloina: ") naulat = int(syote) kilot = NAULAKERROIN * naulat print("massa on {:.3f} kg".format(kilot)) luku_onnistui = True except ValueError: print("virhe: et antanut nauloja kokonaislukuna.") print("yrita uudelleen!") main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 16 / 43

Apufunktio luvun lukemiseen Jos samassa ohjelmassa luetaan kokonaislukuja useassa kohdassa, kannattaa yleensä kirjoittaa apufunktio kokonaisluvun lukemiseen. Funktio lukee ja palauttaa kokonaisluvun. Jos lukeminen ei onnistu, funktio pyytää käyttäjältä uutta kokonaislukua niin kauan, että saadaan kelvollinen kokonaisluku. Vastaavat apufunktiot voidaan kirjoittaa myös muuntyyppisten arvojen lukemiseen. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 17 / 43

Kokonaisluvun lukeminen apufunktion avulla: koodi def lue_kokonaisluku(): luku_onnistui = False while not luku_onnistui: try: luku = int(input()) luku_onnistui = True except ValueError: print("virheellinen kokonaisluku!") print("anna uusi!") return luku CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 18 / 43

Kokonaisluvun lukeminen apufunktion avulla: koodi jatkuu def main(): NAULAKERROIN = 0.4536 print("muutan nauloina annetun massa kilogrammoiksi.") print("anna massa nauloina.") naulat = lue_kokonaisluku() kilot = NAULAKERROIN * naulat print("massa on {:.3f} kg".format(kilot)) main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 19 / 43

Huomatuksia poikkeuksista try except-rakenne voi sisältää useita except-osia erityyppisiä poikkeuksia varten. Tällöin poikkeuksen sattuessa siirrytään ensimmäiseen except-osaan, jonka poikkeuksen tyyppi vastaa aiheutunutta poikkeusta. Ohjelmoija voi myös itse aiheuttaa poikkeuksen (virhetilanteen sattuessa) raise-käskyllä. Sitä ei kuitenkaan käsitellä tällä kurssilla. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 20 / 43

Tiedostot Tiedostojen käsittelyä tarvitaan esimerkiksi seuraavissa tilanteissa: Ohjelman käsittelemiä tietoa halutaan säilyttää ohjelman suorituskerrasta toiseen (esim. puhelinluettelo, opiskelijarekisteri). Halutaan, että käyttäjän ei tarvitse syöttää ohjelman lähtötietoja jokaisella suorituskerralla, vaan lähtötiedot (esimerkiksi mittaussarjan parametrit) luetaan tiedostosta. Ohjelman on käsiteltävä jonkun muun ohjelman tuottamaa dataa. Ohjelma lukee tarvittavat lähtötiedot tiedostosta. Jos ohjelma tekee tietoihin muutoksia ja muuttuneita tietoja halutaan käyttää seuraavalla suorituskerralla, ohjelma kirjoittaa muuttuneet tiedot tiedostoon. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 21 / 43

Tekstitiedosto vs. binääritiedosto Tiedostot jaetaan tekstitiedostoihin ja binääritiedostoihin. Tekstitiedostossa tiedot on tallennettu merkkeinä, esimerkiksi luku 147 merkkeinä 1, 4 ja 7. Tekstitiedostoa voi muokata millä tahansa tekstieditorilla. Binääritiedostossa tiedot on esitetty binääriesitysmuodossa, esimerkiksi luku 147 vastaavana binäärilukuna. Binääritiedostoa ei yleensä pysty käsittelemään järkevästi tavallisella tekstieditorilla. Tällä kurssilla opetetaan ainoastaan tekstitiedostojen käsittely. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 22 / 43

Tiedoston avaaminen Tiedostoja käsitellessä on jotenkin yhdistettävä ohjelman muuttuja fyysiseen tiedostoon. Samalla käyttöjärjestelmäpuolella varaudutaan käsittelemään ko. tiedostoa. Tätä kutsutaan tiedoston avaamiseksi, esimerkki tiedostomuuttuja = open("teksti.txt","r") Ensimmäinen parametri on käsiteltävän tiedoston nimi käyttöjärjestelmässä. Tarvittaessa nimeen on sisällytettävä polku tiedoston hakemistoon. Toinen parametri kertoo tiedoston käsittelytavan. Arvo "r" kertoo, että tiedosto avataan lukemista varten. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 23 / 43

Lisää tiedoston avaamisesta Mahdollisia käsittelytapoja: r lukeminen w kirjoittaminen, vanha sisältö häviää a kirjoittaminen, kirjoitetaan vanhan sisällön perään. Tiedoston avaaminen lukemista varten aiheuttaa poikkeuksen, jos tiedostoa ei ole tai sitä ei pystytä jostain muusta syystä lukemaan. Myös moni muu virhe tiedoston lukemisessa tai siihen kirjoittamisessa voi aiheuttaa poikkeuksen. Poikkeuksen tyyppi vaihtelee sen mukaan, millainen virhe on sattunut, mutta näiden eri tyyppien ylätyyppinä on OSError-tyyppinen poikkeus. Se on syytä käsitellä try except-rakenteella aina, kun luetaan tiedostosta tai kirjoitetaan tiedostoon. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 24 / 43

Rivin lukeminen ja tiedoston sulkeminen Jos muuttuja tiedostomuuttuja viittaa lukemista varten avattuun tiedostoon, niin siitä voi lukea rivin kerrallaan metodin readline avulla seuraavasti: luettu_rivi = tiedostomuuttuja.readline() Luettu rivi sisältää myös sen lopussa olevan rivinvaihtomerkin. Seuraava readline-käsky lukee tiedoston seuraavan rivin jne. Jos tiedosto on jo luettu loppuun ja kutsutaan readline-metodia, se palauttaa arvona tyhjän merkkijonon "" Kun tiedoston lukeminen päättyy, tiedosto pitää sulkea close-käskyllä: tiedostomuuttuja.close() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 25 / 43

Esimerkkiohjelma tiedoston lukemisesta def main(): try: lahtotiedosto = open("tekstia.txt", "r") rivi = lahtotiedosto.readline() while rivi!= "": print(rivi) rivi = lahtotiedosto.readline() lahtotiedosto.close() except OSError: print("virhe tiedoston lukemisessa. Ohjelma paattyy.") main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 26 / 43

Edellisen kalvon esimerkkiohjelma lukee tiedostosta rivin kerrallaan ja tulostaa sen käyttäjälle. Ohjelma tulostaa kuitenkin ylimääräisen tyhjän rivin jokaisen rivin jälkeen. Tämä johtuu siitä, että tiedostoista luettujen rivien lopussa on rivinvaihtomerkki. Jos ylimääräiset rivinvaihdot halutaan välttää, pitää rivinvaihtomerkki poistaa tiedoston lopusta ennen rivin tulostamista. Yksi tapa poistaa rivinvaihtomerkki on käyttää metodia rstrip. Se poistaa kuitenkin myös muut tyhjät merkit rivin lopusta. Seuraava esimerkkiohjelma käyttää tätä tapaa. Se myös kysyy luettavan tiedoston nimen käyttäjältä. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 27 / 43

Parannettu versio tiedostonlukuohjelmasta def main(): nimi = input("anna luettavan tiedoston nimi: ") try: lahtotiedosto = open(nimi, "r") rivi = lahtotiedosto.readline() while rivi!= "": rivi = rivi.rstrip() print(rivi) rivi = lahtotiedosto.readline() lahtotiedosto.close() except OSError: print("virhe tiedoston", nimi, "lukemisessa. Ohjelma paattyy.") main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 28 / 43

Tiedoston rivien lukeminen for-käskyllä Jos ohjelman on luettava kaikki tiedoston rivit, on usein helpointa käydä ne läpi for-käskyn avulla. Käskyn yleinen muoto on for rivi in lahtotiedosto: tee jotain riville rivi Käskyyn ei tarvitse kirjoittaa lainkaan rivin tiedostosta lukevaa käskyä (esim. readline), vaan for-käsky pitää huolen siitä, että rivit luetaan tiedostosta tarvittaessa. Seuraavan kalvon esimerkkiohjelma lukee rivit käyttäjän antamasta tiedostosta ja tulostaa ne kuvaruudulle for-käskyn avulla. Tärkeää: jos ohjelmassa luetaan tiedoston rivit for-käskyn avulla, ei samassa ohjelmassa pidä käyttää readline-metodia. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 29 / 43

Esimerkki tiedoston lukemisesta for-käskyllä def main(): nimi = input("anna luettavan tiedoston nimi: ") try: lahtotiedosto = open(nimi, "r") for rivi in lahtotiedosto: rivi = rivi.rstrip() print(rivi) lahtotiedosto.close() except OSError: print("virhe tiedoston", nimi, "lukemisessa. Ohjelma paattyy.") main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 30 / 43

Lukujen lukeminen tiedostosta Kun tiedostosta luetaan lukuja, pitää luetut rivit muuttaa tyypinmuunnoksella oikeantyyppiksiksi. Jos riviä ei voida muuttaa luvuksi, aiheutuu ValueError, joka on syytä käsitellä. Jos samalla rivillä on useita lukuja, pitää rivi ensin jakaa. Tyypinmuunnos tehdään vasta jaon tuloksena syntyneille luvuille. Seuraava esimerkkiohjelma lukee tiedostosta lämpötiloja ja laskee niiden keskiarvon. Kukin lämpötila on annettu omalla rivillään. Jos tiedostossa on virhe, ohjelma ilmoittaa virheestä ja lopettaa toimintansa. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 31 / 43

Desimaalilukuja tiedostosta, koodi def main(): nimi = input("mista tiedostosta lampotilat luetaan: ") summa = 0.0 lkm = 0 try: lampotiedosto = open(nimi, "r") for rivi in lampotiedosto: rivi = rivi.rstrip() lampotila = float(rivi) summa += lampotila lkm += 1 lampotiedosto.close() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 32 / 43

Desimaalilukuja tiedostosta, koodi jatkuu if lkm == 0: print("tiedostossa ei ollut yhtaan lampotilaa.") else: keskiarvo = summa / lkm print("lampotilojen keskiarvo on", keskiarvo) except OSError: print("virhe tiedoston", nimi, "lukemisessa. Ohjelma paattyy.") except ValueError: print("virheellinen rivi tiedostossa", nimi, "- ohjelma paattyy.") main() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 33 / 43

Lukujen lukeminen csv-tiedostosta Oletetaan, että edellisen kalvon ohjelmalla luetaan tiedostosta, jossa on jokaisella rivillä lämpötilan lisäksi päivämäärä, jolloin lämpötila on mitattu. Rivillä on ensin päivämäärä, sitten pilkku ja sen jälkeen lämpötila. Tällaisia csv-tiedostoja voi tehdä helposti esimerkiksi taulukkolaskentaohjelmilla (csv = comma-separated values). CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 34 / 43

Lukeminen csv-tiedostosta, koodi def main(): nimi = input("mista tiedostosta lampotilat luetaan: ") summa = 0.0 lkm = 0 try: lampotiedosto = open(nimi, "r") for rivi in lampotiedosto: rivi = rivi.rstrip() osat = rivi.split(",") if len(osat) == 2: lampotila = float(osat[1]) summa += lampotila lkm += 1 else: print("virheellinen rivi", rivi) lampotiedosto.close() CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 35 / 43

Ohjelma jatkuu main() if lkm == 0: print("tiedostossa ei ollut yhtaan lampotilaa.") else: keskiarvo = summa / lkm print("lampotilojen keskiarvo on", keskiarvo) except OSError: print("virhe tiedoston", nimi, "lukemisessa. Ohjelma paattyy.") except ValueError: print("virheellinen rivi tiedostossa", nimi, "- ohjelma paattyy.") CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 36 / 43

Tiedostoon kirjoittaminen: tiedoston avaaminen Tiedosto on avattava myös silloin, kun tiedostoon halutaan kirjoittaa. Käsitettelytapa on kuitenkin eri kuin tiedostoon kirjoitettaessa. tiedosto = open("teksti.txt","w") Tai tiedosto = open("teksti.txt","a") Käsittelytapojen ero: "w" kirjoittaa olemassaolevan tiedoston päälle (vanha sisältö häviää kokonaan), "a" kirjoittaa olemassaolevan tiedoston loppuun. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 37 / 43

Tiedostoon kirjoittaminen: rivin kirjoittaminen Tiedostoon voi tulostaa rivin write-metodilla. Se ei lisää rivinvaihtomerkkiä, vaan merkki on lisättävä kirjoitettavaan riviin. tiedosto.write("kirjoitettava rivi\n") Metodilla write voi tulostaa tiedostoon vain merkkijonoja. Esimerkiksi luvut pitää muuttaa ennen tulostamista merkkijonoiksi joko str-tyypinmuunnoksella tai käyttämällä tulostuksen muotoilua. kanta = 3.5 ekspo = 5 tulos = kanta ** ekspo tiedosto.write("{:.2f} potenssiin {:d} on {:.2f}\n".\ format(kanta, ekspo, tulos)) tiedosto.write(str(kanta) + " potenssiin " + \ str(ekspo) + " on " + str(tulos) + "\n") CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 38 / 43

Lisää tiedostoon kirjoittamisesta Myös tiedostoon kirjoittaessa pitää huolehtia virheiden käsittelystä samalla tavalla kuin tiedostosta luettaessa. Tiedoston sulkeminen on erityisen tärkeää silloin, kun kirjoitetaan tiedostoon. Katso ohjelmaesimerkkejä opetusmonisteesta. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 39 / 43

Ohjelmointiprojektin vaiheet 1. Määrittely Mitä ohjelma täsmällisesti ottaen tekee? Miten ohjelma kommunikoi käyttäjän kanssa? 2. Ohjelman suunnittelu (ohjelman rakenne ja ohjelman käyttämät tietorakenteet) Mitä funktioita (tai muita laajempia osia) ohjelmassa on? Mitä parametreja funktioilla on ja millaisia arvoja ne palauttavat? Mitä tietorakenteita (esim. listat, sanakirja jne) ohjelma käyttää? 3. Koodaus ohjelmointikielelle 4. Testaus (rinnakkain koodauksen kanssa) Testataan aluksi mahdollisimman pieniä osia (esim. yksittäisiä funktioita) kerrallaan, sitten laajempia kokonaisuuksia. 5. Käyttöönotto 6. Ylläpito Mahdollisten virheiden korjaus ja uusien omainaisuuksien lisääminen. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 40 / 43

Suunnittelu: mitä funktioita ja tietorakenteita ohjelmaan tulee? Kirjoita kuvaus ohjelman toiminnasta. Millaisista osatehtävistä ohjelman toiminta koostuu? Yleensä kutakin osatehtävää varten kirjoitetaan oma funktio. Aloita ohjelman tärkeimmistä osatehtävistä ja tarkenna sitten näiden toimintaa. Tällöin saattaa osoittautua tarpeelliseksi määritellä uusia osatehtäviä. Lisäksi on mietittävä, mitä tietoja funktio tarvitsee muulta ohjelmalta (parametrit) ja mitä tietoja se tuottaa muulle ohjelmalle (paluuarvot). Huomaa: tämä lähestymistapa ei sovi olio-ohjelmointiin. Tietorakenteet: Mieti, mitä tietoa ohjelma joutuu käsittelemään ja missä muodossa se kannattaa tallentaa. Tarvitaanko esim. merkkijonoja, listoja. sanakirjoja tms. yksittäisiä lukuja esittävien muuttujien lisäksi? CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 41 / 43

Lisää funktioiden suunnittelusta Tavoitteena on se, että funktio näyttää ulkopuolelle mustalta laatikolta: funktion käyttäjän tarvitsee tietää, mitä lähtötietoja funktio tarvitsee ja mitä se palauttaa, mutta ei funktion toiminnan yksityiskohtia. Funktion sisäinen toteutus ei saa vaikuttaa muuhun ohjelmaan. Funktioiden pituus pitää suunnitella sopivaksi. Yhden rivin mittaisista käskyistä kannattaa yleensä tehdä funktioita vain silloin, jos ne laskevat jonkin matemaattisen lausekkeen arvon tai tarkastavat monimutkaisemman ehdon totuusarvon. Toisaalta liian pitkät funktiot vaikeuttavat ohjelman rakenteen ymmärtämistä. Funktion pitäisi olla loogisesti yhtenäinen kokonaisuus. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 42 / 43

Esimerkki: valikkopohjainen puhelinluettelo Puhelinluettelo-ohjelma, joka säilyttää nimi- ja puhelinnumerotiedot tiedostossa. Käyttäjälle tulostetaan valikko, joka kertoo mahdolliset toimenpiteet. Käyttäjä valitsee valikosta aina yhden toimenpiteen kerrallaan, kunnes hän lopettaa ohjelman suorituksen. Kirjoitetaan oma funktio jokaista eri toimenpidettä (tietojen lukeminen tiedostosta numeron kysyminen, numeron lisäys, numeron muuttaminen, numeron poisto, tietojen tallentaminen tiedostoon) varten. Lisäksi kirjoitetaan oma funktio, joka tulostaa käyttäjälle valikon ja pyytää käyttäjän valinnan. Se palauttaa käyttäjän valinnan. Käytettävä puhelinluettelo välitetään sitä käsitteleville funktioille parametrina. Pääohjelma sisältää toistokäskyn, joka kutsuu aina valikon tulostavaa funktiota ja sen jälkeen valitsee suoritettavan funktion käyttäjän valinnan mukaan. CSE-A1111 Ohjelmoinnin peruskurssi Y1 19.10.2016 43 / 43