# Lecture 1: Introduction to Python 3.6 and Jupyter Notebook
By Dr. Anders S. Christensen
`anders.christensen @ unibas.ch`



Today we go through the basics of Python3 and also how to use Jupyter Notebooks (via Google Colab).

Try to run the code block below by clicking the play-button (or pressing Ctrl+Enter).



```
print("Hello Python!")
```

## Section 1.1: Basic math operations




```
print(7 + 17)
```


```
print(7 * 17)
```


```
print(7 - 17)
```


```
print(7 / 17)
```


```
print(7**17)
```

### Exercise 1.1.1: Write your own example here:


```

```

## Section 1.2: Variables and naming


```
x = 7
y = 17.0

z = x * y

print(z)
```

Strings can also be variables:


```
greeting = "Hello World!"

print(greeting)
```

Different data types?


```
x = 1
print(type(x))
```


```
y = 5.0
print(type(y))
```


```
w = x * y
print(type(w))
```

Some variables don't mix:


```
x = "Hello"
y = 42

z = x + y

print("z is", z)
```

Variable names can be really long! Normally we use lower-case and _ in our variables in Python


```
lecturer_name = "Anders Christensen"
students_asleep = 0
days_until_xmas = 200.5
```

Some examples of legal and illegal names:


```
#Legal variable names:
myvar = "John"
my_var = "John"
_my_var = "John"
myVar = "John"
MYVAR = "John"
myvar2 = "John"
```

### Exercise 1.2.1:
The following will not work. Lets fix them!


```
# Illegal variable names:
myvar2 = "John"
my-var = "John"
my var = "John"
```

## Section 1.3: ```for```-loops

We have seen how to write variables and do simple calculations, but often we want to do more than just *one* thing!

In order to do a series of things, we can use the so-called `for`-loop, which is often invoked using the `range()` funtions.

`range(n)` will give you all the numbers from $0$ to $n-1$ 

(Because Python counting starts from $0$)

For example:


```
# Print all numbers from 0 to 19
for i in range(20):
  print(i)

print("Does this get repeated?")
```

Note how everything that is indented gets repeated by the `for` loop!

**Question:** What is `range()`??


```
# Convert the range to a list
print( list(range(10)) )
```

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


Note how `range()` "skips" the final number!

---

Normally `range()` starts from 0, but you can start from any number, by using *two* arguments, for example:


```
# Print from 10 to 19
print( list(range(10, 20)) )
```

    [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]


We can for example use the loop to calculate a sum:
\begin{equation}
k = \sum_{n=0}^{19} i
\end{equation}


```
k = 0
for i in range(20):
  # print(i)
  k = k + i

print("k is", k)
```

### Section 1.4: Lists 
A fundamental data structure of Python is so-called "lists". A list contains a list of items, for example numbers. 

An example of a list with 7 items is given below:

\begin{array}{lrrrrrrr}
\texttt{i}  & 0  & 1 & 2 & 3 & 4 & 5 & 6 \\ \hline
\texttt{my_list} & 3.5 & 2.1 & -2.5 & 1.2 & 6.2 & 5.2 & -8.1
\end{array}

In Python this would be:


```
 my_list = [3.5, 2.1, -2.5, 1.2, 6.2, 5.2, -8.1]
 print(my_list)
```

Note: The first item in the list has index $0$, and the last has index $n-1$. You count starting from 0, and NOT 1! 

For example:


```
# The first item in the list
print(my_list[0])

# The "third" item in the list
print(my_list[2])

# The last item in the list
print(my_list[6])
```


```
# List contatining some numbers
some_numbers = [5, 10, 15, 20, 25, 30]

# print length of that list
print(len(some_numbers))
```


```
# Example 1: Print some_numbers
for i in range(len(some_numbers)):
  print(some_numbers[i])
```


```
# Example 2: Print some_numbers
for n in some_numbers:
  print(n)
```

### Debugging Exercise 1.4.1: What happens if you ask for something that isn't there?


```
my_list = [3.5, 2.1, -2.5, 1.2, 6.2, 5.2, -8.1]

# Only up to 6 allowed!
print(my_list[7])

```

### Section 1.5: Sum over items in list:

This is an example of summation:

\begin{equation}
y = \sum_{i=0}^n x_i
\end{equation}


```
my_sum = 0

for i in range(7):

  print(i, my_list[i])
  my_sum = my_sum + my_list[i]

print("my_sum is", my_sum)
```

## Coding Example: The Quantum Harmonic Oscillator

The behavior of a di-atomic molecule can be approximated by a quantum harmonic oscillator.

In this example we calculate the internal energy, $U$, and the heat capacity $C_v$ of a quantum harmonic oscillator.





The energy $\epsilon_n$ for a state of the harmonic oscillator is given by
\begin{equation}
\epsilon_n = n+\frac{1}{2},
\end{equation}
in units of $\hbar\omega$. We also assume that there are no degenerate states!

The probability for observing the state $n$ at a given temperature $\tau$ is given by:
\begin{equation}
p(n) = \frac{\exp{\left(-\epsilon_n / \tau \right)}}{Z},
\end{equation}

where $Z$ is the partition function (*Zustandssumme*)
\begin{equation}
Z = \sum_{n=0}^{\infty} \exp{\left(-\epsilon_n / \tau\right)}.
\end{equation}

The total *internal* energy $U$ is then given by:
\begin{equation}
U = \langle \epsilon \rangle = \sum_n \epsilon_n p(n)
\end{equation}

---

Another interesting property of this system is the *heat capactity* $C_V$ given by
\begin{align}
C_V &= \frac{\partial U}{\partial \tau} \biggl|_V \\
&= \frac{\langle \epsilon^2 \rangle - \langle \epsilon \rangle^2}{\tau^2}.
\end{align}


The expectation value $\langle \epsilon \rangle$ is given via the energy $U$:
\begin{align}
\langle \epsilon \rangle &= \sum_n \epsilon_n p(n) \\
&= \sum_n \left(n+\frac{1}{2}\right) p(n)
\end{align}

And $\langle \epsilon^2 \rangle$ is the second moment of the energy given by:
\begin{align}
\langle \epsilon^2 \rangle &= \sum_n \epsilon^2_n p(n) \\
&= \sum_n \left(n+\frac{1}{2}\right)^2 p(n)
\end{align}


### Example 1: Print the energy $\epsilon_n$ for each state up to $n=3$?

The energy $\epsilon_n$ for a state of the harmonic oscillator is given by:
\begin{equation}
\epsilon_n = n+\frac{1}{2}
\end{equation}


```
for n in range(3+1):

  epsilon = n + 0.5

  print(n, epsilon)
```

#### Example 2: What is the partition function $Z$ 

for $\tau$ = 2.0?

Recall that the partition function is given by:

\begin{equation}
Z = \sum_{n=0}^{\infty} \exp{\left(-\frac{\left(n+\frac{1}{2}\right)}{\tau}\right)}
\end{equation}


Before we start, we have to import the function to evaluate the exponential function from a package called NumPy.


```
# Import functionality for exponential function: np.exp()
import numpy as np

# np.exp() = "e^x"

print(np.exp(0.0))
print(np.exp(1.0))
```


```
tau = 2.0
n_states = 10000

Z = 0.0

for n in range(n_states+1):
  
  Z = Z + np.exp(-(n + 0.5) / tau)

print(Z)
```

#### Example 3: What is the internal energy $U$ for $\tau$ = 2.0?

\begin{equation}
U = \langle \epsilon \rangle = \sum_n \epsilon_n p(n)
\end{equation}

Also recall that:

\begin{equation}
p(n) = \frac{\exp{\left(-\epsilon_n / \tau \right)}}{Z},
\end{equation}


```
U = 0

for n in range(n_states+1):
  
  epsilon = n + 0.5
  prob = np.exp(-epsilon/tau) / Z
  
  U = U + epsilon * prob
  
  # print(n, epsilon, prob)

print("Internal energy:", U)
```

#### Example 4: Second moment of the energy and the heat capacity


What is the heat capacity $C_V$ for $\tau = 2.0$?
\begin{equation}
C_V = \frac{\langle \epsilon^2 \rangle - \langle \epsilon \rangle^2}{\tau^2}.
\end{equation}

With the second moment of the energy:
\begin{equation}
\langle \epsilon^2 \rangle = \sum_n \left(n+\frac{1}{2}\right)^2 p(n)
\end{equation}



```
# Second moment of the energy:

U2 = 0

for n in range(n_states+1):
  
  epsilon = n + 0.5
  prob = np.exp(-epsilon/tau) / Z
  
  U2 = U2 + epsilon**2 * prob
  
  # print(n, epsilon, prob)

print("Second moment of the energy:", U2)
```

Finally, the heat capacity is:


```
Cv = (U2 - U**2) / tau**2

print("Heat capacity:", Cv)
```

## Extra: Calculating $C_V$ as a function of $\tau$


```
# 7 temperatures
temperatures = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
n_states = 10

for tau in temperatures:

  # Calculate the partition function for tau
  Z = 0.0
  for n in range(n_states+1):
    Z = Z + np.exp(-(n + 0.5) / tau)

  # First moment of the energy
  U = 0.0

  # Second moment of the energy
  U2 = 0.0

  for n in range(n_states+1):
  
    epsilon = n + 0.5
    prob = np.exp(-epsilon/tau) / Z
  
    U = U + epsilon * prob
    U2 = U2 + epsilon**2 * prob
  
  Cv = (U2 - U**2) / tau

  print(tau, Cv)
```

d580401844a8a3e47826fbf5d6ae359ad7676181
ipynb
Jupyter Notebook
intro_lecture1_2020.ipynb
andersx/python-intro
8409c89da7dd9cea21e3702a0f0f47aae816eb58
CC0-1.0
2020-05-03T11:59:01.000Z
2021-11-15T12:33:39.000Z
intro_lecture1_2020.ipynb
andersx/python-intro
8409c89da7dd9cea21e3702a0f0f47aae816eb58
CC0-1.0
intro_lecture1_2020.ipynb
andersx/python-intro
8409c89da7dd9cea21e3702a0f0f47aae816eb58
CC0-1.0
2020-05-10T21:15:15.000Z
2021-12-05T15:13:54.000Z
Qwen/Qwen-72B
1. YES
2. YES