-1

I am using tkinter and scipy to make a program that integrates a function, lets say with respect to x. this is my code:

def newtest1():
intwindow = Tk()

Label(intwindow, text = 'enter here', font = ('Symbol')).grid(row=0)
Label(intwindow, text = 'enter upper bound', font = ('Symbol')).grid(row=1)
Label(intwindow, text = 'enter lower bound', font = ('Symbol')).grid(row=2)

get1 = IntVar()
Entry(intwindow, textvariable = get1).grid(row=0, column=1)

getupper = IntVar()
Entry(intwindow, textvariable = getupper).grid(row=1, column=1)

getlower = IntVar()
Entry(intwindow, textvariable = getlower).grid(row=2, column=1)

bty = Button(intwindow, text='click', command = lambda: newfunction()).grid(row=3)

def newfunction():
    x69 = get1.get()
    x_upper = getupper.get()
    x_lower = getlower.get()

    testz = int(x69)
    upperz= int(x_upper)
    lowerz = int(x_lower)



    x9 = lambda x: x69
    res = integrate.quad(x9, x_lower,x_upper)        

    randomwindow = Tk()
    label = Label(randomwindow, text = 'you got {} '.format(round(res[0])))
    label.grid(row=1)

   # Label(randomwindow, text = 'you got %s ' % res).grid(row=1)
    randomwindow.mainloop()



mainloop()
newtest1()

if you look inside the function newfunction() there is the code

    x9 = lambda x: x69
    res = integrate.quad(x9, x_lower,x_upper)

I was hoping that in the pop up box, I could enter something like say 2*x and it would integrate. However previously I used get1 = IntVar() when testing to see if numbers work in the entry box. I tried removing this for what Im currently trying to achieve but that gives some logical errors. Why can't I enter my own function in terms of x in the pop up box so that python can integrate it?

EDIT


@furas this is the code i use now

import numpy
from numpy import *
import scipy.integrate as integrate
import scipy.special as special
from tkinter import *



def newtest1():
intwindow = Tk()

Label(intwindow, text = 'enter here', font = ('Symbol')).grid(row=0)
Label(intwindow, text = 'enter upper bound', font = ('Symbol')).grid(row=1)
Label(intwindow, text = 'enter lower bound', font = ('Symbol')).grid(row=2)

get1 = StringVar()
Entry(intwindow, textvariable = get1).grid(row=0, column=1)

getupper = IntVar()
Entry(intwindow, textvariable = getupper).grid(row=1, column=1)

getlower = IntVar()
Entry(intwindow, textvariable = getlower).grid(row=2, column=1)

bty = Button(intwindow, text='click', command = lambda: newfunction()).grid(row=3)

def newfunction():
    x69 = get1.get()
    x_upper = getupper.get()
    x_lower = getlower.get()

    #testz = int(x69)
    upperz= int(x_upper)
    lowerz = int(x_lower)



    x9 = eval(f"lambda x: {x69}")
    res = integrate.quad(x9, x_lower,x_upper)        

    randomwindow = Tk()
    label = Label(randomwindow, text = 'you got {} '.format(round(res[0])))
    label.grid(row=1)

   # Label(randomwindow, text = 'you got %s ' % res).grid(row=1)
    randomwindow.mainloop()



mainloop()
newtest1()

And this is the error i get

Exception in Tkinter callback
Traceback (most recent call last):
  File "/opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "/Users/isa/Desktop/Diff Eqns/diffeqn.py", line 45, in <lambda>
    bty = Button(intwindow, text='click', command = lambda: newfunction()).grid(row=3)
  File "/Users/isa/Desktop/Diff Eqns/diffeqn.py", line 58, in newfunction
    x9 = eval(lambda x: {x69})
TypeError: eval() arg 1 must be a string, bytes or code object
  • 2
    I don't understand what you try to do. if you get error then show it in question (not comment) as text (not image) – furas Feb 25 '20 at 01:31
  • and create correctly formatted code (with all import) so we could run it and see problem. – furas Feb 25 '20 at 01:32
  • if you want to put string `"2*x"` in box then you would have to use `StringVar()` instead of `IntVar()` to get it. And probably `x9 = eval(f"lambad x: {x69}")` to convert string `"2*x"` to code `x9 = lambda x: 2*x` – furas Feb 25 '20 at 01:43
  • Read [Why are multiple instances of Tk discouraged?](https://stackoverflow.com/questions/48045401/why-are-multiple-instances-of-tk-discouraged) and [Tkinter understanding mainloop](https://stackoverflow.com/questions/29158220/tkinter-understanding-mainloop) – stovfl Feb 25 '20 at 09:12
  • @furas please see my edit for the error i get when i use x9 = eval(f"lambad x: {x69}") – squashguy919 Feb 25 '20 at 14:01
  • eval need string and I used even f-string to put content of `x69` into this string. `f"lambad x: {x69}"` - and your erro shows that you didn't use string `x9 = eval(lambda x: {x69})` – furas Feb 25 '20 at 15:23

1 Answers1

0

If you want to put string "2*x" in Entry then you would have to use StringVar() instead of IntVar() to get it.

And you need to use eval() to convert this string to function which can calculate value

x9 = lambda x: eval(x69)

or with f-string or .format() to put this string inside other string

x9 = eval(f"lambad x: {x69}")
x9 = eval("lambad x: {}".format(x69)")

In code below I used names which means something so it looks lik

function = lambda x: eval(function_str)

In code I add also other changes - mostly related to PEP 8 -- Style Guide for Python Code

import scipy.integrate as integrate
import tkinter as tk # PEP8: `import *` is not preferred

# --- functions ---

def newtest1():

    # - subfunctions -

    def on_button_click(): # PEP8: name of function should means something
        function_str = function_var.get() # PEP8: name of variable should means something
        upper_int = upper_var.get()
        lower_int = lower_var.get()

        function = lambda x: eval(function_str)
        #function = eval(f"lambda x: {function_str}")
        result = integrate.quad(function, lower_int, upper_int)        
        result = round(result[0])

        randomwindow = tk.Toplevel() # second windows should use `Toplevel()` without `mainloop
        label = tk.Label(randomwindow, text=' you got {} '.format(result))
        label.grid(row=1)

        #tk.Label(randomwindow, text=' you got %s ' % result).grid(row=1)

    # - main -

    intwindow = tk.Tk()

    options = {'font': 'Symbol'}
    tk.Label(intwindow, text='enter here', **options).grid(row=0)  # PEP8: without spaces around '='
    tk.Label(intwindow, text='enter upper bound', **options).grid(row=1)
    tk.Label(intwindow, text='enter lower bound', **options).grid(row=2)

    function_var = tk.StringVar() # PEP8: name of variable should means something
    tk.Entry(intwindow, textvariable=function_var).grid(row=0, column=1)

    upper_var = tk.IntVar()
    tk.Entry(intwindow, textvariable=upper_var).grid(row=1, column=1)

    lower_var = tk.IntVar()
    tk.Entry(intwindow, textvariable=lower_var).grid(row=2, column=1)

    tk.Button(intwindow, text='click', command=on_button_click).grid(row=3) # you don't need `lambda` when function created at start

    intwindow.mainloop()

# --- main ---

newtest1()
furas
  • 134,197
  • 12
  • 106
  • 148
  • How come if I enter something like sin(x) into the box it cannot integrate it? – squashguy919 Feb 27 '20 at 01:49
  • you have `sin()`/`cos()`/etc. in module `math` so you would need to do `from math import *` at start - and then you can use `eval("sin(x)")`. But this `sin()`/`cos()`/etc. needs radians so if you want to work with angles then maybe better use `import math` and create function `def sin(angle): return math.sin(math.radians(angle))` – furas Feb 27 '20 at 02:08