6.1. Loop While

6.1.1. Syntax

  • Continue execution when argument is True

  • Stops if argument is False

while loop generic syntax:

while <condition>:
    <do something>
>>> # doctest: +SKIP
... while True:
...     pass

6.1.2. Convention

  • The longer the loop scope, the longer the variable name should be

  • Avoid one letters if scope is longer than one line

  • Generic names:

    • i - for loop counter

    • abort - for abort flags

    • abort_flag - for abort flags

6.1.3. Use Cases

Never ending loop. Used in servers to wait forever for incoming connections:

>>> # doctest: +SKIP
... while True:
...    print('hello')

Stop conditions:

>>> i = 0
>>>
>>> while i < 3:
...     print(i)
...     i += 1
0
1
2

Iterating over sequence. Better idea for this is to use for loop. for loop supports Iterators. len() must write all numbers to memory, to calculate its length:

>>> i = 0
>>> data = ['a', 'b', 'c']
>>>
>>> while i < len(data):
...     print(i, data[i])
...     i += 1
0 a
1 b
2 c

Exit flag. Exit flag pattern is useful if you have for example multi-threaded application:

>>> abort = False
>>> i = 10
>>>
>>> while not abort:
...     print(i)
...     i -= 1
...
...     if i == 6:
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         abort = True
10
9
8
7
Fuel leak detected. Abort, Abort, Abort!

6.1.4. Force Exit the Loop

Force exit the loop using break keyword:

>>> i = 10
>>>
>>> while True:
...     print(i)
...     i -= 1
...
...     if i == 6:
...         print('Fuel leak detected. Abort, Abort, Abort!')
...         break
10
9
8
7
Fuel leak detected. Abort, Abort, Abort!

Exiting the loop using break keyword:

>>> # doctest: +SKIP
... while True:
...     number = input('Type number: ')
...
...     if not number:
...         # if user hit enter
...         # without typing a number
...         break

6.1.5. Force Skip Iteration

  • if continue is encountered, it will jump to next loop iteration

>>> TEXT = """
...     # "Moon Speech" by John F. Kennedy, Rice Stadium, Houston, TX, 1962-09-12
...     # Source: http://er.jsc.nasa.gov/seh/ricetalk.htm
...     We choose to go to the Moon.
...     We choose to go to the Moon in this decade and do the other things.
...     Not because they are easy, but because they are hard.
...     Because that goal will serve to organize and measure the best of our energies a skills.
...     Because that challenge is one that we are willing to accept.
...     One we are unwilling to postpone.
...     And one we intend to win
... """
>>>
>>> data = TEXT.splitlines()
>>> i = 0
>>>
>>> while i < len(data):
...     line = data[i].strip()
...     i += 1
...
...     if len(line) == 0:
...         continue
...
...     if line.startswith('#'):
...         continue
...
...     print(line)
We choose to go to the Moon.
We choose to go to the Moon in this decade and do the other things.
Not because they are easy, but because they are hard.
Because that goal will serve to organize and measure the best of our energies a skills.
Because that challenge is one that we are willing to accept.
One we are unwilling to postpone.
And one we intend to win

Force skip iteration using continue keyword:

>>> all_astronauts = ['Mark Watney', 'Jan Twardowski', 'Melissa Lewis', 'José Jiménez']
>>> assigned_to_mission = ['Mark Watney', 'Melissa Lewis']
>>> i = 0
>>>
>>> while i < len(all_astronauts):
...     name = all_astronauts[i]
...     i += 1
...
...     if name not in assigned_to_mission:
...         continue
...
...     print(name)
Mark Watney
Melissa Lewis

Force skip iteration using continue keyword:

>>> i = 0
>>>
>>> while i < 10:
...     print(i, end=', ')
...     i += 1
...
...     if i % 3:
...         continue
...
...     print(end='\n')  # doctest: +NORMALIZE_WHITESPACE
0, 1, 2,
3, 4, 5,
6, 7, 8,
9,

6.1.6. Assignments

Code 6.1. Solution
"""
* Assignment: Loop While to Float
* Complexity: easy
* Lines of code: 5 lines
* Time: 5 min

English:
    1. Use data from "Given" section (see below)
    2. Create `result: list[float]`
    3. Use `while` to iterate over `DATA`
    4. Convert current elements of `DATA` to `float`
    5. Converted value append to `result`
    6. Compare result with "Tests" section (see below)

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Stwórz `result: list[float]`
    3. Użyj `while` do iterowania po `DATA`
    4. Przekonwertuj obecny element `DATA` do `float`
    5. Przekonwertowaną wartość dodaj na koniec `result`
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Hints:
    * `Stop` or `Ctrl+C` kills infinite loop

Tests:
    >>> type(result)
    <class 'list'>
    >>> assert all(type(x) is float for x in result)
    >>> result
    [2.0, 3.0, 3.5, 4.0, 4.5, 5.0]
"""


# Given
DATA = (2, 3, 3.5, 4, 4.5, 5)
result: list = []


Code 6.2. Solution
"""
* Assignment: Loop While to Str
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min

English:
    1. Use data from "Given" section (see below)
    2. Create `result: str`
    3. Use `while` to iterate over `DATA`
    4. Add current element of `DATA` to `result`
    5. Do not use `str.join()`
    6. Compare result with "Tests" section (see below)

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Stwórz `result: str`
    3. Użyj `while` do iterowania po `DATA`
    4. Dodaj obecny element z `DATA` do `result`
    5. Nie używaj `str.join()`
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Hints:
    * `Stop` or `Ctrl+C` kills infinite loop

Tests:
    >>> type(result)
    <class 'str'>
    >>> result
    'hello'
"""


# Given
DATA = ['h', 'e', 'l', 'l', 'o']
result: str = ''


Code 6.3. Solution
"""
* Assignment: Loop While Translate
* Complexity: medium
* Lines of code: 5 lines
* Time: 5 min

English:
    1. Use data from "Given" section (see below)
    2. Use `while` to iterate over `DATA`
    3. If letter is in `PL` then use conversion value as letter
    4. Add letter to `result`
    5. Compare result with "Tests" section (see below)

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Użyj `while` do iteracji po `DATA`
    3. Jeżeli litera jest w `PL` to użyj skonwertowanej wartości jako litera
    4. Dodaj literę do `result`
    5. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Hints:
    * `Stop` or `Ctrl+C` kills infinite loop

Tests:
    >>> type(result)
    <class 'str'>
    >>> result
    'zazolc gesla jazn'
"""


# Given
PL = {'ą': 'a', 'ć': 'c', 'ę': 'e',
      'ł': 'l', 'ń': 'n', 'ó': 'o',
      'ś': 's', 'ż': 'z', 'ź': 'z'}

DATA = 'zażółć gęślą jaźń'
result: str = ''


Code 6.4. Solution
"""
* Assignment: Loop While Input
* Complexity: medium
* Lines of code: 14 lines
* Time: 13 min

English:
    1. Use data from "Given" section (see below)
    2. Define `grades: list[float]`
    3. Using `input()` ask user about grade, one at a time
    4. User will type only valid `int` or `float`
    5. To iterate use only `while` loop
    6. If grade is in `GRADE_SCALE` - add it to `grades`
    7. If grade is not in `GRADE_SCALE` - print "Grade is not allowed" and  continue input
    8. If user pressed Enter key, end inserting data
    9. At the end, define `result: float` with calculated mean of `grades`
    10. Test case when report list is empty

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Zdefiniuj `grades: list[float]`
    3. Do iterowania użyj tylko pętli `while`
    4. Używając `input()` poproś użytkownika o ocenę, jedną na raz
    5. Użytkownik poda tylko poprawne `int` lub `float`
    6. Jeżeli ocena jest w `GRADE_SCALE` - dodaj ją do `grades`
    7. Jeżeli oceny nie ma w `GRADE_SCALE` - wyświetl "Grade is not allowed"
    i kontynuuj wpisywanie
    8. Jeżeli użytkownik wcisnął Enter, zakończ wprowadzanie danych
    9. Na zakończenie zdefiniuj `result` z wyliczeniem średniej  arytmetycznej `grades`
    10. Przetestuj przypadek, gdy dzienniczek jest pusty

Hints:
    * `Stop` or `Ctrl+C` kills infinite loop
    * `mean = sum(...) / len(...)`

Tests:
    >>> type(grades)
    <class 'list'>
    >>> type(result)
    <class 'float'>
    >>> assert all(type(x) is float for x in grades)
    >>> len(grades) > 0
    True
    >>> from statistics import mean
    >>> mean(grades) == result
    True
"""


# Given
GRADE_SCALE = (2.0, 3.0, 3.5, 4.0, 4.5, 5.0)
grades: list = []
result: float = 0.0