Laden...

[Lösung mit IronPython?] Formel aus String berechnen.

Erstellt von Fracoon vor 16 Jahren Letzter Beitrag vor 16 Jahren 13.844 Views
F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
[Lösung mit IronPython?] Formel aus String berechnen.

Hi@all

hab da mal wieder ne Frage.. =) Über die Suche bin ich nicht fündig geworden.

Und zwar:

Ist es möglich eine Mathematische Formel die in einem String gespeichert ist automatisch berechnen zu lassen? Also unter beachtung aller matematischer Regeln?

z.B. sowas :


string formel = "(2*2+1)/8+(8*8)";

N
335 Beiträge seit 2006
vor 16 Jahren

Hi!

Klar ist das möglich. Das Thema war hier schon oft, bitte benutze die Suchfunktion und poste die besten Treffer 😉

Mfg NeuroCoder

1.433 Beiträge seit 2006
vor 16 Jahren

Schau Dich mal hier um: Math Members

Theoretisch gesehen gibt es viele Wege dieses Problem zu lösen. Ein Ansatz wäre zum Bsp:

Den Inhalt der Textbox parsen und dann die Werte speichern. Die Mathematische Korrektheit musst Du implementieren (Punkt vor Strick etc.).

Ansonsten, gäbe es da auch schon Math-Cad...

Grüsse
Daniel
Space Profile
Wer nicht fragt, der nicht gewinnt

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Fracoon,

Ich schließe mich NeuroCoder an. Das Thema wurde schon oft besprochen. Ein gutes Stichwort ist Eval. Bitte benutze die Forumssuche und poste die besten Treffer hier. Vielen Dank!

herbivore

2.921 Beiträge seit 2005
vor 16 Jahren

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

B
7 Beiträge seit 2008
vor 16 Jahren

Hallo Zusammen,

sowas wie den Formel-Editor bräuchte ich auch 😁
Bin grade dabei, mir als Übungsmunition einen kleinen Taschenrechner zu basteln.
Da käme mir der Formeleditor gerade recht.

Aaaaber a) ist mir der hier vorgestellte Formeleditor viel zu kompliziert (bin schließlich Anfänger) und b) ist er nicht selbst gemacht! Bringt als in etwa 0 Lernerfolg.

Mein Taschenrechner soll erst mal nur +-*/ können. Gibts da nichts einfacheres um einen Formelstring gleich auszurechnen?

Gruß,
bytebrain

1.378 Beiträge seit 2006
vor 16 Jahren

Natürlich gehts einfacher auch, nur dafür hast auch halt weniger funktionaltiät. 🙂

zB könntest du einen einfachen String wie "5*3" mit String.Split() oder mit String.SubString() in Verbindung mit String.IndexOf() zerlegen und danach mit zB int.Parse() die Werte in Zahlen umwandeln und anschließend berechnen.

Obwohl einfach ist immer relativ. Für einen Anfänger kann das vielleicht auch schon eine Herausforderung sein.

Lg XXX

1.130 Beiträge seit 2007
vor 16 Jahren

Hier ist meine Lösung.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

564 Beiträge seit 2005
vor 16 Jahren

Hab mal einen Formelparser geschrieben, der parst, vereinfacht und ableiten kann. Wenn Interesse besteht lad ichs mal hoch.

B
7 Beiträge seit 2008
vor 16 Jahren

@xxxprod:
Danke für den Hinweis... Hab mir hier im Board und in google einen Wolf gesucht.
Bin kein Programmieranfänger, nur C#anfänger 😉
Ich werds auf jeden Fall mal probieren. Jetzt weiß ich wenigstens, wie die Funktionen heißen, die ich zum splitten brauch 😁

@floste:
ich schau mir das mal an. Ggf. pflück ich deinen Code auseinander, wenn ich darf =) um mir was eigenes zu basteln

@ZiMD:
immer her damit 🙂 Schicks mir ggf. als PM, falls du es hier nicht posten möchtest.

@all:
Danke und Gruß,
bytebrain

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
Gute Lösung??

Ich glaub ich hab ne echt brauchbare Lösung gefunden... basierend auf IronPython..... was haltet ihr davon??

Damit funktionieren alle Rechenarten die Python kennt.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string formel = "sqrt(29)*29.5"
            PythonEngine pe = new PythonEngine();
            pe.Execute("from IronPython.Modules.PythonMath import *");
            Console.WriteLine(pe.Evaluate(formel).ToString()) ;
            Console.ReadLine();
        }
    }
}
49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Fracoon,

ich denke, es gibt genug native C#-Lösungen. Da muss man nicht auf Python ausweichen, selbst dann nicht, wenn die Anbindung von Python an C# gut gelöst ist.

herbivore

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

Spricht irgendwas generell dagegen IronPython einzustzen?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Fracoon,

also ich finde das hier ein bisschen viel Overhead und du hast - wie du ja selbst sagst - dann die Rechenarten und -regeln von Python und nicht von C#. Aber sonst spricht nichts dagegen.

herbivore

564 Beiträge seit 2005
vor 16 Jahren
F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
Hilfe gesucht! PythonRechner

Hallo,

ich bin gerade dabei eine Komponente zu entwickeln, die aus einer Formel die in einem String gespeichert ist ein Ergebnis berechnet.

Da ich noch ziemlicher Anfänger bin wollte ich hier mal nachfragen was ihr davon haltet.

  • Habe ich irgendwelche Anfängerfehler gemacht?
  • Wie mache ich die Ereignisbehandlung? Muss ich alle Exceptions die bei pe.Evaluate auftreten können einzeln abfangen? Oder leitet man dass irgendwie an die Aufrufende Anwendung weiter?
  • Was haltet ihr generell von der Idee?
  • Hat jemand ne Idee wie ich folgendes verhindern kann : Wenn in der Formel z.B. sqrt benutzt wird und ein Benutzer fügt "s" als Variable hinzu, würde er auch das "s" aus "sqrt" ersetzen. Hab im Moment keine Idee wie ich das Verhindern kann!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
using System.Text.RegularExpressions;
using IronPython.Runtime.Exceptions;

namespace PythonRechner
{
    public class Rechner
    {
        public Rechner()
        {
            this.pe.Execute("from IronPython.Modules.PythonMath import *");
        }
        
        private PythonEngine pe = new PythonEngine();
        public List<variable> variablen = new List<variable>();

        private string formel;
        public string Formel
        {
            get { return formel; }
            set { formel = value; }
        }
        
        public void addVariable(variable var)
        {
            variablen.Add(var);
        }

        public double CalcToDouble()
        {
            string werte_formel = formel;
            double ergebnis = 0;
            
            foreach (variable temp_variable in variablen)
            {
                werte_formel = Regex.Replace(werte_formel, temp_variable.Name, temp_variable.Wert.ToString());
                
            }

            werte_formel = Regex.Replace(werte_formel, ",", ".");

           
            ergebnis = Convert.ToDouble(pe.Evaluate(werte_formel));
            
            return ergebnis;
        }

        public string CalcToString()
        {
            string werte_formel = formel;
            string ergebnis = "";

            foreach (variable temp_variable in variablen)
            {
                werte_formel = Regex.Replace(werte_formel, temp_variable.Name, temp_variable.Wert.ToString());
            }

            werte_formel = Regex.Replace(werte_formel, ",", ".");


            ergebnis = pe.Evaluate(werte_formel).ToString();

            return ergebnis;
        }

    }

    public class variable
    {
        public variable(string name, double wert)
        {
            this.name = name;
            this.wert = wert;
        }
        
        private string name;
        private double wert;

        public double Wert
        {
            get { return wert; }
            set { wert = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        
        
    }
}

funktionieren tut das Ganze so :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PythonRechner;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Rechner pr = new Rechner();
            pr.Formel = "a*b*c*sqrt(c)";

            pr.addVariable(new variable("a",27.123));
            pr.addVariable(new variable("b",27.123));
            pr.addVariable(new variable("c",27.123));

            Console.WriteLine(pr.CalcToDouble().ToString());

            Console.ReadLine();
        }
    }
}

K
27 Beiträge seit 2008
vor 16 Jahren

Das ist ein klassisches Compilerbau-Problem. Man benutzt dafür oft LEX und YACC.

Der Lexer übersetzt den String in eine Tokenfolge und die wird dann nach bestimmten Grammatikregeln nach Bottom-Up-Prinzip (LALR(1)) geparsed.

Google nach YACC und LEX/FLEX

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

hi Kartoffel,

danke für deine Antwort. Ich bin mir aber nicht ganz schlüssig ob mich deine Anmerkung weiterbringt!

Ich möchte keinen eigenen Compiler bauen! Ich möchte schon gerne die von mir gennante Methode mit IronPython benutzen!

Oder verstehe ich dich falsch?

K
27 Beiträge seit 2008
vor 16 Jahren

Schau mal hier:

http://www.dabeaz.com/ply/ply.html

Wenn du eine beliebige mathematische Formel auswerten willst, dann willst du doch einen eigenen Compiler bauen. 🙂

Das allgemeine Vorgehen wäre den String z.B, "1+2*2" erst einmal in eine Tokenfolge zu übersetzen (lexikalische Analyse):

Number, Plus, Number, Mul, Number

Danach baut man sich mit Hilfe von regulären Grammatiken, die arithmetische Ausdrücke beschreiben, einen Syntaxbaum zusammen:

   Plus
   /  \
  /    \
Number Mul
      /   \
     /     \
   Number Number

Diesen Sytaxbaum kann man rekursiv durchlaufen und gleichzeitig den Wert des Ausdrucks ermitteln. Das tolle ist, dass es Tools für beide Phasen gibt, die dir alles abnehmen. (siehe Link)

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

Naja, eigenen Compiler bauen will ich nich wirklich! Ich möchte den IronPython Compiler Benutzen... siehst du ja auch in meinem CodeSchnippsel weiter oben!

K
27 Beiträge seit 2008
vor 16 Jahren

Wie magst du denn ein Programm nennen, das dir deine arithmetischen Ausdrücke übersetzt?

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

entweder ich steh komplett auf dem schlauch =)

oder du hast nicht gesehen was ich oben bereits gebastelt hab

oder wir reden aneinander vorbei?!?! =)

Hab ja schon eine "Lösung" gefunden... wollte nur mal nach Meinungen fragen.

So wie ich dich jetzt verstehe wäre dein Vorschlag eine ANDERE Lösung?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Fracoon,

was heißt schon aneinander vorbeireden. Kartoffel schlägt halt eine andere Lösung für dein eigentliches Problem vor und du beharrst auf deiner Lösung. Nicht mehr und nicht weniger. Ich habe ja auch gewisse Vorbehalte gegen die Pyton-Lösung geäußert.

herbivore

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
hmm...

Hallo herbivore....

mein Anliegen ist eigentlich nicht mehr eine Lösung zu finden. Desswegen hatte ich auch einen neuen Thread erstellt. Ich vermute mal dass du ihn hier reinverschoben hast?!?!

Ich möchte eigentlich schon gerne an meiner Lösung festhalten da sie sehr gut funktioniert für meine Zwecke... was ich eigentlich gerne wissen wollte ist was ihr von meiner Umsetzung haltet. Klar gibt es mehrere Wege nach Rom. Ich habe EINEN möglichen gefunden, bin mir aber mit der Umsetzung nicht ganz sicher.

Ich denke in einem neuen Thread wären solche Missverständnisse nicht aufgetreten!!!!

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Fracoon,

ob und welche Missverständnisse auftreten, hat man leider nicht in der Hand. Durch zwei Threads zu einem Thema treten jedenfalls in der Regeln mehr Missverständnisse auf, als wenn man die Threads zusammenfügt. Vor allem werden durch das Zusammenfügen i.d.R. unnötige Nachfragen und unnötige Doppelantworten vermieden.

Außerdem ist es durchaus üblich, dass eine Frage globaler beantwortet wird, als vom Fragesteller beabsichtigt. Du hast nur Details deiner Lösung in Frage gestellt. Es ist aber nicht ungewöhnlich, dass dann die Lösung insgesamt in Frage gestellt wird. Insofern sehe ich hier nicht mal ein Missverständnis.

Und entsprechend teile ich deine Meinung bezüglich des Zusammenfügens nicht. Und selbst wenn du Recht hättest, wäre dieser Thread die Ausnahme, die die Regel bestätigt.

Zu deiner eigentlichen Frage kann ich leider nichts beisteuern.

herbivore

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

naja... belassen wir es mal dabei...

ich hatte eigentlich gehofft, dass jemand mal über meinen geposteten Quelltext schaut der ein bisschen mehr Ahnung hat wie ich.... vieleicht findet sich ja noch jemand..

es mir ja nicht darum ob man es irgendwie auf nem anderen weg Lösen kann.. sondern ob der weg den ich gewählt habe akzeptabel umgestzt ist.