Contents |

Like the literals themselves, combinations of literals are also expressions. For example, suppose you have forgotten your times table and aren't quite sure whether 8 times 7 is 54 or 56. We can ask Python, presenting the interpreter with the expression:

>>> 8 * 7 56 >>> 8*7 56

Pressing the Enter key signals the end of the expression. The
multiplication sign * is known as an *operator*, as it *operates* on the 8
and the 7, producing an equivalent literal value. The 8 and the 7 are
known as *operands*. It seems that the actual names of various operands are
not being taught anymore, so for nostalgia's sake, here they are. The
operand to the left of the multiplication sign (in this case the 8) is
known as the *multiplicand*. The operand to the right (in this case the 7)
is known as the *multiplier*. The result is known as the *product*.

The operands of the other basic operators
have special names too. For addition, the left operand is known as the
*augend* and the right operand is known as the *addend*.
The result is known as the *sum*.
For subtraction,
the left operand is the *minuend*, the right the *subtrahend*, and
the result as the *difference*.
For division (and I think this is still taught), the left operand is
the *dividend*, the right operand is the *divisor*, and the
result is the *quotient*.
Finally, for exponentiation, which is shorthand for repeated multiplication:

>>> 3 ** 4 81 >>> 3 * 3 * 3 * 3 81

the left operand is the *base* and the right operand is the *exponent*.

In general, we will separate
operators from their operands by
spaces, tabs,
or newlines, collectively known as *whitespace*.^{2}
It's not necessary to do so, but it makes your code
easier to read.

Python always takes in an expression and displays an equivalent
literal expression (*e.g.*, integer or real). All Python operators are
binary, meaning they operate on exactly two operands. We first look at
the numeric operators.

If it makes sense to add two things together, you can probably do it in Python using the + operator. For example:

>>> 2 + 3 5 >>> 1.9 + 3.1 5.0

One can see that if one adds two integers, the result is an integer. If one does the same with two reals, the result is a real.

You can even add strings with strings and arrays with arrays:

>>> "hello" + "world" 'helloworld' >>> [1, 3, 5] + [2, 4, 6] [1, 3, 5, 2, 4, 6]

The process of joining strings and arrays together is known as
*concatenation*. Array concatenation is an expensive processive,
since you need to the values of both arrays source arrays to build
the resulting array.

Things get more interesting when you add things having different types. Adding an integer and a real (in any order) always yields a real.

>>> 2 + 3.3 5.3 >>> 3.3 + 2 5.3

Adding an string to an integer (with an augend integer) yields an error; the types are not "close" enough, like they are with integers and reals:

>>> 2 + "hello" TypeError: unsupported operand types(s) for +: 'int' and 'str'

In general, when adding two things, the types must match or nearly match.

You can multiply strings and arrays with numbers:

>>> "hello" * 3 'hellohellohello' >>> [1, 2] * 3 [1, 2, 1, 2, 1, 2]

Subtraction and division of numbers follow the same rules as addition. However, these operators, as defined, do not work for strings and arrays.

Of special note is the division operator with respect to integer operands. Consider evaluating the following expression:

15 / 2

If one asked the Python interpreter to perform this task, the result would be 7.5, as expected. However, often we wish for just the quotient without the remainder. In this case, the quotient is 7 and the remainder is 0.5. The double forward slash operator is Python's quotient operator; if we ask the interpreter to evaluate

14 // 5

the result would be 2, not 2.8.
Use of the quotient operator is known as
*integer* *division*.^{3}

The complement to integer division is the modulus operator %. While the result of integer division is the quotient, the result of the modulus operator is the remainder. Thus

14 % 5

evaluates to 4 since 4 is left over when 5 is divided into 14. To check if this is true, one can ask the interpreter to evaluate:

(14 // 5 * 5) + (14 % 5) == 14

This complicated expression asks the question "is it true that the
quotient times the divisor plus the remainder is equal to the original
dividend?". The Python interpreter will respond that, indeed, it is
true. The reason for the parentheses is delineate
the quotient and the remainder within the addition.
The parentheses can also be used to change the *precedence*
of operators; this is
is explained in more detail in the
next chapter.

Remember the **Boolean** literals, `True` and `False`?
We can use the **Boolean**
comparison operators to generate such values. For example, we can ask
if 3 is less than 4:

>>> 3 < 4 True

The interpreters response says that, indeed, 3 is less than 4. If it were
not, the interpreter would respond with `False`.
Besides
`<`
(less than),
there are other **Boolean** comparison operators:
`<=`
(less than or equal to),
`>`
(greater than),
`>=`
(greater than or equal to),
`==`
(equal to), and
`!=`
(not equal to).

Note that two equal signs are used to see if to things are the same. A single equals sign is reserved for the assignment operator, which you will learn about in a later chapter.

Besides integers, we can compare reals with reals, strings with strings, and arrays with arrays using the comparison operators:

>>> "apple" < "banana" True >>> [1, 2, 3] < [1, 2, 4] True

In general, it is illegal to compare integers or reals with strings.

Any Python type can be compared with any other type with the equality
and inequality operators,
`==`
and
`!=`.
These operators are used to see if two things are the same or not the same,
as the case may be.
Usually, for two things to be considered the same, they have to be
the same kind of thing or *type*. For example, the expression:
`123 == "123"`

resolves to `False`

, because integers are not strings and vice versa.
Likewise, `"False" != False`

resolves to `True`

,
because strings are not
**Booleans** and vice versa.
There is an exception, though.
If an integer is compared with a real,
the integer is converted into a real before the comparison
is made.
In the case of arrays, `==`

will return `False`

if the arrays have differing lengths.
If the arrays have equal length, then each item in one array is
compared using `==`

to the respective item in the other array. All individual
items must be equal for the two arrays to be equal.
For example `[1, [2, 1, 0], 3]`

and `[1, [2, 1, 8], 3]`

would
be considered "not equal", since the middle items would not be considered
equal.

We can combine comparisons with the **Boolean** logical connectives
`and` and `or`:

>>> 3 < 4 and 4 < 5 True >>> 3 < 4 or 4 < 5 True >>> 3 < 4 and 5 < 4 False >>> 3 < 4 or 5 < 4 True

The first interaction asks if both the expression
`3 < 4` and the expression
`4 < 5` are true. Since both are, the
interpreter responds with `True`. The second interaction
asks if at least one of the expressions is true. Again, the
interpreter responds with `True`. The difference between `and`
and `or` is illustrated in the last two interactions. Since
only one expression is true (the latter expression being
false) only the `or` operator yields a true value.

There is one more **Boolean** logic operation, called
*not*. It simply reverses the value of the expression
to which it is attached. The *not* operator can only be called
as a function (since it is not a binary operator). Since
you do not yet know about functions, I'll show you what
it looks like but won't yet explain its actions.

>>> not(3 < 4 and 4 < 5) False >>> not(3 < 4 or 4 < 5) False >>> not(3 < 4 and 5 < 4) True >>> not(3 < 4 or 5 < 4) False

Note that we attached *not* to each of the previous expressions involving
the logical connectives. Note also that the response of the interpreter
is reversed from before in each case.

Contents |