99
1010
1111class Element (object ):
12- def evaluate (self , verbose = False ):
12+ verbose = True
13+
14+ def evaluate (self ):
1315 """Evaluate the current object - a no-op by default"""
1416 return self
1517
1618 def evaluate_object (self , obj , cls = None ):
17- """Evaluates Elements , and optionally coerces objects to a class"""
19+ """Evaluates elements , and coerces objects to a class if needed """
1820 if isinstance (obj , Element ):
19- obj = obj .evaluate ()
21+ obj = obj .evaluate_cached ()
2022 if cls is not None :
2123 obj = cls (obj )
2224 return obj
2325
24- def print_evaluation (self , result ):
25- """Prints an explanation of an evaluation"""
26- print ("Evaluating:" , str (self ), "->" , str (result ))
26+ def evaluate_cached (self , verbose = None ):
27+ """Wraps evaluate(), caching results"""
28+ if not hasattr (self , 'result' ):
29+ self .result = self .evaluate ()
30+ if self .verbose :
31+ print ("Evaluating:" , str (self ), "->" , str (self .result ))
32+ return self .result
2733
2834
2935class Integer (int , Element ):
3036 """A wrapper around the int class"""
3137
38+ verbose = False
39+
3240 @classmethod
3341 def parse (cls , string , location , tokens ):
3442 return cls (tokens [0 ])
@@ -50,7 +58,7 @@ def __repr__(self):
5058 classname (self ), str (self ), self .sides )
5159
5260 def __str__ (self ):
53- return ', ' .join (map (str , self ))
61+ return '[' + ' , ' .join (map (str , self )) + ']'
5462
5563 def __int__ (self ):
5664 return sum (self )
@@ -79,28 +87,17 @@ def from_string(cls, string):
7987 def __init__ (self , amount , sides ):
8088 self .amount = amount
8189 self .sides = sides
82- self .result = None
8390
8491 def __repr__ (self ):
8592 return "Dice({0!r}, {1!r})" .format (self .amount , self .sides )
8693
8794 def __str__ (self ):
8895 return "{0!s}d{1!s}" .format (self .amount , self .sides )
8996
90- def evaluate (self , verbose = False ):
97+ def evaluate (self ):
9198 self .amount = self .evaluate_object (self .amount , Integer )
9299 self .sides = self .evaluate_object (self .sides , Integer )
93-
94- if self .result is None :
95- self .result = Roll (self .amount , self .sides )
96-
97- if verbose :
98- self .print_evaluation (self .result )
99-
100- return self .result
101-
102- def roll (self ):
103- return self .evaluate (verbose = False )
100+ return Roll (self .amount , self .sides )
104101
105102
106103class Operator (Element ):
@@ -114,42 +111,37 @@ def __init__(self, operands):
114111 def __repr__ (self ):
115112 return "{0}({1})" .format (
116113 classname (self ),
117- ', ' .join (map (repr , self .operands )))
114+ ', ' .join (map (str , self .operands )))
118115
119116 def evaluate (self ):
120- raise NotImplementedError (
121- "Operator subclass has no evaluate()" )
122-
123- def evaluate_operands (self ):
124117 self .operands = map (self .evaluate_object , self .operands )
125- return self .operands
126-
118+ return self .function (* self .operands )
127119
128- class FunctionOperator (Operator ):
129120 @property
130121 def function (self ):
131- raise NotImplementedError (
132- "FunctionOperator subclass has no function" )
122+ raise NotImplementedError ("Operator subclass has no function" )
123+
133124
134- def evaluate (self , verbose = False ):
135- return self .function (* self .evaluate_operands ())
125+ class IntegerOperator (Operator ):
126+ def evaluate_object (self , obj ):
127+ return super (IntegerOperator , self ).evaluate_object (obj , Integer )
136128
137129
138- class Div (FunctionOperator ):
130+ class Div (IntegerOperator ):
139131 function = operator .floordiv
140132
141133
142- class Mul (FunctionOperator ):
134+ class Mul (IntegerOperator ):
143135 function = operator .mul
144136
145137
146- class Sub (FunctionOperator ):
138+ class Sub (IntegerOperator ):
147139 function = operator .sub
148140
149141
150- class Add (FunctionOperator ):
142+ class Add (IntegerOperator ):
151143 function = operator .add
152144
153145
154- class Total (FunctionOperator ):
146+ class Total (Operator ):
155147 function = sum
0 commit comments