Chapter 14: Introduction to Operators

The annual book fair at Sunrise Public School runs for three days. This year Aarav and Neha are in charge of the billing counter. On the first morning it goes smoothly. A student picks up two books. Neha adds the prices on a calculator, looks down the printed sheet to see whether the buyer’s name is on the members list, takes off ten per cent if it is, and writes the final amount in a register.

By the afternoon the queue has reached the corridor. Every single bill needs the same four things. Add the prices. Take off the discount. Decide whether the total has crossed the limit for a free bookmark. Check the members list. The work never changes; only the numbers change. Fig. 14.0-1 shows the counter on that busy afternoon.

Diagram

Fig. 14.0-1 – a school book-fair billing counter with a queue of students; two student volunteers at the table with a calculator, a register and a printed members list; four labelled callout boxes above the table reading “Add the prices”, “Take off the discount”, “Free bookmark or not?”, “Name on the members list?”

Their computer teacher watches for a while and says one thing: a Python program can do all four jobs, and it will fit in a few lines. That evening Aarav opens a laptop. He already knows how to store a price in a variable. What he does not know yet is how to make Python work with the values he has stored.

NoteCuriosity Corner

Q1. Why does dividing 5 by 2 in Python give 2.5, while a slightly different symbol gives 2? Q2. How can a program check two things at the same time, such as “the bill is above the limit and the buyer is a member”? Q3. What is the difference between = and == in Python? Q4. How can a program find out whether a name appears in a list without checking every item one by one? Q5. When one line of a program has several symbols in it, which symbol does Python work out first?

This chapter will answer all five of these questions.

14.1 Operators, Operands and Expressions

A variable that only holds a value is not much use on its own. If Neha’s laptop stores the price of a book and the number of copies, it has done nothing that the printed price tag had not already done. The counter becomes faster only when the computer starts doing something with those values — multiplying them, comparing them, deciding whether a discount applies.

Think of a calculator. The number keys let you put values in. The +, −, × and ÷ keys are what actually get work done. Python has the same two kinds of things: values, and symbols that act on values.

A symbol that tells Python to do something with one or more values is called an operator. The + in 8 + 5 is an operator. So is the > in a line that checks whether one price is greater than another.

NoteDefinition

(An operator is a symbol or keyword that tells Python to perform a particular operation on one or more values.)

Notice the words “or keyword”. Most operators are symbols, but a few are ordinary English words, such as and, is and in. They are still operators.

What the operator works on

The values an operator works on have a name too. Each one is called an operand. An operand can be a plain value, or a variable holding a value, or even the result of another operation.

In 8 + 5, the operator is + and the operands are 8 and 5. In price * quantity, the operator is * and the operands are the two variables. See Fig. 14.1-1.

Diagram

Fig. 14.1-1 – the code 8 + 5 written large, with a downward arrow from 8 labelled “operand”, an arrow from + labelled “operator”, and an arrow from 5 labelled “operand”; below it a curved bracket under the whole thing labelled “expression”, and to the right an arrow pointing to the value 13 labelled “the value it produces”

Most Python operators take two operands, one on each side. A few take only one — not is written in front of a single operand, with nothing on its left.

Expressions

Put operators and operands together and you get an expression. An expression is any piece of code that produces a single value. Python works out the value of an expression as soon as it meets one, and this working-out is called evaluating the expression.

NoteDefinition

(An expression is a combination of values, variables and operators that Python evaluates to produce a single value.)

An expression can be long, like price * quantity - discount. It can also be very short.

Q. Is a single number such as 8 an expression?

A. Yes. It produces one value — itself. An expression does not have to contain an operator.

The value an expression produces is not always a number. Comparing two prices produces True or False. Joining two names together produces a string. The type of the result depends on the operator used and on the type of the operands.

The six groups of operators

Python has many operators, so they are studied in groups. The syllabus covers six of them, and the rest of this chapter takes them one at a time.

  1. Arithmetic operators do the calculations — adding, subtracting, multiplying, dividing and raising to a power.
  2. Logical operators combine two or more conditions, so that a program can check several things at once.
  3. Assignment operators put a value into a variable, and can update the value already stored there.
  4. Comparison operators compare two values and answer with True or False.
  5. Identity operators check whether two names refer to the very same object in memory.
  6. Membership operators check whether a value appears inside a sequence such as a list or a string.

Aarav’s billing program will need four of these six groups before it is finished, which is a good sign that none of them is there just for decoration.

writing 2x when you mean 2 * x What goes wrong: In mathematics, writing a number next to a letter means multiply. Python does not follow that rule. 2x is not a valid expression, and the program stops with an error before it runs. The fix: Always write the operator out — 2 * x. Python never guesses an operator that you have not typed.

Spaces around an operator are optional. 8+5 and 8 + 5 mean exactly the same thing to Python. The spaced-out version is easier for a person to read, so it is worth getting into the habit.

14.2 Arithmetic Operators

Almost every program that deals with real life has to do sums somewhere. A bill needs a total. A report card needs an average. A robot that must reach a wall in four seconds needs its speed worked out from a distance and a time. None of this happens unless the program can calculate.

The operators that do calculations are called arithmetic operators. They are the closest thing Python has to the keys on a calculator, except that you type them into a line of code instead of pressing them one at a time.

There are seven of them, and you already know most of them from mathematics. Table 14.1 lists all seven together so that you can see the whole set before studying each one.

Table 14.1 – the seven arithmetic operators in Python, with the name and one example of each | Operator | Name | Example | |—|—|—| | + | Addition | 8 + 5 | | - | Subtraction | 8 - 5 | | * | Multiplication | 8 * 5 | | / | Division | 8 / 5 | | // | Floor division | 8 // 5 | | % | Modulus | 8 % 5 | | ** | Exponent | 8 ** 5 |

Three of these will look unfamiliar. // and % are two different ways of dividing, and ** raises a number to a power. Each gets its own sub-section below.

The type of the answer

Before starting, one idea is worth fixing in your mind, because it explains results that otherwise look strange.

You met two kinds of numbers earlier: an int, which is a whole number such as 7, and a float, which is a number with a decimal point such as 7.0 or 7.25. The type of the answer an arithmetic operator gives depends on the types of its operands.

The general rule is simple. If both operands are int, the answer is an int. If even one operand is a float, the answer is a float. There is one operator that breaks this rule, /, and 14.2.2 explains why.

Q. Are 7 and 7.0 the same thing in Python?

A. They stand for the same amount, but they are different types. 7 is an int and 7.0 is a float. A program that prints one will show 7, and a program that prints the other will show 7.0.

You can, of course, put several arithmetic operators in one line. When you do, Python does not simply work from left to right — it follows an order, much like the order you use in mathematics. That order is explained in 14.8, once all the operators have been introduced. Until then, each example here uses one operator at a time.

14.2.1 Addition, Subtraction and Multiplication

Go back to the billing counter for a moment. A student buys three copies of the same book. Neha does not add the price three times; she multiplies. Then she adds ten rupees for a paper bag. Two operations, both of which a program can do far faster than a person with a calculator.

These three operators behave exactly as they do in mathematics.

+ adds its two operands. - subtracts the right operand from the left. * multiplies. The only surprise is the multiplication sign, which is a star and not a cross.

Working out the bill

Before writing any code, say the method out loud in ordinary words. Multiply the price of one book by the number of copies. That gives the cost of the books. Add the bag charge to it. That gives the amount to be paid.

Each of those two steps becomes one line of Python.

cost of books bought at the school book fair Problem: Find the cost of three copies of a book priced at ₹180 each, and then the total after a ₹10 bag charge.

price = 180
quantity = 3
bag_charge = 10

books_cost = price * quantity
total = books_cost + bag_charge

print("Cost of books:", books_cost)
print("Total to pay:", total)

Output:

Cost of books: 540
Total to pay: 550

Notice that the result of the first calculation is stored in books_cost, and that variable is then used as an operand in the next line. This is what was meant in 14.1 by saying that an operand can itself be the result of an earlier operation.

Changing the program to handle four copies means changing one number. That is the whole reason the counter is faster with a program than with a register.

Whole numbers and decimals

The type rule from 14.2 shows up as soon as a decimal enters the calculation.

how the answer type changes with the operand type Problem: Show what these three operators give when the operands are whole numbers, and what changes when one operand has a decimal point.

print(40 + 25)
print(40 + 25.0)
print(18 - 25)
print(35.5 * 2)

Output:

65
65.0
-7
71.0

The first two lines give the same amount, but not the same type. 40 + 25 has two int operands, so the answer is the int 65. In 40 + 25.0 one operand is a float, so Python gives back the float 65.0.

Q. Why does Python print 65.0 and not just 65?

A. Because the answer is a float, and a float is always shown with a decimal point. The extra .0 is Python telling you the type of the result, not an extra amount.

The third line shows that subtraction is quite happy to give a negative answer. 18 - 25 is -7. Nothing special has to be done for negative results.

If an operand is itself negative, put it in brackets so the line stays readable. 50 - (-6) gives 56, and the brackets make it obvious that the second operand is negative six rather than a typing slip.

leaving out the * between a number and a variable What goes wrong: A line like books_cost = 3 quantity looks reasonable on paper, but Python sees two things side by side with no operator between them and reports a syntax error. The program does not run at all. The fix: Type the operator every time — books_cost = 3 * quantity. Multiplication is never assumed.

14.2.2 Division, Floor Division and Modulus

The book fair leaves forty-seven unsold books, and they have to be packed into cartons that hold six each. Two different answers are needed here. How many full cartons will there be? And how many books will be left over after the last full carton is packed?

Ordinary division does not answer either question properly. Dividing forty-seven by six gives a number with a long decimal tail, and you cannot pack a fraction of a carton. This is why Python has three division operators instead of one.

The / operator

/ is ordinary division, the kind you do in mathematics. It gives the exact answer, decimals and all.

It also does something that surprises everybody at first: it always gives a float, even when the division comes out exactly.

what the three division operators give Problem: Show the result of /, // and % on the same kind of small whole numbers.

print(5 / 2)
print(6 / 2)
print(5 // 2)
print(7 % 4)

Output:

2.5
3.0
2
3

Look at the second line. Six divided by two is three with nothing left over, yet Python prints 3.0. This is deliberate. Python does not check each division to see whether it came out exactly; it simply promises that / always hands back a float. That way you always know the type of the result before the program runs.

The // operator

The third line uses a different operator. // performs floor division: it divides, then rounds the answer down to a whole number. Five divided by two is 2.5, and rounding 2.5 down gives 2.

NoteDefinition

(Floor division, written //, divides the left operand by the right operand and rounds the answer down to the nearest whole number.)

Q1. Why does dividing 5 by 2 in Python give 2.5, while a slightly different symbol gives 2?

A. They are two different operators. / is ordinary division and always gives the exact answer as a float, so 5 / 2 is 2.5. // is floor division: it divides and then rounds down to a whole number, so 5 // 2 is 2. Use / when you want the exact value and // when you want whole units, such as the number of full cartons.

Rounding down is not the same as chopping off the decimal part, and the difference shows up with negative numbers. -5 // 2 gives -3, because -2.5 rounded down is -3, not -2. This catches people out, so be careful when a floor division might receive a negative operand.

If either operand is a float, // still rounds down but gives a float. 7.0 // 2 gives 3.0.

Q. Is int(5 / 2) the same as 5 // 2?

A. For positive numbers, yes — both give 2. For negative numbers they differ. int() throws away the decimal part and gives -2, while // rounds down and gives -3.

The % operator

The last line of the program uses %, called the modulus operator. It divides the left operand by the right operand and gives back the remainder.

Seven divided by four is one, with three left over, so 7 % 4 gives 3. It has nothing to do with percentages, even though it borrows the percentage sign.

NoteDefinition

(The modulus operator, written %, gives the remainder left after dividing the left operand by the right operand.)

// and % are a pair. One tells you how many whole groups you can make, the other tells you what is left over. Together they answer the carton question completely.

packing 47 books into cartons of 6

Given: 47 books; 1 carton holds 6 books.

Find: the number of full cartons, and the number of books left over.

Working: 6 × 7 = 42, and 6 × 8 = 48, which is more than 47. So 7 full cartons can be packed. Books used: 42. Books remaining: 47 − 42 = 5.

7 full cartons, with 5 books left over.

packing books into cartons Problem: Work out the number of full cartons and the number of leftover books, for any number of books and any carton size.

books = 47
per_carton = 6

full_cartons = books // per_carton
left_over = books % per_carton

print("Full cartons:", full_cartons)
print("Books left over:", left_over)

Output:

Full cartons: 7
Books left over: 5

The program and the hand calculation agree, which is exactly what you should check whenever you write a small piece of arithmetic code.

Change per_carton to 8 and write down what you think the two answers will be before you run the program. Then run it and compare.

There is one number that no division operator can handle.

dividing by zero What goes wrong: If the right operand is 0, Python stops the program and reports a ZeroDivisionError. This applies to /, // and % alike, because dividing by zero has no meaningful answer. The fix: When the divisor comes from a variable or from the user, check that it is not zero before dividing. The comparison operators in 14.5 are what you use for that check.

14.2.3 The Exponent Operator

The school wants to tile a square patch of floor in the computer lab and needs to know its area. The patch is 7 metres along each side. Area means side multiplied by side, and you could of course write 7 * 7.

But a cube-shaped storage box would need 7 * 7 * 7, and a calculation with a much larger power would be unbearable to type. Repeated multiplication by the same number deserves an operator of its own.

That operator is **, the exponent operator. It raises the left operand to the power of the right operand. So 2 ** 3 means two multiplied by itself three times, which is 8.

The area of a square is written in mathematics as

\[\text{area} = \text{side}^2\]

where side is the length of one side and area is the space the square covers. The little raised 2 becomes ** 2 in Python.

area and volume of a 7-metre square patch

Given: side = 7 m.

Find: the area of the square patch, and the volume of a cube of the same side.

Working: area = 7 × 7 = 49. Volume = 7 × 7 × 7 = 49 × 7 = 343.

area = 49 m², volume = 343 m³.

area and volume from one side length Problem: Find the area of a square and the volume of a cube, both with a side of 7 metres.

side = 7

area = side ** 2
volume = side ** 3

print("Area in square metres:", area)
print("Volume in cubic metres:", volume)

Output:

Area in square metres: 49
Volume in cubic metres: 343

Both answers match the hand calculation, and both are int values because both operands of ** were whole numbers.

Powers that are not whole numbers

The right operand does not have to be a positive whole number, and this is where ** becomes more useful than plain multiplication.

fractional and negative powers Problem: Show what ** gives when the power is a fraction and when the power is negative.

print(2 ** 3)
print(4 ** 0.5)
print(2 ** -1)

Output:

8
2.0
0.5

A power of 0.5 gives the square root. 4 ** 0.5 is 2.0, because two multiplied by itself is four. A negative power gives one divided by that power, so 2 ** -1 is one divided by two, which is 0.5.

Q. Why does 4 ** 0.5 give 2.0 and not 2?

A. Because one operand, the power 0.5, is a float. By the type rule in 14.2, an answer with a float operand is a float. A negative power gives a float too, even when both operands are whole numbers.

using ^ to mean “to the power of” What goes wrong: In many textbooks and calculators, ^ means a power. In Python it is a completely different operator, so a line like 2 ^ 3 does not fail — it quietly gives 1. The program runs, and the wrong answer goes unnoticed. The fix: Use ** for powers. An error you can see is easier to fix than an answer that only looks reasonable.

14.2.4 Arithmetic Operators on Text and Lists

A printed bill is not only numbers. It has the shop’s name at the top, and a line of dashes under it to separate the heading from the items. Aarav wants his program to print both.

Neither job is arithmetic, and yet two of the operators you have just met do exactly what is needed. + and * behave differently depending on the type of their operands, and on text they do something rather useful.

Joining text with +

When both operands are strings, + does not add — it joins them end to end. Joining two strings this way is called concatenation.

"Sun" + "rise" produces "Sunrise". Nothing is inserted between them, so if you want a space you have to supply it yourself as a string of its own.

Q. Does "Sunrise" + "School" come out with a space in the middle?

A. No. It gives SunriseSchool. Python joins exactly what you give it, so the space has to be added: "Sunrise" + " " + "School".

Repeating text with *

When one operand is a string and the other is a whole number, * repeats the string that many times. "ab" * 3 gives "ababab".

That is the neat way to draw a dividing line. Instead of typing twenty dashes and hoping you counted right, you write "-" * 20 and let Python count.

heading for the book fair bill Problem: Print the shop name with a line of dashes above and below it.

school = "Sunrise"
kind = "Public School"

full_name = school + " " + kind
line = "-" * 20

print(line)
print(full_name)
print(line)

Output:

***
Sunrise Public School
***

The number must be a whole number. "-" * 20.0 is not allowed, because Python cannot repeat something twenty-point-zero times.

Joining lists

A list behaves the same way. + joins two lists into one longer list, and * repeats a list.

Suppose a class has two subjects before the break and two after it, kept in separate lists. One operator puts the whole day together.

joining two lists of subjects Problem: Combine the morning subjects and the afternoon subjects into a single list for the day.

morning = ["Science", "Maths"]
afternoon = ["English", "Computer"]

full_day = morning + afternoon
print(full_day)

Output:

['Science', 'Maths', 'English', 'Computer']

The items stay in order, with the second list’s items placed after the first list’s items.

What does not work

Only + and * behave this way. There is no sensible meaning for subtracting one piece of text from another, so "Science" - "ence" is not allowed, and neither is dividing a string. Python stops the program with a TypeError, which is its way of saying that an operator has been given operand types it cannot work with.

Mixing a string with a number in an addition fails for the same reason.

adding a value typed by the user without converting it What goes wrong: input() always gives back a string, even when the user types digits. So if two typed numbers are stored as they arrive and then joined with +, the strings "5" and "3" give 53 instead of 8. If one of the two is a number and the other is a string, the program stops with a TypeError instead. The fix: Convert the input before doing arithmetic with it — marks = int(input("Enter your marks:")). After the conversion, + adds as expected.

The wider lesson is worth remembering for the whole chapter. An operator does not have one fixed meaning. What it does depends on the types of the operands it is given.

14.3 Logical Operators

At the book fair counter, the free bookmark is not given to everybody. It goes to a buyer whose bill has crossed the limit and who is on the members list. Two conditions, both of which must hold.

Real decisions are usually like this. A school lets a student sit the sports trial if the medical form is signed and the fee is paid. A robot moves forward if the path ahead is clear or the sensor has been switched off for testing. A single yes-or-no fact is rarely enough.

Python stores a yes-or-no fact as one of two special values, True and False. You met these earlier as Boolean values. A condition in a program is simply something that works out to True or False.

The operators that combine such values are called logical operators. There are three of them: and, or and not.

NoteDefinition

(A logical operator combines or reverses True and False values, so that a program can make a decision based on more than one condition.)

Notice that all three are ordinary English words rather than symbols. They are still operators, exactly as + is, and they are written in lower case. Python will not accept AND or And.

Q. Where do the True and False values come from in a real program?

A. Usually from a comparison, such as checking whether the total is above a limit. Those comparisons are covered in 14.5. In this section the values are written as True and False directly, so that the attention stays on what the logical operators do with them.

The three sub-sections below take one operator each. In every case the question to keep in mind is the same: given these True and False values coming in, what single True or False value comes out?

14.3.1 The and Operator

The bookmark rule at the counter has two parts, and both have to be satisfied. A bill above the limit is not enough on its own. Being on the members list is not enough on its own either.

and is the operator for exactly this situation. It looks at the value on its left and the value on its right, and gives True only when both of them are True. In every other case it gives False.

That is a strict rule, and it matches the way a careful shopkeeper thinks. One missing condition and the answer is no.

does this buyer get a free bookmark? Problem: The bookmark is given only if the bill is above the limit and the buyer is on the members list. Work out the answer for a buyer whose bill is above the limit but who is not a member.

above_limit = True
is_member = False

gets_bookmark = above_limit and is_member
print("Free bookmark:", gets_bookmark)

Output:

Free bookmark: False

The buyer met one condition out of two, and and still answered False. Change is_member to True and the same line would give True.

There are only four possible combinations of two Boolean values, so the whole behaviour of and fits in a short program.

and for all four combinations Problem: Show what and gives for every pair of True and False values.

print(True and True)
print(True and False)
print(False and True)
print(False and False)

Output:

True
False
False
False

Table 14.2 sets out the same four results in the form that is easier to look up later.

Table 14.2 – the result of and for every combination of two Boolean values | Left operand | Right operand | Result | |—|—|—| | True | True | True | | True | False | False | | False | True | False | | False | False | False |

Only the first row gives True. This is the quickest way to remember and: one True out of four.

Q2. How can a program check two things at the same time, such as “the bill is above the limit and the buyer is a member”?

A. By joining the two conditions with the logical operator and. Python works out each condition separately, then and combines the two answers into one. The combined answer is True only when both conditions are True, so the bookmark is given only to a buyer who satisfies both.

Q. Can more than two conditions be joined?

A. Yes. You can write a and b and c and add as many as you need. With and, every single one of them must be True for the whole expression to be True.

using and the way it is used in everyday speech What goes wrong: A notice may say “students of class 9 and class 10 may enter the lab”. In speech that means either class. Written as a program condition with and, it asks for a student who is in class 9 and in class 10 at the same time, which is impossible, so the answer is always False. The fix: Ask yourself whether one thing must be true, or both. If one is enough, the operator you want is or, which comes next.

14.3.2 The or Operator

The reading room next to the book fair has a different rule. A student may go in if they are a library member, or if they have been given a day pass for the fair. Either one is enough. A student with both is welcome too.

or is the operator for a rule of that shape. It gives True when at least one of its two operands is True. It gives False only in the one case where both are False.

Where and is strict, or is generous.

may this student enter the reading room? Problem: Entry is allowed to a library member or to a student holding a day pass. Work out the answer for a student who is not a member but does have a day pass.

is_member = False
has_day_pass = True

may_enter = is_member or has_day_pass
print("May enter:", may_enter)

Output:

May enter: True

One condition out of two was enough. Had the same two values been joined with and, the answer would have been False, which is a good reminder that the operator you choose decides the rule.

or for all four combinations Problem: Show what or gives for every pair of True and False values.

print(True or True)
print(True or False)
print(False or True)
print(False or False)

Output:

True
True
True
False

Table 14.3 shows the same four results together.

Table 14.3 – the result of or for every combination of two Boolean values | Left operand | Right operand | Result | |—|—|—| | True | True | True | | True | False | True | | False | True | True | | False | False | False |

Only the last row gives False. That is the mirror image of and, and it is the easiest way to hold the two apart: and needs everything, or needs anything.

Q. What does or give when both operands are True?

A. True. “At least one” includes the case where both are true, so having a membership card and a day pass does not stop a student from entering.

expecting or to mean “one or the other, but not both” What goes wrong: In everyday speech, “would you like tea or coffee” offers a choice between the two. The Python or does not work that way. If both operands are True, the result is still True, so a condition written to allow exactly one of two things will quietly allow both. The fix: Use or when at least one condition being true is acceptable. If a program must reject the case where both are true, that extra restriction has to be written out separately.

14.3.3 The not Operator

Some rules are written the other way round. The office sends a fee reminder to a student whose fee has not been paid. A robot stops when the path ahead is not clear.

In both cases the program already has the fact it needs, but it needs the opposite of it. Turning True into False, and False into True, is the job of not.

not is unusual in taking a single operand. It is written in front of that operand, with nothing on its left.

who gets a fee reminder? Problem: A reminder is sent to a student whose fee is not yet paid. Work out whether a reminder should be sent for a student whose fee is unpaid.

fee_paid = False

send_reminder = not fee_paid
print("Send reminder:", send_reminder)

Output:

Send reminder: True

There are only two values for not to work on, so its complete behaviour fits in Table 14.4.

Table 14.4 – the result of not for each Boolean value | Operand | Result | |—|—| | True | False | | False | True |

Q. After that program runs, has fee_paid changed to True?

A. No. not produces a new value and leaves its operand alone. fee_paid is still False; the reversed value was stored in a different variable.

Where not acts

When not appears in a longer expression, it matters how much of the expression it applies to. not acts on the value immediately to its right, and nothing more.

not with and without brackets Problem: Compare not applied to one value with not applied to a whole condition.

above_limit = True
is_member = False

print(not above_limit and is_member)
print(not (above_limit and is_member))

Output:

False
True

The two lines contain the same three pieces and give opposite answers. In the first line, not reverses above_limit alone, giving False, and False and False is False. In the second line the brackets are worked out first, so not reverses the combined result False, giving True.

The order in which Python works through an expression like this is set out fully in 14.8. Until then, brackets are the safe way to say exactly what you mean, and they cost nothing.

writing ! instead of not What goes wrong: Several other programming languages use ! for “not”. Python does not. A line such as send_reminder = !fee_paid will not run; the program stops with a syntax error before doing anything. The fix: Write the word not. The ! character does appear in Python, but only as part of !=, which is a comparison operator and means something quite different.

14.4 Assignment Operators

Every program so far has quietly used one operator without naming it. Lines such as price = 180 and books_cost = price * quantity all contain an equals sign, and that sign is doing real work.

Think about the counter again. Neha keeps a running total on a slip of paper. Each time a book is scanned she crosses out the old total and writes the new one. The slip always holds one value, and that value keeps being replaced.

A variable is that slip of paper, and the assignment operator is the act of writing on it.

NoteDefinition

(The assignment operator, written =, stores the value on its right into the variable named on its left.)

The direction matters and it is always right to left. Python first works out whatever is on the right, then puts that result into the variable on the left. This is why books_cost = price * quantity makes sense: the multiplication happens first, and only the finished answer is stored.

Q. Is = an operator in the same way that + is?

A. It is an operator, but it is used differently. + produces a value you can print. = does not produce a value to print — its job is to store one. So you can write print(8 + 5), but not print(x = 5).

Python also has a set of shorter assignment operators that update a variable using the value it already holds. They are handy for exactly the running-total job that the slip of paper does. The two sub-sections below cover the plain assignment operator first, then that shorter family.

14.4.1 The Assignment Operator

The simplest use of = is to put a value into a variable for the first time.

x = 50

After this line runs, the variable x holds 50, and the rest of the program can use x wherever it needs that value. The value can be of any type: a whole number, a decimal, a piece of text, a Boolean value, or a list.

The name always goes on the left and the value on the right. Writing 50 = x is not allowed, because Python would be asked to store something into the number fifty.

Giving a variable a new value

A variable does not hold one value for ever. Assign to it again and the new value replaces the old one, which is then gone. See Fig. 14.4-1.

Diagram

Fig. 14.4-1 – a labelled box named total shown twice, side by side; in the first box the value 180, in the second box the value 300 with a small arrow between the two boxes labelled “total = total + 120”; the old value shown faded to indicate it has been replaced

This is what makes a running total possible. The counter’s slip of paper never holds two totals at once.

a running total at the billing counter Problem: Start with the cost of the first book and then add the cost of a second book, keeping one total.

total = 180
print("Total now:", total)

total = total + 120
print("Total now:", total)

Output:

Total now: 180
Total now: 300

The middle line is the one worth staring at. In mathematics, total = total + 120 would be nonsense, because no number equals itself plus 120. In Python it is an instruction rather than a statement of fact.

Q. How can total = total + 120 possibly work?

A. Because the right side is worked out first, using the value the variable holds at that moment. total is 180, so the right side gives 300. Only then is 300 stored back into total, replacing the 180.

Reading such a line from right to left, out loud, usually clears it up: “take the current total, add 120, and put the answer back into total”.

using a variable before any value has been assigned to it What goes wrong: If a line uses a variable that has never appeared on the left of an =, Python stops with a NameError, saying the name is not defined. A spelling slip does the same thing — totl and total are two different names as far as Python is concerned. The fix: Assign a starting value before the variable is used. A running total normally starts at 0, on a line of its own, before anything is added to it.

14.4.2 Augmented Assignment Operators

Look at that running-total line once more.

total = total + 120

The name total is typed twice, and it must be spelt the same way both times. In a program that adds twenty books to a bill, that name gets typed forty times, and any one of them could be mistyped.

Python offers a shorter way of writing the same instruction. These shorter forms are called augmented assignment operators. Each one joins an arithmetic operator to the = sign.

total += 120 means exactly what total = total + 120 means: take the value in the variable, add 120 to it, and store the answer back. The variable name is written only once.

There is one for each arithmetic operator, as Table 14.5 shows.

Table 14.5 – the augmented assignment operators and the longer form each one stands for | Operator | Example | Same as | |—|—|—| | += | x += 3 | x = x + 3 | | -= | x -= 3 | x = x - 3 | | *= | x *= 3 | x = x * 3 | | /= | x /= 3 | x = x / 3 | | //= | x //= 3 | x = x // 3 | | %= | x %= 3 | x = x % 3 | | **= | x **= 3 | x = x ** 3 |

building up a bill with augmented assignment Problem: Start the bill at zero, add two books, then take off a fifty-rupee discount.

total = 0

total += 180
total += 120
print("Total:", total)

total -= 50
print("After discount:", total)

Output:

Total: 300
After discount: 250

The first line still uses plain =, and it has to. An augmented operator uses the value already in the variable, so the variable must hold something before the first += runs. Starting a total at 0 is the usual way to arrange that.

Q. Does total += 120 do anything that total = total + 120 does not?

A. For the values in this chapter, no — the result is the same. The short form is there to save typing and to make the intention clear at a glance: this line is updating a variable, not creating a new one.

Because += follows whatever + does, it works on text as well. If line holds a piece of text, line += " paid" adds those characters to the end of it, in the same way that + joined strings in 14.2.4.

typing =+ instead of += What goes wrong: The two characters are easy to swap, and swapping them does not cause an error. total =+ 120 is read by Python as “store positive 120 into total”, so the running total is thrown away and replaced by 120. The program runs, the bill is wrong, and nothing on the screen says so. The fix: Check the order of the characters. The arithmetic operator comes first and the = sign comes second, in every operator in Table 14.5.

14.5 Comparison Operators

The logical operators in 14.3 all needed True and False values to work on, and those values were simply typed in. A real program cannot do that. Nobody sits beside the counter deciding whether the bill has crossed the limit; the program has to find that out for itself.

Finding it out means comparing two values. Is the total greater than the limit? Is the quantity equal to zero? Is today’s date the same as the last date of the fair?

A comparison operator compares its two operands and answers with a single Boolean value.

NoteDefinition

(A comparison operator compares two values and gives back True if the comparison holds, and False if it does not.)

There are six of them, listed in Table 14.6. Four will be familiar from mathematics; the other two are written differently from what you may expect.

Table 14.6 – the six comparison operators and what each one asks | Operator | Asks whether | |—|—| | == | the two values are equal | | != | the two values are not equal | | > | the left value is greater than the right | | < | the left value is less than the right | | >= | the left value is greater than or equal to the right | | <= | the left value is less than or equal to the right |

Q. What type of value does a comparison produce?

A. Always a Boolean — True or False, and nothing else. It does not matter whether the operands are numbers, text or something else; the answer is one of those two values.

This is what makes comparison and logical operators natural partners. A comparison produces a Boolean value, and a logical operator combines Boolean values. Together they let a program work out a rule as complicated as the bookmark rule from a set of plain facts.

14.5.1 Equal To and Not Equal To

Two operators in this group cause more confusion than all the others together, and both of them involve an equals sign.

= is an order. It tells Python to store a value in a variable.

== is a question. It asks whether two values are the same, and the answer comes back as True or False. Nothing is stored and nothing is changed.

The double sign exists precisely because the single one was already taken.

has the buyer paid the right amount? Problem: Check whether the amount handed over is equal to the bill, and also whether it is different from the bill.

bill = 250
paid = 250

print("Amount matches:", paid == bill)
print("Amount differs:", paid != bill)

Output:

Amount matches: True
Amount differs: False

!= asks the opposite question: are these two values not equal? The ! in front of the = is Python’s way of writing “not”, and this is the only place it is used. For any pair of values, == and != always give opposite answers.

Q3. What is the difference between = and == in Python?

A. = is the assignment operator. It stores the value on its right into the variable on its left, and changes what that variable holds. == is a comparison operator. It compares the values on either side and gives back True or False, changing nothing. So paid = 250 sets the amount paid, while paid == 250 asks whether the amount paid happens to be 250.

writing = where a comparison is meant What goes wrong: A line such as if paid = bill: looks like a reasonable question, but it is an order in the middle of a place where Python expects a question. The program stops with a syntax error and refuses to run. The fix: Use == for every comparison. If the line is asking something rather than setting something, it needs the double sign.

Comparing values of different kinds

Equality compares the values, not the way they are written. A whole number and a decimal that stand for the same amount are counted as equal.

Q. Is 5 == 5.0 True?

A. Yes. The int 5 and the float 5.0 are different types, but they stand for the same amount, so == gives True.

Text is compared character by character, and capital letters are not the same as small ones.

comparing two pieces of text Problem: Check whether two subject names that differ only in a capital letter count as equal.

print("Science" == "science")
print("Science" == "Science")

Output:

False
True

This matters whenever a program compares something a person has typed. A student who enters science instead of Science has, as far as == is concerned, entered a different word altogether.

14.5.2 Greater Than and Less Than

The bookmark rule has a number in it. The bill must cross ₹500. Equality is no use here, because a bill of ₹620 should qualify even though it is not equal to anything in particular.

Four operators handle questions of size. > asks whether the left value is greater than the right, and < asks whether it is smaller. Both are written exactly as in mathematics.

The other two allow the two values to be equal as well. >= asks whether the left value is greater than or equal to the right, and <= asks whether it is less than or equal. The equals sign always comes second; => is not a Python operator.

Writing the bookmark rule at last

With comparison and logical operators together, the rule from the chapter opener can finally be written as it actually is.

deciding whether a buyer gets a free bookmark Input: the bill total, the limit for the offer, and whether the buyer is on the members list. Output: True if the bookmark is to be given, False otherwise. Steps:

1. Compare the total with the limit to see whether the total is greater.
2. Take the members-list fact as it stands.
3. Combine the two answers with and.
4. Give the combined answer as the result.

Why it works: The offer has two conditions and both must hold, so the comparison supplies one Boolean value, the members list supplies the other, and and is True only when both are.

the free bookmark rule Problem: Decide whether a buyer with a bill of ₹620, who is on the members list, gets a free bookmark when the limit is ₹500.

total = 620
limit = 500
is_member = True

above_limit = total > limit
gets_bookmark = above_limit and is_member

print("Above the limit:", above_limit)
print("Free bookmark:", gets_bookmark)

Output:

Above the limit: True
Free bookmark: True

Splitting the rule across two lines is not necessary — both could be written as one long expression — but a program that names its middle results is far easier to check when something goes wrong.

The value on the boundary

The difference between > and >= shows up in exactly one place: when the two values are equal.

a total sitting exactly on the limit Problem: Show what > and >= give when the total is exactly equal to the limit.

print(500 > 500)
print(500 >= 500)

Output:

False
True

So the choice of operator decides a real question about the offer. Does a bill of exactly ₹500 earn the bookmark or not? If the notice says “above ₹500”, the program should use >. If it says “₹500 or more”, it should use >=.

Q. The notice says the offer applies to bills of at least ₹500. Which operator is right?

A. >=. “At least” includes the value itself, so a bill of exactly ₹500 must qualify.

leaving out the operand the second time What goes wrong: A range such as “between 500 and 800” is often written as total > 500 and < 800. Each operator needs an operand on both sides, and the second comparison has been left with nothing on its left, so the program stops with a syntax error. The fix: Write the variable out again — total > 500 and total < 800. Python also accepts the shorter 500 < total < 800, which means the same thing.

14.5.3 Comparing Different Data Types

Comparison operators are not only for numbers. A program that arranges a class list needs to know whether one name comes before another, and that is a comparison too.

Numbers of different types compare without any trouble. A whole number and a decimal both stand for an amount, so Python simply compares the amounts. 7 < 7.5 is True.

Text is compared in dictionary order, one character at a time. Python looks at the first character of each string; if they differ, that settles the answer. If they are the same, it moves on to the second character, and so on.

Each character has a number code stored inside the computer, and the comparison really works on those codes. The codes run in alphabetical order, which is why dictionary order comes out correctly. But all the capital letters have smaller codes than all the small letters, and that produces one result people do not expect.

comparing numbers and text Problem: Show how < behaves on numbers of different types, on two names, and on a capital letter against a small letter.

print(7 < 7.5)
print("Anita" < "Bhavya")
print("Zebra" < "apple")

Output:

True
True
True

The second line is ordinary alphabetical order: A comes before B. The third line says that "Zebra" comes before "apple", which no dictionary would agree with. It happens because a capital Z has a smaller code than a small a, and Python never got past the first character.

Q. How can a program compare names fairly whatever way they are typed?

A. Convert both to the same case before comparing, using .lower() on each string. Then "Zebra".lower() and "apple".lower() are compared as ordinary words.

When the types do not fit

Not every pair of values can be compared. Asking whether a piece of text is greater than a number has no meaning, so "5" > 3 stops the program with a TypeError.

Equality is more forgiving. It does not fail; it simply answers False.

text that looks like a number Problem: Check whether the string "5" counts as equal to the number 5.

print("5" == 5)

Output:

False

The two are of different types, and no amount of similarity on the screen changes that. This is the same trap as the one in 14.2.4: a value that came from input() is text until it is converted, so comparing it with a number will quietly answer False every time.

Boolean values can be compared with numbers, and Python treats True as 1 and False as 0. So True == 1 gives True. This is a leftover from the days when a yes-or-no answer was stored as a single 1 or 0.

A program that matches a person’s name against a stored record using == will reject anything that is not character-for-character identical, including a difference of capitals or an extra space. In a school system that could mean a real student being refused a scholarship form. When a comparison decides something about a person, tidy up the text on both sides first, and give the person a way to correct a record rather than only a message saying no match was found.

14.6 Identity Operators

Two students in the same class own the same novel. The books have the same cover, the same pages, the same words. They are equal in every way that matters to a reader, but they are still two separate books. If one student writes a note in the margin, the other student’s copy is unaffected.

Now imagine instead that one book is shared, and both students have written their names in the same copy. That is a different situation altogether. A note written by one is seen by the other, because there is only one book.

Python keeps track of the same difference. == asks whether two values are equal. An identity operator asks something stricter: whether two names refer to the very same object stored in memory.

NoteDefinition

(An identity operator checks whether its two operands refer to the same object in memory, rather than whether their values are equal.)

There are two of them. is gives True when both operands refer to the same object. is not gives True when they do not.

equal values that are not the same object Problem: Build two lists with the same contents, and a third name for one of them. Compare them by value and by identity.

list_a = [1, 2, 3]
list_b = [1, 2, 3]
list_c = list_a

print(list_a == list_b)
print(list_a is list_b)
print(list_a is list_c)

Output:

True
False
True

The first line says the two lists hold the same items, which they do. The second line says they are not the same object, which is also correct: two separate lists were built, one on each line, and they happen to match.

The third line is different. No new list was built there. list_c = list_a gave a second name to the list that already existed, so both names refer to one object. See Fig. 14.6-1.

Diagram

Fig. 14.6-1 – three labelled name tags on the left, list_a, list_c and list_b; arrows from list_a and list_c both pointing to a single box containing 1, 2, 3; a separate arrow from list_b pointing to a second, identical box containing 1, 2, 3

This is not a fine point of no consequence. Because list_a and list_c refer to one list, adding an item through either name changes what both names show. list_b would stay as it was.

Q. Can two values be equal without being identical?

A. Yes, and the program above shows it. list_a and list_b are equal, because their contents match, but they are not identical, because they are two separate objects.

Table 14.7 – == vs is | Feature | == | is | |—|—|—| | What it asks | Are the two values equal? | Are these the same object in memory? | | Answer for two separate lists holding 1, 2, 3 | True | False | | Answer for two names given to one list | True | True | | Normal use | Comparing values in a program | Checking whether two names refer to one object |

using is where == is meant What goes wrong: is sometimes gives the answer you were hoping for when comparing plain numbers or short pieces of text, because Python may store one copy of a value and reuse it. The same comparison with different values can then give False, and a program that seemed to work starts failing for no visible reason. The fix: Use == whenever you are comparing values, which is nearly always. Keep is for the rare occasion when the question really is about two names referring to one object.

14.7 Membership Operators

The last thing Neha does for every buyer is run her finger down the members list, looking for the name. It is the slowest part of the sale, and it is the part a computer is best at.

You could write this check with the operators you already have: compare the name with the first entry, then with the second, then with the third. For a list of two hundred members that is two hundred comparisons, and you would have to write a loop to do it.

Python has an operator that does the whole search in one go. It is called a membership operator, because it asks whether a value is a member of a sequence.

NoteDefinition

(A membership operator checks whether a value appears inside a sequence such as a list, a tuple or a string.)

There are two. in gives True when the value is found. not in gives True when it is not.

is this buyer on the members list? Problem: Check whether a buyer’s name appears on the members list, and whether a name that is absent is reported correctly.

members = ["Anita", "Rohan", "Farida", "Meera"]
buyer = "Rohan"

print(buyer in members)
print("Kabir" in members)
print("Kabir" not in members)

Output:

True
False
True

One short line replaced the whole finger-down-the-list search, and it works just as well for four names as for four hundred.

Q4. How can a program find out whether a name appears in a list without checking every item one by one?

A. By using the membership operator in. Writing buyer in members gives True if the name is somewhere in the list and False if it is not. Python still looks through the list internally, but you do not have to write that search yourself — one operator does the whole job.

Q. Does in tell you where in the list the name was found?

A. No. It answers only True or False. If the position matters, you need a different tool; in is for the yes-or-no question alone.

Membership in text

A string is a sequence of characters, so in works on text as well. There it asks whether one piece of text appears inside another.

searching inside a piece of text Problem: Check whether a shorter piece of text appears inside a subject name, and what happens when the capital letter does not match.

print("Sci" in "Science")
print("sci" in "Science")
print("Computer" not in "Science")

Output:

True
False
True

The second line is False for the same reason as in 14.5.1: a capital S and a small s are different characters. Membership is exact.

The same operator works on a tuple, which is a sequence like a list but one whose items cannot be changed after it is created.

Add your own name to the members list in the first program and run it again. Then change buyer to a name that is in the list but typed all in small letters, and see what in reports.

expecting in to search a dictionary’s values What goes wrong: A dictionary stores pairs, each with a key and a value. Writing "Rohan" in marks searches only the keys of the dictionary marks, not the values stored against them. A program looking for a mark rather than a name will always be told False. The fix: Remember that in searches keys when it is given a dictionary. Search the values only when that is what you actually want, using "Rohan" in marks.values().

14.8 Operator Precedence

In 14.2.1 the bill was worked out in two separate lines, one for the books and one for the bag charge. Written as a single line it would look like this:

total = 180 * 3 + 10

Two operators, one line. Python has to decide which one to do first, and the two choices give very different bills. Multiplying first gives 550. Adding first gives 2340.

The order in which Python works through the operators in an expression is called operator precedence. It is not a matter of guessing; the order is fixed, and it is the same order you already use in arithmetic.

NoteDefinition

(Operator precedence is the fixed order in which Python works out the operators in an expression when more than one is present.)

the same numbers, two different answers Problem: Show the effect of precedence, and how brackets change it.

print(180 * 3 + 10)
print(180 * (3 + 10))

Output:

550
2340

The first line follows the normal precedence: multiplication is done before addition, so 540 is worked out first and 10 is added to it. In the second line the brackets force the addition to happen first, and 180 is then multiplied by 13.

Brackets sit at the top of the order. Anything inside them is worked out before it is used anywhere else.

The full order

Table 14.8 lists the operators of this chapter from the one Python does first to the one it does last.

Table 14.8 – the operators of this chapter, from highest precedence to lowest | Order | Operators | |—|—| | 1 | ( ) brackets | | 2 | ** | | 3 | *, /, //, % | | 4 | +, - | | 5 | ==, !=, >, <, >=, <=, is, is not, in, not in | | 6 | not | | 7 | and | | 8 | or |

Two things in the table are worth noticing. All the comparison, identity and membership operators sit together on one level, and all of them come before the logical operators. That is exactly what a condition such as total > limit and is_member needs: both comparisons finish first, and and then combines their answers.

The three logical operators are not on one level either. not acts first, then and, then or. This explains the two lines from 14.3.3, and it shows up again here.

precedence among the logical operators Problem: Show that and is worked out before or, and how brackets change the result.

print(True or False and False)
print((True or False) and False)

Output:

True
False

In the first line, False and False is worked out first, giving False, and True or False then gives True. The brackets in the second line reverse the order, and the answer flips.

Q5. When one line of a program has several symbols in it, which symbol does Python work out first?

A. Python follows a fixed order called operator precedence, shown in Table 14.8. Brackets are worked out first, then **, then multiplication and division, then addition and subtraction, then the comparison, identity and membership operators, and last of all not, and and or. Where two operators sit on the same level, Python works from left to right.

When two operators are on the same level, Python works through them from left to right. So 20 - 8 - 5 gives 7, because the first subtraction is done first.

There is one operator that goes the other way. ** is worked out from right to left, so 2 ** 3 ** 2 means 2 ** 9, which is 512, and not 8 ** 2, which would be 64.

Q. If precedence is fixed, is there any point in using brackets?

A. Yes. Brackets cost nothing and they show the reader what you meant. A line whose meaning has to be checked against a table is a line that will be misread one day.

assuming Python works from left to right What goes wrong: An average written as total_marks = maths + science + english / 3 gives a wrong answer that looks plausible. Division has higher precedence than addition, so only the English mark is divided by three, and the other two are added to that result at full value. The fix: Put the addition in brackets — (maths + science + english) / 3. Whenever an expression mixes operators from different rows of Table 14.8, read it once more before trusting it.

14.9 Kinds of Statements in Python

Everything in this chapter has been built out of expressions — pieces of code that produce a value. But an expression on its own is not yet a program. 180 * 3 produces 540 and then, unless something is done with it, that 540 goes nowhere.

What a program is really made of is statements. A statement is one complete instruction that Python can carry out.

NoteDefinition

(A statement is a complete instruction that Python can execute, such as storing a value, printing something, or making a decision.)

An expression is usually a part of a statement. In total = 180 * 3, the expression is 180 * 3 and the statement is the whole line, which works out that expression and stores the result.

Q. Is total = 250 an expression?

A. No, it is a statement. Expressions produce a value; statements carry out an instruction. That is why print(total = 250) does not work, as 14.4 mentioned.

The kinds you will meet

Python has several kinds of statements, and Table 14.9 sets out the ones that make up a Class 9 program. Two of them you have already been writing all through this chapter. The rest are taken up in the chapters that follow.

Table 14.9 – kinds of statements in Python, with an example of each | Kind of statement | Example | What Python does | |—|—|—| | Assignment | total = 250 | Stores a value in a variable | | Augmented assignment | total += 50 | Updates a variable using its current value | | Expression | print("Total:", total) | Works out an expression, usually a call to a function | | Conditional | if total > 500: | Chooses whether to run a block of lines | | Loop | while count < 10: | Repeats a block of lines | | Function definition | def show_bill(): | Gives a name to a block of lines for later use |

The last three are different in shape from the first three. Each has a header line that ends in a colon, followed by an indented block of lines underneath it. A statement built this way is often called a compound statement, because it contains other statements inside it. Conditional and loop statements are covered in the next chapter, and function definitions in the one after that.

A line that does nothing

An expression can stand alone as a statement. Python will work it out — and then throw the answer away.

an expression with nothing done to it Problem: Show what happens when an expression is written on a line by itself in a program file.

250 + 100
print(250 + 100)

Output:

350

Both lines were carried out. The first one added the numbers and discarded the result, so nothing appeared. Only the second line, which passes the value to print(), produced anything on the screen.

expecting a calculation to appear on the screen by itself What goes wrong: A line such as total * 2 in a program file computes the answer and throws it away. Nothing is printed and no error is reported, so the program looks as though it has skipped a step. The fix: Do something with the value. Either store it in a variable, or pass it to print(). Note that Python’s interactive prompt behaves differently and does display the value of a bare expression, which is why the same line seems to work there and fail in a saved program.

Comments are the one thing in a program file that is not a statement at all. Anything after a # on a line is ignored by Python entirely; it is there for the person reading the program.

Every statement in Table 14.9 leans on the operators from this chapter. An assignment needs =. A conditional needs a comparison. A loop usually needs both a comparison and an augmented assignment to move it along. That is why operators come first, and why the next chapter can move straight on to making decisions.

14.10 Summary

  1. An operator is a symbol or keyword that tells Python to perform an operation. The values it works on are called operands, and a combination of values, variables and operators that produces a single value is called an expression.
  2. Arithmetic operators do calculations. Python has seven of them: +, -, *, /, //, % and **.
  3. If both operands of an arithmetic operator are whole numbers, the answer is a whole number. If either operand is a decimal, the answer is a decimal.
  4. / is ordinary division and always gives a decimal answer. // is floor division: it divides and rounds down to a whole number. % gives the remainder after division. Dividing by zero stops the program.
  5. ** raises a number to a power. A power of 0.5 gives a square root, and a negative power gives a decimal answer.
  6. The meaning of an operator depends on the types of its operands. On text and lists, + joins and * repeats.
  7. Logical operators combine yes-or-no values. and gives True only when both operands are True; or gives True when at least one is; not reverses a single value.
  8. The assignment operator = stores the value on its right into the variable on its left. The right side is always worked out first.
  9. Augmented assignment operators such as += and *= update a variable using the value it already holds, writing the variable’s name only once.
  10. Comparison operators compare two values and always answer True or False. There are six: ==, !=, >, <, >= and <=.
  11. = stores a value; == asks whether two values are equal. Comparisons on text are exact, so capital and small letters are treated as different.
  12. Identity operators, is and is not, ask whether two names refer to the same object in memory. Two separate objects can be equal without being identical.
  13. Membership operators, in and not in, check whether a value appears inside a sequence such as a list, a tuple or a string.
  14. Operator precedence is the fixed order in which Python works out an expression: brackets first, then **, then multiplication and division, then addition and subtraction, then the comparison, identity and membership operators, then not, and and or. Brackets make the intended order plain.
  15. A statement is one complete instruction. Assignment, augmented assignment and expression statements were used throughout this chapter; conditional statements, loops and function definitions are built the same way and come later.

14.11 Key Terms

  1. Arithmetic operator: an operator that performs a calculation, such as +, -, *, /, //, % or **.
  2. Assignment operator: the = sign, which stores the value on its right into the variable named on its left.
  3. Augmented assignment: a shorter assignment operator such as += or *= that updates a variable using the value it already holds.
  4. Comparison operator: an operator that compares two values and gives back True or False.
  5. Concatenation: joining two pieces of text end to end using the + operator.
  6. Exponent operator: the ** operator, which raises the left operand to the power of the right operand.
  7. Expression: a combination of values, variables and operators that Python evaluates to produce a single value.
  8. Floor division: division using //, which divides and then rounds the answer down to a whole number.
  9. Identity operator: is or is not, which checks whether two operands refer to the same object in memory.
  10. Logical operator: and, or or not, which combines or reverses True and False values.
  11. Membership operator: in or not in, which checks whether a value appears inside a sequence such as a list, a tuple or a string.
  12. Modulus: the % operator, which gives the remainder left after dividing the left operand by the right operand.
  13. Operand: a value or variable that an operator works on.
  14. Operator: a symbol or keyword that tells Python to perform an operation on one or more operands.
  15. Operator precedence: the fixed order in which Python works out the operators in an expression when more than one is present.
  16. Statement: one complete instruction that Python can execute, such as storing a value, printing something or making a decision.

14.12 Objective Questions

  1. (What is the value of 7 // 2 in Python?)

    1. 3.5
    2. 3
    3. 4
    4. 3.0
  2. (Fill in the blank: The operator that gives the remainder left after a division is called the ________ operator.)

  3. (State whether true or false: In Python, the expression 5 == 5.0 gives True.)

  4. (Which operator checks whether a value appears inside a list?)

    1. is
    2. in
    3. ==
    4. and
  5. (Match each operator in Column A with the correct description in Column B.)

    Column A Column B
    a. ** i. Reverses a True or False value
    b. != ii. Updates a variable using the value it already holds
    c. += iii. Raises a number to a power
    d. not iv. Checks whether two values are different
  6. (What will the following line display? print("ab" * 3))

  7. (What will the following line display? print(2 + 3 * 4))

14.13 Concept Questions

  1. (Define the terms operand and expression. Give one example of each.)

  2. (Differentiate between = and ==, using one example of each.)

  3. (Explain the difference between the / operator and the // operator. Give one example that shows how their results differ.)

  4. (Give a reason why 4 ** 0.5 gives 2.0 and not 2.)

  5. (Differentiate between == and is. Describe one situation in which two values are equal but not identical.)

  6. (What would happen if the line total = total + 120 were run before any value had been stored in total? Name the error Python would report and state how it can be avoided.)

  7. (Write a Python program that stores the price of one notebook and the number of notebooks bought, adds a packing charge of ₹15, and prints the amount to be paid.)

14.14 Case-Based Questions

  1. (The canteen at a school has started a token counter run by two students of Class 9. The prices are given in the table below.)

    Item Price
    Samosa ₹15
    Sandwich ₹40
    Juice ₹25

    (A student buys two samosas and one juice. The canteen gives a free bottle of water to anyone whose bill comes to ₹100 or more.)

    1. Write a Python statement that uses arithmetic operators to work out this student’s total and store it in a variable named total.
    2. Write the condition the program should use to decide whether the free water bottle is given, and state which comparison operator you have chosen and why. Does this student qualify?
    3. The number of samosas is read from the user with input() and used in the calculation without being converted. Explain what goes wrong, and give the correction.
  2. (The school library keeps a list of the students who have taken membership this term.)

members = ["Anita", "Rohan", "Farida", "Meera"]

(A reader is allowed to keep a book for an extra week if the reader is a member and has no pending fine.)

  1. Write a Python statement that uses a membership operator to check whether a reader named reader is on the list.
  2. The variable has_fine holds True when a fine is pending. Write the condition that decides whether the extra week is allowed, and name the logical operators you have used.
  3. A genuine member types her name as anita at the counter, and the program reports that she is not a member. Explain why this happens, and suggest how the program should handle names typed by a person.