01b - Python Basics#

Here are a few basic principles in Python (really any programming language):

Assignment operator vs. equality operator#

The assignment operator is =. The equality operator is ==. So setting a value of 5 to a variable x is done with x = 5. Checking if x is equal to 5 is done with x == 5. Below is example code:

x=5 #set x equal to 5, variable to be assigned is on the left.
print(f'The value of x is {x} and the result of x==5 is {x==5}')
The value of x is 5 and the result of x==5 is True

Data Types#

There are several data types in Python. The most common are int, float, str, bool, and NoneType. int is an integer, float is a decimal number potentially, str is a string like ‘a’ or ‘hello’, bool is True or False, and NoneType is an empty value. The type function can be used to determine the type of a variable. Below is example code:

a = int(7.5); b = 7.97; c = 'Hello World'; d = True; e = None
print(f'a is {a}, b is {b}, c is {c}, d is {d}, e is {e}')
a is 7, b is 7.97, c is Hello World, d is True, e is None

Other common data types are given below

Tuple#

What’s a tuple? How is it different from a list? A tuple is a sequence of immutable Python objects. Tuples are sequences, just like lists. The differences between tuples and lists are, the tuples cannot be changed (immutable) unlike lists and tuples use parenthesis (althouth not required), whereas lists use square brackets.

tup = (4,5) #set a variable name tup to a tuple
tup = tup + (6,) # add another value to the tuple
anothertup = 7,8 #create a tuple without parentheses
print(f'The value of tup is {tup} and tup[0] is {tup[0]}')
print(f'The value of anothertup is {anothertup} and the type of anothertup is {type(anothertup)}')
#now we'll try and change the value of tup[0]
tup = (3,4) #reassign the variable to a different tuple
print(tup)
The value of tup is (4, 5, 6) and tup[0] is 4
The value of anothertup is (7, 8) and the type of anothertup is <class 'tuple'>
(3, 4)

Note that the variable ‘tup’ can be reassigned to a different tuple but that once a tuple has been set, it cannot be changed. This is different from a list which can be changed (as it’s immutable). For example:

tup[0] = 4 #try and reassign the first element of the tuple to 4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 tup[0] = 4 #try and reassign the first element of the tuple to 4

TypeError: 'tuple' object does not support item assignment

Tuples can be useful as in this example where we want to pass multiple values to a function.

from scipy.optimize import fsolve
def equations(p):
    L,V = p
    return (100 - (L+V), 0.4*100-0.1*L-0.8*V) #each equation is set so that it is equal to zero, also the returned value is also a tuple

L,V =  fsolve(equations, (1,1))
print(f'The solution is {L:0.2f} for L and {V:0.2f} for V')
print(type((L,V)),type((1,1)))
The solution is 57.14 for L and 42.86 for V
<class 'tuple'> <class 'tuple'>

Lists and Arrays#

Lists and arrays are similar in that they are both a series of values. However, lists can contain different types of values. Arrays are typically all the same type of value. Arrays are also more efficient to use for calculations.

#Here's a list of numbers
numbers = [1,2,3,4,5,6,7,8,9,10]
print(f'The numbers are {numbers} and the type is {type(numbers)}')
The numbers are [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and the type is <class 'list'>
#Here is a list that has different items in it
blist = ['hello',3,5,numbers,3.14]
print(blist)
['hello', 3, 5, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3.14]
#Heres how to access the third item in the list
print(blist[2]) #remember that python is zero indexed
5
#Here are two ways to access the last item in the list
print(blist[-1]) #index -1 is the last item in the list
print(blist[len(blist)-1]) #len(blist) is the length of the list
3.14
3.14
#an array is useful and different than a list as it is considered a vector
#a list can easily be converted to an array
import numpy as np
arr = np.array(numbers)
print(f'The array is {arr} and the type is {type(arr)}')
The array is [ 1  2  3  4  5  6  7  8  9 10] and the type is <class 'numpy.ndarray'>

Some python operations can be done on a list but other operations cannot and are better done with an array. For example:

import numpy as np
x = [1,2,3]
y = [4,5,6]
print(x + y)
#versus
print(np.array(x) + np.array(y))
[1, 2, 3, 4, 5, 6]
[5 7 9]

Dictionaries#

Dictionary is a collection of key:value pairs. It is similar to a list, but you can access the values by the key instead of the index. Here is an example:

adictionary = {'a':1,'b':2,'c':3} #create a dictionary
print(adictionary['a']) #access the value associated with the key 'a'
#or 
print(adictionary.get('a')) #access the value associated with the key 'a'
1
1

Dictionaries can be very helpful when you have data and you want to access it by a key. For example, if you have a list of students and you want to access their grades, you can use a dictionary with the student name as the key and the grade as the value. A dictionary can also be thought of as a database. They can easily be converted to a pandas dataframe.

Loops#

For and while loops are powerful to complete repetitive tasks. Here are some examples:

a = [] #create an empty list
for i in range(5): #a simple loop
    a.append(i**2) #append the square of i to the list
print(a)
[0, 1, 4, 9, 16]
# a simple while loop
while len(a) < 10:
    a.append(0) #append 0 to the list until the length of the list is 10
print(a)
[0, 1, 4, 9, 16, 0, 0, 0, 0, 0]

Inline loop to generate a list#

anotherlist = [each*2 for each in a] #an inline for loop
print(anotherlist)
[0, 2, 8, 18, 32, 0, 0, 0, 0, 0]

Conditionals#

Conditionals are used to make decisions in code. Most often that is done with an if statement. The if statement checks a condition and then runs the code if the condition is true (or doesn’t run the code if the condition is false). Here is an example:

x = 4
if x == 5:
    print(f'x is 5')
elif x == 4:
    print(f'x is 4')
else:
    print(f'x is not 4 or 5, x is {x}')
x is 4

Objects#

What’s an object? An object is similar to a variable in that it holds a value or series of values called properties. It can also have functions associated with it. For example, a list is an object and it has functions associated with it like append and sort. You will use objects all the time when you’re using Python. Objects are defined by a class operator.

#a list is an object (or instance) of its class
print(type(alist))
alist.append(6) #the append method is a function in the list class to append an element to the list
print(alist[-1]) #access the last element of the list
<class 'list'>
6

I can also make my own objects by defining a class. For example, I can make a class called Person and give it properties like name and age. I can also give it functions like birthday and greet. Here is an example:

class person():
    def __init__(self,name,age): #the __init__ method is called when the class is instantiated
        self.name = name #self refers to the instance of the class
        self.age = age
joe = person('Joe Bai',25) #create an object (an instance)  of the person class
print(f'Hello, my name is {joe.name} and I\'m {joe.age}.') #access the name attribute of the joe object
Hello, my name is Joe Bai and I'm 25.

I recommend using the param package to define objects. It’s has many benefits.

import param
class gas(param.Parameterized):
    Mw = param.Number(0.02897, bounds=(0,None), doc='Molecular weight of the gas, kg/mol')
    Rg = param.Number(8.314, bounds=(0,None), doc='Gas constant, J/mol/K',constant=True)
    T = param.Number(300, bounds=(0,None), doc='Temperature of the gas, K')
    P = param.Number(101325, bounds=(0,None), doc='Pressure of the gas, Pa')
    def density(self):
        return self.Mw*self.P/(self.Rg*self.T) #density in kg/m^3

air = gas(Mw=28.97,T=300)
print(f'The density of air at {air.T} K and {air.P} Pa is {air.density():0.2f} kg/m^3')
The density of air at 300 K and 101325 Pa is 1176.88 kg/m^3
#Here's a benefit of the param library, I can get the doc's on each parameter
print(air.param.Mw.doc)
help(air.param.Mw)
Molecular weight of the gas, kg/mol
Help on Number in module param:

    Molecular weight of the gas, kg/mol

Bits#

Bits are collections of 1s and 0s (or on versus off in a transistor). They are the basis of all computer operations.

# '101' is 
print(f'001 is 2^2*1 + 2^1*0 + 2^0*1 = {2**2*1 + 2**1*0 + 2**0*1}')
#or
print(int('101',2))
001 is 2^2*1 + 2^1*0 + 2^0*1 = 5
5
bin(5) #convert 5 to binary
'0b101'

Below is a code snippet to calculate the number of bits required to represent a number.

# This calculates the number of bits a variable holds
def bits(n):
    return len(bin(n))-2 #bin(n) returns the binary representation of n as a string
print(bits(255))
8