From 0783d13d98928f158cb6274ca5768bab7e61a844 Mon Sep 17 00:00:00 2001 From: lbtanh Date: Sun, 14 Mar 2021 10:40:20 +0700 Subject: [PATCH] add 2 folders --- .../.gitignore | 129 +++++++++ .../Class.ipynb | 272 ++++++++++++++++++ .../Employee Class Variable.ipynb | 107 +++++++ .../Employee Class.ipynb | 86 ++++++ .../Employee Dunder Method.ipynb | 86 ++++++ .../Employee Getter & Sette.ipynb | 86 ++++++ .../Employee Hierarchical Inheritance.ipynb | 94 ++++++ .../Employee Inheritance.ipynb | 95 ++++++ .../Employee Init Method.ipynb | 71 +++++ .../Employee Obj.ipynb | 94 ++++++ .../Employee Print Object.ipynb | 61 ++++ .../Employee Static Method.ipynb | 78 +++++ .../Employee isInstanse & isSubclass.ipynb | 103 +++++++ .../LICENSE | 201 +++++++++++++ .../README.md | 2 + Python-and-OOP-master/01-encapsulation-1.py | 41 +++ Python-and-OOP-master/02-encapsulation-2.py | 29 ++ Python-and-OOP-master/03-encapsulation-3.py | 56 ++++ .../04-init_constructor-1.py | 27 ++ .../05-init_constructor-2.py | 24 ++ .../06-class-attributes-1.py | 24 ++ .../07-class-attributes-2.py | 32 +++ .../08-class-instance-attributes-1.py | 35 +++ Python-and-OOP-master/09-inheritance-1.py | 34 +++ Python-and-OOP-master/10-inheritance-2.py | 47 +++ Python-and-OOP-master/11-polymorphism-1.py | 50 ++++ Python-and-OOP-master/12-polymorphism-2.py | 27 ++ .../13-inheriting-init-constructor-1.py | 21 ++ .../14-multiple-inheritance-1.py | 48 ++++ .../15-multiple-inheritance-2.py | 49 ++++ .../16-multiple-inheritance-3.py | 55 ++++ .../17-instance_methods-1.py | 21 ++ .../18-instance_methods-2.py | 51 ++++ Python-and-OOP-master/19-decorators-1.py | 55 ++++ Python-and-OOP-master/20-decorators-2.py | 35 +++ Python-and-OOP-master/21-decorators-3.py | 38 +++ Python-and-OOP-master/22-decorators-4.py | 34 +++ Python-and-OOP-master/23-decorators-5.py | 25 ++ Python-and-OOP-master/24-decorators-6.py | 23 ++ Python-and-OOP-master/25-decorators-7.py | 32 +++ Python-and-OOP-master/26-class-decorators.py | 39 +++ Python-and-OOP-master/27-classmethod-1.py | 46 +++ Python-and-OOP-master/28-classmethod-2.py | 45 +++ Python-and-OOP-master/29-staticmethod-1.py | 43 +++ Python-and-OOP-master/30-staticmethod-2.py | 38 +++ Python-and-OOP-master/31-magicmethods-1.py | 22 ++ Python-and-OOP-master/32-magicmethods-2.py | 19 ++ .../33-attribute-encapsulation-1.py | 0 Python-and-OOP-master/34-abstractclasses-1.py | 59 ++++ Python-and-OOP-master/35-abstractclasses-2.py | 58 ++++ Python-and-OOP-master/36-abstractclasses-3.py | 58 ++++ .../37-method-overloading-1.py | 56 ++++ .../38-method-overloading-2.py | 45 +++ .../39-method-overloading-3.py | 44 +++ Python-and-OOP-master/40-super-1.py | 28 ++ Python-and-OOP-master/41-super-2.py | 42 +++ Python-and-OOP-master/42-super-3.py | 35 +++ Python-and-OOP-master/README.md | 136 +++++++++ 58 files changed, 3291 insertions(+) create mode 100644 Object-Oriented-Programming-Using-Python-master/.gitignore create mode 100644 Object-Oriented-Programming-Using-Python-master/Class.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Class Variable.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Class.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Dunder Method.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Getter & Sette.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Hierarchical Inheritance.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Inheritance.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Init Method.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Obj.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Print Object.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee Static Method.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/Employee isInstanse & isSubclass.ipynb create mode 100644 Object-Oriented-Programming-Using-Python-master/LICENSE create mode 100644 Object-Oriented-Programming-Using-Python-master/README.md create mode 100644 Python-and-OOP-master/01-encapsulation-1.py create mode 100644 Python-and-OOP-master/02-encapsulation-2.py create mode 100644 Python-and-OOP-master/03-encapsulation-3.py create mode 100644 Python-and-OOP-master/04-init_constructor-1.py create mode 100644 Python-and-OOP-master/05-init_constructor-2.py create mode 100644 Python-and-OOP-master/06-class-attributes-1.py create mode 100644 Python-and-OOP-master/07-class-attributes-2.py create mode 100644 Python-and-OOP-master/08-class-instance-attributes-1.py create mode 100644 Python-and-OOP-master/09-inheritance-1.py create mode 100644 Python-and-OOP-master/10-inheritance-2.py create mode 100644 Python-and-OOP-master/11-polymorphism-1.py create mode 100644 Python-and-OOP-master/12-polymorphism-2.py create mode 100644 Python-and-OOP-master/13-inheriting-init-constructor-1.py create mode 100644 Python-and-OOP-master/14-multiple-inheritance-1.py create mode 100644 Python-and-OOP-master/15-multiple-inheritance-2.py create mode 100644 Python-and-OOP-master/16-multiple-inheritance-3.py create mode 100644 Python-and-OOP-master/17-instance_methods-1.py create mode 100644 Python-and-OOP-master/18-instance_methods-2.py create mode 100644 Python-and-OOP-master/19-decorators-1.py create mode 100644 Python-and-OOP-master/20-decorators-2.py create mode 100644 Python-and-OOP-master/21-decorators-3.py create mode 100644 Python-and-OOP-master/22-decorators-4.py create mode 100644 Python-and-OOP-master/23-decorators-5.py create mode 100644 Python-and-OOP-master/24-decorators-6.py create mode 100644 Python-and-OOP-master/25-decorators-7.py create mode 100644 Python-and-OOP-master/26-class-decorators.py create mode 100644 Python-and-OOP-master/27-classmethod-1.py create mode 100644 Python-and-OOP-master/28-classmethod-2.py create mode 100644 Python-and-OOP-master/29-staticmethod-1.py create mode 100644 Python-and-OOP-master/30-staticmethod-2.py create mode 100644 Python-and-OOP-master/31-magicmethods-1.py create mode 100644 Python-and-OOP-master/32-magicmethods-2.py create mode 100644 Python-and-OOP-master/33-attribute-encapsulation-1.py create mode 100644 Python-and-OOP-master/34-abstractclasses-1.py create mode 100644 Python-and-OOP-master/35-abstractclasses-2.py create mode 100644 Python-and-OOP-master/36-abstractclasses-3.py create mode 100644 Python-and-OOP-master/37-method-overloading-1.py create mode 100644 Python-and-OOP-master/38-method-overloading-2.py create mode 100644 Python-and-OOP-master/39-method-overloading-3.py create mode 100644 Python-and-OOP-master/40-super-1.py create mode 100644 Python-and-OOP-master/41-super-2.py create mode 100644 Python-and-OOP-master/42-super-3.py create mode 100644 Python-and-OOP-master/README.md diff --git a/Object-Oriented-Programming-Using-Python-master/.gitignore b/Object-Oriented-Programming-Using-Python-master/.gitignore new file mode 100644 index 00000000..b6e47617 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/Object-Oriented-Programming-Using-Python-master/Class.ipynb b/Object-Oriented-Programming-Using-Python-master/Class.ipynb new file mode 100644 index 00000000..d70955af --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Class.ipynb @@ -0,0 +1,272 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Blu is a bird\n", + "Woo is also a bird\n", + "Blu is 10 years old\n", + "Woo is 15 years old\n" + ] + } + ], + "source": [ + "class Parrot:\n", + "\n", + " # class attribute\n", + " species = \"bird\"\n", + "\n", + " # instance attribute\n", + " def __init__(self, name, age):\n", + " self.name = name\n", + " self.age = age\n", + "\n", + "\n", + "blu = Parrot(\"Blu\", 10)\n", + "woo = Parrot(\"Woo\", 15)\n", + "\n", + "print(\"Blu is a {}\".format(blu.species))\n", + "print(\"Woo is also a {}\".format(woo.species))\n", + "\n", + "# access the instance attributes\n", + "print(\"{} is {} years old\".format( blu.name, blu.age))\n", + "print(\"{} is {} years old\".format( woo.name, woo.age))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bird is ready\n", + "Penguin is ready\n", + "Penguin\n", + "Swim faster\n", + "Run faster\n" + ] + } + ], + "source": [ + "# parent class\n", + "class Bird:\n", + " \n", + " def __init__(self):\n", + " print(\"Bird is ready\")\n", + "\n", + " def whoisThis(self):\n", + " print(\"Bird\")\n", + "\n", + " def swim(self):\n", + " print(\"Swim faster\")\n", + "\n", + "# child class\n", + "class Penguin(Bird):\n", + "\n", + " def __init__(self):\n", + " # call super() function\n", + " super().__init__()\n", + " print(\"Penguin is ready\")\n", + "\n", + " def whoisThis(self):\n", + " print(\"Penguin\")\n", + "\n", + " def run(self):\n", + " print(\"Run faster\")\n", + "\n", + "peggy = Penguin()\n", + "peggy.whoisThis()\n", + "peggy.swim()\n", + "peggy.run()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Selling Price: 900\n", + "Selling Price: 900\n", + "Selling Price: 1000\n" + ] + } + ], + "source": [ + "### Encapsulation\n", + "class Computer:\n", + "\n", + " def __init__(self):\n", + " self.__maxprice = 900\n", + "\n", + " def sell(self):\n", + " print(\"Selling Price: {}\".format(self.__maxprice))\n", + "\n", + " def setMaxPrice(self, price):\n", + " self.__maxprice = price\n", + "\n", + "c = Computer()\n", + "c.sell()\n", + "\n", + "# change the price\n", + "c.__maxprice = 1000\n", + "c.sell()\n", + "\n", + "# using setter function\n", + "c.setMaxPrice(1000)\n", + "c.sell()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Parrot can fly\n", + "Penguin can't fly\n" + ] + } + ], + "source": [ + "### Polymorphism \n", + "class Parrot:\n", + "\n", + " def fly(self):\n", + " print(\"Parrot can fly\")\n", + " \n", + " def swim(self):\n", + " print(\"Parrot can't swim\")\n", + "\n", + "class Penguin:\n", + "\n", + " def fly(self):\n", + " print(\"Penguin can't fly\")\n", + " \n", + " def swim(self):\n", + " print(\"Penguin can swim\")\n", + "\n", + "# common interface\n", + "def flying_test(bird):\n", + " bird.fly()\n", + "\n", + "#instantiate objects\n", + "blu = Parrot()\n", + "peggy = Penguin()\n", + "\n", + "# passing the object\n", + "flying_test(blu)\n", + "flying_test(peggy)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rahul\n" + ] + } + ], + "source": [ + "# Python program to demonstrate error if we \n", + "# forget to invoke __init__() of parent. \n", + "\n", + "class A: \n", + " def __init__(self, n = 'Rahul'): \n", + " self.name = n \n", + "class B(A): \n", + " def __init__(self, roll): \n", + " A.__init__(self)\n", + " self.roll = roll \n", + "\n", + "object = B(23) \n", + "print(object.name) \n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "B\n" + ] + } + ], + "source": [ + "\n", + "\n", + "class A: \n", + " def __init__(self, n = 'A'): \n", + " self.name = n \n", + "class B: \n", + " def __init__(self, n = 'B'): \n", + " self.name = n \n", + "class D: \n", + " def __init__(self, n = 'D'): \n", + " self.name = n \n", + "\n", + "class C(A,B,D):\n", + " # def __init__(self): \n", + " # A.__init__(self)\n", + " # B.__init__(self)\n", + " pass\n", + " \n", + "\n", + "object = C()\n", + "print(object.name) \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Class Variable.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Class Variable.ipynb new file mode 100644 index 00000000..6030a066 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Class Variable.ipynb @@ -0,0 +1,107 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.04\n", + "1.04\n", + "1.04\n", + "1.04\n", + "100\n", + "1.04\n", + "{'__module__': '__main__', 'no_empl': 2, 'raise_amount': 1.04, '__init__': , 'print': , 'apply_raise': , '__dict__': , '__weakref__': , '__doc__': None}\n", + "{'first': 'Soumyadip', 'last': 'Chowdhury', 'email': 'Soumyadip.Chowdhury@python.com', 'pay': 900000, 'raise_amount': 100}\n", + "{'first': 'Soumyadip', 'last': 'Chowdhury', 'email': 'Soumyadip.Chowdhury@python.com', 'pay': 100000}\n", + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 90000000\n", + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 100000\n", + "No Of Employees 2\n", + "No Of Employees 2\n", + "No Of Employees 2\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " no_empl=0;\n", + " raise_amount=1.04\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " Employee.no_empl=Employee.no_empl+1\n", + " \n", + " \n", + " def print(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + " \n", + " def apply_raise(self):\n", + " self.pay=int(self.pay* self.raise_amount)\n", + " ## Can print using class,self and obj name \n", + " \n", + "emp_1=Employee(\"Soumyadip\",\"Chowdhury\",900000)\n", + "emp_2=Employee(\"Soumyadip\",\"Chowdhury\",100000)\n", + "\n", + "print(Employee.raise_amount)\n", + "print(emp_1.raise_amount)\n", + "print(emp_2.raise_amount)\n", + "\n", + "emp_1.raise_amount=100\n", + "\n", + "print(Employee.raise_amount)\n", + "print(emp_1.raise_amount)\n", + "print(emp_2.raise_amount)\n", + "\n", + "\n", + "print(Employee.__dict__)\n", + "print(emp_1.__dict__)\n", + "print(emp_2.__dict__)\n", + "\n", + "emp_1.apply_raise()\n", + "\n", + "print(emp_1.print())\n", + "print(emp_2.print())\n", + "\n", + "print(\"No Of Employees\",emp_1.no_empl)\n", + "print(\"No Of Employees\",emp_2.no_empl)\n", + "print(\"No Of Employees\",Employee.no_empl)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Class.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Class.ipynb new file mode 100644 index 00000000..81a020d5 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Class.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.04\n", + "1.04\n", + "Soumyadip\n", + "Hello\n" + ] + }, + { + "data": { + "text/plain": [ + "'Soumyadip Chowdhury s.c@python.com 100000'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class Employee:\n", + " \n", + " no_empl=0;\n", + " raise_amount=1.04\n", + " \n", + " def __init__(self):\n", + " self.first=\"Soumyadip\"\n", + " self.last=\"Chowdhury\"\n", + " self.email=\"s.c@python.com\"\n", + " self.pay=100000\n", + " Employee.no_empl=Employee.no_empl+1\n", + " \n", + " \n", + " def print(self):\n", + " print(\"Hello\")\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + " \n", + " \n", + " \n", + "emp_1=Employee()\n", + "print(Employee.raise_amount)\n", + "print(emp_1.raise_amount)\n", + "\n", + "print(emp_1.first)\n", + "emp_1.print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Dunder Method.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Dunder Method.ipynb new file mode 100644 index 00000000..143240ca --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Dunder Method.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Manager Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 [Developer Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 Python]\n", + "Manager Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 [Developer Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 Python]\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " def __repr__(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + "\n", + " \n", + "class Developer(Employee):\n", + " \n", + " \n", + " def __repr__(self):\n", + " return \"Developer Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.lang)\n", + " \n", + " def __init__(self,f ,l ,p ,lang ):\n", + " super().__init__(f,l,p)\n", + " self.lang=lang\n", + " \n", + "class Manager(Employee):\n", + " \n", + " def __repr__(self):\n", + " return (\"Manager Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.employees))\n", + " \n", + " def __init__(self,f ,l ,p ,employees=None):\n", + " super().__init__(f,l,p)\n", + " if employees is None:\n", + " self.employees=[]\n", + " else:\n", + " self.employees=employees\n", + " \n", + " def add(self, emp):\n", + " if emp not in self.employees:\n", + " self.employees.append(emp) \n", + " \n", + "dev_1=Developer(\"Soumyadip\",\"Chowdhury\",700000,\"Python\")\n", + "dev_2=Developer(\"Soumyadip\",\"Chowdhury\",900000,\"JAVA\")\n", + "man_1=Manager(\"Soumyadip\",\"Chowdhury\",700000,[dev_1])\n", + "\n", + "print(repr(man_1))\n", + "print(man_1.__repr__())\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Getter & Sette.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Getter & Sette.ipynb new file mode 100644 index 00000000..19baf996 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Getter & Sette.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 900000\n", + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 100000\n", + "Soumya Dip Soumyadip.Chowdhury@python.com 900000\n", + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 100000\n", + "Deleting\n", + "None None Soumyadip.Chowdhury@python.com 900000\n", + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 100000\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " @property # Getter\n", + " def setterEx(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + " \n", + " @setterEx.setter \n", + " def setterEx(self, name):\n", + " first, last=name.split(' ')\n", + " self.first=first\n", + " self.last=last\n", + " \n", + " @setterEx.deleter \n", + " def setterEx(self):\n", + " print(\"Deleting\")\n", + " self.first=None\n", + " self.last=None\n", + " \n", + "emp_1=Employee(\"Soumyadip\",\"Chowdhury\",900000)\n", + "emp_2=Employee(\"Soumyadip\",\"Chowdhury\",100000)\n", + "\n", + "print(emp_1.setterEx)\n", + "print(emp_2.setterEx)\n", + "\n", + "emp_1.setterEx=\"Soumya Dip\"\n", + "\n", + "print(emp_1.setterEx)\n", + "print(emp_2.setterEx)\n", + "\n", + "del emp_1.setterEx\n", + "\n", + "print(emp_1.setterEx)\n", + "print(emp_2.setterEx)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Hierarchical Inheritance.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Hierarchical Inheritance.ipynb new file mode 100644 index 00000000..2ce83511 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Hierarchical Inheritance.ipynb @@ -0,0 +1,94 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Developer Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 Python\n", + "Developer Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 900000 JAVA\n", + "Manager\n", + "Developer Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 Python\n", + "Developer Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 900000 JAVA\n", + "Manager Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 [<__main__.Developer object at 0x000001EFA8D30888>, <__main__.Developer object at 0x000001EFA8DF2088>]\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " def print(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + "\n", + " \n", + "class Developer(Employee):\n", + " \n", + " \n", + " def print(self):\n", + " return \"Developer Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.lang)\n", + " \n", + " def __init__(self,f ,l ,p ,lang ):\n", + " super().__init__(f,l,p)\n", + " self.lang=lang\n", + " \n", + "class Manager(Employee):\n", + " \n", + " def print(self):\n", + " print(\"Manager\")\n", + " for x in self.employees:\n", + " print(x.print())\n", + " print(\"Manager Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.employees))\n", + " \n", + " def __init__(self,f ,l ,p ,employees=None):\n", + " super().__init__(f,l,p)\n", + " if employees is None:\n", + " self.employees=[]\n", + " else:\n", + " self.employees=employees\n", + " \n", + " def add(self, emp):\n", + " if emp not in self.employees:\n", + " self.employees.append(emp) \n", + " \n", + "dev_1=Developer(\"Soumyadip\",\"Chowdhury\",700000,\"Python\")\n", + "dev_2=Developer(\"Soumyadip\",\"Chowdhury\",900000,\"JAVA\")\n", + "print(dev_1.print())\n", + "print(dev_2.print())\n", + "man_1=Manager(\"Soumyadip\",\"Chowdhury\",700000,[dev_1])\n", + "man_1.add(dev_2)\n", + "man_1.print()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Inheritance.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Inheritance.ipynb new file mode 100644 index 00000000..c87af5ec --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Inheritance.ipynb @@ -0,0 +1,95 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 700000 Python\n", + "Overring : Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 900000 JAVA\n", + "Help on class Developer in module __main__:\n", + "\n", + "class Developer(Employee)\n", + " | Developer(f, l, p, lang)\n", + " | \n", + " | Method resolution order:\n", + " | Developer\n", + " | Employee\n", + " | builtins.object\n", + " | \n", + " | Methods defined here:\n", + " | \n", + " | __init__(self, f, l, p, lang)\n", + " | Initialize self. See help(type(self)) for accurate signature.\n", + " | \n", + " | print(self)\n", + " | \n", + " | ----------------------------------------------------------------------\n", + " | Data descriptors inherited from Employee:\n", + " | \n", + " | __dict__\n", + " | dictionary for instance variables (if defined)\n", + " | \n", + " | __weakref__\n", + " | list of weak references to the object (if defined)\n", + "\n", + "None\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " def print(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + "\n", + " \n", + "class Developer(Employee):\n", + " def print(self):\n", + " return \"Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.lang)\n", + " \n", + " def __init__(self,f ,l ,p ,lang ):\n", + " super().__init__(f,l,p)\n", + " #Employee.__init__(self,f,l,p)\n", + " self.lang=lang\n", + " \n", + "dev_1=Developer(\"Soumyadip\",\"Chowdhury\",700000,\"Python\")\n", + "dev_2=Developer(\"Soumyadip\",\"Chowdhury\",900000,\"JAVA\")\n", + "print(dev_1.print())\n", + "print(dev_2.print())\n", + "print(help(Developer))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Init Method.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Init Method.ipynb new file mode 100644 index 00000000..0b272c50 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Init Method.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<__main__.Employee object at 0x0000020E598AEE88>\n", + "Soumyadip\n", + "Chowdhury\n", + "Soumyadip.Chowdhury@python.com\n", + "900000\n", + "<__main__.Employee object at 0x0000020E598AE108>\n", + "Soumyadip\n", + "Chowdhury\n", + "Soumyadip.Chowdhury@python.com\n", + "100000\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " \n", + "emp_1=Employee(\"Soumyadip\",\"Chowdhury\",900000)\n", + "emp_2=Employee(\"Soumyadip\",\"Chowdhury\",100000)\n", + "print(emp_1)\n", + "print(emp_1.first)\n", + "print(emp_1.last)\n", + "print(emp_1.email)\n", + "print(emp_1.pay )\n", + "print(emp_2)\n", + "print(emp_2.first)\n", + "print(emp_2.last)\n", + "print(emp_2.email)\n", + "print(emp_2.pay )" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Obj.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Obj.ipynb new file mode 100644 index 00000000..5f46e8f1 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Obj.ipynb @@ -0,0 +1,94 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class Employee:\n", + " pass\n", + "\n", + "emp_1=Employee()\n", + "emp_2=Employee()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<__main__.Employee object at 0x000001D9F490C2C8>\n", + "<__main__.Employee object at 0x000001D9F490C308>\n" + ] + } + ], + "source": [ + "print(emp_1)\n", + "print(emp_2)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "emp_1.first=\"Soumyadip\"\n", + "emp_1.last=\"Chowdhury\"\n", + "emp_1.email=\"soumyadip.cmp@gmail.com\"\n", + "emp_1.pay=90000" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<__main__.Employee object at 0x000001D9F490C2C8>\n", + "Soumyadip\n", + "Chowdhury\n", + "soumyadip.cmp@gmail.com\n", + "90000\n" + ] + } + ], + "source": [ + "print(emp_1)\n", + "print(emp_1.first)\n", + "print(emp_1.last)\n", + "print(emp_1.email)\n", + "print(emp_1.pay )" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Print Object.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Print Object.ipynb new file mode 100644 index 00000000..400fe227 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Print Object.ipynb @@ -0,0 +1,61 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Soumyadip Chowdhury Soumyadip.Chowdhury@python.com 900000\n", + "Bristi Biswas Bristi.Biswas@python.com 100000\n", + "True\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " def print(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + " \n", + "\n", + "emp_1=Employee(\"Soumyadip\",\"Chowdhury\",900000)\n", + "emp_2=Employee(\"Bristi\",\"Biswas\",100000)\n", + "print(emp_1.print())\n", + "print(emp_2.print())\n", + "\n", + "print(isinstance(emp_1,Employee))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee Static Method.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee Static Method.ipynb new file mode 100644 index 00000000..58759768 --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee Static Method.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n", + "True\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " no_empl=0;\n", + " raise_amount=1.04\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " Employee.no_empl=Employee.no_empl+1\n", + " \n", + " \n", + " def print(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + " \n", + " def apply_raise(self):\n", + " self.pay=int(self.pay* self.raise_amount)\n", + " ## Can print using class,self and obj name \n", + " \n", + " @staticmethod\n", + " def is_workng(day):\n", + " if day.weekday() == 5 or day.weekday() == 6:\n", + " return False\n", + " return True\n", + " \n", + "emp_1=Employee(\"Soumyadip\",\"Chowdhury\",900000)\n", + "emp_2=Employee(\"Soumyadip\",\"Chowdhury\",100000)\n", + "\n", + "import datetime\n", + "\n", + "myBday=datetime.date(2020,3,19)\n", + "print(Employee.is_workng(myBday))\n", + "print(emp_1.is_workng(myBday))\n", + "print(emp_2.is_workng(myBday))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/Employee isInstanse & isSubclass.ipynb b/Object-Oriented-Programming-Using-Python-master/Employee isInstanse & isSubclass.ipynb new file mode 100644 index 00000000..72c7cc2e --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/Employee isInstanse & isSubclass.ipynb @@ -0,0 +1,103 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n", + "True\n", + "False\n", + "True\n", + "True\n", + "True\n", + "(, )\n", + "False\n" + ] + } + ], + "source": [ + "class Employee:\n", + " \n", + " def __init__(self,f ,l ,p ):\n", + " self.first=f\n", + " self.last=l\n", + " self.email=f+\".\"+l+\"@python.com\"\n", + " self.pay=p\n", + " \n", + " def print(self):\n", + " return \"{} {} {} {}\".format(self.first,self.last,self.email,self.pay)\n", + "\n", + " \n", + "class Developer(Employee):\n", + " \n", + " \n", + " def print(self):\n", + " return \"Developer Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.lang)\n", + " \n", + " def __init__(self,f ,l ,p ,lang ):\n", + " super().__init__(f,l,p)\n", + " self.lang=lang\n", + " \n", + "class Manager(Employee):\n", + " \n", + " def print(self):\n", + " for x in self.employees:\n", + " print(x.print())\n", + " print(\"Manager Overring : {} {} {} {} {}\".format(self.first,self.last,self.email,self.pay,self.employees))\n", + " \n", + " def __init__(self,f ,l ,p ,employees=None):\n", + " super().__init__(f,l,p)\n", + " if employees is None:\n", + " self.employees=[]\n", + " else:\n", + " self.employees=employees\n", + " \n", + " def add(self, emp):\n", + " if emp not in self.employees:\n", + " self.employees.append(emp) \n", + " \n", + "dev_1=Developer(\"Soumyadip\",\"Chowdhury\",700000,\"Python\")\n", + "dev_2=Developer(\"Soumyadip\",\"Chowdhury\",900000,\"JAVA\")\n", + "man_1=Manager(\"Soumyadip\",\"Chowdhury\",700000,[dev_1])\n", + "\n", + "print(isinstance(dev_1,Developer))\n", + "print(isinstance(dev_1,Manager))\n", + "print(isinstance(man_1,Manager))\n", + "print(isinstance(man_1,Developer))\n", + "print(isinstance(dev_1,Employee))\n", + "print(isinstance(man_1,Employee))\n", + "\n", + "print(issubclass(Developer,Employee))\n", + "print((Manager,Employee))\n", + "print(issubclass(Manager,Developer))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Object-Oriented-Programming-Using-Python-master/LICENSE b/Object-Oriented-Programming-Using-Python-master/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Object-Oriented-Programming-Using-Python-master/README.md b/Object-Oriented-Programming-Using-Python-master/README.md new file mode 100644 index 00000000..2d75e1fb --- /dev/null +++ b/Object-Oriented-Programming-Using-Python-master/README.md @@ -0,0 +1,2 @@ +# Object-Oriented-Programming-Using-Python +Python is a multi-paradigm programming language. Meaning, it supports different programming approach. One of the popular approach to solve a programming problem is by creating objects. This is known as Object-Oriented Programming (OOP). diff --git a/Python-and-OOP-master/01-encapsulation-1.py b/Python-and-OOP-master/01-encapsulation-1.py new file mode 100644 index 00000000..7954dac4 --- /dev/null +++ b/Python-and-OOP-master/01-encapsulation-1.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +# encapsulation-1.py + +# Encapsulation means to preserve data in classes using methods +# Here, we're setting the 'val' attribute through 'set_val()'. +# See the next example, `encapsulation-2.py` for more info + +# In this example, we have two methods, `set_val` and `get_val`. +# The first one sets the `val` value while the second one +# prints/returns the value. + + +class MyClass(object): + + def set_val(self, val): + self.value = val + + def get_val(self): + print(self.value) + return self.value + +a = MyClass() +b = MyClass() + +a.set_val(10) +b.set_val(100) + +a.get_val() +b.get_val() + +# NOTE: If you run this code, it won't print anything to the screen. +# This is because, even if we're calling `a.get_val()` and `b.get_val()`, +# the `get_val()` function doesn't contain a `print()` function. +# If we want to get the output printed to screen, we should do any of +# the following: + +# a) Either replace `return self.value` with `print(self.value)` +# or add a print statement **above** `return` as `print(self.value)`. + +# b) Remove `return(self.value)` and replace it with `print(self.value)` \ No newline at end of file diff --git a/Python-and-OOP-master/02-encapsulation-2.py b/Python-and-OOP-master/02-encapsulation-2.py new file mode 100644 index 00000000..4b6e824f --- /dev/null +++ b/Python-and-OOP-master/02-encapsulation-2.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +# encapsulation-2.py + +# This example builds on top of `encapsulation-1.py`. +# Here we see how we can set values in methods without +# going through the method itself, ie.. how we can break +# encapsulation. + +# NOTE: BREAKING ENCAPSULATION IS BAD. + + +class MyClass(object): + def set_val(self, val): + self.value = val + + def get_val(self): + print(self.value) + +a = MyClass() +b = MyClass() + +a.set_val(10) +b.set_val(1000) +a.value = 100 # <== Overriding `set_value` directly +# <== ie.. Breaking encapsulation + +a.get_val() +b.get_val() diff --git a/Python-and-OOP-master/03-encapsulation-3.py b/Python-and-OOP-master/03-encapsulation-3.py new file mode 100644 index 00000000..5411ee0f --- /dev/null +++ b/Python-and-OOP-master/03-encapsulation-3.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +# 03-encapsulation-3.py + +# Here we look at another example, where we have three methods +# set_val(), get_val(), and increment_val(). + +# set_val() helps to set a value, get_val() prints the value, +# and increment_val() increments the set value by 1. + +# We can still break encapsulation here by calling 'self.value' +# directly in an instance, which is **BAD**. + +# set_val() forces us to input an integer, ie.. what the code wants +# to work properly. Here, it's possible to break the encapsulation by +# calling 'self.val` directly, which will cause unexpected results later. +# In this example, the code is written to enforce an intger as input, if we +# don't break encapsulation and go through the gateway 'set_val()' + +# + + +class MyInteger(object): + def set_val(self, val): + try: + val = int(val) + except ValueError: + return + self.val = val + + def get_val(self): + print(self.val) + + def increment_val(self): + self.val = self.val + 1 + print(self.val) + +a = MyInteger() +a.set_val(10) +a.get_val() +a.increment_val() +print("\n") + +# Trying to break encapsulation in a new instance with an int +c = MyInteger() +c.val = 15 +c.get_val() +c.increment_val() +print("\n") + +# Trying to break encapsulation in a new instance with a str +b = MyInteger() +b.val = "MyString" # <== Breaking encapsulation, works fine +b.get_val() # <== Prints the val set by breaking encap +b.increment_val() # This will fail, since str + int wont work +print("\n") diff --git a/Python-and-OOP-master/04-init_constructor-1.py b/Python-and-OOP-master/04-init_constructor-1.py new file mode 100644 index 00000000..12e1fb4e --- /dev/null +++ b/Python-and-OOP-master/04-init_constructor-1.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +# 04-init_constructor.py + +# __init__() is a constructor method which helps to +# set initial values while instatiating a class. + +# __init__() will get called with the attributes set in __init__(), +# when a class is instantiated. + +# The '__' before and after the method name denotes that +# the method is private. It's called private or magic methods +# since it's called internally and automatically. + + +class MyNum(object): + def __init__(self): + print("Calling the __init__() constructor!\n") + self.val = 0 + + def increment(self): + self.val = self.val + 1 + print(self.val) + +dd = MyNum() +dd.increment() # will print 1 +dd.increment() # will print 2 diff --git a/Python-and-OOP-master/05-init_constructor-2.py b/Python-and-OOP-master/05-init_constructor-2.py new file mode 100644 index 00000000..82077656 --- /dev/null +++ b/Python-and-OOP-master/05-init_constructor-2.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +# 05-init_constructor-2.py + +# We add a test in the __init__() constructor to check +# if 'value' is an int or not. + + +class MyNum(object): + def __init__(self, value): + try: + value = int(value) + except ValueError: + value = 0 + self.value = value + + def increment(self): + self.value = self.value + 1 + print(self.value) + + +a = MyNum(10) +a.increment() # This should print 11 +a.increment() # This should print 12 diff --git a/Python-and-OOP-master/06-class-attributes-1.py b/Python-and-OOP-master/06-class-attributes-1.py new file mode 100644 index 00000000..8687ac87 --- /dev/null +++ b/Python-and-OOP-master/06-class-attributes-1.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python2.7 + +# 06-class-attributes-1.py + +# Here we define an attribute under the class `YourClass` +# as well as an attribute within the function. + +# The attribute defined in the class is called `class attributes` +# and the attribute defined in the function is called `instance attributes`. + + +class YourClass(object): + classy = 10 + + def set_val(self): + self.insty = 100 + +dd = YourClass() +dd.classy # This will fetch the class attribute 10. +dd.set_val() +dd.insty # This will fetch the instance attribute 100. + +# Once `dd` is instantiated, we can access both the class and instance +# attributes, ie.. dd.classy and dd.insty. diff --git a/Python-and-OOP-master/07-class-attributes-2.py b/Python-and-OOP-master/07-class-attributes-2.py new file mode 100644 index 00000000..7a6e4d52 --- /dev/null +++ b/Python-and-OOP-master/07-class-attributes-2.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# 07-class-attributes-2.py + +# The code below shows two important points: + +# a) A class attribute can be overridden in an instance, even +# though it is bad due to breaking Encapsulation. + +# b) There is a lookup path for attributes in Python. The first being +# the method defined within the class, and then the class above it. + +# We are overriding the 'classy' class attribute in the instance 'dd'. +# When it's overridden, the python interpreter reads the overridden value. +# But once the new value is deleted with 'del', the overridden value is no longer +# present in the instance, and hence the lookup goes a level above and gets it from +# the class. + + +class YourClass(object): + classy = "class value" + +dd = YourClass() +print(dd.classy) # < This should return the string "class value" + +dd.classy = "Instance value" +print(dd.classy) # This should return the string "Instance value" + +# This will delete the value set for 'dd.classy' in the instance. +del dd.classy +# Since the overriding attribute was deleted, this will print 'class value'. +print(dd.classy) diff --git a/Python-and-OOP-master/08-class-instance-attributes-1.py b/Python-and-OOP-master/08-class-instance-attributes-1.py new file mode 100644 index 00000000..c0e4cfa6 --- /dev/null +++ b/Python-and-OOP-master/08-class-instance-attributes-1.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +# 08-class-instance-attributes-1.py + +# This code shows that an Instance can access it's own +# attributes as well as Class attributes. + +# We have a class attribute named 'count', and we add 1 to +# it each time we create an instance. This can help count the +# number of instances at the time of instantiation. + + +class InstanceCounter(object): + count = 0 + + def __init__(self, val): + self.val = val + InstanceCounter.count += 1 + + def set_val(self, newval): + self.val = newval + + def get_val(self): + print(self.val) + + def get_count(self): + print(InstanceCounter.count) + +a = InstanceCounter(5) +b = InstanceCounter(10) +c = InstanceCounter(15) + +for obj in (a, b, c): + print("value of obj: %s" % obj.get_val()) + print("Count : %s" % obj.get_count()) diff --git a/Python-and-OOP-master/09-inheritance-1.py b/Python-and-OOP-master/09-inheritance-1.py new file mode 100644 index 00000000..d60a0ce6 --- /dev/null +++ b/Python-and-OOP-master/09-inheritance-1.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +# 09-inheritance-1.py + +# The code below shows how a class can inherit from another class. +# We have two classes, `Date` and `Time`. Here `Time` inherits from +# `Date`. + +# Any class inheriting from another class (also called a Parent class) +# inherits the methods and attributes from the Parent class. + +# Hence, any instances created from the class `Time` can access +# the methods defined in the parent class `Date`. + + +class Date(object): + def get_date(self): + print("2016-05-14") + + +class Time(Date): + def get_time(self): + print("07:00:00") + +# Creating an instance from `Date` +dt = Date() +dt.get_date() # Accesing the `get_date()` method of `Date` +print("--------") + +# Creating an instance from `Time`. +tm = Time() +tm.get_time() # Accessing the `get_time()` method from `Time`. +# Accessing the `get_date() which is defined in the parent class `Date`. +tm.get_date() diff --git a/Python-and-OOP-master/10-inheritance-2.py b/Python-and-OOP-master/10-inheritance-2.py new file mode 100644 index 00000000..708bf24f --- /dev/null +++ b/Python-and-OOP-master/10-inheritance-2.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +# 10-inheritance-2.py + +# The code below shows another example of inheritance +# Dog and Cat are two classes which inherits from Animal. +# This an instance created from Dog or Cat can access the methods +# in the Animal class, ie.. eat(). + +# The instance of 'Dog' can access the methods of the Dog class +# and it's parent class 'Animal'. + +# The instance of 'Cat' can access the methods of the Cat class +# and it's parent class 'Animal'. + +# But the instance created from 'Cat' cannot access the attributes +# within the 'Dog' class, and vice versa. + +class Animal(object): + def __init__(self, name): + self.name = name + + def eat(self, food): + print("%s is eating %s" % (self.name, food)) + +class Dog(Animal): + def fetch(self, thing): + print("%s goes after the %s" % (self.name, thing)) + +class Cat(Animal): + def swatstring(self): + print("%s shred the string!" % self.name) + +d = Dog("Roger") +c = Cat("Fluffy") + +d.fetch("paper") +d.eat("dog food") +print("--------") +c.eat("cat food") +c.swatstring() + +# The below methods would fail, since the instances doesn't have +# have access to the other class. + +c.fetch("frizbee") +d.swatstring() \ No newline at end of file diff --git a/Python-and-OOP-master/11-polymorphism-1.py b/Python-and-OOP-master/11-polymorphism-1.py new file mode 100644 index 00000000..a695822a --- /dev/null +++ b/Python-and-OOP-master/11-polymorphism-1.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +# 11-polymorphism-1.py + +# Polymorphism means having the same interface/attributes in different +# classes. + +# Polymorphism is the characteristic of being able to assign +# a different meaning or usage in different contexts. +# A not-so-clear/clean example is, different classes can have +# the same function name. + +# Here, the class Dog and Cat has the same method named 'show_affection' +# Even if they are same, both does different actions in the instance. +# +# Since the order of the lookup is +# 'instance' -> 'class' -> 'parent class', even if the +# 'class' and 'parent class' has functions with the same name, +# the instance will only pick up the first hit, +# ie.. from the 'class' and won't go to the parent class. + + +class Animal(object): + + def __init__(self, name): + self.name = name + + def eat(self, food): + print('{0} eats {1}'.format(self.name, food)) + + +class Dog(Animal): + + def fetch(self, thing): + print('{0} goes after the {1}!'.format(self.name, thing)) + + def show_affection(self): + print('{0} wags tail'.format(self.name)) + + +class Cat(Animal): + + def swatstring(self): + print('{0} shreds more string'.format(self.name)) + + def show_affection(self): + print('{0} purrs'.format(self.name)) + +for a in (Dog('Rover'), Cat('Fluffy'), Cat('Lucky'), Dog('Scout')): + a.show_affection() diff --git a/Python-and-OOP-master/12-polymorphism-2.py b/Python-and-OOP-master/12-polymorphism-2.py new file mode 100644 index 00000000..80eddbb8 --- /dev/null +++ b/Python-and-OOP-master/12-polymorphism-2.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +# 12-polymorphism-2.py + +# Another example for Polymorphism are the several inbuilt +# functions in Python. Take for example, the builtin function +# called 'len'. + +# 'len' is available for almost all types, such as strings, +# ints, floats, dictionaries, lists, tuples etc.. +# When len is called on a type, it actually calls the inbuilts +# private function 'len' on that type or __len__ + +# Every object type that supports 'len' will have a private +# 'len' function inbuilt. + +# Hence, for example, a list type already has a 'len()' +# function inbuilt in the Python code, and when you run the +# len() function on the data type, it checks if the len +# private function is available for that type or not. +# If it is available, it runs that. + +text = ["Hello", "Hola", "helo"] +print(len(text)) + +print(len("Hello")) +print(len({'a': 1, 'b': 2, 'c': 3})) diff --git a/Python-and-OOP-master/13-inheriting-init-constructor-1.py b/Python-and-OOP-master/13-inheriting-init-constructor-1.py new file mode 100644 index 00000000..1650fd5f --- /dev/null +++ b/Python-and-OOP-master/13-inheriting-init-constructor-1.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +# 13-inheriting-init-constructor-1.py + +# This is a normal inheritance example from which we build +# the next example. Make sure to read and understand the +# next example '14-inheriting-init-constructor-2.py'. + + +class Animal(object): + def __init__(self, name): + self.name = name + + +class Dog(Animal): + def fetch(self, thing): + print('%s goes after the %s' % (self.name, thing)) + +d = Dog("Roger") +print "The dog's name is", d.name +d.fetch("frizbee") diff --git a/Python-and-OOP-master/14-multiple-inheritance-1.py b/Python-and-OOP-master/14-multiple-inheritance-1.py new file mode 100644 index 00000000..5d32afd2 --- /dev/null +++ b/Python-and-OOP-master/14-multiple-inheritance-1.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# 14-multiple-inheritance-1.py + +# Python supports multiple inheritance and uses a depth-first order +# when searching for methods. +# This search pattern is call MRO (Method Resolution Order) + +# This is the first example, which shows the lookup of a common +# function named 'dothis()', which we'll continue in other examples. + +# As per the MRO output, it starts in class D, then B, A, and lastly C. + +# Both A and C contains 'dothis()'. Let's trace how the lookup happens. + +# As per the MRO output, it starts in class D, then B, A, and lastly C. + +# class `A` defines 'dothis()' and the search ends there. It doesn't go to C. + +# The MRO will show the full resolution path even if the full path is +# not traversed. + +# The method lookup flow in this case is : D -> B -> A -> C + + +class A(object): + + def dothis(self): + print("doing this in A") + + +class B(A): + pass + + +class C(object): + def dothis(self): + print("doing this in C") + + +class D(B, C): + pass + +d_instance = D() +d_instance.dothis() # <== This should print from class A. + +print("\nPrint the Method Resolution Order") +print(D.mro()) diff --git a/Python-and-OOP-master/15-multiple-inheritance-2.py b/Python-and-OOP-master/15-multiple-inheritance-2.py new file mode 100644 index 00000000..01d561fc --- /dev/null +++ b/Python-and-OOP-master/15-multiple-inheritance-2.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +# 15-multiple-inheritance-2.py + +# Python supports multiple inheritance + +# It uses a depth-first order when searching for methods. +# This search pattern is call MRO (Method Resolution Order) + +# This is a second example, which shows the lookup of 'dothis()'. +# Both A and C contains 'dothis()'. Let's trace how the lookup happens. + +# As per the MRO output using depth-first search, +# it starts in class D, then B, A, and lastly C. + +# Here we're looking for 'dothis()' which is defined in class `C`. +# The lookup goes from D -> B -> A -> C. + +# Since class `A` doesn't have `dothis()`, the lookup goes back to class `C` +# and finds it there. + + +class A(object): + + def dothat(self): + print("Doing this in A") + + +class B(A): + pass + + +class C(object): + + def dothis(self): + print("\nDoing this in C") + + +class D(B, C): + """Multiple Inheritance, + D inheriting from both B and C""" + pass + +d_instance = D() + +d_instance.dothis() + +print("\nPrint the Method Resolution Order") +print(D.mro()) diff --git a/Python-and-OOP-master/16-multiple-inheritance-3.py b/Python-and-OOP-master/16-multiple-inheritance-3.py new file mode 100644 index 00000000..036b8759 --- /dev/null +++ b/Python-and-OOP-master/16-multiple-inheritance-3.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# 16-multiple-inheritance-3.py + +# Python supports multiple inheritance +# and uses a depth-first order when searching for methods. +# This search pattern is call MRO (Method Resolution Order) + +# Example for "Diamond Shape" inheritance +# Lookup can get complicated when multiple classes inherit +# from multiple parent classes. + +# In order to avoid ambiguity while doing a lookup for a method +# in various classes, from Python 2.3, the MRO lookup order has an +# additional feature. + +# It still does a depth-first lookup, but if the occurrence of a class +# happens multiple times in the MRO path, it removes the initial occurrence +# and keeps the latter. + +# In the example below, class `D` inherits from `B` and `C`. +# And both `B` and `C` inherits from `A`. +# Both `A` and `C` has the method `dothis()`. + +# We instantiate `D` and requests the 'dothis()' method. +# By default, the lookup should go D -> B -> A -> C -> A. +# But from Python 2.3, in order to reduce the lookup time, +# the MRO skips the classes which occur multiple times in the path. + +# Hence the lookup will be D -> B -> C -> A. + + +class A(object): + + def dothis(self): + print("doing this in A") + + +class B(A): + pass + + +class C(A): + def dothis(self): + print("doing this in C") + + +class D(B, C): + pass + +d_instance = D() +d_instance.dothis() + +print("\nPrint the Method Resolution Order") +print(D.mro()) diff --git a/Python-and-OOP-master/17-instance_methods-1.py b/Python-and-OOP-master/17-instance_methods-1.py new file mode 100644 index 00000000..179f6b1b --- /dev/null +++ b/Python-and-OOP-master/17-instance_methods-1.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +# 17-instance_methods-1.py + +# Instance methods are also known as Bound methods since the methods +# within a class are bound to the instance created from the class, via +# 'self'. + + +class A(object): + def method(*argv): + return argv + +a = A() +print(a.method) + +# The print() function will print the following : +# python 17-instance_methods-1.py +# > + +# The output shows that 'method' is a bound method diff --git a/Python-and-OOP-master/18-instance_methods-2.py b/Python-and-OOP-master/18-instance_methods-2.py new file mode 100644 index 00000000..572e2797 --- /dev/null +++ b/Python-and-OOP-master/18-instance_methods-2.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +# 18-instance_methods.py + +# Instance methods are the normal way of accessing methods, seen in all +# classes till now. ie.. by instantiating instances from a class, and +# access the methods within the class. The usage of `self` is very +# important in instance methods due to `self` being a hook/handle to the +# instance itself, or the instance itself. + +# We look into a previous example, once more, to understand `Instance methods`. + +# We have an __init__() constructor, and three methods within the +# `InstanceCounter` class. + +# Three instances a, b, and c are created from the class `InstanceCounter`. + +# Since the methods defined in the class are accessed through the +# instances 'a', 'b', and 'c', these methods are called 'Instance +# methods'. + +# Since the instance is bound to the methods defined in the class by the +# keyword `self`, we also call `Instance methods` as 'Bound methods'. + +# In the code below, the instance is `obj` (the iterator) and we access +# each method as `obj.set_val()`, `obj.get_val()`, and `obj.get_count`. + + +class InstanceCounter(object): + count = 0 + + def __init__(self, val): + self.val = val + InstanceCounter.count += 1 + + def set_val(self, newval): + self.val = newval + + def get_val(self): + return self.val + + def get_count(self): + return InstanceCounter.count + +a = InstanceCounter(5) +b = InstanceCounter(10) +c = InstanceCounter(15) + +for obj in (a, b, c): + print("Value of object: %s" % (obj.get_val)) + print("Count : %s " % (obj.get_count)) diff --git a/Python-and-OOP-master/19-decorators-1.py b/Python-and-OOP-master/19-decorators-1.py new file mode 100644 index 00000000..9a9244cc --- /dev/null +++ b/Python-and-OOP-master/19-decorators-1.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# 19-decorators-1.py +# Decorators, as simple as it gets :) + +# Reference: Decorators 101 - A Gentle Introduction to Functional Programming. +# By Jillian Munson - PyGotham 2014. +# https://www.youtube.com/watch?v=yW0cK3IxlHc + +# Decorators are functions that compliment other functions, +# or in other words, modify a function or method. + +# In the example below, we have a function named `decorated`. +# This function just prints "This happened". +# We have a decorator created named `inner_decorator()`. +# This decorator function has an function within, which +# does some operations (print stuff for simplicity) and then +# returns the return-value of the internal function. + +# How does it work? +# a) The function `decorated()` gets called. +# b) Since the decorator `@my_decorator` is defined above +# `decorated()`, `my_decorator()` gets called. +# c) my_decorator() takes a function name as args, and hence `decorated()` +# gets passed as the arg. +# d) `my_decorator()` does it's job, and when it reaches `myfunction()` +# calls the actual function, ie.. decorated() +# e) Once the function `decorated()` is done, it gets back to `my_decorator()`. +# f) Hence, using a decorator can drastically change the behavior of the +# function you're actually executing. + + +def my_decorator(my_function): # <-- (4) + def inner_decorator(): # <-- (5) + print("This happened before!") # <-- (6) + my_function() # <-- (7) + print("This happens after ") # <-- (10) + print("This happened at the end!") # <-- (11) + return inner_decorator + # return None + + +@my_decorator # <-- (3) +def my_decorated(): # <-- (2) <-- (8) + print("This happened!") # <-- (9) + +if __name__ == '__main__': + my_decorated() # <-- (1) + +# This prints: +# # python 19-decorators-1.py +# This happened before! +# This happened! +# This happens after +# This happened at the end! diff --git a/Python-and-OOP-master/20-decorators-2.py b/Python-and-OOP-master/20-decorators-2.py new file mode 100644 index 00000000..9d3e8e15 --- /dev/null +++ b/Python-and-OOP-master/20-decorators-2.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +# Reference: Decorators 101 - A Gentle Introduction to Functional Programming. +# By Jillian Munson - PyGotham 2014. +# https://www.youtube.com/watch?v=yW0cK3IxlHc + +# 20-decorators-2.py +# An updated version of 19-decorators-1.py + +# This code snippet takes the previous example, and add a bit more information +# to the output. + +import datetime + + +def my_decorator(inner): + def inner_decorator(): + print(datetime.datetime.utcnow()) + inner() + print(datetime.datetime.utcnow()) + return inner_decorator + + +@my_decorator +def decorated(): + print("This happened!") + +if __name__ == "__main__": + decorated() + +# This will print: (NOTE: The time will change of course :P) +# # python 20-decorators-2.py +# 2016-05-29 11:46:07.444330 +# This happened! +# 2016-05-29 11:46:07.444367 diff --git a/Python-and-OOP-master/21-decorators-3.py b/Python-and-OOP-master/21-decorators-3.py new file mode 100644 index 00000000..d7b48998 --- /dev/null +++ b/Python-and-OOP-master/21-decorators-3.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +# Reference: Decorators 101 - A Gentle Introduction to Functional Programming. +# By Jillian Munson - PyGotham 2014. +# https://www.youtube.com/watch?v=yW0cK3IxlHc + +# This is an updated version of 20-decorators-2.py. +# Here, the `decorated()` function takes an argument +# and prints it back on terminal. + +# When the decorator `@my_decorator` is called, it +# takes the function `decorated()` as its argument, and +# the argument of `decorated()` as the argument of `inner_decorator()`. +# Hence the arg `number` is passed to `num_copy`. + +import datetime + + +def my_decorator(inner): + def inner_decorator(num_copy): + print(datetime.datetime.utcnow()) + inner(int(num_copy) + 1) + print(datetime.datetime.utcnow()) + return inner_decorator + + +@my_decorator +def decorated(number): + print("This happened : " + str(number)) + +if __name__ == "__main__": + decorated(5) + +# This prints: +# python 21-decorators-3.py +# 2016-05-29 12:11:57.212125 +# This happened : 6 +# 2016-05-29 12:11:57.212168 diff --git a/Python-and-OOP-master/22-decorators-4.py b/Python-and-OOP-master/22-decorators-4.py new file mode 100644 index 00000000..9399fd3a --- /dev/null +++ b/Python-and-OOP-master/22-decorators-4.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +# Reference: Decorators 101 - A Gentle Introduction to Functional Programming. +# By Jillian Munson - PyGotham 2014. +# https://www.youtube.com/watch?v=yW0cK3IxlHc + +# 22-decorators-4.py + +# This example builds on the previous decorator examples. +# The previous example, 21-decorators-3.py showed how to +# deal with one argument passed to the function. + +# This example shows how we can deal with multiple args. + +# Reminder : `args` is a list of arguments passed, while +# kwargs is a dictionary passed as arguments. + + +def decorator(inner): + def inner_decorator(*args, **kwargs): + print(args, kwargs) + return inner_decorator + + +@decorator +def decorated(string_args): + print("This happened : " + string_args) + +if __name__ == "__main__": + decorated("Hello, how are you?") + +# This prints : +# # python 22-decorators-4.py +# ('Hello, how are you?',) diff --git a/Python-and-OOP-master/23-decorators-5.py b/Python-and-OOP-master/23-decorators-5.py new file mode 100644 index 00000000..eed3a746 --- /dev/null +++ b/Python-and-OOP-master/23-decorators-5.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +# 23-decorators-5.py + +# Reference : https://www.youtube.com/watch?v=bxhuLgybIro + +from __future__ import print_function + + +# 2. Decorator function +def handle_exceptions(func_name): + def inner(*args, **kwargs): + try: + return func_name(*args, **kwargs) + except Exception: + print("An exception was thrown : ", Exception) + return inner + + +# 1. Main function +@handle_exceptions +def divide(x, y): + return x / y + +print(divide(8, 0)) diff --git a/Python-and-OOP-master/24-decorators-6.py b/Python-and-OOP-master/24-decorators-6.py new file mode 100644 index 00000000..95190599 --- /dev/null +++ b/Python-and-OOP-master/24-decorators-6.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + + +def decorator(inner): + def inner_decorator(*args, **kwargs): + print("This function takes " + str(len(args)) + " arguments") + inner(*args) + return inner_decorator + + +@decorator +def decorated(string_args): + print("This happened: " + str(string_args)) + + +@decorator +def alsoDecorated(num1, num2): + print("Sum of " + str(num1) + "and" + str(num2) + ": " + str(num1 + num2)) + + +if __name__ == "__main__": + decorated("Hello") + alsoDecorated(1, 2) diff --git a/Python-and-OOP-master/25-decorators-7.py b/Python-and-OOP-master/25-decorators-7.py new file mode 100644 index 00000000..b41569dc --- /dev/null +++ b/Python-and-OOP-master/25-decorators-7.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# 25-decorators-7.py + +# Reference https://www.youtube.com/watch?v=Slf1b3yUocc + +# We have two functions, one which adds two numbers, +# and another which subtracts two numbers. + +# We apply the decorator @double which takes in the +# functions that is called with the decorator, and doubles +# the output of the respective function. + + +def double(my_func): + def inner_func(a, b): + return 2 * my_func(a, b) + return inner_func + + +@double +def adder(a, b): + return a + b + + +@double +def subtractor(a, b): + return a - b + + +print(adder(10, 20)) +print(subtractor(6, 1)) diff --git a/Python-and-OOP-master/26-class-decorators.py b/Python-and-OOP-master/26-class-decorators.py new file mode 100644 index 00000000..ba7cfd84 --- /dev/null +++ b/Python-and-OOP-master/26-class-decorators.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +# 26-class-decorators.py + +# Reference : https://www.youtube.com/watch?v=Slf1b3yUocc +# Talk by Mike Burns + +# Till the previous examples, we saw function decorators. +# But decorators can be applied to Classes as well. +# This example deals with class decorators. + +# NOTE: If you are creating a decorator for a class, you'll it +# to return a Class. + +# NOTE: Similarly, if you are creating a decorator for a function, +# you'll need it to return a function. + + +def honirific(cls): + class HonirificCls(cls): + def full_name(self): + return "Dr. " + super(HonirificCls, self).full_name() + return HonirificCls + + +@honirific +class Name(object): + def __init__(self, first_name, last_name): + self.first_name = first_name + self.last_name = last_name + + def full_name(self): + return " ".join([self.first_name, self.last_name]) + +result = Name("Vimal", "A.R").full_name() +print("Full name: {0}".format(result)) + + +# This needs further check. Erroring out. diff --git a/Python-and-OOP-master/27-classmethod-1.py b/Python-and-OOP-master/27-classmethod-1.py new file mode 100644 index 00000000..37b40404 --- /dev/null +++ b/Python-and-OOP-master/27-classmethod-1.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +# 19-class_methods-1.py + +# A classmethod is an inbuilt decorator which is called on functions via +# @classmethod. + +# The @classmethod decorator marks the function/method as bound to the +# class and not to an instance. + +# Remember that we used 'self' in a function within a class, which denoted +# the instance. In class methods, we use `cls` which denotes the class +# rather than the instance. + +# The following example is a very simple explanation of class-methods. + +# class_1() is a class method while class_2() is an instance method. + +# Class methods can be accessed by the class as well as the instance. + +# Instance methods can only be accessed by the Instance. That's why in this example, MyClass.class_2() will fail with an error. + +# NOTE : For the class MyClass: +# MyClass is the class itself +# MyClass() is an instance + + +class MyClass(object): + @classmethod + def class_1(cls): + print("Class method 1") + + def class_2(self): + print("Self/Instance method 1") + + +print("Calling the class `MyClass` directly without an instance:") +MyClass.class_1() +# MyClass.class_2() + +# NOTE: You will want to comment `MyClass.class_2()` once you hit the `TypeError` +# to continue with the examples below. + +print("\nCalling the instance `MyClass()`:") +MyClass().class_1() +MyClass().class_2() diff --git a/Python-and-OOP-master/28-classmethod-2.py b/Python-and-OOP-master/28-classmethod-2.py new file mode 100644 index 00000000..b557f8d2 --- /dev/null +++ b/Python-and-OOP-master/28-classmethod-2.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +# 28-classmethod-2.py + +# Reference: https://jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/ + +# Classmethods are decorators which are inbuilt in Python. +# We decorate a function as a classemethod using the decorator +# @classmethod. + +# Class methods are used for functions which need not be +# called via an instance. Certain use cases may be: + +# a) Creating instances take resources, hence the methods/functions +# which need necessarily + + +class MyClass(object): + count = 0 + + def __init__(self, val): + self.val = val + MyClass.count += 1 + + def set_val(self, newval): + self.val = newval + + def get_val(self): + return self.val + + @classmethod + def get_count(cls): + return cls.count + +object_1 = MyClass(10) +print("\nValue of object : %s" % object_1.get_val()) +print(MyClass.get_count()) + +object_2 = MyClass(20) +print("\nValue of object : %s" % object_2.get_val()) +print(MyClass.get_count()) + +object_3 = MyClass(40) +print("\nValue of object : %s" % object_3.get_val()) +print(MyClass.get_count()) diff --git a/Python-and-OOP-master/29-staticmethod-1.py b/Python-and-OOP-master/29-staticmethod-1.py new file mode 100644 index 00000000..d069f995 --- /dev/null +++ b/Python-and-OOP-master/29-staticmethod-1.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# 29-staticmethod-1.py + +""" +# Refer https://arvimal.wordpress.com/2016/06/12/instance-class-static-methods-object-oriented-programming/ +# a) Static methods are functions methods which doesn’t need a binding +# to a class or an instance. +# b) Static methods, as well as Class methods, don’t require an instance +# to be called. +# c) Static methods doesn’t need self or cls as the first argument +# since it’s not bound to an instance or class. +# d) Static methods are normal functions, but within a class. +# e) Static methods are defined with the keyword @staticmethod +# above the function/method. +# f) Static methods are usually used to work on Class Attributes. +""" + + +class MyClass(object): + count = 0 + + def __init__(self, val): + self.val = self.filterint(val) + MyClass.count += 1 + + @staticmethod + def filterint(value): + if not isinstance(value, int): + print("Entered value is not an INT, value set to 0") + return 0 + else: + return value + + +a = MyClass(5) +b = MyClass(10) +c = MyClass(15) + +print(a.val) +print(b.val) +print(c.val) +print(a.filterint(100)) diff --git a/Python-and-OOP-master/30-staticmethod-2.py b/Python-and-OOP-master/30-staticmethod-2.py new file mode 100644 index 00000000..f36685ca --- /dev/null +++ b/Python-and-OOP-master/30-staticmethod-2.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +from __future__ import print_function + +# 30-staticmethod-2.py + +# Refer +# https://arvimal.wordpress.com/2016/06/12/instance-class-static-methods-object-oriented-programming/ + +# Static methods are functions/methods which doesn’t need a binding to a class or an instance. +# Static methods, as well as Class methods, don’t require an instance to be called. +# Static methods doesn’t need self or cls as the first argument since it’s not bound to an instance or class. +# Static methods are normal functions, but within a class. +# Static methods are defined with the keyword @staticmethod above the function/method. +# Static methods are usually used to work on Class Attributes. + + +class MyClass(object): + # A class attribute + count = 0 + + def __init__(self, name): + print("An instance is created!") + self.name = name + MyClass.count += 1 + + # Our class method + @staticmethod + def status(): + print("The total number of instances are ", MyClass.count) + +print(MyClass.count) + +my_func_1 = MyClass("MyClass 1") +my_func_2 = MyClass("MyClass 2") +my_func_3 = MyClass("MyClass 3") + +MyClass.status() +print(MyClass.count) diff --git a/Python-and-OOP-master/31-magicmethods-1.py b/Python-and-OOP-master/31-magicmethods-1.py new file mode 100644 index 00000000..f76a3e80 --- /dev/null +++ b/Python-and-OOP-master/31-magicmethods-1.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +# 30-magicmethods-1.py + +# In the backend, python is mostly objects and method +# calls on objects. + +# Here we see an example, where the `print()` function +# is just a call to the magic method `__repr__()`. + + +class PrintList(object): + + def __init__(self, my_list): + self.mylist = my_list + + def __repr__(self): + return str(self.mylist) + + +printlist = PrintList(["a", "b", "c"]) +print(printlist.__repr__()) diff --git a/Python-and-OOP-master/32-magicmethods-2.py b/Python-and-OOP-master/32-magicmethods-2.py new file mode 100644 index 00000000..a9840634 --- /dev/null +++ b/Python-and-OOP-master/32-magicmethods-2.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +# 31-magicmethods-2.py + +# In the backend, python is mostly objects and method +# calls on objects. + +# To read more on magic methods, refer : +# http://www.rafekettler.com/magicmethods.html + +my_list_1 = ["a", "b", "c"] + +my_list_2 = ["d", "e", "f"] + +print("\nCalling the `+` builtin with both lists") +print(my_list_1 + my_list_2) + +print("\nCalling `__add__()` with both lists") +print(my_list_1.__add__(my_list_2)) diff --git a/Python-and-OOP-master/33-attribute-encapsulation-1.py b/Python-and-OOP-master/33-attribute-encapsulation-1.py new file mode 100644 index 00000000..e69de29b diff --git a/Python-and-OOP-master/34-abstractclasses-1.py b/Python-and-OOP-master/34-abstractclasses-1.py new file mode 100644 index 00000000..24ccbc7b --- /dev/null +++ b/Python-and-OOP-master/34-abstractclasses-1.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +# 34-abstractclasses-1.py + +# This code snippet talks about Abstract Base Classes (abc). + +# The `abc` module provides features to create +# Abstract Base Classes. + +# To create an Abstract Base Class, set the `__metaclass__` magic method +# to `abc.ABCMeta`. This will mark the respective class as an Abstract +# Base Class. + +# Now, in order to specify the methods which are to be enforced on the +# child classes, ie.. to create Abstract Methods, we use the decorator +# @abc.abstractmethod on the methods we need. + +# The child class which inherits from an Abstract Base Class can implement +# methods of their own, but *should always* implement the methods defined in +# the parent ABC Class. + +import abc + + +class My_ABC_Class(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def set_val(self, val): + return + + @abc.abstractmethod + def get_val(self): + return + +# Abstract Base Class defined above ^^^ + +# Custom class inheriting from the above Abstract Base Class, below + + +class MyClass(My_ABC_Class): + + def set_val(self, input): + self.val = input + + def get_val(self): + print("\nCalling the get_val() method") + print("I'm part of the Abstract Methods defined in My_ABC_Class()") + return self.val + + def hello(self): + print("\nCalling the hello() method") + print("I'm *not* part of the Abstract Methods defined in My_ABC_Class()") + +my_class = MyClass() + +my_class.set_val(10) +print(my_class.get_val()) +my_class.hello() diff --git a/Python-and-OOP-master/35-abstractclasses-2.py b/Python-and-OOP-master/35-abstractclasses-2.py new file mode 100644 index 00000000..31d1ca72 --- /dev/null +++ b/Python-and-OOP-master/35-abstractclasses-2.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# 34-abstractclasses-1.py + +# This code snippet talks about Abstract Base Classes (abc). + +# The `abc` module provides features to create +# Abstract Base Classes. + +# To create an Abstract Base Class, set the `__metaclass__` magic method +# to `abc.ABCMeta`. This will mark the respective class as an Abstract +# Base Class. + +# Now, in order to specify the methods which are to be enforced on the +# child classes, ie.. to create Abstract Methods, we use the decorator +# @abc.abstractmethod on the methods we need. + +# The child class which inherits from an Abstract Base Class can implement +# methods of their own, but *should always* implement the methods defined in +# the parent ABC Class. + +# NOTE: This code will error out. This is an example on what +# happens when a child class doesn't implement the abstract methods +# defined in the Parent Class. + +import abc + + +class My_ABC_Class(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def set_val(self, val): + return + + @abc.abstractmethod + def get_val(self): + return + +# Abstract Base Class defined above ^^^ + +# Custom class inheriting from the above Abstract Base Class, below + + +class MyClass(My_ABC_Class): + + def set_val(self, input): + self.val = input + + def hello(self): + print("\nCalling the hello() method") + print("I'm *not* part of the Abstract Methods defined in My_ABC_Class()") + +my_class = MyClass() + +my_class.set_val(10) +print(my_class.get_val()) +my_class.hello() diff --git a/Python-and-OOP-master/36-abstractclasses-3.py b/Python-and-OOP-master/36-abstractclasses-3.py new file mode 100644 index 00000000..70532bcc --- /dev/null +++ b/Python-and-OOP-master/36-abstractclasses-3.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +# 34-abstractclasses-1.py + +# This code snippet talks about Abstract Base Classes (abc). + +# The `abc` module provides features to create +# Abstract Base Classes. + +# To create an Abstract Base Class, set the `__metaclass__` magic method +# to `abc.ABCMeta`. This will mark the respective class as an Abstract +# Base Class. + +# Now, in order to specify the methods which are to be enforced on the +# child classes, ie.. to create Abstract Methods, we use the decorator +# @abc.abstractmethod on the methods we need. + +# The child class which inherits from an Abstract Base Class can implement +# methods of their own, but *should always* implement the methods defined in +# the parent ABC Class. + +# NOTE: This code will error out. This is an example on what +# happens when a child class doesn't implement the abstract methods +# defined in the Parent Class. + +import abc + + +class My_ABC_Class(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def set_val(self, val): + return + + @abc.abstractmethod + def get_val(self): + return + +# Abstract Base Class defined above ^^^ + +# Custom class inheriting from the above Abstract Base Class, below + + +class MyClass(My_ABC_Class): + + def set_val(self, input): + self.val = input + + def hello(self): + print("\nCalling the hello() method") + print("I'm *not* part of the Abstract Methods defined in My_ABC_Class()") + +my_class = My_ABC_Class() + +my_class.set_val(10) +print(my_class.get_val()) +my_class.hello() diff --git a/Python-and-OOP-master/37-method-overloading-1.py b/Python-and-OOP-master/37-method-overloading-1.py new file mode 100644 index 00000000..1a3b0bc7 --- /dev/null +++ b/Python-and-OOP-master/37-method-overloading-1.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +# 37-method-overloading-1.py + +# Reference: O'Reilly Learning Path: +# http://shop.oreilly.com/product/0636920040057.do +# Chapter 24 : Method Overloading - Extending and Providing + +# This code is an example on how we can extend a method inherited by +# a child class from the Parent class. + +# 1) We have defined `MyClass()` as an abstract class, +# and it has three methods, my_set_val(), my_get_val(), and print_doc(). +# 2) MyChildClass() inherits from MyClass() +# 3) MyChildClass() extends the parent's my_set_val() method +# by it's own my_set_val() method. It checks for the input, +# checks if it's an integer, and then calls the my_set_val() +# method in the parent. + +# 4) The print_doc() method in the Parent is an abstract method +# and hence should be implemented in the child class MyChildClass() + + +import abc + + +class MyClass(object): + + __metaclass__ = abc.ABCMeta + + def my_set_val(self, value): + self.value = value + + def my_get_val(self): + return self.value + + @abc.abstractmethod + def print_doc(self): + return + + +class MyChildClass(MyClass): + + def my_set_val(self, value): + if not isinstance(value, int): + value = 0 + super(MyChildClass, self).my_set_val(self) + + def print_doc(self): + print("Documentation for MyChild Class") + +my_instance = MyChildClass() +my_instance.my_set_val(100) +print(my_instance.my_get_val()) +print(my_instance.print_doc()) + diff --git a/Python-and-OOP-master/38-method-overloading-2.py b/Python-and-OOP-master/38-method-overloading-2.py new file mode 100644 index 00000000..94a0a09a --- /dev/null +++ b/Python-and-OOP-master/38-method-overloading-2.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +# 37-method-overloading-1.py + +# Reference: O'Reilly Learning Path: +# http://shop.oreilly.com/product/0636920040057.do +# Chapter 24 : Method Overloading - Extending and Providing + +import abc + + +class GetSetParent(object): + + __metaclass__ = abc.ABCMeta + + def __init__(self, value): + self.val = 0 + + def set_val(self, value): + self.val = value + + def get_val(self): + return self.val + + @abc.abstractmethod + def showdoc(self): + return + + +class GetSetList(GetSetParent): + def __init__(self, value=0): + self.vallist = [value] + + def get_val(self): + return self.vallist[-1] + + def get_vals(self): + return self.vallist + + def set_val(self, value): + self.vallist.append(value) + + def showdoc(self): + print("GetSetList object, len {0}, store history of values set".format( + len(self.vallist))) diff --git a/Python-and-OOP-master/39-method-overloading-3.py b/Python-and-OOP-master/39-method-overloading-3.py new file mode 100644 index 00000000..3e364ee1 --- /dev/null +++ b/Python-and-OOP-master/39-method-overloading-3.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +# 39-method-overloading-3.py + +# We've seen that inherited methods can be overloaded. +# This is possible using in-built functions as well. + +# Let's see how we can overload methods from the `list` module. + + +class MyList(list): + + def __getitem__(self, index): + if index == 0: + raise IndexError + if index > 0: + index -= 1 + return list.__getitem__(self, index) + + def __setitem__(self, index, value): + if index == 0: + raise IndexError + if index > 0: + index -= 1 + list.__setitem__(self, index, value) + +x = MyList(['a', 'b', 'c']) +print(x) +print("-" * 10) + +x.append('d') +print(x) +print("-" * 10) + +x.__setitem__(4, 'e') +print(x) +print("-" * 10) + +print(x[1]) +print(x.__getitem__(1)) +print("-" * 10) + +print(x[4]) +print(x.__getitem__(4)) diff --git a/Python-and-OOP-master/40-super-1.py b/Python-and-OOP-master/40-super-1.py new file mode 100644 index 00000000..7e1f4726 --- /dev/null +++ b/Python-and-OOP-master/40-super-1.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +# 40-super-1.py + +# This is an example on how super() works +# in Inheritance. + +# For more step-by-step details, refer : +# https://arvimal.wordpress.com/2016/07/01/inheritance-and-super-object-oriented-programming/ + + +class MyClass(object): + + def func(self): + print("I'm being called from the Parent class") + + +class ChildClass(MyClass): + + def func(self): + print("I'm actually being called from the Child class") + print("But...") + # Calling the `func()` method from the Parent class. + super(ChildClass, self).func() + +my_instance_2 = ChildClass() +my_instance_2.func() + diff --git a/Python-and-OOP-master/41-super-2.py b/Python-and-OOP-master/41-super-2.py new file mode 100644 index 00000000..c53b339c --- /dev/null +++ b/Python-and-OOP-master/41-super-2.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# 41-super-2.py + +# For more information on how this works, refer: + +# https://arvimal.wordpress.com/2016/07/01/inheritance-and-super-object-oriented-programming/ + +# https://arvimal.wordpress.com/2016/06/29/inheritance-and-method-overloading-object-oriented-programming/ + +import abc + + +class MyClass(object): + + __metaclass__ = abc.ABCMeta + + def my_set_val(self, value): + self.value = value + + def my_get_val(self): + return self.value + + @abc.abstractmethod + def print_doc(self): + return + + +class MyChildClass(MyClass): + + def my_set_val(self, value): + if not isinstance(value, int): + value = 0 + super(MyChildClass, self).my_set_val(self) + + def print_doc(self): + print("Documentation for MyChild Class") + +my_instance = MyChildClass() +my_instance.my_set_val(100) +print(my_instance.my_get_val()) +my_instance.print_doc() diff --git a/Python-and-OOP-master/42-super-3.py b/Python-and-OOP-master/42-super-3.py new file mode 100644 index 00000000..c194f96b --- /dev/null +++ b/Python-and-OOP-master/42-super-3.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +# 42-super-3.py + +# super() and __init__() + +# Refer +# https://arvimal.wordpress.com/2016/07/01/inheritance-and-super-object-oriented-programming/ + +# http://www.blog.pythonlibrary.org/2014/01/21/python-201-what-is-super/ + + +class A(object): + def foo(self): + print("A") + + +class B(A): + def foo(self): + print("B") + + +class C(A): + def foo(self): + print("C") + super(C, self).foo() + + +class D(B, C): + def foo(self): + print("D") + super(D, self).foo() + +d = D() +d.foo() diff --git a/Python-and-OOP-master/README.md b/Python-and-OOP-master/README.md new file mode 100644 index 00000000..64e1c400 --- /dev/null +++ b/Python-and-OOP-master/README.md @@ -0,0 +1,136 @@ +# Object Oriented Programming in Python + +01. [Classes](https://github.com/arvimal/Python-and-OOP#01-classes) +02. [Instances, Instance methods, Instance attributes](https://github.com/arvimal/Python-and-OOP#02-instances-instance-methods-instance-attributes) +03. [Class attributes](https://github.com/arvimal/Python-and-OOP#03-class-attributes) +04. [The __init__ constructor](https://github.com/arvimal/Python-and-OOP#04-the-init-constructor) +05. [Inheritance (Inheriting {attributes,methods,constructors etc..})](https://github.com/arvimal/Python-and-OOP#05-inheritance-inheriting-attributesmethodsconstructors-etc) +06. [Encapsulation](https://github.com/arvimal/Python-and-OOP#06-encapsulation) +07. [Polymorphism](https://github.com/arvimal/Python-and-OOP#07-polymorphism) +08. [Instance methods](https://github.com/arvimal/Python-and-OOP#08-instance-methods) +09. [Multiple Inheritance and method/attribute lookup](https://github.com/arvimal/Python-and-OOP#10-multiple-inheritance-and-how-lookup-works) +10. [Method Resolution Order (MRO)](https://github.com/arvimal/Python-and-OOP#11-method-resolution-order-mro) +11. [Decorators](https://github.com/arvimal/Python-and-OOP#12-decorators) +12. [Static methods](https://github.com/arvimal/Python-and-OOP#13-static-methods) +13. [Class methods](https://github.com/arvimal/Python-and-OOP#14-class-methods) + + +# NOTES +------------ +#### 01. Classes + +Classes are the building blocks in Object Oriented Programming. + +Classes can be seen as blueprints from which you create your Instances. + +------------ +#### 02. Instances, Instance methods, Instance attributes + +------------ +#### 03. Class attributes + +Attributes or methods specific to a class are called Class attributes + +Example: + +``` +class MyClass(object): + value = 10 + + def __init__(self): + pass +``` + +Here `value` is a class attribute. These are used when certain values need to be set outside a function. + +------------ +#### 04. The __init__ constructor + +The __init__() constructor is a magic method which gets called when a class is instantiated. + +Any attributes set under the __init__() constructor will be instantiated at the time of instance creation. + +------------ +#### 05. Inheritance (Inheriting {attributes,methods,constructors etc..}) + +------------- +#### 06. Encapsulation + +------------ +#### 07. Polymorphism + +------------ +#### 08. Instance methods + +------------ +#### 09. Multiple Inheritance and method/attribute lookup + +* Any class can inherit from other classes. +* Any python class can inherit from multiple classes at the same time. +* The class that inherits another class is called the Base/Child class. +* The class being inherited by the Child class is called the Parent class. +* The child class inherits any methods and attributes defined in the parent classes. +* Python uses a depth-first method resolution order (MRO) to fetch methods. +* When two classes inherits from the same class, from Python2.3 onwards, the MRO omits the first occurrence of the class. +* This new MRO lookup method applies from Python2.3, and is for the new-style classes. + *NOTE:* New style classes inherits from the 'object' parent class. + +------------ +#### 10. Method Resolution Order (MRO) + +* Python has a method lookup order, called `MRO` (Method Resolution Order) +* The MRO path can be printed to stdout using `print .mro()` +* Python, by default, uses a depth-first lookup path for MRO. + +* ie.. Imagine you have four classes, A, B, C, D. + + 1. You instance is created from `D`. + 2. `D` inherits from `B` and `C` + 3. `B` inherits from `A`. + 4. Both `C` and `A` has a method with the same name. + 5. Since python follows a depth-first MRO, the method is called from `A` + +REFERENCE: Check the code examples in: + * 14-multiple-inheritance-1.py + * 15-multiple-inheritance-2.py + +In some cases, the inheritance can get quite cumbersome when multiple classes inherit from the same classes, in multiple levels. + +**NOTE** : From Python2.3, the MRO has changed slightly in order to speed up the method lookups. + +The MRO lookup now skips/omits the initial occurrences of classes which occurs multiple time in the lookup path. + +* Example: + 1. Four classes, A, B, C, D. + 2. D inherits from both B and C + 3. B inherits from A + 4. C inherits from A + 5. Both C and A contains a similar named method. + 6. Your instance in created from class D. + 7. You try a lookup for the method which is named both in A and C. + 8. The usual lookup should be D -> B -> A -> C -> A + a. Hence since the method exists in A and C, it should return from A. + b. But since the class A is occurring twice and due to the new MRO method, the lookup will be + D -> B -> C -> A. + 9. The lookup should return the method from class C, rather than A. + +REFERENCE: Check the code example in: + * 16-multiple-inheritance-3.py + +-------------- +#### 11. Decorators + +-------------- +#### 12. Static methods + +-------------- +#### 13. Class methods + +-------------- + +#### 14. Magic methods + +Magic methods + + +