forked from huangsam/ultimate-python
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexception_class.py
More file actions
Latest commit
79 lines (59 loc) · 2.76 KB
/
Copy pathexception_class.py
File metadata and controls
79 lines (59 loc) · 2.76 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
"""
Exception classes are used to indicate that something has gone wrong with
the program at runtime. Functions use the `raise` keyword, if an error is
anticipated, and specify the exception class they intend to throw. This
module defines a handful of custom exception classes and shows how they
can be used in the context of a function.
"""
classCustomError(Exception):
"""Custom class of errors.
This is a custom exception for any issues that arise in this module.
One of the reasons why developers design a class like this is for
consumption by downstream services and command-line tools.
If we designed a standalone application with no downstream consumers, then
it makes little sense to define a custom hierarchy of exceptions. In that
case, we should use the existing hierarchy of builtin exception
classes which are listed in the Python docs:
https://docs.python.org/3/library/exceptions.html
"""
classDivisionError(CustomError):
"""Any division error that results from invalid input.
This exception can be subclassed with the following exceptions if they
happen enough across the codebase:
- ZeroDivisorError
- NegativeDividendError
- NegativeDivisorError
That being said, there's a point of diminishing returns when we design
too many exceptions. It is better to design few exceptions that many
developers handle than design many exceptions that few developers handle.
"""
defdivide_positive_numbers(dividend: int, divisor: int) ->int:
"""Divide a positive number by another positive number.
Writing a program in this style is considered defensive programming.
For more on this programming style, check the Wikipedia link below:
https://en.wikipedia.org/wiki/Defensive_programming
"""
ifdividend<=0:
raiseDivisionError(f"Non-positive dividend: {dividend}")
elifdivisor<=0:
raiseDivisionError(f"Non-positive divisor: {divisor}")
returndividend//divisor
defmain() ->None:
# Exception classes are no different from concrete classes in that
# they all have inheritance baked in
assertissubclass(DivisionError, CustomError)
# Try a couple of inputs that are known to throw an error based on
# the exceptions thrown in `divide_positive_numbers`
fordividend, divisorin [(0, 1), (1, 0), (-1, 1), (1, -1)]:
division_failed=False
try:
divide_positive_numbers(dividend, divisor)
exceptDivisionErrorase:
division_failed=True
assertstr(e).startswith("Non-positive")
assertdivision_failedisTrue
# Now let's do it correctly to skip all the exceptions
result=divide_positive_numbers(1, 1)
assertresult==1
if__name__=="__main__":
main()