P1-E004 ======= In this exercise, you will learn about creating your own classes and objects. Information ----------- +----------------------+--------------------------------------------------------+ | Learning goals | +======================+========================================================+ |**Concepts** | | | | * classes, object-oriented programming | +----------------------+--------------------------------------------------------+ |**Skills** | | | | * define your own class | | | * create class instances | | | * save class declarations in script | +----------------------+--------------------------------------------------------+ .. topic:: What to Submit Submit your script(s) for the final task of this exercise. These script should be named *[your surname]_e004.[ext]* or, if you want to split your code into two scripts, *[your surname]_e004_class.[ext]* and *[your surname]_e004_main.[ext]*, where *[ext]* is the file extension. In case of Python, this would be *.py*, for Matlab it is *.m*, etc. Object-Oriented Programming --------------------------- In exercises E001 - E003, you learnt the basics of programming and functions. With those basics, you are already able to write clean and efficient code. Many programming languages, such as *C*, *Pascal* and classic *Fortran*, work only with *procedures* (i.e. functions and subroutines). The programming paradigm of only using procedures, which contain a series of computetional steps, is called **procedural procramming**, and is not uncommon in science. There are, however, many situations that warrant the adoption of **object-oriented programming** using **objects** and **classes**. Those concepts will be introduced in today's lesson. We will work with the following definitions: * class - a code template for creating objects; it consists of object attribute variables and methods (functions). * object - a class instance, a combination of (object attribute) variables, functions and data. What those definitions mean will be clarified with the aid of examples below. Blueprint for Humans -------------------- Imagine you are a supercomputer attempting to take over the world by quietly replacing humans with robots that look and act like humans. First, you would want to create a template or blueprint for humans. This blueprint would include: * variable to store human attributes, such as name, height and age; * procedures that represent typical actions and inner workings of humans; * data, such as a list of achievements for the person's CV. Classes can be thought of as such blueprints. An intuitive name for this class would be *human*. In Python, you define a class with the **class** statement. Let's create this template by writing the following in a new script: .. code-block:: python class human: """ The blueprint for humans. Attributes: name: a string representing the human's name height: a floating point number for the human's height in cm whatAmI: a string representing the human's self-perception Author: Hal """ def __init__(self, arg1, arg2, arg3): """Initialiser.""" self.name = arg1 self.height = arg2 self.whatAmI = arg3 def introduce(self): """Human introduces themselves.""" print('Hi, my name is ', self.name, '. I am ', self.whatAmI) The **class** statement lets you define your class, just like the **def** statements lets you define your function. We have defined a class called *human* and decided on three attributes that each object of the *human* class will have: name, height and whatAmI. Notice how we already have two functions in our class? The first function is called **__init__**. Every class should have one! This is an initialiser method that is automatically called when a new *class instance* or *object* is created for this class. It allows us to set up the attributes required for the objects and give them default values. The second function is one that we think an object in the human class, i.e. a (pseudo) human individual, would be doing. In this case, we *print* two of the object's properties in two sentences. .. Note:: Python docstring Note that we have written comments here as such *""" [comment] """*. Those are so called *docstrings* in Python. For larger projects, such as writing software to take over the world, using docstrings at the top of functions and classes can help you write documentation for your software as they can easily be included in automatic generation of your documentation. Line comments, however, should be regular comments. If you are working on bigger Python projects, consult examples of good/standard use of docstrings before documenting your code. Execute the code above to create the class. Now it's time to create our first human. We do this by declaring that **new object = class name (arguments)**, e.g. .. code-block:: python human001 = human ('no name',0.15,'a real boy') Now that we have created our first human object, let's explore what we can do with it. First, we can access the attributes of a specific ebject by referencing **objectname.attribute**, e.g.: .. code-block:: python human001.name We can change these attributes by simply accessing them as above and overwriting them, e.g.: .. code-block:: python human001.name = 'LegoBot' We can execute functions associated with a certain object in a similar way. Let's make our human001 introduce itself by calling the *introduce()* function: .. code-block:: python human001.introduce() .. figure:: robot_cc0.jpg Functions associated with classes can also take external arguments. Let's modify our introduction to better hide our robots from humans. .. code-block:: python def introduce(self, opposite): """ Object introduces itself differently, based on the type of entity it is interacting with. """ if opposite == 'human': # if we are interacting with a human print('Hi, my name is ', self.name, '. I am a real human, I promise.') else: # if we are interacting with any other entity print('Hi, my name is ', self.name, '. I am ', self.whatAmI) The greeting now takes the nature of the conversational partner into account, which is passed as an argument. If they are human, our robot pretends to be human! Run the script again to update our human class. Re-run the script to update our class, then create an object again. .. code-block:: python human001 = human ('evilBot',0.15,'an evil robot') When you call the *introduce()* function now, we include the argument as we do for all functions. .. code-block:: python human001.introduce('human') Create a few more class instances (objects), additional attributes and functions you think real humans should have, and play around with your object to get a better grasp of classes and objects. **Remember to ask your instructors questions when you're stuck! We don't bite. We are humans, too. We promise.** Your Task --------- For the last assignment, you optimised calculations using functions. Your task for this exercise leaves more room for creativity. Write one or several Python scripts, in which you: * create one or several classes, which serve as templates for your objects and should include object attributes as well as functions; * create a small script that creates one or several class instances (objects) for each class and **makes use of the class specific functions** in a reasonable manner. In case you need some inspiration, here are a few ideas for classes: * (building on previous exercises) a class for students that includes functions to calculate their individual mean grade and automatically writes a short CV; * a class for a planet's climate, and a script that allow you to interact with climates on different planets; * a class for characters in a video game, and a small script that allows you to interact with a character (object) you created; * a class for different items in a task manager, and a small script that allows you to display, create and delete tasks (objects). When you are happy with your code, name your files as described above and submit them via ILIAS. .. warning:: Late submissions won't be accepted!