Ügyességi játékok programozása
Pythonnal és Pygame-mel

Chapter 20: Formatálás

Itt található egy gyors-referencia tábla arról, hogy mikor használunk szöveg formatálást. A további részletekért, olvass tovább.

Szám Formázás Kimenet Leírás
3.1415926 {:.2f} 3.14 2 tizedes helyig
3.1415926 {:+.2f} +3.14 2 tizedes helyig jelöléssel
-1 {:+.2f} -1.00 2 tizedes helyig jelöléssel
3.1415926 {:.0f} 3 Nincs tizedes hely (kerekítve)
5 {:0>2d} 05 Nullával kezdődik az elején, balra
1000000 {:,} 1,000,000 A számformátumban vesszővel választjuk el az ezreseket
0.25 {:.2%} 25.00% Százalékos alak
1000000000 {:.2e} 1.00e+09 Exponenciális alak
11 {:>10d}         11 Jobbra igazított
11 {:<10d} 11 Balra igazított
11 {:^10d}     11 Középre igazított

20.1 Tízes számok

Próbáld meg lefuttatni a következő programot, ami néhány véletlen számot fog kiírni.

import random

for i in range(10):
    x = random.randrange(20)
    print(x)

A bal oldalon megjelenő kimeneten a számok szörnyen néznek ki:

16
13
2
0
10
3
18
1
14
5

Használhatunk szöveges (string) alakot, hogy a számlista jobban nézzen ki, és jobbra igazíthatjuk. Az első lépés ehhez, hogy használjuk a format parancsot, az alábbi módon:

import random

for i in range(10):
    x = random.randrange(20)
    print("{}".format(x) )

Ez a programunkat már egy lépéssel közelebb viszi a jó megoldáshoz, de nem vagyunk még készen. Nézd meg, ahogy a szöveg véget ér a .format(x) kiegészítéssel. Minden szöveg egy osztály leszármazottja, amit String-nek hívnak. Az osztálynak vannak eljárásai, amiket meg lehet hívni. Az egyik ilyen a format.

A format függvény nem írja ki a kapcsos zárójeleket{}, hanem az x értékét helyettesíti be oda. A kimenet (alább) látható, olyan mint volt korábban:

7
15
4
12
3
8
7
15
12
8

Ahhoz, hogy jól nézzen ki, több infót kell megadnunk a formátumról, ami a kapcsos zárójelben fog lenni, és a számra vonatkozik majd:

import random

for i in range(10):
    x = random.randrange(20)
    print("{:2}".format(x) )
 7
15
 4
12
 3
 8
 7
15
12
 8

Máris jobb, megvan a helyesen ábrázolt szám! De hogyan működik ez az egész? A :2, amit adtunk, az nem túl nyilvánvaló.

Íme a magyarázat: a kapcsos zárójel elmondja a számítógépnek, hogy ez egy számformátum fog lenni. A kettőspont után, a kapcsos zárójelen belül, lesz a formatálási információ. Ez esetben, mi a 2-t írtuk be, ami a mező szélességet két karakterre állította. A mező szélessége érték mutatta meg a számítógépnek, hogy próbálja meg a számot két karakter szélesen ábrázolni. Alap értelemben, balra igazítja a szöveget és jobbra igazítja a számokat.

Még jobb, hogy a programnak nem kell meghívnia a str( ) függvényt, hogy a számot szöveggé alakítsa. Szóval szöveg konverzióra nem lesz szükség.

Mi van akkor, ha nagyobb számunk van? Nézzünk nagyobb véletlen számokat meg:

import random

for i in range(10):
    x = random.randrange(100000)
    print( "{:6}".format(x) )

Ez egy jobbra igazított kimenetet ad, de nem néz ki valami fényesen:

 18394
 72242
 97508
 21583
 11508
 76064
 88756
 77413
  7930
 81095
 

Hol vannak a vesszők? Ez a lista szebben nézne ki elválasztással, minden harmadik számjegynél. Vessünk egy pillantást a következő példára, hogy megértsük, hogyan tehetjük ezt meg:

import random

for i in range(10):
    x = random.randrange(100000)
    print( "{:6,}".format(x) )
65,732
30,248
13,802
17,177
 3,584
 7,598
21,672
82,900
72,838
48,557

Minden megadott mező után adtunk egy vessző, és a számok most már vesszővel vannak elválasztva. A vesszőnek a mező után kell lennie, a szélesség megállapítása után, és nem előtte. A vesszőket bele kell számítanunk a mezők szélességének kiszámolásába. Például, az 1,024 az 5 mezőből áll, és nem 4-ből.

Kiírathatunk több értéket is és kombinálhatjuk az értékeket szöveggel. Futtassuk le az alábbi kódot:

x = 5
y = 66
z = 777
print ("A - '{}' B - '{}' C - '{}'".format(x,y,z) )

A program be fogja helyettesíteni a számokat a kapcsos zárójelbe, és még ki is fogja azokat írni a következőképpen:

A - '5' B - '66' C - '777'

Ha három kapcsoszárójel van ott, akkor a számítógép fel fogja tételezni, hogy azoknak az értéke fel lesz sorolva a format parancsban. Az első érték, amit megadtunk fogja behelyettesíti az első kapcsos zárójelet.

Néha szeretnénk kiíratni valamely értéket kétszer. Vagy más sorrendben kiírni, mint ahogyan a format függvénybe már beírtuk őket.

x = 5
y = 66
z = 777
print ("C - '{2}' A - '{0}' B - '{1}' C again - '{2}'".format(x,y,z) )

Figyeljük meg, hogy a számok behelyettesítése a kapcsos zárójelek helyére úgy történik, hogy paramétereket adunk meg a format függvényben. A paraméterek számok, amik 0-val kezdődnek, így jelen esetben az x a 0-s paraméter lesz.

Továbbra is finomíthatjuk a formatálási információkat a kettőspont után. Például:

x = 5
y = 66
z = 777
print ("C - '{2:4}' A - '{0:4}' B - '{1:4}' C again - '{2:4}'".format(x,y,z) )

Láthatjuk, hogy a fenti kód azt mutatja, ahogy az értékek jobbra lesznek rendezve, négy karakter szélesen.

C - ' 777' A - '   5' B - '  66' C again - ' 777'

20.2 Szöveges változók

Lássuk, hogyan formázhatjuk a szöveges változókat (sztringek).

A következő listánk szörnyen néz ki.

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.")
Apples are 4 calories.
Oranges are 300 calories.
Grapes are 70 calories.
Pears are 30 calories.

Most próbáljuk meg használni a format parancsot. Jegyezd meg, hogyan adtunk további szöveget az értékhez, amit ugyanabban a sorban jelenítettünk meg.

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]) )
Apples  are   4 calories.
Oranges are 300 calories.
Grapes  are  70 calories.
Pears   are  30 calories.

Hát ez elég király, és úgy is néz, ki ahogyan szeretnénk. De mi van akkor, ha nem akarjuk a számokat jobbra igazítani és a szöveget balra? Egyszerűen csak használjuk a < és a > karaktereket, ahogyan azt a példán látjuk:

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]) )
 Apples are 4   calories.
Oranges are 300 calories.
 Grapes are 70  calories.
  Pears are 30  calories.

20.3 Kezdő nullák

Ez egy olyan kimenet, ami nem jó:

for hours in range(1,13):
    for minutes in range(0,60):
        print( "Time {}:{}".format(hours, minutes) )
Time 8:56
Time 8:57
Time 8:58
Time 8:59
Time 9:0
Time 9:1
Time 9:2

Úgy kell használnunk a kezdő nullákat, ahogyan az az órákon megszokott. Ahelyett, hogy a meghatároznánk 2 mezőt a mező szélességének, helyette határozzunk meg 02-t. Ez így ki fogja egészíteni a helyet egy zéróval, és nem csak arrébb tolja a számot.

for hours in range(1,13):
    for minutes in range(0,60):
        print( "Time {:02}:{:02}".format(hours, minutes) )
Time 08:56
Time 08:57
Time 08:58
Time 08:59
Time 09:00
Time 09:01
Time 09:02

20.4 Lebegőpontos számok

Kontrolálhatunk lebegőpontos kimenetet is. Például, a következő kód kimenete szerint:

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) )
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

Egy .2 formátum azt jelenti, hogy a megjelnítése a számnak két tizedesjegy pontossággal fog történni. Sajnos, ez azt jelenti, hogy ha kiírjuk az 123 számot, akkor három számot fogunk kapni, akkor ezt a tudományos jelöléssel ellátott számot fogjuk kapni: 1.2e+02.

Egy .2f formátum, (figyeld meg az f-t) azt jelenti, hogy a számot két tizedesjegyig ábrázoljuk a tizedespont után. Így az 1-s szám meg fogja jeleníteni az 1.00 -t és az 1.5555 helyébe 1.56-t kapunk.

Lehet mező szélessége karaktereket is alkalmazni:

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) )

A 10.2f formátum ne jelenti azt, hogy 10 szám lesz a tizedespont előtt és kettő utána. Ez azt jelenti, hogy az összes mező 10. Így 7 számjegy lesz a törtérték előtt, a tizedespont még egy helyiérték, és 2 számjegy utána.

'       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 Dollárok és centek kiíratása

Ha ki szeretnél íratni egy lebegő pontos számot, például árként, akkor használd az f-t, valahogy így:

cost1  = 3.07
tax1   = cost1 * 0.06
total1 = cost1 + tax1

print("Ár:  ${0:5.2f}".format(cost1) )
print("Adó:    {0:5.2f}".format(tax1) )
print("------------")
print("Összesen: ${0:5.2f}".format(total1) )

Ne felejtsd el, hogy könnyű ugyan arra gondolni, hogy az %5.2f azt jelentheti, hogy öt számjegy: egy tizedes jegy, majd kettő számjegy. De ez nem azt jelenti. Ez azt jelenti, hogy a teljes mező 5 széles, beleértve az egészeket és a 2 számjegyet utána is. Itt van a kimenetünk:

Cost:  $ 3.07
Tax:     0.18
------------
Total: $ 3.25

Vigyázz! A fenti kódban van egy tévedés, ami elég gyakori, amikor valaki pénzügyi átutalást hajt végre. Kiszúrod? Próbáld meg a lenti, kibővített kód segítségével:

cost1  = 3.07
tax1   = cost1 * 0.06
total1 = cost1 + tax1

print("Ár:  ${0:5.2f}".format(cost1) )
print("adó:    {0:5.2f}".format(tax1) )
print("------------")
print("Összesen: ${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("Végösszeg: ${0:5.2f}".format(grand_total) )

Íme a kimenet:

Cost:  $ 3.07
Tax:     0.18
------------
Total: $ 3.25

Cost:  $ 5.07
Tax:     0.30
------------
Total: $ 5.37

Grand total: $ 8.63

Észrevetted a hibát? Kerekítési hibánk van! Nézd meg a példát, amin úgy néz ki, hogy az összegnek $ 8.62-nek kellene lennie, de nem annyi.

A kiírás formatálása nem változtatta meg a számot, ez volt a kimenet! Ha megváltoztatjuk a kiírás formatálást, és három számjegyig engedjük kiírna, akkor már könnyebben észlelhetjük a hibát:

Cost:  $3.070
Tax:    0.184
------------
Total: $3.254

Cost:  $5.070
Tax:    0.304
------------
Total: $5.374

Grand total: $8.628

És még egyszer, a megjelenítésnek a formatálása nem változtatja meg a számot. Használjuk a round parancsot, ami valóban kerekíteni fog. Lásd alább:

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) )
Cost:  $ 3.07
Tax:     0.18
------------
Total: $ 3.25

Cost:  $ 5.07
Tax:     0.30
------------
Total: $ 5.37

Grand total: $ 8.62

A kerekítés parancs kezeli azt, hogy mennyi számjegyre kerekítsünk. Egy kerekített értéket ad, de nem változtatja meg az eredeti értéket.

x = 1234.5678
print(round(x, 2))
print(round(x, 1))
print(round(x, 0))
print(round(x, -1))
print(round(x, -2))

Figyeld meg alább az ábrát, ahogyan a round() függvény reagál a -2 értékre:

1234.57
1234.6
1235.0
1230.0
1200.0

20.6 Használjuk ezeket a Pygame-ben

Nem csak a kiírás parancshoz formatálhatjuk a szöveges változókat. Például a timer.py használ szöveges formázásokat, és kiírja azt egy képernyőre, ami egy on-screen óra lehet:

# Használjuk a python szöveges formázását, hogy nullákat tegyünk a számok elé
output_string = "Time: {0:02}:{1:02}".format(minutes,seconds)

# Írjuk ki a játék képernyőre
text = font.render(output_string, True, BLACK)
screen.blit(text, [250, 250])

20.7 Áttekintés

20.7.1 Feladatlap

Click here for the chapter worksheet.


You are not logged in. Log in here and track your progress.