0% found this document useful (0 votes)
90 views

Procedural (C) Vs OOP (C++/Java/Python) : (Sys Version)

The document discusses object-oriented programming (OOP) concepts in Python compared to procedural programming. It provides an example of implementing a URL shortening system in a procedural way using dictionaries, then reimplements it using OOP with a ShortURL class. Key points covered include: - Classes group attributes and methods together, while objects are instances of classes - Methods take self as the first argument to access attributes and other methods from an object - Class variables are shared among all objects, while object attributes are unique to each instance - Private attributes/methods start with double underscores but are not truly private in Python - Examples demonstrate OOP concepts like encapsulation and reuse through a URL shortening class

Uploaded by

Kk P
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
90 views

Procedural (C) Vs OOP (C++/Java/Python) : (Sys Version)

The document discusses object-oriented programming (OOP) concepts in Python compared to procedural programming. It provides an example of implementing a URL shortening system in a procedural way using dictionaries, then reimplements it using OOP with a ShortURL class. Key points covered include: - Classes group attributes and methods together, while objects are instances of classes - Methods take self as the first argument to access attributes and other methods from an object - Class variables are shared among all objects, while object attributes are unique to each instance - Private attributes/methods start with double underscores but are not truly private in Python - Examples demonstrate OOP concepts like encapsulation and reuse through a URL shortening class

Uploaded by

Kk P
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

07/04/2020 LIVE_OOP_Basics_Python

Procedural (C) vs OOP (C++/Java/Python)


Large software can be built in C. e.g: Linux Kernel
OOP: Easier to design, reuse components and build large software
SDE: should know OOP as they will be working in teams building large software
ML & DS roles: Should know the basics to use various modules and extend them when needed.
The true power of OOP and OOD can be undestood when deisgning a large piece of software like a
library for plotting

Pre-requisites: previous live-sessions in this series.

In [139]:

import sys
print (sys.version)

3.7.3 (default, Mar 27 2019, 09:23:15)


[Clang 10.0.1 (clang-1001.0.46.3)]

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 1/15
07/04/2020 LIVE_OOP_Basics_Python

In [150]:

# NON-OOP (a.k.a Procedural) based implementation of a ShortURL System.

import random
import string

d = dict();

# given a long URL, get a short URL


def getShortURL(longURL):
# length = random value in 6-10
l = random.randint(6,10);

# generate random characters into a string of length l


chars = string.ascii_lowercase
shortURL = ''.join(random.choice(chars) for i in range(l))

# check if this string is already present in dict d


if shortURL in d:
return getShortURL(longURL);
else:
d[shortURL] = longURL;

r = "https://www.shortURL.com/"+shortURL
return r;

def getLongURL(shortURL):

# extarct key from URL https://www.shortURL.com/mxzmuis ---> mxzmuis


k = shortURL[25:];

if k in d:
return d[k];
else:
return None;

Class: datatype

Object: variable

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 2/15
07/04/2020 LIVE_OOP_Basics_Python

In [50]:

# Class: group all variables/attributes and functions/methods into a single logi


cal unit

class ShortURL:

def __init__(self): # constructor; not must, but, good to have; initialize


all attributes here
self.d=dict();

# given a long URL, get a short URL


def getShortURL(self, longURL): # first argument to all methods is "self" =>
this object
# length = random value in 6-10
l = random.randint(6,10);

# generate random characters into a string of length l


chars = string.ascii_lowercase
shortURL = ''.join(random.choice(chars) for i in range(l))

# check if this string is already present in dict d


if shortURL in self.d:
return getShortURL(longURL);
else:
self.d[shortURL] = longURL;

r = "https://www.shortURL.com/"+shortURL
return r;

def getLongURL(self, shortURL):

# print(self.d); # print statemnt for debugging

# extarct key from URL https://www.shortURL.com/mxzmuis ---> mxzmuis


k = shortURL[25:];

if k in self.d:
return self.d[k];
else:
return None;

In [51]:

# Class: datatype/DS & Object: variable of a class


s = ShortURL() # constructor being called; memory allocated.

print(type(s))

<class '__main__.ShortURL'>

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 3/15
07/04/2020 LIVE_OOP_Basics_Python

What does this "__main__" mean?

The script invoked directly is considered to be in the main module. It can be imported and accessed the
same way as any other module.

Modules:

[https://www.w3schools.com/python/python_modules.asp
(https://www.w3schools.com/python/python_modules.asp)]

Consider a module to be the same as a code library. A file containing a set of functions you want to include
in your application.

In [52]:

print(s.shortURL("appliedaicourse"))
print(s.shortURL("gate.appliedcourse.com"))

--------------------------------------------------------------------
-------
AttributeError Traceback (most recent cal
l last)
<ipython-input-52-84023b7d1bbb> in <module>
----> 1 print(s.shortURL("appliedaicourse"))
2 print(s.shortURL("gate.appliedcourse.com"))

AttributeError: 'ShortURL' object has no attribute 'shortURL'

In [53]:

print(s.getShortURL("appliedaicourse.com"))
print(s.getShortURL("gate.appliedcourse.com"))

https://www.shortURL.com/alrpoy
https://www.shortURL.com/dlfjxuxhff

In [54]:

print(s.getLongURL("https://www.shortURL.com/alrpoy"))

appliedaicourse.com

In [55]:

print(s.d)

{'alrpoy': 'appliedaicourse.com', 'dlfjxuxhff': 'gate.appliedaicours


e.com'}

In [59]:

s.d["interviewprep.appliedcourse.com"] = "abcdefgh";

print(s.d)

{'alrpoy': 'appliedaicourse.com', 'dlfjxuxhff': 'gate.appliedaicours


e.com', 'interviewprep.appliedcourse.com': 'abcdefgh'}

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 4/15
07/04/2020 LIVE_OOP_Basics_Python

In [151]:

# No need to have any atributes or methods


class EmptyClass:
pass

e = EmptyClass();
print(type(e))

<class '__main__.EmptyClass'>

There are lots of internals and boundary cases for which reading
documentation is a good idea.
https://docs.python.org/3/tutorial/classes.html (https://docs.python.org/3/tutorial/classes.html)

We will focus more on applied aspects in the context of ML/AI.

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 5/15
07/04/2020 LIVE_OOP_Basics_Python

In [77]:

# Class variables shared by all objects

# Class: group all variables/attributes and functions/methods into a soingle log


ical unit

class ShortURL1:

URLPrefix = "https://www.shortURL.com/"; # class variable shared by all obje


cts

def __init__(self): # constructor; not must, but, good to have; initialize


all attributes here
self.d=dict();

# given a long URL, get a short URL


def getShortURL(self, longURL): # first argument to all methods is "self" =>
this object
# length = random value in 6-10
l = random.randint(6,10);

# generate random characters into a string of length l


chars = string.ascii_lowercase
shortURL = ''.join(random.choice(chars) for i in range(l))

# check if this string is already present in dict d


if shortURL in self.d:
return getShortURL(longURL);
else:
self.d[shortURL] = longURL;

r = self.URLPrefix + shortURL
return r;

def getLongURL(self, shortURL):

# print(self.d); # print statemnt for debugging

# extarct key from URL https://www.shortURL.com/mxzmuis ---> mxzmuis


k = shortURL[25:];

if k in self.d:
return self.d[k];
else:
return None;

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 6/15
07/04/2020 LIVE_OOP_Basics_Python

In [78]:

s1 = ShortURL1();

print(s1.getShortURL("appliedaicourse.com"))
print(s1.getShortURL("gate.appliedaicourse.com"))

https://www.shortURL.com/bqrkdpum
https://www.shortURL.com/jaxgluaeoh

In [79]:

print(s1.d)
print(s1.URLPrefix)

{'bqrkdpum': 'appliedaicourse.com', 'jaxgluaeoh': 'gate.appliedaicou


rse.com'}
https://www.shortURL.com/

In [81]:

s1a = ShortURL1();
print(s1a.URLPrefix);
print(s1a.d)

https://www.shortURL.com/
{}

If you have learnt OOP in C++/Java, it is very easy to get confused with syntax and internals. Please
beware

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 7/15
07/04/2020 LIVE_OOP_Basics_Python

In [88]:

# "Private Members"

# Class: group all variables/attributes and functions/methods into a soingle log


ical unit

class ShortURL2:

classVar = "test"; # Public => accesible directly from outside the class

__URLPrefix = "https://www.shortURL.com/"; # "Private" memebers. Member => a


ttribute or method

def __init__(self): # constructor; not must, but, good to have; initialize


all attributes here
self.d=dict();

# given a long URL, get a short URL


def getShortURL(self, longURL): # first argument to all methods is "self" =>
this object
# length = random value in 6-10
l = random.randint(6,10);

# generate random characters into a string of length l


chars = string.ascii_lowercase
shortURL = ''.join(random.choice(chars) for i in range(l))

# check if this string is already present in dict d


if shortURL in self.d:
return getShortURL(longURL);
else:
self.d[shortURL] = longURL;

r = self.__URLPrefix + shortURL
return r;

def getLongURL(self, shortURL):

# print(self.d); # print statemnt for debugging

# extarct key from URL https://www.shortURL.com/mxzmuis ---> mxzmuis


k = shortURL[25:];

if k in self.d:
return self.d[k];
else:
return None;

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 8/15
07/04/2020 LIVE_OOP_Basics_Python

In [90]:

s2 = ShortURL2();
print(s2.classVar)
print(s2.__URLPrefix)

test

--------------------------------------------------------------------
-------
AttributeError Traceback (most recent cal
l last)
<ipython-input-90-4fd735b2fbbe> in <module>
1 s2 = ShortURL2();
2 print(s2.classVar)
----> 3 print(s2.__URLPrefix)

AttributeError: 'ShortURL2' object has no attribute '__URLPrefix'

Abstraction:
[https://en.wikipedia.org/wiki/Abstraction_principle_(computer_programming
(https://en.wikipedia.org/wiki/Abstraction_principle_(computer_programming))]
As a recommendation to the programmer, in its formulation by Benjamin C. Pierce in Types and
Programming Languages (2002), the abstraction principle reads: “ Each significant piece of functionality
in a program should be implemented in just one place in the source code. Where similar functions are
carried out by distinct pieces of code, it is generally beneficial to combine them into one by abstracting
out the varying parts. ”
General concept in porgramming: libraries, classes
"Its main goal is to handle complexity by hiding unnecessary details from the user. That enables the user
to implement more complex logic on top of the provided abstraction without understanding or even
thinking about all the hidden complexity." [Source: https://stackify.com/oop-concept-abstraction/
(https://stackify.com/oop-concept-abstraction/)]

Encapsulation:
[https://en.wikipedia.org/wiki/Encapsulation_(computer_programming
(https://en.wikipedia.org/wiki/Encapsulation_(computer_programming))]
In object-oriented programming languages, and other related fields, encapsulation refers to one of two
related but distinct notions, and sometimes to the combination thereof:

1. A language mechanism for restricting direct access to some of the object's components.
2. A language construct that facilitates the bundling of data with the methods (or other functions) operating
on that data.

Design a MyURLShortner built on top of ShortURLFinal (given in a module) with


some changes
Change getShortURL to have both alphabets and numbers
Change the URLPrefix to my website (myurlshortner.com)

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 9/15
07/04/2020 LIVE_OOP_Basics_Python

In [105]:

# Following is the final implementation of ShortURL in the library

class ShortURLFinal:

URLPrefix = "https://www.shortURL.com/"; # class-variable

def __init__(self): # constructor; not must, but, good to have; initialize


all attributes here
self.d=dict();

# given a long URL, get a short URL


def getShortURL(self, longURL): # first argument to all methods is "self" =>
this object
# length = random value in 6-10
l = random.randint(6,10);

# generate random characters into a string of length l


chars = string.ascii_lowercase
shortURL = ''.join(random.choice(chars) for i in range(l))

# check if this string is already present in dict d


if shortURL in self.d:
return getShortURL(longURL);
else:
self.d[shortURL] = longURL;

r = self.URLPrefix + shortURL
return r;

def getLongURL(self, shortURL):

# print(self.d); # print statemnt for debugging

# extarct key from URL https://www.shortURL.com/mxzmuis ---> mxzmuis


k = shortURL[25:];

if k in self.d:
return self.d[k];
else:
return None;

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 10/15
07/04/2020 LIVE_OOP_Basics_Python

In [109]:

# Lets define MyURLShortner based on ShortURLFinal

# Inheritence: baseclass, derived class [https://docs.python.org/3/tutorial/clas


ses.html#inheritance]
class MyURLShortner(ShortURLFinal):
URLPrefix = "www.myurlshortner.com/" # overriding as same name as base-class

# given a long URL, get a short URL


def getShortURL(self, longURL): # overriding as same name as base-class, use
both digits and lowercase
# length = random value in 6-10
l = random.randint(6,10);

# generate random characters into a string of length l


chars = string.ascii_lowercase + string.digits # both digits and lowerca
se
shortURL = ''.join(random.choice(chars) for i in range(l))

# check if this string is already present in dict d


if shortURL in self.d:
return getShortURL(longURL);
else:
self.d[shortURL] = longURL;

r = self.URLPrefix + shortURL
return r;

# getLongURL and dict "d" not changed

In [110]:

m1 = MyURLShortner(); # base-class constructor is executed

print(m1.d)

{}

In [111]:

print(m1.getShortURL("amazon.com"))
print(m1.getShortURL("google.com"))

www.myurlshortner.com/mt2e9h
www.myurlshortner.com/ymnsyufq3

In [112]:

print(m1.d)

{'mt2e9h': 'amazon.com', 'ymnsyufq3': 'google.com'}

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 11/15
07/04/2020 LIVE_OOP_Basics_Python

In [157]:

class A:
def __init__(self, i):
self.var = i;

def printVar(self):
print(self.var)

a = A(10);
a.printVar()

a = A(20);
a.printVar()

10
20

In [158]:

a =10;

print(type(a))

<class 'int'>

In [159]:

a =20;

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 12/15
07/04/2020 LIVE_OOP_Basics_Python

In [115]:

# example from geometry: [Source: https://overiq.com/python-101/inheritance-and-


polymorphism-in-python/]
import math

class Shape:

def __init__(self, color='black', filled=False):


self.__color = color
self.__filled = filled

def get_color(self):
return self.__color

def set_color(self, color):


self.__color = color

def get_filled(self):
return self.__filled

def set_filled(self, filled):


self.__filled = filled

class Rectangle(Shape):

def __init__(self, length, breadth):


super().__init__()
self.__length = length
self.__breadth = breadth

def get_length(self):
return self.__length

def set_length(self, length):


self.__length = length

def get_breadth(self):
return self.__breadth

def set_breadth(self, breadth):


self.__breadth = breadth

def get_area(self):
return self.__length * self.__breadth

def get_perimeter(self):
return 2 * (self.__length + self.__breadth)

class Circle(Shape):
def __init__(self, radius):
super().__init__()
self.__radius = radius

def get_radius(self):
return self.__radius

def set_radius(self, radius):


self.__radius = radius
localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 13/15
07/04/2020 LIVE_OOP_Basics_Python

def get_area(self):
return math.pi * self.__radius ** 2

def get_perimeter(self):
return 2 * math.pi * self.__radius

r1 = Rectangle(10.5, 2.5)

print("Area of rectangle r1:", r1.get_area())


print("Perimeter of rectangle r1:", r1.get_perimeter())
print("Color of rectangle r1:", r1.get_color())
print("Is rectangle r1 filled ? ", r1.get_filled())
r1.set_filled(True)
print("Is rectangle r1 filled ? ", r1.get_filled())
r1.set_color("orange")
print("Color of rectangle r1:", r1.get_color())

c1 = Circle(12)

print("\nArea of circle c1:", format(c1.get_area(), "0.2f"))


print("Perimeter of circle c1:", format(c1.get_perimeter(), "0.2f"))
print("Color of circle c1:", c1.get_color())
print("Is circle c1 filled ? ", c1.get_filled())
c1.set_filled(True)
print("Is circle c1 filled ? ", c1.get_filled())
c1.set_color("blue")
print("Color of circle c1:", c1.get_color())

Area of rectangle r1: 26.25


Perimeter of rectangle r1: 26.0
Color of rectangle r1: black
Is rectangle r1 filled ? False
Is rectangle r1 filled ? True
Color of rectangle r1: orange

Area of circle c1: 452.39


Perimeter of circle c1: 75.40
Color of circle c1: black
Is circle c1 filled ? False
Is circle c1 filled ? True
Color of circle c1: blue

In [ ]:

In [ ]:

### object is the base class for all classes in Python

class MyClass(object): # object is the base-class by default and implicitly.


pass

# __new__() : creates a new object and calls the __init__()


# __init__() : default constructor
# __str__() : write code to convert object into string for printing.

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 14/15
07/04/2020 LIVE_OOP_Basics_Python

In [161]:

a = [1,2,3,4];
print(type(a))

print(a)

<class 'list'>
[1, 2, 3, 4]

In [116]:

class ClassWithStr(): #default object is the base class


def __str__(self):
return "any string representation of the object of this class that we wa
nt"

c1 = ClassWithStr();
print(c1)

any string representation of the object of this class that we want

Example: https://matplotlib.org/3.1.1/api/axis_api.html
(https://matplotlib.org/3.1.1/api/axis_api.html)

In [ ]:

localhost:8888/nbconvert/html/CodeWalkthroughSessions/LIVE_OOP_Basics_Python.ipynb?download=false 15/15

You might also like