11# -*- coding: utf-8 -*-
2+ import random
3+ import time
24from enum import Enum
35
46
@@ -9,12 +11,19 @@ class Condition(Enum):
911 BAD = 3
1012
1113
14+ class MethodNowAllowed (Exception ):
15+ pass
16+
17+
1218class Bike :
19+ num_wheels = 2
20+ counter = 0
21+
1322 def __init__ (
1423 self ,
15- description : str = "Really Beautiful" ,
16- condition : str = "Perfect Condition" ,
17- sale_price : float = 0 ,
24+ description : str ,
25+ condition : Condition = Condition . GOOD ,
26+ sale_price : float = 100 ,
1827 cost : float = 0 ,
1928 year : int = 2015 ,
2029 ):
@@ -33,24 +42,29 @@ def __init__(
3342 """
3443 self .description = description
3544 self .condition = condition
36- self .sale_price = sale_price
45+ self ._sale_price = None # Private
3746 self .cost = cost
47+ self ._slow_attribute = None
3848
3949 self .age = 2023 - year
4050 self .sold = False
4151 self .premium = None
52+ self .update_sale_price (sale_price )
53+ Bike .counter += 1
4254
4355 def update_sale_price (self , sale_price : float ):
4456 if self .sold :
45- raise AttributeError ("Cannot update sale price of a sold bike." )
57+ raise MethodNowAllowed ("Cannot update sale price of a sold bike." )
4658 if sale_price <= 0 :
4759 raise ValueError ("Sale price must be greater than zero." )
48- self .sale_price = sale_price
60+ self ._sale_price = sale_price
4961
5062 def is_premium (self ):
5163 self .premium = "Yes"
5264
5365 def sell (self ) -> float :
66+ if self .sold :
67+ raise MethodNowAllowed ("Cannot update sale price of a sold bike." )
5468 self .sold = True
5569 profit = self .sale_price - self .cost
5670 print (f"Sold for a profit: { profit } " )
@@ -63,10 +77,69 @@ def service(self, cost, new_sale_price=None, new_condition=None):
6377 if new_condition is not None :
6478 self .condition = new_condition
6579
80+ @property
81+ def sale_price (self ):
82+ return self ._sale_price
83+
84+ @sale_price .setter
85+ def sale_price (self , sale_price : float ):
86+ if self .sold :
87+ raise MethodNowAllowed ("Cannot update sale price of a sold bike." )
88+ if sale_price <= 0 :
89+ raise ValueError ("Sale price must be greater than zero." )
90+ self ._sale_price = sale_price
91+
92+ @property
93+ def profit (self ):
94+ return self .sale_price - self .cost
95+
96+ @property # Used when an attribute is computationally intensive to calculate. Cache version is accessible
97+ def slow_attribute (self ):
98+ if self ._slow_attribute is not None :
99+ print ("Slow Attribute was already cached" )
100+ return self ._slow_attribute
101+ else :
102+ print ("Calculating Slow Attribute" )
103+ time .sleep (5 )
104+ self ._slow_attribute = "Set"
105+ return self ._slow_attribute
106+
66107 @staticmethod
67108 def sing_the_bike_song ():
68109 print ("Singing the Bike Song" )
69110
111+ def __add__ (self , other ):
112+ if isinstance (other , Bike ):
113+ self .cost += other .cost
114+
115+ def __del__ (self ):
116+ Bike .counter -= 1
117+ print ("Bike deleted" )
118+
119+ def __str__ (self ):
120+ """Called when str() or print()"""
121+ return f"{ self .description } : ${ self .sale_price } "
122+
123+ def __repr__ (self ):
124+ return f"Bike({ self .description } , { self .condition } , { self .sale_price } , { self .cost } )"
125+
126+ @staticmethod
127+ def get_test_bike ():
128+ return Bike (condition = Condition .GOOD , sale_price = 1000 , cost = 0 , description = Bike .__name__ )
129+
130+ @classmethod
131+ def get_test_object (cls ):
132+ return cls (
133+ condition = random .choice (list (Condition )),
134+ sale_price = 1000 ,
135+ cost = 0 ,
136+ description = f"{ cls .__name__ } " ,
137+ )
138+
139+
140+ class Unicycle (Bike ):
141+ num_wheels = 1
142+
70143
71144if __name__ == "__main__" :
72145 my_bike = Bike (
@@ -76,10 +149,10 @@ def sing_the_bike_song():
76149 cost = 100 ,
77150 year = 1965 ,
78151 )
79- print ( my_bike )
80- print ( type ( my_bike ) )
81- print (my_bike . condition )
82- my_bike . service ( cost = 100 , new_condition = Condition . OKAY , new_sale_price = 1200 )
83- print (my_bike . condition )
84- my_bike .sell ( )
85- my_bike .sing_the_bike_song ( )
152+ test_unicycle = Unicycle . get_test_object ( )
153+ test_bike = Bike . get_test_bike ( )
154+ print (test_unicycle )
155+ print ( test_bike )
156+ print ([ test_unicycle , test_bike ] )
157+ print ( my_bike .slow_attribute )
158+ print ( my_bike .slow_attribute )
0 commit comments