Expressions#

Expressions can be viewed as a collection of nodes, these nodes are binded to each other using operators.

Expression#

class cake.Expression(starting_op: Operation)[source]#

Bases: BasicExpression

Represents an expression within the cake library, and expression is not equal to a value, inorder to compute equations use an Equations object.

Which are simply 2 expressions with a comparity operator between them.

Hint

Iterating through expressions simply returns the node, not the operand between them.

Warning

Expressions when being compared using symbols such as > will not return a boolean value, instead Comparity is returned.

# Making your own expressions
>>> expr = Expression(Add('x', 5))
>>> expr
x + 5
Parameters:

starting_op (cake.Operation) –

Operation the expression begins with.

>>> op = Add('x', 5)
>>> Expression(op)
x + 5

solve(true_value: bool = False, **values) Any[source]#

Produces a solution to the expression using provided values. Any variables in the expression must be passed as a kwarg!

Parameters:
  • true_value (bool) – Whether to use true_value when evaluating Sqrt

  • code-block: (..) – py: >>> expr = Expression(Add(‘x’, 5)) >>> expr x + 5 >>> expr.solve(x=3) Integral(8)

Operations#

Operations are a fundemental part of expressions, you can use our built in operations which cover most of the python arithmetic range.

class cake.Operation(x: BasicNode, y: BasicNode, /, *nodes: BasicNode)[source]#

Bases: ExpressionNode

Base class for defining operations within the cake library, operations cannot be individually manipulated. Use Expression to assist in this.

abstract flatten() None[source]#

Simplifies the expression into its simplest form if possible, can also be used as a check method when new operations are executed.

Creating your own#

If your in need of your own operation, look no further. But first lets define our own operation:

class MyOperation(cake.Operation):

    ## My cool operation will return the sum of the nodes * 3
    def run(self, node: MyOperation, **kwds) -> Any:
        solved = map(lambda x: cake.utils.solve_if_possible(x, **kwds), self.nodes)
        return sum(solved) * 3

    ## Don't forget the flatten method, this serves as a cleanup function
    ## Called straight after you initialise your operation
    ## We dont need it for anything in our case.
    def flatten(self) -> None:
        return

Now that our operation is defined lets use it!

>>> op = MyOperation('x', 'y', 5)
# Same as doing (x + y + 5) * 3 in our case
>>> expr = Expression(op)
>>> expr
MyOperation(x, y, 5)
>>> expr.solve(x=5, y=5)
45

Prettifying Outputs#

You may have noticed that the string version of our operation isn’t very nice, you can define your own __str__ method which can better represent how your operation works, in our case its easy!

class MyOperation(cake.Operation):

    ## My cool operation will return the sum of the nodes * 3
    def run(self, node: MyOperation, **kwds) -> Any:
        solved = map(lambda x: cake.utils.solve_if_possible(x, **kwds), self.nodes)
        return sum(solved) * 3

    ## Don't forget the flatten method, this serves as a cleanup function
    ## Called straight after you initialise your operation
    ## We dont need it for anything in our case.
    def flatten(self) -> None:
        return

    ## Lets define a new str function
    def __str__(self) -> str:
        nodes = ' + '.join(map(str, self.nodes))
        return f'({nodes}) * 3'

Now whenever we want to print out our expression, we have a consistent approach

>>> op = MyOperation('x', 'y', 5)
>>> op
## Before: MyOperation(x, y, 5)
(x + y + 5) * 3

Predefined Operations#

  • Add: Add ~ Many nodes are able to be passed, represents the addition of all nodes.
    • For subtraction simply use the Add operation but negate the subtraction node

  • Divide: Divide ~ 2 nodes (x, y) are able to be passed, represents the division of 2 nodes.
    • Properties numerator and denominator are used to represent the 2 nodes

  • FloorDiv: FloorDiv ~ Inherits all properties of Divide, except represents the floor division of the nodes.

  • Modulo: Modulo ~ Inherits all properties of Divide, except represents mod of the 2 nodes.

  • Multiply: Multiply ~ Many nodes are able to be passed, represents the multiplication of all nodes

  • Power: Power ~ 2 nodes (x, y) are able to be passed, represents one node is raised to the other node
    • Properties base and power are used to represent the 2 nodes.

Binary operators: LeftShift (<<), RightShift (>>), And (&), Xor (^) and Or (|)

  • These are also supported and can only take 2 nodes (x, y) with no other special properties.

  • Each operation represents x ? y where ? is the operator at hand.