12.6. OOP Methods About

12.6.1. Rationale

  • Methods are functions in the class

  • Prevents copy-paste code

  • Improves readability

  • Improves refactoring

  • Decomposes bigger problem into smaller chunks

  • At this moment:

    • At definition - self should always be a first parameter

    • At call - self is not passed as an argument (Python will do that)

    • Later you will learn more advanced things like static methods etc.

method

Functions in the class which takes instance as first argument (self)

Syntax:

>>> class MyClass:
...     def mymethod(self):
...         pass
>>>
>>>
>>> my = MyClass()
>>> my.mymethod()

12.6.2. Method Parameters

  • At definition - self should always be a first parameter

  • Later you will learn more advanced things like static methods etc.

  • Parameter - Receiving variable used within the function

  • Parameters could be required or optional (with default value)

Required parameter:

  • Necessary to call that function

  • Specified at leftmost side

Optional parameter:

  • Has default value

  • Optional to call that function

  • Default value will be overridden if specified at a call time

  • Specified at rightmost side

Without parameters:

>>> class Astronaut:
...     def say_hello(self):
...         print('My name... José Jiménez')

Methods with required parameter:

>>> class Astronaut:
...     def say_hello(self, firstname):
...         print(f'My name... {firstname}')

Method with optional parameter:

>>> class Astronaut:
...     def say_hello(self, firstname='unknown'):
...         print(f'My name... {firstname}')

Method with required and optional parameter:

>>> class Astronaut:
...     def say_hello(self, firstname, lastname='unknown'):
...         print(f'My name... {firstname} {lastname}')

12.6.3. Method Arguments

  • At call - self is not passed as an argument (Python will do that)

>>> class Astronaut:
...     def say_hello(self):
...         print('My name... José Jiménez')
...
...
>>> jose = Astronaut()
>>> jose.say_hello()
My name... José Jiménez

Method with positional argument:

>>> class Astronaut:
...     def say_hello(self, name):
...         print(f'My name... {name}')
>>>
>>>
>>> jose = Astronaut()
>>>
>>> jose.say_hello('José Jiménez')
My name... José Jiménez
>>>
>>> jose.say_hello()
Traceback (most recent call last):
TypeError: say_hello() missing 1 required positional argument: 'name'

Method with keyword argument:

>>> class Astronaut:
...     def say_hello(self, firstname, lastname):
...         print(f'My name... {firstname} {lastname}')
>>>
>>>
>>> jose = Astronaut()
>>>
>>> jose.say_hello(firstname='José', lastname='Jiménez')
My name... José Jiménez
>>>
>>> jose.say_hello(lastname='Jiménez', firstname='José')
My name... José Jiménez
>>>
>>> jose.say_hello()
Traceback (most recent call last):
TypeError: say_hello() missing 1 required positional argument: 'name'

12.6.4. Assignments

Code 12.7. Solution
"""
* Assignment: OOP Method Syntax
* Required: yes
* Complexity: easy
* Lines of code: 3 lines
* Time: 3 min

English:
    1. Define class `Calculator`
    2. Define method `add` in class `Calculator`
    3. Method `add` take `a` and `b` as arguments
    4. Method returns sum of `a` and `b`
    5. Run doctests - all must succeed

Polish:
    1. Zdefiniuj klasę `Calculator`
    2. Zdefiniuj metodę `add` w klasie `Calculator`
    3. Metoda `add` przyjmuje `a` i `b` jako argumenty
    4. Metoda zwraca sumę `a` i `b`
    5. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from inspect import isclass, ismethod

    >>> assert isclass(Calculator)
    >>> calc = Calculator()
    >>> assert ismethod(calc.add)
    >>> calc.add(1, 2)
    3
"""


Code 12.8. Solution
"""
* Assignment: OOP Method Mean
* Required: yes
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min

English:
    1. Define class `Stats`
    2. Define method `mean()` in `Stats` class
    3. Method takes `data: list[float]` as an argument
    4. Method returns arithmetic mean of the `data`
    5. Returned value must be rounded to one decimal places
    6. Run doctests - all must succeed

Polish:
    1. Zdefiniuj klasę `Stats`
    2. Zdefiniuj metodę `mean()` w klasie `Stats`
    3. Metoda przyjmuje `data: list[float]` jako argument
    4. Metoda zwraca średnią arytmetyczną z `data`
    5. Zwracana wartość ma być zaokrąglona do jednego miejsca po przecinku
    6. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `round()`

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from inspect import isclass, ismethod

    >>> assert isclass(Stats)
    >>> stats = Stats()
    >>> assert ismethod(stats.mean)

    >>> stats.mean([1, 2])
    1.5
    >>> stats.mean([5.8, 2.7, 5.1, 1.9])
    3.9
"""


Code 12.9. Solution
"""
* Assignment: OOP Method Call
* Required: yes
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
    1. Iterate over `DATA` skipping header and separating features from labels
    2. Call `mean()` method of `Stats` class instance passing list of features
    3. Define `result: list[float]` with list of means from each row
    4. Run doctests - all must succeed

Polish:
    1. Iteruj po `DATA` pomijając nagłówek i rodzielając cechy od etykiet
    2. Wywołuj metodę `mean()` instancji klasy `Stats` przekazując listę cech
    3. Zdefiniuj `result: list[float]` z listą średnich każdego z wierszy
    4. Uruchom doctesty - wszystkie muszą się powieść

Hints:
    * `round()`

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

    >>> assert type(result) is list
    >>> assert all(type(x) is float for x in result)

    >>> result
    [3.9, 2.5, 3.5, 4.1, 3.9, 2.4]
"""

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'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
]


class Stats:
    def mean(self, data):
        avg = sum(data) / len(data)
        return round(avg, 1)


stats = Stats()

# list[float]: apply `mean()` to each feature
result = ...