Skip to content

Commit c8f007d

Browse files
committed
markdown source builds
Auto-generated via `{sandpaper}` Source : 312e3c3 Branch : main Author : scottan <33283688+Scottan@users.noreply.github.com> Time : 2026-04-13 12:47:22 +0000 Message : Merge pull request #56 from UoMResearchIT/21-make-errors-example-into-a-function 21 make errors example into a function
1 parent 7d1e0c2 commit c8f007d

File tree

2 files changed

+46
-64
lines changed

2 files changed

+46
-64
lines changed

05-defensive_programming.md

Lines changed: 45 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ More importantly, applications are not expected to crash and we are going to lea
3030

3131
Please look at the following code. Can you find the fundamental problem in this test?
3232

33-
```bash
33+
```python
3434
val = 1
3535

36-
if val>0 and val<10:
37-
print('Value: ', val, 'is a digit.')
38-
elif val==0:
39-
print('Value ', val, 'is nul')
36+
if val > 0:
37+
print('Value:', val, 'is positive.')
38+
elif val == 0:
39+
print('Value:', val, 'is zero.')
4040
else:
41-
print('Value: ', val, 'is a number.')
41+
print('Value:', val, 'is negative.')
4242
```
4343

4444
::::::::::::::: solution
@@ -47,26 +47,26 @@ else:
4747

4848
The test assumes that `val` is a number, and throws an uncontrolled error if it is not.
4949

50-
```bash
50+
```python
5151
val = 'a'
5252

53-
if val>0 and val<10:
54-
print('Value: ', val, 'is a digit.')
55-
elif val==0:
56-
print('Value ', val, 'is nul')
53+
if val > 0:
54+
print('Value:', val, 'is positive.')
55+
elif val == 0:
56+
print('Value:', val, 'is zero.')
5757
else:
58-
print('Value: ', val, 'is a number.')
58+
print('Value:', val, 'is negative.')
5959
```
6060

6161
```output
6262
---------------------------------------------------------------------------
6363
TypeError Traceback (most recent call last)
6464
<ipython-input-2-99c0e25bf5e9> in <module>()
65-
1 val = 'a'
66-
2
67-
----> 3 if val>0 and val<10:
68-
4 print('Value: ', val, 'is a digit.')
69-
5 elif val==0:
65+
1 def check_sign(val):
66+
----> 2 if val > 0:
67+
3 print('Value:', val, 'is positive.')
68+
4 elif val == 0:
69+
5 print('Value:', val, 'is zero.')
7070
7171
TypeError: '>' not supported between instances of 'str' and 'int'
7272
```
@@ -75,16 +75,24 @@ TypeError: '>' not supported between instances of 'str' and 'int'
7575

7676
::::::::::::::::::::::::::::::::::::::::::::::::::
7777

78-
We can avoid problems like this by wrapping our code in an `if` statement:
78+
We can avoid problems like this by wrapping our code in an `if` statement.
79+
To make things simpler, we will first write the test as a function:
7980

8081
```python
81-
if type(val) is int or type(val) is float:
82-
if val>0 and val<10:
83-
print('Value: ', val, 'is a digit.')
84-
elif val==0:
85-
print('Value ', val, 'is nul')
82+
def check_sign(val):
83+
if val > 0:
84+
print('Value:', val, 'is positive.')
85+
elif val == 0:
86+
print('Value:', val, 'is zero.')
8687
else:
87-
print('Value: ', val, 'is a number.')
88+
print('Value:', val, 'is negative.')
89+
```
90+
91+
Then wrap the function call in an `if` statement:
92+
93+
```python
94+
if type(val) is int or type(val) is float:
95+
check_sign(val)
8896
else:
8997
print('val is not a number')
9098
```
@@ -95,29 +103,21 @@ Python provides the `try-except` structure to avoid this issue, enabling develop
95103

96104
```python
97105
try:
98-
if val>0 and val<10:
99-
print('Value: ', val, 'is a digit.')
100-
elif val==0:
101-
print('Value ', val, 'is nul')
102-
else:
103-
print('Value: ', val, 'is a number.')
106+
check_sign(val)
104107
except:
105108
print('Val is not a number')
106109
print('Enter a new number')
107110
```
108111

109112
At the top of the statement is the code that we are interested in executing, which is run in the `try` statement. If that fails then the `except` statement comes into effect, (hopefully) returning helpful information to the user about what happened and giving them some guidance on how to avoid the problem in future.
110113

114+
Using `try-except` statements results in clearer, easier to understand code by following the common Python coding style of [EAFP](https://docs.python.org/3.6/glossary.html#term-eafp) (it's easier to ask for forgiveness than permission). This style shows the code we want to execute first, assuming that the incoming data is correct, before dealing with exceptions if the assumptions prove false.
115+
111116
The `except` statement will catch all errors and so we do not, initially at least, need to know exactly what errors we are trying to avoid. However, python does provide error codes, which we can use to expand the structure to capture specific error types. For the example above, we would want to capture a `TypeError`:
112117

113118
```python
114119
try:
115-
if val>0 and val<10:
116-
print('Value: ', val, 'is a digit.')
117-
elif val==0:
118-
print('Value ', val, 'is nul')
119-
else:
120-
print('Value: ', val, 'is a number.')
120+
check_sign(val)
121121
except TypeError as err:
122122
print('Val is not a number')
123123
print('But our code does not crash anymore')
@@ -130,21 +130,18 @@ As with `if` statements, multiple `except` statements can be used, each with a d
130130

131131
```python
132132
try:
133-
if val>0 and val<10:
134-
print('Value: ', val, 'is a digit.')
135-
elif val==0:
136-
print('Value ', val, 'is nul')
137-
else:
138-
print('Value: ', val, 'is a number.')
133+
check_sign(val)
134+
reciprocal = 1/val
139135
except TypeError as err:
140136
print('Val is not a number')
141-
print('But our code does not crash anymore')
137+
print('The run-time error is:', err)
138+
except Exception as err:
139+
print('Some error other than a TypeError occured')
142140
print('The run-time error is:', err)
143141
else:
144-
print('1/val = ', 1/val)
142+
print('The reciprocal of the value =', reciprocal)
145143
finally:
146144
print('release memory')
147-
del(val)
148145
```
149146

150147
The typical use of the `finally` statement is to deal with the release of external resources (such as files or network connections) whether or not the attempted action has been successful.
@@ -219,12 +216,7 @@ val = 'a'
219216

220217
assert type(val) is float or type(val) is int, "Variable has to be a numerical object"
221218

222-
if val>0 and val<10:
223-
print('Value: ', val, 'is a digit.')
224-
elif val==0:
225-
print('Value ', val, 'is nul')
226-
else:
227-
print('Value: ', val, 'is a number.')
219+
check_sign(val)
228220
```
229221

230222
```output
@@ -252,12 +244,7 @@ val = np.nan
252244

253245
assert type(val) is float or type(val) is int, "Variable has to be a numerical object"
254246

255-
if val>0 and val<10:
256-
print('Value: ', val, 'is a digit.')
257-
elif val==0:
258-
print('Value ', val, 'is nul')
259-
else:
260-
print('Value: ', val, 'is a number.')
247+
check_sign(val)
261248
```
262249

263250
```output
@@ -281,12 +268,7 @@ val = np.nan
281268
assert type(val) is float or type(val) is int, "Variable has to be a numerical object"
282269
assert not np.isnan(val), "Variable must not be a NaN"
283270

284-
if val>0 and val<10:
285-
print('Value: ', val, 'is a digit.')
286-
elif val==0:
287-
print('Value ', val, 'is nul')
288-
else:
289-
print('Value: ', val, 'is a number.')
271+
check_sign(val)
290272
```
291273

292274
```output

md5sum.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"episodes/02-dictionaries.md" "a3e25c74d90bef8f93c72bf320ba0a1b" "site/built/02-dictionaries.md" "2026-04-13"
99
"episodes/03-numpy_essential.md" "8be0e5afb556d4f597f31f059488dd15" "site/built/03-numpy_essential.md" "2025-04-15"
1010
"episodes/04-software_package_management.md" "62db2ba2a4291e16d2bdd07b77bfc961" "site/built/04-software_package_management.md" "2025-04-15"
11-
"episodes/05-defensive_programming.md" "357bca7361e09066ad71393e21ad0c74" "site/built/05-defensive_programming.md" "2025-04-15"
11+
"episodes/05-defensive_programming.md" "6d48a7e584a970aacdad58a28b0b9570" "site/built/05-defensive_programming.md" "2026-04-13"
1212
"episodes/06-units_and_quantities.md" "7e259f66d6f8889505c252a04082481f" "site/built/06-units_and_quantities.md" "2026-04-13"
1313
"episodes/07-pandas_essential.md" "443db701e191bb47de503d890d31d69f" "site/built/07-pandas_essential.md" "2026-04-13"
1414
"instructors/instructor-notes.md" "a59fd3b94c07c3fe3218c054a0f03277" "site/built/instructor-notes.md" "2025-04-15"

0 commit comments

Comments
 (0)