import numpy as np import matplotlib.pyplot as plt from scipy.linalg import norm from scipy.optimize import fsolve
norm
and fsolve
from
the linear algebra and optimization modules of the
scipy package.
as np
and as plt
declarations, the functions from the first two packages are accessed
with preceding np.
and plt.
name tags
like this:
%matplotlib inline import matplotlib.pyplot as plt import numpy as np fig, ax = plt.subplots() x = np.linspace(0,3.14,50) y = np.cos(x) ax.plot(x,y,color='red')
np.linspace
and np.cos
are numpy
functions, while plt.subplots
and ax.plot
are
matplotlib functions. When the cell is run, it incidentally plots
for :
as np
and as plt
serves to
reduce the amount of typing you have to do. If you leave them out,
writing just import numpy
and import
matplotlib.pyplot
you would have to write some lengthier function
names: numpy.linspace
, numpy.cos
,
and matplotlib.pyplot.subplots
in the above example.
norm
function
of the linear algebra module in the scipy package:
from scipy.linalg import norm norm([3,4])
5.0
.
import numpy as np print(np.e) print(np.pi)
2.718281828459045 3.141592653589793
import numpy as np print(np.sqrt(25)) print(np.exp(1)) print(np.log(np.e)) print(np.power(3,2)) print(np.power(2,10)) print(np.cos(np.pi/2)) print(np.arccos(0) * 2) print(np.sin(0)) print(np.arctan(1) * 180/np.pi)
5.0 2.718281828459045 1.0 9 1024 6.123233995736766e-17 3.141592653589793 0.0 45.0
np.cos(np.pi/2)
evaluates to
6.123233995736766e-17
. This
is Pythons scientific notation for the number:
print(np.log10(1e-17)) print(np.log10(1e4))
-17.0 4.0
np.log10
implements the common logarithm (the logarithm to the base 10).
_
= the underscore character
mass
, Mass
,
and MASS
are considered three different variables.
mass = 30 velocity = [3, 4] speed = 5
m = 30 v = [3, 4] sp = 5
type
function:
mysincerity = True mynumber = 5 myrational = 3.14 mystring = 'abc' mylist = [2, 4, -2, 5] mytuple = (7, 'horse') mydict = {'yes': 25, 'no': 12} print('type(mysincerity)',type(mysincerity)) print('type(mynumber) ',type(mynumber)) print('type(myrational) ',type(myrational)) print('type(mystring) ',type(mystring)) print('type(mylist) ',type(mylist)) print('type(mytuple) ',type(mytuple)) print('type(mydict) ',type(mydict))
type(mysincerity) <class 'bool'> type(mynumber) <class 'int'> type(myrational) <class 'float'> type(mystring) <class 'str'> type(mylist) <class 'list'> type(mytuple) <class 'tuple'> type(mydict) <class 'dict'>
isinstance
function:
print('is mynumber an int',isinstance(mynumber,int)) print('is mynumber a str ',isinstance(mynumber,str)) print('is mylist an int ',isinstance(mylist,int)) print('is mylist a list ',isinstance(mylist,list))
is mynumber an int True is mynumber a str False is mylist an int False is mylist a list True
asimplelist = [2, 4, -2, 5] acomplicatedlist = [2, 'text', [100, 200]]
print('One element: ',asimplelist[0]) print('Another element: ',asimplelist[1]) print('2nd lists 2nd element:',acomplicatedlist[1]) print('2nd lists 3rd element:',acomplicatedlist[2])
One element: 2 Another element: 4 2nd lists 2nd element: text 2nd lists 3rd element: [100, 200]
[n:m]
as in:
print('Entire list: ',asimplelist) n = 1 m = 3 print('Two elements:',asimplelist[n:m])
n = 1
to the element right before element with index m = 3
:
Entire list: [2, 4, -2, 5] Two elements: [4, -2]
n
or m
to get all preceding or succeeding elements:
print('Preceding elements: ',asimplelist[:m]) print('Succeeding elements:',asimplelist[n:]) print('All elements: ',asimplelist[:])
Preceding elements: [2, 4, -2] Succeeding elements: [4, -2, 5] All elements: [2, 4, -2, 5]
asimplelist = [10, 4, -2, 5] asimplelist
[10, 4, -2, 5]
asimplelist[0] = 2 asimplelist
[2, 4, -2, 5]
asimplelist.append(8) asimplelist
[2, 4, -2, 5, 8]
2
by invoking the pop()
method:
asimplelist.pop(2)
-2
asimplelist
[2, 4, 5, 8]
asimplelist.pop(-1)
8
asimplelist
[2, 4, 5]
new_list = asimplelist + [3, 7] new_list
[2, 4, 5, 3, 7]
mylist = [2, 4, -2, 5] mylist
[2, 4, -2, 5]
doubledlist = [2*elem for elem in mylist] doubledlist
[4, 8, -4, 10]
for
and in
keywords are controlling the statement together
with the embracing square brackets, [
and ]
that make the so-called list-comprehension
appear as a list in the code even before it is evaluted. Basically, the list-comprehension runs through
all elements of the list calling them elem
(in this example) and evaluating what is between [
and
for
.
if
statement and only get elements for the new list if some condition is fulfilled. Picking only
elements with positive values is done like this:
positive_list = [elem for elem in mylist if elem > 0] positive_list
[2, 4, 5]
somelist = [3.1, 4, 4.4, 8.1, 9] somelist
[3.1, 4, 4.4, 8.1, 9]
intlist = [int(el) for el in somelist if isinstance(el,int)] intlist
[1, 5]
(
and )
.
The elements of tuples are accessed like the elements of lists, but
the elements of tuples cannot be changed.
{
and }
, around
key-value pairs that are separated by commas. The key and the value in a pair are
separated by a colon, :
. It may look like
this:
mydict = {'dogs': 5, 'cats': 2, 'rats': 0}
mydict['mice'] = 8
how_many_mice = mydict['mice'] how_many_birds = mydict.get('birds',0)
.get(key,default)
is the safe choice
if one is not sure if the key-value pair exists and if one wishes to supply a default (it is
optional).
mydict = {'dogs': 5,'cats': 2,'rats': 0} for key,value in mydict.items(): print(key,value)
dogs 5 cats 2 rats 0
myfunctionlabel = 'f(x)'
myderivative = "f'(x)"
'pi: {:.4f}'.format(np.pi)
'pi: 3.1416'
which
can be printed.
{}
in your string. For each occurence of
{}
an argument must be given in the
.format()
call. Here are some examples:
'Arg one: {}, arg two: {}'.format(5,'five')
'Arg one: 5, arg two: five'
{:5d}
that the first argument is a
integer number (with d
) to be printed as 5 characters
and with {:8s}
that the second argument is a string (with s
) to be
printed on 8 characters:
'Arg one: {:5d}, arg two: {:8s}'.format(5,'five')
'Arg one: 5, arg two: five '
{:f}
, {:.3f}
, and
{:.5f}
that three floating point values are to be
printed
with the default number of decimals, with 3 decimals, and with 5
decimals, respectively:
'Arg one: {:f}, arg two: {:.3f}, arg three: {:.5f}'.format(np.pi,np.pi,np.pi)
'Arg one: 3.141593, arg two: 3.142, arg three: 3.14159'
'Arg one: {:10f}, arg two: {:10.3f}, arg three: {:10.5f}'.format(np.pi,np.pi,np.pi)
'Arg one: 3.141593, arg two: 3.142, arg three: 3.14159'
:
, one may
refer to which argument is to be inserted. Here we have only two
arguments and use them in the order first, second, first, since the
formatting strings, {0:10f}
,
{1:10.3f}
, {0:10.5f}
, contain the
0:
, 1:
, and 0:
parts:
'Arg one: {0:10f}, arg two: {1:10.3f}, arg one: {0:10.5f}'.format(np.pi,2*np.pi)
'Arg one: 3.141593, arg two: 6.283, arg one: 3.14159'
format
works here (use the new style).
mytuple = (np.pi/2,np.pi,2*np.pi) ','.join(['{:8.2f}'.format(x) for x in mytuple])
' 1.57, 3.14, 6.28'
.
for
-statement on a list (or on a more complicated Python object, an iterator, such as range
):
print('--begin--') for elem in ['zero','one','two','three']: print(elem) print('--end--')
--begin-- zero one two three --end--
print
-statement is repeated four times, and each time the variable elem
is
adopting a new value from the list in the for
statement.
Note how the indentation (the four space-characters in front of print
-statement
is part of the syntax for a for
-statement.
total_length_of_strings = 0 for elem in ['zero','one','two','three']: total_length_of_strings += len(elem) print('string: {:7s} has length: {:3d}'.format(elem,len(elem))) print('total length of strings: ',total_length_of_strings)
string: zero has length: 4 string: one has length: 3 string: two has length: 3 string: three has length: 5 total length of strings: 15
f
:
f = lambda x : x**2 - 2
:
, and what follows
defines what should be evaluated and returned whenever the function is called. Here are some examples:
print(f(0)) print(f(1),f(2))
-2 -1 2
f = lambda x,sigma: 1/np.sqrt(2*np.pi)/sigma * np.exp(-x**2/2/sigma**2)
lambda x,sigma
indicates that the function expects two arguments, one
for each variable.
Calling a function of more than one variable, all variables must be given:
print('f(0,1)',f(0,1)) print('f(0,2)',f(0,2)) print('f(1,2)',f(1,2))
f(0,1) 0.3989422804014327 f(0,2) 0.19947114020071635 f(1,2) 0.17603266338214976
x**2
and sigma**2
would not work and would
have to be replaced with np.power(x,2)
and np.power(sigma,2)
, respectively. We can then
evaluate the three function values from before in one go:
import numpy as np np.set_printoptions(precision=3) f = lambda x,sigma: 1/np.sqrt(2*np.pi)/sigma * np.exp(-np.power(x,2)/2/np.power(sigma,2)) f([0, 0, 1],[1, 2, 2])
array([0.399, 0.199, 0.176])
x = np.linspace(-3,3,7) x
array([-3., -2., -1., 0., 1., 2., 3.])
f(x,1)
array([0.004, 0.054, 0.242, 0.399, 0.242, 0.054, 0.004])
f(x,2)
array([0.065, 0.121, 0.176, 0.199, 0.176, 0.121, 0.065])
f(x,3)
array([0.081, 0.106, 0.126, 0.133, 0.126, 0.106, 0.081])
fig, ax = plt.subplots() f = lambda x,sigma: 1/np.sqrt(2*np.pi)/sigma * np.exp(-np.power(x,2)/2/np.power(sigma,2)) x = np.linspace(-np.pi,np.pi,100) ax.plot(x,f(x,0.5),linewidth=3,color='b') ax.plot(x,f(x,1),linewidth=3,color='r') ax.plot(x,f(x,2),linewidth=3,color='y') ax.grid() ax.set_xlabel('$x$') ax.set_ylabel('$f(x,\sigma)$') ax.legend(['$\sigma=0.5$','$\sigma=1$','$\sigma=2$'])
print
, type
, isinstance
,
and so on, are in fact pieces of computer code that do well defined
actions on data in variables and return results or provide some
actions (e.g. generating graphical output, electronic files or the
like). One may easily write new functions in Python thereby
extending its capabilities while keeping the code readable. One way
of doing this is to write a lambda function as described elsewhere.
def myfunc(arg1, arg2): print('myfunc({},{})'.format(arg1,arg2),end=' = ') var1 = min(10,arg1) var2 = min(10,arg2) res = var1 * var2 return res print(myfunc(5,7)) print(myfunc(5,12)) print(myfunc(15,12))
myfunc(5,7) = 35 myfunc(5,12) = 50 myfunc(15,12) = 100
def
-keyword and the following variable name, here myfunc
,
becomes the name of the function. In parentheses, (
and )
, follow the arguments, here arg1
and arg2
, and then a colon, :
. Every following indented statement will be a part of the function. That
means the statements will be executed every time the function is called. In the example, the function is called three times. In the
the first call, the statements in the function will be executed with the two variables arg1
and arg2
having values 5
and 7
, respectively. In the next call of the function, the statements
will be executed with arg1
and arg2
being 5
and 12
, respectively, and so on.
end=' = '
means in the call
of the print
-function: It changes
the print
-function from automatically adding a line
break, '\n'
, after the printed string(s), to adding
the string following end=
, in this case '
= '
. Here is another example:
print('123') print('456',end='...') print('789')
123 456...789
def mysum(x=5,y=7,z=11): res = x + y + z print('x={} y={} z={} res={}'.format(x,y,z,res)) return x + y + z
mysum(1,2,3)
x=1 y=2 z=3 res=6
mysum(1,2) mysum(1) mysum()
x=1 y=2 z=11 res=14 x=1 y=7 z=11 res=19 x=5 y=7 z=11 res=23
z
argument may given like this without any positional
arguments, or with for example the first positional argument given:
mysum(z=0) mysum(1,z=0)
x=5 y=7 z=0 res=12 x=1 y=7 z=0 res=8
mysum(z=0,y=2)
x=5 y=2 z=0 res=7
mysum(1,z=0,3)
would not
work, but throw the error message: SyntaxError: positional argument follows keyword argument
.
True
or False
.
Variables of other types may be converted to Boolean type, e.g. integers:
bool(-1), bool(0), bool(1), bool(2)
(True, False, True, True)
bool(''), bool('0'), bool('1'), bool('False'), bool('True')
(False, True, True, True, True)
None
, that evaluates to False
:
bool(None)
False
False
:
bool(()), bool([]), bool({})
(False, False, False)
True
.
True
except if they are an
integer 0
, an empty string, ''
,
the NoneType value, None
, or an empty tuple, list, or dictionary, ()
, []
, or
{}
, in which
case their Boolean representation is False
.
==
operator that requires its two arguments
to evaluate to the same value in order to return True
:
0 == 0, 0 == 5 - 5, 'three' == 'Three'.lower()
(True, True, True)
False
otherwise:
0 == 1, 3 == 3 - 6, 3 == 'three'
(False, False, False)
>
, <
, <=
, etc.
in
that
tests if a value appears in a sequence (a string, a tuple, a list, a dictionary):
'a' in 'char', 3 in (1, 2), 3 in [2, 3], 3 in {2: 'two', 3: 'three'}
(True, False, True, True)
and
and or
:
expr1 = 1 == 1 and 1 > 2 expr2 = 1 == 1 or 1 > 2 expr1, expr2
(False, True)
not
:
not True, not(True), not(False), not(1==2), 1 not in [0, 2, 4]
(False, False, True, True, True)
not True
) and as a function (e.g. not(True)
).
if
-else
compound statement is invoked. In one of its simplest
forms it may look like this:
myinput = input('Write something and hit ENTER: ') if myinput: print('myinput as Boolean is True') else: print('myinput as Boolean is False')
myinput
appearing after if
is treated as an expression that is
evaluted and converted to Boolean type. If the result is True
any indented statements
following the colon, :
, are executed, otherwise, the indented statements following
the else:
are executed.
elif
and
constructing a
if
-elif
-else
compound statement as in
this example:
yourstring = input('Write a number') if yourstring == '0': res = 'zero' elif yourstring.isdigit(): res = 'positive' elif yourstring[0] == '-' and yourstring[1:].isdigit(): res = 'negative' else: res = 'not a number' print('Your input {} is {}'.format(yourstring,res))
Choose which booklet to go to: