Seite 1 von 1

Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 01:57
von Expanse
Hallo,

ich würde gerne durch eine Eingabe des Nutzer eine Berechnung durchführen. Allerdings sollte die Eingabe durch Variablen erfolgen. In einer Liste oder Dictionary sollen die Variablen mit den entsprechenden Werten abgespeichert sein.
Ein einfaches Beispiel:

Code: Alles auswählen

A, B, C = 1, 2, 3
liste = [A, B, C]
dictionary = {'A': 1, 'B': 2, 'C': 3)

result = input('Berechung: ')
print(result)
Leider habe ich bisher noch keinen guten Ansatz gefunden. Mit eval() habe ich es auch versucht, nur konnte ich dies nicht mit den Variablen verbinden.

Ich bedanke mich vorab.

Viele Grüße
Michael

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 11:16
von __deets__
Ich habe keine Idee, was du da vorhast. Kannst du mal ein Beispiel deiner Eingabe angeben?

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 12:10
von pillmuncher
eval() würde ich nicht verwenden, weil die Benutzer da alles Mögliche eingeben (und ausführen!) können, um auf deinem Rechner Schaden anzurichten.
Statt dessen benutze entweder ast.literal_eval() oder bau dir einen einfachen Interpreter für arithmetische Formeln. Zum Beispiel nach dieser Anleitung: https://www.booleanworld.com/building-r ... n_grammars

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 12:41
von pillmuncher
Just for funsies:

Code: Alles auswählen

from __future__ import print_function
from parcon import number, id_word, InfixExpr, Forward
from operator import add, sub, mul, truediv, neg


class Universe(dict):

    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        formula = Forward()
        term = (
            number[lambda value: float(value) if '.' in value else int(value)]
            | id_word[self.__getitem__]
            | '-' + formula[neg]
            | '(' + formula + ')'
        )
        term = InfixExpr(term, [('*', mul), ('/', truediv)])
        term = InfixExpr(term, [('+', add), ('-', sub)])
        formula << term
        self.evaluate = formula.parse_string


def main():
    solver = Universe(a=2, b=3, c=5)
    print(solver.evaluate('a'))
    print(solver.evaluate('b'))
    print(solver.evaluate('c'))
    print(solver.evaluate('123'))
    print(solver.evaluate('123.45 * a + b'))
    print(solver.evaluate('123.45 * (a + b) * -c'))


if __name__ == '__main__':
    main()
Ergebnis:

Code: Alles auswählen

2
3
5
123
249.9
-3086.25
Geht leider nur mit Python 2.7, weil Parcon da scheinbar stehengeblieben ist.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 15:31
von Expanse
Vielen Dank für die Antwort.
Leider kann ich Pardon nicht benutzen, ich arbeite mit Python 3.9. Trotzdem sehr guter Ansatz, wird mir sehr hilfreich sein.

Um nochmals mein Problem etwas genauer zu schildern:
Der User soll bspw. durch die Eingabe (Input) von

Code: Alles auswählen

A + B
das Ergebnis 3 erhalten. Genauso auch Sub, Mul, Div Rechnungen tätigen können.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 15:34
von __deets__
pillmuncher hat ja auch ein paar andere Ansaetze genannt. Probier die aus.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 16:03
von __blackjack__
@Expanse: `parcon` ist nicht das einzige Projekt seiner Art. Recht verbreitet und noch aktiv weiterentwickelt wird beispielsweise PyParser.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 16:49
von Expanse
Ok, ich bin noch nicht weit fortgeschritten in Python. Aber gibt es keine einfache Möglichkeit dass der User auf die Dictionary zugreifen kann.

Code: Alles auswählen

D = {'A': 1, 'B': 2, 'C': 3)

eingabe = input('Berechung: ')

if eingabe in D:
	print(D[eingabe])
nun wollte ich mit elif die Operators definieren, um Berechnungen durchführen zu können, wie A + B oder A + B - C

Code: Alles auswählen

elif '+' in eingabe:
	pass
elif '-' in eingabe:
	pass
...
Vielen Danke vorab für eure Hilfe!

Gruß
Michael

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 17:30
von __blackjack__
@Expanse: Wie sollen denn die Eingaben genau aussehen? Wir sind ja bisher davon ausgegangen, dass da beliebige Ausdrücke mit den Operatoren "+", "-", "*", und "/" stehen dürfen und das Punkt- vor Strichrechnung gilt. Vielleicht solltest Du erst einmal *genau* spezifizieren was das Programm am Ende können soll. Inklusive was passieren soll wenn der Benutzer etwas falsches eingibt.

So wie Du Dir das mit ``if`` und ``relif`` gedacht hast, wird das sicher nicht funktionieren, denn wenn der Benutzer "A + B" eingibt, dann ist das nicht im Wörterbuch und "+" wäre auch in "+" enthalten, oder in "+AB" oder "AB+".

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 18:14
von Expanse
Das Problem ist eigentlich, dass ich eine Sammlung von Variablen habe, mit denen ich Rechenoperationen durchführen lassen will (durch den User).

Die Variablen (A, B, C ... G) sind float-Werte (+ und - ) und sollen entweder in einer Liste oder Dictionary aufgelistet sein. Bisher bin ich mit Dictionary besser voran gekommen.

Die Rechenoperationen sollen einfachste Rechnungen sein: Add und Sub. Mul und Div wären Zusatz und kein Muss, in meinem Fall. Genauso auch mathematische Regeln wie Minus-Klammer kein muss.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 18:45
von __deets__
Du musst dir eben einen parser schreiben. Wenn weder Klammern noch andere Operatoren ausser + und - vorkommen, ist das ja trivial: du tokenisierst die Eingabe, und gehst die von links nach rechts durch. Am Anfang ist das Ergebnis 0, die erste Variable setzt es dann auf den Wert der Variablen, dann kommt ein Operator, den du dir merkst, und dann kommt die naechste Variable, und zusammen mit dem Operator berechnest du das neue Ergebnis. Etc.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 20:22
von Expanse
Ja genau, so habe ich es anfangs auch gemacht. Allerdings soll jede Berechnung mit einer einzigen Eingabe erfolgen (also in einer Zeile).
Also: A + B + C
und nicht als getrennte Inputs:
A
+
B
+
C

Gibt es hierzu auch eine Möglichkeit? Mit der split() Funktion habe ich auch versucht. Bin damit aber auch nicht weitergekommen

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 20:37
von __deets__
Das ist doch nahezu das Gleiche. Selbstverstaendlich kannst u auch in einer Zeile

A + B

oder auch

A+B

eingeben.

Da du nicht kontrollieren kannst, ob deine Benutzer wirklich Leerzeichen eingeben, reicht split eben nicht.

Stattdessen musst du eben zeichenweise ueber die Eingabe laufen, und pruefen was es ist:

- ein Buchstabe aus deiner Variablenmenge -> Wert behandeln
- ein Operator -> Operation merken
- ein Leerzeichen -> ignorieren
- irgendwas anderes: Fehler ausgeben.

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 21:05
von Expanse
Ja, aber input ist mit einer For-Schleife der Länge einer bestimmten Liste verknüpft. Der User soll dementsprechend die Variablen bzw. Variablenberechnungen eingeben können und die Ergebnisse sollen wiederum in einer Liste abgespeichert werden. Deswegen müsste jede Berechnung in einer Zeile erfolgen

Re: Berechnung mit Input

Verfasst: Samstag 2. Januar 2021, 21:09
von __blackjack__
@Expanse: Ich verstehe nicht so recht was Du uns damit sagen willst. __deets__ hat beschrieben wie man für eine Rechnung vorgehen muss. Wenn Du das hast, kannst Du das ja ganz einfach für jede Zeile aufrufen.