!!! Classes and Methods
%%info
This is __Exercise 4__ of the [Micro Python Tutorial].
%%
We can define __classes__ in Python. Classes are defined globally, within the file/module as they begin in column 0.
Within a class its functions are called __methods__. Unlike functions, methods are defined within the scope of the class and are therefore indented within the class's block.
A class has a __constructor__, a special method named {{{__init__}}}. The constructor is called when you create a new object of the class. It can be said that the new object has a type of its class. 
%%info
All special methods in Python are surrounded by double underscores. (There are more of these but we'll get to them later.)
%%
%%filename boo.py %%
%%python {{{
class Boo:
    __init__(self):
        print('boo!')
}}} %%
Now let's enter the Python REPL and use our new class:
%%repl {{{
/pyboard> repl
Entering REPL. Use Control-X to exit.
>
MicroPython v1.25.0 on 2025-04-15; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>> 
>>> from boo import Boo
>>> b = Boo()
boo!
>>> 
>>> print(b)
<Boo object at 20005f50>
>>>
>>> print(type(b))
<class 'Boo'>
>>> 
}}} %%
%%info 
__What did we do?__ 
After creating a class named {{Boo}},
# we imported the class ("{{from boo import Boo}}") so the interpreter was aware of it,
# then we ''instantiated'' (created an instance of) an object of the Boo class ("{{b = Boo()}}") and we assigned the object a name "b". Notice that when we created the object, the print line in Boo's constructor was executed ("boo!")
# then we printed the object (the interpreter returned a default result "{{<Boo object at 20005f50>}}"),
# then we printed the type of the object ("{{print(type(b))}}")
%%
%%filename motor_controller.py %%
%%python {{{
from motor import Motor
class MotorController:
    def __init__(self):
      self.port_forward_motor = Motor('pfwd')
      self.stbd_forward_motor = Motor('sfwd')
      print('motor controller ready.')
}}}
%%
%%filename motor.py %%
%%python {{{
class Motor:
    def __init__(self, name):
        self.motor_name = name
        self.motor_speed = 0
        print('motor {} ready.'.format(self.motor_name))
        
    def set_speed(self, speed):
        self.motor_speed = speed
        print("speed: {}".format(speed))
    def get_speed(self):
        return self.motor_speed
}}}
%%
%%filename main.py %%
%%python {{{
from motor_controller import MotorController
try:
    motor_ctrl = MotorController()
except Exception as ex:
    print('an error occurred: {}'.format(ex))
finally:
    print('complete.')
}}}
%%
----
__Previous:__ [MicroPython Tutorial Exercise 3|MicroPythonTutorialExercise03]: functions \\
__Next:__ [MicroPython Tutorial Exercise 5|MicroPythonTutorialExercise05]: using classes