library(reticulate) # to use python in RStudio
Errors are common in coding. Exception handling can help our code to 1) keep running despite of any errors and 2) at the same time produce informative alerts to help identify relevant problems. (example here)
We can also leverage exception handling to make our code more fault-tolerate by proactively considering and preparing for various potential issues. (example here)
Exception handling is especially important and commonly used for automated code that runs at the background.
The following code will lead to an error and couldn’t proceed, because the format of the 3rd item in the sales list contains a dollar symbol. However, sometimes we might not want the code to stop completely due to an error like this. Instead, we might want to the code to proceed with all the correct sales values first, and at the same time alert us of the item with problem.
sales = ['400', '350', '$250', '450']
total_sales = 0
for i in sales:
print(i)
total_sales += float(i)
## Error in py_call_impl(callable, dots$args, dots$keywords): ValueError: could not convert string to float: '$250'
##
## Detailed traceback:
## File "<string>", line 3, in <module>
The following code does just that: It proceeds with whatever items that it can process and in the meantime highlights and alerts us of any problematic items: It is easy to identify the problematic 3rd item from the output.
for i in sales:
try:
# code that might lead to errors
total_sales += float(i)
print(f'complete: {i}')
except:
# what to do when error occurs
print(f'____PROBLEM: {i}')
## complete: 400
## complete: 350
## ____PROBLEM: $250
## complete: 450
In the above example, the code skips and alerts us of any errors. But we can also create the process to be more fault-tolerant by proactively considering specific situations where errors could occur and preparing the code to accommodate for these situations.
For example, date.time strings could come in many formats. And we can prepare a versatile function to try and error with multiple formats.
from datetime import datetime
def my_get_dt(dt_str):
'''
convert dt_str to datetime object
return datetime object
'''
try:
#format: 2022-01-31 01:01:01
return datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
except:
pass
try:
#format: 01/31/2022
return datetime.strptime(dt_str, '%m/%d/%Y')
except:
pass
try:
#format: Jan 31, 2022
return datetime.strptime(dt_str, '%b %d, %Y')
except:
pass
try:
#format: 31-01-2022 01:01:01
return datetime.strptime(dt_str, '%d-%m-%Y %H:%M:%S')
except:
pass
try:
#format: 31.01.2022
return datetime.strptime(dt_str, '%d.%m.%Y')
except:
pass
print(f"can't convert {dt_str}") #flag unconvertible strings
return None
Let’s test the above function with various date.time formats.
my_get_dt('2022-06-11 10:20:30')
## datetime.datetime(2022, 6, 11, 10, 20, 30)
my_get_dt('Jun 11, 2022')
## datetime.datetime(2022, 6, 11, 0, 0)
my_get_dt('11.06.2022')
## datetime.datetime(2022, 6, 11, 0, 0)
my_get_dt('11-06-2022 10:20:30')
## datetime.datetime(2022, 6, 11, 10, 20, 30)
my_get_dt('Saturday June 11, 2022') #this format was not incorporated into the function
## can't convert Saturday June 11, 2022