4.1. Sequence Tuple

4.1.1. Rationale

  • Immutable - cannot add, modify or remove items

4.1.2. Syntax

Defining tuple() is more explicit, however empty tuple with () is used more often and it's also faster:

>>> data = ()
>>> data = tuple()

Can store elements of any type:

>>> data = (1, 2, 3)
>>> data = (1.1, 2.2, 3.3)
>>> data = (True, False)
>>> data = ('a', 'b', 'c')
>>> data = ('a', 1, 2.2, True, None)

4.1.3. Type Casting

Builtin function tuple() converts argument to tuple

>>> data = 'abcd'
>>> tuple(data)
('a', 'b', 'c', 'd')
>>> data = ['a', 'b', 'c', 'd']
>>> tuple(data)
('a', 'b', 'c', 'd')
>>> data = ('a', 'b', 'c', 'd')
>>> tuple(data)
('a', 'b', 'c', 'd')
>>> tuple('a', 'b', 'c', 'd')
Traceback (most recent call last):
TypeError: tuple expected at most 1 argument, got 4

4.1.4. Optional Brackets

Brackets are optional, but it's a good practice to always write them:

>>> data = (1, 2, 3)
>>> data = 1, 2, 3

Single element tuple require comma at the end (important!):

>>> data = (1,)
>>> type(data)
<class 'tuple'>
>>> data = (1)
>>> type(data)
<class 'int'>

Comma after last element of multi value tuple is optional:

>>> data = (1, 2)
>>> type(data)
<class 'tuple'>
>>> data = (1, 2,)
>>> type(data)
<class 'tuple'>

4.1.5. Tuple or Int, Float, Str

>>> x = 1           # int
>>> x = 1.          # float
>>> x = 1,          # tuple
>>> x = (1)         # int
>>> x = (1.)        # float
>>> x = (1,)        # tuple
>>> x = 'one'       # str
>>> x = 'one',      # tuple
>>> x = 'one'.
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> x = (12)        # int
>>> x = (1.2)       # float
>>> x = (1,2)       # tuple
>>> x = 1.,1.       # tuple
>>> x = 1.,.1       # tuple
>>> x = .1,1.       # tuple

4.1.6. Length

>>> data = (1, 2, 3)
>>> len(data)
3

4.1.7. Sort

>>> data = (3, 1, 2)
>>> tuple(sorted(data))
(1, 2, 3)

4.1.8. Reversed

>>> data = (1, 2, 3)
>>> tuple(reversed(data))
(3, 2, 1)

4.1.9. Memory

../../_images/memory-tuple.png

Figure 4.1. Memory representation for tuple

4.1.10. Assignments

Code 4.1. Solution
"""
* Assignment: Sequence Tuple Create
* Required: yes
* Complexity: easy
* Lines of code: 5 lines
* Time: 5 min

English:
    1. Create tuples:
        a. `result_a` with elements: 1, 2, 3
        b. `result_b` with elements: 1.1, 2.2, 3.3
        c. `result_c` with elements: 'a', 'b', 'c'
        d. `result_d` with elements: True, False
        e. `result_e` with elements: 1, 2.2, True, 'a'
    2. Run doctests - all must succeed

Polish:
    1. Stwórz tuple:
        a. `result_a` z elementami: 1, 2, 3
        b. `result_b` z elementami: 1.1, 2.2, 3.3
        c. `result_c` z elementami: 'a', 'b', 'c'
        d. `result_d` z elementami: True, False, True
        e. `result_e` z elementami: 1, 2.2, True, 'a'
    2. Uruchom doctesty - wszystkie muszą się powieść

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

    >>> assert result_a is not Ellipsis, \
    'Assign result to variable: `result_a`'
    >>> assert result_b is not Ellipsis, \
    'Assign result to variable: `result_b`'
    >>> assert result_c is not Ellipsis, \
    'Assign result to variable: `result_c`'
    >>> assert result_d is not Ellipsis, \
    'Assign result to variable: `result_d`'
    >>> assert result_e is not Ellipsis, \
    'Assign result to variable: `result_e`'

    >>> assert type(result_a) is tuple, \
    'Variable `result_a` has invalid type, should be tuple'
    >>> assert type(result_b) is tuple, \
    'Variable `result_b` has invalid type, should be tuple'
    >>> assert type(result_c) is tuple, \
    'Variable `result_c` has invalid type, should be tuple'
    >>> assert type(result_d) is tuple, \
    'Variable `result_d` has invalid type, should be tuple'
    >>> assert type(result_e) is tuple, \
    'Variable `result_e` has invalid type, should be tuple'

    >>> assert result_a == (1, 2, 3), \
    'Variable `result_a` has invalid value, should be (1, 2, 3)'
    >>> assert result_b == (1.1, 2.2, 3.3), \
    'Variable `result_b` has invalid value, should be (1.1, 2.2, 3.3)'
    >>> assert result_c == ('a', 'b', 'c'), \
    'Variable `result_c` has invalid value, should be ("a", "b", "c")'
    >>> assert result_d == (True, False), \
    'Variable `result_d` has invalid value, should be (True, False)'
    >>> assert result_e == (1, 2.2, True, 'a'), \
    'Variable `result_e` has invalid value, should be (1, 2.2, True, "a")'
"""

# tuple[int]: with elements: 1, 2, 3
result_a = ...

# tuple[float]: with elements: 1.1, 2.2, 3.3
result_b = ...

# tuple[str]: with elements: 'a', 'b', 'c'
result_c = ...

# tuple[bool]: with elements: True, False
result_d = ...

# tuple[int|float|bool|str]: with elements: 1, 2.2, True, 'a'
result_e = ...

Code 4.2. Solution
"""
* Assignment: Sequence Tuple Select
* Required: yes
* Complexity: easy
* Lines of code: 1 lines
* Time: 5 min

English:
    1. Define `result: tuple` representing all species
    2. To convert table use multiline select with `alt` key in your IDE
    3. Do not use `slice`, `getitem`, `for`, `while` or any other
       control-flow statement
    4. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `result: tuple` z nazwami gatunków
    2. Do konwersji tabelki wykorzystaj zaznaczanie wielu linijek za pomocą
       klawisza `alt` w Twoim IDE
    3. Nie używaj `slice`, `getitem`, `for`, `while` lub jakiejkolwiek innej
       instrukcji sterującej
    4. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `ALT` + `left mouse button` = multiple select
    * `ALT` + `SHIFT` + `left mouse button drag` = vertical selection

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

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

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

    >>> assert all(type(x) is str for x in result), \
    'All elements in result should be str'

    >>> assert len(result) == 5, \
    'Variable `result` length should be 5'

    >>> assert result.count('virginica') == 2, \
    'Result should have 2 elements of virginica'

    >>> assert result.count('setosa') == 1, \
    'Result should have 1 elements of setosa'

    >>> assert result.count('versicolor') == 2, \
    'Result should have 2 elements of versicolor'

    >>> assert ('sepal_length' not in result
    ...     and 'sepal_width' not in result
    ...     and 'petal_length' not in result
    ...     and 'petal_width' not in result
    ...     and 'species' not in result)
"""

DATA = ['sepal_length,sepal_width,petal_length,petal_width,species',
        '5.8,2.7,5.1,1.9,virginica',
        '5.1,3.5,1.4,0.2,setosa',
        '5.7,2.8,4.1,1.3,versicolor',
        '6.3,2.9,5.6,1.8,virginica',
        '6.4,3.2,4.5,1.5,versicolor']

# tuple[str]: define a tuple with species names
result = ...

Code 4.3. Solution
"""
* Assignment: Sequence Tuple Mean
* Required: no
* Complexity: medium
* Lines of code: 8 lines
* Time: 8 min

English:
    1. Calculate mean for each numerical values column
    2. To convert table use multiline select with `alt` key in your IDE
    3. Do not use `str.split()`, `slice`, `getitem`, `for`, `while`
       or any other control-flow statement
    4. Run doctests - all must succeed

Polish:
    1. Wylicz średnią arytmetyczną dla każdej z kolumn numerycznych
    2. Do konwersji tabelki wykorzystaj zaznaczanie wielu linijek
       za pomocą klawisza `alt` w Twoim IDE
    3. Nie używaj `str.split()`, `slice`, `getitem`, `for`, `while`
       lub jakiejkolwiek innej instrukcji sterującej
    4. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `mean = sum(...) / len(...)`
    * `ALT` + `left mouse button` = multiple select
    * `ALT` + `SHIFT` + `left mouse button drag` = vertical selection
    * `ALT` + `SHIFT` + `right` = select word to the right (macOS)
    * `ALT` + `SHIFT` + `left` = select word to the left (macOS)
    * `CTRL` + `SHIFT` + `right` = select word to the right (Windows)
    * `CTRL` + `SHIFT` + `left` = select word to the left (Windows)
    * `CTRL` + `right` = jump over the word to the right
    * `CTRL` + `left` = jump over the word to the left
    * `CTRL` + `ALT` + L = Reformat Code on Windows
    * `CMD` + `ALT` + L = Reformat Code on macOS

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

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

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

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

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

    >>> assert type(sepal_length) is float, \
    'Variable `sepal_length` has invalid type, should be float'

    >>> assert type(sepal_width) is float, \
    'Variable `sepal_width` has invalid type, should be float'

    >>> assert type(petal_length) is float, \
    'Variable `petal_length` has invalid type, should be float'

    >>> assert type(petal_width) is float, \
    'Variable `petal_width` has invalid type, should be float'

    >>> sepal_length
    5.859999999999999

    >>> sepal_width
    3.0200000000000005

    >>> petal_length
    4.14

    >>> petal_width
    1.34
"""

DATA = ['sepal_length,sepal_width,petal_length,petal_width,species',
        '5.8,2.7,5.1,1.9,virginica',
        '5.1,3.5,1.4,0.2,setosa',
        '5.7,2.8,4.1,1.3,versicolor',
        '6.3,2.9,5.6,1.8,virginica',
        '6.4,3.2,4.5,1.5,versicolor']

# float: arithmetic mean from tuple with 5.8, 5.1, 5.7, 6.3, 6.4
sepal_length = ...

# float: arithmetic mean from tuple with 2.7, 3.5, 2.8, 2.9, 3.2
sepal_width = ...

# float: arithmetic mean from tuple with 5.1, 1.4, 4.1, 5.6, 4.5
petal_length = ...

# float: arithmetic mean from tuple with 1.9, 0.2, 1.3, 1.8, 1.5
petal_width = ...