Why am I getting syntax error on 'excpet'? - python

I don't know why i'm getting a syntax error on 'excpet'. All seems well to me! Here's my code:
def length():
gameLength = int(input("How many words do you want to play? You can chose anywhere from 1-40: "))
global gameLength
if gameLength <= 40 and gameLength >= 1:
quit
else:
int(input("Please choose a number between 1 & 40 "))
except ValueError = True:
int(input("Please choose a number between 1 & 40 "))
return gameLength

You need to indent your code correctly, and add a try statement before the except. You also need to evaluate the true with '==' instead of '='.
def length():
global gameLength
gameLength = int(input("How many words do you want to play? You can chose anywhere from 1-40: "))
if gameLength <= 40 and gameLength >= 1:
quit
else:
try:
int(input("Please choose a number between 1 & 40 "))
except ValueError == True:
int(input("Please choose a number between 1 & 40 "))
return gameLength

Solution:
First, you got to indent your function (not the main error). Now on to the next errors:
1. You must have a try statement before having an except. Also, rather than repeating the same function, you should use return ValueError. Here, I modified the code but made it what you desired:
try:
if gameLength <= 40 and gameLength >= 1:
quit
else:
return ValueError
except ValueError: // or except ValueError == true
length()
Look at the line with except ValueError = true:. One equal sign means you are assigning ValueError to equal true, like you say x = 10. Two equal signs mean that you are asking, "does it equal true?", like saying 1 + 5 == 6 will return true, because 1+5 IS 6. Now go back to your ValueError.
Change your except line with: except ValueError == true. Now you're asking, "is the ValueError equal to true?" rather than saying, "ValueError MUST equal true!" You can also say except ValueError because if statements and other statements always go if it returns true. For example, if true: will work or while true will go on forever, but if 1+1==3: will never work, because 1+1==3 returns false.
Assign gameLength as a global variable before assigning it a value.
Put gameLength in the try statement:
try:
gameLength = int(input("How many..."))
Why? Because if you put it before the try statement and the input was, for instance, "hi", you can't make "hi" an integer. Try statements try to do something, and after failing, doesn't just give up and return an error, but does what the programmer wants it to do. In this case, we want it to repeat the function, so we will do length() on the except. And that's
repeating the function over and over.
except ValueError:
print("Please type a number from 1-40.")
length()
Finally, I'll change one more thing:
quit is a function. Make it quit(), or it won't quit, as you expected.
Output (And Code)
def length():
global gameLength
try:
gameLength = int(input("How many words do you want to play? You can choose any number from 1-40: "))
if gameLength <= 40 and gameLength >= 1:
quit()
else:
return ValueError
except ValueError:
print("Please type a number from 1-40.")
length()
return gameLength
length()
IDLE: How many words do you want to play? You can choose any number from 1-40:
ME: "I'm a string."
IDLE: Please type a number from 1-40.
IDLE: How many words do you want to play? You choose any number from 1-40:
ME: 54919
IDLE: Please type a number from 1-40.
IDLE: How many words do you want to play? You choose any number from 1-40:
ME: 37.1
*Making number an integer: 37.1 => 37.
CON: 37
Quitting Python.

Related

Try/Except handling

Today i made this function to try and understand the try/except.
If i run this code it should ask for a positive integer x, to roll a dice function x times.
I made the code below but it seems to never get in the "ValueError". I'd like to check if the input (n) is first an integer (digit in the string) and secondly if the integer is positive. if one of these occur, raise the exception.
How can i fix it that it works correctly?
def userInput():
while True:
try:
n=input("How many times do you want to roll the dice? ")
if not n.isdigit():
raise TypeError
n = int(n)
if n < 0:
raise ValueError
else:
break
except ValueError:
#if type is integer but not a positive integer
print("Please enter a positive integer")
except TypeError:
#if type is not an integer
print("Only positive integers allowed")
return n
Stripping out the - doesn't address the issue of some digits not actually being integers, as Matthias's link describes. You would be much better off trying to convert to int without checking isdigit(). If the input can't be converted to an integer, this raises a ValueError with the message "invalid literal for int() with base 10: '...'".
If you want to raise a ValueError with a custom message for your positive number check, you can do raise ValueError("Please enter a positive integer")
Then, in the except block, you can access this message through the .args attribute of the exception:
def userInput():
while True:
try:
n = int(input("How many times do you want to roll the dice? "))
if n < 0:
raise ValueError("Please enter a positive integer")
else:
return n # You probably want to do this instead of just break out of the loop
except ValueError as ex:
print(ex.args[0])
Calling the function gives:
How many times do you want to roll the dice? -5
Please enter a positive integer
How many times do you want to roll the dice? abc
invalid literal for int() with base 10: 'abc'
How many times do you want to roll the dice? 1
To be clear, it would be cheaper to simply print the error message for non-positive integers instead of raising an error only to catch it immediately. That way, you can modify the message that is printed when the int() conversion fails. Consider:
def userInput():
while True:
try:
n = input("How many times do you want to roll the dice? ")
n = int(n)
if n < 0:
print("Please enter a positive integer")
else:
return n # You probably want to do this instead of just break out of the loop
except ValueError as ex:
print(f"Hey, {n} is not a valid integer!")
which would print:
How many times do you want to roll the dice? abc
Hey, abc is not a valid integer!
How many times do you want to roll the dice? 10.5
Hey, 10.5 is not a valid integer!
How many times do you want to roll the dice? -100
Please enter a positive integer
How many times do you want to roll the dice? 100
Your code works perfectly for positive numbers, to handle negative numbers, you need to modify at one place
if not n.lstrip('-').isdigit():
I hope this solves your problem

How to print a message to the user when a negative number is inputed?

I am learning about the try and except statements now and I want the program to print out a message when a negative number is inserted but I don't know how to create the order of the statements for this output:
print("how many dogs do you have?")
numDogs= input()
try:
if int(numDogs)>=4:
print("that is a lof of dogs")
else:
print("that is not that many dogs")
except:
print("you did not enter a number")
I want the program to print tje output when the user enters a negative number.
How can I do it?
Just code is like
try:
if no<0:
print("no is negative ")
raise error
And further code will be as it is
Here is what you are trying to achieve.
class CustomError(Exception):
pass
print("how many dogs do you have?")
try:
numDogs = int(input())
if numDogs < 0:
raise CustomError
elif int(numDogs)>=4:
print("that is a lot of dogs")
else:
print("that is not that many dogs")
except CustomError:
print("No Negative Dogs")
except:
print("you did not enter a number")
You can start by creating a custom exception. See https://www.programiz.com/python-programming/user-defined-exception
After which, you should have a condition to first detect the negative value then raise an error from it.
Finally, You can then create multiple excepts to get different error. The first except is raised on input of negative values (as your condition will do for you) whereas the second is used to catch non valid value such as characters.
Note that your int(input) segment should be WITHIN your try block to detect the error
Solution I found is from this SO question
I want the program to print out a message when a negative number is inserted
You can raise a valueError like #Jackson's answer, or you can raise an Exception like in my code below.
elif numDogs < 0:
raise Exception("\n\n\nYou entered a negative number")
def main():
try:
numDogs= int(input("how many dogs do you have? "))
if numDogs >= 4:
print("that is a lot of dogs")
elif numDogs < 0:
raise Exception("\n\n\nYou entered a negative number")
else:
print("that is not that many dogs")
except ValueError:
print("you did not enter a number")
main()
One thing that I though I should point out is that its probably better practice to just check if the number is < 0 or is NAN. But like you said, you're trying to learn about the try and except statements. I thought it was cool that in this code segment:
try:
if numDogs < 0:
raise ValueError
except ValueError:
print("Not a negative Number")
you can throw what error you want and your try will catch it. Guess im still learning a lot too. Only part is, if that happens if your code then one won't know if its a negative number issue or if the number is something like "a", which cannot be converted to one (in this way).
All in all, I think its best to solve this problem with no try / except statements:
def main():
num_dogs = input("# of dogs: ")
if not num_dogs.isnumeric():
return "Error: NAN (not a number)"
num_dogs = int(num_dogs)
return ["thats not a lot of dogs", "that's a lot of dogs!"][num_dogs >= 4] if num_dogs > 0 else "You Entered a negative amount for # of dogs"
print(main())
Notice that I wrapped everything in a `main` function, because that way we can return a string with the result; this is important because if we get an error we want to break out of the function, which is what return does.

How do I get this loop to iterate back to the line indented right under the while keyword?

I've been trying this code, and everything works unless I guess the wrong number, and then it loops back to ask how many sides are on the dice, rather than asking you to guess another number. What am I doing wrong?
import random
def guessDice():
try:
numSides = int(input("\nHow many sides are on your dice? "))
print("\nYour dice is being rolled...")
while True:
numGuess = int(input("\nPick a number from 1 to " + str(numSides) + " "))
randNum = random.randint(1, numSides)
if numGuess == randNum:
print("\nCongrats! You got it!")
break
else:
print("\nSorry, you guessed the wrong number! Try again.")
except ValueError:
print("\nYou typed in the wrong value. This time, type an integer!")
guessDice()
So try/except blocks should be as succinct as possible. Consider rewriting:
import random
# Helper function which verifies that the user input is an integer
def get_integer_input(user_prompt: str) -> int:
while True:
try:
return int(input(f"{user_prompt}\n > "))
except ValueError:
print("Invalid input! Please enter an integer!")
def guessDice():
num_sides = get_integer_input("How many sides are on your dice?")
print("\nYour dice is being rolled...")
die_roll = random.randint(1, num_sides)
while True:
user_guess = get_integer_input(f"Pick a number from 1 to {num_sides}")
if user_guess == die_roll:
print("\nCongrats! You got it!")
break
else:
print("\nSorry, you guessed the wrong number! Try again.")
guessDice()
This adds a helper function which verifies the user input and fixes some issues with your code, most prominently the fact that you were re-generating a random die roll every time the user guessed incorrectly, resulting in what could be potentially an infinite loop if the user continues to guess wrongly (even if you go 1-6 for a 6-sided die, you're re-rolling every guess, meaning it's entirely possible to just keep guessing wrong).
The try/except is short and sweet: all it tries to do is cast the user input to an integer, and if it fails, it asks again. If it succeeds, it breaks from the while loop, and then the dice-guessing logic happens.
I've also changed the "pick a number" prompt to an f-string so that you don't need to cast and concatenate the user input.
Lastly, I changed "dice" to "die", and converted your variables and functions to snake_case, with which Python is conventionally written.

Using a While loop in python when asking for something specific

Question is to
Prompt the user for a number from 1 to 100. Using a while loop, if they entered an invalid number, tell them the number entered is invalid and then prompt them again for a number from 1 to 100. If they enter a valid number - thank them for their input.
x = int(input("please enter a number 1-100, inclusive: "))
y = x<0 or x>100
while y is True:
print("invalid.")
int(input("please enter a number 1-100, inclusive: ")
else:
print("thank you for your input")
my code is incorrect. Help me fix it please?
Aren't you missing a parenthesis in the statement before else: ? Looks like it says else: is invalid due to that.
Besides the syntax error (missing ) before the line of else, your code also have logical error, you need to set the y = False when user give proper input to get out from the while loop, like :
x = int(input("please enter a number 1-100, inclusive: "))
y = x<0 or x>100
while y is True:
print("invalid.")
value = int(input("please enter a number 1-100, inclusive: "))
if value >= 0 and value <= 100:
y = False
else:
print("thank you for your input")
Simplification and correction of your code
while True:
x = int(input("please enter a number 1-100, inclusive: "))
if 1 <= x <= 100: # range check
print("thank you for your input")
break # terminates while loop
else:
print("invalid.") # print then continue in while loop
#Krish says a really good answer about how you are missing a second bracket during the line that you prompt inside the while loop. I assume you receive a SyntaxError about it (probably listing the immediately following line--unfortunately common in software).
Solution
However, you have a much more fundamental issue with your code: you never update y so you have an infinite loop that will always think that the input is invalid.
x = int(input("please enter a number 1-100, inclusive: "))
y = x<0 or x>100
while y: # it is unnecessary to check a boolean against a condition
print("invalid.")
x = int(input("please enter a number 1-100, inclusive: ")) # missing bracket
y = x<0 or x>100 # necessary to end the loop
else:
print("thank you for your input")
Improvement
Another option is to use break to exit the loop on the spot. It can make for cleaner code with less duplication because now everything is inside the loop.
while True: # infinite loop...but not because of break
x = int(input("please enter a number 1-100, inclusive: "))
if x<0 or x>100:
print("invalid.")
else:
print("thank you for your input")
break
Advanced
For completeness I will also include a couple more advanced features. You can skip this part since you are starting out, but it may be interesting to come back to once you have become more familiar with the language.
Lambda
Helps make the code cleaner.
user_input = lambda: int(input("please enter a number 1-100, inclusive: "))
condition = lambda x: x<0 or x>100
while condition(user_input()):
print("invalid.")
else:
print("thank you for your input")
Cmd
This one is really advanced and overkill for what you are trying to accomplish. Still, it is good to know about for a later, more advanced problem that it would be appropriate for. Docs found here.
from cmd import Cmd
class ValidNumberPrompter(Cmd):
"""
This is a class for a CLI to prompt users for a valid number.
"""
prompt = "please enter a number 1-100, inclusive: "
def parseline(self, line): # normally would override precmd but this is modifying the way the line is parsed for commands later
command, args, line = super().parseline(line) # superclass behaviour
return (command, args, int(line))
def default(self, line): # don't care about commands
if line<0 or line>100:
print("invalid.")
return False
else:
print("thank you for your input")
return True
"""
Only start if module is being run at the cmdline.
If it is being imported, let the caller decide
what to do and when to run it.
"""
if __name__ = '__main__':
ValidNumberPrompter().cmdloop()

none type, don't know how to get rid of it

I'm having a problem with some coding that I'm doing for a school assignment, the same thing happened and I managed to fix it but I did so without knowing how I did it.
def number():
num = input("please enter the number of people that would like play:")
try:
if int(num) >= 2:
if int(num) <=7:
return num
else:
print("number must be 7 or less")
number()
else:
print("number must be greater than 2")
number()
except:
print("that is not a valid number. number must be between 2 and 7")
number()
number = number()
print(number,"people are playing")
This is the code which is causing the problem. If I enter an invalid number it works fine, I can just re-enter a new number, but as you can see I have wanted to print out the "number of people playing" but it returns with "none people are playing" but this is only after I have entered an invalid number. What can I do?
In the ideal case, without any errors, number() returns the entered num and all is well. However, in all other cases, you end the function with a recursive call to number() without actually returning anything. So the function implicitly returns None (i.e. nothing).
Just change every recursive call to return number() and it should work.
Btw. you should avoid recursion for this; see this answer on how to best ask the user repeatedly for valid input.
You need to use a loop rather than calling your routine again which will not have the effect you are looking for (look into recursion). Something like the following approach would be better:
def number():
while True:
num = input("please enter the number of people that would like play: ")
try:
num = int(num)
if num > 7:
print("number must be 7 or less")
elif num <= 2:
print("number must be greater than 2")
else:
return num
except:
print("that is not a valid number. number must be between 2 and 7")
number = number()
print(number, "people are playing")
The reason you are seeing None is that it is possible to reach the bottom of your function without a return being used. In this case Python defaults the returned value to None.

Categories

Resources