Rushy Panchal - 1 year ago 58

Python Question

I was working on a program to find the integral of a function, where the user specifies the amount of rectangles, the start, and the stop.

NOTE: I am using left-end points of the rectangles.

I have the function working perfectly (at least, it seems to be perfect). However, I wanted to see if I could write a one-liner for it, but not sure how because I'm using

`eval()`

`def integral(function, n=1000, start=0, stop=100):`

"""Returns integral of function from start to stop with 'n' rectangles"""

increment, rectangles, x = float((stop - start)) / n, [], start

while x <= stop:

num = eval(function)

rectangles.append(num)

if x >= stop: break

x += increment

return increment * sum(rectangles)

This works fine:

`>>> integral('x**2')`

333833.4999999991

The actual answer is

`1000000/3`

My attempt at a one-liner:

`def integral2(function, n=1000, start=0, stop=100): rectangles = [(float(x) / n) for x in range(start*n, (stop*n)+1)]; return (float((stop-start))/n) * sum([eval(function) for x in rectangles])`

However, this isn't a truly a one-liner since I'm using a semi-colon. Also, it's a bit slower (takes a few seconds longer, which is pretty significant) and gives the wrong answer:

`>>> integral2('x**2')`

33333833.334999967

So, is it possible to use a one-liner solution for this function? I wasn't sure how to implement

`eval()`

`float(x)/n`

`float(x)/n`

`range`

Thanks!

Answer Source

```
def integral2(function, n=1000, start=0, stop=100): return (float(1)/n) * sum([eval(function) for x in [(float(x) / n) for x in range(start*n, (stop*n)+1)]])
```

Note that there is a big difference between `integral`

and `integral2`

: `integral2`

makes `(stop*n)+1-(start*n)`

rectangles, while `integral`

only makes `n`

rectangles.

```
In [64]: integral('x**2')
Out[64]: 333833.4999999991
In [68]: integral2('x**2')
Out[68]: 333338.33334999956
```

```
In [69]: %timeit integral2('x**2')
1 loops, best of 3: 704 ms per loop
In [70]: %timeit integral('x**2')
100 loops, best of 3: 7.32 ms per loop
```

Perhaps a more comparable translation of `integral`

would be:

```
def integral3(function, n=1000, start=0, stop=100): return (float(stop-start)/n) * sum([eval(function) for x in [start+(i*float(stop-start)/n) for i in range(n)]])
In [77]: %timeit integral3('x**2')
100 loops, best of 3: 7.1 ms per loop
```

Of course, it should go with say that there is no purpose for making this a one-liner other than (perverse?) amusement :)