16.7. OOP State
Definition: state - data stored in object
Methods can access and modify state
16.7.1. Vars
>>> class User:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
... self._authenticated = False
>>>
>>> mark = User('Mark', 'Watney')
>>>
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': False}
16.7.2. Methods Can Access State
User.is_authenticated()
>>> class User:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
... self._authenticated = False
...
... def is_authenticated(self):
... if self._authenticated:
... return True
... else:
... return False
>>> mark = User('Mark', 'Watney')
>>>
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': False}
>>>
>>> mark.is_authenticated()
False
16.7.3. Methods Can Modify State
User.login()
User.logout()
>>> class User:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
... self._authenticated = False
...
... def login(self):
... self._authenticated = True
...
... def logout(self):
... self._authenticated = False
>>>
>>>
>>> mark = User('Mark', 'Watney')
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': False}
>>>
>>> mark.login()
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': True}
>>>
>>> mark.logout()
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney', '_authenticated': False}
16.7.4. Use Case - 1
>>> class Car:
... def __init__(self):
... self.engine = 'off'
...
... def engine_start(self):
... self.engine = 'on'
...
... def engine_stop(self):
... self.engine = 'off'
...
... def drive_to(self, location):
... if self.engine != 'on':
... raise RuntimeError('Engine must be turned on to drive')
... else:
... return f'Driving to {location}'
>>>
>>>
>>> maluch = Car()
>>>
>>> maluch.drive_to('Cologne, Germany')
Traceback (most recent call last):
RuntimeError: Engine must be turned on to drive
>>>
>>> maluch.engine
'off'
>>>
>>> maluch.engine_start()
>>> maluch.engine
'on'
>>>
>>> maluch.drive_to('Cologne, Germany')
'Driving to Cologne, Germany'
>>>
>>> maluch.engine_stop()
>>> maluch.engine
'off'
16.7.5. Use Case - 2
>>> class Point:
... def __init__(self, x, y, z):
... self.x = x
... self.y = y
... self.z = z
...
... def get_coordinates(self):
... return self.x, self.y, self.z
...
... def show(self):
... return f'Point(x={self.x}, y={self.y}, z={self.z})'
>>>
>>>
>>> point = Point(x=1, y=2, z=3)
>>>
>>> point.get_coordinates()
(1, 2, 3)
>>>
>>> point.show()
'Point(x=1, y=2, z=3)'
16.7.6. Use Case - 3
>>> class Counter:
... def __init__(self):
... self.current_value = 0
...
... def increment(self):
... self.current_value += 1
...
... def decrement(self):
... self.current_value -= 1
... if self.current_value < 0:
... raise ValueError('Cannot decrement below zero')
...
... def show(self):
... return self.current_value
>>>
>>>
>>> c = Counter()
>>>
>>> c.increment()
>>> c.increment()
>>> c.show()
2
>>>
>>> c.decrement()
>>> c.decrement()
>>> c.show()
0
>>>
>>> c.decrement()
Traceback (most recent call last):
ValueError: Cannot decrement below zero
16.7.7. Assignments
# %% About
# - Name: OOP State Auth
# - Difficulty: easy
# - Lines: 5
# - Minutes: 3
# %% 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
# %% English
# 1. Modify class `User`
# 2. Add method `is_authenticated` returning:
# - `True` if field `_authenticated` is True
# - `False` if field `_authenticated` is False
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User`
# 2. Dodaj metodę `is_authenticated` zwracającą:
# - `True` jeśli pole `_authenticated` jest True
# - `False` jeśli pole `_authenticated` jest False
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isclass, ismethod
>>> assert isclass(User)
>>> mark = User('Mark', 'Watney')
>>> assert ismethod(mark.is_authenticated)
>>> assert hasattr(mark, '_authenticated')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
User: type
is_authenticated: Callable[[object], bool]
# %% Data
# %% Result
class User:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
self._authenticated = False
# %% About
# - Name: OOP State Login/Logout
# - Difficulty: easy
# - Lines: 4
# - Minutes: 3
# %% 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
# %% English
# 1. Modify class `User`
# 2. Add method `login`, setting field `_authenticated` to `True`
# 3. Add method `logout`, setting field `_authenticated` to `False`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User`
# 2. Dodaj metodę `login`, ustawiającą pole `_authenticated` na `True`
# 3. Dodaj metodę `logout`, ustawiającą pole `_authenticated` na `False`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isclass, ismethod
>>> assert isclass(User)
>>> mark = User('Mark', 'Watney')
>>> assert ismethod(mark.login)
>>> assert ismethod(mark.logout)
>>> assert hasattr(mark, '_authenticated')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
User: type
login: Callable[[object], None]
logout: Callable[[object], None]
# %% Data
# %% Result
class User:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
self._authenticated = False
# %% About
# - Name: OOP State EditProfile
# - Difficulty: easy
# - Lines: 5
# - Minutes: 3
# %% 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
# %% English
# 1. Modify class `User`
# 2. Add method `edit_profile()`:
# - Arguments: `firstname`, `lastname`
# - Method checks if user is authenticated
# - If yes, set instance fields values
# - If not, raise `PermissionError` with message `User is not authenticated`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User`
# 2. Dodaj metodę `edit_profile()`:
# - Argumenty: `firstname`, `lastname`
# - Metoda sprawdza czy użytkownik jest uwierzytelniony
# - Jeśli tak, to ustawia wartości pól instancji
# - Jeśli nie, podnieś `PermissionError` z komunikatem `User is not authenticated`
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isclass, ismethod
>>> assert isclass(User)
>>> mark = User('Mark', 'Watney')
>>> assert ismethod(mark.login)
>>> assert ismethod(mark.logout)
>>> assert hasattr(mark, '_authenticated')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
User: type
edit_profile: Callable[[object, str, str], None]
# %% Data
# %% Result
class User:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
self._authenticated = False
def login(self):
self._authenticated = True
def logout(self):
self._authenticated = False
def is_authenticated(self):
if self._authenticated:
return True
else:
return False