Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1415:j_b

Beitrag eines Teilnehmers von Mathesis (J.)

Das hier ist eine echt tolle Seite über Rekursive Kunst. Du weißt nicht, was das ist? Dann schau doch mal rein!

Funktionen sind toll!

#Das hier ist ein Beispiel fuer eine Funktion, die rekursiv die Fakultaet einer Zahl berechnet.
def fakultaet(x):
	if (x == 0):
		return 1
	else:
		return x*fakultaet(x-1)

Um nun zu zeigen, warum Funktionen so nützlich sind, wollen wir das folgende Programm betrachten, welches den Binomialkoeffizienten $\binom nk$ berechnet. Dabei gilt Folgendes: $$\binom nk = \frac{n!}{k! \cdot (n-k)!}$$ Wir müssen also gleich drei mal die Fakultät berechnen1). Also gut, legen wir los. Zuerst einmal ohne die Nutzung irgendwelcher Funktionen:

input = raw_input('Bitte n und k eingeben:')
k, n = [int(num) for num in input.split()]
bnk = 0
#berechne zuerst die drei Fakultaeten.
nfak, kfak, nkfac = 1,1,1
#Achtung, die range-Funktion schliesst das letzte Element nicht ein, '0' aber dafür schon.
for i in range(1,n + 1):
	nfak*=i
for i in range(1,k + 1):
	kfak*=i
for i in range(1,n - k + 1):
	nkfak*=i
#Nun können wir den den Binomialkoeffizienten berechnen:
bnk = nfak/(kfak*nkfak)
print 'Binomialkoeffizient von', n, 'ueber', k, 'ist:', bnk

Nun noch einmal das Ganze, aber mit Nutzung unserer tollen Fakultäts-Funktion:

def fakultaet(x):
	if (x == 0):
		return 1
	else:
		return x*fakultaet(x-1)
 
input = raw_input('Bitte n und k eingeben:')
k, n = [int(num) for num in input.split()]
bnk = fakultaet(n)/(fakultaet(k)*fakultaet(k-n))
print 'Binomialkoeffizient von', n, 'ueber', k, 'ist:', bnk

Nicht nur, dass der Quelltext viel kürzer und leichter zu verstehen ist, er ist auch sehr viel einfacher zu warten. Nehmen wir an, wir wollten jedes mal, wenn die Fakultät einer Zahl berechnet wurde, einen Zähler erhöhen, um irgendwelche Statistiken zu ermitteln. Wir würden also die Zeile:

fakultaetszaehler += 1

beim ersten Beispiel 3mal einfügen, beim 'ordentlichen' Beispiel jedoch nur einmal2). Stellen wir uns nun vor, wir wollen etwas kompliziertere Operationen mit dem Fakultätszähler3) durchführen, wenn wir eine Fakultät berechnen. Dies könnte sehr schnell zu einem sehr unübersichtlichen Code führen:

def fakultaet(x):
	if (x == 0):
		fakultaetszaehler += 1
		#Hier
		#koennten
		#noch
		#ein
		#paar
		#komplizierte
		#Rechnungen
		#stehen
		return 1
	else:
		return x*fakultaet(x-1)
 
input = raw_input('Bitte n und k eingeben:')
k, n = [int(num) for num in input.split()]
bnk = fakultaet(n)/(fakultaet(k)*fakultaet(k-n))
print 'Binomialkoeffizient von', n, 'ueber', k, 'ist:', bnk

sieht aber immer noch besser aus als:

input = raw_input('Bitte n und k eingeben:')
k, n = [int(num) for num in input.split()]
bnk = 0
#berechne zuerst die drei Fakultaeten.
nfak, kfak, nkfac = 1,1,1
#Achtung, die range-Funktion schliesst das letzte Element nicht ein, '0' aber dafür schon.
for i in range(1,n + 1):
	nfak*=i
	fakultaetszaehler += 1
	#Hier
	#koennten
	#noch
	#ein
	#paar
	#komplizierte
	#Rechnungen
	#stehen
for i in range(1,k + 1):
	kfak*=i
	fakultaetszaehler += 1
	#Hier
	#koennten
	#noch
	#ein
	#paar
	#komplizierte
	#Rechnungen
	#stehen
for i in range(1,n - k + 1):
	nkfak*=i
	fakultaetszaehler += 1
	#Hier
	#koennten
	#noch
	#ein
	#paar
	#komplizierte
	#Rechnungen
	#stehen
#Nun können wir den den Binomialkoeffizienten berechnen:
bnk = nfak/(kfak*nkfak)
print 'Binomialkoeffizient von', n, 'ueber', k, 'ist:', bnk

Man sieht also - selbst an diesem sehr konstruiertem, an-den-Haaren-herbeigezogenem Beispiel - dass die Nutzung von Funktionen viele Vorteile bietet:

  • Der Code ist übersichtlicher und leichter verständlich
  • Der Code ist leichter zu warten und zu verbessern
  • Der Code ist wesentlich kürzer

Das war es erst einmal zu Funktionen, aber vielleicht kommt hier ja nochwas dazu!

1) Natürlich könnte man hier n! mit (n-k)! kürzen und sich so eine Forschleife sparen.
2) Das funktioniert natürlich nicht so einfach, wir haben ja die Variable nirgendwo angelegt. Wir nehmen der Einfachkeit halber aber einfach mal an, dass das hier nur ein Ausschnitt aus einem größerem Programm ist, in dem das alles geregelt ist und vielleicht sogar in eine Datei geschrieben wird.
3) Hier ermpfiehlt es sich fast schon, eine eigene Funktion dafür zu definieren und diese dann jedes Mal aufzurufen
ws1415/j_b.txt · Zuletzt geändert: 2021/04/28 10:47 von stefanborn