Taschenrechner Fehler finden

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

Hallo,

ich habe ein Problem, ich habe einen Taschenrechner programmiert. Dieser ist auf einer Linie, das heißt man muss nur eine Zeile eingeben. Doch bei "Mal" hat etwas nicht hin. Es kommt immer der Fehler : Traceback (most recent call last):
File "C:/Users/Felix/AppData/Local/Programs/Python/Python35/nn.py", line 134, in <module>
Rechnung = Rechnung_anfang + erg + Rechnung_ende
TypeError: Can't convert 'int' object to str implicitly


Mein Programmcode lautet:

Code: Alles auswählen

def mal(FaktorEins, FaktorZwei):
    erg = FaktorEins * FaktorZwei
    return erg

def plus(Summand1, Summand2):
    erg = Summand1+Summand2
    return erg

def minus(Minuend, Subtrahend):
    erg = Minuend-Subtrahend
    return erg

def geteilt(Dividend, Divisor):
    if Dividend%Divisor==0:
       erg = int(Dividend/Divisor)
    else: erg = Dividend/Divisor
    return erg

def hoch(Basis, Exponent):
    erg = Basis**Exponent
    return str(erg)

def wurzelrechnen(Wurzel, Zahl):
    erg = int(Zahl**(1/Wurzel))
    return str(erg)


Rechnung = str(input("Geben Sie bitte die Rechnung ein, die Sie ausrechnen möchten:    "))
Laenge = len(Rechnung)
stelle = 0
RechnungAusgefuehrt = False
Fertig = False
RechnungFertig = False


while RechnungFertig==False:
    
    Fertig = False
    while stelle<len(Rechnung) and Fertig==False:
        if ord(Rechnung[stelle])>47 and ord(Rechnung[stelle])<58:
            stelle+=1
        else:
            stelle+=1
            Fertig=True
    if Fertig==False:
            RechnungFertig = True
    

    RechnungAusgefuehrt = False

    stelle = 0
    while stelle<len(Rechnung) and RechnungAusgefuehrt==False and RechnungFertig==False:
        if Rechnung[stelle] == ".":
            davor = 1
            Wurzel = ""
            while ord(Rechnung[stelle-davor])>47 and ord(Rechnung[stelle-davor])<58 and stelle-davor>=0:
                Wurzel = Rechnung[(stelle-davor)]+Wurzel
                davor+=1
            davor-=1

            danach = 8
            Zahl = Rechnung[stelle+danach]
            danach = 9
            while ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58:
                Zahl = Zahl + Rechnung[stelle+danach]
                danach+=1
            Wurzel = int(Wurzel)
            Zahl = int(Zahl)
            Ergebnis = wurzelrechnen(Wurzel, Zahl)
            Rechnung_anfang = Rechnung[:stelle-davor]
            Rechnung_ende = Rechnung[stelle+danach+1:]
            Rechnung = Rechnung_anfang + Ergebnis + Rechnung_ende
            RechnungAusgefuehrt = True
        else: stelle += 1

    stelle = 0
    while stelle<len(Rechnung) and RechnungAusgefuehrt==False and RechnungFertig==False:
        if Rechnung[stelle]=="^":
            davor = 1
            Basis = ""
            while ord(Rechnung[stelle-davor])>47 and ord(Rechnung[stelle-davor])<58 and stelle-davor>=0:
                Basis = Rechnung[(stelle-davor)]+Basis
                davor+=1
            davor-=1

            danach = 1
            Exponent = ""
            while ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58 and stelle+danach+1<len(Rechnung):
                Exponent = Exponent + Rechnung[stelle+danach]
                danach+=1
            if ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58:
                Exponent = Exponent + Rechnung[stelle+danach]
                danach+=1
            Basis = int(Basis)
            Exponent = int(Exponent)
            Ergebnis = hoch(Basis, Exponent)
            Rechnung_anfang = Rechnung[:stelle-davor]
            if danach==1:
                Rechnung_ende = Rechnung[stelle+danach+1:len(Rechnung)]
            else:   Rechnung_ende = Rechnung[stelle+danach:len(Rechnung) ]
            Rechnung = Rechnung_anfang + Ergebnis + Rechnung_ende
            RechnungAusgefuehrt = True
        else: stelle+=1

   

        
    stelle = 0
    while stelle<len(Rechnung) and RechnungAusgefuehrt==False and RechnungFertig==False:
        if Rechnung[stelle]=="*":
            davor=1
            FaktorEins = ""
            while ord(Rechnung[stelle-davor])>47 and ord(Rechnung[stelle-davor])<58 and stelle-davor>=0:
                FaktorEins = Rechnung[stelle-davor]+FaktorEins
                davor+=1
            davor-=1

            danach = 1
            FaktorZwei = ""
            while ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58 and stelle+danach+1<len(Rechnung):
                FaktorZwei = FaktorZwei + Rechnung[stelle+danach]
                danach+=1
            if ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58:
                FaktorZwei = FaktorZwei + Rechnung[stelle+danach]
                danach+=1
            FaktorEins = int(FaktorEins)
            FaktorZwei = int(FaktorZwei)
            erg = mal(FaktorEins, FaktorZwei)
            Rechnung_anfang = Rechnung[:stelle-davor]
            if danach==1:
                Rechnung_ende = Rechnung[stelle+danach+1:len(Rechnung)]
            else:
                Rechnung_ende = Rechnung[stelle+danach:len(Rechnung)]
            Rechnung = Rechnung_anfang + erg + Rechnung_ende
            RechnungAusgefuehrt = True                
        else: stelle+=1 #NICHT LOESCHEN!! Muss ans Ende der mal/geteilt Berechnung


Es wäre echt toll wenn mir jemand helfen könnte, da ich gerade echt verzweifle und dies bald als Schulaufgabe abgeben muss.


Vielen dank für die Mühe die Sie/Ihr euch macht, auch wenn es nicht klappen sollte.

MfG Nudrec
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Nudrec: in Deinem Code einen Fehler suchen zu wollen, macht bestimmt keinen Spaß. Das Hauptprogramm ist viel zu lang. Statt Teile 5 mal zu kopieren solltest Du Funktionen schreiben, die so klar und kurz sind, dass man ihre Richtigkeit einfach prüfen kann. Warum belegst Du vor der großen while-Schleife alle möglichen Variablen mit Werten, obwohl sie nicht gebraucht werden? Man prüft nicht explizit auf True oder False, True ist einfach schon der Wert der boolschen Variable, prüfen auf False erreicht man mit "not". Es gibt str.isdigit, das verkürzt z.B. die ersten 12 Zeilen der großen while-Schleife auf "while not Rechnung.isdigit():". Die Bedingungen der while-Schleifen sind auch viel zu kompliziert. Es gibt break.

Insgesamt ist die Logik des Programms falsch. Du ersetzt die in der Mathematik übliche Punkt-vor-Strich-Regel durch eine seltsame Minderheitenoperationen-werden-bevorzugt-Regel. Normalerweise wird der String erst in eine Folge von Einheiten (Zahl, Operator, Klammer, etc.) zerlegt, die dann nach den Prioritätsregeln abgearbeitet wird.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

@Sirus3 Das heißt meine Logik ist komplett falsch und ich soll von vorne Anfangen? :( Das wäre nicht so toll. Meine Idee in dieser Schreibweise war diese, das ich nach und nach den Term auflöse. Gibt es eine Möglichkeit auch ide Regeln einzubringen, indem man nurKleinigkeiten verändert, denn ich hab allein für das was da steht mehrere Stunden, ich glaube mindestens 15 dran gesessen und alles umzuschreiben, na ja.
Letztenendlich geht ja nur dieser Teil nicht

Code: Alles auswählen

 
 stelle = 0
    while stelle<len(Rechnung) and RechnungAusgefuehrt==False and RechnungFertig==False:
        if Rechnung[stelle]=="*":
            davor=1
            FaktorEins = ""
            while ord(Rechnung[stelle-davor])>47 and ord(Rechnung[stelle-davor])<58 and stelle-davor>=0:
                FaktorEins = Rechnung[stelle-davor]+FaktorEins
                davor+=1
            davor-=1

            danach = 1
            FaktorZwei = ""
            while ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58 and stelle+danach+1<len(Rechnung):
                FaktorZwei = FaktorZwei + Rechnung[stelle+danach]
                danach+=1
            if ord(Rechnung[stelle+danach])>47 and ord(Rechnung[stelle+danach])<58:
                FaktorZwei = FaktorZwei + Rechnung[stelle+danach]
                danach+=1
            FaktorEins = int(FaktorEins)
            FaktorZwei = int(FaktorZwei)
            erg = mal(FaktorEins, FaktorZwei)
            Rechnung_anfang = Rechnung[:stelle-davor]
            if danach==1:
                Rechnung_ende = Rechnung[stelle+danach+1:len(Rechnung)]
            else:
                Rechnung_ende = Rechnung[stelle+danach:len(Rechnung)]
            Rechnung = Rechnung_anfang + erg + Rechnung_ende
            RechnungAusgefuehrt = True                
        else: stelle+=1
Wäre echt cool wenn es eine andere Lösung gibt als alles neu schreiben.

Danke für die Hilfe
MfG Nudrec
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Nudrec: Du hast ja sicher während der 15 Stunden etwas dazugelernt, so dass das Neu-Schreiben deutlich schneller geht. Als erstes solltest Du eine Funktion schreiben, die einen String in eine Liste aus Operatoren und Zahlen umwandelt. Wenn das programmiert ist und ausgiebig getestet, kannst Du Dich an den nächsten Schritt machen, die Liste in eine Folge von Summanden aufteilen, die Teillisten in eine Folge von Faktoren und diese nach Exponenten und Basen.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

@sirius3 Danke für die Hilfe, ich werde also neu beginnen und hoffe es klappt dann . Vlt kannst du mir ja helfen wenn ich noch eine Frage hab. Danke

MfG Nudrec
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Nudrec: hoffen brauchst Du beim Programmieren nicht. Teile Deine Aufgabe in so keine Häppchen, dass Du eine ganz konkrete Vorstellung davon hast, was diese Funktion machen soll. Schreibe die Funktion und teste sie so lange, bis Du sicher bist, dass sie das tut, was Du erwartest. Arbeite Dich Schritt für Schritt vor, Aufbauend auf einfachen Funktionen hin zu immer komplexeren. Zum Schluß bist Du fertig.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

@Sirius3 Bin fertig. Hab jetzt zwar einen neuen, doch ich habe den "alten" repariert, er geht nun. Es fehlte nur ein " str() ". Und ohne das ich was weiter umgeschrieben habe kann man mehrere Zahlen zusammenrechen wie 10+10*2.

Trotzdem danke für die Hilde

MfG Nudrec
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

So ein Problem hab ich noch, und zwar geht jetzt alles doch ich hab bei der Gui einen Fehler, bei dem ich nicht weiß was ich tun soll. Villeicht kann mir jeamnd helfen. Genauer gesagt geht es um diesen Fehler: " File "C:\Users\Felix\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "O:\Schule\Info\Python\Taschenrechner\taschenrechner-II\Taschenrechner.py", line 4, in buttonStart
Rechnung = float(entryRechnung.get())
ValueError: could not convert string to float: '10+10'
"

Das heißt ja das ich zwei verschiedene Sachen gebe, welche sich aufheben, doch das hab ich nicht.
Ich hab lediglich dieses an gegeben:

Code: Alles auswählen

Rechnung = float(entryRechnung.get())
Was ist daran falsch . Es wäre toll wenn es eine Lösung gibt und ich sie erfahre.

Danke für Eure Hilfe

MfG Nudrec
BlackJack

@Nudrec: Die `get()`-Methode liefert den Inhalt des Eingabefelds als Zeichenkette und `float()` wandelt (unter anderem) eine Zeichenkette die eine Zahl repräsentiert in eine Gleitkommazahl um. Nun ist '10+10' allerdings keine Darstellung einer Zahl. Du möchtest die Zeichenkette vielleicht Deiner Funktion übergeben die Du geschrieben hast um Zeichenketten mit einer Rechnung auszuwerten.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

---
Zuletzt geändert von Nudrec am Montag 8. Februar 2016, 17:40, insgesamt 1-mal geändert.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

Wenn man das float weglässt geht es nichtmehr :( Was muss ich sonst schreiben'?
BlackJack

@Nudrec: Was heisst es geht nicht mehr? Mit `float()` geht es doch offensichtlich auch nicht, also geht es insgesamt nicht. Was Du schreiben musst, kann man so nicht sagen. Halt das richtige, also das was nötig ist, damit das passiert was Du möchtest.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

BlackJack hat geschrieben:@Nudrec: Was heisst es geht nicht mehr? Mit `float()` geht es doch offensichtlich auch nicht, also geht es insgesamt nicht. Was Du schreiben musst, kann man so nicht sagen. Halt das richtige, also das was nötig ist, damit das passiert was Du möchtest.

So jetzt kommt ein anderesr Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\Felix\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__
    return self.func(*args)
  File "O:\Schule\Info\Python\Taschenrechner\taschenrechner-II\Taschenrechner.py", line 4, in buttonStart
    Rechnung = entryRechnung.get('text')
TypeError: get() takes 1 positional argument but 2 were given
Den 'text' muss ich einfügen sonst schmiert Python ab.

Eine Ahnung warum??

MfG Nudrec
BlackJack

@Nudrec: Das Argument musst Du da nicht übergeben, nein Du darfst das sogar nicht tun, denn genau das sagt Dir die Fehlermeldung. `Entry.get()` erwartet kein Argument. (Ausser dem impliziten `self`.)
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@Nudrec: Vermutlich möchtest du einen einfachen Parser für arithmetische Ausdrücke schreiben. Dabei könntest du das re-Modul aus der Standard-Bibliothek verwenden, um zuerst den arithmetischen Ausdruck in Tokens zu zerlegen. Der Parser kann dann auf einer Sequenz von Tokens operieren. Am einfachsten wäre wohl, einen rekursiv absteigenden Parser zu programmieren. Oder man verwendet eine bestehende Parser-Bibliothek wie pyparsing oder Parcon, dann kann man sich das Tokeinsieren sparen.
In specifications, Murphy's Law supersedes Ohm's.
Nudrec
User
Beiträge: 10
Registriert: Samstag 6. Februar 2016, 14:26

An alle die geholfen habe. Egal wie. Ich Danke euch hab den Taschenrechner schon seit einiger Zeit fertig. Es hat alles geklappt. Danke dafür :D :idea:

MfG Nudrec
Antworten