Python
- Comments
#
- String: double or single quotes; can be indexed; immutable
.title(), .upper(), lower(), .rstrip(), .lstrip(), .strip(), .split(), .join(list)
.isalpha(), .isdigit(), .isspace()
.startswith('other'), .endswith('other'), .find('other'), .replace('old', 'new')
- f-string (format):
f"{string1}\n{string2}"
- raw string with
r: r'C:\some\name' - \n would not be a new line
- Two or more string literals next to each other are auto concatenated
- Multiple lines: (1) backslash
\ at the end, or (2) use triple quotes
- Convert to string:
str()
- Numbers:
- exponents,
**
- floor division,
//
- divide always results in float
- underscore:
14_000_000
- In interactive mode, last printed expression is assigned to
_
- Convert to numbers:
int() or float()
- Multiple assignments:
x, y, z = 1, 2, 3
- Variables: no type association; can be reassigned to other types
__foo__: convention for system name, e.g. __init__, __main__
_foo: convention to indicate private Variable
__foo: interpreter replaces with _classname__foo to avoid name conflict
- Constants:
MAX_CONNECTIONS = 5000
input(): read as string, use int() or float() to convert
import module_name as mn: import the whole module
from module_name import function_0, function_1
function_0()
from module_name import * to avoid dot; _foo would not be imported
pip install -r requirements.txt install modules from a file
from module_name import (
function1,
function2,
function3
)
Flow Control
- Identation to determine block
range(start, end, step): end exclusive, step optional
min(), max(), sum()
for item in items:
# do something
print(item)
while condition:
# do something
match points:
case []:
print("No points")
case [Point(0, 0)]:
print("The origin")
case [Point(x, y)]:
print(f"Single point {x}, {y}")
case [Point(0, y1), Point(0, y2)]:
print(f"Two on the Y axis at {y1}, {y2}")
case _:
print("Something else")
# guard
match point:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
case _:
pass
# Enum
from enum import Enum
from enum import Enum
class Color(Enum):
RED = 'red'
GREEN = 'green'
BLUE = 'blue'
color = Color(input("Enter your choice of 'red', 'blue' or 'green': "))
match color:
case Color.RED:
print("I see red!")
case Color.GREEN:
print("Grass is green")
case Color.BLUE:
print("I'm feeling the blues :(")
IF statement
- “Zero” values:
None, 0, empty string, empty list, empty dictionary, False
- Any non-empty is True
==, !=, and, or, in, not in, is
None is special class. It’s not False, but can be used as False in if
if car == 'bmw':
# do something
elif car == 'telsa':
# do something
else car == 'toyota': # else optional
#do something
Data Structure
- Tuple:
(); cannot modify; access with [index]
- List:
[]
- negative index starts from end
.append(), .insert(0, item), .pop(), .remove(item)
- organize:
.sort(), .sort(reverse=True), .reverse()
- temp sort:
sorted(list)
- length:
len(list)
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[1])
print(bicycles[-1])
del bicycles[1]
popped = bicycles.pop()
first = bicycles.pop(0)
bicycles.remove('trek') # deletes only the first occurrence
# list comprehension
squares = [value**2 for value in range(1, 11)]
# slice
list[0:3]
list[:3]
list[2:]
list[-3:] # last three
# copy a list
duplicate = list[:]
- Dictionary:
{key: value}
dict['key']
.get('key', 'msg if key non-exist')
# add pair
dict['new_key'] = new_value
dict = {} # empty dict
# delete
del dic['old_key']
# loop through
for key, value in dict.items():
# do something
# get all keys
dict.keys()
# get all values, can duplicate
dict.values()
set(dict.values()) # unique values
Functions
- Docstring: three " or three `
def function_name(para1, para2):
"""Display information about this function"""
# something
return some_value
function_name(p1, p2) # positional arguments
function_name(para1=p1, para2=p2) #keyword arguments
# default value
# arguments with default value needs to be at the end
# None is a perfectly fine default value
def fn_name(arg1, arg2='para2'):
"""default arguments"""
# do something
fn_name("para1)
# arbitray number of arguments
def fn_name(first, *arguments):
print(first)
for arg in arguments:
print(f"- {arg}")
Class
__init__(self, arg1, arg2) default function
- Subclass:
class NewClass(OldClass):
- Use
super() to access parent class
class SampleClass:
class_instance = something
def __init__(self, arg):
self.instance = arg
self.other = something
s = SampleClass(a)
print(s.other)
s.new_instance = something # new instance created on the fly
Files
.open(path), .read(), .write()
- Use
json module to dump and load data
path = '~/test.txt'
with open(path) as file_object:
content = file_object.read()
s = ''
for line in file_object:
s += line.rstrip()
lines = file_object.readlines()
# `r` read (default), `w` write, `a` append, `r+` read and write
with open(path, 'w') as file_object:
file_object.write("some thing\n") # need \n for line break
# json
import json
with open(filename, 'w') as f:
json.dump(data, f)
with open(filename) as f:
data = json.load(f)
Try-Except-Else
try:
# do something
except ErrorName:
# do something
# or `pass`
except AnotherError as err:
print(f"Unexepected {err=}, {type(err)=}")
else:
# do something
Testing
- Import
unittest module
- Create a subclass from
unittest.TestCase
- Write a series of methods to test
- any method start with
test_ will be run automatically
self.assertEqual(a, b), assertNotEqual(a,b), assertTrue(x), assertFalse(x), assertIn(item, list), assertNotIn(item, list)
import unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""Tests for 'name_function.py'."""
def test_first_last_name(self):
"""Do names like 'Janis Joplin' work?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
# in case the file is being run as the main program
if __name__ == '__main__':
unittest.main()
# for class test, use `setUp()` to create object
def setUp(self):
"""
create objects
"""
self.attr = "something"
Configuration
ini allows one level, and everything is a string
[APP]
ENVIRONMENT = test
DEBUG = True
# Only accept True or False
[DATABASE]
USERNAME = username
PASSWORD = password
yaml allows for multiple levels, and natively encodes datatypes
APP:
ENVIRONMENT: test
DEBUG: True
# Only accept True or False
DATABASE:
USERNAME: user
PASSWORD: pwd
json does not allow comments
{
"APP": {
"ENVIRONMENT": "test",
"DEBUG": true
},
"DATABASE": {
"USERNAME": "user",
"PASSWORD": "psw",
"HOST": "127.0.0.1",
"PORT": 5432
}
}
toml syntax is similar to ini, but allows for data type (need double quotes)
[APP]
ENVIRONMENT = "test"
DEBUG = true
# Only accept True or False
[DATABASE]
USERNAME = "user"
- Read
json/yaml returns dict object
import json
import yaml
def read_json(file_path):
with open(file_path, "r") as f:
return json.load(f)
def read_yaml(file_path):
with open(file_path, "r") as f:
return yaml.safe_load(f)
assert read_json("data/sample.json") == read_yaml("data/sample.yaml")
import configparser
def read_ini(file_path, config_json):
config = configparser.ConfigParser()
config.read(file_path)
for section in config.sections():
for key in config[section]:
print((key, config[section][key]))
read_ini("source/data/sample.ini", config_json)