2

I am working on a rather complicated math project using python but keep getting stuck with one problem:

a = lambda x: input('Function in terms of x')

This works until I have to run a command like:

z = a(n)

Every time this is done it asks for an input again so I get a console that looks like:

Function in terms of x:
Function in terms of x:

I know that I should theoretically be able to get around with the following:

func = input('Function: ')
a = lambda x: func

This creates another problem: x isn't defined in the outer scope, so I added sympy symbols like so:

x = sym.Symbol('x')
func = input('Function: ')
a = lambda x: func

but then running a command like this results in something weird:

Function: 5*x +1
>>>a(10)
5*x + 1

I think this is because lambda doesn't work with sympy, but I can't think of another way to get around the problem... Thank You for any help.

The full code is as follows; the function asks for the first input at line 18, and then at line 50 where it isn't supposed too. I believe that this has to do with the fact that I use the lambda function twice.

import matplotlib.pyplot as plt
import os
import time
from mpl_toolkits.mplot3d import axes3d
from sympy import *
import numpy as np
import tkinter as tk
from colorama import init, Fore, Back, Style
import mpmath


def main():
    """
    Handling for Range and function
    """
    rng = raw_input('Minimum, Maximum: ').split(',')
    rng = [float(rng[i]) for i in range(2)]
    a = lambda x: input('Function of x: ')  # function a is the main polynomial#
    """
        2 Dimensional Graph
    """
    two_d_x = np.arange(rng[0], rng[1], abs(rng[1] - rng[0]) / 100)
    two_d_y = a(two_d_x)
    fig1 = plt.figure()
    ax1 = fig1.add_subplot(221)
    print [np.amin(two_d_x), np.amax(two_d_x), np.amin(two_d_y), np.amax(two_d_y)]
    ax1.axis([np.amin(two_d_x), np.amax(two_d_x), np.amin(two_d_y), np.amax(two_d_y)])
    ax1.plot(two_d_x, two_d_y, 'r-')
    ax1.set_title(r'$\mathit{f(x)}\in \mathbb{R}^2$')
    ax1.set_xlabel(r'$\mathit{x}$')
    ax1.set_ylabel(r'$\mathit{y}$')
    ax1.grid()
    ax1.spines['left'].set_position('zero')
    ax1.spines['right'].set_color('none')
    ax1.spines['bottom'].set_position('zero')
    ax1.spines['top'].set_color('none')
    ax1.spines['left'].set_smart_bounds(True)
    ax1.spines['bottom'].set_smart_bounds(True)
    plt.gca().set_aspect('equal', adjustable='box')
    ax1.xaxis.set_ticks_position('bottom')
    ax1.yaxis.set_ticks_position('left')
    """
        Quiver Plot of Function
    """
    ax2 = fig1.add_subplot(222)
    u, v = np.meshgrid(np.arange(rng[0], rng[1], 1),
                       np.arange(rng[0], rng[1], 1))
    ### u+vj -> w+rjf
    print False
    output = a(u + (v * 1j))
    print False
    w = output.real
    r = output.imag
    ax2.axis([np.amin(w) * 1.1, np.amax(w) * 1.1, np.amin(r) * 1.1, np.amax(r) * 1.1])
    distance = np.sqrt(((w - u) ** 2) + ((r - v) ** 2))
    quiver_plot = ax2.quiver(u, v, w, r, distance, angles='xy', scale_units='xy', scale=1, cmap=plt.cm.jet)
    plt.colorbar(quiver_plot, cmap=plt.cm.jet)
    ax2.set_title(r'$\mathit{f(x)}\in \mathbb{C}^2$')
    ax2.set_xlabel(r'$\mathit{rl}$')
    ax2.set_ylabel(r'$\mathit{im}$')
    ax2.grid()
    ax2.spines['left'].set_position('zero')
    ax2.spines['right'].set_color('none')
    ax2.spines['bottom'].set_position('zero')
    ax2.spines['top'].set_color('none')
    ax2.spines['left'].set_smart_bounds(True)
    ax2.spines['bottom'].set_smart_bounds(True)
    plt.gca().set_aspect('equal', adjustable='box')
    ax2.xaxis.set_ticks_position('bottom')
    ax2.yaxis.set_ticks_position('left')
    plt.show()


main_program_loop = True
while main_program_loop == True:
    print '| Quandri 1.0 | by: Boolean Designs\n'
    main()
    stay_loop_tp = True
    while stay_loop_tp != False:
        stay_loop_tp = raw_input("Would you like to continue using this program <yes/no>? ")
        if stay_loop_tp == 'yes' or stay_loop_tp == 'y':
            os.system('cls')
            stay_loop_tp = False
        elif stay_loop_tp == 'no' or stay_loop_tp == 'n':
            print 'Exiting Quandri...'
            time.sleep(1)
            exit()
            stay_loop_tp = False
        else:
            print "Improper Input."
            time.sleep(2)
            os.system('cls')
7
  • input returns str-objects, not Python code Commented May 14, 2017 at 17:39
  • Python 2.7 allows code inputs using the input() function. Commented May 14, 2017 at 17:42
  • 2
    well, evaluating user input definitely not a good approach Commented May 14, 2017 at 17:44
  • At which point do you actually evaluate the entered function? I don't see that happening. You call 'a(10)', which calls plain 'func', which in turn calls the input statement, and the return value of the input statement is then passed back through until the initial call. I.e., it's no surprise, that you only get back your '5*x+1'. Commented May 14, 2017 at 17:46
  • 1
    I cannot reproduce your repeated statement on python 2.7, it just works. Commented May 14, 2017 at 17:52

2 Answers 2

1

The sympy lib has support for parsing and evaluating expression:

import sympy
from sympy.parsing.sympy_parser import parse_expr

x = sympy.Symbol('x')
expression_string = input("Function: ")
expr = parse_expr(expression_string)
expr.evalf(subs={x:10})

see this http://docs.sympy.org/dev/modules/parsing.html and this How to calculate expression using sympy in python


Edit: Thomas Kühn's answer is good, but in python2.7 raw_input must be used

f = raw_input("Function: ")
a = lambda x:eval(f) 
print(a(10)) 
Sign up to request clarification or add additional context in comments.

6 Comments

I used to use this method, but I have to parse/evaluate a meshgrid, which is longer than 32 creating another error from Sympy.
Can you provide further details about that error? Maybe it's easier to find a work around for that instead of writing a new parser/evaluator.
'code'Traceback (most recent call last): z = function.evalf(subs={x:X,y;Y}) ValueError: sequence too large; cannot be greater than 32
What are X and Y? Scalar or vectors? That error seems to be raised by numpy: it seems that you're trying to allocate a multidimensional array with the number of dimensions greater than 32
X and Y are a meshgrid for 3d graphing. So I guess that makes them scalar.
|
0

I don't know, if it is advisable to do something like this, but here is some code that works for me on python 3.5:

func = input('Function: ')
a = lambda x: eval(func)
print(a(10))

calling this script with python, I get:

Function: x+1
11

1 Comment

Not supported by Python 2.7. Thanks for the help though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.