3

I have started programming with python yesterday, so I'm quite a newbie!

I have this function, which must check

  1. if an inserted value is a number
  2. if the number is no greater than 31 (see code below)

During debugging, I have found out this bug I don't understand:

  1. I choose deliberately a number greater than 31, for example 45
  2. it prompts me again and I choose a correct number, for example 7
  3. In the code, I ask to print the voto variable twice (in the comments I call them 'POINT A' and 'POINT B')
  4. in the output I get:

    7

    45

and I'm again asked to type in a different number.

I don't understand why the variables changes its value just after the while loop has started.

Can you please explain it to me, using very simple words? (<- please, remember I'm a beginner! :D )

Thank you in advance!

def controlla_voto(voto_lett):
    flag=1
    while flag:
        for y in voto_lett:
            if (ord(y) in range(48,58))==0:
                voto_lett=raw_input("Invalid charachters, try again: ")
                flag=1
                break
            else: flag=0
    voto=int(voto_lett)
    print voto   # POINT A
    while (voto in range(32))==0:
       print voto #POINT B
       voto_lett=raw_input("Invalid number, try again: ")
       controlla_voto(voto_lett)
    return voto
kojiro
  • 74,557
  • 19
  • 143
  • 201
user2669155
  • 87
  • 2
  • 9

1 Answers1

2

It's perfect! You just forgot the return on the recursive call.

def controlla_voto(voto_lett):
flag=1
while flag:
    for y in voto_lett:
        if (ord(y) in range(48,58))==0:
            voto_lett=raw_input("Invalid charachters, try again: ")
            flag=1
            break
        else: flag=0
voto=int(voto_lett)
print voto   # POINT A
while (voto in range(32))==0:
    print voto #POINT B
    voto_lett=raw_input("Invalid number, try again: ")
    return controlla_voto(voto_lett)
return voto

Another solution would be:

voto = controlla_voto(voto_lett)

but something is needed to break out of the while loop.

Jiminion
  • 5,080
  • 1
  • 31
  • 54
  • Thanks for replying! Why do I have to add the return? – user2669155 Aug 09 '13 at 20:50
  • Because you want to get the result of the second call. – Jiminion Aug 09 '13 at 20:54
  • 1
    @user2669155 because you'll have to return whatever the call gave you. If you don't, you'll either `return None` (if you don't hit a `return` statement) or return something different which might be an old value. – glglgl Aug 09 '13 at 20:54
  • I voted up question because it's an odd and interesting use of recursion. – Jiminion Aug 09 '13 at 20:57
  • I thought calling the function would be exactly like copying and pasting all of the previous code infinite times... where am I wrong? – user2669155 Aug 09 '13 at 21:00
  • 1
    Thanks Jim for voting the question! I will certainly vote the answer, just please keep on explaining until I get it... :-$ – user2669155 Aug 09 '13 at 21:02
  • 1
    OK, here's what's going on: The integer voto NEVER changes in the lower while loop, so the only way to get out is to have a return. Without a return, controlla_voto (the second one) just finishes and you are stuck back in that loop. With voto still being something over 31. – Jiminion Aug 09 '13 at 21:03
  • I don't understand two things: 1) is recursion different from copying and pasting the previous code an infinite number of times? 2) I expected the second controlla_voto function to change the value of voto and it actually does, otherwise the print in POINT A wouldn't give the correct result. As the value of voto is correctly changed, why does it get the previous value when entering the loop? Sorry if it's a stupid question. – user2669155 Aug 09 '13 at 21:07
  • @user2660155 Apparently you are a beginner not only in Python but generally in programming. Why then do you mess up with recursive functions? This is an advanced topic. There are many other things you need to clear up in your head first. – Antonis Christofides Aug 09 '13 at 21:27
  • 1
    A new copy of voto is created everytime you call the function. So when the function ends (without a return) then that context ends and the old value is back at that level of processing. Recursion is tricky, and it is different from copying and pasting the code, because call has a new context. – Jiminion Aug 09 '13 at 21:29
  • 1
    @Antonis Christofides: yours is not exactly a costructive comment :D It's true that I'm a beginner, but either you give me a list of what I should clear up first or it's not going to help. I use a recursive function because I need a recursive function. – user2669155 Aug 09 '13 at 21:29
  • @Jim: ok, I think I got it! It probably is the same if I write voto=controlla_voto(voto_lett) right? – user2669155 Aug 09 '13 at 21:37
  • Yes! I just noticed that. That's prob. a better answer for you. – Jiminion Aug 10 '13 at 00:23