Python For Quantum Mechanics#

Week 1: Variables#

from IPython.display import YouTubeVideo
YouTubeVideo('dU8NKvAxcnE',width=700, height=400)

Now we will move on to working directly in python; namely working with different types of data.

Integer and Float Variables#

To make a variable in python you can simply give it a value as shown here. Make sure to run the cell!

a = 1 # This is a variable we have called 'a' and given a value of 1.
''' Also this and the text above are comments! You can use this to make notes to you an others about your code.
 Anything following the hash symbol or enclosed in tripple qutation marks is not executed.
 Code can also be "commented out" for the purpose of testing.'''
' Also this and the text above are comments! You can use this to make notes to you an others about your code.\n Anything following the hash symbol or enclosed in tripple qutation marks is not executed.\n Code can also be "commented out" for the purpose of testing.'

As seen above we can add comments using # or ''' '''.

It should be noted that unlike other languages we do not need to specify the type (or class) of this variable, that will simply be infered from the value it is given. Here a is an integer becuase we have set it to one. To display a variable’s value we can use the print() function.

print(a)
1

We can also check what class this varible is using the type() function as follows and we find that a is indeed an integer (denoted by int).

print(type(a))
<class 'int'>

Another difference between Python and other languages is that equating two variables sets the value of one variable to a copy of the other. Subsequently changing one does not change the other.

a = 1
b = a
a = 1.5

print(a)
print(b)
1.5
1

As seen above we can also work with decimals which are called floating point variables (floats). This is a new data type we changed a into.

print(type(a))
<class 'float'>

We can also update the value of a variable in terms of it’s old value. This may seem very strange as an equation but the = sign should be thought of as an assignment rather than an equals sign in the traditional mathematical sense.

a = 1
print(a)
a = a + 1
print(a)
1
2

It should be noted that this action cannot be performed by a ++ operation (as in C/C++ etc.), but a +=, -= etc. operations can be done.

a = 1.5 # a is redefined as a float with value 1.5
print(a)
a += 0.5 # Here 0.5 is added to a
print(a)
a -= 1 # Here 1 is taken away from a
print(a)
1.5
2.0
1.0

In the last cell you have have noted that I mixed floats and integers in a single operation and a float was returned. This can also be done for multiplication *, division /, powers **, and absolute value abs().

# Multiplication
print(2*5) 
print(2.3*5)
10
11.5
# Powers
print(12.0**2) # returns float
print(12**2) # returns integer
print(pow(12.0,2)) # alternative to **
144.0
144
144.0
# Division (Float Division)
print(2/5)
print(1.0/5)
print(3/2.1)
0.4
0.2
1.4285714285714286
# Absolute Value
print(abs(-4))
print(abs(4.6))
4
4.6

/ will always give float division.

If the integer version of these operations is required one can simply make both vaules an integer and use // for division (this will round down to the nearest integer).

print(19/5) 
print(19//5) 
3.8
3

For those who are not familiar with other languages there is a modulo or remainder operation %. This is the remainder of a division operation which at first may not seem particulary useful but is actually a crucial operation in many algorithms. For example 3 divides into 20, 6 times with remainder 2 as shown.

print(20//3) # Integer division
print(20%3) # Remainder or modulo 
6
2

Scientific Notation#

Consider the following cell,

print(123450000000000000) # notice that this is an integer...
print(123450000000000000.0) # and this is a float
123450000000000000
1.2345e+17

At first it may seem like something has gone wrong and what was written was not printed to screen but in fact the float has been converted to scientific notation with e standing in for 10ˆ.

This can be very useful when dealing with very large or small values. For example,

\[h \approx 6.626 \times 10^{-34} \text{m}^2\text{kg/s}\]
\[m_e \approx 9.109 \times 10^{-31}\text{kg}\]
\[M_{sun} \approx 1.989 \times 10^{30} \text{kg}\]
h = 6.626e-34 # Plank's Constant in m^2 kg/s
e_mass = 9.109e-31 # electron mass in kg
sun_mass = 1.989e+30 # solar mass in kg

These are floats as demonstrated below.

print(type(h))
<class 'float'>

Comparison Operators and Boolean Variables#

It is often important to compare two variables with >, <, == (equal), != (not equal), >= (greater than or equal to), and <= (less than or equal to. Note that checking if two things are equal we use == rather than = which is reserved for assignment. But what would such an operation give as a value? Well, the statement is either true or false. This is exactly what is returned, a Boolean True or False, a new valiable. Let’s see how it works.

a = True
print(a)
print(1 < 2)
print(2 == 2)
print(7.1 != 7.2) # '!=' refers to not equal
print(4 >= 4.3)
print(type(4 >= 4.3))
True
True
True
True
False
<class 'bool'>

There exists the following operations that act on two Boolean values:

  • and: if both are True, it returns True, otherwise it returns False.

  • or: if either is True, it returns True, otherwise it returns False. Another useful Boolean operator is not which simply reverses the proceeding Boolean. An example of each of these is found below.

print((1 > 2) and (3 > 2))
print(True or (3 <= 2))
print(not (1 == 2))
False
True
True

Complex Numbers#

Python also supports complex numbers with the complex unit denoted by j which acts as one one expect. The extraction of the real and imaginary parts is also shown below.

z = 4 + 3j
w = 1 - 16j

print(type(z))
print(z + w)
print(z * w)

print() # just to seperate out our results

print(abs(z)) # the abs() function takes the modulus of the complex number

print()

print(z.real) # returns the real part of z
print(w.imag) # returns the complex part of w
<class 'complex'>
(5-13j)
(52-61j)

5.0

4.0
-16.0

Strings#

Another type of variable is a string which is an ordered set of characters. This is done using quotation marks. Words and phrases can therefore be outputted and added together (concatenated) with +.

word = 'hello'
phrase = 'how are you?'

whole = word + ', ' + phrase

print(type(word))
print(phrase)
print(whole)
<class 'str'>
how are you?
hello, how are you?

We can also ‘multiply’ a string by an integer in the following way

print((word + ' ')*3)
hello hello hello 

A string can include the new line character or '\n' to have the effect of a return.

print('hello,\nhow are you?')
hello,
how are you?

It is often useful to output variables intersperced in our text. A useful method to do this is the following,

state = 'up'
prob = .8152

text = 'the state was found to be in the %s state with probability %.2f' % (state, prob)

print(text)
the state was found to be in the up state with probability 0.82

Here the %s and the %f stand in for later specified strings and floats respectively. The .2 preceding the f refers to the fact that I want the answer rounded to two decimal places.

%d can be used for an integer and %g for a generic number.

We can find the length of a string using len(),

word = 'hello'
len(word)
5

and we can get specific characters by using [] and groups of characters using :.

word = 'hello'

letter = word[0] 
# notice that in python numbering starts at 0, 
# this notation will be discussed further in the next section on data structures

print(letter)
h

h

e

l

l

o

,

t

h

i

s

i

s

a

l

o

n

g

e

r

s

t

r

i

n

g

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

longer_string = 'hello, this is a longer string'

print(longer_string[7:14]) 
# slices off the section between character 7 (including) 
# and 14 (not including) 

print('\n') # just to seperate our outputs a bit

print(longer_string[:14]) 
print(longer_string[7:]) 
# if the first or second argument is neglected 
# the default value will be 0 and the end of 
# the string respectively.

print('\n')

print(longer_string[7:14:2]) # skips every second character, so prints 7, 9, 11, and 13

print(longer_string[::-1]) # prints backwards 
this is


hello, this is
this is a longer string


ti s
gnirts regnol a si siht ,olleh

Finally you can put the words into a list, an object we will discuss in the next section.

print(longer_string.split())
['hello,', 'this', 'is', 'a', 'longer', 'string']

Casting#

We can change between these classes using the int(), float(), complex(), bool(), and str() functions. This acts as expected with the Boolean casting operator changing everything to True except False, 0, 0.0, the empty string '', and None which we will discuss next.

a = 2.1
print(a)
a = int(a)
print(a)
a = float(a)
print(a)
a = complex(a)
print(a)
a = str(a)
print(a)
print(type(a))
a = bool(a)
print(a)
2.1
2
2.0
(2+0j)
(2+0j)
<class 'str'>
True

None Type#

Finally we have the null variable (denoted by None) which you might see used on occasion.

It should be noted what None is not;

  • None is not the same as False.

  • None is not 0.

  • None is not an empty string.

print(type(None))
print(None == False)
print(None == 0)
print(None == '')
print(None == None)
<class 'NoneType'>
False
False
False
True

Operator Precedence#

In this section we have discussed variables and different operations (like addition and division) that you can do with them. Often when writing code we require multiple operations to be done. We know from maths that the order of operations is important for example $\( 2 \times 5 + 3 = 13, \)\( but \)\( 2 \times (5 + 3) = 16. \)$ Here we know the order the operations are performed in is determined by the BODMAS (alternatively BIMDAS, BIRDMAS, etc.) rule. In Python operations are performed in the following order.

Operator

Description

()

Parentheses

**

Exponentation

+x, -x

positive, negative

*, /, %

multiplication, division, remainder

+, -

adition and subtraction

<, <=, >, >=, !=, ==

comparison operations

not x

Boolean NOT

and

Boolean AND

or

Boolean OR

This list is incomplete, one can find a complete one here. Consider the following examples of these rules in action

print(2 * 5 + 3) 
print(3 + 5 * 2) 
print((3 + 5) * 2) 
13
13
16
print(3 + 5 / 5) 
print(3 * 5 / 5)
print((3 + 5) / 5) 
4.0
3.0
1.6
print(False and not 6+9<10 or True)
True

In this we had

False and not 6+9<10 or True

There are not brackets, exponents, positives/negatives, multiplication, or division so the addition is done first,

False and not 15<10 or True

The comparison operator is done next giving False,

False and not False or True

The Boolean NOT is then applied,

False and True or True

Then the Boolean AND,

False or True

and finally the Boolean OR,

True