5.8. Mapping Switch

5.8.1. Rationale

  • No switch statement in Python!

  • switch in Object Oriented Programming is considered a bad practise

  • PEP 275 -- Switching on Multiple Values [Rejected]

  • Since Python 3.10: PEP 636 -- Structural Pattern Matching: Tutorial

5.8.2. Example

>>> hello = {
...    'English': 'Hello',
...    'Russian': 'Здравствуйте',
...    'German': 'Guten Tag',
...    'Polish': 'Witaj',
... }
>>>
>>>
>>> hello.get('English')
'Hello'
>>>
>>> hello.get('Polish')
'Witaj'
>>>
>>> hello.get('Russian')
'Здравствуйте'

5.8.3. Dict Switch

>>> hello = {
...     'English': 'Hello',
...     'Russian': 'Здравствуйте',
...     'German': 'Guten Tag',
...     'Polish': 'Witaj',
...     'default': "I don't speak this language",
... }
>>>
>>>
>>> language = input('What is your language?: ')  # User input: 'French'
>>> result = hello.get(language, hello['default'])
>>>
>>> print(result)
I don't speak this language

5.8.4. Function Switch

>>> def hello(language):
...     data = {
...         'English': 'Hello',
...         'Russian': 'Здравствуйте',
...         'German': 'Guten Tag',
...         'Polish': 'Witaj',
...         'default': "I don't speak this language"}
...     return data.get(language, data['default'])
>>>
>>>
>>> hello('Russian')
'Здравствуйте'
>>>
>>> hello('French')
"I don't speak this language"

5.8.5. Assignments

Code 5.4. Solution
"""
* Assignment: Mapping Switch Value
* Required: no
* Complexity: easy
* Lines of code: 2 lines
* Time: 5 min

English:
    1. Create translator of pilot's alphabet
    2. Each letter has it's phonetic counterpart
    3. Ask user to input letter
    4. User will always put only one capitalized letter or number
    5. Define `result: str` with phonetic letter pronunciation
    6. If character not existing in alphabet, print: 'Not found'
    7. Do not use `if`, `try`, and `except`
    8. `MagicMock` will simulate inputting a letter by user
    9. Use `input()` function as normal
    10. Run doctests - all must succeed

Polish:
    1. Stwórz tłumacza alfabetu pilotów
    2. Pojedynczym literom przyporządkuj ich fonetyczne odpowiedniki
    3. Poproś użytkownika o wprowadzenie litery
    4. Użytkownik zawsze poda tylko jedną dużą literę lub cyfrę
    5. Zdefiniuj `result: str` z fonetyczną wymową litery
    6. Jeżeli znak nie występuje w alfabecie, wypisz: 'Not found'
    7. Nie używaj `if`, `try` ani `except`
    8. `MagicMock` zasymuluje wpisanie litery przez użytkownika
    9. Skorzytaj z funkcji `input()` tak jak normalnie
    10. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `input()`

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

    >>> assert letter is not Ellipsis, \
    'Ask user to input letter and assign it to: `letter`'

    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'

    >>> assert type(result) is str, \
    'Variable `result` has invalid type, should be str'

    >>> result
    'Mike'
"""

from unittest.mock import MagicMock


# Simulate user input (for test automation)
input = MagicMock(side_effect=['M'])

ALPHABET = {
    'A': 'Alfa',
    'B': 'Bravo',
    'C': 'Charlie',
    'D': 'Delta',
    'E': 'Echo',
    'F': 'Foxtrot',
    'G': 'Golf',
    'H': 'Hotel',
    'I': 'India',
    'J': 'Juliet',
    'K': 'Kilo',
    'L': 'Lima',
    'M': 'Mike',
    'N': 'November',
    'O': 'Oscar',
    'P': 'Papa',
    'Q': 'Quebec',
    'R': 'Romeo',
    'S': 'Sierra',
    'T': 'Tango',
    'U': 'Uniform',
    'V': 'Victor',
    'W': 'Whisky',
    'X': 'X-Ray',
    'Z': 'Zulu',
}

# str: with letter from user
letter = ...

# str: with converted letter to Pilot alphabet or 'Not found'
result = ...

Code 5.5. Solution
"""
* Assignment: Mapping Switch Default
* Required: no
* Complexity: easy
* Lines of code: 2 lines
* Time: 5 min

English:
    1. Ask user to input single letter
    2. Convert to lowercase
    3. If letter is in `PL` then use conversion value as letter
    4. `MagicMock` will simulate inputting of a letter by user
    5. Use `input()` function as normal
    6. Run doctests - all must succeed

Polish:
    1. Poproś użytkownika o wprowadzenie jednej litery
    2. Przekonwertuj literę na małą
    3. Jeżeli litera jest w `PL` to użyj skonwertowanej wartości jako litera
    4. `MagicMock` zasymuluje wpisanie litery przez użytkownika
    5. Skorzytaj z funkcji `input()` tak jak normalnie
    6. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `input()`
    * `str.lower()`

Example:
    | Input | Output |
    |-------|--------|
    |   A   |    a   |
    |   x   |    x   |
    |   Ł   |    ł   |
    |   ś   |    s   |
    |   Ź   |    z   |

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

    >>> assert letter is not Ellipsis, \
    'Ask user to input letter and assign it to: `letter`'

    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'

    >>> assert type(result) is str, \
    'Variable `result` has invalid type, should be str'

    >>> assert result not in PL.keys(), \
    'Result should not be in PL dict'

    >>> assert result in string.ascii_letters, \
    'Result should be an ASCII letter'
"""

from unittest.mock import MagicMock


# Simulate user input (for test automation)
input = MagicMock(side_effect=['Ł'])

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

# str: with letter from user
letter = ...

# str: with converted letter without PL diacritic chars
result = ...