This is my first Project that i have to accomplish from the tutorial im currently facing.So here is the Problem i have.I am trying to use collatz(number) in order to get the collatz sequenze.I tryd to find a similar Problem on stackoverflow but nothing i could relate to (or rather me not understanding it maybe).The error occurs on the second int part.An invalid syntax error occurs on it. I checked everything i could think of(checked all spaces inbetween also changed "except" to "else" because i had trouble there) and than this problem occurred.I also tried to get another paranthese on else int((number)) %2==1: but that didn't help either. i hope you have enough information to help me out.Thank you very much for your Time.
def collatz(number):
number=input()
try:
if int(number) %2==0:
print('hi')
else int(number) %2==1:
print(int(number*3+1))
So to fix your code as described:
def collatz(number):
number = input() # number is passed in - doesn't make sense to get it again
try:
number = int(number) # Just interpret once
except ValueError: # try must have an except clause
return # exit on error
if number%2 == 0:
print('hi')
elif number%2 == 1: # Don't really need an elif - %2 can only have 2 values
print(number*3+1)
However, you may want to look into using a generator (yield):
def collatz(number):
while number > 1:
if number % 2 == 0:
number //= 2
else:
number = 3*number + 1
yield number
def collatz_series():
try:
number = int(input())
except ValueError:
return
for n in collatz(number):
print(n)
Related
Hi I want to get a number from user and only except input within a certain range.
The below appears to work but I am a noob and thought whilst it works there is no doubt a more elegant example... just trying not to fall into bad habits!
One thing I have noticed is when I run the program CTL+C will not break me out of the loop and raises the exception instead.
while True:
try:
input = int(raw_input('Pick a number in range 1-10 >>> '))
# Check if input is in range
if input in range(1,10):
break
else:
print 'Out of range. Try again'
except:
print ("That's not a number")
All help greatly appreciated.
Ctrl+C raises a KeyboardInterruptException, your try … except block catches this:
while True:
try:
input = int(raw_input('Pick a number in range 1-10 >>> '))
except ValueError: # just catch the exceptions you know!
print 'That\'s not a number!'
else:
if 1 <= input < 10: # this is faster
break
else:
print 'Out of range. Try again'
Generally, you should just catch the exceptions you expect to happen (so no side effects appear, like your Ctrl+C problem). Also you should keep the try … except block as short as possible.
There are several items in your code that could be improved.
(1) Most importantly, it's not a good idea to just catch a generic exception, you should catch a specific one you are looking for, and generally have as short of a try-block as you can.
(2) Also,
if input in range(1,10):
would better be coded as
if 1 <= input < 10:
as currently function range() repeatedly creates a list of values form 1 to 9, which is probably not what you want or need. Also, do you want to include value 10? Your prompt seems to imply that, so then you need to adjust your call to range(1, 11), as the list generated will not include the upper-range value. and the if-statement should be changed to if 1 <= input <= 10:
You can use this code:
def read_int(prompt, min, max):
while True:
try:
val = int(input(prompt))
except ValueError:
print('Error: wrong input')
else:
if(min <= val < max): # this is faster
break
else:
print('Error: the value is not within permitted range (min..max)')
return val
v = read_int("Enter a number from -10 to 10: ", -10, 10)
print("The number is:", v)
I am going through book automate boring stuff with python and trying to solve the practical problems.
In this project I need to define collatz() function and print results as seen in code until it gets 1.
So basically i need to input only one number and program should return numbers until it returns 1.
Program works fine but i have one question if i can make it better :D .
My question is after using try: and except: is there a way to not end process when typing string in input function but to get message below 'You must enter number' and get back to inputing new number or string and executing while loop normally. Code works fine just wondering if this is possible and if so how?
def collatz(number):
if number % 2 == 0:
print(number // 2)
return number // 2
else:
print(3 * number + 1)
return 3 * number + 1
try:
yourNumber = int(input('Enter number: '))
while True:
yourNumber = collatz(yourNumber)
if yourNumber == 1:
break
except ValueError:
print('You must enter a number')
Put the try/except inside a loop, such that on the except the loop will continue but on a success it will break:
while True:
try:
yourNumber = int(input('Enter number: '))
except ValueError:
print('You must enter a number')
else:
break
while yourNumber != 1:
yourNumber = collatz(yourNumber)
I'm currently working on the collatz project in chapter 3 of Automate the Boring Stuff. I have a fully working collatz function for integer inputs, however I'm stuck trying to get the program to run when I add try, except statements for non-integer values.
Here is my code that only works for integer inputs:
def collatz(number):
if number % 2 == 0:
print(number // 2)
return(number // 2)
else:
print(3 * number + 1)
return(3 * number + 1)
print('Type in a number: ')
colNum = int(input())
while colNum != 1:
colNum = collatz(colNum)
Now, heres my code when I add a try/except statement:
def collatz(number):
if number % 2 == 0:
print(number // 2)
return(number // 2)
else:
print(3 * number + 1)
return(3 * number + 1)
def integercheck(inputVal):
try:
return int(inputVal)
except ValueError:
print('Error: Input needs to be a number.')
print('Type in a number: ')
integercheck(input())
print('Type in a number: ')
colNum = integercheck(input())
while colNum != 1:
colNum = collatz(colNum)
and here is the error code I recieve:
Type in a number:
string
Error: Input needs to be a number.
Type in a number:
string
Error: Input needs to be a number.
Type in a number:
5
Traceback (most recent call last):
File "/Users/Library/Preferences/PyCharmCE2018.2/scratches/scratch_1.py", line 22, in <module>
colNum = collatz(colNum)
File "/Users/Library/Preferences/PyCharmCE2018.2/scratches/scratch_1.py", line 3, in collatz
if number % 2 == 0:
TypeError: unsupported operand type(s) for %: 'NoneType' and 'int'
Process finished with exit code 1
To be clear, this program works when I throw in an integer immediately, but it fails to work when I throw in an integer after I've typed in a string. If anyone could help I would appreciate it. Thank you!
The recursive case doesn't return anything, so control reaches the end of the function as the call stack resolves (Python functions implicitly return None, hence your error). Change the line:
integercheck(input())
to
return integercheck(input())
or avoid recursion entirely. A few additional remarks:
Avoid printing inside your function. This side effect makes it less reusable.
input("") takes a prompt string that's worth taking advantage of.
Use snake_case in Python per PEP8
collatz only does one step of the sequence, so the name is a little misleading. The burden of setting the next iteration falls on the caller, but this does give the caller some flexibility in determining what to do with intermediate values. With that in mind, this function seems like a perfect fit for refactoring to a generator, giving the ability to take elements one at a time or run the whole sequence as the calling code sees fit.
A possible rewrite:
def collatz(n):
while n > 1:
if n % 2 == 0:
n //= 2
else:
n = 3 * n + 1
yield n
def get_int(prompt="Enter a number: ",
err="Error: Input needs to be a number."):
while True:
try:
return int(input(prompt))
except ValueError:
print(err)
if __name__ == "__main__":
for step in collatz(get_int()):
print(step)
Seeing as this book is a beginners guide to Python, and I am n00basF the code I wrote that got this to work is as follows:
def collatz(number):
try:
number = int(number)
while (number) != 1:
if number % 2 == 0:
number = number // 2
print(number)
elif number % 2 == 1:
number = 3 * number + 1
print(number)
else:
break
except ValueError:
print('ERROR!!! You need to enter an integer.')
print('Enter a number: ')
userNumber = input('>> ')
collatz(userNumber)
My code is below. To do the exception handling, I put it in a while loop that breaks to call the collatz function.
In my collatz function, it tests to see if the number is 1 first, then proceeds to check if the number is even or odd, and proceeds with the operation to create the new number and prints it. I call the collatz function recursively within my odd / even blocks using my new number.
def collatz(number):
if int(number) == 1:
print('')
elif int(number) % 2 == 0:
newNumber = int(number / 2)
print(newNumber)
collatz(newNumber)
elif int(number) % 2 == 1:
newNumber = int(3 * number + 1)
print(newNumber)
collatz(newNumber)
print('Enter a number:')
while True:
try:
number = int(input())
break
except ValueError:
print('Please enter a NUMBER:')
collatz(number)
I have this program:
def validateNumber(number):
if (count > 10) :
print('Invalid number')
return -1
elif (count < 10):
print('Invalid number')
return -1
while True:
count = 0
num = int(input('Number:'))
while num > 0:
num = num//10
count = count+1
if (count == 10) :
break
But I can't print the print('Invalid number') and it turn out to be like this:
Number:122344
Number:123442
Number:1234567890
>>>
I want it to print the print('Invalid number') when the number is less or more than 10.
Number:122344
Invalid number
Number:123442088080989098
Invalid number
Number:1234567890
>>>
Help please. Thanks
The return -1 is for if the number is missing or invalid
Firstly, you could condense your if check to one statement. Note that the easiest way to count the number of digits is to convert it to a string and check its length.
def validateNumber(number):
if len(str(number)) != 10:
return -1
Unfortunately, you do not return a legitimate value if the number is valid. Why not return a boolean value instead?
def validateNumber(number):
if len(str(number)):
return True
return False
You can further reduce this to:
def validateNumber(number):
return len(str(number)) == 10
Note that all the validation logic has now been moved to the function. You'll see how this simplifies the loop code.
Next, you have defined two loops. When you break from the inner, the outer will continue, so you come back to the inner, thus restarting the process.
As a fix, I'd recommend doing this with one loop only, like this:
while True:
x = int(input('...'))
if validateNumber(x):
break
else:
print('Invalid Number')
Since validateNumber returns a bool result, simply have the if query the return value, and break if the number is valid, otherwise the loop repeats.
The good thing about having all your validation code inside the function is that you don't have to modify your loop code if your validation logic changes.
If the player types in any out of range or invalid values, I want it to loop back to ask him to place his bet again.
I can get this half-way working when I wrap raw_input with int().
However, if say the player accidentally typed a letter or just hit enter without typing anything, it would throw an error, thus stopping the game/script.
So if a player does make a mistake like that, I need it to loop back to "Place your bet" again instead of throwing an error and crashing the script.
def betAmount():
if number_of_hands == 1:
if chip_count_player1 > 0:
global chips_bet
chips_bet = raw_input("Place your bet!")
if chips_bet in range(0, chip_count_player1 + 1):
print "Your bet is within range"
else:
print "NOT IN RANGE"
betAmount()
You need to convert the chips_bet to a number like this
try:
chips_bet = int(raw_input("Place your bet!"))
except ValueError:
betAmount()
You are constructing a new list of numbers and then checking if the chips_bet is there in it or not. That is inefficient. You can check like this
if 0 <= chips_bet <= chip_count_player1:
The base idea can be implemented like this
bet = getBet()
...
def getBet(maximum):
bet = -1
while (bet < 0) or (bet > maximum):
try:
bet = int(raw_input("Place your bet!"))
except ValueError: pass
return bet
you can split your prompt/input/validate loop into a little function, and just call that (it's easier to separate the retry loop from the program logic)
For example, this won't throw, and will only return a validated number:
def safe_int_input(prompt, validate):
while True:
try:
val = int(raw_input(prompt))
if validate(val):
return val
except: pass
print "invalid input"
and you'd call it like this:
chips_bet = safe_int_input("Place your bet! ",
lambda v:(v >= 0 and v <= chip_count_player1))