10.3. Loop While Break

  • Force exit the loop

10.3.1. Syntax

>>> while True:
...     break

10.3.2. Example

>>> i = 0
>>>
>>> while True:
...     print(i)
...     i += 1
...     if i == 3:
...         break
0
1
2

10.3.3. No Input

  • if user hit enter, without typing a number

Simulate user input (for test automation):

>>> from unittest.mock import MagicMock
>>> input = MagicMock(side_effect=['1', '2', '3', ''])
>>> while True:
...     number = input('Type number: ')
...
...     if not number:
...         # if user hit enter
...         # without typing a number
...         break

10.3.4. Use Case - 0x01

>>> 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!

10.3.5. Assignments

# TODO: Write tests
"""
* Assignment: Loop While GuessGame1
* Type: homework
* Complexity: medium
* Lines of code: 9 lines
* Time: 5 min

English:
    1. Use `input` in `while True` loop to ask user about number
    2. Compare user's number with `HIDDEN`:
       a. If number is equal, print `Exactly` and break game
       b. If number is greater, print `Above`
       c. If number is lower, print `Below`
    3. Non-functional requirements:
        a. User will always input only one digit
        b. User will not input any invalid characters or longer numbers
        c. `Mock` will simulate inputting numbers by a user
        d. Use `input()` function as normal
    4. Run doctests - all must succeed

Polish:
    1. Użyj `input` w pętli `while True` do pytania użytkownika o liczbę
    2. Porównaj liczbę wprowadzoną przez użytkownika z `HIDDEN`:
       a. Jeżeli jest taka sama, to wypisz `Exactly` i zakończ grę
       b. Jeżeli jest większa, to wypisz `Above`
       c. Jeżeli jest mniejsza, to wypisz `Below`
    3. Wymagania niefunkcjonalne:
        a. Użytkownik zawsze wpisze tylko jedną cyfrę
        b. Użytkownik nie wpisze żadnych nieprawidłowych znaków lub dłuższych liczb
        c. `Mock` zasymuluje wpisanie liczb przez użytkownika
        d. Skorzytaj z funkcji `input()` tak jak normalnie
    4. Uruchom doctesty - wszystkie muszą się powieść

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

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

# Following two lines is needed for test automation
# In your code use `input()` function as normal
# `Mock` will simulate inputting numbers by a user
# So that, first number is `0`, second is `9`, and so on
from unittest.mock import Mock
input = Mock(side_effect=['0', '9', '1', '8', '2', '7', '3', '6', '4'])


HIDDEN = 4

"""
* Assignment: Loop While Input
* Type: homework
* Complexity: medium
* Lines of code: 14 lines
* Time: 13 min

English:
    1. Define `grades: list[float]`
    2. Using `input()` ask user about grade, one at a time
    3. User will type only valid `int` or `float`
    4. To iterate use only `while` loop
    5. If grade is in `GRADE_SCALE` - add it to `grades`
    6. If grade is not in `GRADE_SCALE`, skip this iteration
    7. If user pressed Enter key, end inserting data
    8. Define `result: float` with arithmetic mean of `grades`
    9. Test case when report list is empty
    10. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `grades: list[float]`
    2. Do iterowania użyj tylko pętli `while`
    3. Używając `input()` poproś użytkownika o ocenę, jedną na raz
    4. Użytkownik poda tylko poprawne `int` lub `float`
    5. Jeżeli ocena jest w `GRADE_SCALE` - dodaj ją do `grades`
    6. Jeżeli oceny nie ma w `GRADE_SCALE`, pomiń tą iterację
    7. Jeżeli użytkownik wcisnął Enter, zakończ wprowadzanie danych
    8. Zdefiniuj `result: float` ze średnią arytmetyczą `grades`
    9. Przetestuj przypadek, gdy dzienniczek jest pusty
    10. Uruchom doctesty - wszystkie muszą się powieść

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

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from statistics import mean

    >>> type(grades)
    <class 'list'>
    >>> type(result)
    <class 'float'>

    >>> assert all(type(x) is float for x in grades)

    >>> mean(grades) == result
    True

    >>> result
    3.5
"""

# Simulate user input (for test automation)
from unittest.mock import Mock
input = Mock(side_effect=['2', '2.5', '3', '3.5', '4', '5', '6', ''])


GRADE_SCALE = (2.0, 3.0, 3.5, 4.0, 4.5, 5.0)

# All user grades
# type: list[float]
grades = ...

# Arithmetic mean of grades
# type: float
result = ...