• Ei tuloksia

Tulostuksen muotoilusta

3.2 Toistokäsky

3.2.5 Tulostuksen muotoilusta

Ennen kuin jatketaan toistokäskyistä ja niitä käyttävistä esimerkeistä, katsotaan vähän sitä, miten ohjelmoija voi vaikuttaa ohjelman tulostuksen muotoiluun.

Tähänastissa esimerkeissä desimaaliluvut on tulostettu sillä tarkkuudella, mitä Python-tulkki on oletuksena käyttänyt. Käytännössä tämä on tarkoittanut sitä, että tulostustetuissa luvuissa on usein ollut tarpeettoman monta desimaalia. Tulostukses-ta tulisi selvästi siistimpi, jos desimaalipisteen jälkeen tulevien numeroiden määrää rajoitettaisiin. Tämä voidaan tehdä tulostuksen muotoilun avulla.

Muotoilun avulla voidaan myös määritellä, miten leveään kenttään kokonaisluvut ja merkkijonot tulostetaan. Kentällä tarkoitetaan sitä aluetta, joka tulostuksessa käytetään jonkin asian esittämiseen. Jos kentän leveydeksi on määritelty esimerkik-si 8, niin luvulle varataan tulostuksessa 8 merkin levyinen alue, vaikka itse luku veisikin vain 2 merkkiä. Joko ennen lukua tai sen jälkeen kirjoitetaan ylimääräisiä välilyöntejä. (Jos luku on niin suuri, että se ei mahdu sille varattuun kenttään, osaa luvusta ei kuitenkaan jätetä tulostamatta, vaan luvun annetaan käyttää enemmän tilaa kuin mitä sille on muotoilussa määrätty.) Kentän leveyden määrittelyä tar-vitaan esimerkiksi silloin, kun halutaan tulostaa useita arvoja peräkkäisille riveille niin, että vastaavat arvot tulevat rivillä aina samaan kohtaan.

Kun halutaan vaikuttaaprint-käskyllä tulostettavan rivin muotoiluun, kirjoitetaan ensin lainausmerkkien sisälle tulostettavalle riville tuleva vakioteksti. Tämän teks-tin keskelle lisätäänmuotoilukoodejaniihin paikkoihin, joihin tulostuksessa halutaan tulevan jonkin muuttujan arvo. Muotoilukoodi osoittaa, mihin paikkaan muuttujan arvo tulee tulostettavassa tekstissä, ja lisäksi se kertoo, miten tulostettava arvo muo-toillaan, esimerkiksi kuinka leveä kenttä arvolle varataan ja montako desimaalia de-simaaliluvusta tulostetaan. Lainausmerkeissä olevan tekstin jälkeen kirjoitetaan %-merkki, ja sen jälkeen luetellaan sulkujen sisällä niiden muuttujien nimet, joiden arvot rivillä halutaan tulostaa. Riviä tulostettaessa muotoilukoodit korvataan luet-telossa olevien muuttujien arvoilla niin, että ensimmäinen muotoilukoodi korvataan listan ensimmäisen muuttujan arvolla, toinen muotoilukoodi listan toisen muuttujan arvolla jne.

Muotoilukoodi alkaa aina%-merkillä. Sen jälkeen tulee arvolle varattavan kentän le-veys kokonaislukuna. Lele-veys voidaan jättää myös pois, jolloin arvolle varataan sen tarvitsema tila (esimerkiksi 4-numeroiselle kokonaisluvulle 4 merkin levyinen kent-tä). Desimaalilukuja koskevissa muotoilukoodeissa tulee seuraavaksi piste ja tämän jälkeen toinen luku, joka kertoo, kuinka monta numeroa esitetään desimaalipisteen jälkeen. Viimeisenä muotoilukoodissa onmäärittelykirjain, joka kertoo, minkä tyyp-pinen arvo kohtaan tulee, esimerkiksi d, kun on kysymyksessä kokonaisluku, s, jos kysymyksessä on merkkijono jaf,etaig, jos kysymyksessä on desimaaliluku. (Muo-toilukoodissa voi olla myös muita osia tai muita kirjaimia erilaisia tyyppejä varten.

Niitä ei esitetä tässä sen tarkemmin, mutta kiinnostunut lukija voi tutkia asiaa tar-kemmin Pythonin omasta dokumentaatiosta.)

Seuraavaksi joitakin esimerkkejä muotoilukoodien käytöstä ja niiden selityksiä. Esi-merkit eivät ole kokonaisia ohjelmia, vaan Python-tulkille on annettu yksittäisiä käskyjä kappaleessa 2.1 kuvatulla tavalla.

>>> kertoja = 5

>>> kerrottava = 8

>>> tulos = kertoja * kerrottava

>>> print "%3d kertaa %3d on %6d" % (kertoja, kerrottava, tulos) 5 kertaa 8 on 40

Tässä on kerrottu, että tulostettavaan tekstiin tulee ensin kokonaislukuarvo, jolle varataan 3 merkin levyinen kenttä, sen jälkeen teksti "kertaa ", sitten kokonaislu-kuarvo, jolle varataan 3 merkin levyinen kenttä, sen jälkeen teksti "on "ja lopuksi kokonaislukuarvo, jolle varataan kuuden merkin levyinen kenttä. Tulostuksessa en-simmäisen muotoilukoodin paikalle sijoitetaan muuttujankertojaarvo, toisen koo-din paikalle muuttujankerrottava arvo ja kolmannen koodin paikalle muuttujan tulosarvo.

>>> etunimi1 = "Matti"

>>> sukunimi1 = "Virtanen"

>>> palkka1 = 2800

>>> etunimi2 = "Tiina-Maija"

>>> sukunimi2 = "Pomo"

>>> palkka2 = 11000

>>> print "%15s %15s %5d euroa" % (sukunimi1, etunimi1, palkka1)

Virtanen Matti 2800 euroa

>>> print "%15s %15s %5d euroa" % (sukunimi2, etunimi2, palkka2) Pomo Tiina-Maija 11000 euroa

Tässä on muotoilukoodien avulla määritelty merkkijonojen ja kokonaisluvun ken-tän leveys. Näin peräkkäin tulostettavilla riveillä sarakkeet menevät päällekkäin, vaikka merkkijonojen pituus ja lukujen suuruus vaihtelevat. Oletuksen mukaisesti sarakkeet on tasattu niin, että niiden oikea reuna on samassa kohdassa. Jos halu-taan säätää tulostus kentän vasempaan reunaan, lisätään muotoilukoodiin%-merkin jälkeen merkki-, kuten alla on tehty etunimiä ja sukunimiä tulostettaessa:

>>> print "%-15s %-15s %5d euroa" % (sukunimi1, etunimi1, palkka1)

Virtanen Matti 2800 euroa

>>> print "%-15s %-15s %5d euroa" % (sukunimi2, etunimi2, palkka2)

Pomo Tiina-Maija 11000 euroa

Seuraavaksi esimerkki desimaalilukujen tulostamisesta. Ensimmäisessä esimerkissä luvut on tulostettu määrittelykirjaimenfavulla. Esimerkissä tulostuskäskyn ensim-mäisen rivin lopussa esiintyy merkki\. Tämä merkki kertoo, että käsky jatkuu seu-raavalle riville, koska se ei mahtunut kokonaan yhdelle riville. Seuraavan rivin alussa oleva...ei ole ohjelmoijan kirjoitusta, vaan Python-tulkki lisää sen automaattisesti seuraavan rivin alkuun silloin, kun edellistä riviä jatketaan.

>>> pituus = 4.5678945

>>> leveys = 12.84593

>>> pinta_ala = pituus * leveys

>>> print "Pituus on %5.2f m, leveys %5.2f m, pinta-ala %8.2f m2" % \ ... (pituus, leveys, pinta_ala)

Pituus on 4.57 m, leveys 12.85 m, pinta-ala 58.68 m2

Jos muotoilukoodissa ei anneta kentän leveyttä, luvulle varataan tarpeellinen määrä tilaa. Muotoilukoodilla voi tällöinkin vaikuttaa esimerkiksi siihen, kuinka monta desimaalia desimaaliluvusta tulostetaan:

>>> print "Pituus on %.2f m, leveys %.2f m, pinta-ala %.2f m2" % \ ... (pituus, leveys, pinta_ala)

Pituus on 4.57 m, leveys 12.85 m, pinta-ala 58.68 m2

Seuraavassa esimerkissä samat luvut on tulostettu määrittelykirjaimeneavulla. Täl-löin desimaaliluku esitetään niin, että desimaalipisteen edessä on vain yksi numero ja lisäksi kerrotaan, millä kymmenen eksponentilla luku pitää kertoa. Esimerkiksi 5.87e+01 tarkoittaa 5.87 ·101. Kaksi ensimmäistä lukua eivät enää mahdu niille varattuun kenttään, mutta kuten esimerkistä nähdään, kentän leveyttä kasvatetaan tarvittaessa muotoilukoodissa annettua leveyttä suuremmaksi.

>>> print "Pituus on %5.2e m, leveys %5.2e m, pinta-ala %8.2e m2" % \ ... (pituus, leveys, pinta_ala)

Pituus on 4.57e+00 m, leveys 1.28e+01 m, pinta-ala 5.87e+01 m2

Jos ei ole tietoa tulostettavan desimaaliluvun suuruusluokasta, voi käyttää mää-rittelykirjaintag. Tällöin luku tulostetaan ilman eksponenttiosaa, jos näin voidaan siististi tehdä ja eksponenttiosan kanssa, jos luku on itseisarvoltaan hyvin pieni tai suuri. Määrittelykirjaintag käytettäessä pisteen jälkeen tuleva luku ei kuitenkaan enää määrää desimaalipisteen jälkeen tulevien lukujen lukumäärää, vaan tulostuk-sessa esiintyvien merkitsevien numeroiden lukumäärää.

>>> pieni_luku = 1.2308e01

>>> suuri_luku = 14.5e20

>>> tulo = pieni_luku * suuri_luku

>>> print "Kun kerrotaan %5.4g ja %8.4g, saadaan %10.4g" % \ ... (pieni_luku, suuri_luku, tulo)

Kun kerrotaan 12.31 ja 1.45e+21, saadaan 1.785e+22