Python - The Collatz Sequence Can I get a review of my code for the the Collatz Sequence from Chapter three of Automate the Boring Stuff with Python?


  The Collatz Sequence
  
  Write a function named collatz() that has one parameter named number.
  If number is even, then collatz() should print number // 2 and return
  this value. If number is odd, then collatz() should print and return 3
  * number + 1.
  
  Then write a program that lets the user type in an integer and that
  keeps calling collatz() on that number until the function returns the
  value 1. (Amazingly enough, this sequence actually works for any
  integer—sooner or later, using this sequence, you’ll arrive at 1! Even
  mathematicians aren’t sure why. Your program is exploring what’s
  called the Collatz sequence, sometimes called “the simplest impossible
  math problem.”)
  
  Remember to convert the return value from input() to an integer with
  the int() function; otherwise, it will be a string value.
  
  Hint: An integer number is even if number % 2 == 0, and it’s odd if
  number % 2 == 1.
  
  The output of this program could look something like this:
  
  Enter number:
3
10
5
16
8
4
2
1

  
  Input Validation
  
  Add try and except statements to the previous project to detect
  whether the user types in a noninteger string. Normally, the int()
  function will raise a ValueError error if it is passed a noninteger
  string, as in int('puppy'). In the except clause, print a message to
  the user saying they must enter an integer.


I am mainly wondering if there is a cleaner way to write my solution.

def collatz(num):
    while num &gt; 1:
        if num % 2 == 0:
            print(num//2)
            num = num //2
        elif num % 2 ==1:
            print(3*num+1)
            num = 3*num+1
        else:
            print(num)

def getNum():
    global num
    num = (input("&gt; "))
    try:
        num = int(num)
    except ValueError:
        print('plese enter a number')
        getNum()
getNum()
collatz(num)
Prompt

The most obvious bad practice here is the use of a global variable.  Instead of setting num as a side-effect, your function should return the result.

getNum() is not such a good name for the function.  PEP 8, the official style guide for Python, says that function names should be lower_case_with_underscores.  Furthermore, "get" implies that the function is retrieving a piece of data that is already stored somewhere, which is not the case here.  Finally, "Num" should be more specific.

The use of recursion is not appropriate.  If you want a loop, write a loop.

def ask_integer():
    """
    Return an integer entered by the user (repeatedly prompting if
    the input is not a valid integer).
    """
    while True:
        try:
            return int(input("&gt; "))
        except ValueError:
            print("Please enter an integer")

num = ask_integer()


collatz function

Strictly speaking, you didn't follow the instructions.  Your solution isn't wrong or bad — you just didn't implement the collatz function according to the specification that was given, which says that you should print and return one single number.

def collatz(num):
    """
    Given a number, print and return its successor in the Collatz sequence.
    """
    next = num // 2 if num % 2 == 0 else 3 * num + 1
    print(next)
    return next

num = ask_integer()
while num &gt; 1:
    num = collatz(num)