for, while, range, break: judging a whole inbox
Introduction to Data Science and Machine Learning · Md Mahbub E Noor · University of Barishal
for msg in inbox:
if "free" in msg.lower():
print("SPAM?", msg)i changes each roundfor i in range(1, 6):
print(f"Message {i} checked")Message 1 checked Message 2 checked Message 3 checked Message 4 checked Message 5 checked
inbox = ["Hi", "Win cash", "Bye"]
for msg in inbox:
print(msg)
Hi Win cash Bye
for starts the loopEach round, msg takes the next item. The body runs once per round.
inbox = ["Hi", "Win cash", "Bye"]
for msg in inbox:
print(len(msg), msg)2 Hi 8 Win cash 3 Bye
| round | msg | len(msg) | prints |
|---|---|---|---|
| 1 | 'Hi' | 2 | 2 Hi |
| 2 | 'Win cash' | 8 | 8 Win cash |
| 3 | 'Bye' | 3 | 3 Bye |
Next row: arrow key or the ▶ button. Predict it first!
list() is only here so we can see the numbers. In a for loop you write range(...) directly.
| You type | Python gives | Meaning |
|---|---|---|
list(range(5)) | [0, 1, 2, 3, 4] | 0 up to 5, stop not included |
list(range(1, 6)) | [1, 2, 3, 4, 5] | start at 1, stop before 6 |
list(range(0, 11, 2)) | [0, 2, 4, 6, 8, 10] | third number = step |
list(range(5, 0, -1)) | [5, 4, 3, 2, 1] | negative step counts down |
len(range(1, 10)) | 9 | how many numbers: 9 |
for i in range(2, 11, 3):
print(i)What will this print? Write your prediction as a comment before you run the cell.
for i in range(2, 11, 3):
print(i)2 5 8
Start with 0 before the loop, then add each item inside the loop.
nums = [4, 7, 1, 8]
total = 0
for n in nums:
total = total + n
print(total)20
| round | n | total before | total after |
|---|---|---|---|
| 1 | 4 | 0 | 4 |
| 2 | 7 | 4 | 11 |
| 3 | 1 | 11 | 12 |
| 4 | 8 | 12 | 20 |
Next row: arrow key or the ▶ button. Predict it first!
WATCH FOR
Silent video: press play, pause any time.
The count goes up only in rounds where the condition is True.
count = 0
for i in range(1, 8):
if i % 2 == 0:
count = count + 1
print(count)3
| i | i % 2 | even? | count |
|---|---|---|---|
| 1 | 1 | False | 0 |
| 2 | 0 | True | 1 |
| 3 | 1 | False | 1 |
| 4 | 0 | True | 2 |
| 5 | 1 | False | 2 |
| 6 | 0 | True | 3 |
| 7 | 1 | False | 3 |
Next row: arrow key or the ▶ button. Predict it first!
n = 3
while n > 0:
print(n)
n = n - 1
print("Go!")
3 2 1 Go!
while: repeat as long as the condition is TrueThe condition is checked before each round. The loop ends the first time it is False.
n = 3
while n > 0:
print(n)
n = n - 1
print("Go!")3 2 1 Go!
| n | n > 0 | what happens |
|---|---|---|
| 3 | True | print 3, then n = 2 |
| 2 | True | print 2, then n = 1 |
| 1 | True | print 1, then n = 0 |
| 0 | False | leave loop, print Go! |
Next row: arrow key or the ▶ button. Predict it first!
WATCH FOR
Silent video: press play, pause any time.
Without n = n - 1, n stays 3 and n > 0 is always True. In Colab, click the stop square next to the cell, or Runtime > Interrupt execution.
n = 3
while n > 0:
print(n)
# forgot: n = n - 1 -> prints 3 foreverbreak leaves the loop immediatelyinbox = ["Hi", "See you", "WIN cash", "Bye"]
for msg in inbox:
if "win" in msg.lower():
print("First spam:", msg)
break
print("OK:", msg)OK: Hi OK: See you First spam: WIN cash
continue skips the rest of this round onlyfor msg in ["Hi", "", "Bye", ""]:
if msg == "":
continue
print("Checking:", msg)Checking: Hi Checking: Bye
enumerate gives (position, item) pairsinbox = ["Hi", "Win cash", "Bye"]
for i, msg in enumerate(inbox):
print(i, msg)0 Hi 1 Win cash 2 Bye
found resets to False for each new messagespam_words = ["free", "win"]
inbox = ["Win cash", "Class at 10",
"Free gift"]
for msg in inbox:
found = False
for word in spam_words:
if word in msg.lower():
found = True
print(found, msg)True Win cash False Class at 10 True Free gift
Outer loop: one message at a time. Inner loop: every word for that message.
for msg in inbox:
found = False
for word in spam_words:
if word in msg.lower():
found = True
print(found, msg)| msg | word | word in msg? | found |
|---|---|---|---|
| 'Win cash' | 'free' | False | False |
| 'Win cash' | 'win' | True | True |
| 'Class at 10' | 'free' | False | False |
| 'Class at 10' | 'win' | False | False |
| 'Free gift' | 'free' | True | True |
| 'Free gift' | 'win' | False | True |
Next row: arrow key or the ▶ button. Predict it first!
WATCH FOR
Silent video: press play, pause any time.
Loops + decisions + a list of suspicious words: the filter from Lecture 1's demo, in real code.
spam_words = ["free", "win", "prize", "cash"]
inbox = ["Win a free phone",
"Class moved to room 305",
"Claim your cash prize",
"See you at the library"]
spam_count = 0
for msg in inbox:
is_spam = False
for word in spam_words:
if word in msg.lower():
is_spam = True
if is_spam:
spam_count = spam_count + 1
print("SPAM ", msg)
else:
print("OK ", msg)
print(f"Flagged {spam_count} of {len(inbox)}")SPAM Win a free phone OK Class moved to room 305 SPAM Claim your cash prize OK See you at the library Flagged 2 of 4
Same rules, two trickier messages. Predict the labels before you run it.
tricky = ["Claim your FR33 g1ft now",
"Free lunch after the seminar"]
for msg in tricky:
is_spam = False
for word in spam_words:
if word in msg.lower():
is_spam = True
print(is_spam, msg)False Claim your FR33 g1ft now True Free lunch after the seminar
Read the last line of an error first. It names the problem.
| What you typed | What Python says | What it means |
|---|---|---|
for i in range(5)
print(i) | SyntaxError: expected ':' | Missing colon after the for line. |
for i in range(5): print(i) | IndentationError: expected an indented block after 'for' statement on line 1 | The body must be indented. |
for x in 5:
print(x) | TypeError: 'int' object is not iterable | A number is not a collection. Use range(5). |
for i in range(3):
totl = totl + i | NameError: name 'totl' is not defined | totl was never created. Create it before the loop, and check spelling. |
Each task uses a loop. Test with N = 20 unless stated.
Print all even numbers from 1 to N.
Print 1 to N except numbers divisible by 5.
Print numbers from 1 to N divisible by 3 or 4 but not by 5.
Print all primes up to N. Expected for 20: 2 3 5 7 11 13 17 19.
Find the second largest distinct value of [4, 9, 2, 9, 7] with a loop, no sort. Expected: 7.
Given n = 4721, add its digits with a while loop. Hint: n % 10 and n // 10. Expected: 14.
Show these after students have tried the exercises.
range(1, N + 1) includes N. end=" " prints on one line instead of a new line each time.
N = 20
for i in range(1, N + 1):
if i % 2 == 0:
print(i, end=" ")
print()
for i in range(1, N + 1):
if i % 5 != 0:
print(i, end=" ")2 4 6 8 10 12 14 16 18 20 1 2 3 4 6 7 8 9 11 12 13 14 16 17 18 19
and is evaluated before or. Without brackets, 15 would wrongly be printed.
N = 20
for i in range(1, N + 1):
if (i % 3 == 0 or i % 4 == 0) and i % 5 != 0:
print(i, end=" ")3 4 6 8 9 12 16 18
A prime has no divisor between 2 and itself. break stops checking as soon as one divisor is found.
N = 20
for n in range(2, N + 1):
is_prime = True
for d in range(2, n):
if n % d == 0:
is_prime = False
break
if is_prime:
print(n, end=" ")2 3 5 7 11 13 17 19
Second largest: skip the maximum, then track the largest of the rest. Digits: take the last digit, then drop it.
nums = [4, 9, 2, 9, 7]
largest = max(nums)
second = None
for x in nums:
if x != largest:
if second == None or x > second:
second = x
print(second)
n = 4721
total = 0
while n > 0:
total = total + n % 10
n = n // 10
print(total)7 14
In the lab you can
Opens in a new tab and works offline. All labs: labs/START_HERE.html
for x in items: | Repeat for each item |
range(a, b, step) | Numbers from a, stop before b |
total = 0 ... total += x | Accumulator pattern |
while condition: | Repeat while True |
break | Leave the loop now |
continue | Skip to the next round |
for i, x in enumerate(items): | Position and item |
loop inside a loop | Every pair of items |
Due before Lecture 4.1 · [date]
Predict first: the output of for i in range(10, 0, -3): print(i), and print(len(range(0, 100, 10))).
Ask for no input: store n = 7 and print n x 1 up to n x 10 in the form 7 x 3 = 21.
Draw a trace table by hand for the accumulator slide with nums = [2, 5, 3]. Then check by running.
Make 8 invented messages. Count how many contain any word from your spam_words list, using nested loops.
Store secret = 7 and a list of guesses [3, 9, 7, 5]. Loop over guesses, print Too low / Too high, and break when correct.
Watch it again at home to revise.