Skip to content

Commit c27b2a3

Browse files
committed
tweak the correction of explang
1 parent 2675f22 commit c27b2a3

File tree

2 files changed

+58
-19
lines changed

2 files changed

+58
-19
lines changed

notebooks/tps/explang/.teacher/explangv1.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,36 @@
1111
from operator import neg, add, sub, mul, truediv
1212

1313

14-
class Atom:
14+
class Expression:
15+
"""
16+
the root of all expression classes
17+
useful for type checking - search for isinstance below
18+
that is its only purpose though
19+
"""
20+
pass
21+
22+
23+
24+
class Atom(Expression):
1525
"""
1626
a class to implement an atomic value,
1727
like an int, a float, a str, ...
1828
1929
in order to be able to use this,
20-
child classes need to provide self.type
21-
that should be a class like int or float
30+
child classes need to provide self.implementation_type
31+
that should be a Python class - like typically int or float
2232
or similar whose constructor expects one arg
2333
"""
2434
def __init__(self, value):
25-
self.value = self.type(value)
35+
# convert the argument into the specific class implementation type
36+
self.value = self.implementation_type(value)
2637

2738
def eval(self):
2839
return self.value
2940

3041

3142

32-
class Unary:
43+
class Unary(Expression):
3344
"""
3445
the mother of all unary operators
3546
@@ -38,6 +49,9 @@ class Unary:
3849
which is expected to be a 1-parameter function
3950
"""
4051
def __init__(self, operand):
52+
classname = self.__class__.__name__
53+
if not isinstance(operand, Expression):
54+
raise TypeError(f"passing a non-Expression object in {classname} is not supported")
4155
self.operand = operand
4256

4357
def eval(self):
@@ -56,7 +70,7 @@ def eval(self):
5670
# we can factor true binary (minus and divide) with n-ary (plus and mult)
5771
# if we're a little careful about how we do the evaluation
5872

59-
class MultiAry:
73+
class MultiAry(Expression):
6074
"""
6175
the mother of all binary or n-ary operators
6276
@@ -73,6 +87,9 @@ def __init__(self, *children):
7387
classname = self.__class__.__name__
7488
if not self.arg_checker(nargs):
7589
raise TypeError(f"passing {nargs} arguments in {classname} is not supported")
90+
for child in children:
91+
if not isinstance(child, Expression):
92+
raise TypeError(f"passing a non-Expression object in {classname} is not supported")
7693
self.children = children
7794

7895
def eval(self):
@@ -104,10 +121,10 @@ class Nary(MultiAry):
104121
# and with all that in place the code for adding new operators becomes
105122

106123
class Integer(Atom):
107-
type = int
124+
implementation_type = int
108125

109126
class Float(Atom):
110-
type = float
127+
implementation_type = float
111128

112129

113130
class Negative(Unary):

notebooks/tps/explang/.teacher/explangv2.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,41 @@
1111
from operator import neg, add, sub, mul, truediv
1212

1313

14-
class Atom:
14+
class Expression:
15+
"""
16+
the root of all expression classes
17+
useful for type checking - search for isinstance below
18+
19+
in this second version we take advantage of this class to factorize
20+
this type-checking oriented snippet
21+
"""
22+
23+
def check_is_expression(self, expression):
24+
classname = self.__class__.__name__
25+
if not isinstance(expression, Expression):
26+
raise TypeError(f"passing a non-Expression object in {classname} is not supported")
27+
28+
29+
class Atom(Expression):
1530
"""
1631
a class to implement an atomic value,
1732
like an int, a float, a str, ...
1833
1934
in order to be able to use this,
20-
child classes need to provide self.type
21-
that should be a class like int or float
35+
child classes need to provide self.implementation_type
36+
that should be a Python class - like typically int or float
2237
or similar whose constructor expects one arg
2338
"""
2439
def __init__(self, value):
25-
self.value = self.type(value)
40+
# convert the argument into the specific class implementation type
41+
self.value = self.implementation_type(value)
2642

2743
def eval(self, env):
2844
return self.value
2945

3046

3147

32-
class Unary:
48+
class Unary(Expression):
3349
"""
3450
the mother of all unary operators
3551
@@ -38,6 +54,7 @@ class Unary:
3854
which is expected to be a 1-parameter function
3955
"""
4056
def __init__(self, operand):
57+
self.check_is_expression(operand)
4158
self.operand = operand
4259

4360
def eval(self, env):
@@ -56,7 +73,7 @@ def eval(self, env):
5673
# we can factor true binary (minus and divide) with n-ary (plus and mult)
5774
# if we're a little careful about how we do the evaluation
5875

59-
class MultiAry:
76+
class MultiAry(Expression):
6077
"""
6178
the mother of all binary or n-ary operators
6279
@@ -73,6 +90,8 @@ def __init__(self, *children):
7390
classname = self.__class__.__name__
7491
if not self.arg_checker(nargs):
7592
raise TypeError(f"passing {nargs} arguments in {classname} is not supported")
93+
for child in children:
94+
self.check_is_expression(child)
7695
self.children = children
7796

7897
def eval(self, env):
@@ -104,10 +123,10 @@ class Nary(MultiAry):
104123
# and with all that in place the code for adding new operators becomes
105124

106125
class Integer(Atom):
107-
type = int
126+
implementation_type = int
108127

109128
class Float(Atom):
110-
type = float
129+
implementation_type = float
111130

112131

113132
class Negative(Unary):
@@ -142,7 +161,7 @@ class Divide(Binary):
142161

143162
# and the new guys
144163

145-
class Variable:
164+
class Variable(Expression):
146165
def __init__(self, name):
147166
self.name = name
148167

@@ -153,10 +172,12 @@ def eval(self, env):
153172
return env[self.name]
154173

155174

156-
class Expressions:
175+
class Expressions(Expression):
157176
# make sure there is at least one expression
158177
def __init__(self, mandatory, *others):
159178
self.children = (mandatory, *others)
179+
for child in self.children:
180+
self.check_is_expression(child)
160181

161182
def eval(self, env):
162183
"""
@@ -167,10 +188,11 @@ def eval(self, env):
167188
return result
168189

169190

170-
class Assignment:
191+
class Assignment(Expression):
171192
def __init__(self, name, expr):
172193
self.name = name
173194
self.expr = expr
195+
self.check_is_expression(expr)
174196

175197
def eval(self, env):
176198
"""

0 commit comments

Comments
 (0)