Errors in program for calculating integrals
Question: I am trying to calculate the area of a graph using integrals.

The user is supposed to give me 3 numbers:

  * x1, x2 - the bounds of the integral 
  * N is in how many pieces the program will divide the function

However, I keep getting wrong results.

The first difficulty that I faced is that range accepts only integers.

Also `z=(x2-x1)/N` if I try and make it a float, I can't make it a step after,
and I don't make it float it approaches to zero so Python shows me an error
that the step is zero.

Also how can I summarize `(z*(f(i)+f(i+z)/2)`?

Here is my code:

    
    
    # -*- coding: UTF-8 -*-
    import math
    
    def f(x) :
        y = (-1/6.0)*(x-1)*(x-2)*(x+2)*(x-4)
        return y 
    x1=int(raw_input ('Δωστε το χ1 οπου αρχιζει η μετρηση του ολοκληρωματος \n ')) #greek letters
    x2=int(raw_input ('Δωστε χ2 οπου θελετε να ολοκληρωνεται η μετρηση \n '))
    N=int(raw_input('Δωστε τον αριθμο n που θα ειναι το πληθος \n των τραπεζιων που θα χρησιμοπιουνται στη προσσεγγιση  \n '))
    z=(x2-x1)/N
    for i in range(x1,x2,z):
        z=float(z)
        x1=float(x1)
        x2=float(x2)
        print (z*(f(i)+f(i+z))/2) 
    


Answer: You are reading `x1`, you cast it to an `int` (read: throw away information),
then you cast it back to a float upon each iteration. The lost information
will not reappear.

    
    
    z=(x2-x1)/N
    

Because your value are integers, it will perform an integer division, i.e. if
N > (x2 - x1), `z` will be zero. And since you always want to choose a large
`N`, `z` will always be zero.

Thus, `range()` cannot not work.

What you need to do instead is read the inputs as floats:

    
    
    number = float(raw_input("Please enter a number: "))
    

* * *

Note that applying `float()` repeatedly doesn't do anything useful. Thus, this
code is not necessary:

    
    
    for ...
        z=float(z)
        x1=float(x1)
        x2=float(x2)
    

* * *

> Also how can i summarise the (z*(f(i)+f(i+z)/2)?

You can't make it shorter, since `f()` isn't a linear function.

* * *

Another thing about `range()` is, that the step parameter must be an integer.

You can easily create your own range function though:

    
    
    def frange(start, stop, steps):
        x = start
        difference = float(stop - start)
        for step in range(0, steps):
            next_x = start + difference * (1 + step) / steps
            yield x, next_x - x
            x = next_x
    

* * *

## Working code

    
    
    # -*- coding: UTF-8 -*-
    import math
    
    def f(x) :
        y = (-1/6.0)*(x-1)*(x-2)*(x+2)*(x-4)
        return y 
    x1 = float(raw_input ('Δωστε το χ1 οπου αρχιζει η μετρηση του ολοκληρωματος \n ')) #greek letters
    x2 = float(raw_input ('Δωστε χ2 οπου θελετε να ολοκληρωνεται η μετρηση \n '))
    N = int(raw_input('Δωστε τον αριθμο n που θα ειναι το πληθος \n των τραπεζιων που θα χρησιμοπιουνται στη προσσεγγιση  \n '))
    result = 0
    for x, delta_x in frange(x1, x2, N):
        result += delta_x * (f(x)+f(x+delta_x)) / 2
    print result 
    

