Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
The Collatz Sequence
#1
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.

def collatz(number):
    if number % 2 == 0:
        print(number//2)
    else:    
        result = 3*number + 1
        print(result)        
try:
    n = input("Give me a number: ")
    while n != 1:
        n = collatz(int(n))
except ValueError:
    print('Type a number please!')
message:
Traceback (most recent call last):
File "C:\Python36\kodovi\coll.py", line 10, in <module>
n = collatz(int(n))
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'


Not sure why am I receiving this message.
Reply
#2
Is this your full code? How are you running it? Are you providing any input to it? If so, please provide it.
Reply
#3
your collatz function is not returning anything so you should change it to something like this:
def collatz(number):
    if number % 2 == 0:
        return number//2
    else:    
        return 3*number + 1
and then print the result inside your while loop.
Reply
#4
Hello,

the main problem is that your function doesn't return any value, like mlieqo says. Also you have two points more to revise:

1- input function returns a 'char'. Then you are comparing in your loop in its first iteration a char with a int. '1' is not the same that 1. You solve it to cast the input.

2- You are not controlling negative values. Then, a -1, -5, -100... values are allowed (maybe "while n>1")

Maybe anything like this:
def collatz(number):
    if number % 2 == 0:
    	result = number//2
    	return result
    else:    
        result = 3*number + 1
        return result
try:
    n = int(input("Give me a number: "))
    while n != 1:
    	print(n)
    	n = collatz(n)
except ValueError:
    print('Type a number please!')
... Sorry for my low English level...
Reply
#5
(Apr-17-2018, 11:10 PM)micseydel Wrote: Is this your full code? How are you running it? Are you providing any input to it? If so, please provide it.

After I run the file in command prompt ( like any other code ) it asks me for a number and after I add it it gives me that error..

(Apr-18-2018, 09:29 AM)mlieqo Wrote: your collatz function is not returning anything so you should change it to something like this:
def collatz(number):
    if number % 2 == 0:
        return number//2
    else:    
        return 3*number + 1
and then print the result inside your while loop.

def collatz(number):
    if number % 2 == 0:
        print(number//2)
        return number//2
    else:    
        result = 3*number + 1
        print(result)  
        return result		
try:
    n = input("Give me a number: ")
    while n != 1:
        n = collatz(int(n))
except ValueError:
    print('Type a number please!')
This code works fine after I add return to if/else statement.

vaison, this edit solved the issue with negative integers.
while n != 1:
        n = collatz(abs(int(n)))
Reply
#6
Hello,

I think that in your first iteration you're still comparing a char with an integer. Try to introduce '1' and verify if the execution doesn't enter to the loop. I think that you must do the cast to integer in the input() function and not in the collatz function.

try:
    n = int(input("Give me a number: "))
    while n != 1:
        print(n)
        n = collatz(abs(n))
except ValueError:
    print('Type a number please!')
What do you think?
Reply
#7
Hi,

When I input 1 it gives:
4
2
1

I don't know what exactly to think :)
Reply
#8
Hello,

Do you want that when you input 1, the loop condition doesn't acomplish?
while n != 1:
Then, if you input 1, there should not be any print at the output. Not?

I said that you are comparing a char (input()) with an integer 1. Then you can cast to int the returned value of the input() function.

My English level is not good. I explained myself well?
Reply
#9
Aha, now I get what you mean. Yes, you are correct.
The final code:

def collatz(number):
    if number % 2 == 0:
        print(number//2)
        return number//2
    else:    
        result = 3*number + 1
        print(result)  
        return result		
try:
    n = int(input("Give me a number: "))
    while n != 1:
        print(n)
        n = collatz(abs(n))
except ValueError:
    print('Type a number please!')
Reply
#10
Truman, in your final code, you are now printing the results twice, first in your collatz function and then in your while loop. So now if I input f.e. number 3 output is:
Output:
3 10 10 5 5 16 16 8 8 4 4 2 2 1
You should remove print from your collatz function, and probably add one more condition for printing number 1.
def collatz(number):
    if number % 2 == 0:
        return number//2
    else:    
        result = 3*number + 1
        return result       
try:
    n = int(input("Give me a number: "))
    while n != 1:
        print(n)
        n = collatz(abs(n))
    if n == 1:
        print(n)
except ValueError:
    print('Type a number please!')
Also one more thing to consider -> I dont think user should be able to input negative number, from what I read on wikipedia -
Quote:The Collatz conjecture is a conjecture in mathematics that concerns a sequence defined as follows: start with any positive integer n.

Actually in this case, if statement from my comment above
    if n == 1:
should be replaced with else(same result, but nicer).
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Collatz-problem CaptainNeemo 2 2,206 Dec-07-2020, 04:09 PM
Last Post: deanhystad
  How can I found how many numbers are there in a Collatz Sequence that I found? cananb 5 3,771 Nov-23-2020, 05:15 PM
Last Post: cananb
  [split] The Collatz Sequence valencia 4 3,694 Jan-06-2019, 08:10 PM
Last Post: valencia

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020