M0: Introduction to Python#

Build your conda environment#

Before you run any code, you should install all the necessary packages in a conda environment

Necessary packages:

Use the terminal application for the commands below. Everytime you open the terminal the first step is to activate your environment pchem where you are installing all your software by typing: “conda activate pchem”

conda install python=3.12
pip install pyscf
pip install geometric
conda install -c conda-forge matplotlib
conda install -c conda-forge notebook

Additional packages

conda install sympy

conda install -c conda-forge ipywidgets
conda install -c plotly plotly

conda install pandas
conda install -c conda-forge py3dmol

The prefered way to edit and interact with all the class material is by using Visual Studio Code (https://code.visualstudio.com/). It is free of charge but propietary. Alternatively, anyone can also use the jupyter-notebook installed above. In this latter case, in the terminal, type jupyter-notebook (in Mac) or jupyter notebook (in Windows). A new tab in your browser should appear. Learn to navigate through files using jupyter notebook.

Types of variables 1: integers, floats, and strings#

Integers, floats, and strings#

#the variable "a" is an integer
a=23
#the variable "b" is a float
b=23.0
#the variable "c" is a string
c="23"

Operations with integers, floats, and strings#

#the operation between integers and floats give floats
print(a+b)
#one can convert integers into floats and viceversa
print( float(a) )
print( int(b))
46.0
23.0
23
#typical operations are +, -, *, /
print(a*b)
# for more sophisticated operations we will use the "math" module or "numpy"
#strings and numbers (int or floats)
print(c+a)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [7], in <cell line: 2>()
      1 #strings and numbers (int or floats)
----> 2 print(c+a)

TypeError: can only concatenate str (not "int") to str
#but if a string has numbers it can be converted into a number
print(float(c)+a)
46.0
#Two strings can be joined or concatenated with +
e='this is a'
f=' variable'
print(' ** ', f)
print(' ** ',e)
print(e+f)
print(e+' string'+f)
 **   variable
 **  this is a
this is a variable
this is a string variable

Using modules or libraries#

import math

print(math.sin(a))
print(math.exp(a))
print(math.pi / math.exp(0))
-0.8462204041751706
9744803446.248903
3.141592653589793

Types of variables 2: lists and dictionaries#

#a list is indicated with the square bracket. A list can contain integers, floats, strings or more lists.

#a list of integers
g = [-23,6,-34,7]

#access the elements of the list with brackets starting to count at zero
print(g[0],g[3])

#you can also print a range using ':'
h=['a','b','c','d','e']
print(h[2:4])
-23 7
['c', 'd']
#create a slit with the function 'split'
i='This is a long string made out of words that it is about to be split'.split()
print(i)
#print first and last
print(i[0],i[-1],i[-2])

#using len you can see how many elements the list has
print( len(i))
['This', 'is', 'a', 'long', 'string', 'made', 'out', 'of', 'words', 'that', 'it', 'is', 'about', 'to', 'be', 'split']
This split be
16
#a dictionary uses curled brackets and instead of 

j={1:'this is number one',
  'a':'this is the letter a',
  '2':'this is a string'}

print(j[1])
print(j['2'])
this is number one
this is a string

Main structures: Loops#

#looping through a list

myLoop = [2,3,4,5,6]
for thisThing in myLoop:
    print(thisThing*2)
4
6
8
10
12
#using range for a range of numbers
for this in range(10):
    print(this)
0
1
2
3
4
5
6
7
8
9
#Looping through a string
thisString = 'abcdefghijkl'
for z in thisString:
    print(z)
for z in thisString[2:5]:
    print("This is element",z)
a
b
c
d
e
f
g
h
i
j
k
l
This is element c
This is element d
This is element e

Main structures: Conditionals#

a=4
if a < 10:
    print(a,"is smaller than 10")
else:
    print(a,"is larger than 10")
a=40
if a < 10:
    print(a,"is smaller than 10")
else:
    print(a,"is larger than 10")
4 is smaller than 10
40 is larger than 10

Combining loops and conditionals#

gettys='Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal'

for word in gettys.split():
    if 'r' in word:
        print('This word contains the letter r:',word)
This word contains the letter r: Four
This word contains the letter r: score
This word contains the letter r: years
This word contains the letter r: our
This word contains the letter r: fathers
This word contains the letter r: brought
This word contains the letter r: forth
This word contains the letter r: Liberty,
This word contains the letter r: proposition
This word contains the letter r: are
This word contains the letter r: created

Plotting#

import matplotlib.pyplot as plt

x=[1,2,3,4,5]
y=[-10,-20,30,40,-50]
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x115325910>]
_images/f3f20f84b801f0bd78724202799d220323b209bf92fdda7ac3e68f013894567f.png
plt.scatter(x,y,label='this label')
plt.xlabel("Title for the x axis")
plt.ylabel("Title for the y axis")
plt.legend(loc='upper left')
plt.title("Main title")
plt.show();
_images/b2fd06812c45ca62f42c8958630f6604986e5e97291f22a35a612c8093a8def9.png

More plotting options with matplotlib#

fig = plt.figure(figsize=(15,10))


ax1 = plt.subplot(121) #121 means: the subplots will be 1 row 2 columns and this one is subplot number 1
ax2 = plt.subplot(122, sharey = ax1) #share-y means that it will share the y-axis with the ax1 plot
#for 3x3 plot matrix you would have written subplot(331) 332 333 334...

y2 = [n*2 for n in y]
y3 = [n*3 for n in y]
print(y2)
ax1.plot(x,y2,'-o')
ax2.plot(x,y3,'--');
[-20, -40, 60, 80, -100]
_images/38a0ae8c5dcd334a17022db6f3d4192345f2afa1f5a9398a17469e6a01f7bcbc.png
fig = plt.figure(figsize=(15,10))

ax1 = plt.subplot(131) #121 means: the subplots will be 1 row 2 columns and this one is subplot number 1
ax2 = plt.subplot(132, sharey = ax1) #share-y means that it will share the y-axis with the ax1 plot
ax3 = plt.subplot(133, sharey = ax1) 

for n in range(10):
    ax1.axhline(y=n*2,xmin=-2., xmax=2., c='green')
for n in range(10):
    ax2.axhline(y=n*0.5,xmin=0., xmax=2., c='blue')
for n in range(10):
    ax3.axhline(y=n*0.3,xmin=0., xmax=2., c='red')
_images/2c0f625ba97d0aa1c67757f822b03703c271fe002bbfecb81830ae8d78dcc57d.png
y = [1]*(len(y2)) # this is the height of the signal. It doesnt matter, just height = 1
fig, ax = plt.subplots()
ax.stem(y2, y, markerfmt=' ',linefmt="red")
ax.set_xlabel("Energy of the transition")
ax.set_ylabel("Absorbance")
ax.set_title("Absorption");
_images/140180dc67281a905047c2bdada74a9ac767901cddc4548c9078470ddc8ad281.png
import matplotlib.pyplot as plt
import numpy as np

x = np.random.normal(170, 10, 250)

plt.hist(x)
plt.show() 
_images/e056a911c55c8fc5bf0f4afc206c46f6978d675248911f5aef0c90816248e51f.png