smoczyna
smoczyna

Reputation: 519

wrong result from python eval() function

I have a function which is supposed to calculate Riemann sums, here it is:

import sympy as sym

x = sym.Symbol('x')

def left_riemann_sum(f, lower_bound, list):
    area = 0
    cur_val = lower_bound
    for x in list:
        height = eval(f(cur_val))
        width = x - cur_val
        print("cal area for height: " + str(height) + " and width: " + str(width))
        area = area + height * width
        cur_val = x

    return area

the problem is that eval(f(cur_val)) gives wrong value when run this function with this params:

print('left sum: ' + str(left_riemann_sum(f1, 3, [6.5, 10])))

and for this function:

def f1(x):
    return '-10*x**2+3*x+6'

it appears the heights are: -397 and -964 while it supposed to be -75 and -397. It looks like it skips first runs or so, I can't figure it out.

Upvotes: 0

Views: 436

Answers (2)

Saeed
Saeed

Reputation: 152

If you want to get a symbolic solution, you can define 3 symbols x y h and pass them to left_riemann_sum function like this,

x, y, h = sym.symbols('x y h')
print('left sum: ' + str(left_riemann_sum(f1, h, [x, y])))

Then this is the output,

cal area for height: -10*h**2 + 3*h + 6 and width: -h + x
cal area for height: -10*x**2 + 3*x + 6 and width: -x + y
left sum: (-h + x)*(-10*h**2 + 3*h + 6) + (-x + y)*(-10*x**2 + 3*x + 6)

Here is the rest of the code,

import sympy as sym

def left_riemann_sum(f, lower_bound, list):
    area = 0
    cur_val = lower_bound
    for y in list:
        height = f(cur_val)
        width = y - cur_val
        print("cal area for height: " + str(height) + " and width: " + str(width))
        area = area + height * width
        cur_val = y

    return area

def f1(x):
    return -10*x**2+3*x+6

Upvotes: -1

ALFA
ALFA

Reputation: 1744

Instead of defining functions as strings, define it as expressions:

def f1(x):
    return -10*x**2+3*x+6

Then your height will be calculated as:

height = f(cur_val)

So that the final code will be:

import sympy as sym

x = sym.Symbol('x')

def left_riemann_sum(f, lower_bound, list):
    area = 0
    cur_val = lower_bound
    for x in list:
        height = f(cur_val)
        width = x - cur_val
        print("cal area for height: " + str(height) + " and width: " + str(width))
        area = area + height * width
        cur_val = x

    return area

def f1(x):
    return -10*x**2+3*x+6

print('left sum: ' + str(left_riemann_sum(f1, 3, [6.5, 10])))

Output

cal area for height: -75 and width: 3.5
cal area for height: -397.0 and width: 3.5
left sum: -1652.0

If you really, really want to use eval()

You're doing it wrong. First define your function as above, returning an expression:

def f1(x):
    return -10*x**2+3*x+6

Then you can calculate the height using:

height = eval('f(cur_val)')

Upvotes: 2

Related Questions