{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "All the IPython Notebooks in this lecture series are available at https://github.com/rajathkumarmp/Python-Lectures" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#Classes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables, Lists, Dictionaries etc in python is a object. Without getting into the theory part of Object Oriented Programming, explanation of the concepts will be done along this tutorial." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A class is declared as follows" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "class class_name:\n", "\n", " Functions" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class FirstClass:\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**pass** in python means do nothing. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Above, a class object named \"FirstClass\" is declared now consider a \"egclass\" which has all the characteristics of \"FirstClass\". So all you have to do is, equate the \"egclass\" to \"FirstClass\". In python jargon this is called as creating an instance. \"egclass\" is the instance of \"FirstClass\"" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "egclass = FirstClass()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "instance" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(egclass)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "classobj" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(FirstClass)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let us add some \"functionality\" to the class. So that our \"FirstClass\" is defined in a better way. A function inside a class is called as a \"Method\" of that class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Most of the classes will have a function named \"\\_\\_init\\_\\_\". These are called as magic methods. In this method you basically initialize the variables of that class or any other initial algorithms which is applicable to all methods is specified in this method. A variable inside a class is called an attribute." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These helps simplify the process of initializing a instance. For example,\n", "\n", "Without the use of magic method or \\_\\_init\\_\\_ which is otherwise called as constructors. One had to define a **init( )** method and call the **init( )** function." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "eg0 = FirstClass()\n", "eg0.init()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But when the constructor is defined the \\_\\_init\\_\\_ is called thus intializing the instance created. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will make our \"FirstClass\" to accept two variables name and symbol.\n", "\n", "I will be explaining about the \"self\" in a while." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class FirstClass:\n", " def __init__(self,name,symbol):\n", " self.name = name\n", " self.symbol = symbol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have defined a function and added the \\_\\_init\\_\\_ method. We can create a instance of FirstClass which now accepts two arguments. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg1 = FirstClass('one',1)\n", "eg2 = FirstClass('two',2)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n" ] } ], "source": [ "print eg1.name, eg1.symbol\n", "print eg2.name, eg2.symbol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**dir( )** function comes very handy in looking into what the class contains and what all method it offers" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__']" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(FirstClass)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**dir( )** of an instance also shows it's defined attributes." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__', 'name', 'symbol']" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(eg1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Changing the FirstClass function a bit," ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class FirstClass:\n", " def __init__(self,name,symbol):\n", " self.n = name\n", " self.s = symbol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Changing self.name and self.symbol to self.n and self.s respectively will yield," ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg1 = FirstClass('one',1)\n", "eg2 = FirstClass('two',2)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "ename": "AttributeError", "evalue": "FirstClass instance has no attribute 'name'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0meg1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0meg1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msymbol\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0meg2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0meg2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msymbol\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mAttributeError\u001b[0m: FirstClass instance has no attribute 'name'" ] } ], "source": [ "print eg1.name, eg1.symbol\n", "print eg2.name, eg2.symbol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "AttributeError, Remember variables are nothing but attributes inside a class? So this means we have not given the correct attribute for the instance." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__', 'n', 's']" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(eg1)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n" ] } ], "source": [ "print eg1.n, eg1.s\n", "print eg2.n, eg2.s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So now we have solved the error. Now let us compare the two examples that we saw.\n", "\n", "When I declared self.name and self.symbol, there was no attribute error for eg1.name and eg1.symbol and when I declared self.n and self.s, there was no attribute error for eg1.n and eg1.s\n", "\n", "From the above we can conclude that self is nothing but the instance itself.\n", "\n", "Remember, self is not predefined it is userdefined. You can make use of anything you are comfortable with. But it has become a common practice to use self." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class FirstClass:\n", " def __init__(asdf1234,name,symbol):\n", " asdf1234.n = name\n", " asdf1234.s = symbol" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg1 = FirstClass('one',1)\n", "eg2 = FirstClass('two',2)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one 1\n", "two 2\n" ] } ], "source": [ "print eg1.n, eg1.s\n", "print eg2.n, eg2.s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since eg1 and eg2 are instances of FirstClass it need not necessarily be limited to FirstClass itself. It might extend itself by declaring other attributes without having the attribute to be declared inside the FirstClass." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg1.cube = 1\n", "eg2.cube = 8" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__', 'cube', 'n', 's']" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(eg1)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Just like global and local variables as we saw earlier, even classes have it's own types of variables.\n", "\n", "Class Attribute : attributes defined outside the method and is applicable to all the instances.\n", "\n", "Instance Attribute : attributes defined inside a method and is applicable to only that method and is unique to each instance." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class FirstClass:\n", " test = 'test'\n", " def __init__(self,name,symbol):\n", " self.name = name\n", " self.symbol = symbol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here test is a class attribute and name is a instance attribute." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg3 = FirstClass('Three',3)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "test Three\n" ] } ], "source": [ "print eg3.test, eg3.name" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us add some more methods to FirstClass." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class FirstClass:\n", " def __init__(self,name,symbol):\n", " self.name = name\n", " self.symbol = symbol\n", " def square(self):\n", " return self.symbol * self.symbol\n", " def cube(self):\n", " return self.symbol * self.symbol * self.symbol\n", " def multiply(self, x):\n", " return self.symbol * x" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg4 = FirstClass('Five',5)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "25\n", "125\n" ] } ], "source": [ "print eg4.square()\n", "print eg4.cube()" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eg4.multiply(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above can also be written as," ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "FirstClass.multiply(eg4,2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##Inheritance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There might be cases where a new class would have all the previous characteristics of an already defined class. So the new class can \"inherit\" the previous class and add it's own methods to it. This is called as inheritance." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Consider class SoftwareEngineer which has a method salary." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class SoftwareEngineer:\n", " def __init__(self,name,age):\n", " self.name = name\n", " self.age = age\n", " def salary(self, value):\n", " self.money = value\n", " print self.name,\"earns\",self.money" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = SoftwareEngineer('Kartik',26)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Kartik earns 40000\n" ] } ], "source": [ "a.salary(40000)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__', 'salary']" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(SoftwareEngineer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now consider another class Artist which tells us about the amount of money an artist earns and his artform." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class Artist:\n", " def __init__(self,name,age):\n", " self.name = name\n", " self.age = age\n", " def money(self,value):\n", " self.money = value\n", " print self.name,\"earns\",self.money\n", " def artform(self, job):\n", " self.job = job\n", " print self.name,\"is a\", self.job" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = Artist('Nitin',20)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nitin earns 50000\n", "Nitin is a Musician\n" ] } ], "source": [ "b.money(50000)\n", "b.artform('Musician')" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__', 'artform', 'money']" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(Artist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "money method and salary method are the same. So we can generalize the method to salary and inherit the SoftwareEngineer class to Artist class. Now the artist class becomes," ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class Artist(SoftwareEngineer):\n", " def artform(self, job):\n", " self.job = job\n", " print self.name,\"is a\", self.job" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [], "source": [ "c = Artist('Nishanth',21)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__', '__init__', '__module__', 'artform', 'salary']" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(Artist)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nishanth earns 60000\n", "Nishanth is a Dancer\n" ] } ], "source": [ "c.salary(60000)\n", "c.artform('Dancer')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Suppose say while inheriting a particular method is not suitable for the new class. One can override this method by defining again that method with the same name inside the new class." ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Artist(SoftwareEngineer):\n", " def artform(self, job):\n", " self.job = job\n", " print self.name,\"is a\", self.job\n", " def salary(self, value):\n", " self.money = value\n", " print self.name,\"earns\",self.money\n", " print \"I am overriding the SoftwareEngineer class's salary method\"" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c = Artist('Nishanth',21)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nishanth earns 60000\n", "I am overriding the SoftwareEngineer class's salary method\n", "Nishanth is a Dancer\n" ] } ], "source": [ "c.salary(60000)\n", "c.artform('Dancer')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If not sure how many times methods will be called it will become difficult to declare so many variables to carry each result hence it is better to declare a list and append the result." ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class emptylist:\n", " def __init__(self):\n", " self.data = []\n", " def one(self,x):\n", " self.data.append(x)\n", " def two(self, x ):\n", " self.data.append(x**2)\n", " def three(self, x):\n", " self.data.append(x**3)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [], "source": [ "xc = emptylist()" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1]\n" ] } ], "source": [ "xc.one(1)\n", "print xc.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since xc.data is a list direct list operations can also be performed." ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 8]\n" ] } ], "source": [ "xc.data.append(8)\n", "print xc.data" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 8, 9]\n" ] } ], "source": [ "xc.two(3)\n", "print xc.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If the number of input arguments varies from instance to instance asterisk can be used as shown." ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class NotSure:\n", " def __init__(self, *args):\n", " self.data = ''.join(list(args)) " ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [], "source": [ "yz = NotSure('I', 'Do' , 'Not', 'Know', 'What', 'To','Type')" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'IDoNotKnowWhatToType'" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yz.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#Where to go from here?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Practice alone can help you get the hang of python. Give your self problem statements and solve them. You can also sign up to any competitive coding platform for problem statements. The more you code the more you discover and the more you start appreciating the language.\n", "\n", "\n", "Now that you have been introduced to python, You can try out the different python libraries in the field of your interest. I highly recommend you to check out this curated list of Python frameworks, libraries and software http://awesome-python.com\n", "\n", "\n", "The official python documentation : https://docs.python.org/2/\n", "\n", "\n", "You can also check out Python practice programs written by my friend, Kartik Kannapur. Github Repo : https://github.com/rajathkumarmp/Python-Lectures \n", "\n", "\n", "Enjoy solving problem statements because life is short, you need python!\n", "\n", "\n", "Peace.\n", "\n", "\n", "Rajath Kumar M.P ( rajathkumar dot exe at gmail dot com)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }