Using try after except is not working on Python
Question:
I’m doing exercise 4 on CS50P "outdated" and after trying to make the code work with if/else statements I came across a solution that used try/except for dealing with cases instead of if/else. In the following code I don’t understand why the second except gets executed and thus, renders the second part of the code useless.
months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
]
while True:
msg = input("Date: ")
try:
msg = msg.split("/")
msg[0] = int(msg[0])
msg[1] = int(msg[1])
msg[2] = int(msg[2])
if 0 < msg[0] < 13 and 0 < msg[1] < 32 and 0 < msg[2]:
MM = f"{msg[0]:02}"
DD = f"{msg[1]:02}"
YY = f"{msg[2]:02}"
break
except:
try:
msg = msg.split(" ")
msg[0] = int(months.index(msg[0])+1)
msg[1] = msg[1].replace(",","")
msg[1] = int(msg[1])
msg[2] = int(msg[2])
if 0 < msg[0] < 13 and 0 < msg[1] < 32 and 0 < msg[2]:
MM = f"{msg[0]:02}"
DD = f"{msg[1]:02}"
YY = f"{msg[2]:02}"
break
except:
print()
pass
print(YY,MM,DD, sep="-")
When I try to execute the msg.split(" ") part first, it does work and then the following part doesn’t work. Right now I have only been able to execute the first part (the code before the except). I would like to know where is the error since the terminal does not show any.
Answers:
Rather than a linear approach to this problem you should write two discrete functions for handling the two possible input date formats.
The allowed formats are:
MM/DD/YYYY
MM DD, YYYY
In the second format MM is a month full name – e.g., September
Use the datetime module to try to construct a datetime object from the user input. Anything invalid in the user input will cause an exception to be raised during construction of the datetime object.
from calendar import month_name
from datetime import datetime
# Possibly MM/DD/YYYY format
def type_1(s):
if len(parts := s.split('/')) == 3:
mm, dd, yyyy = map(int, parts)
return datetime(yyyy, mm, dd)
# Possibly MM DD, YYYY where MM is months fullname - e.g., September
def type_2(s):
if len(parts := s.replace(',', '').split()) == 3:
mm = [*month_name].index(parts[0])
dd, yyyy = map(int, parts[1:])
return datetime(yyyy, mm, dd)
while user_date := input('Enter a date: '):
for func in type_1, type_2:
try:
if d := func(user_date):
print(datetime.strftime(d, '%Y-%m-%d'))
break
except Exception:
pass
else:
print('Invalid date')
I’m doing exercise 4 on CS50P "outdated" and after trying to make the code work with if/else statements I came across a solution that used try/except for dealing with cases instead of if/else. In the following code I don’t understand why the second except gets executed and thus, renders the second part of the code useless.
months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
]
while True:
msg = input("Date: ")
try:
msg = msg.split("/")
msg[0] = int(msg[0])
msg[1] = int(msg[1])
msg[2] = int(msg[2])
if 0 < msg[0] < 13 and 0 < msg[1] < 32 and 0 < msg[2]:
MM = f"{msg[0]:02}"
DD = f"{msg[1]:02}"
YY = f"{msg[2]:02}"
break
except:
try:
msg = msg.split(" ")
msg[0] = int(months.index(msg[0])+1)
msg[1] = msg[1].replace(",","")
msg[1] = int(msg[1])
msg[2] = int(msg[2])
if 0 < msg[0] < 13 and 0 < msg[1] < 32 and 0 < msg[2]:
MM = f"{msg[0]:02}"
DD = f"{msg[1]:02}"
YY = f"{msg[2]:02}"
break
except:
print()
pass
print(YY,MM,DD, sep="-")
When I try to execute the msg.split(" ") part first, it does work and then the following part doesn’t work. Right now I have only been able to execute the first part (the code before the except). I would like to know where is the error since the terminal does not show any.
Rather than a linear approach to this problem you should write two discrete functions for handling the two possible input date formats.
The allowed formats are:
MM/DD/YYYY
MM DD, YYYY
In the second format MM is a month full name – e.g., September
Use the datetime module to try to construct a datetime object from the user input. Anything invalid in the user input will cause an exception to be raised during construction of the datetime object.
from calendar import month_name
from datetime import datetime
# Possibly MM/DD/YYYY format
def type_1(s):
if len(parts := s.split('/')) == 3:
mm, dd, yyyy = map(int, parts)
return datetime(yyyy, mm, dd)
# Possibly MM DD, YYYY where MM is months fullname - e.g., September
def type_2(s):
if len(parts := s.replace(',', '').split()) == 3:
mm = [*month_name].index(parts[0])
dd, yyyy = map(int, parts[1:])
return datetime(yyyy, mm, dd)
while user_date := input('Enter a date: '):
for func in type_1, type_2:
try:
if d := func(user_date):
print(datetime.strftime(d, '%Y-%m-%d'))
break
except Exception:
pass
else:
print('Invalid date')