Binominialkoeffizienten berechnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
WorldPark
User
Beiträge: 5
Registriert: Donnerstag 14. Februar 2019, 11:37

Hallo,

ich bin gerade dabei mir selber Python beizubringen, habe aber gerade erst angefangen. Ich hoffe ihr könnt mir bei meinem Problem weiterhelfen. Ich möchte den Binominialkoeffizienten berechnen. Dazu habe ich folgendes Skript angefertigt:

def fakult(n):
#Für Re- hat die Fakultät keine Wertemenge
if n < 0:
raise ValueError
#Nach Definition ist 0! = 1
if n == 0:
return 1
#Ansonten wird hier die Fakultät ausgerechnet
else:
save = 1
for i in range(2,n+1):
save *= i
return save

def binomial(n,k):
save=fakult(n)/(fakult(k)*fakult(n-k))
return=safe

x=fakult(6,2)
print("Hier müsste zwanzig stehen: %s" % x)[/list]

Ich bekomme allerdings den Fehler:

File "ex3_extra.py", line 16
save=fakult(n)/(fakult(k)*fakult(n-k))
^
IndentationError: expected an indented block
PS C:\Users\tobia\onedrive\dokumente\python>

Was mache ich verkehrt?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@WorldPark: In Deinem Quelltext hast Du falsch eingerückt, das sagt ja auch die Fehlermeldung, und im Beitrag hast Du den Quelltext nicht in [ code ]-Tags gesetzt, so dass wir hier gar keine Einrückung mehr sehen können. Im vollständigen Editor ist das die Schaltfläche mit der Beschriftung </>.

Edit: Für die Fakultät gibt es bereits eine Funktion im `math`-Modul, das braucht man sich nicht selbst schreiben.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
WorldPark
User
Beiträge: 5
Registriert: Donnerstag 14. Februar 2019, 11:37

__blackjack__ hat geschrieben: Donnerstag 14. Februar 2019, 12:18 @WorldPark: In Deinem Quelltext hast Du falsch eingerückt, das sagt ja auch die Fehlermeldung, und im Beitrag hast Du den Quelltext nicht in [ code ]-Tags gesetzt, so dass wir hier gar keine Einrückung mehr sehen können. Im vollständigen Editor ist das die Schaltfläche mit der Beschriftung </>.

Edit: Für die Fakultät gibt es bereits eine Funktion im `math`-Modul, das braucht man sich nicht selbst schreiben.
Vielen Dank. Es hat jetzt geklappt und fürs nächste Mal weiß ich Bescheid :)
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@WorldPark: Wenn man das mit der Einrückung richtig macht, was Du bei `fakult()` ja problemlos hinbekommen hast, dann ist der nächste Syntaxfehler der Versuch dem Schlüsselwort ``return`` einen Wert zuzuweisen. Was Du in `fakult()` auch nie versucht hast. Wenn man das Problem behebt, bekommt man einen `NameError` weil `safe` nirgends definiert ist.

`save` ist übrigens auch ein komischer Name, was soll das bedeuten? Das wäre eher ein Name für eine Funktion oder Methode, weil es eine Tätigkeit beschreibt: „speichern“. Üblichweise hätte so eine Funktion/Methode dann auch einen Dateinamen als Argument. So ganz allgemein der Name für ein Ergebnis wäre `result`.

Um binäre Operationen und dem Gleicheitszeichen bei Zuweisungen ausserhalb von Argumentlisten setzt man zur besseren Lesbarkeit üblicherweise Leerzeichen. Genau so nach Kommas.

Das ``if n == 0:``/``else`` in `fakult()` ist überflüssig da auch im ``else``-Zweig 1 heraus kommt wenn `n` Null ist. Bleibt also das hier übrig:

Code: Alles auswählen

def fakult(n):
    if n < 0:
        raise ValueError('undefined for negative numbers')
    
    result = 1
    for i in range(2, n + 1):
        result *= i
    
    return result
Dann könnte man das mit `functools.reduce()` und `operator.mul()` noch kompakter ausdrücken:

Code: Alles auswählen

def fakult(n):
    if n < 0:
        raise ValueError('undefined for negative numbers')

    return reduce(mul, range(2, n + 1), 1)
Aber wie gesagt, gibt es die Fakultätsfunktion schon im `math`-Modul.

Da immer eine ganze Zahl heraus kommt über und unter dem Bruchstrich und auch bei der Division selbst, würde man in `binomial()` die ganzzahlige Division wählen.

Um `x` zu berechnen versuchst Du `fakult()` aufzurufen, statt `binomial()`.

Zeichenkettenformatierung mit ``%`` ist eher veraltet. Da nimmt man heute die `format()`-Methode oder f-Zeichenketten für.

Dann landen wir letztlich bei:

Code: Alles auswählen

#!/usr/bin/env python3
from math import factorial


def binomial(n, k):
    return factorial(n) // (factorial(k) * factorial(n - k))


def main():
    print(f'Hier müsste zwanzig stehen: {binomial(6, 2)}')


if __name__ == '__main__':
    main()
Mit dem Problem das da jetzt folgendes ausgegeben wird, lasse ich Dich mal weitermachen:

Code: Alles auswählen

Hier müsste zwanzig stehen: 15
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten