-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathfs_python_exceptions.Rmd
More file actions
126 lines (104 loc) · 4.47 KB
/
fs_python_exceptions.Rmd
File metadata and controls
126 lines (104 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
---
title: "Python Raise, Try and Catch Exceptions"
titleshort: "Python Raise, Try and Catch Exceptions"
description: |
Raise an Exception in a python function, try and catch and print to string.
Trace full exception stack.
core:
- package: python
code: |
raise
try except
ValueError
TypeError
- package: traceback
code: |
print_exc()
date: 2020-11-04
date_start: 2020-12-28
output:
pdf_document:
pandoc_args: '../../_output_kniti_pdf.yaml'
includes:
in_header: '../../preamble.tex'
html_document:
pandoc_args: '../../_output_kniti_html.yaml'
includes:
in_header: "../../hdga.html"
always_allow_html: true
urlcolor: blue
---
### Exception Handling
```{r global_options, include = FALSE}
try(source("../../.Rprofile"))
```
`r text_shared_preamble_one`
`r text_shared_preamble_two`
`r text_shared_preamble_thr`
```{python}
```
#### A function That Raises an Error with Try Statement Catching it
Below, we have a function that will raise a *TypeError* unless we provide an integer input. The function is called with integer input and then called with a string input. The string input is wrapped in a try and except call, where the exception catches the TypeError and prints it.
```{python}
# define the function
def ffi_error_test(gn_speckey=None):
if isinstance(gn_speckey, int):
print(f'{gn_speckey=} is an integer')
else:
raise TypeError(f'{gn_speckey=} is not an integer')
# Call function with integer
error_test(1)
# Call function with string
try:
ffi_error_test('abc')
except TypeError as error:
print('Caught this error: ' + repr(error))
```
#### Catch an Exception Noisily
Rather than only catching the last element of the exception, show the full trace. Notice in the example below, the second element of the loop does not work as function input. With exception catching, the loop continued despite the second element not working. The traceback shows more details at the end with full trace of the exception from the second element of the list as input for ffi_error_test().
```{python}
import traceback
import numpy as np
ls_ob_inputs = [2, ['abc','efg'], 1, 123]
for ob_input in ls_ob_inputs:
print(f'try input {ob_input=} with the error_test function:')
try:
ffi_error_test(ob_input)
except TypeError as error:
traceback.print_exc()
print('Caught this error: ' + repr(error))
```
see [How to print the stack trace of an exception object in Python?](https://stackoverflow.com/q/52742612/8280804)
#### Handle Parameters When Conditions Not Satisfied
There is a function, that can estimate or simulate, under both functionalities, there is a common string parameter, that requires specifying estimation or simulation conditions. The common string parameter should be a simple string without special separators in the case of simulation, and should be four strings concatenated together with equal sign for estimation. Generate an exception if the function is called for estimation but the string parameter does not have the required structure.
- [Python 3 TypeError](https://docs.python.org/3/library/exceptions.html#TypeError)
- [Manually raising (throwing) an exception in Python](https://stackoverflow.com/a/30317038/8280804)
```{python, include=TRUE, eval = FALSE, echo = TRUE}
# ls_st_spec_key_dict = ['NG_S_D', 'NG_S_D=KAP_M0_NLD_M_SIMU=2=3']
# st_connector = '='
# ls_st_esti_simu = ['esti', 'simu']
# for st_spec_key_dict in ls_st_spec_key_dict:
# for st_esti_simu in ls_st_esti_simu:
# if st_esti_simu == 'simu':
# if len(st_spec_key_dict.split(st_connector)) and
# print('simulate with ' + st_spec_key_dict)
if estimate and not isinstance(spec_key_dict, str):
pass
elif (estimate is False and isinstance(spec_key_dict, str)) or (estimate is False and isinstance(spec_key_dict, dict)):
pass
else:
st_error = 'speckey=' + speckey + ' and estimate=' + str(estimate)
raise ValueError(st_error)
```
#### Proceed Despite Error
Sometimes, code should proceed despite error, to finish a loop for example:
```{python, include=TRUE, eval = FALSE, echo = TRUE}
# estimate at each initial random points
for it_esti_ctr in range(esti_param_vec_count):
# Update the 3rd element of combo_type, which determines which draw index to use
combo_type[3] = it_esti_ctr
try:
invoke_run_main.invoke_main(combo_type, **dc_invoke_main_args)
except Exception:
logging.critical(f'Finished this {it_esti_ctr=} of {range(esti_param_vec_count)=}')
```