Education Technology

Adding “Class” to Your Python Code

Posted 09/09/2022 by John Hanna

I’m back! Are you ready to expand your skill set in Python? Remember that Python is both a procedural and an object-oriented programming language (OOP). A class is the definition (description) of an object. An object has attributes (variables) and methods (functions) that determine its properties and behaviors. In one of my previous blogs on creating your own promposal, I included two demo projects that use classes to define balloons and buttons in the two separate sample programs.

Here’s a partial sample of those classes:


Object-oriented programming using classes is a different approach to software design that focuses on the nouns (balloons, buttons, objects) in a project rather than the verbs (print, display, =, actions). Of course, we can mix and match the two approaches in designing an application (program) and the three fundamental control structures (sequence, branch and loop) are still critical to all programs. This blog introduces Python classes using both TI‑Nspire™ CX II and TI‑84 Plus CE Python graphing calculators.

In the beginning ...
As seen in the two partial examples above, I start a class using the keyword class followed by any class name and a colon:
class balloon: and the rest of the class definition is indented.
An important method in defining a class is called __init__(self, …): as seen in both images above. I use this method to assign values (usually passed as arguments) to the object’s attributes. __init__ can perform other functions as well.

self is a required first argument in all class methods, including __init__(). self is used to refer to each specific object (instance) of the class. I can have many balloons (or instances of a balloon), each with its own color, size and position, and self is used to refer to each one’s attributes and methods.

Example:
b1 = balloon(255, 0,0, 100, 100, 50) makes (constructs an instance of ...) a red (255,0,0) balloon with a center at (100,100) and a radius 50. The __init__ method assigns each argument to a corresponding attribute. Then ... print(b1.r) would display the value 50 which is assigned to the attribute self.r in the __init__( ) method.
Each balloon created has its own attributes and methods and thus will be unique, so only b1’s radius is displayed. It is not necessary to refer to self when accessing b1.r.

Note: __init__ has two underscore characters (_ _) before and after the word init:
def _ _ init _ _ (self, ...) (spaces for showing the separate characters)
Adding methods to the class
First notice the indentation within the class: Each class method, beginning with the __init__() method, is indented and the indentation continues for all the methods that I add to the balloon class. Part of the balloon draw() method is seen below.


The entire draw() code is:

def draw(self): for i in range(self.r,0,-1): r=int(self.red*(0.97**i)) g=int(self.green*(0.97**i)) b=int(self.blue*(0.97**i)) set_color(r,g,b) fill_circle(self.x, self.y, i)
Note the widespread use of the prefix self. in the code above so that each balloon uses its own attributes. The for loop creates a “3D” effect on the balloon: dark around the edges and light in the center thanks to Bert Wikkerink in Holland. Using the balloon object b1 defined earlier, I can draw the balloon b1 using the statement b1.draw( ) with no arguments since b1 “knows” its own color, position and radius:


When writing a “method” (defining a function for the class), I am telling the class “how” to do something to, or with, one of its instances. The argument “self” in the function definition (def draw(self):) does not need an actual parameter passed to it. The Python interpreter takes care of that by passing the current object. So, in the statement b1.draw( ) there is no argument, but the balloon b1 itself is passed to the “self” argument in the draw(self) function.

A class in a module: TI-Nspire™ CX II graphing calculator
When a class is designed within a module (a separate *.py file) then it can be used in other Python applications. A separate module file contains the class definition __init__( ) and all other class methods. The module can then be imported into other Python applications. The module file can be a separate Python file within the same project document (*.tns), but, if the *.tns document containing the class module is stored in my PyLib folder, then the class is available to all my TI-Nspire™ Python projects.


Here is the result of the birthday program:


A class in a module: TI-84 Plus CE Python
The same code structure works on the TI-84 Plus CE Python. Just write the balloon.py module containing the balloon class and then write the birthday.py program, importing the balloon.py module:


There is one change in the BIRTHDAY code from the TI-Nspire™ CX II graphing calculator to the TI-84 Plus CE Python: while not escape( ):.

The balloon class is unchanged. On the TI-84 Plus CE Python, all files are stored in the same location.

Result of birthday.py:


One more method for the balloon class on the TI-Nspire™ CX II graphing calculator
In the promposal demo program with balloons, the user is supposed to pop the balloons using the mouse in the reverse order in which they appeared (it’s not always obvious). To implement the “popping,” I introduced one more method to the balloon class: is_clicked(self, x, y):


The is_clicked() method on the left is invoked after using get_key() and get_mouse() functions as seen in the right image. If the key pressed is the “center” key (that’s the center of the touchpad or a mouse-click on a computer), then x, y = get_mouse() is used to get the current mouse position on the screen (in default coordinates regardless of any window setting). Then the last balloon, top = blist[-1], is checked to see if it was clicked by calculating the distance of the point (x, y) from the center of the balloon using the distance formula. If it is clicked, then the balloon is removed (popped) from the list of balloons and the screen is redrawn (in the buffer). pop() is a built-in list function that deletes or removes the last element from the list.

Note: When the index of a list is negative, counting starts at the end of the list: blist[ -1 ] is the same as blist[ len(blist) – 1 ]
Note: The TI-84 Plus CE Python does not have a get_key() function or a mouse cursor, but an alternate approach is certainly possible.

The bottom line (the “why should I care about all this”) or summary
If you are trying to impress your friends with your coding prowess, OOP is the classy way to make your code “pop”:
  • Classes are used to encapsulate information (data and functions) into a logical unit called an “object.”
  • __init__( ) is used to initialize the attributes (variables) of an object (an instance of the class).
  • self is used to refer to each object’s own attributes and methods.
  • Methods (functions) can be added to the class to perform other tasks (behaviors) and all methods of the class are indented to be part of the class.
  • Python also supports the other OOP principles. Encapsulation, Inheritance, Polymorphism, and Data Abstraction are all part of the Python OOP paradigm, and you can learn a lot more about Python OOP online.

Until next time... happy programming!



About the author: John Hanna is a retired teacher splitting time between sailing in New Jersey and mountain biking in Florida (did he get that backwards?), still getting kicks out of working with TI to provide feedback on new products, and developing meaningful programming content for mathematics and science ... and still having fun with all the graphing calculators and the accompanying toys.