Making a collatz program automate the boring stuff

2019-01-17 22:42发布

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. Here's the project outline:

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.

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. Here's 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)

20条回答
Fickle 薄情
2楼-- · 2019-01-17 23:08

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
查看更多
Fickle 薄情
3楼-- · 2019-01-17 23:09

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 != 1:
        n = collatz(int(n))
except ValueError:
    print('whoops, type an integer, bro.')
查看更多
小情绪 Triste *
4楼-- · 2019-01-17 23:10

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.')
查看更多
Evening l夕情丶
5楼-- · 2019-01-17 23:10

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)

查看更多
地球回转人心会变
6楼-- · 2019-01-17 23:11

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')
查看更多
Juvenile、少年°
7楼-- · 2019-01-17 23:13
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)
查看更多
登录 后发表回答