Az előző fejezetben megtudtuk, hogyan hozzunk létre különböző változókat. Változóinkon különböző műveleteket szoktunk végezni. Már adtunk össze számértékeket és fűztünk össze stringeket. A műveletek műveleti jelek változók vagy literál értékek közé írásával végezhetőek el. Érdemes a változónév vagy számértékek és a műveleti jelek közé egy szóközt írni. Ez bizonyos esetekben nélkülözhetetlen ahhoz, hogy a Python fordító értelmezni tudja a kódot. Más esetekben pedig nekünk segít, hogy ne folyjanak egymással össze a dolgok. Most nézzünk további művelettípusokat!
Számértékekkel (legyeneke ezek egész számok vagy tizedes törtek) aritmetikai műveleteket szokás végezni. Az összeadás és szorzás nagyon sok programban fontos szerepet kap.
A teljesség kedvéért ismételjük át a korábban látott összeadást. Két számérték közé + operátort írva összeadjuk a kettőt.
Számértékek között - operátort írva az értékek különbségét kapjuk eredményül.
Számértékek között * operátort írva az értékek szorzatát kapjuk eredményül.
Számértékek között / operátort írva az értékek hányadosát kapjuk eredményül.
Számértékek között // operátort írva (két törtvonal) az értékek hányadosának egész részét kapjuk eredményül. A tizedes vessző utáni rész kerekítés nélkül lesz levágva.
Számértékek között % operátort írva az értékek maradékos osztása során fennmaradó maradékot kapjuk eredményül.
Számértékek között ** operátort írva (két aszteriszk) a baloldalsó értéket a jobboldalsó érték szerinti hatványkitevőre emeljük.
print(10 + 3) # = 13
print(10 - 3) # = 7
print(10 * 3) # = 30
print(10 / 3) # = 3.3333333333333335
print(10 // 3) # = 3
print(10 % 3) # = 1
print(10 ** 3) # = 1000
Ezzel a kiíratással tesztelhetjük az előbb felsorolt aritmetikai műveleteket. Érdemes megfigyelni, hogy az osztás eredményeként előálló végtelen szakaszos tizedes tört véges pontossággal, és a végén 5-re kerekítve jelenik meg. Ez nem szabályos kerekítés, hiszen a 3-mat szabály szerint lefelé kerekítjük. Nem is igazi kerekítés ez, hanem egyszerűen a számítógép véges precizitásának eredménye az 5. Az értékek bináris számrendszerben vannak tárolva. Ami itt ennél lényegesebb, hogy egy előre megszabott mennyiségű helyiértéken. Pythonban a float értékek általában 64 bitesek, de előfordulhat 32 bites is. Ez azt jelenti, hogy 64 bináris számjegy áll rendelkezésre arra, hogy leírjunk egy számot. Floatok esetében annyival árnyaltabb a kép, hogy változik, hogy hol található a tizedesvessző. A számítógép annak megfelelően választja meg a tizedesvessző helyét, hogy éppen egy nagyon nagy számot, vagy egy nagyon nagy pontosságú számot akarunk tárolni. Ez automatikusan működik.
Példaként végezzünk műveleteket a 3.3333333333333335 értékkel!
# 3.3333333333333335
print(3.3333333333333335 * 0.001) # = 0.0033333333333333335
Látszik, hogy itt több helyiértéket ír ki a program. Ez azért lehetséges, mivel ez egy kisebb szám, így felszabadultak a legnagyobb helyiértékek. Így a számítógép "balrább" téve a tizedesvesszőt több tizedesjegyet tud megjeleníteni.
# 3.3333333333333335
print(3.3333333333333335 * 1.000) # = 3333.3333333333335
Itt az előzővel ellentétben egy nagyobb számot kell kiíratni, ezért vesztünk a pontosságból.
Ez a jelenség természetesen integer (egész) értékeknél nem jelentkezik. Ott egyáltalán nem tárolódnak tizedesjegyek.
A műveleti sorrend a következően alakul: Az összeadás és kivonás azonos precedenciájú. Az szorzás és osztás egymással szintén azonos precedenciájú, és az összeadás és kivonásnál magasabb precedenciájú. Azonos precedenciájú műveletek közt balról jobbra történik a műveletvégzés. Ezt módosíthatjuk gömbölyű zárójelek írásával. A zárójelezés persze nem csak aritmetikai műveletekkel használható.
Gyakran felmerül az igény, hogy különböző értékeket összehasonlítsunk egymással. Egyenlőek-e? Hogyha nem, akkor melyik a nagyobb? Ilyen és hasonló kérdések megválaszolására szolgálnak az összehasonlító műveletek (Comparison Operators). Ezek mindegyike boolean típusú (logikai) értéket ad vissza eredményül. A visszaadott érték True, hogyha a kifejezés teljesül, és False, hogyha nem.
Két érték közt == operátort írva (két egyenlőségjel) megkapjuk, hogy a kettő egyenlő-e. A legtöbb programozási nyelv azért alkalmaz két egyenlőségjelet az egyenlőség vizsgálatára, hogy megkülönböztesse azt a hozzárendelés műveletétől. Korábban már láttuk, hogy a szimpla = a baloldali változóhoz rendelte a jobboldali értéket. Ezt fontos tudatosítani, mert hogyha egy összehasonlításnak szánt egyenlőségjelet csak egyszeresen írunk, akkor az hozzárendelést fog jelenteni. Erre nagyon figyeljünk!
Két érték közt != operátort írva (felkiáltójel és egyenlőségjel) akkor kapunk igaz értéket, ha a kettő nem egyenlő. Ez a == ellentettje.
Két érték közt > operátort írva akkor kapunk igaz értéket, ha a baloldalsó érték nagyobb a jobboldalsónál. Hogyha a baloldalsó kisebb vagy egyenlő a jobbnál, akkor hamis visszatérési értéket kapunk.
Két érték közt < operátort írva akkor kapunk igaz értéket, ha a baloldalsó érték kisebb a jobboldalsónál. Hogyha a baloldalsó nagyobb vagy egyenlő a jobbnál, akkor hamis visszatérési értéket kapunk.
Két érték közt >= operátort írva akkor kapunk igaz értéket, ha a baloldalsó érték nagyobb vagy egyenlő a jobboldalsónál. Hogyha a baloldalsó kisebb a jobbnál, akkor hamis visszatérési értéket kapunk.
Két érték közt <= operátort írva akkor kapunk igaz értéket, ha a baloldalsó érték kisebb vagy egyenlő a jobboldalsónál. Hogyha a baloldalsó nagyobb a jobbnál, akkor hamis visszatérési értéket kapunk.
print(5 == 4) # = False
print(5 != 4) # = True
print(5 > 4) # = True
print(5 < 4) # = False
print(5 >= 4) # = True
print(5 <= 4) # = False
print(4 >= 4) # = True
print(4 <= 4) # = True
Egyelőre integerek voltak az összehasonlítás tárgyai. Most vizsgáljuk meg röviden a float értékek összehasonlítását! Az össze eddig felsorolt komparáló művelet működik float értékekkel is. A ==, !=, >= és <= operátorok használata viszont nem javasolt. Miért? Korábban már esett szó a számok véges precizitásáról. Tegyük fel, hogy bizonyos értékeket bonyolultabb műveletek eredményéül kapunk! Ebben az esetben a számítások pontatlansága miatt lehetséges, hogy az elvárttól picit eltérő értéket kapunk. Ekkor a teljes egyezés vizsgálata félrevezető lehet. Hasonlóan járhatunk, hogyha azt vizsgáljuk, hogy két érték eltérő-e. Ezek tudatában a >= és <= operátorok is szimplán fölöslegesek. A gyakorlatban floatok egyenlőségének vizsgálatakor valamilyen hibaküszöböt vezetnek be. Kíváncsiak vagyunk, hogy az x változó értéke egyezik-e 10.0-zel. A vizsgálat valahogyan így nézhet ki:
(x > 9.9999 and x < 10.0001)
Az and operátorról pillanatokon belül lesz szó.
Nem csak számértékek közt végezhetünk összehasonlítást. Hogyha például az érdekel, hogy két embernek ugyanaz-e a neve, akkor ezt könnyedén kideríthetjük az egyenlőség operátor használatával. Hasonlóan jól működik a többi összehasonlító művelet. Az operátorok balról jobbra haladnak a szövegen, és egyesével összehasonlítják a karakterek Unicode kódját. Ez részben ábécésorrendet jelent, de nem teljesen. Például a nagybetűk kisebb kóddal rendelkeznek a kisbetűknél. Az "Alma" tehát kisebb értékű, mint az "alma". Az ékezetes karakterek nagyobb kóddal rendelkeznek a latin ábécé ékezet nélküli összes karakterénél. Tehát a "bálna" kisebb az "ámbráscet"-nél.
name1 = "Tomi"
name2 = "Lajos"
name3 = "Lajos"
print(name1 == name2) # = False
print(name2 == name3) # = True
print("Alma" < "alma") # = True
print("bálna" < "ámbráscet") # = True
Nem érdemes tehát ezzel a módszerel betűrendbe rakni szavakat.
Most nézzük a logikai műveleteket! Ebből nem nem lesz sok, viszont annál fontosabbak. Már volt szó boolean értékekről, illetve összehasonlító műveletekről, amelyek logikai értéket adnak eredményül. Ezeket hasznos lenne összekapcsolni, hogy összetettebb logikai kifejezéseket kapjunk. Már találkoztunk egy ilyennel, amikor float értékek egyezését vizsgáltuk hibaküszöbbel.
Két logikai érték közt az and operátort írva akkor kapunk igaz értéket, ha a bal és jobb érték is igaz. Hogyha legalább az egyik érték hamis, akkor az eredő kifejezés értéke is hamis lesz.
Két logikai érték közt az or operátort írva akkor kapunk igaz értéket, ha a bal vagy jobb érték közül legalább az egyik igaz. Hogyha mindkét érték hamis, akkor a kifejezés értéke is hamis.
Egy logikai kifejezés előtt a not operátort írva az eredeti kifejezés negáltját kapjuk. Az eredő kifejezés akkor lesz igaz értékű, ha az eredeti kifejezés hamis. Az eredő kifejezés akkor lesz hamis értékű, ha az eredeti kifejezés igaz. Az eddig tanult műveletek közül ez az első, amelyik nem két érték közé kerül, hanem csak egy operandusa van, amit az operátor után írunk.
print(True and True) # = True
print(True and False) # = False
print(False and False) # = False
print(True or True) # = True
print(True or False) # = True
print(False or False) # = False
print(not True) # = False
print(not False) # = True
Ebben a bekezdésben már nem tanulunk igazán újat. Csak ötvözzük a korábban tanultak egy részét. Egyfajta kényelmi funkció bemutatása következik. Már találkoztunk a =, mint hozzárendelés művelettel. Sokszor van szükszég arra, hogy egy változó értékén műveletet végezzünk, majd a változóban az új megváltozott értéket tovább tároljuk. Ez például összeadás esetén az eddig tanultakkal valahogy így néz ki:
en_kis_valtozom = en_kis_valtozom + 10
Valamennyire talán érződik, hogy fölösleges kétszer kiírni a változó nevét. (Hogyha mégsem érződik, akkor a következő műveletek elsajátítása után már biztosan nem lesz többé kedvünk kétszer leírni ugyanazt.)
A x += y művelet az x = x + y művelet leírását egyszerűsíti. Ehhez hasonlóan létezik -=, *=, /=, //=, %= és **= operátor.
Ebben a fejezetben tanultunk egy csomó nélkülözhetetlen dolgot. Többé már nem fölöslegesek a változóink! Lehet velük játszadozni. A következőkben fogjuk is gyakorolni a műveletvégzést. Összefoglalva tehát az eddigieket:
Tudunk változókat létrehozni, amelyek felvehetnek szám, karakterlánc és logikai értékeket. (Megemlítettük, hogy tudunk listát készíteni a változókból, bár ezt eddig nem igazán használtuk ki.) Számértékű változóinkon aritmetikai műveleteket végeztünk. Összehasonlítottunk számokat és nem csak számokat. Megemlítettük, hogy figyelni kell a float értékek összehasonlítására, mivel a számítás véges precizitású bináris számokkal történik. Logikai értékű elemi kifejezéseinket és és vagy kapcsolatba hoztuk. Még egy igen hasznos egyszerűsítő megoldást is tanultunk a változókon végzendő aritmetikai módosításokra.