Ohjelmoinnin peruskurssi Y1

Samankaltaiset tiedostot
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 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 peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

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 perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

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 perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

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

Ohjelmoinnin perusteet Y Python

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

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Java-kielen perusteet

TT00AA Ohjelmoinnin jatko (TT10S1ECD)

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

Ohjelmoinnin peruskurssi Y1

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet, syksy 2006

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

Tutoriaaliläsnäoloista

Harjoitustyö: virtuaalikone

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Python-ohjelmointi Harjoitus 2

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Luento 5. Timo Savola. 28. huhtikuuta 2006

Java-kielen perusteet

Harjoitus 5 (viikko 48)

14. Hyvä ohjelmointitapa 14.1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

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

Ohjelmoinnin perusteet Y Python

Transkriptio:

Ohjelmoinnin peruskurssi Y1 CS-A1111 18.10.2017 CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 1 / 44

Mahdollisuus antaa luentopalautetta Luennon aikana voit kirjoittaa kommentteja ja kysymyksiä sivulle presemo.aalto.fi/opey1luento7 Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute. Tätä kautta on mahdollisuus antaa nimettömänä palautetta luennosta. Myös harjoitustehtävistä voi antaa palautetta palautuksen yhteydessä, mutta tämä palaute ei ole nimetöntä. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 2 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 3 / 44

Hyvä ohjelmointityyli Miksi ihmisen pitää pystyä lukemaan valmista ohjelmakoodia? virheiden korjaus ohjelman laajentaminen tai muuttaminen pohja uutta ohjelmaa tehdessä. Hyvä ohjelmointityyli auttaa ohjelman lukemisessa ja ymmärtämisessä. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 4 / 44

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 CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 5 / 44

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ää? CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 6 / 44

Hyvään ohjelmointityyliin kuuluvia asioita Ohjelman järkevä jako funktioihin. (Katso luentokalvojen loppuosa.) Kuvaavat nimet muuttujilla, parametreilla, funktioilla jne. Järkevä kommentointi. Sisennykset. Tyhjien tilan järkevä käyttö. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 7 / 44

Nimistä Muuttujat, parametrit ja funktiot on syytä nimetä niin, että ne kuvaavat mahdollisimman hyvin muuttujan tms. tarkoitusta. Esimerkiksi korkeus vs. 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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 8 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 9 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 10 / 44

Poikkeukset Ohjelmaa suoritettaessa voidaan törmätä virhetilanteisiin. Osa virheistä johtuu ohjelmointivirheistä, mutta osaan ohjelmoija ei voi vaikuttaa (esim. väärän tyyppinen syöte). 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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 11 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 12 / 44

Virheelliseen syötteeseen varautuminen Jos käyttäjän antama syöte on väärää tyyppiä, aiheutuu ValueError-tyyppinen poikkeus, kun yritetään esim. 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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 13 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 14 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 15 / 44

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: naulat pitää olla kokonaisluku.") print("yrita uudelleen!") main() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 16 / 44

Välitehtävä 1 Miksi naulojen pyytämistä uudelleen ei sijoitettu except-osan sisään? Vastaa sivulla presemo.aalto.fi/opey1luento7 CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 17 / 44

Apufunktio luvun lukemiseen Jos samassa ohjelmassa luetaan kokonaislukuja useassa kohdassa, kannattaa yleensä kirjoittaa apufunktio kokonaisluvun lukemiseen. Funktio lukee ja palauttaa kokonaisluvun. Se pyytää käyttäjältä uutta kokonaislukua niin kauan, että saadaan kelvollinen kokonaisluku. Vastaavat apufunktiot voidaan kirjoittaa myös muuntyyppisten arvojen lukemiseen. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 18 / 44

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 CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 19 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 20 / 44

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ä (ei käsitellä tällä kurssilla). CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 21 / 44

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 (esim. mittaussarjan parametrit). 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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 22 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 23 / 44

Tiedoston avaaminen Tiedostoja käsitellessä on kerrottava, mitä fyysistä tiedostoa ohjelman muuttuja vastaa. 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 sen pitää sisältää polku tiedoston hakemistoon. Toinen parametri kertoo tiedoston käsittelytavan. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 24 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 25 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 26 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 27 / 44

Rivinvaihtomerkistä Edellisen kalvon ohjelma tulostaa 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 voidaan välttää poistamalla rivinvaihtomerkki rivin lopusta ennen tulostamista. Yksi tapa poistaa rivinvaihtomerkki on käyttää metodia rstrip. Se poistaa kuitenkin myös muut tyhjät merkit rivin lopusta. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 28 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 29 / 44

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 rivimuuttuja in lahtotiedosto: tee jotain riville rivimuuttuja Käskyyn ei tarvitse kirjoittaa lainkaan rivin tiedostosta lukevaa käskyä (esim. readline). Tärkeää: jos ohjelmassa luetaan tiedoston rivit for-käskyn avulla, ei samassa ohjelmassa pidä käyttää readline-metodia. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 30 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 31 / 44

Lukujen lukeminen tiedostosta Python-tulkki palauttaa tiedostosta luetut rivit aina merkkijonoina. Jos tiedostossa on 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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 32 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 33 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 34 / 44

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). CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 35 / 44

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() CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 36 / 44

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.") CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 37 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 38 / 44

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") CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 39 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 40 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 41 / 44

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? CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 42 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 43 / 44

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. CS-A1111 Ohjelmoinnin peruskurssi Y1 18.10.2017 44 / 44