Updated S6: Object Oriented Programming (markdown) authored by Rod Pérez's avatar Rod Pérez
...@@ -147,7 +147,7 @@ class Seq: ...@@ -147,7 +147,7 @@ class Seq:
pass pass
``` ```
When the class is defined, we can **create objects** of this class as shown here: When the class is defined, we can **create objects** of that class as shown below:
```python ```python
# Main program # Main program
...@@ -158,7 +158,7 @@ s1 = Seq() ...@@ -158,7 +158,7 @@ s1 = Seq()
s2 = Seq() s2 = Seq()
``` ```
Let's place a **breakpoint** in the line 7 Let's place a **breakpoint** in line 7
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-01.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-01.png)
...@@ -166,7 +166,7 @@ Press the **step over** option twice. On the variable panel we will see the **tw ...@@ -166,7 +166,7 @@ Press the **step over** option twice. On the variable panel we will see the **tw
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-02.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-02.png)
Contrats! You have created your first two **empty objects**! Congrats! You have created your first two **empty objects**!
### The \_\_init\_\_ method ### The \_\_init\_\_ method
...@@ -200,9 +200,9 @@ Testing.... ...@@ -200,9 +200,9 @@ Testing....
### Adding data: attribute strbases ### Adding data: attribute strbases
For representing a **sequence** we will use a **string** that is store in every object. We will call this string as **strbases**. The data stored in the objects is referred as **attributes** For representing a **sequence** we will use a **string** that will be stored in every object. We will call this string **strbases**. Data stored in the objects are referred as **attributes**
We modify the \_\_init\_\_ method to include a new parameter: the string for creating the object. That parameter will be stored in the object attribute: **self.strbases** Let's modify the \_\_init\_\_ method to include a new parameter: the string for creating the object. That parameter will be stored in the object attribute: **self.strbases**
```python ```python
class Seq: class Seq:
...@@ -220,7 +220,7 @@ class Seq: ...@@ -220,7 +220,7 @@ class Seq:
s1 = Seq("AGTACACTGGT") s1 = Seq("AGTACACTGGT")
s2 = Seq("CGTAAC") s2 = Seq("CGTAAC")
``` ```
If you **execute** it, you will see the **same output** than before. But now something has happened. The two objects created have their own **sequence string** stored in the **strbases** attribute. Let's debug it to see it If you **execute** it, you will see the **same output** as before, but now something has happened. The two objects created have their own **sequence string** stored in the **strbases** attribute. Let's debug it to see it
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-03.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-03.png)
...@@ -268,7 +268,7 @@ Sequence 2: CGTAAC ...@@ -268,7 +268,7 @@ Sequence 2: CGTAAC
Testing.... Testing....
``` ```
In **debug mode**, if the **step into** option is pressed when the next instruction to be executed is the first print, you will see how the execution pointer moved into the **\_\_str\_\_ method** In the **debug mode**, if the **step into** option is pressed when the next instruction to be executed is the first print, you will see how the execution pointer moved into the **\_\_str\_\_ method**
### Adding methods: len() ### Adding methods: len()
...@@ -323,7 +323,7 @@ Sequence 2: CGTAAC ...@@ -323,7 +323,7 @@ Sequence 2: CGTAAC
### Inheritance ### Inheritance
New classes can be **derived** from others, reusing their methods and adding new ones. This is called **inheritance**. Just to present the concepts, Let's create the **Gene class** derived from the Sequence. It will not add anything New classes can be **derived** from others, reusing their methods and adding new ones. This is called **inheritance**. Just to present the concepts, Let's create the **Gene class**, that derives (inherits) from Seq. It will not add anything
```python3 ```python3
class Gene(Seq): class Gene(Seq):
...@@ -348,7 +348,7 @@ print(f"Gene: {g}") ...@@ -348,7 +348,7 @@ print(f"Gene: {g}")
print(f" Length: {g.len()}") print(f" Length: {g.len()}")
``` ```
If we **run** the program this is what is shown in the **console**: If we **run** the program this is what we get:
``` ```
New sequence created! New sequence created!
...@@ -361,7 +361,7 @@ Gene: CGTAAC ...@@ -361,7 +361,7 @@ Gene: CGTAAC
#### Expanding the Gene Class #### Expanding the Gene Class
The **Gene** is a kind of **specialized sequence**. Not all the sequences are Genes, but all the genes are sequences. We can **expand** the **Gene class** by adding more information that is not present in the general sequences. For example the **name**: usually the genes have a special name The **Gene** is a kind of **specialized sequence**. Not all the sequences are Genes, but all the genes are sequences. We can **expand** the **Gene class** by adding more information that is not present in the general sequences. For example the **name** (usually the genes have a special name)
Let's create a new \_\_init\_\_ file method that includes a new optional parameter: the name of the Gene Let's create a new \_\_init\_\_ file method that includes a new optional parameter: the name of the Gene
...@@ -380,7 +380,7 @@ class Gene(Seq): ...@@ -380,7 +380,7 @@ class Gene(Seq):
print("New gene created") print("New gene created")
``` ```
As the Gene is also a Seq, for creating a Gene first we should call the **init** function from the **Seq class**. We do it by calling the **super().__init__(strbases)** method. And then we add the properties of the Gene. In this case its name As the Gene is also a Seq, for creating a Gene first we should call the **init** function from the Seq class. We do it by calling the **super().__init__(strbases)** method, and then we add the properties of the Gene. In this case, only its name
When creating the Gene in the main program, we specify its **name** as a parameter, for example FRAT1: When creating the Gene in the main program, we specify its **name** as a parameter, for example FRAT1:
...@@ -394,7 +394,7 @@ print(f"Sequence 1: {s1}") ...@@ -394,7 +394,7 @@ print(f"Sequence 1: {s1}")
print(f"Gene: {g}") print(f"Gene: {g}")
``` ```
When the program is **executed**, we can see this on the **Console**: When the program is **executed**, this is what we get:
``` ```
New sequence created! New sequence created!
...@@ -404,11 +404,11 @@ Sequence 1: AGTACACTGGT ...@@ -404,11 +404,11 @@ Sequence 1: AGTACACTGGT
Gene: CGTAAC Gene: CGTAAC
``` ```
Notice how the **init function** from the **Seq** has been **called twice**. The init function from the Gene only **once** Notice how the **init** function from Seq has been **called twice**, and the init function from the Gene only **once**
#### Overriding the Seq methods #### Overriding the Seq methods
In the new **Gene class**, we can create **new methods**, or we can **re-implement** method that were already implemeted in the Seq class. This operation of re-implementation is called overriding. For example, let's change the \_\_str\_\_ method for **printing** the **Gene name** along with the sequence In the new Gene class, we can create **new methods**, or we can **re-implement** methods that were already implemented in the *mother/father* class (Seq in this case). This operation of re-implementation is called **overriding**. For example, let's change the \_\_str\_\_ method for **printing** the **Gene name** along with the sequence
```python3 ```python3
class Gene(Seq): class Gene(Seq):
...@@ -441,8 +441,7 @@ print(f"Sequence 1: {s1}") ...@@ -441,8 +441,7 @@ print(f"Sequence 1: {s1}")
print(f"Gene: {g}") print(f"Gene: {g}")
``` ```
This is the result of the **execution**. We can see how the Gene object is printed diferently: This is the result of the **execution**:
``` ```
New sequence created! New sequence created!
New sequence created! New sequence created!
...@@ -458,12 +457,12 @@ On the other hand, if you have a look at the \_\_str\_\_ method in the **Seq Cla ...@@ -458,12 +457,12 @@ On the other hand, if you have a look at the \_\_str\_\_ method in the **Seq Cla
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-05.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/oop-05.png)
This means that there is a **sub-clas**s that is overriding this methods, as we already know. And that the Seq \_\_str\_\_ method is also overriding another one from its **super class** This means that there is a **sub-class** that is overriding this method. And that the Seq \_\_str\_\_ method is also overriding another one from its **super class** (generic)
## Installing libraries: termcolor ## Installing libraries: termcolor
There are many **python libraries** available for you to use. You only have to **install** them. As an example of how to do it, let's install the [termcolor](https://pypi.org/project/termcolor/) library. It will allow us to **print messages in color** on the **console** There are many **python libraries** available for you to use. You only have to **install** them. As an example of how to do it, let's install the [termcolor](https://pypi.org/project/termcolor/) library. It will allow us to **print messages in color** in the **console**
Create a **new python file** in the **Session-06** folder and call it **test-color-py**. Write this code: Create a **new python file** in the **Session-06** folder and call it **test-color-py**. Write this code:
...@@ -473,7 +472,7 @@ import termcolor ...@@ -473,7 +472,7 @@ import termcolor
termcolor.cprint("Hey! this is printed in green!", 'green') termcolor.cprint("Hey! this is printed in green!", 'green')
``` ```
You will see that the word **termcolor** is underlined in **red**. This is because Pycharm does not know anything about the termcolor module. You will see that the word **termcolor** is underlined in **red**. This is because Pycharm does not know anything about the termcolor module.
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/libraries-02.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/libraries-02.png)
...@@ -481,13 +480,13 @@ Place the **mouse pointer** on termcolor and a **new window** will pop up: ...@@ -481,13 +480,13 @@ Place the **mouse pointer** on termcolor and a **new window** will pop up:
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/libraries-01.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/libraries-01.png)
Click on the **install package termcolor** option. The package start the installation. After some seconds it is ready and the termcolor is no longer in red Click on the **install package termcolor** option. The package start the installation. After some seconds it will be ready so the termcolor word will be no longer in red
Now **run** the program. You will see a green message on the console Now **run** the program. You will see a green message:
![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/libraries-03.png) ![](https://github.com/myTeachingURJC/2019-2020-PNE/raw/master/s6-OOP/libraries-03.png)
You now have the power of printing in colors in the console. Use it wisely... You now have the power of printing in colors...use it wisely :)
## Exercises ## Exercises
... ...
......