Python: Compound Try/Except Blocks
Question:
I am working on a random word picker (used in the command line). The word picker itself works perfectly (I have a text file that has a bunch of words separated by spaces. The program will take the text file and make a list, the entries being everything in the list split with spaces).
The next step I want to take is to be able to programmatically add words to the text file. I was able to get it to add whatever the user gives from input, but now I want to make sure that the word provided from the user doesn’t have spaces, numbers, or uppercase letters.
The first attempt I took looked like this:
def add_word():
word_to_add = input("Word to add: ")
valid_word = False
if any(char.isdigit() for char in word_to_add):
valid_word = False
elif any(char.isupper() for char in word_to_add):
valid word = False
elif any((" " in chars) for chars in word_to_add):
valid word = False
else:
valid word = True
I know this is a super inefficient method to use. That said, I’m trying to use Try/Except blocks to clean it up a little bit. I think I have an idea of how they work. Since I’m trying to test against multiple conditions, it would be something like
try:
# code for no numbers
try:
# code for no uppercases
try:
# code for no spaces
except:
# blah blah blah
else:
# blah blah blah
Now, the dilemma I’m facing is how do I route each try:
to a specific exception? What I mean is if there is an exception with the numbers, it would print something like "your word cannot contain numbers! Try again." and the same deal for spaces and uppercases. Is there a way for me to make something like this:
try:
# if there's a number go to exception A
try:
# if there's an uppercase go to exception B
try:
# if there's a space go to exception C
exception a:
# blah blah blah
exception b:
# blah blah blah
exception c:
# blah blah blah
else:
# blah blah blah
Would it end up being more efficient to just have multiple try/except blocks or a "compound" version like the above code?
The reason I don’t want to use if/elif/else is because sometimes it will still add the user input to the word list even if valid_word
was false.
Sorry that I can’t be more specific here, I just don’t really know how to articulate what I’m trying to accomplish here. Thanks in advance for any help
Answers:
You can raise
an exception inside a try
block to immediately jump to a matching except
, e.g.:
def add_word():
while True:
word_to_add = input("Word to add: ")
try:
if any(char.isdigit() for char in word_to_add):
raise ValueError("Your word cannot contain numbers!")
if any(char.isupper() for char in word_to_add):
raise ValueError("Your word cannot contain capitals!")
if " " in word_to_add:
raise ValueError("Your word cannot contain spaces!")
except ValueError as err:
print(err)
print("Try again")
else:
break
# now do whatever you need to do to add word_to_add
But you could just as easily structure this as an if/elif
block where each error condition is an elif
and you break
the loop in the else
:
def add_word():
while True:
word_to_add = input("Word to add: ")
if any(char.isdigit() for char in word_to_add):
print("Your word cannot contain numbers!")
elif any(char.isupper() for char in word_to_add):
print("Your word cannot contain capitals!")
elif " " in word_to_add:
print("Your word cannot contain spaces!")
else:
break
print("Try again!")
# now do whatever you need to do to add word_to_add
-
You can only have one try
. But it can have multiple except
s. You cannot stack multiple tries. You can legally try
s inside each other just like you nest if
statements or for
loops. But there isn’t much reason to do this in a single function since you can stack multiple except
s on a single try
.
-
The code in the except
will only be called when some code raise
s an error in the try
. This most commonly happens when you call a function which then raises an error. But you can also manually raise
in the try
.
I am working on a random word picker (used in the command line). The word picker itself works perfectly (I have a text file that has a bunch of words separated by spaces. The program will take the text file and make a list, the entries being everything in the list split with spaces).
The next step I want to take is to be able to programmatically add words to the text file. I was able to get it to add whatever the user gives from input, but now I want to make sure that the word provided from the user doesn’t have spaces, numbers, or uppercase letters.
The first attempt I took looked like this:
def add_word():
word_to_add = input("Word to add: ")
valid_word = False
if any(char.isdigit() for char in word_to_add):
valid_word = False
elif any(char.isupper() for char in word_to_add):
valid word = False
elif any((" " in chars) for chars in word_to_add):
valid word = False
else:
valid word = True
I know this is a super inefficient method to use. That said, I’m trying to use Try/Except blocks to clean it up a little bit. I think I have an idea of how they work. Since I’m trying to test against multiple conditions, it would be something like
try:
# code for no numbers
try:
# code for no uppercases
try:
# code for no spaces
except:
# blah blah blah
else:
# blah blah blah
Now, the dilemma I’m facing is how do I route each try:
to a specific exception? What I mean is if there is an exception with the numbers, it would print something like "your word cannot contain numbers! Try again." and the same deal for spaces and uppercases. Is there a way for me to make something like this:
try:
# if there's a number go to exception A
try:
# if there's an uppercase go to exception B
try:
# if there's a space go to exception C
exception a:
# blah blah blah
exception b:
# blah blah blah
exception c:
# blah blah blah
else:
# blah blah blah
Would it end up being more efficient to just have multiple try/except blocks or a "compound" version like the above code?
The reason I don’t want to use if/elif/else is because sometimes it will still add the user input to the word list even if valid_word
was false.
Sorry that I can’t be more specific here, I just don’t really know how to articulate what I’m trying to accomplish here. Thanks in advance for any help
You can raise
an exception inside a try
block to immediately jump to a matching except
, e.g.:
def add_word():
while True:
word_to_add = input("Word to add: ")
try:
if any(char.isdigit() for char in word_to_add):
raise ValueError("Your word cannot contain numbers!")
if any(char.isupper() for char in word_to_add):
raise ValueError("Your word cannot contain capitals!")
if " " in word_to_add:
raise ValueError("Your word cannot contain spaces!")
except ValueError as err:
print(err)
print("Try again")
else:
break
# now do whatever you need to do to add word_to_add
But you could just as easily structure this as an if/elif
block where each error condition is an elif
and you break
the loop in the else
:
def add_word():
while True:
word_to_add = input("Word to add: ")
if any(char.isdigit() for char in word_to_add):
print("Your word cannot contain numbers!")
elif any(char.isupper() for char in word_to_add):
print("Your word cannot contain capitals!")
elif " " in word_to_add:
print("Your word cannot contain spaces!")
else:
break
print("Try again!")
# now do whatever you need to do to add word_to_add
-
You can only have one
try
. But it can have multipleexcept
s. You cannot stack multiple tries. You can legallytry
s inside each other just like you nestif
statements orfor
loops. But there isn’t much reason to do this in a single function since you can stack multipleexcept
s on a singletry
. -
The code in the
except
will only be called when some coderaise
s an error in thetry
. This most commonly happens when you call a function which then raises an error. But you can also manuallyraise
in thetry
.