🎬 Santhosh Srinivasan
- Rapid Prototyping Language
- Easy to learn, read and use
- An interpreted language
- Productivity and Readable Code
- reads like "pseudo-code"
- "Life's better without braces" (Bruce Eckel)
- and semicolons (me!)
If you're still not convinced
By Raymond Hettinger (@raymondh)
typically 3-5 times shorter than equivalent Java programs.
often 5-10 times shorter than equivalent C++ code!
Python has an applicability well beyond Perl's niche
- Open Source
- Mature (Almost as old as me!)
- Portable
- Automatic Memory Management
- No core dumps
- Web Development
- Data Analytics and Data Science
- Machine Learning
- GUI Apps
- and many more...
- NASA
- NYSE
- Yahoo
- Redhat
- and many more...
- interactive "shell"
- basic types: numbers, strings
- container types: lists, tuples, sets, dictionaries
- variables
- control structures
- functions
- classes
- modules & packages
- exceptions
- files & standard library
Demo
- Python Shell
- IDLE
msg = "hello"
print(msg)
A bit advanced
# with type hinting
msg: str = "hello"
print(msg)
- Numbers
- Strings
- Lists
- Tuples
- Sets
- Dictionaries
>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # division always returns a floating point number
1.6
>>> 17 / 3 # classic division returns a float
5.666666666666667
>>>
>>> 17 // 3 # floor division discards the fractional part
5
>>> 17 % 3 # the % operator returns the remainder of the division
2
>>> 5 * 3 + 2 # result * divisor + remainder
17
code | output |
---|---|
"hi" + " san!" |
"hi san!" |
"hello" * 3 |
"hellohellohello" |
"hello"[0] |
"h" |
"hello"[-1] |
"o" |
"hello"[1:4] |
"ell" |
len("hello") |
5 |
code | output |
---|---|
"hello" < "jello" |
True |
"e" in "hello" |
True |
"x" not in "hello" |
True |
"python" |
'python' |
'python' |
'python' |
r'python' |
'python' |
code | output |
---|---|
"python".upper() |
PYTHON |
"python".capitalize() |
Python |
"PYTHON".lower() |
python |
"hello".count("l") |
2 |
"hello".find("l") |
2 |
"hello".index("el") |
1 |
Flexible Arrays
a = [99, "bottles of beer", ["on", "the", "wall"]]
Same operators as strings
a+b, a*3, a[0], a[-1], a[1:], len(a)
lists vs strings; strings are immutable
Item and Slice Assignment
a = [99, "bottles of beer", ["on", "the", "wall"]]
a[0] = 98 # [98, "bottles of beer", ["on", "the", "wall"]]
a[1:2] = ["bottles", "of", "beer"]
# [98, "bottles", "of", "beer", ["on", "the", "wall"]]
del a[-1] # [98, "bottles", "of", "beer"]
More List Operations
>>> a = list(range(5)) # [0, 1, 2, 3, 4]
>>> a.append(5) # [0, 1, 2, 3, 4, 5]
>>> a.pop() # [0, 1, 2, 3, 4]
5
>>> a.insert(0, 42) # [42, 0, 1, 2, 3, 4]
>>> a.pop(0) # [0, 1, 2, 3, 4]
42
>>> a.reverse() # [4, 3, 2, 1, 0]
>>> a.sort() # [0, 1, 2, 3, 4]
More List Operations
>>> a
[0, 1, 2, 3, 4]
>>> min(a)
0
>>> max(a)
4
>>> sum(a)
10
>>> a.count(2)
1
key = (lastname, firstname)
point = x, y, z # parentheses optional
x, y, z = point # unpack
lastname = key[0]
singleton = (1,) # trailing comma!!!
empty = () # parentheses!
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])
Unique Values
files = {'py', 'java', 'c', 'py', 'sh', 'java'}
print(files) # {'sh', 'c', 'java', 'py'}
Faster Membership Testing
'py' in files # True
'go' in files # False
Use set()
to create sets
a = set('abracadabra') # {'d', 'c', 'r', 'a', 'b'}
b = set('alacazam') # {'c', 'z', 'l', 'a', 'm'}
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}
Hash tables, "associative arrays"
d = {"make": "Honda", "model": "CR-V"}
Lookup:
d["make"] # "Honda"
d["brand"] # raises KeyError exception
Delete, insert, overwrite:
del d["model"] # {"make": "Honda"}
d["make"] = "Toyota" # {"make": "Toyota"}
d["model"] = "Corolla" # {"make": "Toyota", "model": "Corolla"}
Keys, values, items:
d.keys() # dict_keys(['make', 'model'])
d.values() # dict_values(['Toyota', 'Corolla'])
d.items() # dict_items([('make', 'Honda'), ('model', 'Corolla')])
Presence check:
"make" in d # True
"brand" in d # False
"brand" not in d # True
Values of any type; keys almost any
{
"name":"Guido",
"age":43,
("hello","world"):1,
42:"yes",
"flag": ["red","white","blue"]
}
- Keys must be immutable:
- numbers, strings, tuples of immutables
- these cannot be changed after creation
- reason is hashing (fast lookup technique)
- not lists or other dictionaries -these types of objects can be changed "in place"
- no restrictions on values
- numbers, strings, tuples of immutables
if condition:
statements
[elif condition:
statements]...
else:
statements
x = int(input("Please enter an integer: "))
if x < 0:
x = 0
print('Negative changed to zero')
elif x == 0:
print('Zero')
elif x == 1:
print('Single')
else:
print('More')
for var in sequence:
statements
# Measure some strings:
words = ['cat', 'window', 'defenestrate']
for w in words:
print(w, len(w))
# prints as below
# cat 3
# window 6
# defenestrate 12
while condition:
statements
break
continue
In C:
for (i = 0; i < 20; i++) {
if (i%3 == 0) {
printf("%d\n", i);
if (i%5 == 0) {
printf("Bingo!\n");
}
}
printf("---\n");
}
In Python:
for i in range(20):
if i%3 == 0:
print(i)
if i%5 == 0:
print("Bingo!")
print("---")
for c in "python": # over a string
for item in [1, 2, 3]: # over a list
for key in {"a": 1, "b": 2}: # over a dict
for item in (1, 2, 3): # over a tuple
def name(arg1, arg2):
"""documentation""" # optional doc string
statements
return expression
def gcd(a, b):
"""greatest common divisor"""
while a != 0:
a, b = b%a, a # parallel assignment
return b
>>> gcd.__doc__
'greatest common divisor'
>>> gcd(12, 20)
4
def gcd(a: int, b: int) -> int:
"""greatest common divisor"""
while a != 0:
a, b = b%a, a # parallel assignment
return b
def say_hello(name="there"):
"""prints hello with a given or a default name"""
print(f"Hello, {name}!")
say_hello() # Hello, there!
say_hello("San") # Hello, San!
def average(total, count):
"""returns average by dividing total by count"""
return total/count
average(5, 2) # 2.5
average(total=5, count=2) # 2.5
average(count=2, total=5) # 2.5
class name:
"""documentation"""
statements
or
class name(base1, base2, ...):
...
Most statements are method defnitions:
def name(self, arg1, arg2, ...):
...
Example Class:
class Stack:
"""A well-known data structure…"""
def __init__(self): # constructor
self.items = []
def push(self, x):
self.items.append(x) # the sky is the limit
def pop(self):
x = self.items[-1] # what happens if it’s empty?
del self.items[-1]
return x
def empty(self):
return len(self.items) == 0 # Boolean result
To create an instance, simply call the class object:
x = Stack() # no 'new' operator!
To use methods, use dot notation:
x.empty() # -> True
x.push(1) # [1]
x.empty() # -> False
x.push("hello") # [1, "hello"]
x.pop() # -> "hello" # [1]
To inspect instance variables, use dot notation:
x.items # -> [1]
Subclassing
class FancyStack(Stack):
"""stack with added ability to inspect inferior stack items"""
def peek(self, n):
"""peek(0) returns top; peek(-1) returns item below that; etc."""
size = len(self.items)
assert 0 <= n < size # test precondition
return self.items[size-1-n]
Subclassing (2)
class LimitedStack(FancyStack):
"""fancy stack with limit on stack size"""
def __init__(self, limit):
self.limit = limit
FancyStack.__init__(self) # base class constructor
def push(self, x):
assert len(self.items) < self.limit
FancyStack.push(self, x) # "super" method call
- Collection of stuff in foo.py file
- functions
- classes
- variables
Importing modules:
import re;
print(re.match("[a-z]+", s))
# or
from re import match;
print(match("[a-z]+", s))
Import with rename:
import re as regex
# or
from re import match as m
- Collection of modules in directory
- Must have
__init__.py
file - May contain subpackages
Import syntax:
from P.Q.M import foo;
print(foo())
from P.Q import M;
print(M.foo())
import P.Q.M;
print(P.Q.M.foo())
import P.Q.M as M;
print(M.foo()) # new
def foo(x):
return 1/x
def bar(x):
try:
print(foo(x))
except ZeroDivisionError as err:
print("Can't divide by zero:", err)
bar(0)
f = open(file)
try:
process_file(f)
finally:
f.close() # always executed
print("OK") # executed on success only
raise IndexError # shorthand for 'raise IndexError()'
raise IndexError("k out of range")
try:
something
except:
print("Oops!")
raise # reraise
f = open(filename, mode)
- mode can be
r
,w
,a
(like C stdio); defaultr
- append
b
for text translation mode - append
+
for read/write open
with open('file.txt') as f:
for line in f:
print(line)
- Operating System Interface (
import os
) - System (
import sys
) - RegEx (
import re
) - Testing (
import unittest
)
- Pretty Print (
import pprint
) - Logging (
import logging
) - Collections (
import collections
) - itertools (
import itertools
)
- Third Party Packages (
pip
,PyPI
) - Comprehensions
- Iterators
- Generators
- Magic Methods
- Decorators
Questions?
- Guido's Presentations
- Official Tutorial
- Essential Python for DS