Skip to content

Commit 32c12d8

Browse files
committed
ch07
1 parent b6eb3ef commit 32c12d8

File tree

11 files changed

+301
-0
lines changed

11 files changed

+301
-0
lines changed

ch07/context/decimal.prec.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# context/decimal.prec.py
2+
from decimal import Context, Decimal, getcontext, setcontext
3+
4+
one = Decimal("1")
5+
three = Decimal("3")
6+
7+
orig_ctx = getcontext()
8+
ctx = Context(prec=5)
9+
setcontext(ctx)
10+
print(ctx)
11+
print(one / three)
12+
setcontext(orig_ctx)
13+
print(one / three)
14+
15+
16+
"""
17+
$ python context/decimal.prec.py
18+
Context(prec=5, rounding=ROUND_HALF_EVEN, Emin=-999999,
19+
Emax=999999, capitals=1, clamp=0, flags=[],
20+
traps=[InvalidOperation, DivisionByZero, Overflow])
21+
0.33333
22+
0.3333333333333333333333333333
23+
"""
24+
25+
26+
orig_ctx = getcontext()
27+
ctx = Context(prec=5)
28+
setcontext(ctx)
29+
try:
30+
print(ctx)
31+
print(one / three)
32+
finally:
33+
setcontext(orig_ctx)
34+
print(one / three)
35+
36+
37+
from decimal import localcontext
38+
39+
with localcontext(Context(prec=5)) as ctx:
40+
print(ctx)
41+
print(one / three)
42+
print(one / three)
43+
44+
45+
with localcontext(Context(prec=5)), open("out.txt", "w") as out_f:
46+
out_f.write(f"{one} / {three} = {one / three}\n")

ch07/context/generator.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# context/generator.py
2+
from contextlib import contextmanager
3+
4+
@contextmanager
5+
def my_context_manager():
6+
print("Entering 'with' context")
7+
val = object()
8+
print(id(val))
9+
try:
10+
yield val
11+
except Exception as e:
12+
print(f"{type(e)=} {e=} {e.__traceback__=}")
13+
finally:
14+
print("Exiting 'with' context")
15+
16+
17+
print("About to enter 'with' context")
18+
with my_context_manager() as val:
19+
print("Inside 'with' context")
20+
print(id(val))
21+
raise Exception("Exception inside 'with' context")
22+
print("This line will never be reached")
23+
24+
print("After 'with' context")
25+
26+
27+
"""
28+
$ python context/generator.py
29+
About to enter 'with' context
30+
Entering 'with' context
31+
139768531985040
32+
Inside 'with' context
33+
139768531985040
34+
type(e)=<class 'Exception'> e=Exception("Exception inside 'with'
35+
context") e.__traceback__=<traceback object at 0x7f1e65a42800>
36+
Exiting 'with' context
37+
After 'with' context
38+
"""

ch07/context/manager.class.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# context/manager.class.py
2+
class MyContextManager:
3+
def __init__(self):
4+
print("MyContextManager init", id(self))
5+
6+
def __enter__(self):
7+
print("Entering 'with' context")
8+
return self
9+
10+
def __exit__(self, exc_type, exc_val, exc_tb):
11+
print(f"{exc_type=} {exc_val=} {exc_tb=}")
12+
print("Exiting 'with' context")
13+
return True
14+
15+
16+
ctx_mgr = MyContextManager()
17+
18+
print("About to enter 'with' context")
19+
20+
with ctx_mgr as mgr:
21+
print("Inside 'with' context")
22+
print(id(mgr))
23+
raise Exception("Exception inside 'with' context")
24+
print("This line will never be reached")
25+
26+
print("After 'with' context")
27+
28+
29+
"""
30+
$ python context/manager.class.py
31+
MyContextManager init 140340228792272
32+
About to enter 'with' context
33+
Entering 'with' context
34+
Inside 'with' context
35+
140340228792272
36+
exc_type=<class 'Exception'> exc_val=Exception("Exception inside
37+
'with' context") exc_tb=<traceback object at 0x7fa3817c5340>
38+
Exiting 'with' context
39+
After 'with' context
40+
"""

ch07/exceptions/first.example.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# exceptions/first.example.py
2+
# This is not a valid Python module - Don't run it.
3+
# a few examples of exceptions
4+
5+
>>> gen = (n for n in range(2))
6+
>>> next(gen)
7+
0
8+
>>> next(gen)
9+
1
10+
>>> next(gen)
11+
Traceback (most recent call last):
12+
File "<stdin>", line 1, in <module>
13+
StopIteration
14+
>>> print(undefined_name)
15+
Traceback (most recent call last):
16+
File "<stdin>", line 1, in <module>
17+
NameError: name 'undefined_name' is not defined
18+
>>> mylist = [1, 2, 3]
19+
>>> mylist[5]
20+
Traceback (most recent call last):
21+
File "<stdin>", line 1, in <module>
22+
IndexError: list index out of range
23+
>>> mydict = {'a': 'A', 'b': 'B'}
24+
>>> mydict['c']
25+
Traceback (most recent call last):
26+
File "<stdin>", line 1, in <module>
27+
KeyError: 'c'
28+
>>> 1 / 0
29+
Traceback (most recent call last):
30+
File "<stdin>", line 1, in <module>
31+
ZeroDivisionError: division by zero

ch07/exceptions/for.loop.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# exceptions/for.loop.py
2+
n = 100
3+
found = False
4+
for a in range(n):
5+
if found: break
6+
for b in range(n):
7+
if found: break
8+
for c in range(n):
9+
if 42 * a + 17 * b + c == 5096:
10+
found = True
11+
print(a, b, c) # 79 99 95
12+
13+
14+
class ExitLoopException(Exception):
15+
pass
16+
17+
try:
18+
n = 100
19+
for a in range(n):
20+
for b in range(n):
21+
for c in range(n):
22+
if 42 * a + 17 * b + c == 5096:
23+
raise ExitLoopException(a, b, c)
24+
except ExitLoopException as ele:
25+
print(ele.args) # (79, 99, 95)

ch07/exceptions/multiple.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# exceptions/multiple.py
2+
values = (1, 2) # try (1, 0) and ('one', 2)
3+
4+
try:
5+
q, r = divmod(*values)
6+
except (ZeroDivisionError, TypeError) as e:
7+
print(type(e), e)
8+
9+
10+
try:
11+
q, r = divmod(*values)
12+
except ZeroDivisionError:
13+
print("You tried to divide by zero!")
14+
except TypeError as e:
15+
print(e)

ch07/exceptions/raising.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# exceptions/raising.py
2+
# This is not a valid Python module - Don't run it.
3+
>>> raise NotImplementedError("I'm afraid I can't do that")
4+
Traceback (most recent call last):
5+
File "<stdin>", line 1, in <module>
6+
NotImplementedError: I'm afraid I can't do that

ch07/exceptions/replace.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# exceptions/replace.py
2+
# This is not a valid Python module - Don't run it.
3+
>>> class NotFoundError(Exception):
4+
... pass
5+
...
6+
>>> vowels = {'a': 1, 'e': 5, 'i': 9, 'o': 15, 'u': 21}
7+
>>> try:
8+
... pos = vowels['y']
9+
... except KeyError as e:
10+
... raise NotFoundError(*e.args)
11+
...
12+
Traceback (most recent call last):
13+
File "<stdin>", line 2, in <module>
14+
KeyError: 'y'
15+
16+
During handling of the above exception, another exception occurred:
17+
18+
Traceback (most recent call last):
19+
File "<stdin>", line 4, in <module>
20+
__main__.NotFoundError: y
21+
>>> try:
22+
... pos = vowels['y']
23+
... except KeyError as e:
24+
... raise NotFoundError(*e.args) from e
25+
...
26+
Traceback (most recent call last):
27+
File "<stdin>", line 2, in <module>
28+
KeyError: 'y'
29+
30+
The above exception was the direct cause of the following exception:
31+
32+
Traceback (most recent call last):
33+
File "<stdin>", line 4, in <module>
34+
__main__.NotFoundError: y

ch07/exceptions/trace.back.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# exceptions/trace.back.py
2+
def squareroot(number):
3+
if number < 0:
4+
raise ValueError("No negative numbers please")
5+
return number ** .5
6+
7+
def quadratic(a, b, c):
8+
d = b ** 2 - 4 * a * c
9+
return ((-b - squareroot(d)) / (2 * a),
10+
(-b + squareroot(d)) / (2 * a))
11+
12+
quadratic(1, 0, 1) # x**2 + 1 == 0
13+
14+
15+
"""
16+
$ python exceptions/trace.back.py
17+
Traceback (most recent call last):
18+
File "exceptions/trace.back.py", line 12, in <module>
19+
quadratic(1, 0, 1) # x**2 + 1 == 0
20+
File "exceptions/trace.back.py", line 9, in quadratic
21+
return ((-b - squareroot(d)) / (2 * a),
22+
File "exceptions/trace.back.py", line 4, in squareroot
23+
raise ValueError("No negative numbers please")
24+
ValueError: No negative numbers please
25+
"""

ch07/exceptions/try.syntax.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# exceptions/try.syntax.py
2+
3+
def try_syntax(numerator, denominator):
4+
try:
5+
print(f'In the try block: {numerator}/{denominator}')
6+
result = numerator / denominator
7+
except ZeroDivisionError as zde:
8+
print(zde)
9+
else:
10+
print('The result is:', result)
11+
return result
12+
finally:
13+
print('Exiting')
14+
15+
print(try_syntax(12, 4))
16+
print(try_syntax(11, 0))
17+
18+
19+
"""
20+
$ python try.syntax.py
21+
In the try block: 12/4 # try
22+
The result is: 3.0 # else
23+
Exiting # finally
24+
3.0 # return within else
25+
26+
In the try block: 11/0 # try
27+
division by zero # except
28+
Exiting # finally
29+
None # implicit return end of function
30+
"""

0 commit comments

Comments
 (0)