def test_associate(self): self.assertEqual(Int(12).associate_l_to_r(), Int(12)) self.assertEqual(Int(12).associate_r_to_l(), Int(12)) self.assertEqual(Var("a").associate_l_to_r(), Var("a")) self.assertEqual(Var("a").associate_r_to_l(), Var("a")) self.assertEqual( Plus(Int(1), Int(2)).associate_l_to_r(), Plus(Int(1), Int(2))) self.assertEqual( Times(Int(1), Int(2)).associate_l_to_r(), Times(Int(1), Int(2)))
def test_to_pos_neg(self): self.assertEqual(Int(12).to_pos_neg(), Int(12)) self.assertEqual(Var("a").to_pos_neg(), Int("a")) self.assertEqual(Negative(Int(12).to_pos_neg()), Negative(Int(12))) self.assertEqual( Plus(Int(3), Int(5)).to_pos_neg(), Plus(Int(3), Int(5))) self.assertEqual( Times(Int(3), Int(5)).to_pos_neg(), Times(Int(3), Int(5))) self.assertEqual( Minus(Int(3), Int(5)).to_pos_neg(), Plus(Int(3), Negative(Int(5)))) self.assertEqual( Negative(Minus(Int(3), Int(5))).to_pos_neg(), Negative(Plus(Int(3), Negative(Int(5))))) self.assertEqual( Times(Minus(Int(3), Int(5)), Minus(Int(6), Int(7))).to_pos_neg(), Times(Plus(Int(3), Negative(Int(5))), Plus(Int(6), Negative(Int(7))))) self.assertEqual( Plus(Minus(Int(3), Int(5)), Minus(Int(6), Int(7))).to_pos_neg(), Plus(Plus(Int(3), Negative(Int(5))), Plus(Int(6), Negative(Int(7))))) self.assertEqual( Equals(Minus(Int(3), Int(5)), Minus(Int(6), Int(7))).to_pos_neg(), Equals(Plus(Int(3), Negative(Int(5))), Plus(Int(6), Negative(Int(7)))))
from henri_4_8_21 import questions, documentation from QuestionMachine import QuestionMachine from Expression import Int, Var, Plus, Minus, Times, Equals, Negative qm = QuestionMachine(questions) qm.ask() expr = Plus(Var("n"), Var("n")) qm.check(expr.combine_like_terms(Var("n"))) qm.check(Plus(Int(1), Int(1)).combine_like_terms(Int(1))) expr = Plus(Var("n"), Plus(Var("n"), Var("n"))) qm.check(expr.combine_like_terms(Var("n"))) expr = Plus(Plus(Var("n"), Var("n")), Var("n")) qm.check(expr.combine_like_terms(Var("n"))) qm.check(Plus(Var("a"), Times(Int(4), Var("a"))).combine_like_terms(Var("a"))) expr = Plus(Var("a"), Times(Var("a"), Int(4))) qm.check(expr.sub_comm(Times(Var("a"), Int(4))).combine_like_terms(Var("a"))) expr = Plus(Times(Int(3), Var("a")), Times(Var("a"), Int(4))) qm.check(expr.sub_comm(Times(Var("a"), Int(4))).combine_like_terms(Var("a"))) expr = Plus(Plus(Int(3), Var("a")), Times(Var("a"), Int(4))) qm.check( expr.sub_comm(Times(Var("a"), Int(4))).alr().combine_like_terms(Var("a")))
def check_answer(a0): return lambda a: a == a0 def check_str_no_ws(a0): return lambda a: remove_all_whitespace(a) == remove_all_whitespace(a0) def conv_q(expr1_str, expr2_str, af): return Question( "Convert the expression '{}' to '{}'".format(expr1_str, expr2_str), af) extra_stuff = [ Times(Times(Var("n"), Var("n")), Var("n")), Minus(Int("n"), Int("n")), Plus(Int(11), Minus(Var("n"), Var("n"))), Plus(Plus(Int(3), Int(1)), Var("d")), ] documentation = [ "Expression.to_pos_neg(): Converts an expression that looks like 'a - b' to 'a + -b'", "Expression.pos_neg_to_minus(): Converts an expression that looks like 'a + -b' to 'a - b'", "Expression.associate_l_to_r(): Converts an expression that looks like '(a + b) + c' to 'a + (b + c)'. You can replace '+' with '*'", "Expression.associate_r_to_l(): Converts an expression that looks like 'a + (b + c)' to '(a + b) + c'. You can replace '+' with '*'", ] # I need to teach Henri the associative property at some point, but I won't today. # Actually, I might need to. Teaching it would be simplified if Henri had the option to convert all subtractions to # +-s. Fpr example, (11 + n) - n would become (11 + n) + -n. The associative property can then be used to turn the
from Expression import Int, Plus, Equals, Var, Minus, Times def check_q(i): return lambda a: a == i def check_q_table(expr, pairs): table = dict(pairs) return lambda a: a == table questions = [ Question( "Make a dictionary of 'k * 4' for k = 1, 2, 3, 8, 40, and 70", check_q_table(Times(Var("k"), Int(4)), [[Int(1), Int(4)], [Int(2), Int(8)], [Int(3), Int(12)], [Int(8), Int(32)], [Int(40), Int(160)], [Int(70), Int(280)]])), Question( "Make a dictionary of '(6 * m) - 3' for m = 1, 2, 3, 6, 50, and 100", check_q_table(Minus(Times(Int(6), Var("m")), Int(3)), [[Int(1), Int(3)], [Int(2), Int(9)], [Int(3), Int(15)], [Int(6), Int(33)], [Int(50), Int(297)], [Int(100), Int(597)]])), Question( "Make a dictionary of '21 + (3 * r)' for r = 1, 2, 3, 7, 20, and 50", check_q_table(Plus(Int(21), Times(Int(3), Var("r"))), [[Int(1), Int(24)], [Int(2), Int(27)], [Int(3), Int(30)], [Int(7), Int(42)], [Int(20), Int(81)], [Int(50), Int(171)]])),
return Question("Convert the expression '{}' to '{}'".format(expr1_str, expr2_str), af) documentation = [ "expr.to_pos_neg(): If expr looks like 'a - b', it is converted to 'a + -b'", "expr.pos_neg_to_minus(): If expr looks like 'a + -b', it is converted to 'a - b'", "expr.associate_l_to_r(): If expr looks like '(a + b) + c', it is converted to 'a + (b + c)'. You can replace '+' with '*'.", "Expression.associate_r_to_l(): Converts an expression that looks like 'a + (b + c)' to '(a + b) + c'. You can replace '+' with '*'", "Expression.rewrite_subexpression(sub_expr, equal_expr): " ] # I need to teach Henri the associative property at some point, but I won't today. # Actually, I might need to. Teaching it would be simplified if Henri had the option to convert all subtractions to # +-s. Fpr example, (11 + n) - n would become (11 + n) + -n. The associative property can then be used to turn the # expression into (11) questions = [ # (1 + 2) + 3 --> 1 + (2 + 3) conv_q("(1 + 2) + 3", "1 + (2 + 3)", check_answer(Plus(Int(1), Plus(Int(2), Int(3))))), # 9 - 4 --> 9 + -4 conv_q("9 - 4", "9 + -4", check_answer(Plus(Int(9), Negative(Int(4))))), # (a + -4) + -8 --> (a - 4) - 8 conv_q("(a + -4) + -8", "(a - 4) - 8", check_answer(Minus(Minus(Var("a"), Int(4)), Int(8)))), # 1 + (2 - 3) --> 1 + (2 + -3) --> 1 + (2 - 3) conv_q("1 + (2 - 3)", "(1 + 2) - 3", check_answer(Minus(Plus(Int(1), Int(2)), Int(3)))), # (1 - 2) - 3 --> (1 + -2) + -3 --> 1 + (-2 + -3) --> 1 + (-2 - 3) conv_q("(1 - 2) - 3", "1 + (-2 - 3)", check_answer(Plus(Int(1), Minus(Negative(Int(2)), Int(3))))), # (a + 4) + (3 - 2) --> (a + 4) + (3 + -2) --> ((a + 4) + 3) + -2 --> ((a + 4) + 3) - 2 conv_q("(a + 4) + (3 - 2)", "((a + 4) + 3) - 2)", check_answer(Minus(Plus(Plus(Var("a"), Int(4)), Int(3)), Int(2)))), # 1 + ((2 + 3) + 4) --> 1 + (2 + (3 + 4)) conv_q("1 + ((2 + 3) + 4)", "1 + (2 + (3 + 4))", check_answer(Plus(Int(1), Plus(Int(2), Plus(Int(3), Int(4)))))) ]
from Question import Question from Expression import Int, Plus, Equals, Var, Minus def check_sub_q(a): return a.interpret() == True questions = [ Question("If a = 1, what is another way of writing 'b'?", lambda a: a == Var("b")), Question("If x = 3, what is another way of writing 'x + y?'", lambda a: a == Plus(Int(3), Var("y"))), Question( "Use substitute to make '11 + a = 17' True // copy-paste Equals(Plus(Int(11), Var(\"a\")), Int(17))", check_sub_q), Question( "Use substitute and Minus to make '44 - b = 20' True // copy-paste Equals(Minus(Int(44), Var(\"b\")), Int(20))", check_sub_q), Question( "Use substitute to make '30 + 50 = x' True // copy-paste Equals(Plus(Int(30), Int(50)), Var(\"x\"))", check_sub_q), Question( "Use substitute to make 'y - 7 = 33' True // copy-paste Equals(Minus(Var(\"y\"), Int(7)), Int(33))", check_sub_q), Question( "Use substitute to make 'n + 50 = 140' True // copy-paste Equals(Plus(Var(\"n\"), Int(50)), Int(140))", check_sub_q), Question( "Use substitute to make '11 + m = 31' True // copy-paste Equals(Plus(Int(11), Var(\"m\")), Int(31))", check_sub_q),
from Question import Question from Expression import Int, Plus, Equals, Var a = Var("a") questions = [ Question("How do you write '10' using Int?", lambda a: a == Int(10)), Question("How do you write '812' using Int?", lambda a: a == Int(812)), Question("How do you write '-812' using Int?", lambda a: a == Int(-812)), Question("How do you write '1,000' using Int?", lambda a: a == Int(1000)), Question("How do you write '4 + 5' using Plus?", lambda a: a == Plus(Int(4), Int(5))), Question("How do you write '4 + -5' using Plus?", lambda a: a == Plus(Int(4), Int(-5))), Question("How do you write '(1 + 2) + 3' using Plus?", lambda a: a == Plus(Plus(Int(1), Int(2)), Int(3))), Question("What is '(1 + 2) + 3' equal to?", lambda a: a == 6), Question("How do you write '1 + (2 + 3)' using Plus?", lambda a: a == Plus(Int(1), Plus(Int(2), Int(3)))), Question("What is '1 + (2 + 3)' equal to?", lambda a: a == 6), Question("How do you write '1 = 2' using Equals?", lambda a: a == Equals(Int(1), Int(2))), Question("Is 1 = 2 True or False?", lambda a: a == False), Question("How do you write '1 = 1' using Equals?", lambda a: a == Equals(Int(1), Int(1))), Question("Is 1 = 1 True or False?", lambda a: a), Question( "How do you write '(1 + 2) + 3 = 1 + (2 + 3)' using Equals?", lambda a: a == Equals(Plus(Plus(Int(1), Int(2)), Int(3)), Plus(Int(1), Plus(Int(2), Int(3))))), Question("Is (1 + 2) + 3 = 1 + (2 + 3) True or False?", lambda a: a),
import unittest from Expression import Var, Int, Plus, Minus, Equals, Times, Negative i_1, i_2, i_n2, i_3, i_4, i_5, i_6, i_7 = Int(1), Int(2), Int(-2), Int(3), Int( 4), Int(5), Int(6), Int(7) a, b, c, x, y, z, cool = Var("a"), Var("b"), Var("c"), Var("x"), Var("y"), Var( "z"), Var("cool") i_P_1_2 = Plus(i_1, i_2) i_P_n2_3 = Plus(i_n2, i_3) i_P_nested = Plus(i_P_1_2, i_P_n2_3) b_2_E_3 = Equals(i_2, i_3) b_P_a_3_E_P_n2_3 = Equals(Plus(a, i_3), i_P_n2_3) class TestRepresentation(unittest.TestCase): def test_simple(self): self.assertEqual(i_1.__repr__(), "1") self.assertEqual(i_n2.__repr__(), "-2") self.assertEqual(a.__repr__(), "a") self.assertEqual(cool.__repr__(), "cool") def test_plus(self): self.assertEqual(i_P_1_2.__repr__(), "1 + 2") self.assertEqual(i_P_nested.__repr__(), "(1 + 2) + (-2 + 3)") def test_equals(self): self.assertEqual(b_2_E_3.__repr__(), "2 = 3") self.assertEqual(b_P_a_3_E_P_n2_3.__repr__(), "a + 3 = -2 + 3") def test_substitute(self): self.assertEqual(a.substitute(b, i_1), a)
questions = [ eval_in_for("3 * r", "21 + (3 * r)", "r", 1, Plus(Int(21), Int(3))), eval_in("21 + 3", "21 + 3", Int(24)), eval_in_for("3 * r", "21 + (3 * r)", "r", 2, Plus(Int(21), Int(6))), eval_in("21 + 6", "21 + 6", Int(27)), eval_in_for("3 * r", "21 + (3 * r)", "r", 3, Plus(Int(21), Int(9))), eval_in("21 + 9", "21 + 9", Int(30)), eval_in_for("3 * r", "21 + (3 * r)", "r", 7, Plus(Int(21), Int(21))), eval_in("21 + 21", "21 + 21", Int(42)), eval_in_for("3 * r", "21 + (3 * r)", "r", 20, Plus(Int(21), Int(60))), eval_in("21 + 60", "21 + 60", Int(81)), eval_in_for("3 * r", "21 + (3 * r)", "r", 50, Plus(Int(21), Int(150))), eval_in("21 + 150", "21 + 150", Int(171)), Question( "Make a dictionary of '21 + (3 * r)' for r = 1, 2, 3, 7, 20, and 50", check_q_table(Plus(Int(21), Times(Int(3), Var("r"))), [[Int(1), Int(24)], [Int(2), Int(27)], [Int(3), Int(30)], [Int(7), Int(42)], [Int(20), Int(81)], [Int(50), Int(171)]])), eval_in_for("45 - w", "2 * (45 - w)", "w", 1, Times(Int(2), Int(44))), eval_in("2 * 44", "2 * 44", Int(88)), eval_in_for("45 - w", "2 * (45 - w)", "w", 2, Plus(Int(21), Int(43))), eval_in("2 * 43", "2 * 43", Int(27)), eval_in_for("45 - w", "2 * (45 - w)", "w", 3, Plus(Int(21), Int(42))), eval_in("2 * 42", "2 * 42", Int(30)), eval_in_for("45 - w", "2 * (45 - w)", "w", 15, Plus(Int(21), Int(30))), eval_in("2 * 30", "2 * 30", Int(42)), eval_in_for("45 - w", "2 * (45 - w)", "w", 20, Plus(Int(21), Int(25))), eval_in("2 * 25", "2 * 25", Int(81)), eval_in_for("45 - w", "2 * (45 - w)", "w", 35, Plus(Int(21), Int(10))), eval_in("2 * 10", "2 * 10", Int(171)),
"expr.remove_add_zeroes(): Removes all zeroes being added inside of expr", "expr.combine_like_terms(n): Changes all subexpressions of the form 'n + n + ... + n' to 'm * n'", # "expr.both_sides_plus(expr_to_add): Adds expr_to_add to both sides of the equal sign", # "expr.both_sides_minus(expr_to_add): Adds expr_to_add to both sides of the equal sign" ] def check_or_answer(a1, a2): return lambda a: a == a1 or a == a2 def check_answer(a0): return lambda a: a == a0 def conv_q(expr1_str, expr2_str, af): return Question("Convert the expression '{}' to '{}'".format(expr1_str, expr2_str), af) def simp_q(expr_str, af): return Question("Simplify the expression '{}'".format(expr_str), af) def solve_q(start_str, v, af): return Question("Solve for '{}' in '{}'".format(v, start_str), af) questions = [ conv_q("n + n", "2 * n", check_answer(Times(Int(2), Var("n")))), conv_q("1 + 1", "2 * 1", check_answer(Times(Int(2), Int(1)))), conv_q("n + (n + n)", "3 * n", check_answer(Times(Int(3), Var("n")))), conv_q("(n + n) + n", "3 * n", check_answer(Times(Int(3), Var("n")))), conv_q("a + (4 * a)", "5 * a", check_answer(Times(Int(5), Var("a")))), conv_q("a + (a * 4)", "5 * a", check_answer(Times(Int(5), Var("a")))), conv_q("(3 * a) + (a * 4)", "7 * a", check_answer(Times(Int(7), Var("a")))), conv_q("(3 + a) + (a * 4)", "3 + (5 * a)", check_answer(Plus(Int(3), Times(Int(5), Var("a"))))), ]