6.1. Iterable Tuple

  • Immutable - cannot add, modify or remove items

  • Stores elements of any type

6.1.1. Define Empty

  • data = () - empty tuple

  • data = tuple() - empty tuple

  • data = () is faster than data = tuple()

Empty tuple:

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

Performance:

>>> %%timeit -r 1000 -n 1000  # doctest: +SKIP
... data = ()
...
3.97 ns ± 0.337 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
4.00 ns ± 0.244 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
3.94 ns ± 0.317 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
4.00 ns ± 0.243 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
4.02 ns ± 0.27 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
>>> %%timeit -r 1000 -n 1000  # doctest: +SKIP
... data = tuple()
...
6.87 ns ± 1.78 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
6.84 ns ± 2.31 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
6.85 ns ± 2.44 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
6.82 ns ± 2.33 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
6.83 ns ± 1.88 ns per loop (mean ± std. dev. of 1000 runs, 1,000 loops each)
  • Date: 2025-01-09

  • Python: 3.13.1

  • IPython: 8.30.0

  • System: macOS 15.2

  • Computer: MacBook M3 Max

  • CPU: 16 cores (12 performance and 4 efficiency) / 3nm

  • RAM: 128 GB RAM LPDDR5

6.1.2. Define With Elements

  • Can store elements of any type

  • data = (1, 2.0, 'three') - tuple with values

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

6.1.3. Trailing Comma

  • Single element tuple require comma at the end

  • Multi element tuple does not require comma at the end

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

>>> data = (1,)

Comma after last element of multi value tuple is optional:

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

Problem:

>>> data = (1)   # int
>>> data = (1,)  # tuple

6.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

Problem:

>>> data = 1,2  # tuple
>>> data = 1.2  # float

6.1.5. Conversion

  • tuple() - will convert its argument to tuple

  • Takes one iterable as an argument

  • Multiple arguments are not allowed

Builtin function tuple() converts argument to tuple

>>> tuple('abc')
('a', 'b', 'c')
>>> tuple(['a', 'b', 'c'])
('a', 'b', 'c')

6.1.6. Count

  • tuple.count() - number of occurrences of value

>>> colors = ('red', 'green', 'blue', 'red')
>>>
>>> colors.count('red')
2

6.1.7. Index

  • tuple.index() - position at which something is in the tuple

  • Note, that Python start counting at zero (zero based indexing)

  • Raises ValueError if the value is not present

>>> colors = ('red', 'green', 'blue')
>>>
>>>
>>> colors.index('red')
0
>>>
>>> colors.index('green')
1
>>>
>>> colors.index('blue')
2

6.1.8. Sorted

  • sorted() - return a new list containing all items from the iterable in ascending order

  • Note, that the result will be a list, so we need to type cast

  • Reverse flag can be set to request the result in descending order

>>> data = (3, 1, 2)
>>>
>>> sorted(data)
[1, 2, 3]
>>> data = (3, 1, 2)
>>>
>>> sorted(data, reverse=True)
[3, 2, 1]

6.1.9. Length

  • len() - Return the number of items in a container

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

6.1.10. Sum

  • sum() - Sum of elements

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

6.1.11. Min, Max

  • min() - Minimal value

  • max() - Maximal value

  • Works with numeric and string values

List with numeric values:

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

List with string values:

>>> data = ('a', 'c', 'b')
>>>
>>> min(data)
'a'
>>> max(data)
'c'

6.1.12. Recap

  • Immutable - cannot add, modify or remove items

  • Stores elements of any type

  • Fast and memory efficient

6.1.13. Assignments

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Definition
# - Difficulty: easy
# - Lines: 5
# - Minutes: 3

# %% English
# 1. Define `result_a` as a `tuple` without elements
# 2. Define `result_b` as a `tuple` with elements: 1, 2, 3
# 3. Define `result_c` as a `tuple` with elements: 1.1, 2.2, 3.3
# 4. Define `result_d` as a `tuple` with elements: 'a', 'b', 'c'
# 5. Define `result_e` as a `tuple` with elements: True, False, None
# 6. Define `result_f` as a `tuple` with elements: 1, 2.2, True, 'a'
# 7. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result_a` jako `tuple` bez elementów
# 2. Zdefiniuj `result_b` jako `tuple` z elementami: 1, 2, 3
# 3. Zdefiniuj `result_c` jako `tuple` z elementami: 1.1, 2.2, 3.3
# 4. Zdefiniuj `result_d` jako `tuple` z elementami: 'a', 'b', 'c'
# 5. Zdefiniuj `result_e` jako `tuple` z elementami: True, False, None
# 6. Zdefiniuj `result_f` jako `tuple` z elementami: 1, 2.2, True, 'a'
# 7. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

>>> 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 type(result_f) is tuple, \
'Variable `result_f` has invalid type, should be tuple'

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

# Define `result_a` as a `tuple` without elements
# type: tuple
result_a = ...

# Define `result_b` as a `tuple` with elements: 1, 2, 3
# type: tuple[int,int,int]
result_b = ...

# Define `result_c` as a `tuple` with elements: 1.1, 2.2, 3.3
# type: tuple[float,float,float]
result_c = ...

# Define `result_d` as a `tuple` with elements: 'a', 'b', 'c'
# type: tuple[str,str,str]
result_d = ...

# Define `result_e` as a `tuple` with elements: True, False, None
# type: tuple[bool,bool,None]
result_e = ...

# Define `result_f` as a `tuple` with elements: 1, 2.2, True, 'a'
# type: tuple[int,float,bool,str]
result_f = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Index
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with an index of an element `c` in `DATA`
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z indeksem elementu `c` w `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

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

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

>>> assert result == 2, \
'Variable `result` has invalid value. Check your calculations.'

>>> pprint(result)
2
"""

DATA = ('a', 'b', 'c', 'd')


# Define `result` with an index of an element `c` in `DATA`
# type: int
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Count
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with a count of an element `c` in `DATA`
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z liczbą wystąpień elementu `c` w `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

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

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

>>> assert result == 1, \
'Variable `result` has invalid value. Check your calculations.'

>>> pprint(result)
1
"""

DATA = ('a', 'b', 'c', 'd')


# Define `result` with a count of an element `c` in `DATA`
# type: int
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Count
# - Difficulty: easy
# - Lines: 5
# - Minutes: 3

# %% English
# 1. Define `result_a` with number of occurrences of 1 in `DATA_A`
# 2. Define `result_b` with number of occurrences of 1 in `DATA_B`
# 3. Define `result_c` with number of occurrences of 1 in `DATA_C`
# 4. Define `result_d` with number of occurrences of 1 in `DATA_D`
# 5. Define `result_e` with number of occurrences of 1 in `DATA_E`
# 6. Define `result_f` with number of occurrences of 1 in `DATA_F`
# 7. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result_a` z liczba wystąpień 1 w `DATA_A`
# 2. Zdefiniuj `result_b` z liczba wystąpień 1 w `DATA_B`
# 3. Zdefiniuj `result_c` z liczba wystąpień 1 w `DATA_C`
# 4. Zdefiniuj `result_d` z liczba wystąpień 1 w `DATA_D`
# 5. Zdefiniuj `result_e` z liczba wystąpień 1 w `DATA_E`
# 6. Zdefiniuj `result_f` z liczba wystąpień 1 w `DATA_F`
# 7. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

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

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

>>> assert result_a == 0, \
'Variable `result_a` has invalid value. Check your calculations.'
>>> assert result_b == 1, \
'Variable `result_b` has invalid value. Check your calculations.'
>>> assert result_c == 1, \
'Variable `result_c` has invalid value. Check your calculations.'
>>> assert result_d == 0, \
'Variable `result_d` has invalid value. Check your calculations.'
>>> assert result_e == 1, \
'Variable `result_e` has invalid value. Check your calculations.'
>>> assert result_f == 3, \
'Variable `result_f` has invalid value. Check your calculations.'

>>> pprint(result_a)
0
>>> pprint(result_b)
1
>>> pprint(result_c)
1
>>> pprint(result_d)
0
>>> pprint(result_e)
1
>>> pprint(result_f)
3
"""

DATA_A = ()
DATA_B = (1, 2, 3)
DATA_C = (1.0, 2.0, 3.0)
DATA_D = ('1', '2', '3')
DATA_E = (True, False)
DATA_F = (1, 1.0, True, '1')

# Define `result_a` with number of occurrences of 1 in `DATA_A`
# type: int
result_a = ...

# Define `result_b` with number of occurrences of 1 in `DATA_B`
# type: int
result_b = ...

# Define `result_c` with number of occurrences of 1 in `DATA_C`
# type: int
result_c = ...

# Define `result_d` with number of occurrences of 1 in `DATA_D`
# type: int
result_d = ...

# Define `result_e` with number of occurrences of 1 in `DATA_E`
# type: int
result_e = ...

# Define `result_f` with number of occurrences of 1 in `DATA_F`
# type: int
result_f = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Sum
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with a sum of all elements in `DATA`
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z sumą wszystkich elementów w `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

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

>>> result
6
"""

DATA = (1, 2, 3)

# Define `result` with a sum of all elements in `DATA`
# type: int
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Len
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with result of `DATA` length
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z wynikiem długości `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

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

>>> result
3
"""

DATA = ('a', 'b', 'c')

# Define `result` with result of `DATA` length
# type: int
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Mean
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with a result of the `DATA` arithmetic mean
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z wynikiem średniej arytmetycznej `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `sum()`
# - `len()`
# - `mean = sum(...) / len(...)`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

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

>>> result
2.5
"""

DATA = (1, 2, 3, 4)

# Define `result` with a result of the `DATA` arithmetic mean
# type: float
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Min
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with smallest element of `DATA`
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z najmniejszym elementem z `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

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

>>> result
1
"""

DATA = (1, 2, 3)

# Define `result` with smallest element of `DATA`
# type: int
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Max
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Define `result` with the biggest element of `DATA`
# 2. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj `result` z największym elementem z `DATA`
# 2. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

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

>>> result
3
"""

DATA = (1, 2, 3)

# Define `result` with the biggest element of `DATA`
# type: int
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Select
# - Difficulty: easy
# - Lines: 1
# - Minutes: 3

# %% English
# 1. Define `result: tuple` representing all species
# 2. To convert table use multiline select with `alt` or `alt+shift`
#    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` lub `alt+shift` 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 sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> assert result is not Ellipsis, \
'Assign your 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 element 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 with species names
# type: tuple[str]
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Iterable Tuple Mean
# - Difficulty: medium
# - Lines: 8
# - Minutes: 8

# %% English
# 1. Define variables:
#    - `result_a` with arithmetic mean of column `sepal_length`
#    - `result_b` with arithmetic mean of column `sepal_width`
#    - `result_c` with arithmetic mean of column `petal_length`
#    - `result_d` with arithmetic mean of column `petal_width`
# 2. Use column selection with `alt` key shortcut
# 3. Do not use `str.split()`, `slice`, `getitem`, `for`, `while`
#    or any other control-flow statement
# 4. Non-functional requirements:
#    - practice tuple creation syntax, not automation
#    - practice vertical selection in IDE
# 5. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj zmienne:
#    - `result_a` z średnią arytmetyczną kolumny `sepal_length`
#    - `result_b` z średnią arytmetyczną kolumny `sepal_width`
#    - `result_c` z średnią arytmetyczną kolumny `petal_length`
#    - `result_d` z średnią arytmetyczną kolumny `petal_width`
# 2. Wykorzystaj zaznaczanie kolumnowe za pomocą klawisza `alt`
# 3. Nie używaj `str.split()`, `slice`, `getitem`, `for`, `while`
#    lub jakiejkolwiek innej instrukcji sterującej
# 4. Wymagania niefunkcjonalne:
#    - przećwicz składnię tworzenia `tuple`, a nie automatyzację,
#    - przećwicz zaznaczanie pionowe w IDE
# 5. 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 sys.version_info >= (3, 9), \
'Python 3.9+ required'

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

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

>>> result_a
5.86

>>> result_b
3.02

>>> result_c
4.14

>>> result_d
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
"""

# Arithmetic mean of sepal_length column
# type: float
result_a = ...

# Arithmetic mean of sepal_width column
# type: float
result_b = ...

# Arithmetic mean of petal_length column
# type: float
result_c = ...

# Arithmetic mean of petal_width column
# type: float
result_d = ...