Problem bei Berechnung

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
Erbsensuppe
User
Beiträge: 2
Registriert: Sonntag 26. September 2010, 13:17

Hallo,
ich bin neu bei der Programmiersprache Python und hab mal versucht ein kleines Programm zu schreiben. Mit der Formel

Code: Alles auswählen

Rge = float(1 / R1) + (1 / R2) + (1 / R3) + (1 / R4) + (1 / R5) + (1 / R6) + (1 / R7) + (1 / R8) + (1 / R9) + (1 / R10)
sollen Widerstände in Parallelschaltung berechnet werden. Allerdings kommt bei "Rge" bei mir immer 0 raus. Ich hab auch schon anhand eines Buches nach dem Fehler gesucht, aber nicht finden können, was den Fehler verursacht.
Der gesammte Code ist:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import math
print "Dieses Program ist zur Berechnung von Widerständen in Parallel- und Reihenschaltung."

R1 = 0
R2 = 0
R3 = 0
R4 = 0
R5 = 0
R6 = 0
R7 = 0
R8 = 0
R9 = 0
R10 = 0
R1 = input("erster Widerstand")
R2 = input("zweiter Widerstand")
R3 = input("dritter Widerstand")
R4 = input("vierter Widerstand")
R5 = input("fünfter Widerstand")
R6 = input("sechster Widerstand")
R7 = input("siebter Widerstand")
R8 = input("achter Widerstand")
R9 = input("neunter Widerstand")
R10 =input("zehnter Widerstand")

Rges = float(R1 + R2 + R3 + R4 + R5 + R6 + R7 + R8 + R9 + R10)
Rge = float(1 / R1) + (1 / R2) + (1 / R3) + (1 / R4) + (1 / R5) + (1 / R6) + (1 / R7) + (1 / R8) + (1 / R9) + (1 / R10)
print "Rg in Reihenschaltung hat:", Rges, "Ohm"
print "Rg in Parallelschaltung hat:", Rge , "Ohm"

Ich danke schon mal im Vorraus.
BlackJack

Der Fehler ist die ganzzahlige Division:

Code: Alles auswählen

In [829]: 1 / 42
Out[829]: 0

In [830]: 1. / 42
Out[830]: 0.023809523809523808
Wenn beide Operanden ganze Zahlen sind, kommt auch wieder nur der ganzzahlige Anteil heraus.

`input()` sollte man nicht verwenden. Die Funktion erwartet einen syntaktisch korrekten Python-Ausdruck als Eingabe und wertet den aus. Zum einen ist das eine Sicherheitslücke wenn der Benutzer nahezu beliebigen Code ausführen kann, zum anderen lässt sich da nur umständlich auf falsche Eingaben reagieren, denn es kann ja wirklich *alles* passieren, bis hin zu einem `SyntaxError` wenn der Benutzer ungültigen Python-Quelltext eingibt.

Und wenn man anfängt Namen durchzunummerieren, will man lieber eine Liste verwenden.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Hallo und Willkommen im Forum,

das Problem ist die Integer-Division. Da hilft auch nicht float, weil die Division zuerst ausgewertet wird:

Code: Alles auswählen

>>> 1 / 3
0
>>> 1.0 / 3.0
0.33333333333333331
Weitere Anmerkungen zum Code:
- Variablen müssen in Python nicht deklariert werden. Die ganzen Zuweisungen (R1 = 0 etc.) sind daher unnötig.
- Wenn man Namen durchnummeriert, will man meist eine Liste (R = x) benutzen.
- Anstelle von "input" solltest du "raw_input" verwenden und in z.B. "float" umwandeln. "input" führt jeden validen Python-Code aus, den der Benutzer eingibt, was unsicher ist.
- Wenn du eine Liste für die Widerstände benutzt, kannst du mit der Funktion "sum()" arbeiten.

Grüße
Gerrit
BlackJack

Das könnte dann so aussehen:

Code: Alles auswählen

def main():
    print 'Dieses Program ist zur Berechnung von Widerständen in Parallel-'
    print 'und Reihenschaltung.'
    
    resistors = list()
    for i in xrange(10):
        resistors.append(float(raw_input('%d. Widerstand: ' % (i + 1))))
    series = sum(resistors)
    parallel = sum(1 / r for r in resistors)
    
    print 'Rg in Reihenschaltung hat %f Ohm.' % series
    print 'Rg in Parallelschaltung hat %f Ohm.' % parallel


if __name__ == '__main__':
    main()
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Und wenn man die Anzahl nicht vorher festlegen mag:

Code: Alles auswählen

from itertools import count
resistors = [float(r) for r in iter(lambda n=count(1): raw_input('Widerstand %d: ' % n.next()), '')]
Und wenn es ein Maximum geben soll, gehts sogar ohne itertools:

Code: Alles auswählen

NMAX = 10
resistors = [float(r) for r in iter(lambda n=iter(xrange(1, NMAX+1)): raw_input('Widerstand %d: ' % n.next()), '')]
:twisted:
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Erbsensuppe
User
Beiträge: 2
Registriert: Sonntag 26. September 2010, 13:17

Vielen Dank für die Antworten.
@gkuhl:
Das mit der Deklaration hab ich aus einem Beispiel aus dem Buch. Und kannte das auch noch von meinen Versuchen mit C. Die Sache mit "raw_input" hab ich auch gelesen, aber da stand etwas, dass man hinterher die Eingabe noch irgendwie umwandeln muss. Also hab ich erst mal die einfachere aber unsichere Version gewählt.
@BlackJack:
Danke für die Überarbeitung des Codes. Jetzt hab ich ein paar Anhaltspunkte, wie etwas in dieser Richtung funktionieren kann. Versuche mal das ganze zu verstehen und übe noch ein bisschen.
@birkenfeld:
Die Ideen sind auch interessant. Werde ich auch mal versuchen anzuwenden.
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Diesen Fehler von Python (ja, es ist ein Fehler, deshalb ist ja auch in Python 3.x anders) kann man dadurch beheben, dass man am Beginn des Quellcodes die Zeile

Code: Alles auswählen

from __future__ import division
ausführt.
Dann klappt die Formel so wie am Anfang gepostet.
Antworten