7.3. Mapping Getitem

  • Key lookup is very efficient O(1)

  • [...] throws KeyError exception if key not found in dict

  • .get() returns None if key not found

  • .get() can have default value, if key not found

>>> hello = {
...    'English': 'Hello',
...    'German': 'Guten Tag',
...    'Polish': 'Witaj',
... }
>>>
>>>
>>> hello.get('English')
'Hello'
>>>
>>> hello.get('Polish')
'Witaj'

7.3.1. Getitem Method

>>> crew = {
...     'commander': 'Melissa Lewis',
...     'botanist': 'Mark Watney',
...     'pilot': 'Rick Martinez',
... }
>>>
>>>
>>> crew['commander']
'Melissa Lewis'
>>>
>>> crew['chemist']
Traceback (most recent call last):
KeyError: 'chemist'

7.3.2. Get Method

>>> crew = {
...     'commander': 'Melissa Lewis',
...     'botanist': 'Mark Watney',
...     'pilot': 'Rick Martinez',
... }
>>>
>>>
>>> crew.get('commander')
'Melissa Lewis'
>>>
>>> crew.get('chemist')
>>>
>>> crew.get('chemist', 'not assigned')
'not assigned'

7.3.3. Switch

Simulate user input (for test automation):

>>> from unittest.mock import MagicMock
>>> input = MagicMock(side_effect=['French'])
>>> hello = {
...     'English': 'Hello',
...     'German': 'Guten Tag',
...     'Polish': 'Witaj',
...     'default': "I don't speak this language",
... }
>>>
>>>
>>> language = input('What is your language?: ')  #input: 'French'
>>> result = hello.get(language, hello['default'])
>>>
>>> print(result)
I don't speak this language

7.3.4. Use Case - 0x01

>>> MONTHS = {
...     1: 'January',
...     2: 'February',
...     3: 'March',
... }
>>>
>>> MONTHS[1]
'January'
>>>
>>> MONTHS['1']
Traceback (most recent call last):
KeyError: '1'
>>>
>>> MONTHS['01']
Traceback (most recent call last):
KeyError: '01'

7.3.5. Use Case - 0x02

>>> MONTHS = {
...     1: 'January',
...     2: 'February',
...     3: 'March',
... }
>>>
>>> MONTHS.get(1)
'January'
>>>
>>> MONTHS.get(13)
>>>
>>> MONTHS.get(13, 'invalid month')
'invalid month'

7.3.6. Use Case - 0x03

>>> MONTHS = {
...     1: 'January',
...     2: 'February',
...     3: 'March',
...     4: 'April',
...     5: 'May',
...     6: 'June',
...     7: 'July',
...     8: 'August',
...     9: 'September',
...     10: 'October',
...     11: 'November',
...     12: 'December'
... }
>>>
>>> DATE = '1961-04-12'
>>>
>>> year, month, day = DATE.split('-')
>>>
>>> year
'1961'
>>> month
'04'
>>> day
'12'
>>>
>>> MONTHS[month]
Traceback (most recent call last):
KeyError: '04'
>>>
>>> MONTHS[int(month)]
'April'

7.3.7. Use Case - 0x04

>>> PAYROLL = [
...     {'name': 'Mark Watney',   '2000-01': 2000, '2000-02': 2000, '2000-03': 2000},
...     {'name': 'Melissa Lewis', '2000-01': 3000, '2000-02': 3000, '2000-03': 3000},
...     {'name': 'Rick Martinez', '2000-03': 2500},
...     {'name': 'Alex Vogel',    '2000-01': 2500, '2000-02': 2500, '2000-03': 2500},
... ]
>>> result = f'{"Employee":<15} {"January":>10} {"February":>9} {"March":>6}'
>>>
>>> for employee in PAYROLL:
...     name = employee['name']
...     january = employee['2000-01']
...     february = employee['2000-02']
...     march = employee['2000-03']
...     result += f'{name:<15} {january:>10} {february:>9} {march:>6}'
...
Traceback (most recent call last):
KeyError: '2000-01'
>>> result = f'{"Employee":<15} {"January":>10} {"February":>9} {"March":>6}\n'
>>>
>>> for employee in PAYROLL:
...     name = employee['name']
...     january = employee.get('2000-01', 'n/a')
...     february = employee.get('2000-02', 'n/a')
...     march = employee.get('2000-03', 'n/a')
...     result += f'{name:<15} {january:>10} {february:>9} {march:>6}\n'
>>>
>>> print(result)
Employee           January  February  March
Mark Watney           2000      2000   2000
Melissa Lewis         3000      3000   3000
Rick Martinez          n/a       n/a   2500
Alex Vogel            2500      2500   2500
>>> result = f'{"Employee":<15} {"January":>10} {"February":>9} {"March":>6}\n'
>>>
>>> for employee in PAYROLL:
...     name = employee['name']
...     january = employee.get('2000-01', '-')
...     february = employee.get('2000-02', '-')
...     march = employee.get('2000-03', '-')
...     result += f'{name:<15} {january:>10} {february:>9} {march:>6}\n'
>>>
>>> print(result)
Employee           January  February  March
Mark Watney           2000      2000   2000
Melissa Lewis         3000      3000   3000
Rick Martinez            -         -   2500
Alex Vogel            2500      2500   2500
>>> result = f'{"Employee":<15} {"January":>10} {"February":>9} {"March":>6}\n'
>>>
>>> for employee in PAYROLL:
...     name = employee['name']
...     january = employee.get('2000-01', '')
...     february = employee.get('2000-02', '')
...     march = employee.get('2000-03', '')
...     result += f'{name:<15} {january:>10} {february:>9} {march:>6}\n'
>>>
>>> print(result)
Employee           January  February  March
Mark Watney           2000      2000   2000
Melissa Lewis         3000      3000   3000
Rick Martinez                          2500
Alex Vogel            2500      2500   2500

7.3.8. Assignments

Code 7.6. Solution
"""
* Assignment: Mapping Switch Value
* Type: homework
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 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 your 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',
}

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

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

Code 7.7. Solution
"""
* Assignment: Mapping Switch Default
* Type: homework
* 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   |
    |   A   |    a   |
    |   ą   |    a   |
    |   Ą   |    a   |
    |   b   |    b   |
    |   B   |    B   |
    |   c   |    c   |
    |   C   |    c   |
    |   ć   |    c   |
    |   Ć   |    c   |
    |  ...  |   ...  |

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 your 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',
}

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

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

Code 7.8. Solution
"""
* Assignment: Mapping Switch Default
* Type: homework
* 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   |
    |   A   |    a   |
    |   ą   |    a   |
    |   Ą   |    a   |
    |   b   |    b   |
    |   B   |    B   |
    |   c   |    c   |
    |   C   |    c   |
    |   ć   |    c   |
    |   Ć   |    c   |
    |  ...  |   ...  |

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 your 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=['L'])

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

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

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