Hello! Welcome to this new series of videos on Python programming. This time I want to focus on Object-oriented Programming. Object-oriented Programming (OOP) is a very powerful methodology that you have to learn if you want to be proficient in the Python programming language.
Object-oriented is a methodology, it's a way to structure your programs, a way to properly design components in a system that can work together. As any other methodology object-oriented has a theoretical part and then an implementation that differs from language to language. Python, being an object-oriented programming language has its own implementation which can be tricky for advanced programmers so it's definitely confusing beginners sometimes, so I believe it's worth digging into it in detail to understand what's going on behind the scenes. Well, if you are ready, let's dive into it. Let's start with the reason why object-oriented was invented. Here, in my Python notebook I defined a structure called Lift. With this structure we keep track of the status of a lift we know the floor the lift is at and the status of its doors which can be open or closed. The Python implementation of the structure is very simple. It's a list of two values, the first one is an integer representing in the floor, and the second one is a string. I can also create a function print_lift that prints out the status of a lift.
As you can see the function works, and it's important to note that this function doesn't change the values in the lift it just reads them from the variable and prints them on the screen. We know however that functions can modify data and we can create a function that changes the status of the doors of a lift. Let's call it open_lift, it accepts a lift and it changes the second element of the list from whatever it was before to open once again we can call the function and everything works. Please note however that this time the function changes the value of its inputs. In this third example I created another type of data which I called SecurityLift. A SecurityLift is pretty much the same thing as a Lift but it has a third value in the list which is another string locked or unlocked, and the idea is that I can open a SecurityLift only if it's unlocked. To work with a security lift we have to define a new function which is called open_security_lift and this time we have to first test the third element of the list before acting on the second element. As you can see this says: "if lift[2] is unlocked at that point you can set lift[1] to open". For the third time we can run the function and check that everything works. There is a problem, though. Not in the code itself but in the way we use it, namely we have to remember the connection between a lift and the open_lift function at the connection between a security lift and the open_security_lift function. Python doesn't understand the connection between the data structure and the function. There is nothing that connects a lift to the open_lift function and the security lifts to the open_security_lift function, and every time you has a programmer have to keep in mind something there is a chance to introduce a bug, so the question is: "can Python remember the connection between Lift and open_lift, and in general between a data structure and a function that works on that data structure and this is exactly why object-oriented was invented. Programmers were looking for a way to keep track of this connection in a language Before we start discussing how object-oriented sorts the problem of keeping track, between types and functions, let's discuss the word type itself. I already used it many times but it is important to define it. It's a word that we will use a lot in object-oriented, so it is good to be aware of its meaning.
In this picture you see an animal and I am pretty sure that everybody agrees this is a duck. Why do we say this is a duck? Well it has the correct colours, the proper form, and if this was an animation you could see it moving like a duck. So we said that the type of these animal is duck because it behaves like a duck and here behavior doesn't refer only to the way it moves but also to how it appears. Its appearance it's that of a duck, so it's a duck. But now we have a surprise. As you can see the animal we captured was not a duck but very sophisticated robot pretending to be a duck. So suddenly we say that the type of this thing is no more duck but robot. At this point however we are using the word type in a different way, because we are no more describing the external behaviour or appearance but the internal structure. So, these are the two different meanings of the word type. One is the "behavioural meaning" or, if you want, the "external meaning", and the other one is the "structural meaning" or the "internal meaning". The thing we have to learn as programmers generally speaking is that the behavioural meaning is more important. Whenever we connect to a system, through Internet for example, we are not interested in how the system has been implemented. We just want to know how the system behaves, how we can exchange data with it.
When we discussed language structures we call this external behaviour type. The term "duck typing" that you will hear a lot in Python and in other object-oriented programming languages was created in 2000 by Alex Martelli referring exactly to this external behaviour concept. The idea is that if you can make something behave like a duck you can call it a duck. In computer science terms there should be no difference between two structures implemented in different ways if they behave to same. So this is what I wanted to tell you in terms of the general theory of object-oriented. In the next video we will dig into the Python implementation, we will start coding in Python and see how we can keep track of this connection between types and functions and how the word type is implemented in Python itself. Thank you for watching!


