Python Programming Language
Language
print
…is a build in function in Python 3
print('s') # s
print('s',end='') # disable newline
print(1,2,3) # 1 2 3
print(1,2,3,sep=',') # 1,2,3
print('s','r',sep='/') # s/r
print([1,2,3]) # [1, 2, 3]
print(*[1,2,3]) # 1 2 3 Variables
The assignment operation name = object references values to variables:
- Assignment declares and initializes a variable with a value
- Most suitable data type for assignment is select automatically by the interpreter
- A cascading assignment modifies an object referenced by a variable
x = 1.2 + 8 # assign right expression
x = y = z = 0 # assign a single value to multiple variables
x,y,z = 1,2,3 # multiple assignments
x,y = y,x # variable swap
a,*b = [1,2,3] # unpacking a sequence
del x # remove variable
x = None # undefined value
id(x) # return object memory address for variable x
hex(id(x)) # ...hexadecimal memory address
globals() # dictionary of global variablesNaming conventions:
var_with_sep # underscore separated downcase letters
_ # unused variable (i.e. within a loop)
var # public
_var # internal
var_ # convention to avoid conflict keyword
__var # private use in class
_var_ # protected use in class
__var__ # "magic: method or attribute- Names are case sensitive
- Python keywords can not be used as names
Scope and binding:
- Variables are always assigned to local scope current code block (i.e. within a function body)
nonlocalassigns to variables in an outer scope (but not global)globalassigns to a variable in the module’s top level aka global scope
globals().keys() # prints all variable names in global scope
locals().keys() # prints all variable names in local scopeNumbers
| Type | Description |
|---|---|
int |
Integer number are of arbitrary size |
float |
Floating point number precision depends on the implementation and system architecture |
complex |
Complex number |
Literals
123 # integer
-123 # negative signed integer
9.23 # float
-1.7e-6 # scientific notation
2 + 1j # complex number
0b010 # 2 binary notation
0o642 # 418 octal
0xf3 # 243 hexadecimal
None # indefined valueTypes, and type-casting:
type(1) # <class 'int'>
type(1.2) # <class 'float'>
type(None) # <class 'NoneType'>
## string to numerical
int('123') # 123
float('1.23') # 1.23
## Type check ##
isinstance(10,int) # True
isinstance(1.234,float) # TrueArithmetic
1+2 # 3
1-2 # -1
1*2 # 2
1/2 # 0.5
5%3 # 2 (remainder)
2**3 # 8
## Built-in functions ##
abs(-2.3) # 2.3
round(1.6666,2) # 1.67
pow(2,3) # 8
sum((1,2,3,4,5)) # 15
max([1,2,3,4,5]) # 5
min([1,2,3,4,5]) # 1Logic
## Booleans
True # logic true
False # logic fales
not True # False
True and True # True
True and False # False
True or False # True
False or False # False
1 # True
0 # False
## Comparison with boolean results
1 < 2 # True
1 > 2 # False
1 <= 1 # True
2 >= 3 # False
1 == 1 # True
1 != 1 # False
## Ternary conditional statement
1 if True else 2 # 1
1 if False else 2 # 2Strings
Escape sequences interpreted according to rules similar to those used by Standard C
'' # empty line
'\n' # blank line
# Double quote (escape with \)
"a\"bc" # 'a"bc'
# Single quote
'a\'bc' # "a'bc"
## Raw strings ##
r"\t\n\\" # '\\t\\n\\\\'
R"\"\n\"" # '\\"\\n\\"'Raw-string prefixed with r or R use different rules for backslash escape sequences
# Built-in function to get ASCII codes
ord('a') # 97
# convert to sequence pr collection types
list('abc') # ['a', 'b', 'c']
set('abc') # {'b', 'a', 'c'}
tuple('abc') # ('a', 'b', 'c')Escape sequences:
\\ Backslash (\)
\' Single-quote (')
\" Double-quote (")
\a ASCII bell (BEL)
\b ASCII backspace (BS)
\f ASCII formfeed (FF)
\n ASCII linefeed (LF)
\N{name} Character named name in the Unicode database (Unicode only)
\r ASCII carriage return (CR)
\t ASCII horizontal tab (TAB)
\uxxxx Character with 16- bit hex value xxxx (Unicode only)
\Uxxxxxxxx Character with 32- bit hex value xxxxxxxx (Unicode only)
\v ASCII vertical tab (VT)
\ooo Character with octal value oo
\xhh Character with hex value hh
Format
Legacy format operator…
"%s, %s" % ('s','t') # 's, t'Global build in function
format(10.0,"7.3g") # ' 10'Use of the str.format() function…
"{}|{}".format(1,2) # '1|2'
# ...positional index
"{1},{0},{2}".format('r','s','t') # 's,r,t'
# ...parameter names
"{b}{a}".format(a='s',b='t') # 'ts'
# ...nested data structures
'{d[2]},{d[0]}'.format(d=['r','s','t']) # 't,r'
'{d[b]},{d[a]}'.format(d={'a':1,'b':2}) # '2,1'Padding…
"{:4d}".format(123) # ' 123'
'{:06.2f}'.format(3.14159) # '003.14'
"{:>3}".format('s') # ' s'
"{:.<4}".format('s') # 's...'
"{:^5}".format('s') # ' s '
# ...parametrized format
'{:{a}{w}}'.format('s',a='>',w=5) # ' s'
# ...positional arguments
'{:{}{}{}.{}}'.format(2.7182,'>','+',10,3) # ' +2.72'Since Python 3.6 f-strings…
- …formatted string literals …less verbose then
str.format() - …
fas string literal prefix …{}curly braces containing expressions …will be replaced with their values - …evaluated at runtime …allow any valid Python expressions
v = 's'
f'text{v}' # 'texts'
f"{1 + 1}" # '2'
F'{v.upper()}' # 'S'Multi line f-strings…
# ...place an f in front of each line
v = f'line' \
f'line'
# ...easier...
f"""
multi lines text
"""Manipulation
# ...concatenation
"s" + "t" # 'st'
"s " + str(123) # 's 123'
# ...leading, trailing white-space management
" s ".strip() # 's'
' s \n'.rstrip() # ' s'
' s'.lstrip() # 's'
# ...cut by separator
"s\nt\nr\n".splitlines() # ['s', 't', 'r']
"s|t".split("|") # ['s', 't']
'p:q:r:s'.rsplit(':',2) # ['p:q', 'r', 's']
# ...return tuple, preserve the delimiter
"s:r:t".partition(':') # ('s', ':', 'r:t')
"s:r:t".rpartition(':') # ('s:r', ':', 't')
# ...join by separator
':'.join('123') # '1:2:3'
# ...matching
't' in 'str' # True
"st".startswith('s') # True
'str'.endswith('r') # True
' '.isspace() # True
'12'.isdecimal() # True
'1.2'.isdecimal() # False
'strts'.find('r') # 2
# ...replacement
'srtr'.replace('r','R') # 'sRtR'
'srtr'.replace('r','R',1) # 'sRtr'Control & Loop Constructs
Block indentation:
- Blocks of code begin with a colon (:) and contain indented lines below (no ending identifier)
- Always use 4 spaces for indentation
- Single line statements may be put on the same line (considered bad style)
- Empty blocks cause an IndentationError, use
pass(a command that does nothing)`
Conditional Statements
- Can go with multiple
eliffollowed by a singleelse - First true condition is executed
if x < 2:
...
elif x > 2:
...
else:
...Python has no direct analogous to a switch-case statement.
def switch(case):
return {
'a': 'A',
'b': 'B'
}.get(case,None)
print(switch('a')) # Adef a():
return 'A'
def b():
return 'B'
switch = { 'a': a(), 'b': b() }
print(switch['a']) # ALoops
Code blocks repeated through a number of loops (iterations):
- The
breakstatement executed within a loop breaks the control flow out of the loop immediatly - A
continuestatement skips to the next interation of a loop
A while loop executed a code block until the loop condition is false:
x = 0
while True: # endless loop
print(x)
if x == 3: # break condition
break # break the loop
x += 1 # incrementfor loops iterate over a collection of items, and execute a code block for each element:
for x in (0,1,2,3):
if x == 2: # skip condition
continue # skip the rest of the code block
print(x)range is a function returning a series of numbers in an iterable from, commenly use with for loops:
for x in range(3):
print(x)
else:
print('no break')Loops can optionally have an else clause executed if the iteration is completed successfull.
# couple of range examples
list(range(5)) # [0, 1, 2, 3, 4]
tuple(range(4,12)) # (4, 5, 6, 7, 8, 9, 10, 11)
tuple(range(0,10,2)) # (0, 2, 4, 6, 8)
tuple(range(100,0,-10)) # (100, 90, 80, 70, 60, 50, 40, 30, 20, 10)Sequences & Collections
Tuple
A tuple is a immutable sequences of elements with an index number and a value.
# literals for tuples
()
(1,2,3)
('a','b','c')
type((1,2)) # tuple
# assign tuple to a variable t
t = ('a','b','c')
t # ('a', 'b', 'c')
# does a value exists in a tuple t
'a' in t # True
'a' not in t # False
# access elements in a tuple t
t[0] # 'a'
t[-2] # 'b'
t[:2] # ('a', 'b')
t[2:] # ('c',)
# find index of value
t.index('b') # 1
# number of occurrences of a given value
t.count('b') # 1
# concatenation return a new tuple
(1, 2, 3) + (4, 5, 6) # (1, 2, 3, 4, 5, 6)
# number of elements in a tuple
len(('a','b')) # 2
# sort a tuple
sorted(('b','a')) # ['a', 'b']
# smallest/largest value in tuple
min(34,23,45) # 23'
max(34,23,45) # 45
# convert a string to tuple
tuple('abcd') # ('a', 'b', 'c', 'd')
# convert a list into a tuple
tuple([1,2,3,4,5]) # (1, 2, 3, 4, 5)List
A list is a sequences (with dynamic length) of elements with an index number and a value.
type([1,'a',2]) # list
[] # empty list
l = [1,2,'a',3,'b'] # list assignment to variable
# append value to the end of the list list
l.append(4)
# append multiple values to list
l.extend([5,'c'])
# print a list
l # [1, 2, 'a', 3, 'b', 4, 5, 'c']
# does a value exists in a list
'a' in l # True
# find index of a value
l.index('a') # 2
# number of elements in list
len(l) # 8
# access values by index
l[:] # [1, 2, 'a', 3, 'b', 4, 5, 'c']
l[:4] # [1, 2, 'a', 3]
l[-4] # 'b'
l[4:-1] # ['b', 4, 5]
# delete element by value
l.remove(3)
l # [1, 2, 'a', 'b', 4, 5, 'c']
# remove index from list and return its value
l.pop(-1) # 'c'
l # [1, 2, 'a', 'b', 4, 5]
# concatenation return a new list
l + [6,7,'c'] # [1, 2, 'a', 'b', 4, 5, 6, 7, 'c']
l # [1, 2, 'a', 'b', 4, 5]
# delete element by index
del l[3]
l # [1, 2, 'a', 4, 5]
# number of occurrences of a given value
l.count('a') # 1
# shallow copy of the list
m = l.copy()
m[0] = 'z'
l # [1, 2, 'a', 4, 5]
m # ['z', 2, 'a', 4, 5]
# iteration
for i in l: print(l.index(i),i)
# convert a string into a list
list("abcde") # ['a', 'b', 'c', 'd', 'e']
# convert tuple into a list
list((1,2,3,4,5,6)) # [1, 2, 3, 4, 5, 6]Set
A set is a unordered collections of unique elements:
{}
{1,2,'a'} # {1, 2, 'a'}
{1,2,1,2,1} # {1, 2}
type({1,2}) # set
# union
{1,2} | {2,3,4} # {1, 2, 3, 4}
# intersection
{1,2} & {2,3,4} # {2}
# difference
{1,2} - {2,3,4} # {1}
# symmetric difference
{1,2} ^ {2,3,4} # {1, 3, 4}
# does a value exists in set
1 in {1,2,3} # True
'a' in {1,2,3} # False
# iterator
for v in {1,2,3}:Dictionary
A dictionary is a associative list with defined keys and values.
{}
{1:'a','b':2} # {1: 'a', 'b': 2}
# add/change key/value
d = {}
d['a'] = 1
d['b'] = 2
d # {'a': 1, 'b': 2}
d['b'] # 2
# remove element by key
del d['a']
d # {'b': 2}
# merge
d.update({'c':3, 'd':4})
d # {'b': 2, 'c': 3, 'd': 4}
# remove element, return value
d.pop('c') # 3
d # {'b': 2, 'd': 4}
# get a value
d.get('b') # 2
d # {'b': 2, 'd': 4}
# remove all elements
d.clear()
d # {}
# iterators
for k in d.keys()
for v in d.values()
for k,v in d.items()
# conversion
dict(a=1,b=2,c=3) # {'a': 1, 'b': 2, 'c': 3}
dict(zip(['a','b'],[1,2])) # {'a': 1, 'b': 2}Subprocess
Simplest method to execute a command and iterate over the output by line…
import subprocess
text = subprocess.getoutput('ls -l')
for line in text.splitlines():
# ...File I/O
Use open() to store data in a file and read it back:
- The path to the file is the first argument.
- Followed by the access mode:
r(read),w(write),a(append) - Encoding: ‘ascii’, ‘utf8’
txt = "1st line\n2nd line\n3rd line\n4th line"
path = '/tmp/file.txt'
## write into a file
f = open(path,'w',encoding='utf8')
f.write(txt) # write into the file
f.flush() # write cache
f.close() # close when finished
f = open(path,'r')
f.name # path ot the file '/tmp/file.txt'
f.read() # read entire file
# iterate over file content
for l in f.readlines() # by line
for l in iter(f):
for l in f.read().split('\n') # by seperatorUsing a context manager:
with open('/etc/hosts') as f:
for _ in f.readlines():
print(_)Modules
A module is a files containing Python definitions and statements.
dir(__builtins__) # list build-in functions
help(type) # help text for a given modul/functionImport a module to use its functions:
import math
math.pi # 3.141592653589793
math.sqrt(81) # 9.0Load module, and allow direct access to functions:
from math import pi,e,sin,log
sin(pi/4) # 0.7071067811865475
log(e**2) # 2.0Define an alias for a module:
import math as m
m.pi # 3.141592653589793Functions
Functions are defined using the def keyword
- Followed by the function name (identifier), i.e.
f - Arguments given between parentheses followed by
:(colon) - The function body (blocks) must be indented
- The
returnkeyword passes values from the function
# includes argument with default value
def f(x,y,z=3):
"""documentation"""
return (x,y,z)
f(1,2) # (1, 2, 3)
# variable positional arguments as tuple
def g(x,*y):
return (x,y)
g(1,2,3,4,5,6) # (1, (2, 3, 4, 5, 6))
# variable named arguments as dict
def h(x,**y):
return [x,y]
h(1,a=1,b=2) # [1, {'a': 1, 'b': 2}]Lambda
The Lambda expression (anonymous function) creates a function objects with following notation:
lambda: <<args,...>> : <<expression>>
Semantically lambda is a shorthand for a function definition:
- Lambda functions can be used wherever function objects are required.
- It can have any number of arguments before the colon.
- The function body is syntactically restricted to a single expression.
- Typically used as nameless function as argument to a higher-order function.
f = lambda x,y : x+y
f(1,1) # 2
f = lambda x: x**2 + 2*x - 5
f(2) # 3
# Fahrenheit to Celsius conversion
f2c = lambda c: float('{:.2f}'.format((5.0 / 9) * ( c - 32 )))
f2c(32) # 0Lambda functions are used along with build-in function like map(), or filter().
Map
The map(<<func>>,<<sequence>>) function applies a function to every item in an sequence. It returns a list containing all the function call results.
def sqr(x): return x ** 2
list(map(sqr, [1, 2, 3, 4, 5])) # [1, 4, 9, 16, 25]
# with a lambda expression
list(map(lambda x: x+1, [1,2,3,4,5,6])) # [2, 3, 4, 5, 6, 7]
list(map(lambda x: x**2, range(0,12,2))) # [0, 4, 16, 36, 64, 100]Filter
The filter(<<func>>,<<sequence>>) function extracts each element in a sequence for which a function returns True.
list(filter(lambda x: x<0,range(-5,5))) # [-5, -4, -3, -2, -1]
list(filter(lambda x: (x%2==0), [1,5,4,6,8,11,3,12])) # [4, 6, 8, 12]
## intersection
a,b = [1,2,3,5,7,9],[2,3,5,6,7,8]
list(filter(lambda x: x in a,b)) # [2, 3, 5, 7]Reduce
The reduce() function reduces a sequence to a single value by combining all elements via a defined function.
reduce(<<func>>,<<sequence>>[,<<initializer>>])
By default, the first item in the sequence initialized the starting value.
from functools import reduce
reduce(lambda x,y: x+y, [1,2,3,4]) # 10
reduce(lambda x,y: x*y, [2,3],2) # 12
import operator
reduce(operator.sub,[50,3,4,6]) # 37
## flatten a list
reduce(list.__add__, [[1, 2, 3], [4, 5], [6, 7, 8]], []) # [1, 2, 3, 4, 5, 6, 7, 8]
## union of a list of sets
reduce(operator.or_, ({1},{1,2},{1,3})) # {1, 2, 3}
## intersection of a list of sets
reduce(operator.and_, ({1},{1,2},{1,3})) # {1}Classes
Classes, instances, and data attributes:
- A class is defined with the keyword
classfollowed by a name (capitalized) and colon. - Class instantiation uses function notation to assign a class object (instance”) to a variable.
- Class attributes are referenced with the dot notation
<object>.<attribute>. - Object data attributes (instance variables) need not be declared, they are assigned on first used.
class Human(): # define a class called Human
pass # Use pass for a class without attributes/methods
# create two instances of the class
alice = Human()
bob = Human()
# set data attributes of both instances
alice.age = 25
bob.age = 31
# print instance attributes
print(bob.age,alice.age) # 31 25Class Constructor & Instance Methods
- Methods automatically pass a class object
self(by convention) as first argument. - The method
__init__()(the constructor) is automatically invoked on newly-created class instances. - Instance objects can use attribute references to data attributes and methods.
class Human():
# constructor
def __init__(self, name, age):
self.name = name
self.age = age
# method
def who(self):
return '{} age {}'.format(self.name, self.age)
# Iterate over two class objects
for _ in (Human('alice',25),Human('bob',31)):
# call the method of an object
print(_.who())
# pass an object to a method
print(Human.who(_))Class Variables & Class Methods
Class variables:
- Shared among all instances of a class
- Accessible as
<class>.<attribute>or as<object>.<attribute>
Class methods:
- Declared with a decorator
@classmethod - Automatically pass a class as first argument called
cls(by convention) - Typically use to build alternative constructors
class Human():
num = 0 # define a class variable
# constructor
def __init__(self, name, age):
self.name = name
self.age = age
# increment the number of humans
Human.num += 1
# decorator to identify a class method
@classmethod
def from_str(cls, string):
name, age = string.split(':')
return Human(name,age)
# method
def who(self):
# use self to access a class variable
return '{} age {} [of {}]'.format(self.name, self.age, self.num)
humans = [
Human('alice',25),
Human('bob',31),
Human.from_str('joe:19')
]
print(humans[2].who()) # joe age 19 [of 3]Class Properties
A method used to get a value is decorated with @property before its definition.
A method used to set a value is decorated with @<<name>>.setter before its definition.
class C:
def __init__(self,v):
self._v = v
# getter
@property
def v(self):
return self._v
# setter
@v.setter
def v(self,__):
self._v = __
c = C(123)
c.v = 321 # set a value
print(c.v) # get a valueCommand-Line
Use following libraries:
- argparse to parse command-line options, arguments and sub-commands
- logging for multi-level application logging
Runtime services in the sys library:
import sys
sys.argv # list of command line arguments
sys.stdout.write(s) # write string s to standard output
sys.stderr.write(s) # write string s to standard error
sys.exit(i) # exit with error code iPython modules executable as main program also:
- Source files executed as the main program have the variable
__name__set to__main__ - Call an optional
main()function if not loaded by animport <module>
def main():
pass
if __name__ == '__main__':
main()Get input from the user with the input function:
- The argument will be printed followed by a prompt to wait for user input
- The function returns the input provided by the user
- Note that the return value is always of type
str
input('Give me a string: ')
int(input('Give me a number'))Consume data from the input pipe STDIN:
# read input from STDIN
if not sys.stdin.isatty():
stdin = io.StringIO(sys.stdin.read())
else:
raise Exception('No input data specified, STDIN is empty')venv
- …creation of virtual environments
- …requires Python 3.3 or newer.
- …a virtual environment includes:
- …isolates Python (interpreter,libraries) into a dedicated directory
- …
easy_installandpipwork es expected
python -m venv $path # create new virtual environment
source $path/bin/activate # activate environment
deactivate # exit virtual environmentconda
- …package manager for Python
- …open-source …BSD-3 License …hosted on github.com/conda
- Partly owned and controlled by Anaconda Inc…
- …Anaconda is a commercial distribution of Python …not free and not open-source
- …note that anaconda channel is prohibiting for commercial usage
conda info # basic information
conda info --envs # display a list of all environments
conda search --full-name python # list available Python versions
conda create --name <env> python=<ver> [<pkg>] # install global environment
conda create --prefix ~/<path> python=<ver> [<pkg>] # install use specific version
source activate <env> # load global environment
source activate ~/<path> # load user specific environment
source deactivate # unload environment
conda remove --name <env> --all # delete an environmentManaging packages…
- …make sure to only use free and open-source Conda package channels
- …check the active channels by running
conda config --show channels - …use
~/.condarcto configure the channels to use
conda list # list packages
conda search $pkg # search for a package
conda install $pkg # install into current environment
conda update $pkg # update package in current environment
conda remove $pkg # delete package fro current environment- …free minimal installer for conda
- …includes only conda and Python
ipython
Interactive Python
Keyboard shortcuts:
ctrl-l clear terminal
ctrl-c interrupt command
ctrl-d exit session
ctrl-r search command history
ctrl-a cursor to the beginning of the line
ctrl-e cursor to the end of the linr
ctrl-k cut text from cursor to end of line
ctrl-u cut text from beginning of line to cursor
ctrl-y yank (paste) text cut before
Access Documentation
Access the documentation with the build-in help(<obj>[.<method>]) function.
Alternatively use the short hand <obj>[.<method>]? with a question mark:
In [1]: tuple?
Init signature: tuple(self, /, *args, **kwargs)
Docstring:
tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable's items
If the argument is a tuple, the return value is the same object.
Type: type
In [2]: list.index?
Docstring:
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.
Type: method_descriptor
It support objects methods, and includes user defined code.
In [3]: def square(a):
...: """Return square of argument."""
...: return a**2
...:
In [4]: square?
Signature: square(a)
Docstring: Return square of argument.
Type: function
In [5]: square??
Signature: square(a)
Source:
def square(a):
"""Return square of argument."""
return a**2
Type: function
Display source code with the short hand <obj>[.<method>]?? (two questions marks), unless it is a build-in implemented in C.
Help support wild card completion?
In [6]: C*Error*?
ChildProcessError
ConnectionAbortedError
ConnectionError
ConnectionRefusedError
ConnectionResetError
In [7]: dict.*__g*?
dict.__ge__
dict.__getattribute__
dict.__getitem__
dict.__gt__
Magic Commands
The %lsmagic command lists all magic commands:
- Single magic commands are prefixed with % (percent)
- Multi-line expressions start with %% (double percent)
- Prefix the magic command with ? (question mark) to see the help text
In [1]: ?%lsmagic
Docstring: List currently available magic functions.
File: /usr/lib/python3/dist-packages/IPython/core/magics/basic.py
In [2]: %cat square.py
def square(a):
"""Return square of argument."""
return a**2
print(square(2))
print(square(10))
In [2]: %run square.py
4
100
General description of magic functions is available with %magic.
Shell Commands
Shell commands are prefixed with !, which can be omitted if auto-magic is on:
In [1]: %automagic 1
Automagic is ON, % prefix IS NOT needed for line magics.
In [2]: ls
ipython.md jupyter.ipynb mathplot.ipynb numpy.md README.md
Store output of a shell command into a variables by assignment. (Here the exclamation mark is required)
In [3]: files = !ls
In [4]: print(files)
['ipython.md', 'jupyter.ipynb', 'mathplot.ipynb', 'numpy.md', 'README.md']
In [5]: s = "cheers"
In [6]: !echo {s}
Interpolate the contents of a variable with {<var>}.
Subshell started with ! are non-interactive non-login instance of the user’s default shell:
In [1]: !echo $SHELL
/bin/zsh
In [2]: !ps -p $$ && :
PID TTY TIME CMD
19295 pts/5 00:00:00 zshZSH user need to load their custom environment with ~/.zshenv
Library
Numpy
The Nympy library adds support for large homogeneous multi-dimensional arrays and matrices, along with a large collection of high-level mathematical functions to operate on these arrays.
- Homogeneously typed (all elements have the same type).
- Numpy
ndarrayclass for n-dimensional array is a more efficient implementation of a python list. - Numerical operations with ndarray run on full compiled code speed.
# recommended convention to import numpy
import numpy as np # with abbr. npCreate
Dimensions are called axes, and the number of axes is rank
# crate an ndarray using a tuple or list
np.array((1,2,3,4,5))
np.array([1,2,3,4,5]) # [1 2 3 4 5]
# explicit data type
np.array((1.1,2,3)) # [ 1.1 2. 3. ]
np.array((1,2),float) # [ 1. 2.]
np.array([1,2],dtype=complex) # [ 1.+0.j 2.+0.j]
# nested tuples/lists result in multi-dimensional arrays
np.array(([1,2,3],[4,5,6],[7,8,9])) # [[1 2 3] [4 5 6] [7 8 9]]
np.array([range(i, i+3) for i in [1,2,3]]) # [[1 2 3] [2 3 4] [3 4 5]]
# initial with placeholder content
np.zeros((3,2)) # [[ 0. 0.] [ 0. 0.] [ 0. 0.]]
np.ones((2,2,2)) # [[[ 1. 1.] [ 1. 1.]] [[ 1. 1.] [ 1. 1.]]]
np.full((2,2),5) # [[5 5] [5 5]]
np.diag(np.array([1, 2, 3])) # [[1 0 0] [0 2 0] [0 0 3]]
# create sequences of numbers with args. [start,]stop[,step] (cf. range)
np.arange(5) # [0 1 2 3 4]
np.arange(5,10) # [5 6 7 8 9]
np.arange(0,30,10) # [0 10 20]
# linearly spaced sequence
np.linspace(2,3,5) # [2. 2.25 2.5 2.75 3.]
# log spaced sequence
np.logspace(0,1,5) # [1. 1.77827941 3.16227766 5.62341325 10. ]Random values:
# float values between 0 and 1 in defined dimension
np.random.rand(1,3) # [0.19544155 0.389351 0.09039669]
np.random.rand(2,2) # [[ 0.62209577 0.55083187] [ 0.31431768 0.98404029]]
# 5 integers between 0 and 10
np.random.randint(0,10,5) # [7 2 9 4 8]
# in defined dimension
np.random.randint(0,10,(2,3)) # [[6 3 6] [8 2 7]]Shape
# print dimensions
a = np.array(((1,2),(3,4)))
a.ndim # 2
a,size # 4
a.shape # (2, 2)
a.dtype # dtype('int64')
# size in bytes per element
a.itemsize # 8
# size of all elements (size x itemsize)
a.nbytes # 32
# flatten
np.array(((1,2),(3,4))).flatten()
np.array(((1,2),(3,4))).ravel() # [1 2 3 4]
# change dimensions
np.arange(6).reshape(2,3) # [[0 1 2] [3 4 5]]
# transpose
np.zeros((2,3)).T # [[ 0. 0.] [ 0. 0.] [ 0. 0.]]
np.zeros((2,3)).transpose()
## stacking together
# vertical
np.vstack((np.zeros((2,2)),np.ones((2,2)))) # [[ 0. 0.] [ 0. 0.] [ 1. 1.] [ 1. 1.]]
# horizontal
np.hstack((np.zeros((2,2)),np.ones((2,2)))) # [[ 0. 0. 1. 1.] [ 0. 0. 1. 1.]]
np.hsplit(np.arange(10),2) # [[0 1 2 3 4] [5 6 7 8 9]]Operations
np.array((10,20,30)) + np.array((1,2,3)) # [11 22 33]
np.array((10,20,30)) - np.array((1,2,3)) # [ 9 18 27]
np.array((2,4,8)) ** 2 # [ 4 16 64]
np.array((2,4,8)) >= 4 # [False True True]
np.array((2,2,2)).sum() # 6
np.array(((1,2),(4,5))).sum(axis=1) # [3 9]
np.array((1,2,3)).min() # 1
np.array((1,2,3)).max() # 3
np.array(((1,2),(4,5))).cumsum(axis=1) # [[1 3] [4 9]]
# vector products
np.array([1,2]).dot(np.array([3, 4])) # 11
# multiply a vector by a matrix
np.array([1,2]).dot(np.array([[3,4],[5,6]])) # [13 16]
# multiply matrices
np.array([[1,2],[3,4]]).dot(np.array([[5,6],[7,8]])) # [[19 22] [43 50]]Indexing, Slicing and Iterating
a = np.array([1,2,3,4])
# access elements in array a
a[3] # 4
a[-2] # 3
a[:2] # [1 2] last index not included!
a[3] = 5 # [1 2 3 5]
## multiple dimensions
a = np.array([[1,2,3],[4,5,6]], float)
# ':' all elements in dimension
a[1,:] # [ 4. 5. 6.]
a[:,2] # [ 3. 6.]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
a[:2,1:3] # [[2 3] [6 7]]
# reversing a sequence
np.arange(10)[::-1] # [9 8 7 6 5 4 3 2 1 0]
# slice sequences [start:end:step]
np.arange(10)[2:9:3] # [2 5 8]
np.arange(10)[::3] # [0 3 6 9]
# ... (dots) represent as many colons as needed to produce a complete indexing tuple
np.arange(12).reshape(3,4)[1,...] # [4 5 6 7]
np.arange(12).reshape(3,4)[...,2] # [2 6 10]Slicing operation creates a view on the original array.
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
b = a[::2] # [0 2 4 6 8]
np.may_share_memory(a,b) # True
c = b.copy() # force a copy
np.may_share_memory(a,c) # FalseIO
Store data into a file:
# write a binary file
>>> np.array([1,2,3],float).tofile('f.bin')
>>> !file f.bin
f.bin: dBase III DBT, next free block index 1
>>> print(np.fromfile('f.bin'))
[ 1. 2. 3.]
# write a clear text file
>>> np.savetxt('f.txt',np.array((1,2,3)))
>>> !cat f.txt
1.000000000000000000e+00
2.000000000000000000e+00
3.000000000000000000e+00
>>> print(np.loadtxt('f.txt'))
[ 1. 2. 3.]Embedded Python
What is MicroPython?
- Reimplementation of Python 3 for MCUs
- Efficient with resources, runs on bare metal
- Written in C++, includes compiler, run-time
- REPL (read, evaluate, print loop)
- Compiler emitters…
- Byte code for a virtual machine
- Native machine code (x86, x64, ARM…)
- Supports inline assembler
Micro:bit uses a pre-compiles run-time…
- Runtime
.hexflashed to the micro:bit .hexcontains complete MicroPython language
CicruitPython open source derivative of MicroPython
Install uflash:
sudo apt install -y python3-pip
pip3 install uflash
# mount the device
pmount /dev/sdb MICROBIT
uflash $sourceReferences
- CircuitPython, Adafruit
- MicroPython
- MicroFS micro:bit command-line tool
- uFlash - Flash Python onto the BBC’s micro:bit device
Editors & IDEs…
- Mu Python Editor
- Micro:bit Web Python Editor
Workshops & Tutorials…
- BBC micro:bit MicroPython documentation
- Networking with the micro:bit Python Edition
- UCL’s BBC Micro:bit Tutorials
- Micro:bit Lessons - Introduction to cryptography
- Conway’s Game of Life
- BBC micro:bit – Tetris Game
- micro:bit Space Invaders
References
Lectures…
- CS50P, CS50’s Introduction to Programming with Python, Harvard
Books…
- 100 Page Python Intro
- Learn Python with Jupyter