Seite 1 von 1

Plotter für Funktionen oder aber "Probleme mit raw_inpu

Verfasst: Dienstag 16. März 2010, 19:09
von neongruuen
Hallo,
schonmal Daumen hoch. Das Forum hat mir schon viel geholfen! Aber jetzt habe ich auch noch eine Frage. Hab schon überall gesucht, aber keine so wirklich befriedigende Antwort gefunden. Falls das Problem hier nicht hinpasst, bitte verschieben; bin mir mit dem wirklichen Thema nicht so ganz sicher.

Also das Problem ist, dass ich versuche raw_input zu benutzen um eine Funktion abzufragen (bspw. x*x). Wenn ich damit weiterarbeiten will, speichert er aber das x*x als 'x*x' sprich nicht als Variable/Zahl sondern als Zeichenkette. Meine Frage ist jetzt, wie bekomme ich das hin, dass er das als Variablen interpretiert (könnt ja mal über mein Script drüberschauen; im Anhang).

Danke schonmal für eure Hilfe :).

LG Neon

Script:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#DoC - 16.03.2010
#(c) by N.Boeckhorst, D. Goeritzer
#fuer N. Domes
#Dieses Programm ist freie Software, es darf unendlich kopiert werden
#solang dieser Kommentar erhalten bleibt.
#Plotter für beliebige Funktionen (1/x) ausgeschlossen

# ~~~

#Vorwarbeit & Import

from xturtle import*
from math import*

setup(1.0,1.0)
li = []
func = raw_input ('Bitte geben Sie eine Funktion ein:')
ht()

#Definitionsbereich

##Koordinatensystem
	
def koords():
	bgcolor('black')
	color('orange')
	goto(300, 0)
	goto(-300, 0)
	goto(0, 0)
	goto(0, 300)
	goto(0, -300)
	goto(0, 0)

##Graph I	
	
def graph(x):
	return(func)
	
##Listenerweiterung	
	
for x in range(-15, 15):
	li.append((21.5*x, 21.5*graph(x)))

##Graph II

def graphdraw():
	color('red')
	pensize(5)
	for punkt in li:
		goto(punkt)

#Aufrufbereich

koords()
graph(x)
print(li)	
graphdraw()

#Programm in Loop schalten

mainloop()
Die "21.5*" kommen davon, dass der Graph sonst zu klein ist, 'Mitkursler' aus meinem Informatikkurs haben etwas von "scale" gesagt, dass habe ich aber nicht ganz verstanden.

Die Fehlermeldung sieht wie folgt aus:

Code: Alles auswählen

xturtle0.95a0 - bugfixes: 1
No config file!
Bitte geben Sie eine Funktion ein:x*x
Traceback (most recent call last):
  File "C:\Users\Niels\Documents\Eclipse Workspace\Informatikunterricht\Plotter.py", line 44, in <module>
    li.append((21.5*x, 21.5*graph(x)))
TypeError: can't multiply sequence by non-int of type 'float'
PS: Außerdem funktionieren keine Funktionen in richtung 1/x, da ein "DbZ" Fehler bei rauskommt (Divide by Zero).
PPS: Bei manchen Funktionen spinnt er ein wenig & wenn man das Script ausführt, kommt ein Zeichenfehler. Ist nicht weiter schlimm, aber vielleicht hat ja jemand eine Idee.

Verfasst: Dienstag 16. März 2010, 19:38
von numerix
Was du willst, ist ein Parser für Funktionsterme. Ohne entsprechende Erfahrung oder Vorkenntnisse, ist das aber nicht mal eben so gemacht. Zu dem Thema findest du einiges im Forum und ich meine auch es gäbe Threads, wo bereits fertige Parser gepostet worden wären. Das sind aber auf jeden Fall Lösungen, die ihr eurem Informatiklehrer kaum als eure eigenen Lösungen präsentieren könnt.

Die quick-and-dirty-Lösung wäre die Verwendung von eval(), womit sich eine übergebene Zeichenkette auswerten lässt, sofern es ein gültiger Python-Ausdruck ist. Das birgt ein gewisses Sicherheitsrisiko, weil der Anwender dann eben auch statt eines Terms eine Eingabe tätigen kann, die Dinge tut, die nicht erwünscht sind. (Wenn du nach eval im Forum suchst, findest du einiges dazu).

Dass bei 1/x eine Fehlermeldung kommt, wenn du x=0 verwendest, wundert dich hoffentlich nicht wirklich ...

Verfasst: Dienstag 16. März 2010, 22:20
von start_with_python
Oder anstatt einen Parser zu schreiben/nutzen machst du evtl mehrere Abfragen?!
Nach dem Prinzip:
1. was willst du tun? (Das mathematische Zeichen, welches als String kommt, mit einer Funktion etc. verbinden)
2. Variable 1
3. Variable 2
4. Ausgabe der Rechnung

Verfasst: Dienstag 16. März 2010, 23:07
von gkuhl
Noch eine Alternative wäre auf diese Eingabe komplett zu verzichten. Schreibe stattdessen ein Modul, dass eine plot-Funktion zur Verfügung stellt. Diese kannst du dann aus der Python-Konsole heraus importieren und verwenden. Der Funktion übergibt der Benutzer deines Moduls Werte für x und y als zwei Listen, die dann beim Aufruf gezeichnet werden.

Das könnte dann auf der Benutzerebene dann wie folgt aussehen:

Code: Alles auswählen

>>> import plotter
>>> x = range(0,20)
>>> y = [z**2 + 3*z + 4 for z in x]
>>> plotter.plot(x, y, color = 'blue')
Der Funktion kannst du natürlich noch weitere optionale Elemente übergeben, wie im Beispiel ein Argument für die Farbe der Punkte/Turtles.

Grüße
Gerrit

Verfasst: Mittwoch 17. März 2010, 00:03
von ms4py