Skip to content

Commit 934d0f1

Browse files
committed
update
1 parent a847370 commit 934d0f1

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

Diff for: Reference Notes/classmethod and staticmethod.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
'''
2+
Circuitous, LLC -
3+
An Advanced Circle Analytics Company
4+
Summary: Toolset for New-Style Classes
5+
1. Inherit from object().
6+
2. Instance variables for information unique to an instance.
7+
3. Class variables for data shared among all instances.
8+
4. Regular methods need "self" to operate on instance data.
9+
5. Class methods implement alternative constructors. They need "cls"
10+
so they can create subclass instances as well.
11+
6. Static methods attach functions to class. They don't need
12+
either "self" or "cls".
13+
Static methods improve discoverability and require context to be specified.
14+
7. A property() lets getter and setter methods be invoked automatically by
15+
attribute access. This allows Python classes to freely expose their
16+
instance variables.
17+
8. The "__slots__" variable implements the Flyweight Design Pattern by
18+
suppressing instance dictionaries
19+
9. The __method() is a class local reference, making sure the method refers
20+
to this class's method, not its childrens'.
21+
10. Thread local calls use the double underscore. Gives subclasses the
22+
freedom to override methods without breaking other methods.
23+
'''
24+
25+
import math
26+
27+
class Circle(object): # new-style class
28+
'An advanced circle analytics toolkit'
29+
30+
# flyweight design pattern suppresses the instance dictionary
31+
__slots__ = ['diameter']
32+
version = '0.7' # class variable
33+
34+
def __init__(self, radius):
35+
# init is not a constructor. It's job is to initialize the instance variables
36+
self.radius = radius # instance variables
37+
38+
@property # convert dotted access to method calls
39+
def radius(self):
40+
return self.diameter / 2.0
41+
42+
@radius.setter
43+
def radius(self, radius):
44+
'Radius of a circle'
45+
self.diameter = radius * 2.0
46+
47+
def area(self): # regular methods have 'self' as first argument
48+
# Given that the perimeter method is modified and used in a subclass, we use the double under to create a class local reference to ensure modified perimeter from subclass is not used
49+
p = self.__perimeter()
50+
r = p / math.pi / 2.0
51+
return math.pi * r** 2.0
52+
53+
def perimeter(self):
54+
return 2.0 * math.pi * self.radius
55+
56+
@classmethod # Alternative constructor
57+
def from_bbd(cls, bbd): # use `cls` petermeter to support subclassing
58+
'Construct a circle from a bounding box diagonal'
59+
radius = bbd / 2.0 / math.sqrt(2.0)
60+
return cls(radius) # return `cls(radius)` instead of `Circle(radius)` so subclasses are not suppressed
61+
62+
@staticmethod # Attach functions to classes - works without instantiating the class
63+
def angle_to_grade(angle):
64+
# A standard method would require creating a new instance just to call a function which needs no 'self' variables or any information about the instance of a `Circle`
65+
# Adding this function inside the Circle class improves discoverability and ensures the function is used in the appropriate context
66+
'Convert angle in degree to a percentage grade'
67+
return math.tan(math.radians(angle)) * 100.0 # variables used here do not require information about the instance
68+
69+
__perimeter = perimeter # Class local reference
70+
71+
72+
class Tire(Circle):
73+
'Tires are circles with an odometer corrected perimeter'
74+
75+
def perimeter(self):
76+
'Circumference corrected for the rubber'
77+
return Circle.perimeter(self) * 1.25
78+
79+
if __name__ == "__main__":
80+
std = Circle(2)
81+
print('Radius of the Circle:', std.radius)
82+
print('Area of the Circle:', std.area())
83+
print('Perimeter of the Circle:', std.perimeter())
84+
85+
print()
86+
new = Circle.from_bbd(25)
87+
print('Radius of the Circle:', new.radius)
88+
print('Area of the Circle:', new.area())
89+
print('Perimeter of the Circle:', new.perimeter())
90+
91+
print()
92+
t = Tire.from_bbd(25)
93+
print('Radius of the Circle:', t.radius)
94+
print('Area of the Circle:', t.area())
95+
print('Perimeter of the Circle:', t.perimeter()) # This does not work if `classmethod` returns the class instance rather than `cls`
96+
97+
print()
98+
t = Tire(15)
99+
print('Radius of the Circle:', t.radius)
100+
print('Area of the Circle:', t.area())
101+
print('Perimeter of the Circle:', t.perimeter())
102+
103+
print()
104+
grade = Circle.angle_to_grade(30)
105+
print('Angle:', 30)
106+
print('Grade:', grade)
107+
print('Type:', type(grade))

Diff for: 1 - Advanced Course in Programming Notes/classmethod and staticmethod.py renamed to Reference Notes/classmethods and staticmethods-2.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@ def some_function(c, d):
5656
return c + d
5757

5858
test = CustomClass.some_function(3,5)
59-
print(type(test)) # test is not an instance of CustomClass. It is only a reference to the return value from the staticmethod
59+
print(type(test)) # test is not an instance of CustomClass. It is only a reference to the return value from the staticmethod

0 commit comments

Comments
 (0)