2018. szeptember 3., hétfő

Faktoriális kiszámítása Pythonban

A program két helyen mutatja be a kivételkezelést: először az adatbeolvasás ellenőrzésére (az int() ugyanis kivételt dob, ha nem egész számot, hanem törtet vagy szöveget vagy baglyot tartalmazó stringet akarunk konvertálni vele), másodszor a veremtúlcsordulást okozó rekurzió leállítására. A három eredmény ugyan egyforma, de a rekurzió a memória állapotától függően n=1000 környékén kifullad, és ilyenkor a program megszakadása miatt a másik két eredményt sem látnánk.

Sem az iteratív, sem a rekurzív megoldásban nem adtuk meg a visszaadott érték típusát; azt az értelmező dinamikusan állapítja meg, így – mivel az egész típusnak nincs méretkorlátja – a program meglepően nagy számok faktoriálisát is ki tudja számítani, csak győzzük elolvasni.

A program végén az if __name__=='__main__': sor ne riasszon el senkit, pusztán öncélú elegancia, hogy teljesen strukturált legyen a programunk. Ha csak az alatta levő két sort írnánk oda behúzás nélkül, ugyanígy működne. A magyarázata itt olvasható, célszerű és indokolt használatára pedig a bitmap.py modul mutat példát.

Ha valaki ékezetes függvényneveket vél fölfedezni, az nem optikai csalódás vagy nyomdahiba! A Python 3000 ezt is tudja. :-)

Check Tesztelve a 3.1.2 verzióban.

import math    #Ez csak a beépített faktoriálisfüggvény bemutatásához kell.

def szövegel():
    print("""Ez a program egy természetes szám faktoriálisát számítja ki
többféleképpen. A rekurzív algoritmus a tapasztalat szerint kb. 993-ig
működik; efelett "RuntimeError: maximum recursion depth exceeded in
comparison" hibaüzenettel áll le, de a határ a memória pillanatnyi hangulatától
is függ. Lehet kísérletezni, a hiba le van kezelve.\n""")

def beolvas():
    N=input('Kérek egy egész számot! ')    #string lesz!
    try:
        n=int(N)
    except ValueError:     #Nem egész szám, negatívvá tesszük
        n=-1
    print()
    return(n)

def RekFaktor(n):
    if n==0:
        return(1)
    else:
        return(RekFaktor(n-1)*n)

RekFaktor2 = lambda x: x*RekFaktor2(x-1) if x>1 else 1

def IterFaktor(n):
    f=1
    for i in range(n):  #Ez a [0;n-1] intervallum!
        f*=(i+1)
    return(f)

def kiír(n):
    if n<0:
        print('Ez bizony nem természetes szám.')
    else:
        try:
            print('%d! rekurzívan:              %d' % (n,RekFaktor(n)))
            print('%d! rekurzívan (lambda):     %d' % (n,RekFaktor2(n)))
        except RuntimeError:
            print('Túl nagy szám, a rekurzív számítást nem tudom elvégezni.')
        print("-"*79 if n>85 else"")    #Elválasztás az olvashatóság kedvéért
        print('%d! iteratívan:              %d' % (n,IterFaktor(n)))
        print("-"*79 if n>85 else"")
        print('%d! a beépített függvénnyel: %d' % (n,math.factorial(n)))
   
if __name__=='__main__':
    szövegel()
    kiír(beolvas())

Nincsenek megjegyzések:

Megjegyzés küldése