Commit d3a8ad0a authored by Taddeus Kroes's avatar Taddeus Kroes

Moved all spreaded node creation functions to src/node.py.

parent dfbc16d4
......@@ -606,3 +606,76 @@ def negate(node, n=1):
new_node.negated = n
return new_node
def infinity():
"""
Return an infinity leaf node.
"""
return ExpressionLeaf(INFINITY)
def absolute(exp):
"""
Put an 'absolute value' operator on top of the given expression.
"""
return ExpressionNode(OP_ABS, exp)
def sin(*args):
"""
Create a sinus function node.
"""
return ExpressionNode(OP_SIN, *args)
def cos(*args):
"""
Create a cosinus function node.
"""
return ExpressionNode(OP_COS, *args)
def tan(*args):
"""
Create a tangens function node.
"""
return ExpressionNode(OP_TAN, *args)
def log(exponent, base=10):
"""
Create a logarithm function node (default base is 10).
"""
if not isinstance(base, ExpressionLeaf):
base = ExpressionLeaf(base)
return ExpressionNode(OP_LOG, exponent, base)
def ln(exponent):
"""
Create a natural logarithm node.
"""
return log(exponent, base=E)
def der(f, x=None):
"""
Create a derivative node.
"""
return ExpressionNode(OP_DER, f, x) if x else ExpressionNode(OP_DER, f)
def integral(*args):
"""
Create an integral node.
"""
return ExpressionNode(OP_INT, *args)
def indef(*args):
"""
Create an indefinite integral node.
"""
return ExpressionNode(OP_INT_INDEF, *args)
from .utils import find_variables, first_sorted_variable
from .logarithmic import ln
from .goniometry import sin, cos
from ..node import ExpressionNode as N, ExpressionLeaf as L, Scope, OP_DER, \
OP_MUL, OP_LOG, OP_SIN, OP_COS, OP_TAN, OP_ADD, OP_DIV, E
from ..node import ExpressionLeaf as L, Scope, OP_DER, OP_MUL, OP_LOG, \
OP_SIN, OP_COS, OP_TAN, OP_ADD, OP_DIV, E, sin, cos, der, ln
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
def der(f, x=None):
return N(OP_DER, f, x) if x else N(OP_DER, f)
def second_arg(node):
"""
Get the second child of a node if it exists, None otherwise.
......
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_ADD, OP_MUL, \
OP_DIV, OP_SIN, OP_COS, OP_TAN, OP_SQRT, PI, TYPE_OPERATOR
OP_DIV, OP_SIN, OP_COS, OP_TAN, OP_SQRT, PI, TYPE_OPERATOR, sin, cos
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
def sin(*args):
return N(OP_SIN, *args)
def cos(*args):
return N(OP_COS, *args)
def tan(*args):
return N(OP_TAN, *args)
def match_add_quadrants(node):
"""
sin(t) ^ 2 + cos(t) ^ 2 -> 1
......@@ -26,9 +14,9 @@ def match_add_quadrants(node):
sin_q, cos_q = node
if sin_q.is_power(2) and cos_q.is_power(2):
sin, cos = sin_q[0], cos_q[0]
sinus, cosinus = sin_q[0], cos_q[0]
if sin.is_op(OP_SIN) and cos.is_op(OP_COS):
if sinus.is_op(OP_SIN) and cosinus.is_op(OP_COS):
p.append(P(node, add_quadrants, ()))
return p
......
from .utils import find_variables, replace_variable, find_variable, absolute
from .logarithmic import ln
from .goniometry import sin, cos
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_INT, \
OP_INT_INDEF, OP_MUL, OP_DIV, OP_LOG, OP_SIN, OP_COS, Scope
from .utils import find_variables, replace_variable, find_variable
from ..node import ExpressionLeaf as L, OP_INT, OP_INT_INDEF, OP_MUL, OP_DIV, \
OP_LOG, OP_SIN, OP_COS, Scope, sin, cos, ln, integral, indef, absolute
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
def integral(*args):
"""
Create an integral node.
"""
return N(OP_INT, *args)
def indef(*args):
"""
Create an indefinite integral node.
"""
return N(OP_INT_INDEF, *args)
def choose_constant(integral):
"""
Choose a constant to be added to the antiderivative.
......
from itertools import combinations, product
from .utils import find_variables, partition
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_LOG, E, \
OP_ADD, OP_MUL, OP_POW, Scope
from ..node import ExpressionLeaf as L, OP_LOG, OP_ADD, OP_MUL, OP_POW, \
Scope, log
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
def log(exponent, base=10):
if not isinstance(base, L):
base = L(base)
return N(OP_LOG, exponent, base)
def ln(exponent):
return log(exponent, base=E)
def match_constant_logarithm(node):
"""
log_1(a) -> # raise ValueError for base 1
......
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_MUL, OP_DIV, \
INFINITY, OP_ABS
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_MUL, OP_DIV
def greatest_common_divisor(a, b):
......@@ -126,17 +125,3 @@ def replace_variable(f, x, replacement):
children = map(lambda c: replace_variable(c, x, replacement), f)
return N(f.op, *children)
def infinity():
"""
Return an infinity leaf node.
"""
return L(INFINITY)
def absolute(exp):
"""
Put an 'absolute value' operator on top of the given expression.
"""
return N(OP_ABS, exp)
from src.node import ExpressionNode as N, ExpressionLeaf as L, Scope, \
nary_node, get_scope, OP_ADD
nary_node, get_scope, OP_ADD, infinity, absolute, sin, cos, tan, log, \
ln, der, integral, indef
from tests.rulestestcase import RulesTestCase, tree
......@@ -249,3 +250,44 @@ class TestNode(RulesTestCase):
def test_construct_function_absolute_child(self):
self.assertEqual(str(tree('ln(|x|)')), 'ln|x|')
self.assertEqual(str(tree('sin(|x|)')), 'sin|x|')
def test_infinity(self):
self.assertEqual(infinity(), tree('oo'))
def test_absolute(self):
self.assertEqual(absolute(tree('x2')), tree('|x2|'))
def test_sin(self):
self.assertEqual(sin(tree('x')), tree('sin(x)'))
def test_cos(self):
self.assertEqual(cos(tree('x')), tree('cos(x)'))
def test_tan(self):
self.assertEqual(tan(tree('x')), tree('tan(x)'))
def test_log(self):
x = tree('x')
self.assertEqual(log(x, 'e'), tree('ln x'))
self.assertEqual(log(x, 2), tree('log_2 x'))
self.assertEqual(log(x), tree('log x'))
self.assertEqual(log(x, 10), tree('log x'))
def test_ln(self):
self.assertEqual(ln(tree('x')), tree('ln x'))
def test_der(self):
x2, x, y = tree('x ^ 2, x, y')
self.assertEqual(der(x2), tree('[x ^ 2]\''))
self.assertEqual(der(x2, x), tree('d/dx x ^ 2'))
self.assertEqual(der(x2, y), tree('d/dy x ^ 2'))
def test_integral(self):
x2, x, y, a, b = tree('x ^ 2, x, y, a, b')
self.assertEqual(integral(x2, x), tree('int x2 dx'))
self.assertEqual(integral(x2, x, a, b), tree('int_a^b x2 dx'))
self.assertEqual(integral(x2, y, a, b), tree('int_a^b x2 dy'))
def test_indef(self):
x2, a, b, expect = tree('x ^ 2, a, b, [x ^ 2]_a^b')
self.assertEqual(indef(x2, a, b), expect)
......@@ -3,14 +3,9 @@ import unittest
from src.parser import Parser
from src.node import ExpressionNode as Node, ExpressionLeaf as Leaf, \
SPECIAL_TOKENS
SPECIAL_TOKENS, sin, cos, der, log, ln, integral, indef, absolute
from tests.parser import ParserWrapper, run_expressions, line, graph
from tests.rulestestcase import tree
from src.rules.goniometry import sin, cos
from src.rules.derivatives import der
from src.rules.logarithmic import log, ln
from src.rules.integrals import integral, indef
from src.rules.utils import absolute
class TestParser(unittest.TestCase):
......
......@@ -6,9 +6,7 @@ from src.rules.derivatives import der, get_derivation_variable, \
logarithmic, match_goniometric, sinus, cosinus, tangens, \
match_sum_product_rule, sum_rule, product_rule, match_quotient_rule, \
quotient_rule, power_rule
from src.rules.logarithmic import ln
from src.rules.goniometry import sin, cos
from src.node import Scope
from src.node import Scope, sin, cos, ln
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......
# vim: set fileencoding=utf-8 :
from src.rules.goniometry import sin, cos, tan, match_add_quadrants, \
add_quadrants, match_negated_parameter, negated_sinus_parameter, \
negated_cosinus_parameter, match_standard_radian, standard_radian, \
is_pi_frac
from src.node import PI, OP_SIN, OP_COS, OP_TAN
from src.rules.goniometry import match_add_quadrants, add_quadrants, \
match_negated_parameter, negated_sinus_parameter, is_pi_frac, \
negated_cosinus_parameter, match_standard_radian, standard_radian
from src.node import PI, OP_SIN, OP_COS, OP_TAN, sin, cos, tan
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
from src.rules import goniometry
......
......@@ -6,8 +6,6 @@ from src.rules.integrals import indef, choose_constant, solve_integral, \
match_division_integral, division_integral, extend_division_integral, \
match_function_integral, logarithm_integral, sinus_integral, \
cosinus_integral
from src.rules.logarithmic import ln
from src.rules.goniometry import sin, cos
from src.node import Scope
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......
from src.rules.logarithmic import log, ln, match_constant_logarithm, \
from src.rules.logarithmic import log, match_constant_logarithm, \
base_equals_raised, logarithm_of_one, divide_same_base, \
match_add_logarithms, add_logarithms, expand_negations, \
subtract_logarithms, match_raised_base, raised_base, \
......
from src.rules import utils
from src.rules.utils import least_common_multiple, is_fraction, partition, \
find_variables, first_sorted_variable, find_variable, \
replace_variable, infinity
find_variables, first_sorted_variable, find_variable, replace_variable
from tests.rulestestcase import tree, RulesTestCase
......@@ -28,9 +27,6 @@ class TestRulesUtils(RulesTestCase):
self.assertEqual(partition(lambda x: x & 1, range(6)),
([1, 3, 5], [0, 2, 4]))
def test_infinity(self):
self.assertEqual(infinity(), tree('oo'))
def test_find_variables(self):
x, l2, add, mul0, mul1 = tree('x, 2, x + 2, 2x, xy')
self.assertSetEqual(find_variables(x), set(['x']))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment