#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0

    Forward Euler error message: "a float is required"


    Good morning all,
    First time poster and growing admirer of the python language. This is my first time getting my hands dirty with programming and I am currently working on a project to demonstrate different integrator methods, one of them being Euler. I currently am using python 2.7.3

    My script design is one such that it creates an interface that prompts the user to choose variables that should output Euler points (and later plot the graph once I get over my current hump).

    Here is a snippet of my code:

    Code:
    def Fwdeuler(fxy, x0, xn, y0, n):  
    
    #Calculating the step-size h, taking the length of the solution interval and 
    #dividing it by the number of steps to be used 
    n, r = divmod(xn-x0, h)     
    if r == 0:        
    n += 1     
    x = x0     
    y = y0 
    
    #for an integer in a range of numbers 
    #x = operator.iadd(x,y).     
    
    for i in range(n):         
    y += h * fxy(x, y)            
    x += h  
    
    #Returns value of y at xb.     
    return (y)        
    
    if __name__ == "__main__":     
    method = select()     
    formula = raw_input('Give a function f(x,y):')     
    x0 = eval(raw_input('Give x0 =? '))     
    y0 = eval(raw_input('Give y0 =? '))     
    xn = eval(raw_input('Give xn =? '))     
    h = eval(raw_input('Give the step size = ?'))     
    print 'For formula %s with parameters x =%g, y = %g, xn = %g, and n = %g produces %g' \             
    % (formula, x0, y0, xn,  h,  method)
    I currently get this message:

    unhandled TypeError "a float is required, not function."


    I'm not entirely sure why my script doesn't like my inputs but what was brought to my attention was that perhaps the script thinks that my variable method should store a numerical value but in fact is a pointer to an object (not listed) that calls for user input for the specific type of integrator they may want to use.

    Probably another problem I will find too is that i'm not calling enough arguments in my print statement and so not all the euler points are going to output.

    Hopefully I made any sense. Any help is definitely appreciated.

    HL
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,904
    Rep Power
    481
    Post the shortest working bit that exhibits the symptom with python indentations. Without that let's take a guess.

    select() returns a function, and then you tried to format that function---not the function's result---with '%g' .

    Code:
    >>> '%g'%abs(complex(5,12))   # Typical
    '13'
    >>> '%g'%abs                  # Not normally wanted
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: float argument required, not builtin_function_or_method
    >>>
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    b49P23TIvg,
    Thanks for your reply. I believe that you may be on to something. I do believe that I may be trying to format the function and not the function result. But I believe I am also calling the function result incorrectly in my print statement (something i'm trying to work on fixing but it's a slow process because, well it's me) as I want to print a list of euler points and not just one numerical value. I just seem to be at a bit of a wall on what to do.

    Here is a snippet of my code that should run once you enter 1 after it compiles. I do apologize if I didn't get all the indents right. I had to try to do what I could using this forums formatting.

    Code:
    from math import * 
    import sys  
    
    #Constructing function 'displayMenu' to list options for different integrators 
    
    def displayMenu():        
       print('')        
       print '(1) Forward Euler'        
       print('')  
    
    #Construct a function 'select' that allows you to choose from displayMenu
    
    def select():     
       displayMenu()     
       choice = input('Please enter choice number: ')     
    
       if (choice == 1):         
          method = Fwdeuler     
       else:         
            print "Invalid choice: ", choice         
            sys.exit(1)     
       return method    
    
    def Fwdeuler(fxy, x0, xn, y0, n):  
    
    #Calculating the step-size h, taking the length of the solution interval and 
    #dividing it by the number of steps to be used 
     
    n, r = divmod(xn-x0, h)     
       if r == 0:        
         n += 1     
       x = x0     
       y = y0 
    
    #for an integer in a range of numbers 
    #x = operator.iadd(x,y).     
       for i in range(n):         
           y += h * fxy(x, y)         
           x += h  
    
    #Returns value of y at xb.     
       return (y)        
    
    if __name__ == "__main__":     
       method = select()     
       formula = raw_input('Give a function f(x,y):')     
       x0 = eval(raw_input('Give x0 =? '))     
       y0 = eval(raw_input('Give y0 =? '))     
       xn = eval(raw_input('Give xn =? '))     
       h = eval(raw_input('Give the step size = ?'))     
       print 'For formula %s with parameters x =%g, y = %g, xn = %g, and n = %g produces %g' \             
              % (formula, x0, y0, xn,  h,  method)
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,904
    Rep Power
    481
    Program works. Maybe I changed it a little. There was confusion around step size and number of steps. In this version the user enters the number of steps.
    Code:
    '''
        EXAMPLE
    
        $ python q.py 
        Give a function f(x,y): y
        Give x0 =? 0
        Give y0 =? 1
        Give xn =? 1
        Use how many steps? 999
        For formula y with parameters x = 0, y = 1, xn = 1, in 999 steps produces 2.71692
    '''
    
    
    from math import *
    import sys
    
    def Fwdeuler(fxy, x0, xn, y0, n, **kwargs):
        #Calculate the step-size h, taking the length of the solution interval and
        #dividing it by the number of steps to be used
        h = (xn-x0) / float(n)
        x, y = x0, y0
        for i in range(n):
            y += h * fxy(x = x, y = y, **kwargs)
            x += h
        #Returns value of y at xb.
        return (y)
    
    class function:
    
        def __init__(self, pythonic_string_representation_of_a_function):
            self.f = pythonic_string_representation_of_a_function
    
        def __str__(self):
            return self.f
    
        def __call__(self, **kwargs):
            return eval(self.f, globals(), kwargs)
    
    if __name__ == "__main__":
       method = Fwdeuler
       formula = raw_input('Give a function f(x,y): ')
       x0 = eval(raw_input('Give x0 =? '))
       y0 = eval(raw_input('Give y0 =? '))
       xn = eval(raw_input('Give xn =? '))
       n = eval(raw_input('Use how many steps? '))
       fxy = function(formula)
       yn = method(fxy, x0, xn, y0, n,)
       print('For formula %s with parameters x = %g, y = %g, xn = %g, in %d steps produces %g'
             % (fxy, x0, y0, xn, n, yn))
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Thank you for the assistance b49P23TIvg,
    I haven't gotten a chance to parse through what you did (as I do want to understand what's happening with the code and make comparisons the differences between your modification and mine). I have a late shift today so won't be able to follow up until earliest tonight or tomorrow.

    Just to quickly clarify, My code asks the user how big the step size is and then makes a self check to see if the user input meets that criteria.

    I just wanted to say thank you ahead of time.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by b49P23TIvg
    Program works. Maybe I changed it a little. There was confusion around step size and number of steps. In this version the user enters the number of steps.
    Code:
    '''
        EXAMPLE
    
        $ python q.py 
        Give a function f(x,y): y
        Give x0 =? 0
        Give y0 =? 1
        Give xn =? 1
        Use how many steps? 999
        For formula y with parameters x = 0, y = 1, xn = 1, in 999 steps produces 2.71692
    '''
    
    
    from math import *
    import sys
    
    def Fwdeuler(fxy, x0, xn, y0, n, **kwargs):
        #Calculate the step-size h, taking the length of the solution interval and
        #dividing it by the number of steps to be used
        h = (xn-x0) / float(n)
        x, y = x0, y0
        for i in range(n):
            y += h * fxy(x = x, y = y, **kwargs)
            x += h
        #Returns value of y at xb.
        return (y)
    
    class function:
    
        def __init__(self, pythonic_string_representation_of_a_function):
            self.f = pythonic_string_representation_of_a_function
    
        def __str__(self):
            return self.f
    
        def __call__(self, **kwargs):
            return eval(self.f, globals(), kwargs)
    
    if __name__ == "__main__":
       method = Fwdeuler
       formula = raw_input('Give a function f(x,y): ')
       x0 = eval(raw_input('Give x0 =? '))
       y0 = eval(raw_input('Give y0 =? '))
       xn = eval(raw_input('Give xn =? '))
       n = eval(raw_input('Use how many steps? '))
       fxy = function(formula)
       yn = method(fxy, x0, xn, y0, n,)
       print('For formula %s with parameters x = %g, y = %g, xn = %g, in %d steps produces %g'
             % (fxy, x0, y0, xn, n, yn))
    Good evening b49P23TIvg,
    I just wanted to thank you for your help and sorry for taking long to reply to you. As I am still fairly new with programming and python, it took me some time to try to understand your code. With additional help from looking up documentation and asking for advice, I was able to find a solution for my own methods (for now, it's just easier for me to call functions. I figured once I can get past this stage, I can improve upon my code by using classes. What do you think?

    I was wondering if you could continue to help me try to solve more integration methods. I am now trying to come up with a runge kutta method for heun's equation based on my existing code.

    What I tried to do was modify my euler's method. I figured it should be *easy* since what I believe I need to do is take eulers method and create a new set of points that will later be used for a new set of integrators (heun and then later RK4).

    Anyway here's what I have (the place where I *think* i'm having the issue is the xvector area.

    Code:
    import matplotlib.pyplot as plt
    import numpy as np
    from math import *
    
    def heun(f, x0, xn, y0, h):
    
    #Calculating the step-size h, taking the length of the solution interval and
    #dividing it by the number of steps to be used.  Is it step size or number of steps.
    #n is the number of steps while h is step size
        n = int((xn-x0) / h)
        while x0 + n*h < xn:
            n += 1
        x = x0
        y = y0
        xvector = [x]
        yvector = [y]
        
    #for an integer in a range of numbers 
    #defines xn+1 = xn + h 
        for i in range(n):  
            y += h * eval(f)
            yvector.append(y)
            
    #i+1 number of steps taken. 
    # defines the equation yn+1 = yn+(h/2)(f(xn, yn) + f(xn + h, yn + hf(xn, yn))) 
            x = x0 +(i+1)*(h/2)+((y,x0) + x0 + (i+1) * h)
            xvector.append(x)
    
    #values are store in vectors and assigned to numpy arrays
        return np.array(xvector),  np.array(yvector) 
        
    if __name__ == "__main__":
        formula = raw_input('Give a function f(x,y):')
        x0 = eval(raw_input('Give x0 =? '))
        y0 = eval(raw_input('Give y0 =? '))
        xn = eval(raw_input('Give xn =? '))
        h = eval(raw_input('Give the step size = ? '))
        xall,  yall = heun(formula,  x0,  xn,  y0,  h)
        print 'The function %s with parameters x =%g, y = %g, xn = %g, and h = %g produces %g' \
                % (formula, x0, y0, xn,  h,  yall[-1])    
    
    plt.plot(xall, yall)
    plt.grid(True)
    plt.show()
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    194
    Rep Power
    2
    I personally do think that in certain situations the use of eval is forgivable. That said, if you are a starting out programmer I would really caution you against thinking that code like:
    python Code:
    x0 = eval(raw_input('Give x0 =? '))
    y0 = eval(raw_input('Give y0 =? '))
    xn = eval(raw_input('Give xn =? '))
    n = eval(raw_input('Use how many steps? '))
    is acceptable. In python 2.x the regular input function does exactly this. There is a reason that it was removed in python 3.

    -Mek
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by Mekire
    I personally do think that in certain situations the use of eval is forgivable. That said, if you are a starting out programmer I would really caution you against thinking that code like:
    python Code:
    x0 = eval(raw_input('Give x0 =? '))
    y0 = eval(raw_input('Give y0 =? '))
    xn = eval(raw_input('Give xn =? '))
    n = eval(raw_input('Use how many steps? '))
    is acceptable. In python 2.x the regular input function does exactly this. There is a reason that it was removed in python 3.

    -Mek
    Mek, thank you.

    I do not know what my fascination with eval is besides what I perceived was a "safety percaution" due to my novice skills in evaluating a function so that there is no mistake as to what its input is (distinguishing whether it's a float, int, etc). I will take this into heavy consideration and not use it in my code.

IMN logo majestic logo threadwatch logo seochat tools logo