Companies which use Python at sacle
Youtube, Dropbox
Frameworks
Web applications and API Design
Django, Flask, Pyramid
Configuration
Ansible, Boto for AWS
Data Analysis
Pandas, MatplotLib, Bokeh, Tensoflow, SciKitLearn
Language Features
There are multiple interpretations of Python
Versions
2/3
Batteries Included
- large amount of libraries
Zen Of Python
> > > import this
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea – let’s do more of those!
Python REPL
Read Eval Print Loop
4 spaces for indentation
all constructs end with colon :
PEP
Python Enhancement Proposal
PEP 8 - style guide for python
PEP 20 - Zen of Python
Get help for any module
> > > help(module_name)
help(math)
prints all functions and descriptions
> > > help(math.factorial)
Import Modules
this will import full library into the current namespace
»> import math
»> math.factorial(10)
this will import only one function into current namespace
»> from math import factorial
»> factorial(10)
> > > from math import factorial as f
Built In Data Types
Scalar types - int, float, None, bool
int
float
None
- no value
bool
bool([]) - False
bool([1, 2, 3]) - True
bool(“”) - False
Control Flow Structures
Breaking a while loop
if expression:
print(“”)
else:
print(“”)
while exp:
print()
while expression:
if expressions:
break;
String Datatype (str)
c = 'oslo' c1 = c.capitalize()
c was not modified but instead anew string was created. Because strings are immutable.
Bytes
split returns a list of byte objects
»> split(b’hello world’)
»> [b’hello’, b’world’]
**** very important ***
encoding - converts strings to bytes
decoding - converts bytes to string
all http response, files etc are transmitted as bytes but we choose to work in string with UTF-8 encoding
nor = “some norwegian chars”
data = nor.encode(“UTF-8”)
»> data
»> b’norwegian chars’
Lists
list constructor - used to create list from other objects
»> list(“hello”)
»> [‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
Dictionary
For Loop
cities = [“London”, “Paris”, “Berlin”]
for city in cities:
print(city)
countries = {“usa”: “washington”, “england”: “london”}
for country in countries:
print(capitals[country])
for country, capital in countries:
print(country, capital)
Decoding and Encoding
names = [b”alice”, b”bob”, b”cindy”]
for name in names:
print(name.decode(“UTF-8”))
Functions
__name__
from hello import (foo, bar) => import only certain funcs
from hello import * => import everything
def foo(arg):
“”” This is a function
Args:
bar: this is bar
Returns:
A message
“””
return “foo”
Command Line args
## hello.py import sys
if __name__ == “__main__”:
print(sys.argv[0], sys.argv[1])
python3 hello.py “foo”
> > > hello, foo
argv[0] - filename
id() function
gives back id of an object i.e. 10 in this case and not the id of reference i.e. i
there is object and . object reference
i.e. i = 10
i is object reference and 10 is the integer object
====> named references to objects
i = 10
id(i) => 244224355343
i += 10
id(i) => 5345452345342
Python does not have variables per se. It only has named references to object - which allows us to retrieve objects
value equality and identity are different
- a variable can have the same value as another variable but is not necessarily the same object
Python objects
p = [1, 2, 3] q = [1, 2, 3]
p == q => T
p is q => F
How to prove function args are pass by object reference?
def foo(k): return k
a = [10, 20, 30] b = foo(a)
a is b => T
a == b => T
####################
def modify(a):
a.append(100)
b = [1, 2, 3] modify(b) >>>a >>> [1, 2, 3, 100] >>>b >>>[1, 2, 3, 100] both have been modified since its pass by reference
now same code with a twist
#######################
def modify(a):
a = [100, 200, 300]
b = [1, 2, 3] modify(b) >>>a >>> [100, 200, 300] >>>b >>>[1, 2, 3]
here the value of a is assigned to another list hence the original list is not modified
Default args
def foo(arg1, arg2="bar"): print(arg1, arg2)
arg1 - positional arg
arg2 = keyword argument
foo(“hello”)
foo(“hello”, world)
foo(“hello”, arg2=”world”)
all keyword args must be specified after positional args
Default value trap
def add_eggs(arg1=[]):
arg1.append("eggs")
return arg1
foo(“rice”) => [“rice”, “eggs”]
foo(“veg”) > [“veg”, “eggs”]
foo() => [“eggs”]
foo() => [“eggs”, “eggs”]
## right way
def add_eggs(arg1=None):
if arg1 == None:
arg1 = []
arg1.append("egg")
return arg1foo() => [“eggs”]
foo() => [“eggs”]
Python Name Scopes
foo.py
i = 10 # where is i stored?
scopes are contexts in which named references can be looked up
LEGB local scope - functions enclosing global - module - import statement, functions, global vars buitin
module scopes
count = 0
def show(): print(count)
def increment(c): count = c
>>> show() >>> 0 >>> increment() >>> show() >>> 0 This is unexpected. But we have created a new variable called count inside of the increment() which shadows the global variable
For this to work properly we need to use golbal i.e. def increment(c): global count count = c