Python - ttulka/programming GitHub Wiki
- Data Types
- Variables
- Conditions
- For Loops
- While Loops
- Functions
- Objects and Classes
- Error Handling
- Generators
- Modules
- Debugging
- File I/O
- Regular Expressions
- Testing
- References
Data Types
type(exp) type of the expression.
bin(number) binary representation of number as string.
int('0b101', 2) # 5 or int('5') # 5 parses number.
str(123) parses as string.
Fundamental Data Types
intfloatboolstrlistdicttuplesetcomplex
Numbers
print(2 ** 3) # 2^3 == 8
print(7 / 3) # 2.3333333333333335
print(7 // 3) # 5 div 3 == 1
Strings
- Strings are immutable.
len(string)lenght of string.
s = 'string'
s = "string"
s = '''multiple
line
string
'''
s = 'string' + 123 # Error
s = 'string' + str(123)
weather = "It's \"kind of\" sunny\n"
'abc' * 3 # 'abcabcabc'
s = ' '.join(['a','b','c']) # 'a b c'
contains = 'ab' in 'abc' # True
String slicing
string[start:stop:stepover] creates slice from string.
'0123'[0] # '0' (string)
'0123'[1:3] # '12'
'0123'[1:] # '123'
'0123'[:2] # '01'
'012345'[1:5:2] # '13'
'012345'[::3] # '03'
'012345'[-2] # '4'
'012345'[-2:6] # '45'
'012345'[2:-2] # '23'
'012345'[::-1] # '543210'
'012345'[::-2] # '531'
Formatted strings
print('User {} is {}.'.format('John', 33))
print('User {1} is {0}.'.format(33, 'John'))
print('User {name} is {age}.'.format(name='John', age=33))
name = 'John'
age = 33
print(f'User {name} is {age}.')
print(f'Name is {len(name)} chars long.')
Booleans
TrueorFalsenot(bool)negates.
bool(1) # True
bool(0) # False
bool(None)# False
bool(123) # True
bool('ab')# True
bool('0') # True
bool(0.0) # False
bool(0.01)# True
bool([]) # False
bool([0]) # True
bool('') # False
2 - True # 1
2 - False # 2
Truthy and Falsey
if 5:
print('5 is truthy')
All values are considered "truthy" except for the following, which are "falsy":
FalseNone00.00jDecimal(0)Fraction(0, 1)[]- empty list{}- empty dict()- empty tuple''- empty strb''- empty bytesset()- empty set- empty range, like
range(0) - objects for which
obj.__bool__()returnsFalseobj.__len__()returns0
== vs is Operator
==checks for equalityischecks for identity (in memory)
True == 1 # True
'' == 1 # False
'1' == 1 # False
10 == 10.0 # True
[1,2] == [1,2] # True
True is 1 # False
'' is 1 # False
'1' is 1 # False
10 is 10.0 # False
[1,2] is [1,2] # False
1 is 1 # True
'1' is '1' # True
Lists
- Lists are mutable.
len(list)lenght of list.
li = [1, 2, 3]
li = ['a', 'b', 'c']
li = [1, 2, True, 'abc']
matrix = [1], [2, 3], [4](/ttulka/programming/wiki/1],-[2,-3],-[4)
matrix[1][0] = 300
li = list[:]orli = list.copy()copy of list.li = list(range(3))creates list[0,1,2].li = list(range(2,5))creates list[2,3,4].
Adding into list
list.append(obj)appends object into list.list.insert(index, obj)inserts obj into index.list.extend([obj1, obj2, ...])appends objects.
Removing from list
list.pop()pops last item out of list.list.remove(obj)removes object.list.clear()removes all.
Retriving list items
list.index(obj, [start, [stop]])finds object in list.obj in listreturns True if object is in list.list.count(obj)occurences of object in list.list.sort()sorts list.li = sorted(list)returns sorted copy of list.list.reverse()reverses list.
List slicing
list[start:stop:stepover]creates slice from list.
[0,1,2,3,4,5][1:5:2] # [1, 3]
[0,1,2,3,4,5][2:-2] # [2, 3]
List unpacking
a,b,c = [1,2,3] # a==1, b==2, c==3
a,b,*other = [1,2,3,4] # a==1, b==2, c==[3,4]
a,*other,b = [1,2,3,4] # a==1, other==[2,3], b==4
Dictionaries
- Only hashable immutable keys are allowed.
di = {True: 1, 123: [], (1,2): 'x', 'abc': {}}
di['abc']['a'] = 1
di # {True: 1, 123: [], (1,2): 'x', 'abc': {'a': 1}}
di.get('key')gets value for key orNone.di.get('key', default)get value of default.key in dictTrue if key exists in dictionary.di.keys()keys of dictionary.di.values()values of dictionary.di.items()tuples of dictionary.di.clear()clears disctionary.di.copy()copy of disctionary.di.pop(key)removes item with key.di.update({key:val})modifies or add item.
Tuples
- Immutable lists.
tu = (1,2,3,4,5)
tu[0] # 1
tu[1:3] # (2,3)
a,b,*x = tu # a==1, b==2, x==[3,4,5] (list)
tu = (2,) # single element
tu.index(obj)index of object.len(tu)length of tuple.
Sets
- Unique objects with no order.
- Doesn't support indexing.
se = {1,2,3,3,3,3} # {1,2,3}
se = set([1,2,3,3,3]) # {1,2,3}
se.add(val)add value.len(se)length of set.se.copy()copy of set.se.clear()clears set.se.discart(val)removes value from set if exists.val in seTrue if value exists in set.se1.difference(se2)set with differences.se1.intersection(se2)orse1 & se2intersection set.se1.union(se2)orse1 | se2union set.se1.issubset(se2)True if se1 is subset of se2.se1.issuperset(se2)True if se1 is superset of se2.
Classes (Custom Types)
Specialized Data Types
None
Variables
- Letters, Numbers, Underscores
- Case-sensitive
- Must start with lowercase or underscore.
- snake_case
a,b,c = 1,2,3
x = 1
y = 2
x,y = y,x
print(x, y) # 2 1
Conditions
if condition:
command
command
...
elif condition:
command
command
...
elif condition:
command
command
...
else:
command
command
...
# Short Circuiting applied for both
if cond1 and cond2:
command
if cond1 or cond2:
command
Ternary Operator
if_true if condition else if_false
allowed = True
msg = 'is allowed' if allowed else 'not allowed'
msg # 'is allowed'
For Loops
for i in iterable:
command
pass
break
continue
...
print(i) # i still available
Iterables
- List, tuple, set, string (as chars), dictionary (as keys), ...
- Range
for num in range(0, 100):
print('number:', num) # 100 times
for num in range(0, 100, 2): # only even numbers
print('number:', num) # 50 times
for num in range(100, 0, -1): # 100 to 1
print('number:', num) # 100 times
enumerate(iterable)creates enumeration from iterable:
for index,val in enumerate([1,2,3]):
print(index, val)
Comprehensions (List, Set, Dictionary)
li = [char for char in 'hello'] # ['h','e','l','l','o']
li = [num for num in range(0,5)] # [0, 1, 2, 3, 4]
li = [num**2 for num in range(0,5)] # [0, 1, 4, 9, 16]
li = [n**2 for n in range(0,5) if n%2==0] # [0, 4, 16]
se = {n**2 for n in range(0,5) if n%2==0} # {0, 4, 16}
di = {'a': 1, 'b': 2}
di = {k:v**2 for k,v in di.items() if v%2==0} # {'b': 4}
li = [1, 1, 2, 3, 4, 3]
list({x for x in li if li.count(x) > 1}) # [1,3]
While Loops
while condition:
command
pass
break
continue
...
else: # executes only when no break
command
command
...
Functions
def myfunc(param1=defval1, param2=defval2, ...):
'''
Docstring hints the users about this func.
'''
command
command
pass
def myfunc2(...):
...
...
return val
myfunc(val1, val2, ...)
myfunc(param2=val2, param1=val1)
myfunc_ref = myfunc
myfunc_ref(...) # calls the referenced function
*args and **kwargs
func(params, *args, default params, **kwargs)
def myfunc(*args):
print(args)
return sum(args)
myfunc(1, 2, 3) # 6
# prints tuple (1,2,3)
def myfunc(**kwargs):
print(kwargs)
return sum(kwargs.values())
myfunc(var1=1, var2=2) # 4
# prints dict {'var1':1, 'var2':2}
def myfunc(first, *args, i='hi', **kwargs):
print(first)
print(args)
print(i)
print(kwargs)
myfunc('abc',1, 2, var1=True, var2=False)
# prints:
# abc
# (1, 2)
# hi
# {'var1': True, 'var2': False}
Scope
- Local
- Parent local
- Global
- Build-in functions
a = 1
if True:
x = 1
def myfn():
global a
a = 2
x = 2
y = 2
z = 2
def myfn2():
nonlocal z
z = 3
myfn2()
return z
z = myfn()
print(a) # 2
print(x) # 1
# print(y) # Error
print(z) # 3
Higher Order Functions
def run_func(fn): # HOC
fn()
def hello():
print('hello')
run_func(hello) # hello
Decorators
def my_decorater(func):
def wrap_func():
print('start')
func()
print('end')
return wrap_func
@my_decorater
def hello():
print('hello')
hello() # start hello end
def my_param_decorater(func):
def wrap_func(*args, **kwargs):
func(*args, **kwargs)
return wrap_func
@my_param_decorater
def hello(name):
print(f'hello, {name}!')
hello('abc')
from time import time
def performance(fn):
def wrap(*args, **kwargs):
t1 = time()
res = fn(*args, **kwargs)
t2 = time()
print(f'took {t2-t1} ms')
return res
return wrap
@performance
def do_something():
print('working...')
do_something()
Built-in Functions
Object
getattr(object, name[, default])- gets object attribute.hasattr(object, name)-Trueif object has attribute.setattr(object, name, value)- sets attribute.delattr(object, name)- deletes attribute from object.hash(object)- integer hash value of object (if has any).id(object)- unique integer object identity.vars([object])- attributes as dictionary.
Number
abs(num)- absolute value.max(iterable, *[, key, default])- max value.min(iterable, *[, key, default])- min value.sum(iterable, /, start=0)- sum value.pow(base, exp[, mod])- powers base to exp.round(num[, ndigits])- rouned number.
String
format(value[, format_spec])- formats value.ascii(object)- sting with escaped non-ASCII literals.bin(num)- string binary representation starting with0b.hex(x)- string hexadecimal starting with0x.oct(x)- string octal starting with0o.chr(int)- string for Unicode character.ord(c)- integer Unicode for character.repr(object)- object as string.
Iterable
len(seq)- length of sequence (string, bytes, tuple, list, range).enumerate(iterable, start=0)- enumerates object.range(stop),range(start, stop[, step])next(iterator[, default])- next value.all(iterable)-Trueif all items are truthy.any(iterable)-Trueif any item is truthy.filter(predicatefn, iterable)- iterator from iterable matching predicate.map(func, iterable, ...)- maps all items in iterable.sorted(iterable, *, key=None, reverse=False)- sorted list.reversed(seq)- reversed iterator.slice(stop),slice(start, stop[, step])- slice object.zip(*iterables)- zip object (product).
Function
callable(object)-Trueif object is callable.
Classes
type(object),type(name, bases, dict)- type of object.isinstance(object, classinfo)-Trueif object is instance of class.issubclass(class, classinfo)-Trueif object is subclass of class.super([type[, object-or-type]])- proxy object.
File
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)- opens file.
Other
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)- prints.input([prompt])- prompts user unput.dir([object])- list of valid names in local scope, or object attributes.eval(expression[, globals[, locals]])- evaluates expression.exec(object[, globals[, locals]])- executes Python code.help([object])- prints help info with docstring.
Pure Functins
map,filter,zipandreduce.
def multiply_10(item):
return item * 10
def is_odd(num):
return num % 2 != 0
li = [1, 2, 3]
li2 = list(
map(multiply_10,
filter(is_odd, li)))
print(li2) # [10, 30]
zi1 = list(zip(li, li2))
zi2 = list(zip(li2, li))
print(zi1) # [(1, 10), (2, 30)]
print(zi2) # [(10, 1), (30, 2)]
def sum(a, c):
return a + c
from functools import reduce
r = reduce(sum, li, 0)
print(r) # 6
print(li) # [1, 2, 3]
Lambda Expressions
One-time annonynous functions.
(lambda x: x + 1)(2) # 3
add_one = lambda x: x + 1
add_one(2) # 3
high_ord_func = lambda x, func: x + func(x)
high_ord_func(2, lambda x: x * x) # 6
(lambda x, y, z=3: x + y + z)(1, 2) # 6
(lambda x, y, z=3: x + y + z)(1, y=2) # 6
map(lambda i: i * 2, [1,2,3]) # [2,4,6]
reduce(lambda a, c: a + c, [1,2,3], 0) # 6
a = [(0,2), (4,3), (2,1)]
# sorting by the second key
a.sort(key=lambda x: x[1])
print(a) # [(2,1), (0,2), (4,3)]
Objects and Classes
- No access modificators.
- By convention use
_for private members.
class MyObject:
classobj = 1 # static member
def __init__(self, name):
self.name = name
MyObject.classobj = 2
def mymethod(self, hello):
print(f'{hello}, {self.name}!')
@classmethod
def staticmethod1(cls, text):
classobj = 3
return cls(text)
@staticmethod
def staticmethod2(val):
classobj = val
myobj = MyObject('abc')
myobj.mymethod('Hello') # Hello, abc!
myobj = MyObject.staticmethod1('cde')
myobj.mymethod('Hello') # Hello, cde!
myobj = MyObject.staticmethod2(4)
Inheritance
class SuperClass:
def __init__(self, name):
self.name = name
def mymethod1(self):
print('super', self.name)
class SubClass(SuperClass):
def __init__(self, name):
super().__init__(name)
# SuperClass.__init__(self, name)
def mymethod2(self):
print('sub', self.name)
super().mymethod1()
# SuperClass.mymethod1(self)
sub = SubClass('my')
sub.mymethod1() # super my
sub.mymethod2() # sub my super my
isinstance(sub, SubClass) # true
isinstance(sub, SuperClass) # true
isinstance(sub, object) # true
Multiple Inheritance
Multiple inheritance is possible in Python.
class Super1:
def __init__(self, name, s1):
self.name = name
self.s1 = s1
def method1(self):
print(self.name, self.s1)
class Super2:
def __init__(self, name, s2):
self.name = name
self.s2 = s2
def method2(self):
print(self.name, self.s2)
class Sub(Super1, Super2):
def __init__(self, name, s1, s2):
Super1.__init__(self, name, s1)
Super2.__init__(self, name, s2)
sub = Sub('my','o1','o2')
sub.method1() # my o1
sub.method2() # my o2
Method Resolution Order (MRO)
Based on Depth First Search.
# A
# / \
# C B X
# \ / /
# D---
class X:
name = 'x'
class A:
name = 'a'
class B(A):
pass
class C(A):
name = 'c'
class D(C, B, X):
pass
D.mro() # D, C, B, A, X, object
D.name # 'c'
Dunder Methods
Special object methods __method__.
str(myobj) == myobj.__str__();
class MyClass:
def __str__(self):
return 'my object'
my = MyClass()
str(my) # 'my object'
class MyClass:
def __call__(self):
print('calling...')
my = MyClass()
my() # calling...
class MyClass:
def __getitem__(self, i):
return f'{i}. item'
my = MyClass()
my[2] # '2. item'
my['xyz'] # 'xyz. item'
Error Handling
try:
raise Exception('boom')
except (ValueError, IndexError) as e:
print(f'Error occured: {e}')
except TypeError:
print('Type error occured')
except:
print('Error occured')
else:
print('Everything fine')
finally:
print('Done')
Generators
- For streaming values.
- Iterable.
- Don't hold items in memory (reuse the same memory place for current item).
- Using
rangeandyield.
def my_generator(n):
for i in range(n):
yield i
for i in my_generator(100):
print(i) # 0 - 99
g = my_generator(100)
next(g) # 0
next(g) # 1
def fibonacci_generator(n):
prev = 0
next = 1
for _ in range(n+1):
yield prev
prev, next = next, prev+next
for i in fibonacci_generator(7):
print(i) # 0 1 1 2 3 5 8 13
Modules
__pycache__directory contains compiled imports.__init__.pyfile must be in every Python package.__name__is always__main__for file being run.__name__is filename for files being imported.
# common/utility.py
print(__name__) # common/utility.py
def multiply(a, b):
return a * b
def divide(a, b):
return a / b
# main.py
print(__name__) # __main__
import common.utility
common.utility.multiply(2, 3)
from common import utility
utility.multiply(2, 3)
from common.utility import multiply, divide
multiply(2, 3)
divide(6, 2)
from common.utility import *
multiply(2, 3)
divide(6, 2)
pip
TBD
Debugging
import pdb
def add(a, b):
pdb.set_trace() # pauses here
return a + b
add(1, 'abc')
File I/O
f = open('test.txt')
content = f.read() # content of file
content = f.read() # nothing
f.seek(0)
content = f.read() # content of file
f.seek(0)
line = f.readline() # next line
f.seek(0)
lines = f.readlines() # list of lines
f.close()
try:
with open('test.txt', mode='r+') as f: # closes automatically
bytes_written = f.write('hello') # 5
print(f.read())
except FileNotFoundError as e:
print('file does not exist')
raise e
except IOError as e:
print(f'IO Error: {e}'')
raise except
Regular Expressions
import re
pattern = re.compile('this')
string = 'search in this text'
a = patter.match(string) # True
b = pattern.search(string) # 'this'
c = pattern.findall(string)
c.group() # ['this']
Testing
# main.py
def add(a, b):
return a + b
# test.py
import unittest
import main
class TestMain(unittest.TestCase):
def setUp(self):
print('runs before each test')
def test_adding(self):
test_a = 2
test_b = 3
result = main.add(test_a, test_b)
self.assertEqual(result, 5)
def test_wrong_param(self):
test_a = 2
test_b = 'abc'
result = main.add(test_a, test_b)
self.assertIsInstance(result, TypeError)
def tearDown(self):
print('run after every test')
unittest.main() # run all tests