8.3. Syntax Loop Else¶

• Not only if statement has else clause

• Conditionals: if ... elif ... else

• Exceptions: try ... except ... else

• While loop: while ... else

• For loop: for ... else

>>> colors = ['red', 'green', 'blue']
>>> search = 'black'
>>>
>>> i = 0
>>> while i < len(colors):
...     color = colors[i]
...     i += 1
...     if color == search:
...         print('found')
...         break
... else:
...     print('missing')
...
missing

>>> colors = ['red', 'green', 'blue']
>>> search = 'black'
>>>
>>> for color in colors:
...     if color == search:
...         print('found')
...         break
... else:
...     print('missing')
...
missing


8.3.1. Example¶

• 3, 2, 1, 0, Launching rocket to outer space

• 3, 2, Fuel leak detected. Abort, Abort, Abort!

• Note, this will print the value first, decrement and then check for leak

>>> i = 3
>>>
>>> while i >= 0:
...     print(i)
...     i -= 1
...
...     if i == None:  # no problems detected
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         break
3
2
1
0
>>>
>>> print('Launching rocket to outer space')
Launching rocket to outer space

• Can we launch a rocket?

>>> i = 3
>>>
>>> while i >= 0:
...     print(i)
...     i -= 1
...
...     if i == 1:  # problem detected in the last second
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         break
3
2
Fuel leak detected. Abort, Abort, Abort!
>>>
>>> print('Launching rocket to outer space')
Launching rocket to outer space

• This time we aborted and still launched - this is not good

• How to detect if the countdown was successful?

8.3.2. Flag¶

In order to answer those questions we need to introduce a variable to hold the status if the countdown was aborted or successful. Let's name it abort. If the flag is set to True, then there was an abort procedure called during the countdown and we cannot launch a rocket to outer space.

>>> abort = False
>>> i = 3
>>>
>>> while i >= 0:
...     print(i)
...     i -= 1
...
...     if i == 1:  # problem detected in the last second
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         abort = True
...         break
3
2
Fuel leak detected. Abort, Abort, Abort!
>>>
>>> if not abort:
...     print('Launching rocket to outer space')


But the problem here is that the follow-up code is split from the while loop. This can cause problems if the codebase will grow.

8.3.3. Else¶

The else clause to while loop will be executed if a loop does not exit with break statement. In the other words: if there was no problem detected during the countdown, launch the rocket to outer space.

>>> i = 3
>>>
>>> while i >= 0:
...     print(i)
...     i -= 1
...
...     if i == 1:  # problem detected in the last second
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         break
... else:
...     print('Launching rocket to outer space')
3
2
Fuel leak detected. Abort, Abort, Abort!

>>> i = 3
>>>
>>> while i >= 0:
...     print(i)
...     i -= 1
...
...     if i == None:  # no problems detected
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         break
... else:
...     print('Launching rocket to outer space')
3
2
1
0
Launching rocket to outer space


8.3.4. Assignments¶

"""
* Assignment: Loop WhileElse Found
* Required: no
* Complexity: medium
* Lines of code: 5 lines
* Time: 5 min

English:
1. Modify game code below
2. User can try MAX_TRIES times, if he/sh does not guess number by then
print Game over, max tries achieved.
3. Don't use while ... else syntax
4. Run doctests - all must succeed

Polish:
1. Zmodyfikuj kod gry poniżej
2. Użytkownik może próbować MAX_TRIES razy, jeżeli w tym czasie nie zgadnie
to wypisz Game over, max tries achieved.
3. Nie używaj składni while ... else
4. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* Stop or Ctrl+C kills infinite loop

Tests:
>>> import sys; sys.tracebacklimit = 0
"""

# Simulate user input (for test automation)
from unittest.mock import MagicMock
input = MagicMock(side_effect=['0', '9', '1', '8', '2', '7', '3', '6', '4'])

HIDDEN = 4
MAX_TRIES = 4

while True:
guess = input('\nType number: ')

if int(guess) > HIDDEN:
print('Above')
elif int(guess) < HIDDEN:
print('Below')
else:
print('Exactly')
break


"""
* Assignment: Loop WhileElse Found
* Required: no
* Complexity: medium
* Lines of code: 5 lines
* Time: 5 min

English:
1. Modify game code below
2. User can try MAX_TRIES times, if he/sh does not guess number by then
print Game over, max tries achieved.
3. Don't use while ... else syntax
4. Run doctests - all must succeed

Polish:
1. Zmodyfikuj kod gry poniżej
2. Użytkownik może próbować MAX_TRIES razy, jeżeli w tym czasie nie zgadnie
to wypisz Game over, max tries achieved.
3. Nie używaj składni while ... else
4. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* Stop or Ctrl+C kills infinite loop

Tests:
>>> import sys; sys.tracebacklimit = 0
"""

# Simulate user input (for test automation)
from unittest.mock import MagicMock
input = MagicMock(side_effect=['0', '9', '1', '8', '2', '7', '3', '6', '4'])

HIDDEN = 4
MAX_TRIES = 4

while True:
guess = input('\nType number: ')

if int(guess) > HIDDEN:
print('Above')
elif int(guess) < HIDDEN:
print('Below')
else:
print('Exactly')
break