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
= 1.2 + 8 # assign right expression
x = y = z = 0 # assign a single value to multiple variables
x = 1,2,3 # multiple assignments
x,y,z = y,x # variable swap
x,y *b = [1,2,3] # unpacking a sequence
a,del x # remove variable
= None # undefined value
x id(x) # return object memory address for variable x
hex(id(x)) # ...hexadecimal memory address
globals() # dictionary of global variables
Naming conventions:
# underscore separated downcase letters
var_with_sep # unused variable (i.e. within a loop)
_ # public
var # internal
_var # convention to avoid conflict keyword
var_ # private use in class
__var # protected use in class
_var_ # "magic: method or attribute __var__
- 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)
nonlocal
assigns to variables in an outer scope (but not global)global
assigns 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 scope
Numbers
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 value
Types, 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) # True
Arithmetic
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]) # 1
Logic
## 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 # 2
Strings
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()
- …
f
as string literal prefix …{}
curly braces containing expressions …will be replaced with their values - …evaluated at runtime …allow any valid Python expressions
= 's'
v f'text{v}' # 'texts'
f"{1 + 1}" # '2'
F'{v.upper()}' # 'S'
Multi line f-strings…
# ...place an f in front of each line
= f'line' \
v 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
elif
followed 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'
None)
}.get(case,
print(switch('a')) # A
def a():
return 'A'
def b():
return 'B'
= { 'a': a(), 'b': b() }
switch
print(switch['a']) # A
Loops
Code blocks repeated through a number of loops (iterations):
- The
break
statement executed within a loop breaks the control flow out of the loop immediatly - A
continue
statement skips to the next interation of a loop
A while
loop executed a code block until the loop condition is false:
= 0
x while True: # endless loop
print(x)
if x == 3: # break condition
break # break the loop
+= 1 # increment x
for
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
= ('a','b','c')
t # ('a', 'b', 'c')
t # does a value exists in a tuple t
'a' in t # True
'a' not in t # False
# access elements in a tuple t
0] # 'a'
t[-2] # 'b'
t[2] # ('a', 'b')
t[:2:] # ('c',)
t[# find index of value
'b') # 1
t.index(# number of occurrences of a given value
'b') # 1
t.count(# 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
[] = [1,2,'a',3,'b'] # list assignment to variable
l # append value to the end of the list list
4)
l.append(# append multiple values to list
5,'c'])
l.extend([# print a list
# [1, 2, 'a', 3, 'b', 4, 5, 'c']
l # does a value exists in a list
'a' in l # True
# find index of a value
'a') # 2
l.index(# number of elements in list
len(l) # 8
# access values by index
# [1, 2, 'a', 3, 'b', 4, 5, 'c']
l[:] 4] # [1, 2, 'a', 3]
l[:-4] # 'b'
l[4:-1] # ['b', 4, 5]
l[# delete element by value
3)
l.remove(# [1, 2, 'a', 'b', 4, 5, 'c']
l # remove index from list and return its value
-1) # 'c'
l.pop(# [1, 2, 'a', 'b', 4, 5]
l # concatenation return a new list
+ [6,7,'c'] # [1, 2, 'a', 'b', 4, 5, 6, 7, 'c']
l # [1, 2, 'a', 'b', 4, 5]
l # delete element by index
del l[3]
# [1, 2, 'a', 4, 5]
l # number of occurrences of a given value
'a') # 1
l.count(# shallow copy of the list
= l.copy()
m 0] = 'z'
m[# [1, 2, 'a', 4, 5]
l # ['z', 2, 'a', 4, 5]
m # 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 'a'] = 1
d['b'] = 2
d[# {'a': 1, 'b': 2}
d 'b'] # 2
d[# remove element by key
del d['a']
# {'b': 2}
d # merge
'c':3, 'd':4})
d.update({# {'b': 2, 'c': 3, 'd': 4}
d # remove element, return value
'c') # 3
d.pop(# {'b': 2, 'd': 4}
d # get a value
'b') # 2
d.get(# {'b': 2, 'd': 4}
d # 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
= subprocess.getoutput('ls -l')
text 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’
= "1st line\n2nd line\n3rd line\n4th line"
txt = '/tmp/file.txt'
path ## write into a file
= open(path,'w',encoding='utf8')
f # write into the file
f.write(txt) # write cache
f.flush() # close when finished
f.close() = open(path,'r')
f # path ot the file '/tmp/file.txt'
f.name # read entire file
f.read() # iterate over file content
for l in f.readlines() # by line
for l in iter(f):
for l in f.read().split('\n') # by seperator
Using 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/function
Import a module to use its functions:
import math
# 3.141592653589793
math.pi 81) # 9.0 math.sqrt(
Load module, and allow direct access to functions:
from math import pi,e,sin,log
/4) # 0.7071067811865475
sin(pi**2) # 2.0 log(e
Define an alias for a module:
import math as m
# 3.141592653589793 m.pi
Functions
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
return
keyword passes values from the function
# includes argument with default value
def f(x,y,z=3):
"""documentation"""
return (x,y,z)
1,2) # (1, 2, 3)
f(# variable positional arguments as tuple
def g(x,*y):
return (x,y)
1,2,3,4,5,6) # (1, (2, 3, 4, 5, 6))
g(# variable named arguments as dict
def h(x,**y):
return [x,y]
1,a=1,b=2) # [1, {'a': 1, 'b': 2}] h(
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.
= lambda x,y : x+y
f 1,1) # 2
f(= lambda x: x**2 + 2*x - 5
f 2) # 3
f(# Fahrenheit to Celsius conversion
= lambda c: float('{:.2f}'.format((5.0 / 9) * ( c - 32 )))
f2c 32) # 0 f2c(
Lambda 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
= [1,2,3,5,7,9],[2,3,5,6,7,8]
a,b 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
class
followed 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
= Human()
alice = Human()
bob # set data attributes of both instances
= 25
alice.age = 31
bob.age # print instance attributes
print(bob.age,alice.age) # 31 25
Class 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():
= 0 # define a class variable
num # constructor
def __init__(self, name, age):
self.name = name
self.age = age
# increment the number of humans
+= 1
Human.num # decorator to identify a class method
@classmethod
def from_str(cls, string):
= string.split(':')
name, age 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 'alice',25),
Human('bob',31),
Human('joe:19')
Human.from_str(
]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(123)
c = 321 # set a value
c.v print(c.v) # get a value
Command-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
# list of command line arguments
sys.argv # write string s to standard output
sys.stdout.write(s) # write string s to standard error
sys.stderr.write(s) # exit with error code i sys.exit(i)
Python 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():
= io.StringIO(sys.stdin.read())
stdin 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_install
andpip
work es expected
python -m venv $path # create new virtual environment
source $path/bin/activate # activate environment
deactivate # exit virtual environment
conda
- …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 environment
Managing packages…
- …make sure to only use free and open-source Conda package channels
- …check the active channels by running
conda config --show channels
- …use
~/.condarc
to 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 zsh
ZSH 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
ndarray
class 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. np
Create
Dimensions are called axes, and the number of axes is rank
# crate an ndarray using a tuple or list
1,2,3,4,5))
np.array((1,2,3,4,5]) # [1 2 3 4 5]
np.array([# explicit data type
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]
np.array([# nested tuples/lists result in multi-dimensional arrays
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]]
np.array([# initial with placeholder content
3,2)) # [[ 0. 0.] [ 0. 0.] [ 0. 0.]]
np.zeros((2,2,2)) # [[[ 1. 1.] [ 1. 1.]] [[ 1. 1.] [ 1. 1.]]]
np.ones((2,2),5) # [[5 5] [5 5]]
np.full((1, 2, 3])) # [[1 0 0] [0 2 0] [0 0 3]]
np.diag(np.array([# create sequences of numbers with args. [start,]stop[,step] (cf. range)
5) # [0 1 2 3 4]
np.arange(5,10) # [5 6 7 8 9]
np.arange(0,30,10) # [0 10 20]
np.arange(# linearly spaced sequence
2,3,5) # [2. 2.25 2.5 2.75 3.]
np.linspace(# log spaced sequence
0,1,5) # [1. 1.77827941 3.16227766 5.62341325 10. ] np.logspace(
Random values:
# float values between 0 and 1 in defined dimension
1,3) # [0.19544155 0.389351 0.09039669]
np.random.rand(2,2) # [[ 0.62209577 0.55083187] [ 0.31431768 0.98404029]]
np.random.rand(# 5 integers between 0 and 10
0,10,5) # [7 2 9 4 8]
np.random.randint(# in defined dimension
0,10,(2,3)) # [[6 3 6] [8 2 7]] np.random.randint(
Shape
# print dimensions
= np.array(((1,2),(3,4)))
a # 2
a.ndim # 4
a,size # (2, 2)
a.shape # dtype('int64')
a.dtype # size in bytes per element
# 8
a.itemsize # size of all elements (size x itemsize)
# 32
a.nbytes # flatten
1,2),(3,4))).flatten()
np.array(((1,2),(3,4))).ravel() # [1 2 3 4]
np.array(((# change dimensions
6).reshape(2,3) # [[0 1 2] [3 4 5]]
np.arange(# transpose
2,3)).T # [[ 0. 0.] [ 0. 0.] [ 0. 0.]]
np.zeros((2,3)).transpose()
np.zeros((## stacking together
# vertical
2,2)),np.ones((2,2)))) # [[ 0. 0.] [ 0. 0.] [ 1. 1.] [ 1. 1.]]
np.vstack((np.zeros((# horizontal
2,2)),np.ones((2,2)))) # [[ 0. 0. 1. 1.] [ 0. 0. 1. 1.]]
np.hstack((np.zeros((10),2) # [[0 1 2 3 4] [5 6 7 8 9]] np.hsplit(np.arange(
Operations
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]]
np.array(((# vector products
1,2]).dot(np.array([3, 4])) # 11
np.array([# multiply a vector by a matrix
1,2]).dot(np.array([[3,4],[5,6]])) # [13 16]
np.array([# multiply matrices
1,2],[3,4]]).dot(np.array([[5,6],[7,8]])) # [[19 22] [43 50]] np.array([[
Indexing, Slicing and Iterating
= np.array([1,2,3,4])
a # access elements in array a
3] # 4
a[-2] # 3
a[2] # [1 2] last index not included!
a[:3] = 5 # [1 2 3 5]
a[## multiple dimensions
= np.array([[1,2,3],[4,5,6]], float)
a # ':' all elements in dimension
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]]
a[:# reversing a sequence
10)[::-1] # [9 8 7 6 5 4 3 2 1 0]
np.arange(# slice sequences [start:end:step]
10)[2:9:3] # [2 5 8]
np.arange(10)[::3] # [0 3 6 9]
np.arange(# ... (dots) represent as many colons as needed to produce a complete indexing tuple
12).reshape(3,4)[1,...] # [4 5 6 7]
np.arange(12).reshape(3,4)[...,2] # [2 6 10] np.arange(
Slicing operation creates a view on the original array.
= np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
a = a[::2] # [0 2 4 6 8]
b # True
np.may_share_memory(a,b) = b.copy() # force a copy
c # False np.may_share_memory(a,c)
IO
Store data into a file:
# write a binary file
>>> np.array([1,2,3],float).tofile('f.bin')
>>> !file f.bin
bin: dBase III DBT, next free block index 1
f.>>> 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
.hex
flashed to the micro:bit .hex
contains 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 $source
References
- 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