3

I'm guessing that there is a scope issue here that I missed somewhere. This function squares all of the numbers and adds them together. It should stop if the number hits 1 or 89, otherwise keep going. Here's my code:

count = 0
def chain(x,count):
    x = str(x)
    temp = 0
    for let in range(0,len(x)):
        temp = temp + (int(x[let]) ** 2)
    x = temp
    print("\n")
    print(temp)
    if x == 89:
      count = count + 1
      print(count)
    elif x == 1:
      return False
    else:
        chain(x, count)

 chain(145, 0)

  print(count)

The problem is, when I print count when x == 89, I get 1. But when I print count at the end, it comes out as 0. I've looked over and I don't seem to be setting it to anything else, and I've also tried adding in return, return count, return True, and nothing seems to fix it. If someone could point out my error, I would greatly appreciate it!

Joel Banks
  • 141
  • 1
  • 11

3 Answers3

4

Solution 1: make count a global variable

count = 0
def chain(x):
    global count
    x = str(x)
    temp = 0
    for let in range(0,len(x)):
        temp = temp + (int(x[let]) ** 2)
    x = temp
    print("\n")
    print(temp)
    if x == 89:
      count = count + 1
      print(count)
    elif x == 1:
      return False
    else:
        chain(x)

chain(145)

print(count)

Solution 2: return count and receive it when recursively called.

def chain(x,count):
    x = str(x)
    temp = 0
    for let in range(0,len(x)):
        temp = temp + (int(x[let]) ** 2)
    x = temp
    print("\n")
    print(temp)
    if x == 89:
      count = count + 1
      print(count)
    elif x == 1:
        pass  # you may want to use -1 or something as flag
    else:
      count = chain(x, count)
    return count


print(chain(145,0))
lincr
  • 1,633
  • 1
  • 15
  • 36
  • Thank you, this works perfectly! Since I'm relatively a beginner, which of the two solutions do you recommend using in most situations/ which is better practice? – Joel Banks Dec 19 '18 at 02:13
  • 1
    Generally global variables can make things a mess. Try to read [this question](https://stackoverflow.com/questions/19158339/why-are-global-variables-evil) for detailed discussion. And I also recommend you to read some stuff about name binding in Python to understand what is happening in solution 2. – lincr Dec 19 '18 at 02:19
1

These are two different variables with the same name. the count outside the function will not change when the count inside the function will so printing at the end will give 0

asafpr
  • 347
  • 1
  • 5
1

Well, the count is not exactly a reference since it's a primitive, so you don't get the same object every time (it is immutable).

Also, the count you are referencing outside of the function is not the same you pass initially (since your first call feeds it a 0, not the same variable).

  1. Make count a global variable by removing it from the function parameters and using the modifier global

Example

count = 0
def chain(x):
    global count
    ...
  1. Make the count a mutable type and pass it from the very beginning (e.g. a Class, a Dict, a list).

Example

line 01: count = {'total': 0}
line 20: chain(145, count)
OHHH
  • 1,011
  • 3
  • 16
  • 34