Kristen Huber
Kristen Huber

Reputation: 31

Python--Function not returning value

I want to write a function to compare two values, val1 and val2, and if val1 is larger than val2, add 1 point to a_points (Think of it like Team A) and vice versa (add one point to b_points if val2 is larger.) If the two values are even I won't add any points to a_points or b_points.

My problem is test_val will not return the values of a_points or b_points.

a_points=0
b_points=0

def test_val(a_points,b_points,val1,val2):
    if val1 > val2:
        a_points+=1
        return a_points
    elif val2 > val1:
        b_points+=1
        return b_points
    elif val1==val2:
         pass

Here's a link to a visualization showing the problem.

Upvotes: 2

Views: 27965

Answers (7)

urban
urban

Reputation: 5682

Your problem is the that Python integers are immutable which in general is good to read about. A few more details can be found here.

Now, regarding solutions:

  1. As suggested, you can use global variables. Keep in mind this is usually considered bad practice cause it leads to messy code... but globals have their place in programming.

  2. Also suggested, you can always return both a_points and b_points

  3. Use lists to keep score:

    • The test_val will return either 0, 1 or 2 where 0 means equal, 1 means the first argument is larger and 2 means the second argument is larger.
    • Your main script will have a list with the above indexes where it will "keep score"

The code:

a0=5
a1=6
a2=7
b0=3
b1=6
b2=10
points=[0, 0, 0]


def test_val(val1,val2):
    if val1 > val2:
        return 1
    elif val2 > val1:
        return 2
    elif val1==val2:
        return 0

points[test_val(a0,b0)] += 1
points[test_val(a1,b1)] += 1
points[test_val(a2,b2)] += 1

print("eq=%d, A=%d, B=%d" % (points[0], points[1], points[2]))

Output (visualize)

eq=1, A=1, B=1

Hope it helps

Upvotes: 0

alexanderlukanin13
alexanderlukanin13

Reputation: 4715

Global variables are generally a bad idea. Don't use them unless you really have to.

The proper way to implement such counter is to use a class.

class MyCounter(object):

    def __init__(self):
        self.a_points = 0
        self.b_points = 0

    def test_val(self, val1, val2):
        if val1 > val2:
            self.a_points += 1
        elif val2 > val1:
            self.b_points += 1
        else:
            pass

counter = MyCounter()
counter.test_val(1, 2)
counter.test_val(1, 3)
counter.test_val(5, 3)
print(counter.a_points, counter.b_points)

Output:

(1, 2)

Note that returning a value from test_val doesn't make sense, because caller has no way to know if she gets a_points or b_points, so she can't use return value in any meaningful way.

Upvotes: 2

Gormador
Gormador

Reputation: 380

This will simplify your code and logic. And make it work ;-)

a0=5
a1=6
a2=7
b0=3
b1=6
b2=10
a_points=0
b_points=0

def test_val(a_points,b_points,val1,val2):
    if val1 > val2:
        a_points+=1

    elif val2 > val1:
        b_points+=1

    return a_points, b_points



a_points, b_points = test_val(a_points,b_points,a0,b0)
a_points, b_points = test_val(a_points,b_points,a1,b1)
a_points, b_points = test_val(a_points,b_points,a2,b2)

print(a_points,b_points)

Upvotes: 0

Gaurav Dhama
Gaurav Dhama

Reputation: 1336

print (test_val(a_points,b_points,1,2))
print (test_val(a_points,b_points,2,1))
print (test_val(a_points,b_points,2,2))

This will give you a result:

1
1
None

Hence you should not look at the function to return values, rather it updates the values of variables a_points and b_points. That is why in the link that you shared the code includes a print(a_points,b_points) statement at the end

Upvotes: 0

opalczynski
opalczynski

Reputation: 1647

Consider this:

a0=5
a1=6
a2=7
b0=3
b1=6
b2=10
a_points=0
b_points=0

def test_val(a_points, b_points, val1, val2):
    if val1 > val2:
        a_points += 1
        return (a_points, b_points)
    elif val2 > val1:
        b_points += 1
        return (a_points, b_points)
    elif val1==val2:
        return (a_points, b_points)

a_points, b_points = test_val(a_points,b_points, a0, b0)
a_points, b_points = test_val(a_points,b_points, a1, b1)
a_points, b_points = test_val(a_points,b_points, a2, b2)

print(a_points, b_points)

Good luck!

Upvotes: 3

Carles Mitjans
Carles Mitjans

Reputation: 4866

a_points=0
b_points=0

def test_val(a_points,b_points,val1,val2):
    global a_points
    global b_points

    if val1 > val2:
        a_points+=1
        return a_points
    elif val2 > val1:
        b_points+=1
        return b_points

    elif val1==val2:
         # If you pass, it won't return a_points nor b_points
         return a_points # or b_points

Upvotes: 0

Blair d
Blair d

Reputation: 78

Note that a_points and b_points shadow your global variables, since they are also passed as parameters.

Any way, you are not returning value in case of equality, instead of pass, return a value

def test_val(a_points,b_points,val1,val2):
    if val1 > val2:
        a_points+=1
        return a_points
    elif val2 > val1:
        b_points+=1
        return b_points
    elif val1==val2:
         return a_points

Upvotes: -2

Related Questions