0

Simple while loop, not working as expected. I am trying to create a function that will simulate a roll of a die, and keep a running total of the result, until that total is >= m, at which point it should stop. I want to know what the final total is, and how many rolls it took to get there.

Currently it rolls twice, and reports a sum of 9. I have checked the code outside the loop and it does what it should do (that is, these 3 lines: r = rdm.randint(1,6), tot += r, rolls.append(r)).

What am I missing??

def roll(m):
    rolls = []
    tot = 0
    while tot < m:
        r = rdm.randint(1,6)
        tot += r  
        rolls.append(r)
    return tot
    return rolls
    return r

m=100    
roll(m)    
print "The number of rolls was", len(rolls)  
print "The total is", tot
5
  • Please reduce your example, e.g. the while-loop is completely irrelevant. Commented Apr 9, 2015 at 5:59
  • why 3 return statements? return statement will return code. Also not accepting return value roll(m) Commented Apr 9, 2015 at 6:00
  • How can it report anything other than a NameError since rolls doesn't exist outside the function? Commented Apr 9, 2015 at 6:02
  • @Ulrich it is?? how can I achieve this otherwise - repeat an action until a condition is met? Commented Apr 9, 2015 at 15:29
  • Your problem seems to be with the behaviour of function calls (passing data between caller and callee), not with the behaviour inside, because the while loop works correctly, as far as I can tell. Even if that was not your issue, you could still reduce the code, because then the function call would probably be superfluous. Learn breaking down problems into smaller pieces, it helps you focus on manageable parts. Commented Apr 9, 2015 at 18:25

3 Answers 3

6

It seems you have a misconception on how control returns from a function and how to return values. The current issue is nothing pertinent to your while loop rather how you are processing returns from a function.

You should understand that there can be multiple return paths but for any particular execution, one and only one return is executed, any subsequent returns in a sequential path is ignored.

Also, you need a way to capture the return values and it cannot automatically pollute your global namespace

So to summarize and solve your problem, a possible way out would be

def roll(m):
    rolls = []
    tot = 0
    while tot < m:
        r = rdm.randint(1,6)
        tot += r  
        rolls.append(r)
    return tot, rolls, r
tot, rolls, r = roll(m) 
print "The number of rolls was", len(rolls)  
print "The total is", tot
Sign up to request clarification or add additional context in comments.

Comments

0

This should work in general, but you're using multiple return statements in a row for one function -- that won't work. The moment a function evaluates a return, that function stops firing. If you want to return multiple values, return a tuple:

def roll(m):
    rolls = []
    tot = 0
    while tot < m:
        r = rdm.randint(1,6)
        tot += r  
        rolls.append(r)
    return tot, rolls, r

m=100    
a, b, c = roll(m)    
print "The number of rolls was", len(b)  
print "The total is", a

Comments

0

You can only have to one return statement. Separate your return values with a comma and assign them to variables when you call the function using multiple assignments.

return tot, rolls, r

And when you call the function:

tot, rolls, r = roll(m)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.