Skip to content

Commit d563ca8

Browse files
author
kiarashplusplus
committed
lab0
1 parent 30a5d81 commit d563ca8

11 files changed

+981
-0
lines changed

lab0/algebra.py

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Section 3: Algebraic simplification
2+
3+
# This code implements a simple computer algebra system, which takes in an
4+
# expression made of nested sums and products, and simplifies it into a
5+
# single sum of products. The goal is described in more detail in the
6+
# problem set writeup.
7+
8+
# Much of this code is already implemented. We provide you with a
9+
# representation for sums and products, and a top-level simplify() function
10+
# which applies the associative law in obvious cases. For example, it
11+
# turns both (a + (b + c)) and ((a + b) + c) into the simpler expression
12+
# (a + b + c).
13+
14+
# However, the code has a gap in it: it cannot simplify expressions that are
15+
# multiplied together. In interesting cases of this, you will need to apply
16+
# the distributive law.
17+
18+
# Your goal is to fill in the do_multiply() function so that multiplication
19+
# can be simplified as intended.
20+
21+
# Testing will be mathematical: If you return a flat list that
22+
# evaluates to the same value as the original expression, you will
23+
# get full credit.
24+
25+
26+
# We've already defined the data structures that you'll use to symbolically
27+
# represent these expressions, as two classes called Sum and Product,
28+
# defined below. These classes both descend from the abstract Expression class.
29+
#
30+
# The top level function that will be called is the .simplify() method of an
31+
# Expression.
32+
#
33+
# >>> expr = Sum([1, Sum([2, 3])])
34+
# >>> expr.simplify()
35+
# Sum([1, 2, 3])
36+
37+
38+
### Expression classes _____________________________________________________
39+
40+
# Expressions will be represented as "Sum()" and "Product()" objects.
41+
# These objects can be treated just like lists (they inherit from the
42+
# "list" class), but you can test for their type using the "isinstance()"
43+
# function. For example:
44+
#
45+
# >>> isinstance(Sum([1,2,3]), Sum)
46+
# True
47+
# >>> isinstance(Product([1,2,3]), Product)
48+
# True
49+
# >>> isinstance(Sum([1,2,3]), Expression) # Sums and Products are both Expressions
50+
# True
51+
52+
class Expression:
53+
"This abstract class does nothing on its own."
54+
pass
55+
56+
class Sum(list, Expression):
57+
"""
58+
A Sum acts just like a list in almost all regards, except that this code
59+
can tell it is a Sum using isinstance(), and we add useful methods
60+
such as simplify().
61+
62+
Because of this:
63+
* You can index into a sum like a list, as in term = sum[0].
64+
* You can iterate over a sum with "for term in sum:".
65+
* You can convert a sum to an ordinary list with the list() constructor:
66+
the_list = list(the_sum)
67+
* You can convert an ordinary list to a sum with the Sum() constructor:
68+
the_sum = Sum(the_list)
69+
"""
70+
def __repr__(self):
71+
return "Sum(%s)" % list.__repr__(self)
72+
73+
def simplify(self):
74+
"""
75+
This is the starting point for the task you need to perform. It
76+
removes unnecessary nesting and applies the associative law.
77+
"""
78+
terms = self.flatten()
79+
if len(terms) == 1:
80+
return simplify_if_possible(terms[0])
81+
else:
82+
return Sum([simplify_if_possible(term) for term in terms]).flatten()
83+
84+
def flatten(self):
85+
"""Simplifies nested sums."""
86+
terms = []
87+
for term in self:
88+
if isinstance(term, Sum):
89+
terms += list(term)
90+
else:
91+
terms.append(term)
92+
return Sum(terms)
93+
94+
95+
class Product(list, Expression):
96+
"""
97+
See the documentation above for Sum. A Product acts almost exactly
98+
like a list, and can be converted to and from a list when necessary.
99+
"""
100+
def __repr__(self):
101+
return "Product(%s)" % list.__repr__(self)
102+
103+
def simplify(self):
104+
"""
105+
To simplify a product, we need to multiply all its factors together
106+
while taking things like the distributive law into account. This
107+
method calls multiply() repeatedly, leading to the code you will
108+
need to write.
109+
"""
110+
factors = []
111+
for factor in self:
112+
if isinstance(factor, Product):
113+
factors += list(factor)
114+
else:
115+
factors.append(factor)
116+
result = Product([1])
117+
for factor in factors:
118+
result = multiply(result, simplify_if_possible(factor))
119+
return result.flatten()
120+
121+
def flatten(self):
122+
"""Simplifies nested products."""
123+
factors = []
124+
for factor in self:
125+
if isinstance(factor, Product):
126+
factors += list(factor)
127+
else:
128+
factors.append(factor)
129+
return Product(factors)
130+
131+
def simplify_if_possible(expr):
132+
"""
133+
A helper function that guards against trying to simplify a non-Expression.
134+
"""
135+
if isinstance(expr, Expression):
136+
return expr.simplify()
137+
else:
138+
return expr
139+
140+
# You may find the following helper functions to be useful.
141+
# "multiply" is provided for you; but you will need to write "do_multiply"
142+
# if you would like to use it.
143+
144+
def multiply(expr1, expr2):
145+
"""
146+
This function makes sure that its arguments are represented as either a
147+
Sum or a Product, and then passes the hard work onto do_multiply.
148+
"""
149+
# Simple expressions that are not sums or products can be handled
150+
# in exactly the same way as products -- they just have one thing in them.
151+
if not isinstance(expr1, Expression): expr1 = Product([expr1])
152+
if not isinstance(expr2, Expression): expr2 = Product([expr2])
153+
return do_multiply(expr1, expr2)
154+
155+
156+
def do_multiply(expr1, expr2):
157+
"""
158+
You have two Expressions, and you need to make a simplified expression
159+
representing their product. They are guaranteed to be of type Expression
160+
-- that is, either Sums or Products -- by the multiply() function that
161+
calls this one.
162+
163+
So, you have four cases to deal with:
164+
* expr1 is a Sum, and expr2 is a Sum
165+
* expr1 is a Sum, and expr2 is a Product
166+
* expr1 is a Product, and expr2 is a Sum
167+
* expr1 is a Product, and expr2 is a Product
168+
169+
You need to create Sums or Products that represent what you get by
170+
applying the algebraic rules of multiplication to these expressions,
171+
and simplifying.
172+
173+
Look above for details on the Sum and Product classes. The Python operator
174+
'*' will not help you.
175+
"""
176+
177+
if isinstance(expr1, Sum) and isinstance(expr2, Sum):
178+
sm = []
179+
for term1 in expr1:
180+
for term2 in expr2:
181+
prd = []
182+
prd.append(term1)
183+
prd.append(term2)
184+
sum_list.append(Product(prd))
185+
elif isinstance(expr1, Product) and isinstance(expr2, Sum):
186+
sm = []
187+
for term2 in expr2:
188+
prd = [term2]
189+
prd.extend(list(expr1))
190+
sm.append(Product(prd))
191+
return Sum(sm)
192+
elif isinstance(expr1, Sum) and isinstance(expr2, Product):
193+
sm = []
194+
for term1 in expr1:
195+
prd = [term1]
196+
prd.extend(list(expr2))
197+
sm.append(Product(prd))
198+
return Sum(sm)
199+
else:
200+
prd = list(expr1)
201+
prd.extend(list(expr2))
202+
return Product(prd)

lab0/algebra.pyc

5.64 KB
Binary file not shown.

lab0/algebra_utils.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""
2+
These are functions for transferring algebra.py's test cases over the
3+
Internet. You shouldn't need to mess with these.
4+
"""
5+
from algebra import simplify_if_possible, Sum, Product, Expression
6+
7+
def distribution(val):
8+
if isinstance(val, Expression):
9+
raise ValueError("expression has already been decoded")
10+
return encode_sumprod(simplify_if_possible(decode_sumprod(val)))
11+
12+
def encode_sumprod(lst):
13+
retVal = []
14+
15+
if isinstance(lst, Sum):
16+
retVal.append('Sum')
17+
elif isinstance(lst, Product):
18+
retVal.append('Product')
19+
20+
for elt in lst:
21+
if isinstance(elt, (Sum, Product)):
22+
retVal.append( encode_sumprod(elt) )
23+
else:
24+
retVal.append(elt)
25+
26+
return retVal
27+
28+
29+
def decode_sumprod(lst):
30+
retVal = []
31+
32+
for elt in lst[1:]:
33+
if isinstance(elt, (list, tuple)):
34+
retVal.append(decode_sumprod(elt))
35+
else:
36+
retVal.append(elt)
37+
38+
if lst[0] == 'Sum':
39+
retVal = Sum(retVal)
40+
elif lst[0] == 'Product':
41+
retVal = Product(retVal)
42+
else:
43+
raise Exception, "Error: List was not an encoded Sum or Product!"
44+
45+
return retVal
46+
47+

lab0/algebra_utils.pyc

1.58 KB
Binary file not shown.

lab0/key.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Login information for the 6.034 Automated Tester
2+
3+
USERNAME="kiarash_MIT_EDU"
4+
PASSWORD="ShcD6yxK4cs4a6UUz4he"
5+
XMLRPC_URL="https://6.034.scripts.mit.edu:444/fall12/tester/xmlrpc/"
6+

lab0/key.pyc

306 Bytes
Binary file not shown.

lab0/lab0.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# This is the file you'll use to submit most of Lab 0.
2+
3+
# Certain problems may ask you to modify other files to accomplish a certain
4+
# task. There are also various other files that make the problem set work, and
5+
# generally you will _not_ be expected to modify or even understand this code.
6+
# Don't get bogged down with unnecessary work.
7+
8+
9+
# Section 1: Problem set logistics ___________________________________________
10+
11+
# This is a multiple choice question. You answer by replacing
12+
# the symbol 'fill-me-in' with a number, corresponding to your answer.
13+
14+
# You get to check multiple choice answers using the tester before you
15+
# submit them! So there's no reason to worry about getting them wrong.
16+
# Often, multiple-choice questions will be intended to make sure you have the
17+
# right ideas going into the problem set. Run the tester right after you
18+
# answer them, so that you can make sure you have the right answers.
19+
20+
# What version of Python do we *recommend* (not "require") for this course?
21+
# 1. Python v2.3
22+
# 2. Python v2.5 or Python v2.6
23+
# 3. Python v3.0
24+
# Fill in your answer in the next line of code ("1", "2", or "3"):
25+
26+
ANSWER_1 = '2'
27+
28+
29+
# Section 2: Programming warmup _____________________________________________
30+
31+
# Problem 2.1: Warm-Up Stretch
32+
33+
def cube(x):
34+
return x*x*x
35+
36+
def factorial(x):
37+
if (x is 0 or x is 1):
38+
return 1
39+
return factorial(x-1)*x
40+
41+
def count_pattern(pattern, lst):
42+
tuples=[]
43+
for i in xrange(0, len(lst)-len(pattern)+1):
44+
tuples.append(tuple(lst[i:i+len(pattern)]))
45+
46+
return tuples.count(tuple(pattern))
47+
48+
# Problem 2.2: Expression depth
49+
50+
def depth(expr, d=0):
51+
if not isinstance(expr,(list,tuple)):
52+
return d
53+
return max(depth(expr[1]),depth(expr[2])) + 1
54+
55+
56+
# Problem 2.3: Tree indexing
57+
58+
def tree_ref(tree, index):
59+
if len(index) is 1:
60+
return tree[index[0]]
61+
val = index[0]
62+
index.pop(0)
63+
return tree_ref(tree[val], index)
64+
65+
66+
# Section 3: Symbolic algebra
67+
68+
# Your solution to this problem doesn't go in this file.
69+
# Instead, you need to modify 'algebra.py' to complete the distributer.
70+
71+
from algebra import Sum, Product, simplify_if_possible
72+
from algebra_utils import distribution, encode_sumprod, decode_sumprod
73+
74+
# Section 4: Survey _________________________________________________________
75+
76+
# Please answer these questions inside the double quotes.
77+
78+
# When did you take 6.01?
79+
WHEN_DID_YOU_TAKE_601 = "SP 11"
80+
81+
# How many hours did you spend per 6.01 lab?
82+
HOURS_PER_601_LAB = "4"
83+
84+
# How well did you learn 6.01?
85+
HOW_WELL_I_LEARNED_601 = "good. I was LA for that."
86+
87+
# How many hours did this lab take?
88+
HOURS = "3"

lab0/lab0.pyc

1.82 KB
Binary file not shown.

0 commit comments

Comments
 (0)