Skip to content

Commit 5ac9449

Browse files
committed
initial
1 parent f9e473d commit 5ac9449

File tree

5 files changed

+302
-0
lines changed

5 files changed

+302
-0
lines changed

00-start.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from math import pi
2+
3+
4+
class Point:
5+
def __init__(self, x, y):
6+
self.x = x
7+
self.y = y
8+
9+
def move_by(self, dx, dy):
10+
self.x += dx
11+
self.y += dy
12+
13+
def __str__(self):
14+
return f'A Point at {self.x}, {self.y}'
15+
16+
def __repr__(self):
17+
return f'{self.__class__.__name__}({self.x}, {self.y})'
18+
19+
20+
class Circle:
21+
def __init__(self, center, radius):
22+
self.center = center
23+
self.radius = radius
24+
25+
@property
26+
def area(self):
27+
return pi * self.radius ** 2
28+
29+
def __str__(self):
30+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
31+
f'radius {self.radius}'
32+
33+
def __repr__(self):
34+
return f'{self.__class__.__name__}({self.center!r}, {self.radius!r})'
35+
36+
37+
# What about this?
38+
# p = Point('1', '2')
39+
# p.move_by('10, '20')

01-properties.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from math import pi
2+
3+
4+
class Point:
5+
def __init__(self, x, y):
6+
self.x = x
7+
self.y = y
8+
9+
@property
10+
def x(self):
11+
return self._x
12+
13+
@x.setter
14+
def x(self, value):
15+
assert isinstance(value, int), 'Booooo! Expecting an int'
16+
self._x = value
17+
18+
@property
19+
def y(self):
20+
return self._y
21+
22+
@y.setter
23+
def y(self, value):
24+
assert isinstance(value, int), 'Booooo! Expecting an int'
25+
self._y = value
26+
27+
def move_by(self, dx, dy):
28+
self.x += dx
29+
self.y += dy
30+
31+
def __str__(self):
32+
return f'A Point at {self.x}, {self.y}'
33+
34+
def __repr__(self):
35+
return f'{self.__class__.__name__}({self.x}, {self.y})'
36+
37+
38+
class Circle:
39+
def __init__(self, center, radius):
40+
self.center = center
41+
self.radius = radius
42+
43+
@property
44+
def center(self):
45+
return self._center
46+
47+
@center.setter
48+
def center(self, value):
49+
assert isinstance(value, Point), 'Booooo! Expecting a Point'
50+
self._center = value
51+
52+
@property
53+
def radius(self):
54+
return self._radius
55+
56+
@radius.setter
57+
def radius(self, value):
58+
assert isinstance(value, int), 'Booooo! Expecting an int'
59+
self._radius = value
60+
61+
@property
62+
def area(self):
63+
return pi * self.radius ** 2
64+
65+
def __str__(self):
66+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
67+
f'radius {self.radius}'
68+
69+
def __repr__(self):
70+
return f'{self.__class__.__name__}({self.center!r}, {self.radius!r})'
71+
72+
73+
# Lots of code!
74+
# Tedious to modify

02-property_macro.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from math import pi
2+
3+
4+
def check_type(name, required_type):
5+
variable_name = f'_{name}'
6+
7+
@property
8+
def variable(self):
9+
return getattr(self, variable_name)
10+
11+
@variable.setter
12+
def variable(self, value):
13+
assert isinstance(value, required_type), \
14+
f'Booooo! Expecting a {required_type.__name__}'
15+
setattr(self, variable_name, value)
16+
return variable
17+
18+
19+
class Point:
20+
x = check_type('x', int)
21+
y = check_type('y', int)
22+
23+
def __init__(self, x, y):
24+
self.x = x
25+
self.y = y
26+
27+
def move_by(self, dx, dy):
28+
self.x += dx
29+
self.y += dy
30+
31+
def __str__(self):
32+
return f'A Point at {self.x}, {self.y}'
33+
34+
def __repr__(self):
35+
return f'{self.__class__.__name__}({self.x}, {self.y})'
36+
37+
38+
class Circle:
39+
center = check_type('center', Point)
40+
radius = check_type('radius', int)
41+
42+
def __init__(self, center, radius):
43+
self.center = center
44+
self.radius = radius
45+
46+
@property
47+
def area(self):
48+
return pi * self.radius ** 2
49+
50+
def __str__(self):
51+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
52+
f'radius {self.radius}'
53+
54+
def __repr__(self):
55+
return f'{self.__class__.__name__}({self.center!r}, {self.radius!r})'
56+
57+
58+
# Fewer lines of code!
59+
# Mind-bending?

03-property_macro_redux.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from math import pi
2+
3+
4+
def check_type(name, required_type):
5+
variable_name = f'_{name}'
6+
7+
@property
8+
def variable(self):
9+
return getattr(self, variable_name)
10+
11+
@variable.setter
12+
def variable(self, value):
13+
assert isinstance(value, required_type), \
14+
f'Booooo! Expecting a {required_type.__name__}'
15+
setattr(self, variable_name, value)
16+
return variable
17+
18+
19+
ensure_int = lambda name: check_type(name, int) # noqa
20+
ensure_point = lambda name: check_type(name, Point) # noqa
21+
22+
23+
class Point:
24+
x = ensure_int('x')
25+
y = ensure_int('y')
26+
27+
def __init__(self, x, y):
28+
self.x = x
29+
self.y = y
30+
31+
def move_by(self, dx, dy):
32+
self.x += dx
33+
self.y += dy
34+
35+
def __str__(self):
36+
return f'A Point at {self.x}, {self.y}'
37+
38+
def __repr__(self):
39+
return f'{self.__class__.__name__}({self.x}, {self.y})'
40+
41+
42+
class Circle:
43+
center = ensure_point('center')
44+
radius = ensure_int('radius')
45+
46+
def __init__(self, center, radius):
47+
self.center = center
48+
self.radius = radius
49+
50+
@property
51+
def area(self):
52+
return pi * self.radius ** 2
53+
54+
def __str__(self):
55+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
56+
f'radius {self.radius}'
57+
58+
def __repr__(self):
59+
return f'{self.__class__.__name__}({self.center!r}, {self.radius!r})'
60+
61+
62+
# Fewer lines of code!
63+
# Mind-bending?

04-descriptors.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from math import pi
2+
3+
4+
class TypeChecker:
5+
required_type = object
6+
7+
def __init__(self, name):
8+
self.name = name
9+
10+
def __get__(self, instance, owner=None):
11+
return instance.__dict__[self.name]
12+
13+
def __set__(self, instance, value):
14+
assert isinstance(value, self.required_type), \
15+
f'Booooo! Expecting a {self.required_type.__name__}'
16+
instance.__dict__[self.name] = value
17+
18+
19+
class IntType(TypeChecker):
20+
required_type = int
21+
22+
23+
class Point:
24+
x = IntType('x')
25+
y = IntType('y')
26+
27+
def __init__(self, x, y):
28+
self.x = x
29+
self.y = y
30+
31+
def move_by(self, dx, dy):
32+
self.x += dx
33+
self.y += dy
34+
35+
def __str__(self):
36+
return f'A Point at {self.x}, {self.y}'
37+
38+
def __repr__(self):
39+
return f'{self.__class__.__name__}({self.x}, {self.y})'
40+
41+
42+
class PointType(TypeChecker):
43+
required_type = Point
44+
45+
46+
class Circle:
47+
center = PointType('center')
48+
radius = IntType('radius')
49+
50+
def __init__(self, center, radius):
51+
self.center = center
52+
self.radius = radius
53+
54+
@property
55+
def area(self):
56+
return pi * self.radius ** 2
57+
58+
def __str__(self):
59+
return f'A Circle at {self.center.x}, {self.center.y} and ' + \
60+
f'radius {self.radius}'
61+
62+
def __repr__(self):
63+
return f'{self.__class__.__name__}({self.center!r}, {self.radius!r})'
64+
65+
66+
# Fewer lines of code!
67+
# Mind-bending?

0 commit comments

Comments
 (0)