Operations

%reload_ext rubberize
from rubberize.config import config

Operator Precedence

Rubberize follows Python’s standard operator precedence rules1 when deciding how to properly render an expression. when an operation already naturally follows the operator precedence, Rubberize renders it without any extra parentheses:

%%tap
2 + 3 * 4
2 + (3 * 4)  # Unnecessary parentheses are not rendered
\( \displaystyle 2 + 3 \times 4 = 14 \)
\( \displaystyle 2 + 3 \times 4 = 14 \)
Unnecessary parentheses are not rendered

Because multiplication has higher precedence than addition, no parentheses are needed. However, when an operation requires explicit grouping, Rubberize includes parentheses:

%%tap
(2 + 3) * 4
\( \displaystyle \left( 2 + 3 \right) \cdot 4 = 20 \)

Arithmetic Operations

Arithmetic operations are rendered by Rubberize in mathematical notation:

%%tap
a = 5  # @hide
b = 3  # @hide

a + b   # Addition
a - b   # Subtraction
a * b   # Multiplication
a / b   # Division
a // b  # Floor division
a % b   # Modulo
a ** 3  # Exponentiation
\( \displaystyle a + b = 5 + 3 = 8 \)
Addition
\( \displaystyle a - b = 5 - 3 = 2 \)
Subtraction
\( \displaystyle a\,b = 5 \times 3 = 15 \)
Multiplication
\( \displaystyle \frac{a}{b} = \frac{5}{3} = 1.67 \)
Division
\( \displaystyle \left\lfloor\frac{a}{b}\right\rfloor = \left\lfloor\frac{5}{3}\right\rfloor = 1 \)
Floor division
\( \displaystyle a \mathbin{\%} b = 5 \mathbin{\%} 3 = 2 \)
Modulo
\( \displaystyle a^{3} = 5^{3} = 125 \)
Exponentiation

Contextual Multiplication Symbol

@use_contextual_mult controls which multiplication symbol to show.

config.use_contextual_mult
True

If set to True, Rubberize infers which symbol to use for multiplication based on how the operands are rendered. The multiplication symbol (\(a \times b\)), a dot (\(a \cdot b\)), or implicit multiplication (\(a\,b\)) is used depending on readability and convention.

The following table shows how the appropriate multiplication symbol is determined. Rows are the left operand types, and columns are right operand types. The intersection specifies the symbol used.

L \ R N -N L -L W -W C -C B -B ? -?
N \(\times\) \(\times\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\cdot\) \(\cdot\)
-N \(\times\) \(\times\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\cdot\) \(\cdot\)
L \(\cdot\) \(\cdot\) \(\,\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
-L \(\cdot\) \(\cdot\) \(\,\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
W \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
-W \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
C \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
-C \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
B \(\cdot\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\cdot\) \(\cdot\)
-B \(\cdot\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\,\) \(\cdot\) \(\cdot\) \(\cdot\)
? \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)
-? \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\) \(\cdot\)

The operand types are:

  • N: Numeric values (e.g., \(3\), \(-2.50\))
  • L: Letter variables (a single-character base name), including Greek letters, which are rendered in italics (e.g., \(x\), \(a_{\mathrm{foo}}\), \(\epsilon\), \(\Delta T\))
  • W: Word variables (with multiple characters for base name), which are rendered in Roman font (e.g., \(\mathrm{foo}\), \(\mathrm{var}_{a}\), \(\Delta \mathrm{Temp}\))
  • C: Function (or class, or method) call. (e.g., \(\cos \alpha\), \(\mathrm{fcn}(a, b)\) )
  • B: Bracketed expressions
  • ?: Other type not covered
Note

Between numeric values, multiplication symbol (\(\times\)) is preferred over dot (\(\cdot\)) because the latter is harder to read with decimal numbers (e.g., \(6.90 \cdot 4.20\) versus \(6.90 \times 4.20\)).

If @use_contextual_mult=False, all multiplications will be rendered with a dot (\(a \cdot b\)).

Unary Operations

Unary operations are rendered by Rubberize:

%%tap
+a
-a
--a
-a**2
(-a)**2
\( \displaystyle +a = +5 = 5 \)
\( \displaystyle -a = -5 \)
\( \displaystyle -\left( -a \right) = -\left( -5 \right) = 5 \)
\( \displaystyle -a^{2} = -5^{2} = -25 \)
\( \displaystyle \left( -a \right)^{2} = \left( -5 \right)^{2} = 25 \)

Comparisons and Membership

Comparisons are rendered by Rubberize:

%%tap --dead --grid
a == b
a != b
a < b
a <= b
a > b
a >= b
a < b <= c
a >= b > c
a is None
a is not None
a in [3, 4, 5]
a not in [3, 4, 5]
\( \displaystyle a = b \)
\( \displaystyle a \ne b \)
\( \displaystyle a < b \)
\( \displaystyle a \le b \)
\( \displaystyle a > b \)
\( \displaystyle a \ge b \)
\( \displaystyle a < b \le c \)
\( \displaystyle a \ge b > c \)
\( \displaystyle a \equiv \emptyset \)
\( \displaystyle a \not\equiv \emptyset \)
\( \displaystyle a \in \left[ 3,\, 4,\, 5 \right] \)
\( \displaystyle a \notin \left[ 3,\, 4,\, 5 \right] \)

Logical Operations

Logical operators and, or, and not are rendered as logical symbols \(\land\), \(\lor\), and \(\lnot\), respectively:

%%tap
a = b = False
c = True

not a
a and b
a or b

a and b or c
a and (b or c)
\( \displaystyle a = b = \text{False} \)
\( \displaystyle c = \text{True} \)
\( \displaystyle \lnot a = \lnot \text{False} = \text{True} \)
\( \displaystyle a \land b = \text{False} \land \text{False} = \text{False} \)
\( \displaystyle a \lor b = \text{False} \lor \text{False} = \text{False} \)
\( \displaystyle a \land b \lor c = \text{False} \land \text{False} \lor \text{True} = \text{True} \)
\( \displaystyle a \land \left( b \lor c \right) = \text{False} \land \left( \text{False} \lor \text{True} \right) = \text{False} \)

Grouped Logical

If the same boolean operation is repeated more times than @max_inline_bool, the compared values will be arranged vertically for readability.

config.max_inline_bool
3
%%tap --dead --grid
a and b and c and d or e and f
(a or b or c or d) and (e or f)
\( \displaystyle \left\{ \begin{array}{l} a \\ \land\ b \\ \land\ c \\ \land\ d \end{array} \right\} \lor e \land f \)
\( \displaystyle \left\{ \begin{array}{l} a \\ \lor\ b \\ \lor\ c \\ \lor\ d \end{array} \right\} \land \left( e \lor f \right) \)

Conditional Expressions

Conditional expressions (not statements) are rendered like piecewise expressions:

%%tap
x = 3

y = 1 if x > 0 else -1 if x < 0 else 0
\( \displaystyle x = 3 \)
\( \displaystyle y = \begin{cases} \displaystyle 1, &\text{if}\ x > 0 \\ \displaystyle -1, &\text{if}\ x < 0 \\ \displaystyle 0, &\text{otherwise} \end{cases} = 1 \)

Named Expressions

Named expressions, more commonly known as the walrus operator (:=) is rendered with an arrow (\(a \gets b\)) rather than an equality.

%%tap
(a := 3) > 0
a
\( \displaystyle \left( a \gets 3 \right) > 0 = \text{True} \)
\( \displaystyle a = 3 \)

Lambda Functions

Anonymous lambda functions are supported:

%%tap
a = lambda x, y: x + y
a(1, 2)
\( \displaystyle a = x,\, y \mapsto x + y \)
\( \displaystyle \operatorname{a} \left( 1,\, 2 \right) = 3 \)

Generator Expressions

Generator expressions are rendered like so:

%%tap
a = [1, 2, 3, 4]
x = 3  # x is shadowed by the comprehension scope

generator = (x**2 for x in a if x % 2 == 0) 
\( \displaystyle a = \left[ 1,\, 2,\, 3,\, 4 \right] \)
\( \displaystyle x = 3 \)
x is shadowed by the comprehension scope
\( \displaystyle \mathrm{generator} = \left(\, x^{2} \;\middle|\; x \in a \land x \mathbin{\%} 2 = 0 \,\right) \)

Starred Expressions

Starred expressions are rendered like so:

%%tap
a, *b, c = (1, 2, 3, 4, 5)
b
\( \displaystyle a,\, *b,\, c = \left( 1,\, 2,\, 3,\, 4,\, 5 \right) \)
\( \displaystyle b = \left[ 2,\, 3,\, 4 \right] \)

Also see rendering of starred expressions when used in unpacking context in collections.

Footnotes

  1. Python Software Foundation, The Python Language Reference, Section 6.16: Operator Precedence, Python 3 Documentation. Available: https://docs.python.org/3/reference/expressions.html#operator-precedence↩︎