Arcade-pelien ohjelmointi
Pythonilla ja PygamellaChapter 20: Tekstien muotoilukoodit
Alla on taulukoituna tekstin muotoilukoodit. Yksityiskohtainen selitys koodeille seuraa alla.
Number | Format | Output | Description |
---|---|---|---|
3.1415926 | {:.2f} | 3.14 | 2 decimal places |
3.1415926 | {:+.2f} | +3.14 | 2 decimal places with sign |
-1 | {:+.2f} | -1.00 | 2 decimal places with sign |
3.1415926 | {:.0f} | 3 | No decimal places (will round) |
5 | {:0>2d} | 05 | Pad with zeros on the left |
1000000 | {:,} | 1,000,000 | Number format with comma separator |
0.25 | {:.2%} | 25.00% | Format percentage |
1000000000 | {:.2e} | 1.00e+09 | Exponent notation |
11 | {:>10d} | 11 | Right aligned |
11 | {:<10d} | 11 | Left aligned |
11 | {:^10d} | 11 | Center aligned |
20.1 Kokonaisluvut
Kopioi ja aja seuraava ohjelma, joka tulostaa useita satunnaislukuja.
import random for i in range(10): x = random.randrange(20) print(x)
Tulostuksessa luvut tasataan vasemmalle ja ulkoasu ei ole kovin hyvä:
16 13 2 0 10 3 18 1 14 5
Tulostus saadaan näyttämään paremmalta käyttämällä muotoilukoodia ja tasaamalla luvut oikealle. Ensimmäiseksi käytämme format komentoa merkkijonossa, ks. alla:
import random for i in range(10): x = random.randrange(20) print("{}".format(x) )
Tämä on askel parempaan, mutta ei kuitenkaan vielä valmis. Katso, miten merkkijono päättyy .format(x)kanssa. Kaikki merkkijonot ovat itse asiassa luokan String olioita. Tässä luokassa on kutsuttavia metodeja, joista yksi on format.
format funktio ei tulosta aaltosulkeita {} vaan ne korvataan arvolla x. Alla koodi näyttää kuitenkin vielä samalta kuin aiemmin.
7 15 4 12 3 8 7 15 12 8
Lukujen oikealle tasaamiseen tarvitaan aaltosulkeiden {} väliin lisää informaatiota:
import random for i in range(10): x = random.randrange(20) print("{:2}".format(x) )
Tulostus:
7 15 4 12 3 8 7 15 12 8
Nyt näyttää paremmalta. Luvut on tasattu oikealle, mutta mikä tämän sai aikaan? Luku :2 on lisättynä aaltosulkeisiin, mutta ei kuitenkaan aivan 'lonkalta'.
Tässä tarkempi selitys: Aaltosulkeilla { } kerromme tietokoneelle, että käytämme lukujen muotoilua. Kaksoispisteen : jälkeen suluissa on muotoiluinformaationa luku 2, joka määrittelee kentän leveyden kahden merkin kokoiseksi. Tämä varaa tulostukselle siis aina kahden merkin kokoisen kentän, vaikka tulostus olisikin yhden merkin kokoinen. Oletuksena tämä muotoilu tasaa luvut oikealle ja tekstin vasemmalle.
Eikä tässä tarvita kutsua str( ) funktioon luvun muuntamiseksi tekstiksi, joten sen voi hyvin jättää pois.
Miten suurempien lukujen kanssa toimitaan? Tehdään kokeeksi suurempia satunnaislukuja:
import random for i in range(10): x = random.randrange(100000) print("{:6}".format(x) )
Tämä saa aikaan kelvollisen tulostuksen oikealle tasattuna:
18394 72242 97508 21583 11508 76064 88756 77413 7930 81095
Jos tulostukseen haluttaisiin amerikkalaiseen tapaan tuhaterottimeksi pilkku, niin se on lisättynä alla olevassa koodissa:
import random for i in range(10): x = random.randrange(100000) print("{:6,}".format(x) )
The output:
65,732 30,248 13,802 17,177 3,584 7,598 21,672 82,900 72,838 48,557
Muotoilukoodiin lisättiin pilkku kentän leveyden määrityksen jälkeen. Se kirjoitetaan kenttäleveyden jälkeen, ei ennen. Pilkkumerkki luetaan mukaan kentän leveyteen. Esimerkiksi, 1,024 on leveydeltään 5, ei 4.
Voimme tulostaa moninaisia arvoja ja yhdistää niitä tekstiin. Kopioi ja aja alla oleva koodi.
x = 5 y = 66 z = 777 print("A - '{}' B - '{}' C - '{}'".format(x, y, z))
Ohjelma korvaa luvut aaltosulkeiden paikalle format-funktion parametreilla x, y ja z:
A - '5' B - '66' C - '777'
Jos aaltosuljepareja on kolme, ohjelma odottaa kolmea arvoa listattuna format funktion parametreiksi. Ensinnä annettu korvaa ensimmäisen suljeparin.
Toisinaan haluamme tulostaa saman arvon useaan kertaan tai eri järjestyksessä. Järjestys voidaan määrittää aaltosulkeiden sisään kirjoitettavalla järjestysnumerolla.
x = 5 y = 66 z = 777 print("C - '{2}' A - '{0}' B - '{1}' C again - '{2}'".format(x, y, z))
Yllä olevassa esimerkissä järjestysluvut on kirjoitettu aaltosulkeiden sisään siinä järjestyksessä, kun ne 'poimitaan' format funktion parametrilistasta. Parametrit ovat listassa järjestyksessä alkaen 0:sta, joten x on siis paikassa 0.
Muotoilua voidaan tarkentaa vielä kaksoispisteen jälkeen. Esimerkiksi:
x = 5 y = 66 z = 777 print("C - '{2:4}' A - '{0:4}' B - '{1:4}' C again - '{2:4}'".format(x, y, z))
Tässä humaamme, että kukin muuttuja tulostetaan numeroidussa järjestyksessä ja kaksoispisteen jälkeen annetaan tulostukseen varatun kentän leveys. Luku tasataan kentän oikeaan reunaan.
C - ' 777' A - ' 5' B - ' 66' C again - ' 777'
20.2 Merkkijonot
KAtsotaan seuraavaksi, miten merkkijonot muotoillaan.
Seuraava lista näyttää kamalalta.
my_fruit = ["Apples","Oranges","Grapes","Pears"] my_calories = [4, 300, 70, 30] for i in range(4): print(my_fruit[i], "are", my_calories[i], "calories.")
The output:
Apples are 4 calories. Oranges are 300 calories. Grapes are 70 calories. Pears are 30 calories.
Muotoillaanpa sitä format komennolla. Huomaa, kuinka samalle riville voidaan tulostaa lisättyä tekstiä samalle riville.
my_fruit = ["Apples", "Oranges", "Grapes", "Pears"] my_calories = [4, 300, 70, 30] for i in range(4): print("{:7} are {:3} calories.".format(my_fruit[i],my_calories[i]) )
Tulostus on:
Apples are 4 calories. Oranges are 300 calories. Grapes are 70 calories. Pears are 30 calories.
Nyt tulostus näyttää kelvolliselta. Mutta, jos emme haluakaan tasata lukuja oikealle. Tässä voidaan käyttää < ja > merkkejä seuraavalla tavalla:
my_fruit = ["Apples", "Oranges", "Grapes", "Pears"] my_calories = [4, 300, 70, 30] for i in range(4): print("{:>7} are {:<3} calories.".format(my_fruit[i],my_calories[i]) )
Tulostaa:
Apples are 4 calories. Oranges are 300 calories. Grapes are 70 calories. Pears are 30 calories.
20.3 Alkunollat
Tämä ohjelma saa aikaan virheellisen tulostuksen:
for hours in range(1,13): for minutes in range(0,60): print("Time {}:{}".format(hours, minutes))
Ei kovin hyvin muotoiltu tulostus:
Time 8:56 Time 8:57 Time 8:58 Time 8:59 Time 9:0 Time 9:1 Time 9:2
Lisätään tulostukseen etunolla, jolloin saadaan esitettyä kellonaikoja. Kirjoittamalla pelkän 2:en sijasta kirjoitetaankin 02. Tämä täyttää kentän tyhjän merkin sijasta nollalla.
for hours in range(1,13): for minutes in range(0,60): print("Time {:02}:{:02}".format(hours, minutes))
Tulostaa:
Time 08:56 Time 08:57 Time 08:58 Time 08:59 Time 09:00 Time 09:01 Time 09:02
20.4 Liukuluvut, desimaaliluvut
Myös desimaalilukuja voidaan muotoilla. Tutki seuraavan koodina aikaan saama tulostus:
x = 0.1 y = 123.456789 print("{:.1} {:.1}".format(x,y) ) print("{:.2} {:.2}".format(x,y) ) print("{:.3} {:.3}".format(x,y) ) print("{:.4} {:.4}".format(x,y) ) print("{:.5} {:.5}".format(x,y) ) print("{:.6} {:.6}".format(x,y) ) print() print("{:.1f} {:.1f}".format(x,y) ) print("{:.2f} {:.2f}".format(x,y) ) print("{:.3f} {:.3f}".format(x,y) ) print("{:.4f} {:.4f}".format(x,y) ) print("{:.5f} {:.5f}".format(x,y) ) print("{:.6f} {:.6f}".format(x,y) )
Ja tässä on koodin tulostus:
0.1 1e+02 0.1 1.2e+02 0.1 1.23e+02 0.1 123.5 0.1 123.46 0.1 123.457 0.1 123.5 0.10 123.46 0.100 123.457 0.1000 123.4568 0.10000 123.45679 0.100000 123.456789
Muotoilu .2 tarkoittaa lukujen esittämistä kahden numeron tarkkuudella. Valitettavasti tämä johtaa siihen, että luku 123, jossa on kolme merkitsevää numeroa, pyöristetään kahden numeron tarkkuuteen ja esitetään tieteellisessä muodossa: 1.2e+02.
Muotoilulla .2f (huomaa f) saadaan aikaiseksi tulostus kahden desimaalin tarkkudella. Joten luku 1 näytetään 1.00 ja luku 1.5555 näytetään 1.56.
Muotoilukoodiin voidaan asettaa myös kentän leveys:
x = 0.1 y = 123.456789 print("'{:10.1}' '{:10.1}'".format(x,y) ) print("'{:10.2}' '{:10.2}'".format(x,y) ) print("'{:10.3}' '{:10.3}'".format(x,y) ) print("'{:10.4}' '{:10.4}'".format(x,y) ) print("'{:10.5}' '{:10.5}'".format(x,y) ) print("'{:10.6}' '{:10.6}'".format(x,y) ) print() print("'{:10.1f}' '{:10.1f}'".format(x,y) ) print("'{:10.2f}' '{:10.2f}'".format(x,y) ) print("'{:10.3f}' '{:10.3f}'".format(x,y) ) print("'{:10.4f}' '{:10.4f}'".format(x,y) ) print("'{:10.5f}' '{:10.5f}'".format(x,y) ) print("'{:10.6f}' '{:10.6f}'".format(x,y) )
Muotoilu 10.2f ei aseta 10 merkin leveyttä ennen desimaalipistettä ja kahta jälkeen. Se asettaa koko kentän leveydeksi 10, joten kentässä on ennen desimaalipistettä 7 merkin leveys, desimaalipiste vie yhden merkin tilan ja pisteen jälkeen tulostuu kaksi merkkiä.
' 0.1' ' 1e+02' ' 0.1' ' 1.2e+02' ' 0.1' ' 1.23e+02' ' 0.1' ' 123.5' ' 0.1' ' 123.46' ' 0.1' ' 123.457' ' 0.1' ' 123.5' ' 0.10' ' 123.46' ' 0.100' ' 123.457' ' 0.1000' ' 123.4568' ' 0.10000' ' 123.45679' ' 0.100000' '123.456789'
20.5 Tulostetaan valuuttasymbolit dollari ja sentti
Jos käytät tulostuksessa hintoja, niin tulosta luvut käyttäen muotoilua f. Katso esimerkki alla:
cost1 = 3.07 tax1 = cost1 * 0.06 total1 = cost1 + tax1 print("Cost: ${0:5.2f}".format(cost1) ) print("Tax: {0:5.2f}".format(tax1) ) print("------------") print("Total: ${0:5.2f}".format(total1) )
Muistathan! Helposti luullaan, että %5.2f tarkoittaisi viittä numeroa, desimaalipistettä ja kahta desimaalia. Mutta näin ei sii ole. Tässä kentän koko leveys on viisi, jossa ovat mukana desimaalipiste ja numerot ennen ja jälkeen. Tulostun on:
Cost: $ 3.07 Tax: 0.18 ------------ Total: $ 3.25
Hupsis! Tässä tuleekin nyt virhe, joka on varsin yleinen hintojen kanssa toimittaessa. Huomaatko virheen? Tarkastele seuraavaa koodia alla:
cost1 = 3.07 tax1 = cost1 * 0.06 total1 = cost1 + tax1 print("Cost: ${0:5.2f}".format(cost1) ) print("Tax: {0:5.2f}".format(tax1) ) print("------------") print("Total: ${0:5.2f}".format(total1) ) cost2 = 5.07 tax2 = cost2 * 0.06 total2 = cost2 + tax2 print() print("Cost: ${0:5.2f}".format(cost2) ) print("Tax: {0:5.2f}".format(tax2) ) print("------------") print("Total: ${0:5.2f}".format(total2) ) print() grand_total = total1 + total2 print("Grand total: ${0:5.2f}".format(grand_total) )
Tulostaa:
Cost: $ 3.07 Tax: 0.18 ------------ Total: $ 3.25 Cost: $ 5.07 Tax: 0.30 ------------ Total: $ 5.37 Grand total: $ 8.63
Huomaatko virheen lukujen pyöristyksessä? Loppusumman pitäisi olla $ 8.62, mutta eipä ole.
Tulostuksen muotoilu ei pyöristä lukuja, vaan ainoastaan tulostus näkyy virheellisenä. JOs asetamme tulostukseen kolmen desimaalin tarkkuuden, niin virheen syy alkaa paljastua:
Cost: $3.070 Tax: 0.184 ------------ Total: $3.254 Cost: $5.070 Tax: 0.304 ------------ Total: $5.374 Grand total: $8.628
Nytkään muotoilu ei vaikuta luvun pyöristykseen. Käytetään tässä round funktiota luvun pyöristämiseen. KAtso alla olevaa esimerkkiä:
cost1 = 3.07 tax1 = round(cost1 * 0.06, 2) total1 = cost1 + tax1 print("Cost: ${0:5.2f}".format(cost1) ) print("Tax: {0:5.2f}".format(tax1) ) print("------------") print("Total: ${0:5.2f}".format(total1) ) cost2 = 5.07 tax2 = round(cost2 * 0.06,2) total2 = cost2 + tax2 print() print("Cost: ${0:5.2f}".format(cost2) ) print("Tax: {0:5.2f}".format(tax2) ) print("------------") print("Total: ${0:5.2f}".format(total2) ) print() grand_total = total1 + total2 print("Grand total: ${0:5.2f}".format(grand_total) )
Output:
Cost: $ 3.07 Tax: 0.18 ------------ Total: $ 3.25 Cost: $ 5.07 Tax: 0.30 ------------ Total: $ 5.37 Grand total: $ 8.62
round funktiolla saadaan määrättyä, mihin tarkkuuteen desimaaliluku pyöristetään. Se palauttaa pyöristetyn arvon, mutta ei vaikuta alkuperäisen luvun arvoon. Katso alla:
x = 1234.5678 print(round(x, 2)) print(round(x, 1)) print(round(x, 0)) print(round(x, -1)) print(round(x, -2))
Katso alla, miten round() funktion arvo muuttuu, kun annetaan -2 parametriksi:
1234.57 1234.6 1235.0 1230.0 1200.0
20.6 Käyttö Pygamessa
Muotoilua ei tehdä ainoastaan print-komentoja varten tekstipohjaiseen tulostukseen. Sitä voidaan käyttää esimerkiksi timer.py Pygame-ikkunassa tulostettaviin teksteihin, kuten esimerkissä kellonaikojen tulostukseen:
# Use python string formatting to format in leading zeros output_string = "Time: {0:02}:{1:02}".format(minutes,seconds) # Blit to the screen text = font.render(output_string, True, BLACK) screen.blit(text, [250, 250])
20.7 Review
20.7.1 Short Answer Worksheet
Klikkaa tästä kappaleen kertaustehtäviin.
You are not logged in. Log in here and track your progress.
English version by Paul Vincent Craven
Spanish version by Antonio Rodríguez Verdugo
Russian version by Vladimir Slav
Turkish version by Güray Yildirim
Portuguese version by Armando Marques Sobrinho and Tati Carvalho
Dutch version by Frank Waegeman
Hungarian version by Nagy Attila
Finnish version by Jouko Järvenpää
French version by Franco Rossi
Korean version by Kim Zeung-Il
Chinese version by Kai Lin