Making a collatz program automate the boring stuff

Question:

I’m trying to write a Collatz program using the guidelines from a project found at the end of chapter 3 of Automate the Boring Stuff with Python. I’m using python 3.4.0. Following is the project outline:

Write a function named collatz() that has one parameter named number. If the number is even, then collatz() should print number // 2 and return this value. If the 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.

The output of this program could look something like this:

Enter number: 3 10 5 16 8 4 2 1 

I am trying to make a function that uses if and elif statements within a while loop. I want the number to print, and then return to the beginning of the loop and reduce itself to one using the Collatz sequence, with each instance of a resulting number being printed as it goes through the loop. With my current code, I’m only able to print the first instance of the number, and that number does not go through the loop after that. Following is my code:

#collatz

print("enter a number:")
try:
    number = (int(input()))
except ValueError:
          print("Please enter a valid INTEGER.")


def collatz(number):
    while number != 1:

        if number % 2==0:
            number = (number//2)
            #print(number)
            return (print(int(number)))

        elif nnumber % 2==1:
            number = (3*number+1) 
            #print(number)
            return (print(int(number)))

        continue


collatz(number)
Asked By: DeltaFlyer

||

Answers:

Your collatz() function should print & return only the next value. (It ends when it returns.)

The while loop should not be inside the collatz() function.

You’ve also got inconsistent variable names (n, number, nnumber), and some important code is commented out.

Answered By: Jonathan Clede
def collatz(number):

    if number % 2 == 0:
        print(number // 2)
        return number // 2

    elif number % 2 == 1:
        result = 3 * number + 1
        print(result)
        return result

n = input("Give me a number: ")
while n != 1:
    n = collatz(int(n))

Output:

Give me a number: 3
10
5
16
8
4
2
1

Give me a number: 11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
Answered By: Nuncjo

Nuncjo got the solution that works. I tweaked it a little to add try and except statements for error handling.

def collatz(number):
    if number % 2 == 0:
        print(number // 2)
        return number // 2

    elif number % 2 == 1:
        result = 3 * number + 1
        print(result)
        return result

try:
    n = input("Enter number: ")
    while n > 0 and n!= 1:
        n = collatz(int(n))
except ValueError:
    print('whoops, type an integer, bro.')
Answered By: docgunthrop
def collatz(number):
    while number != 1:
        if number % 2 == 0:
            number = number // 2
            print(number)

        elif number % 2 == 1:
            number = number * 3 + 1
            print(number)

try:
    num = int(input())
    collatz(num)
except ValueError:
    print('Please use whole numbers only.')

This is what I came up with on my own and based solely on what I’ve learned from the book so far. It took me a little bit but one of the tools I used that was invaluable to me finding my solution and has also been invaluable in learning this content is the python visualizer tool at: http://www.pythontutor.com/visualize.html#mode=edit

I was able to see what my code was doing and where it was getting hung up and I was able to continually make tweaks until I got it right.

Answered By: Ryan Hallberg
def collatz(num): 
    if num % 2: 
        return 3 * num + 1
    else:
        return num // 2

while True:
    try:
    number = int(input('Enter a positive integer.'))  
    if number <= 0: 
        continue
    break
except ValueError: 
    continue


while number != 1:
    number = collatz(number)
    print(number)
Answered By: Maecenas

My Code

def collatz(number):
    while number != 1:
        if number % 2 == 0:
            print(number // 2)
            number = number // 2
        elif number % 2 == 1:
            print(number * 3 + 1)
            number =  number *3 + 1

try:
    print ('Enter the number to Collatz:')
    collatz(int(input()))
except ValueError:
    print('Enter a valid integer')
Answered By: Jebin

Here’s what I came up with:

import sys

def collatz(number):
    if number % 2 == 0:           # Even number
        result = number // 2
    elif number % 2 == 1:         # Odd number
        result = 3 * number + 1

    while result == 1:            # It would not print the number 1 without this loop
        print(result)
        sys.exit()                # So 1 is not printed forever.

    while result != 1:            # Goes through this loop until the condition in the previous one is True.
        print(result)
        number = result           # This makes it so collatz() is called with the number it has previously evaluated down to.
        return collatz(number)    

print('Enter a number: ')         # Program starts here!
try:
    number = int(input())         # ERROR! if a text string or float is input.
    collatz(number)
except ValueError:
    print('You must enter an integer type.')

                                  # Fully working!
Answered By: ubundows
def collatz(number):
    if number % 2 == 0:  # Even number
        return number // 2

    elif number % 2 == 1:  # Odd number
        return number * 3 + 1

print('Please enter a number') # Ask for the number


# Check if the number is an integer, if so, see if even or odd. If not, rebuke and exit
try:
    number = int(input())
    while number != 1:
        collatz(number)
        print(number)
        number = collatz(number)
    else:
        print('You Win. The number is now 1!')
except ValueError:
     print('Please enter an integer')

This is what I came up with for this practice exercise.
It asks for an input
Validates whether it’s an integer. If not it rebukes and exits. If it is, it loops through the collatz sequence until the result is 1 and then you win.

Answered By: Christopher Wales
def collatz(number):
    if number % 2 == 0:
        print(number//2)
        return number // 2
    elif number % 2 == 1:
        print(3*+number+1)
        return 3 * number + 1
r=''
print('Enter the number')
while r != int:
    try:
        r=input()
        while r != 1:
            r=collatz(int(r))
        break   
    except ValueError:
            print ('Please enter an integer')

I added input validation

Answered By: Lukyanov Mikhail

Every solution on this thread is missing one thing: if the user inputs “1” the function should still run the computations of the Collatz sequence. My solution:

def collatz(number):
    while number == 1:
        print("3 * " + str(number) + " + 1 = " + str(3*number+1))
        number = 3*number+1 ##this while loop only runs once if at all b/c at end of it the value of the variable is not equal to 1
    else:
        while number != 1:
            if number % 2 == 0:
                print(str(number) + ' // 2 = ' + str(number//2))
                number = number//2
            else:
                print("3 * " + str(number) + " + 1 = " + str(3*number+1))
                number = 3*number+1

 print('Please input any integer to begin the Collatz sequence.')

while True:
    try:
        number = int(input())
        collatz(number)
        break
    except ValueError:
        print('please enter an integer')
Answered By: stevensonmt
def collatz(number):
    if(number%2==0):
        n=number//2
        print(n)
        return n
    else:
        ev=3*number+1
        print(ev)
        return ev
num1=input("Enter a number: n")

try:
    num= int(num1)
    if(num==1):
        print("Enter an integer greater than 1")
    elif(num>1):
        a=collatz(num) 
        while(True):
            if(a==1):
                break
            else:
                a=collatz(a)
    else:
        print("Please, Enter a positive integer to begin the Collatz sequence")

except:
    print("please, Enter an integer")

Try to came up with a solution based on up to chapter Function from automate the boring stuff.
If need help related to Collatz Problem, then visit here:
http://mathworld.wolfram.com/CollatzProblem.html

Answered By: Md. Raihan

i am reading the same course and i made a very long solution (improving it when i learn somethign new). i suggest keeping your collatz program up to date as you progress in the chapters, its good training. mine has string manipulation and saving to a collatzrecords.txt now!

I solved the core problem by using recursion (a method calls itself):

def autocollatz(number):
global spam                     
spam.append(number)             
if number % 2 == 0:             
    autocollatz (int(number/2))
elif number % 2 == 1 and number != 1:
    autocollatz(int(number*3+1))

spam is my list for all the values a number “sees” on its way to 1.
as you can see, when the number is even the ethod is called agin with number/2. if the number is even it is called with number*3+1.

modified the number == 1 check a bit. i hope it saves calculating time – im up to 23 000 000 already! (current record is 15 733 191 with 704 steps to get it to 1)

Answered By: user7091705
import sys

def collatz(number):
if number % 2 == 0:
    result = number // 2
    print (result)

elif number % 2 == 1:
    result = number * 3 + 1
    print (result)

while result == 1:
    sys.exit

while result != 1:
    number = result
    collatz(number)

print ('Enter a number')

try:
    number = int(input())
    collatz(number)

except ValueError:
    print('Please enter a valid integer')
Answered By: Subterranean
def collatz(number):
    while number != 1:
        if number %2==0:
            number = number//2
            yield number
        elif number %2 ==1:
            number=number*3 +1
            yield number

while True:
    try:
        for n in collatz(int(input('Enter number:'))):
            print(n)
        break
    except ValueError:
        print('Please enter an integer')

The extra while True loop will help the program to continue functioning after the user inputs a non-integer.

Answered By: zheng yang
def collatz(number):
    if number % 2 == 0:
        return number // 2
    elif number % 2 == 1:
        return 3 * number + 1

try:
    chosenInt = int(input('Enter an integer greater than 1: '))

    while chosenInt < 2:
        print("Sorry, your number must be greater than 1.")
        chosenInt = int(input('Enter an integer greater than 1: '))

    print(chosenInt)

    while chosenInt != 1:
        chosenInt = collatz(chosenInt)
        print(chosenInt)

except ValueError:
    print('Sorry, you must enter an integer.')
Answered By: Dylan
def collatz(number): 
    if number%2==0:    
        return number//2
    elif number%2==1:
        return number*3+1
step=1 #counter variable for amusement and seeing how many steps for completion.
try: #in case of ValueError   
    number=int(input('Enter a Number for Collatz Sequencing:')) 
    while collatz(number)!=1:    
        print(collatz(number))
        number=int(collatz(number))
        if collatz(number)!=1: 
            print('Calculating step ' + str(step) + '.')
            step=step+1
        else:
            print ('Calculating step ' +str(step) + '.')
            print('1 Has Been Reached.')
except ValueError: 
     print('Enter an Integer please:')
Answered By: Tossaire

Here’s my 19 lines:

def collatz(number):
    if number % 2 == 0:
        return number // 2
    else:
        return number*3 + 1


number = 0
while number == 0:
    try:
        number = int(input('Please enter a number: '))
        if number == 0:
            print('Number must be an integer not equal to zero.')
        else:
            while True:
                number = collatz(number)
                print(number)
                if abs(number) == 1 or number == -5 or number == -17: 
                    break #Collatz seq ends/enters recurring loop when number hits -17, -5, -1 or 1
    except ValueError:
        print('Number must be an integer.')
Answered By: toonarmycaptain

I think that this solution may be even simpler for learners than the accepted one:

def collatzSequence(number):
    if (number % 2 == 0): # if it's even
        number = number // 2
    else:                 # if it's odd
        number = number * 3 + 1
    print (number)
    return (number)

n = int(input('Enter a number: '))
while (n != 1):
    n = collatzSequence(n)

The result will something like this:

Enter a number: 5
16
8
4
2
1
Answered By: Noob

My 17 lines of code for the same exercise that I have came up with.

    def collatz(number):
    """ check if the number is even or odd and performs calculations.
    """
    if number % 2  == 0: # even
        print(number // 2)
        return number //2
    elif number % 2 != 0: # odd 
        result = 3*number+1
        print(result)
        return result

try:
    n = input('Enter number: ') # takes user input
    while n !=1: # performs while loop until 'n' becomes 1
        n = collatz(int(n)) # passes 'n' to collatz() function until it arrives at '1'
except ValueError:
    print('Value Error. Please enter integer.')
Answered By: Simas

I managed to get it right without using any return statements and nested a while loop inside the function.

number=int(input('Enter number:n'))

def collatz(number):

    while number !=1:
        if number% 2 == 0:
            number= number//2
            print(number)

        else:
           number=  3 * number + 1
           print(number)    


collatz(number)
Answered By: user11435774

I have added the try and except like this (with a break)

def collatz(number):
if number %2 == 0:
    print(number//2)
    return number//2
elif number %2 == 1:
    print(3 * number + 1)
    return 3 * number + 1

n = input("Give me a number: ")

while n != 1:
    try:
        isinstance(n, int)
        n = collatz(int(n))
    except:
        print('Error: Invalid argument.')
        break
Answered By: Flip Vermeersch

14 lines:

Don’t get why we need “elif number %2 == 1:” instead of simple ‘else’?

def  collatz(number):
    while number != 1:
        if number %2 == 0:
            number = number/2
            print(number)
        else:
            number = 3*number+1
            print(number)
print('Enter a number')
try:
    number = (int(input()))
except ValueError:
          print("Please enter an INTEGER.")
collatz(number)
Answered By: Mike K

I had a hard time understanding the logic of this exercise.
but I don’t know what I did wrong to display the error if we have a negative number.

def collatz(number):
if number % 2 == 0:
    print(number // 2)
    return number // 2

elif number % 2 == 1:
    result = 3 * number + 1
    print(result)
    return result

while True:
try:
    entry = input('enter a positive number: ')
    while entry != 1:
        entry = collatz(int(entry))

    # if we have a negative number
    while entry < 1:
        break

except ValueError:
    print('Error, enter valid number')
Answered By: Kimochi Neina
def cyclic(number):
    if number % 2 == 0:
        if number // 2 == 1:
            print(1)
        else:
            print(number//2)
            cyclic(number // 2)
    else:
        print((number * 3) + 1)
        cyclic((number * 3) + 1)


print("Enter a number:")
try:
    n = int(input())
    cyclic(n)
except ValueError:
    print("Unvalied value")

The simplest one

Answered By: user12640668

You can simply try this

while True:
 number=int(input('Enter next positive number or 0 to quit: '))
 iteration=0
 currentNumber=0
 item=1
 sumOfNumbers=0
 print(number,end='  ')
 if(number):
    while currentNumber !=1 :
        currentNumber=int(number/2) if(number%2==0) else number*3+1
        number=currentNumber
        iteration +=1; item +=1
        sumOfNumbers +=currentNumber
        print(currentNumber,end ='n' if(item %5==0) else '  ')
    print('nIt took ',iteration,'iterations to arrive at 1')
    print('The average  is ',round((sumOfNumbers/iteration),2))
 else :
    break
Answered By: Ruman
  1. In your program (question), after return statement is executed, continue is not executed. so it will loop for only one iteration.

  2. Your program will not work for input integer 1. You may want to check the result of method with 1, should not check the user input in the beginning itself. 1 is also a valid input to the program.

  3. Methods would be preferred to perform one action. (SOLID principles of programming). Better to call function in a loop rather than looping inside function. increases the reusability of the method.

def collatz(number):
    if number % 2 == 0:
        print(number // 2)              # logically, floor division is equivalent to division when even number with 2
        return number // 2
    elif number % 2 != 0:
        print(number * 3 + 1)
        return number * 3 + 1


number = int(input("Please enter a numbern"))
result = collatz(number)                # this way the program also takes 1 as input
while result != 1:
    result = collatz(result)



# Output:


Please enter a number
1
4
2
1

Please enter a number
32
16
8
4
2
1

Formatted output

Answered By: Surendra

This is a perfect recursive problem, wonder why no body code it like that:

def Collatz(Num):
    if Num==1:
        return
    if Num % 2 == 1:
        newNum=int(Num*3+1)
    else:
        newNum=int(Num/2)
    print(newNum)
    Collatz(newNum)
#------------------------------------
Num = input("Enter your value: ")
try:
    val = int(Num)
    if val < 0 :
        print("Error: Please enter a positive integer only")
        exit(1)
except ValueError:
    print("Error: Please enter a positive integer only")
    exit(1)

Collatz(int(Num))
=============================================
Enter your value: 11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
Answered By: FEldin
import sys   
result = 0   
print('key in any integer:')

def collatz():   

    number = int(input())    
    if number % 2 == 0:    
        result = number//2    
        print (result)    
        if result == 1:    
            print('finally u got it')    
            sys.exit()    
    if number % 2 == 1:    
        result = 3 * number + 1    
        print (result)

while result != 1:  
    collatz()
Answered By: user6201481
import sys

def collatz(number):
    global x
    if number % 2 == 0:
        even = number // 2
        print(even)
        if even == 1:
            sys.exit()
    elif number % 2 == 1:
        odd = 3 * number + 1
        print(odd)


while True:
    try:
        x = int(input('Enter an int: '))
        collatz(x)
    except ValueError:
        print('Please input number.')
Answered By: Reitei17
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.