Basic introduction of python#

Setting the environment for Python#

  • Anaconda : Include essential packages for basic scientific computation. It is easy to install it just follow the instruction.

  • Not required, but easy to use for beginners.

Why numerical approach?#

Need to confirm the mechanism of your idea#

  • An idea for the novel physics

  • Numerical experiments driven by scientific ideas

  • Numerical experiments driven theoretical ideas

Need to connect with real experiments#

  • To strenthen the abstract idea and connect with real world

  • Get additional information that is difficult to access in experiments and make prediction that is accessible for experiments

Numerics for many body physics is non-trivial!#

  • The problem itself is a intelletral challenging and interesting discrete mathmetical problems.

  • Hardware limitation force one to think in a smart way

Generate data to convey what you mean#

  • Statistics

  • Plots

My point of view of numerical approaches#

Level of numerical loading#

  • Light: Mathematica, Python, matlab (For quick checking and benchmark. Once the simple concept passes, use the medium or heavy numerical approach)

  • Heavy: C/C++, Fortran

Why Python?#

Simple, well-structured, general-purpose language#

  • Readability great for quality control and collaboration

  • Code how you think: many books now use python as pseudocode

High-level#

  • Rapid development

  • Do complicated things in few lines

Interactive#

  • Rapid development and exploration

  • No need to compile, run, debug, revise, compile

  • Data collection, generation, analysis and publication plotting in one place

Speed#

  • Usually plenty fast – will discuss more

  • Your development time is more important than CPU time

  • Not as fast as C, C++, Fortran but these can be easily woven in where necessary

Vibrant community#

  • Great online documentation / help available

  • Open source

Rich scientific computing libraries#

  • Don’t reinvent the wheel. Only reinvent important wheels!

Accessible for everyone. No need to pay money#

Scientific Python Key Components#

The core pieces of the scientific Python platform are:

Python, the language interpreter

  • Many standard data types, libraries, etc

  • Python 3.7 is the current version; use this

  • Python 2.7 (released 2010) is still maintained but will die in 2020

Jupyter: notebook based (in browser) interface

  • Builds on IPython, the interactive Python shell

  • Interactive manipulation of plots

  • Easy to use basic parallelization

  • Lots of useful extra bells and whistles for Python

Numpy, powerful numerical array objects, and routines to manipulate them.

  • Work horse for scientific computing

  • Basic linear algebra (np.linalg)

  • Random numbers (np.random)

Scipy, high-level data processing routines.

  • Signal processing (scipy.signal)

  • Optimization (scipy.optimize)

  • Special functions (scipy.special)

  • Sparse matrices and linear algebra

Matplotlib, plotting and visualization

  • 2-D and basic 3-D interactive visualization

  • “Publication-ready” plots

  • LaTeX labels/annotations automagically

Pandas, data analysis/management

  • data structures for relational data manipulation

  • useful in observational/numerical analysis

  • Won’t discuss here

Mayavi, 3-D visualization

  • For more sophisticated 3-D needs (won’t discuss)

Jupyter Workflow#

Two primary workflows:#

  1. Work in a Jupyter/IPython notebook. Write code in cells, analyze, plot, etc. Everything stored in .ipynb file.

  2. Write code in .py files using a text editor and run those within the IPython notebook or from the shell.

We still stick to the first.

While you are using a notebook, there is a kernel running which actually executes your commands and stores your variables, etc. If you quit/restart the kernel, all variables will be forgotten and you will need to re-execute the commands that set them up. This can be useful if you want to reset things. The input and output that is visible in the notebook is saved in the notebook file.

Note: .py files are called scripts if they consist primarily of a sequence of commands to be run and modules if they consist primarily of function definitions for import into other scripts/notebooks.

Notebook Usage#

Two modes: editing and command mode.

Press escape to go to command mode. Press return to go into editing mode on selected cell.

In command mode:

  1. Press h for a list of keyboard commands.

  2. Press a or b to create a new cell above or below the current.

  3. Press m or y to convert the current cell to markdown or code.

  4. Press shift-enter to execute.

  5. Press d d to delete the current cell. (Careful!)

In editing mode:

  1. Press tab for autocomplete

  2. Press shift-tab for help on current object

  3. Shift-enter to execute current cell

Two types of cells:

  1. Markdown for notes (like this)

  2. Code for things to execute

Exercise

Try editing this markdown block to make it more interesting. For example, type in some equations \(e^{i\pi}+1=0\).

Exercise

Execute the next block and then create a new block, type x. and press tab and shift-tab.

x = 10

Exercise

Run this stuff.

print('Hello, world!')
Hello, world!
"Hello, world!"
'Hello, world!'
2.5 * 3
7.5
3**3
27
3 + 3
6
"ab" + "cd"
'abcd'
"Hello" == 'Hello'
True

Variables and Objects#

Everything in memory in Python is an object. Every object has a type such as int (for integer), str (for strings) or ndarray (for numpy arrays). Variables can reference objects of any type and that type can change.

The equals sign in programming does not mean ‘is equal to’ as in math. It means ‘assign the object on the right to the variable on the left’.

a = 3
a
3
type(a)
int
a+a
6
2+a
5
import numpy as np
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[14], line 1
----> 1 import numpy as np

ModuleNotFoundError: No module named 'numpy'
a = np.array([1,2])
a
array([1, 2])
type(a)
numpy.ndarray
# All objects have properties, accessible with a .
a.shape
(2,)
a+a
array([2, 4])
2+a
array([3, 4])
a = "Hello, world!"
a
'Hello, world!'
type(a)
str
a+a
'Hello, world!Hello, world!'
2+a
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_128278/1750888518.py in <module>
----> 1 2+a

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Overloading#

Operators and functions will try to execute no matter what type of objects are passed to them, but they may do different things depending on the type. + adds numbers and concatenates strings.

Variables as References#

All variables are references to the objects they contain. Assignment does not make copies of objects.

a = np.array([1,2])
a
array([1, 2])
b = a
b
array([1, 2])
b[0] = 0
b
array([0, 2])
a
array([0, 2])

Types of Objects#

Basic Types#

  1. Numeric, Immutable

  2. Integer: -1, 0, 1, 2, …

  3. Float: 1.2, 1e8

  4. Complex: 1j, 1. + 2.j

  5. Boolean: True, False

  6. Strings, “hi”

  7. Tuples, (2,7, “hi”)

  • Ordered collection of other objects, represented by parentheses

  • can’t change after creation (immutable)

  1. Lists, [0,1,2,”hi”, 4]

  • Ordered collection of other objects, represented by square brackets

  • can add/remove/change elements after creation (mutable)

  1. Dictionaries, {‘hi’: 3, 4: 7, ‘key’: ‘value’}

  2. Functions, def func()

Common Scientific Types#

  1. NumPy arrays, array([1,2,3])

  • Like lists but all entries have same type

  1. Sparse arrays, scipy.sparse

  2. Pandas DataFrames, high level ‘table’ a bit like an excel spreadsheet

Basic Types: Numeric#

There are 4 numeric types:

  • int: positive or negative integer

  • float: a ‘floating point’ number is a real number like 3.1415 with a finite precision

  • complex: has real and imaginary part, each of which is a float

  • bool: two ‘Boolean’ values, True or False

a = 4
type(a)
int
c = 4.
type(c)
float
a = 1.5 + 0.1j
type(a)
complex
a.real
1.5
a.imag
0.1
flag = (3>4)
flag
False
type(flag)
bool
type(True)
bool
# Type conversion
float(1)
1.0

Careful with integer division!#

In Python 3, dividing integers promotes to a float. Use // for integer division.

3/2
1.5
3/2.
1.5

Force integer division:

3//2
1

Basic Types: Strings#

Strings are immutable sequences of characters. This means you can’t change a character in the middle of a string, you have to create a new string.

Literal strings can be written with single or double-quotes. Multi-line strings with triple quotes. ‘Raw’ strings are useful for embedding LaTeX because they treat backslashes differently.

'Hello' == "Hello"
True
a = """This is a multiline string.
Nifty, huh?"""
a
'This is a multiline string.\nNifty, huh?'
print("\nu")
u
print(r"\nu")
\nu
a = 3.1415
# Simple formatting (type convert to string)
"Blah " + str(a)
'Blah 3.1415'
# Old style string formatting (ala sprintf in C)
"Blah %1.2f, %s" % (a, "hi")
'Blah 3.14, hi'
# New style string formatting 
"Blah {:1.2f}, {}".format(a, "hi")
'Blah 3.14, hi'

Basic Types: Lists#

Python lists store ordered collections of arbitrary objects. They are efficient maps from index to values. Lists are represented by square brackets [ ].

Lists are mutable: their contents can be changed after they are created.

It takes time O(1) to:

  1. Lookup an entry at given index.

  2. Change an item at a given index.

  3. Append or remove (pop) from the end of the list.

It takes time O(N) to:

  1. Find items by value if you don’t know where they are.

  2. Remove items from near the beginning of the list.

You can also grab arbitrary slices from a list efficiently.

Lists are 0-indexed. This means that the first item in the list is at position 0 and the last item is at position N-1 where N is the length of the list.

days_of_the_week = ["Sunday","Monday","Tuesday",
                    "Wednesday","Thursday","Friday"]
days_of_the_week[0]
'Sunday'
# The slice from 2 to 5 (inclusive bottom, exclusive top)
days_of_the_week[2:5]
['Tuesday', 'Wednesday', 'Thursday']
days_of_the_week[-1]
'Friday'
# every other day
days_of_the_week[0:-1:2]
['Sunday', 'Tuesday', 'Thursday']
# every other day (shorter)
days_of_the_week[::2]
['Sunday', 'Tuesday', 'Thursday']
# Oops!
days_of_the_week.append("Saturday")
days_of_the_week[-1]
'Saturday'
days_of_the_week[5] = "Casual Friday"
days_of_the_week
['Sunday',
 'Monday',
 'Tuesday',
 'Wednesday',
 'Thursday',
 'Casual Friday',
 'Saturday']
# Get the length of the list
len(days_of_the_week)
7
# Sort the list in place
days_of_the_week.sort()
days_of_the_week
['Casual Friday',
 'Monday',
 'Saturday',
 'Sunday',
 'Thursday',
 'Tuesday',
 'Wednesday']

Remember tab completion Every thing in Python (even the number 10) is an object. Objects can have methods which can be accessed by the notation a.method(). Typing a. allows you to see what methods an object a supports. Try it now with days_of_the_week:

days_of_the_week.
  File "<ipython-input-64-56fb3f712b66>", line 1
    days_of_the_week.
                     ^
SyntaxError: invalid syntax

Each item is arbitrary: You can have lists of lists or lists of different types of objects.

aList = ["zero", 1, "two", 3., 4.+0j]
aList
['zero', 1, 'two', 3.0, (4+0j)]
listOfLists = [[1,2], [3,4], [5,6,7], 'Hi']
listOfLists[2][1]
6

Basic Types: Dictionaries#

A dictionary is an efficient map from keys to values. They are represented by curly brackets {}.

Dictionaries are mutable but all keys must be immutable. IE. keys can be strings, numbers, or tuples thereof but not lists or other dictionaries. Values can be anything.

It is unordered but takes time O(1) to:

  1. Lookup a value from a key

  2. Add a key, value pair

  3. Remove a key, value pair

It takes time O(N) to find an entry with a particular value.

You can iterate through all the entries efficiently O(N).

tel = {'emmanuelle': 5752, 'sebastian': 5578}
tel['francis'] = 5915
tel
{'emmanuelle': 5752, 'sebastian': 5578, 'francis': 5915}
tel['sebastian']
5578
tel.keys()
dict_keys(['emmanuelle', 'sebastian', 'francis'])
tel.values()
dict_values([5752, 5578, 5915])
len(tel)
3
'francis' in tel
True
del tel['francis']
tel
{'emmanuelle': 5752, 'sebastian': 5578}

Basic Types: Tuples#

A tuple is an ordered collection of objects. They are represented by round parantheses ().

Tuples are almost like lists but they are immutable. This means that they cannot be changed once they are created.

t = (1,2,3,'Hi')
t
(1, 2, 3, 'Hi')
# IMMUTABLE !
t[0] = 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-78-e89466f5bd6a> in <module>
      1 # IMMUTABLE !
----> 2 t[0] = 2

TypeError: 'tuple' object does not support item assignment

The empty tuple and length 1 tuples have special notation since parentheses can also represent grouping.

emptyTuple = ()
emptyTuple
()
lengthOne = ('hi',)
lengthOne
('hi',)
notLengthOne = ('hi')
notLengthOne
'hi'
notLengthOne[0]
'h'

Control Flow#

The flow of a program is the order in which the computer executes the statements in the code. Typically, this is in order from top to bottom. However, there are many cases where we want to change the flow in some way. For example, we might want to divide two numbers but only if the divisor is not zero. Or we might want to iterate: repeat a block of code many times for each value in some list. The commands which allow these are called control flow commands.

WARNING: Python cares about white space! You must INDENT CORRECTLY because that’s how Python knows when a block of code ends.

Typically, people indent with 4 spaces per block but 2 spaces or tabs are okay. They must be consistent in any block.

If/elif/else#

if 2>3:
    print("Yep")
    print("It is")

elif 3>4:
    print("Not this one either.")
    
else:
    print("Not")
    print("At all")
Not
At all

For Loops#

For loops iterate through elements in a collection. This can be a list, tuple, dictionary, array or any other such collection.

These are the most Pythonic way to think about iterations.

for i in range(5):
    j = i**3
    print("The cube of " + str(i) + " is " + str(j))
The cube of 0 is 0
The cube of 1 is 1
The cube of 2 is 8
The cube of 3 is 27
The cube of 4 is 64
for day in days_of_the_week:
    print("Today is " + day)
Today is Casual Friday
Today is Monday
Today is Saturday
Today is Sunday
Today is Thursday
Today is Tuesday
Today is Wednesday
for key in tel:
    print(key + "'s telephone number is " + str(tel[key]))
emmanuelle's telephone number is 5752
sebastian's telephone number is 5578

Enumerate to get index and value of iteration element

words = ('your', 'face', 'is', 'beautiful')

for (i, word) in enumerate(words):
    print(i, word)
0 your
1 face
2 is
3 beautiful

While Loops#

Repeats a block of code while a condition holds true.

x = 5

while x > 0:
    print("Bark " + str(x))
    x -= 1
Bark 5
Bark 4
Bark 3
Bark 2
Bark 1

Functions#

Any code that you call multiple times with different values should be wrapped up in a function. For example:

def square(x):
    """Return the square of x."""
    return x*x
square?
square(9)
81
def printAndSquare(x):
    """Print the square of x and return it."""
    y = x**2
    print(y)
    return y
printAndSquare?
printAndSquare(8)
64
64

Functions are Objects#

Functions are just like any object in Python:

type(square)
function

Make another variable refer to the same function:

a = square
a(5)
25

A function being passed to another function.

def test():
    print("In Test!")
    return

def callIt(fun):
    print("In callIt!")
    fun()
    return
callIt(test)
In callIt!
In Test!