pythonfunctionreturn-valuedefinitionoperands

How can i solve a problem by using the outcome of a function as a variable in the following?


I have come up with this code:

lista= [5,3.2, 'Error', 44, 'Error', 35]
listb= [70, 70, 20, 410,'Error', 4.9]
for i in range(6):
    a= lista[i]
    b= listb[i]
    if a == 'Error' or b == 'Error':
        print(f" Case {i}")
        print(" One of the values is not a number")
        print("-----")
    else:
        def c(a):      
            c=0.1*a**3 -0.6*a**2 
            return c
            def d(a,b,c):       
                return a+b+c(a)
        print(f" Case {i} ")
        print(f" Initial values {a} {b}")
        print(f" Final values {c(a)} {d(a,b,c)}")
        print("-----")``

The problem is the second function, which doesn't work. If i erase everything with d and function number two, it's exactly the same as the desired output. The error i get is: supported operand type(s) for +: 'int' and 'function' Can somebody please help me? The desired output:

Case 0 Initial values 5 70 Final values -2.5 72.5

Case 1 Initial values 3.2 70 Final values -2.8672 70.3328

Case 2 One of the values is not a number

Case 3 Initial values 44 410 Final values 7356.799999999999 7810.799999999999

Case 4 One of the values is not a number Case 5 Initial values 35.0 4.9 Final values 3552.5 3592.4

The number of active lines can't be more than 20.


Solution

  • Your current code is not correct Python code due to the function d() being defined within the function c() and it is therefore not visible outside of c(). By fixing the indentation of function d(), I get

    lista= [5,3.2, 'Error', 44, 'Error', 35]
    listb= [70, 70, 20, 410,'Error', 4.9]
    for i in range(6):
        a= lista[i]
        b= listb[i]
        if a == 'Error' or b == 'Error':
            print(f" Case {i}")
            print(" One of the values is not a number")
            print("-----")
        else:
            def c(a):      
                c=0.1*a**3 -0.6*a**2 
                return c
            def d(a,b,c):       
                return a+b+c(a)
            print(f" Case {i} ")
            print(f" Initial values {a} {b}")
            print(f" Final values {c(a)} {d(a,b,c)}")
            print("-----")
    

    This code works and also produces your desired output:

    Case 0 
     Initial values 5 70
     Final values -2.5 72.5
    -----
     Case 1 
     Initial values 3.2 70
     Final values -2.8672 70.3328
    -----
     Case 2
     One of the values is not a number
    -----
     Case 3 
     Initial values 44 410
     Final values 7356.799999999999 7810.799999999999
    -----
     Case 4
     One of the values is not a number
    -----
     Case 5 
     Initial values 35 4.9
     Final values 3552.5 3592.4
    -----
    

    I would generally avoid defining functions withing loops and move c() and d() outside of the loop:

    def c(a):      
        c=0.1*a**3 -0.6*a**2 
        return c
    def d(a,b,c):       
        return a+b+c(a)
    
    lista= [5,3.2, 'Error', 44, 'Error', 35]
    listb= [70, 70, 20, 410,'Error', 4.9]
    
    for i in range(6):
        a= lista[i]
        b= listb[i]
        if a == 'Error' or b == 'Error':
            print(f" Case {i}")
            print(" One of the values is not a number")
            print("-----")
        else:
            print(f" Case {i} ")
            print(f" Initial values {a} {b}")
            print(f" Final values {c(a)} {d(a,b,c)}")
            print("-----")
    

    Also try to avoid function names like c and d especially when you also use c as a variable. You save a little bit of typing and loose a lot of readability and are also prone to errors when mixing up functions and variables. Single letter variables and functions should almost always be avoided, except when they stand for established natural constants (c = speed of light, and even then it is debatable) or established variable names for coordinates like x, y, z.