Beginner friendly, simple to read, Interpreted, Dynamically typed
Python Hello World
print ("Hello world")
a=3
print (a)
print ("Type of a -> ", type(a))
Maximum possible value of an integer in python?
a = 10000000000000000000000000000000000000000000
b = 1
a+b
b = 4.555
print (b)
print ("Type of b -> ", type(b))
c = "Python"
print (c)
print ("Type of c -> ", type(c))
d = 'p'
print (d)
print ("Type of d -> ", type(d))
d = 3+8j
print (d)
print ("Type of d -> ", type(d))
e = True
print ("Type of e -> ", type(e))
a = 9
b = 8
a+b
a = "Python"
b = "Programming"
a+b
a = 3
b = "python"
a+b
a = 9.8
b = 9
a+b
a = "python"
c = 'l'
a+c
a = 9
b = 8
a-b
a = "PythonProgramming"
b = "Python"
a-b
a = 0.333333
b = 4.222221
a-b
a = 3.4444
b = 3
a*b
a = "python"
b = "programming"
a*b
a = 3
b = "python"
a*b
a = "python"
b = 3
a*b
a = 9
b = 4
a/b
a = 9
b = 4
a//b
a = 17
b = 5
a%b
a = 17.9
b = 5
a%b
a = 5
b = 2
a**2
a = 9.6
b = 0.9
a**b
a = "hi"
b = 2
a**b
a = 80
b = 90
print ("a>b : ", a>b)
print ("a<b : ", a<b)
a = "python"
b = "programming"
a>b
Strings are compared lexicographically
== -> Equal to: True if both operands are equal
a = 90
b = 90
print (a==b)
a = "hi"
b = "hi"
c = b
print (a==c)
a = "hi"
b = "Hi"
print (a==b)
a = 90.999997
b = 90.999998
print (a==b)
a = 9.9999999999999999993
b = 9.9999999999999999994
print (a==b)
a = "python"
b = 0
print (a!=b)
a = "python"
b = 90
print (a>=b)
a = 100
b = 100.01
print (a<=b)
a = True
b = False
c = 0
d = 90
e = -9
print (a and b)
print (a or b)
print (not b)
print (not c)
print (not d)
print (not e)
print (c and e)
print (d and e)
print (e and d)
print (e and not d)
If else statements
l = [1,2,3]
if(l):
print ("True")
else:
print ("False")
l = {}
if(l):
print ("True")
else:
print ("False")
Iteration, for loop, Range
for i in range(10):
print (i)
#Print from 5 to 9
for i in range(5,10):
print (i)
for i in range(1,10,2):
print (i)
for i in range(1,-10):
print (i)
for i in range(1,-10, -2):
print (i)
l = [1,2,3]
print ("Type of l : ",type(l))
l = ["python", "programming", "is", "fun"]
print (l)
l = [1, "py", 3.4, True]
print (l)
l1 = ["python", "programming", "session"]
l2 = l1
print (l2)
l2[1]="basics"
print (l1)
l1 = [0,9,8]
print ("l1 = ",l1)
print ("l2 = ", l2)
l = [1,2,3,4,5,6,7,8,9,10]
l
print ("l[0:3] -> ", l[0:3])
print ("l[9:3] -> ", l[9:3])
print ("l[2:2] -> ", l[2:2])
print ("l[2:20] -> ", l[2:20])
print ("l[2:] -> ", l[2:])
print ("l[:2] -> ", l[:2])
print ("l[-1:-3] -> ", l[-1:-3])
print ("l[-3:-1] -> ", l[-3:-1])
print ("l[-4:-1] -> ", l[-4:-1])
print ("l[:-1] -> ", l[:-1])
print ("l[-1:] -> ", l[-1:])
print ("l[0:5:2] -> ", l[0:5:2])
print ("l[-6:-1:-2] -> ", l[-6:-1:-2])
print ("l[-6:-1:2] -> ", l[-6:-1:2])
print ("l[6:0:-2] -> ", l[6:0:-2])
print ("l[::2] -> ", l[::2])
Assignment using slicing
l = [9,8,7,6,5,4,3,2,1]
l[0]=99
l
l[0:2]=90,80
l
l[-3:-1] = [30,20]
l
l[4:6]=90
l
l[2:3]="p"
l
l[3:6]=[]
l
l[-1] = 10
l
List Iteration
l = [1,2,3,4,5,6,7,8,9]
#Add all elements in the list
acc = 0
for i in range(len(l)):
acc += l[i]
acc
l = [1,2,3,4,5,6,7,8,9]
#Add all elements in the list
acc = 0
for i in l:
acc += i
acc
l = [1,2,3,4,5,6,7,8,9]
#Add all elements in the list
acc = 0
for i in l[0:5]:
acc += i
acc
#Print alternate elements
l = [1,2,3,4,5,6,7,8,9]
for i in l[0::2]:
print (i)
List Comprehension
l1 = []
for i in range(10):
l1.append(i)
l1
l2 = [i for i in range(10)]
l2
List Comprehension with conditions
#Get a list of integers divisible by 3
l3 = [i for i in range(10) if i%3==0]
l3
#Using if else
l = ['d','g','r','e','s','j','q','t','i']
vowels = ['a', 'e', 'i', 'o', 'u']
l4 = ["Vowel" if i in vowels else "Consonant" for i in l]
l4
l1 = [1,2,3]
l2 = [4,5,6]
#Multiply both the list using for loops
l3 = []
for i in l1:
for j in l2:
l3.append(i*j)
l3
#Nested List comprehension
l1 = [1,2,3]
l2 = [4,5,6]
l3 = [i*j for j in l1 for i in l2]
l3
#Nested List comprehension
l1 = [[1,2,3], [4,5,6], [7,8,9]]
#print all the elements as single list
l2 = [i for j in l1 for i in j]
l2
Classes in Python
class Cat:
#Class attribute
species = "mammal"
#Instance variables
def __init__(self,name,age):
self.name = name
self.age = age
a = Cat("Ginger", 2)
a.name
Cat.species
class Person:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
def isEmployee(self):
return False
class Employee(Person):
def isEmployee(self):
return True
p = Person("Name1")
p.getName()
emp = Person("Name1")
print(emp.getName(), emp.isEmployee())
emp = Employee("Name2")
print(emp.getName(), emp.isEmployee())
class Base:
pass
class Derived(Base):
pass
print(issubclass(Derived, Base))
print(issubclass(Base, Derived))
d = Derived()
b = Base()
print(isinstance(b, Derived))
print(isinstance(d, Base))
print(isinstance(d, b))
#Diamond problem?
class Base1(object):
def __init__(self):
self.str1 = "Name1"
print ("Base1")
class Base2(object):
def __init__(self):
self.str2 = "name2"
print ("Base2")
class Derived(Base1, Base2):
def __init__(self):
Base1.__init__(self)
Base2.__init__(self)
print ("Derived")
def printStrs(self):
print(self.str1, self.str2)
ob = Derived()
ob.printStrs()
class Base1(object):
def __init__(self):
self.str1 = "Name1"
print ("Base1")
class Base2(object):
def __init__(self):
self.str1 = "Name2"
print ("Base2")
class Derived(Base1, Base2):
def __init__(self):
Base2.__init__(self)
Base1.__init__(self)
print ("Derived")
def printStrs(self):
print(self.str1)
ob = Derived()
ob.printStrs()
class Simple:
def __init__(self, a,b):
self.a = a
self.b = b
def __repr__(self):
return 'Simple '+str(self.a)+" " +str(self.b)
s = Simple(1,2)
s
class MyList:
def __init__(self, iterable):
self.list = list(iterable)
def __getitem__(self, key):
if isinstance(key, slice):
return [self.list[i] for i in range(key.start, key.stop, key.step)]
return self.list[key]
def __setitem__(self,key,val):
if isinstance(key,slice):
(start,stop,stride)=key.indices(len(self.list))
l=(stop-start)//stride
if len(val)!=l:
raise ValueError("Length must be the same for slice assignment")
self.list.__setitem__(key,val)
def __repr__(self):
return str(self.list)
s = MyList((1,2,3))
s[1:3:1]
s[1:2]=[9]
s
class MyList(list):
def __iter__(self):
return (self.do_something(x) for x in list.__iter__(self))
def do_something(self, x):
return x*x
my_list = MyList(range(10))
for item in my_list:
print (item)
#Functions generating other functions
def compose_greet_func():
def get_message():
return "Hello there!"
return get_message
greet = compose_greet_func()
print (type(greet))
print (greet())
#Passing functions as arguments
def greet(name):
return "Hello " + name
def call_func(func):
other_name = "Ginger"
return func(other_name)
print (call_func(greet))
def a_decorator_passing_arguments(function_to_decorate):
def a_wrapper_accepting_arguments(arg1, arg2):
print ('I got args! Look:', arg1, arg2)
function_to_decorate(arg1, arg2)
return a_wrapper_accepting_arguments
@a_decorator_passing_arguments
def print_full_name(first_name, last_name):
print ('My name is', first_name, last_name)
print_full_name('Willy', 'Wonka')
#Passing arguments to decorators
def a_decorator_passing_arguments(function_to_decorate):
def a_wrapper_accepting_arguments(*args):
print ('I got args! Look:', *args)
function_to_decorate(*args)
return a_wrapper_accepting_arguments
@a_decorator_passing_arguments
def print_full_name(*args):
print ('My name is', *args)
print_full_name('hi', 'Willy', 'Wonka', 'bye')
#logging
def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
func(x)
print("After calling " + func.__name__)
return function_wrapper
def foo(x):
print("Hi, foo has been called with " + str(x))
foo("Hi")
foo = our_decorator(foo)
foo(42)
def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
return func(x)
return function_wrapper
@our_decorator
def incr(n):
return n + 1
incr(10)
from math import sin, cos
def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
res = func(x)
print(res)
print("After calling " + func.__name__)
return function_wrapper
sin = our_decorator(sin)
cos = our_decorator(cos)
for f in [sin, cos]:
f(3.1415)
def argument_test_natural_number(f):
def helper(x):
if type(x) == int and x > 0:
return f(x)
else:
raise Exception("Argument is not an integer")
return helper
@argument_test_natural_number
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
for i in range(1,10):
print(i, factorial(i))
print(factorial(-1))
#Handle exceptions
def smart_divide(func):
def inner(a,b):
print("I am going to divide",a,"and",b)
if b == 0:
print("Cannot divide")
return
return func(a,b)
return inner
@smart_divide
def divide(a,b):
return a/b
divide(9,3)
def bread(func):
def wrapper():
print ("</''''''\>")
func()
print ("<\______/>")
return wrapper
def ingredients(func):
def wrapper():
print ('#tomatoes#')
func()
print ('~salad~')
return wrapper
@bread
@ingredients
def sandwich():
print ("ham")
sandwich()
#Method decorators
def method_friendly_decorator(method_to_decorate):
def wrapper(self):
print ("The value is ")
return method_to_decorate(self)
return wrapper
class someClass(object):
def __init__(self):
self.value = 2
@method_friendly_decorator
def print_value(self):
print (self.value)
l = someClass()
l.print_value()
#Decorators with parameters
def header(expr):
def decorator(func):
def wrapper(x):
print(expr + " class!")
func(x)
return wrapper
return decorator
@header("Good Morning")
def foo(x):
print(x)
foo("How are you doing?")
def decorator(func):
def wrapper(a):
return func(a)
return wrapper
@decorator
def my_function(a):
return a*a
my_function(9)
my_function.__name__
def decorator(func):
def wrapper(a):
"""dd dd ff"""
wrapper.__name__ = func.__name__
return func(a)
return wrapper
@decorator
def my_function(a):
"""aaa"""
return a*a
my_function(9)
my_function.__name__
my_function.__doc__
import functools
def decorator(func):
"""bbb"""
@functools.wraps(func)
def wrapper(a):
return func(a)
return wrapper
@decorator
def my_function(a):
"""aaa"""
return a*a
my_function(9)
my_function.__name__
my_function.__doc__
Uses -
extending a function behavior from an external lib
debugging
logging
Validation and runtime checks
Code reuse
#Simple decorator class
class CustomAttr:
def __init__(self, obj):
self.attr = "a custom function attribute"
self.obj = obj
def __call__(self):
self.obj()
class CustomAttrArg:
def __init__(self, value):
self.value = value
def __call__(self, obj):
self.value+=1
print ("a custom function attribute with value {}".format(self.value))
return obj
@CustomAttrArg(1)
def func():
print ("hi")
func()
class DecoratorForClasses:
def __init__(self, passed_class):
self.passed_class = passed_class
self.passed_fancy_method = self.passed_class.fancy_method
self.passed_class.fancy_method = self.fancy_method
print("init")
def __call__(self, arg=None):
print("call")
return self.passed_class()
def fancy_method(self):
print("before")
self.passed_fancy_method(self.passed_class)
print("after")
@DecoratorForClasses
class MyFancyClassTest():
def fancy_method(self):
print("fancy print from fancy method")
fancy_object = MyFancyClassTest()
fancy_object.fancy_method()
def decorator(cls):
class Wrapper:
def __init__(self, *args):
self.wrapped = cls(*args)
def __getattr__(self, name):
print('Getting the {} of {}'.format(name, cls.__name__))
return getattr(self.wrapped, name)
return Wrapper
@decorator
class C:
def __init__(self, x, y):
self.x = x
self.y = y
obj = C(1,2)
print(obj.x)
The special syntax *args in function definitions in python is used to pass a variable number of arguments to a function. The special syntax **kwargs in function definitions in python is used to pass a keyworded, variable-length argument list.
def myFun(**kwargs):
for key, value in kwargs.items():
print ("%s = %s" %(key, value))
myFun(first ='Good', mid ='morning', last='class')