Expressions and Arithmetic

City University of Hong Kong

CS1302 Introduction to Computer Programming


from ipywidgets import interact, fixed

Operators

The followings are common operators you can use to form an expression in Python:

OperatorOperationExample
unary -Negation-y
+Additionx + y
-Subtractionx - y
*Multiplicationx*y
/Divisionx/y
  • x and y in the examples are called the left and right operands respectively.
  • The first operator is a unary operator, which operates on just one operand.
    (+ can also be used as a unary operator, but it is not very useful.)
  • All other operators are binary operators, which operate on two operands.

Python also supports some more operators:

OperatorOperationExample
//Integer divisionx//y
%Modulox%y
**Exponentiationx**y

The following demonstrates the operations of binary operators:

binary_operators = {
    "+": " + ",
    "-": " - ",
    "*": "*",
    "/": "/",
    "//": "//",
    "%": "%",
    "**": "**",
}


@interact(operand1=r"10", operator=binary_operators, operand2=r"3")
def binary_operation(operand1, operator, operand2):
    expression = f"{operand1}{operator}{operand2}"
    value = eval(expression)
    print(
        f"""{'Expression:':>11} {expression}\n{'Value:':>11} {value}\n{'Type:':>11} {type(value)}"""
    )

What does the modulo operator % do?

You can think of it as computing the remainder, but the truth is more complicated. Try using fractions and negative numbers for the operands.

See Also

The operator implements the modular arithmetic in Mathematics. The second operand is called the modulus, which means measure in Latin.

Solution to Exercise 1
  • / is the usual division, and so 10/3 returns the floating-point number 3.3˙3.\dot{3}.
  • // is integer division, and so 10//3 gives the integer quotient 3.
Solution to Exercise 2 #
  • The first expression means concatenating 'abc' three times.
  • The second means concatenating 'a' ten times.

Operator Precedence and Associativity

An expression can consist of a sequence of operations performed in a row such as x + y*z.

How to determine which operation should be performed first?

Like arithmetics, the order of operations is decided based on the following rules applied sequentially:

  1. Grouping by parentheses: inner grouping first
  2. Operator precedence/priority: higher precedence first
  3. Operator associativity:
    • Left associativity: Associate all operations on the left for the left operand, e.g.,
      2 + 3 + 4 + 5 is equivalent to ((2 + 3) + 4) + 5
    • Right associativity: Associate all operations on the right for the right operand, e.g.,
      2 ** 3 ** 4 is equivalent to 2 ** (3 ** (4 ** 5))

What are the operator precedence and associativity?

The following table gives a concise summary:

OperatorsAssociativity
**right
- (unary)right
*,/,//,%left
+,-left
@interact(
    operator1={"None": "", "unary -": "-"},
    operand1=fixed(r"10"),
    operator2=binary_operators,
    operand2=fixed(r"2"),
    operator3=binary_operators,
    operand3=fixed(r"3"),
)
def three_operators(operator1, operand1, operator2, operand2, operator3, operand3):
    expression = f"{operator1}{operand1}{operator2}{operand2}{operator3}{operand3}"
    value = eval(expression)
    print(
        f"""{'Expression:':>11} {expression}\n{'Value:':>11} {value}\n{'Type:':>11} {type(value)}"""
    )
Solution to Exercise 4

The expression evaluates to ((102))×3=300(-(10^2))\times 3=-300 instead because the exponentiation operator ** has higher precedence than both the multiplication * and the negation operators -.

print(-10**2 * 3)  # can use code-prettify or formatter to fix incorrect styles
print((-10)**2 * 3)

Augmented Assignment Operators

For convenience, Python defines the augmented assignment operators such as +=, where

x += 1 means x = x + 1.

The following widgets demonstrate other augmented assignment operators.

@interact(
    initial_value=fixed(r"10"),
    operator=["+=", "-=", "*=", "/=", "//=", "%=", "**="],
    operand=fixed(r"2"),
)
def binary_operation(initial_value, operator, operand):
    assignment = f"x = {initial_value}\nx {operator} {operand}"
    _locals = {}
    exec(assignment, None, _locals)
    print(f"Assignments:\n{assignment:>10}\nx: {_locals['x']} ({type(_locals['x'])})")
y = 3*(x := 15)
x, y
3*(x = 15)
Solution to Exercise 6

Assignment operators are used in assignment statements, which are not expressions because they cannot be evaluated.