Plotter für Funktionen oder aber "Probleme mit raw_inpu

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
neongruuen
User
Beiträge: 1
Registriert: Dienstag 16. März 2010, 10:31

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.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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 ...
start_with_python
User
Beiträge: 41
Registriert: Samstag 20. Juni 2009, 18:12

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
Grüße[b]
start_with_python[/b]

Lust auf [url=https://www.dropbox.com/referrals/NTE5OTQ5Mjk5]DropBox[/url]? (RefLink)
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

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
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Antworten