problem mit selbstgemachtem TR

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
Luap12
User
Beiträge: 19
Registriert: Donnerstag 24. Juni 2010, 21:38

Code: Alles auswählen

def ka():
    print()
    print("------------")
    print()

def ga():
    print()
    print()
    print("------------")
    print()
    print()

mm = 1

while mm != 0:
    print("""Geben sie an, welche Rechenoperation sie ausführen wollen.
      1 = Addition
      2 = Subtraktion
      3 = Multiplikation
      4 = Division
      5 = Quadrieren""")

    ka()

    x = input()
    zahla = int(x)
    
    # Addition
    if zahla == 1:

        summe = 0

        print("Geben sie an, wieviele Zahlen sie addieren wollen")

        ka()

        m = int(input())
        m += 1


        for i in range(1,m):
            fehler = True

            while fehler:
                zahl = input(str(i) + ". Summand eingeben: ")

                try:
                    summe += float(zahl)
                    fehler = False

                except:
                    print("Das war keine Zahl")
                    fehler = True

        print("Summe:", summe)
        ka()
        print("0 = Programm schließen")
        print("Andere Zahl um zum Hauptmenü zurück zugelangen")
        mm = int(input())

        ga()
        
    # Subtraktion
    elif zahla == 2:
        
        print("Bitte geben sie den Minuend ein.")
        minuend = float(input())
        
        print("Bitte geben sie den Subtrahend ein.")
        subtrahend = float(input())
        
        differenz = minuend - subtrahend
        
        print("Differenz:", differenz)
        ka()
        print("0 = Programm schließen")
        print("Andere Zahl um zum Hauptmenü zurück zugelangen")
        mm = int(input())


    # Multiplikation
    elif zahla == 3:

        produkt = 0

        print("Geben sie an, wieviele Zahlen sie multiplizieren wollen")

        ka()

        m = int(input())
        m += 1


        for i in range(1,m):
            fehler = True

            while fehler:
                zahl = input(str(i) + ". Faktor eingeben: ")

                try:
                    produkt *= float(zahl) #hier ist mein problem
                    fehler = False

                except:
                    print("Das war keine Zahl")
                    fehler = True

        print("Produkt:", produkt)
        ka()
        print("0 = Programm schließen")
        print("Andere Zahl um zum Hauptmenü zurück zugelangen")
        mm = int(input())

        ga()
Also, ich habe mal den ganzen TR-Code aufgelistet. Ich habe das so gemacht das man bei zb. Addition eingeben kann wieviele Zahlen man addiert. Bei der Multiplikation ist allerdings das Problem das beim Produkt am Ende immer wieder 0 rauskommt, völlig unlogisch, finde ich.^^ Denn bei der Addition funktioniert es ja. Bei dem Kommentar "Hier ist mein Problem" ist mein Problem^^, aber das verstehe ich nicht da ich ja nur das Additionszeichen durch ein Multiplikationszeichen ersetzt habe... komisch!
Bin schon am verzweifeln!!


LG
Luap12
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ein Tipp: Was ist das neutrale Element der Multiplikation? Bei der Addition hast du korrekt 0 gewählt.

Stefan
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hua... man weiß bei dem Code gar nicht, wo man anfangen soll...

- zunächst einmal: Beachte PEP8 besser! Wozu die vielen Leerzeilen?
- Die Bennenung ist "suboptimal"; was sollen denn "ga()" und "ka()" tun?
- Wieso nutzt Du Funktionen nicht für die bessere Aufgliederung Deines Tools? Du könntest so eine universelle Eingaberoutine schreiben, und dieses nicht jedes Mal für alle Rechen-OPs und Menüauswahlen wiederholen! Nennt man auch DRY (Don't repeat yourself) Auch für jede Operation könnte man eine Funktion schreiben.
- Anstelle der "if zahla == x"-Kaskaden würde man da besser ein Dictionary nutzen, um an die ausgewählte Funktion zu verzweigen.
- Generell gibt es das operator-Modul. In diesem findet man die Funktionen, die Du hier anbietest auch als Funktion. Somit könnte man sehr kompakten Code schreiben, der im Menü-Dispatcher direkt die richtige Funktion mit den Operanden aufruft.
- Entferne den Code auf Moduleben und lagere den eigentlichen Einstieg in eine main()-Funktion aus mit dem 'if __name__ == "__main__"'-Hook.
- bei except fange immer nur die konkreten Exceptions auf, die Du auch behandeln willst.

Zu Deinem Problem:
Denk mal drüber nach, wie Du "produkt" initialisierst ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Luap12
User
Beiträge: 19
Registriert: Donnerstag 24. Juni 2010, 21:38

Hmm, klar!? Produkt = 0, und das dann mal ne Zahl ist immer 0!! Blöder Fehler!!^^ Danke!
Hyperion hat geschrieben:- zunächst einmal: Beachte PEP8 besser! Wozu die vielen Leerzeilen?
Was genau ist PEP8?

Hyperion hat geschrieben:- Die Bennenung ist "suboptimal"; was sollen denn "ga()" und "ka()" tun?
das hat für mich system^^ ga= großer abstand; ka = kleiner Abstand :)
Hyperion hat geschrieben:- Wieso nutzt Du Funktionen nicht für die bessere Aufgliederung Deines Tools? Du könntest so eine universelle Eingaberoutine schreiben, und dieses nicht jedes Mal für alle Rechen-OPs und Menüauswahlen wiederholen! Nennt man auch DRY (Don't repeat yourself) Auch für jede Operation könnte man eine Funktion schreiben.
- Anstelle der "if zahla == x"-Kaskaden würde man da besser ein Dictionary nutzen, um an die ausgewählte Funktion zu verzweigen.
- Generell gibt es das operator-Modul. In diesem findet man die Funktionen, die Du hier anbietest auch als Funktion. Somit könnte man sehr kompakten Code schreiben, der im Menü-Dispatcher direkt die richtige Funktion mit den Operanden aufruft.
- Entferne den Code auf Moduleben und lagere den eigentlichen Einstieg in eine main()-Funktion aus mit dem 'if __name__ == "__main__"'-Hook.
- bei except fange immer nur die konkreten Exceptions auf, die Du auch behandeln willst.
Den Rest verstehe ich beim besten Willen nicht... Sry, aber ich bin noch nicht solange dabei, ich bin froh das der TR erstmal so funktioniert wie er hier beschrieben ist.
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

Luap12 hat geschrieben: Was genau ist PEP8?
Let me google that for you.
Luap12
User
Beiträge: 19
Registriert: Donnerstag 24. Juni 2010, 21:38

Liffi hat geschrieben:
Luap12 hat geschrieben: Was genau ist PEP8?
Let me google that for you.
Ok, danke. Ich werde versuchen, mich zu bessern^^
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Luap12 hat geschrieben: Was genau ist PEP8?
http://www.python.org/dev/peps/pep-0008/
Da drin wird beschrieben, wie man seinen Quelltext formatieren sollte. Hältst Du Dich an die Konvention, so können anderen Deinen Code leichter lesen und verstehen.
Luap12 hat geschrieben:
Hyperion hat geschrieben:- Die Bennenung ist "suboptimal"; was sollen denn "ga()" und "ka()" tun?
das hat für mich system^^ ga= großer abstand; ka = kleiner Abstand :)
Du erkennst selber den Denkfehler? "für mich..." ;-) In einem halben Jahr weißt Du das ggf. nicht mehr so einfach. Als ich zu proggen lernte mit dem genialen Commodore Basic V2.0 wäre ich froh über beliebig lange Namen gewesen. (@BlackJack: Ja, ich weiß, man konnte auch mehr als 2 Byte lange Namen in den Quellcode schreiben, aber beim Lookup hat der Interpreter ja nur die ersten beiden benutzt ;-) )
Also: wähle stets aussagekräftige Namen!
Hyperion hat geschrieben:- Wieso nutzt Du Funktionen nicht für die bessere Aufgliederung Deines Tools? Du könntest so eine universelle Eingaberoutine schreiben, und dieses nicht jedes Mal für alle Rechen-OPs und Menüauswahlen wiederholen! Nennt man auch DRY (Don't repeat yourself) Auch für jede Operation könnte man eine Funktion schreiben.
Also ich denke das kann man auch als Anfänger kapieren ;-) (Zumal Du ja schon Funktionen nutzt!)
Beispiel:

Code: Alles auswählen

def add():
    # hier Code für Addition

def sub():
    # s.o.

def main():
    # hier Schleife mit Menüauswahl
    while True:
        print "Menü: 1-Addition, 2-Subtraktion, ..."
        choice = int(input(...))
        if choice == 1:
            add()
        elif choice == 2:
            sub()
Zusätzlich könntest Du eine Funktion basteln, die Dir eine beliebige Frage printet und dann einen Zahlenwert zurückliefert, so in der Art:

Code: Alles auswählen

def get_value(question):
    while True:
        try:
            return int(input(question))
        except ValueError, e:
            print "Bitte nur Zahlen eingeben!"
Damit kannst Du dann die einzelnen Operationen verschlanken:

Code: Alles auswählen

def add():
    summand_a = get_value("Bitte geben Sie den 1. Summanden ein")
    summand_b = get_value("Bitte geben Sie den 1. Summanden ein")
    return summand_a + summand_b
Hyperion hat geschrieben: - Anstelle der "if zahla == x"-Kaskaden würde man da besser ein Dictionary nutzen, um an die ausgewählte Funktion zu verzweigen.
Damit ist folgendes Konstrukt gemeint:

Code: Alles auswählen

operations = {
    1: add,
    2: sub
}
# Aufruf von Funktion, die zum Schlüssel "1" passt:
operations[1]()
# Anstelle eines konkreten Schlüssels, nimm die Benutzeriengabe der Menüwahl
choice = get_choice()
operations[choice]()
Damit kannst Du relativ einfach weitere Funktionen nachträglich hinzufügen, ohne in irgendwelchen if...elif..else-Konstrukten rumzupfuschen. Auch die Ausgabe der Menüoptionen sind so dynamisch, da Du den Text ja aus dem Dictionary gewinnen könntest, wenn man es noch ein wenig aufbohrt:

Code: Alles auswählen

operations = {
    1: {"op": add, "info": "Addition"},
    2: {"op": sub, "info": "Subtraktion"
}
choice = get_choice(operations)

# und hier zu Funktion
def get_choice(operations):
    for key, value in operations.iteritems():
        print "{key} - {info}".format(key, **value)
    return int(input("Auswahl"))
Natürlich könnte man auch die oben bereits implementierte nutzen und die Ausgabe der Optionen separat implementieren.
Hyperion hat geschrieben: - Generell gibt es das operator-Modul. In diesem findet man die Funktionen, die Du hier anbietest auch als Funktion. Somit könnte man sehr kompakten Code schreiben, der im Menü-Dispatcher direkt die richtige Funktion mit den Operanden aufruft.
Im operator-Modul gibt es Wrapper für die von Dir genutzten Operatoren:

Code: Alles auswählen

In [28]: from operator import add

In [29]: add(1, 4)
Out[29]: 5

In [30]: from operator import sub

In [31]: sub(add(1, 4), 2)
Out[31]: 3
Dies kann man nun nutzen, um sich die eigene Implementierung der Funktionen zu sparen. Wir verzweigen im Dispatcher eben nicht auf unsere eigenen Funktionen, sondern die bereits im operator-Modul implementierten.

Code: Alles auswählen

from operator import add, sub

operations = {
    1: add,
    2: sub
}
# Benutzer nach Menüauswahl fragen -> an "choice" binden
# Benutzer nach Operanden fragen -> an "op_a", "op_b" binden
# und dann der Aufruf:
operations[choice](op_a, op_b)
Hyperion hat geschrieben: - Entferne den Code auf Moduleben und lagere den eigentlichen Einstieg in eine main()-Funktion aus mit dem 'if __name__ == "__main__"'-Hook.
Verlagere alles in Funktionen und schreibe dann ganz unten:

Code: Alles auswählen

# dein bisheriger Code
# Füge eine Funktion ein, die "main" heißt. Das ist quasi der Einstieg in deine Logik
def main():
    # hier Code, z.B. die Endlosschleife mit menüauswahl usw.

if __name__ == "__main__":
    main()
Somit kannst Du Dein Script per import selber in einer Shell oder einem anderen Script importieren und die Funktionen getrennt aufrufen. Zudem kannst Du es aber auch ganz "normal" als Script starten.
Hyperion hat geschrieben: - bei except fange immer nur die konkreten Exceptions auf, die Du auch behandeln willst.
Naja, habe ich ja oben schon gezeigt mit dem "ValueError". Indem Du die konkrete Exception angibst, die Du behandeln willst, verschluckt Dein Programm keine anderen evtl. aufgetretenen Exceptions. So wie bei Dir bekommst Du andere Ausnahmen nicht mit.

Hyperion hat geschrieben: Den Rest verstehe ich beim besten Willen nicht... Sry, aber ich bin noch nicht solange dabei, ich bin froh das der TR erstmal so funktioniert wie er hier beschrieben ist.
So, ich hoffe ich konnte ein wenig Licht ins Dunkel bringen :-)

Btw: Iirc BlackJack (oder doch sma?) hatten grad neulich erst ein nettes Taschenrechner-Beispiel hier gezeigt, welches viele von den Techniken zeigt, die ich hier kurz umrissen habe.

Edit: Da isser: http://python-forum.de/viewtopic.php?p=175585#p175585
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

mal was ganz anderes: Bei dieser Art von Menüführung bietet sich das curses-Modul an. :-)

Gruß, noisefloor
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

noisefloor hat geschrieben:Hallo,

mal was ganz anderes: Bei dieser Art von Menüführung bietet sich das curses-Modul an. :-)
Wobei curses irgend wie eine ätzende API hat... gefällt mir gar nicht.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Daher ja auch urwid.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Luap12
User
Beiträge: 19
Registriert: Donnerstag 24. Juni 2010, 21:38

Ah, ok, jetzt versteh ich das, wenigsten das meiste^^
Bin euch sehr dankbar!!

Und das mit dem PEP8 werde ich mir auch noch angewöhnen!
Antworten