Skip to content

Commit 1d2666b

Browse files
committed
differences for PR #56
1 parent e510e17 commit 1d2666b

File tree

2 files changed

+42
-62
lines changed

2 files changed

+42
-62
lines changed

05-defensive_programming.md

Lines changed: 41 additions & 61 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,18 +130,13 @@ 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)
139134
except TypeError as err:
140135
print('Val is not a number')
141136
print('But our code does not crash anymore')
142137
print('The run-time error is:', err)
143138
else:
144-
print('1/val = ', 1/val)
139+
print('The value provided to the check_sign function did not result in a TypeError')
145140
finally:
146141
print('release memory')
147142
del(val)
@@ -219,12 +214,7 @@ val = 'a'
219214

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

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.')
217+
check_sign(val)
228218
```
229219

230220
```output
@@ -252,12 +242,7 @@ val = np.nan
252242

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

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.')
245+
check_sign(val)
261246
```
262247

263248
```output
@@ -281,12 +266,7 @@ val = np.nan
281266
assert type(val) is float or type(val) is int, "Variable has to be a numerical object"
282267
assert not np.isnan(val), "Variable must not be a NaN"
283268

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.')
269+
check_sign(val)
290270
```
291271

292272
```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" "b938e0d6ea1e317eb234e6279532e2eb" "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)