For-Schleife und Berechnungen

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
Immortalmemo
User
Beiträge: 13
Registriert: Mittwoch 22. Oktober 2014, 00:02
Wohnort: Berlin

Hallo Leute,

ich bin Python-neuling und komme im Moment nicht weiter bei meinem Code.

Zunächst: Unsere Aufgabe folgendes: http://puu.sh/clnAL/ed33a278f1.png.
In dieser Aufgabe soll eine Approximation der Exponentialfunktion `exp(x) : x ⟼ e^x` berechnet werden. Wir verwenden dazu, dass

Code: Alles auswählen

               n     
             ____    
             \   `   
              \     i
         lim   \   x 
exp(x) = n→∞   /   ──
              /    i!
             /___,   
             i = 0 
**Eingabe** Jede Zeile der Eingabe enthält eine Testinstanz in Form zweier natürlicher Zahlen x ∈ [1,20], n ∈ [0,60] (in dieser Reihenfolge und mit einem Leerzeichen getrennt).

**Ausgabe** Für jede Testinstanz soll eine einzelne Zeile ausgegeben werden, in der der Wert [der Rechnung¹] mit genau 4 Nachkommastellen steht.

*Achtung: Gerundete Ergebnisse sollen immer gemäß Pythons ``float`` Rundung ausgegeben werden — trotz möglicher Ungenauigkeiten!*

[¹ Hier stand noch einmal die rechte Seite der Formel.]
Mein Lösungsansatz:

Code: Alles auswählen

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

summe=0
for line in stdin:
        x, n =(int(word) for word in line.split())
        for i in range(n+1):
                power=pow(x,i)
                fakul=factorial(i)
                summe=summe+power/fakul
        print("{:.4f}".format(summe))
Wir sollten dann unser Programm testen indem wir ein paar Werte eingeben.
Allerdings rechnet mein Programm zwar zunächst z.B. wenn ich 1 1 eingebe kommt 2.0000 raus
Wenn ich danach 2 5 eingabe rechnet er das auch noch richtig aus aber ab der 3. Eingabe kommen nur komische Werte raus.

z.B.
1. Eingabe 1 1 -> Ausgabe 2.000
2. Eingabe 2 5 -> Ausgabe 9.2667
3. Eingabe 20 60 ->Ausgabe 48165.6764 (richtig wäre)485165195.4097


Kann mir jemand helfen, den Fehler zu finden^^
Zuletzt geändert von Anonymous am Freitag 24. Oktober 2014, 11:01, insgesamt 5-mal geändert.
Grund: Bilder durch Text ersetzt.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Immortalmemo hat geschrieben:Mein Lösungsansatz:
http://puu.sh/clnJY/ed921c4f14.png
Es gibt bessere Wege um hier Code zu posten, benutze den "Code" Button.
Ich denke Du solltest summe=0 zwei Zeilen nach unten schieben.
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Der Code ist mathematisch nicht optimal. Zum Vergleich, was ich meine.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function

for x, n in ((1, 1), (2, 5), (20, 60)):
    sum, power, fak = 1, 1, 1
    # starts with 1 because 0! = 1 &&  x^0 = 1
    for i in range(n + 1)[1:]:
        power *= x
        fak *= i
        sum += float(power) / fak
            
    print("%.4f" % sum)
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

for i in range(n + 1)[1:]:
Warum einfach, wenn es auch kompliziert geht?

Code: Alles auswählen

for i in range(1, n + 1):
Daneben sollte man natuerlich die Berechnung von `exp` in eine eigenen Funktion verschieben und von der Eingabe trennen, so passiert der urspruengliche Fehler gar nicht erst.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Es gibt zig Wege exp(x) zu berechnen. Dein Weg ist aber nicht grundsätzlich falsch. In Deinem Code sind zwei Fehler drin
  1. Die Summe muss vor jeder neuen Berechnung Null gesetzt werden.
  2. x muss float sein
So funktioniert Dein Code:

Code: Alles auswählen

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

for line in stdin:
    summe=0
    line_elements = line.split()
    x = float(line_elements[0])
    n = int(line_elements[1])
    for i in range(n+1):
            power=pow(x,i)
            fakul=factorial(i)
            summe=summe+power/fakul
    print("{:.4f}".format(summe))
Und hier die Berechnung ohne (innere) Schleife

Code: Alles auswählen

import numpy as np
from scipy.misc import factorial

for x, n in ((1, 1), (2, 5), (20, 60)):
    i = np.arange(n+1, dtype=np.float64)
    summe = np.sum(x**i / factorial(i))
    print("%.15G" % summe)
Der Vorteil dieser Syntax ist, dass der Kern der Berechnung

Code: Alles auswählen

np.sum(x**i / factorial(i))
sehr große Ähnlichkeit zur mathematischen Formulierung hat

Code: Alles auswählen

 ____   
\   `   
  \     i
   \   x
   /   ──
  /    i!
/___,
a fool with a tool is still a fool, www.magben.de, YouTube
BlackJack

@MagBen: `x` kann ruhig ein `int` sein, es handelt sich ja um Python 3.

Der Nachteil von der Berechnung ohne innere Schleife ist das es Numpy voraussetzt.

Syntax die Nahe an der symbolischen, mathematischen Formulierung ist, kann man auch in ”reinem” Python ausdrücken: ``sum(x**i / factorial(i) for i in range(n + 1)))``.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

BlackJack hat geschrieben:`x` kann ruhig ein `int` sein, es handelt sich ja um Python 3.
Wie erklärst Du dann das hier:
Immortalmemo hat geschrieben:3. Eingabe 20 60 ->Ausgabe 48165.6764 (richtig wäre)485165195.4097
a fool with a tool is still a fool, www.magben.de, YouTube
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@MagBen: Den Unterschied kann man damit gar nicht erklären. Denn mit Integer-Arithmetik würden sich nur die letzten Stellen ändern, nicht aber die Größenordnung. Wie der Threadersteller auf die Zahl gekommen ist, wird er wohl selbst nicht mehr nachvollziehen können.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dann war der Code von Immortalmemo ja richtig. Falsch war lediglich das Ergebnis.
a fool with a tool is still a fool, www.magben.de, YouTube
Immortalmemo
User
Beiträge: 13
Registriert: Mittwoch 22. Oktober 2014, 00:02
Wohnort: Berlin

Hallo,

das Problem lag wirklich lediglich an der "Positionierung " von summe=0. Ich hab es in die 1. "for-schleife" reingenommen.
Hat soweit alles geklappt.

Bin überrascht über die zahlreiche Beteiligung. Vielen Dank :)
Antworten