Part 1b -- Python Basic Structures (Complete)¶
Victory Laps for This Session¶
For this session we will explore
- Bloat your Python Directories with Stuff that may be Useful
- Simple Output to The Screen
- Elementary Arithmetic
- Data Elements of Basic Python
- Integers
- Floating Points
- Character Strings
- Lists (Arrays come later)
- Indexing arrays
- How indexing in Python is different from other languages
- Loops
- "Counting" through a "range"
- Walking through a list
- While Loops
- If-Elif-Else Structures (Forshadowing our next session)
Hello World¶
It’s a tradition. We do it in nearly every language we teach. Here we will use it to demonstrate how we print stuff to the string with the basic python routine “print”
Specifically let's look at the print function. Here we are only printing a string. But also notice as we play below that
- It doesn't matter (so far) if you use single or double quotes so long as you close with who opened it.
- You can separate character strings with
- a comma (which will slide in an extra breaking space), or
- a plus (which directly abutts each string against each other with no padding)
When we start playing with numbers and printing them, that will change a little.
#####################################################
#
# Hello World (Comments in Python start with a #Capital-3)
#
print('Hello World')
print('Hello' + " " + 'World')
print("Hello", 'World')
#
#####################################################
Hello World Hello World Hello World
Python Arithmetic¶
This section does not include complex math functions such as trig functions, logs, etc.
This is just going to cover the basic things found on most cheap calculators.
The basic operators are pretty intuitive if you've worked with Excel or other languages.
- (+) addition
- (-) subtraction
- (*) multiplication
- (/) division
- (%) modulus (aka the remainder from division)
- (**) raising the former to the latter's power.
- You probably were expecting a "capital-6" (^). The (**) is how it's done in Fortran.
- If you are a C-programmer and want to use the pow(x,y) function that is also available as a intrinsic (built-in) function.
The order of operations are the same as in basic arithmetic.
#####################################################
#
# The Traditional Arithmetic Operators
#
# Try these with a + instead of a comma as a
# separator
#
print(" 9 + 6 = ", 9 + 6)
print(" 9 - 6 = ", 9 - 6)
print(" 9 * 6 = ", 9 * 6)
print(" 9 / 6 = ", 9 / 6)
print(" 9 % 6 = ", 9 % 6)
print(" 9 ** 6 = ", 9 ** 6)
print(" pow(9,6) = ", pow(9,6))
#
#####################################################
9 + 6 = 15 9 - 6 = 3 9 * 6 = 54 9 / 6 = 1.5 9 % 6 = 3 9 ** 6 = 531441 pow(9,6) = 531441
A few simple intrinsic functions¶
If you tried to use a + sign to separate the string and calculation above, you got an error.
The (+) sign joins (or "concatenates") strings, the comma will join separate data "types". A plus WILL work if you convert the number into a string with the str() function (and notice the change in typesetting when you try it!):
#####################################################
#
# Comparing printing ...
#
# a number as a number separated with a comma
#
print(" 9 + 6 = ", 9 + 6)
#
# and a number as a string with both a comma
# and a plus
#
print(" 9 + 6 = " + str(9 + 6))
print(" 9 + 6 = ", str(9 + 6))
#
#####################################################
9 + 6 = 15 9 + 6 = 15 9 + 6 = 15
There are a few other onboard intrinsic functions. But for many of the math functions you may take for granted (unless you've been using Mathcad and remember what happens when you are off the campus license server!), those will be accessed with external libaries which we will cover in subsequent sessions.
Data Types¶
As with other languages there are multiple data types with which to work. Here are a few of them and how to "active" them.
Integers¶
These are the easiest. Just type it in without a decimal. Integers in Python 3 are 8-bytes long which gives them a dynamic range of (−9,223,372,036,854,775,807 to +9,223,372,036,854,775,807).
#####################################################
#
# Integers ...
#
# Plain old counting numbers
#
a = 3
b = 4
print("a = ", a)
print("b = ", b)
print()
print("a + b = ", a + b)
print("b - a = ", b - a)
print("b * a = ", b * a)
print("b / a = ", b / a) # look I just became a floating point number!
#
#####################################################
a = 3 b = 4 a + b = 7 b - a = 1 b * a = 12 b / a = 1.3333333333333333
This last one is rather nice because some languages will return a integer from an operation of two integers no matter what the results are.
If you are unclear after beating on a value if it's an integer or note you can query it's status as shown in the example below using the type() function.
#####################################################
#
# Am I an integer or floating point?
#
c = a + b
d = b - a
e = b * a
f = b / a
#
#
print(a,"+",b, "makes a ", type(c))
print(b,"-",a, "makes a ", type(d))
print(b,"*",a, "makes a ", type(e))
print(b,"/",a, "makes a ", type(f))
#
#####################################################
3 + 4 makes a <class 'int'> 4 - 3 makes a <class 'int'> 4 * 3 makes a <class 'int'> 4 / 3 makes a <class 'float'>
... and that last one brings us to
Floating Points¶
In Python 3 Floating points are 8-bytes long (what we call "double precision) should be able to go from an exponent range $10^{-308}$ to $10^{+308}$ and 15-17 significant figures.
Calling one just requires a decimal place or an "e" to create a mantisa-exponent pair like you would in excel or any other language.
Thus,
#####################################################
#
# Floating Points ...
#
x = 3.0
y = 6.0221409e+23
z = 1e308
print("x = ", x, type(x))
print("y = ", y, type(x))
print("z = ", z, type(z))
#
#####################################################
x = 3.0 <class 'float'> y = 6.0221409e+23 <class 'float'> z = 1e+308 <class 'float'>
"I will get over this because I am shallow and self-centered... You, however, are [snort] complex. You will be agonizing over this for months!"¶
Complex Numbers can be created by calculating them or by initial design. Note what while we often use i for the value of \sqrt{-1}$ they use the j (which is common when working with electrical engineers since Electrical Current is also denoted with the symbol i)
#####################################################
#
# Complex numbers...
#
imagination = (-2)**(1/2)
print("sqrt(-1) = ", imagination, type(imagination))
print(" i squared = ", 1j ** 2)
snuffolupogus = (3+4j)
print(" (3+4j) = ", snuffolupogus, type(snuffolupogus))
#
#####################################################
sqrt(-1) = (8.659560562354934e-17+1.4142135623730951j) <class 'complex'> i squared = (-1+0j) (3+4j) = (3+4j) <class 'complex'>
Characters and Strings¶
Characters and strings are easy to produce with either a pair of single-quotes or a pair of double-quotes.
#####################################################
#
# Strings and Characters
#
string1 = "Hello"
string2 = 'World'
string3 = string1 + " " + string2
#
print("string1 = ", string1, type(string1))
print("string2 = ", string2, type(string2))
print("string3 = ", string3, type(string3))
#
#####################################################
string1 = Hello <class 'str'> string2 = World <class 'str'> string3 = Hello World <class 'str'>
Lists, "Tupples" and Arrays¶
Arrays and Lists are treated differently. Arrays will be addressed in a future session on Numerical Python (NumPy).
For lists it's easy. They are 1-D lists (but not vectors) with brackets for "wrapping" and commas to delimit the members of the list.
One interesting thing about lists is that you can list heterogeneous types in them, mixing types (e.g., characters, integers, & floats) in a single list. (This won't be the case with numerical arrays)
#####################################################
#
# Lists
#
a = [0, 1, 2, 3, 4 ]
b = [0., 10., 20., 30., 40.]
c = ['zero',"one","two",'three',"four"]
d = [0, 1j, 2, 3j, 4]
e = [0, "one", 2, 3j, 4]
#
print("a = ", a, type(a))
print("b = ", b, type(b))
print("c = ", c, type(c))
print("d = ", d, type(d))
print("e = ", e, type(e))
print()
a_plus_b = a + b
print("2a = ", 2*a, type(2*a))
print("a + b = ",a_plus_b, type(a_plus_b))
#
#####################################################
a = [0, 1, 2, 3, 4] <class 'list'> b = [0.0, 10.0, 20.0, 30.0, 40.0] <class 'list'> c = ['zero', 'one', 'two', 'three', 'four'] <class 'list'> d = [0, 1j, 2, 3j, 4] <class 'list'> e = [0, 'one', 2, 3j, 4] <class 'list'> 2a = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] <class 'list'> a + b = [0, 1, 2, 3, 4, 0.0, 10.0, 20.0, 30.0, 40.0] <class 'list'>
(Whoa! Did those two do what you expected? A list is NOT an array or traditional vector or array. It operates more like a string. So in both cases (even the 2*a case which surprised me!) "adding" lists concatenate (string together) lists rather than peform math on them. We will be able to do "math" on them with numerical python
You may also sometimes see a structure that wraps a series of fields in a parenthesis.
These are called "tupples." In Python a tupple is a list that you can create or declare but while you can change the values in an array or list, you cannot do so in a "Tupple." While a function may throw me a tupple, I personally prefer not to use them, prefering the more flexible lists and arrays instead.
#####################################################
#
# Tupple Demonstration
#
mylist = ["A", "a", 1, 2, "happy"] # list
mytupple = ("A", "a", 1, 2, "happy") # tupple
print("MyList ", mylist)
print("MyTupple ", mytupple)
# Let's try to change an element in each.
# Indexing in Python starts at zero
mylist[1] = "b"
print("My New List ", mylist)
#
mytupple[1] = "b" # (this will make an error)
print("My New Tupple ", mytupple)
#
#####################################################
MyList ['A', 'a', 1, 2, 'happy'] MyTupple ('A', 'a', 1, 2, 'happy') My New List ['A', 'b', 1, 2, 'happy']
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[11], line 21 17 print("My New List ", mylist) 19 # ---> 21 mytupple[1] = "b" # (this will make an error) 22 print("My New Tupple ", mytupple) 24 # 25 ##################################################### TypeError: 'tuple' object does not support item assignment
Indexing Arrays and Lists in Python... This is going to get weird!¶
Indexing in Python starts at zero. Indicies are wrapped in brackets (not parentheses) So for example getting the above first element in list "b" is ...
#####################################################
#
print("The first element of b (element zero) is = ", b[0])
#
#####################################################
The first element of b (element zero) is = 0.0
#####################################################
#
print("The second element of b (element 1) is = ", b[1])
#
#####################################################
The second element of b (element 1) is = 10.0
That's straight forward enough. But what if you want to print a range of elements. Let's say the first 3 elements (0, 1 & 2). To fetch more than one you can use the : to create the range - this is similar to other languages.
#####################################################
#
print("The first three elements of b SHOULD be... ", b[0:2])
#
#####################################################
The first three elements of b SHOULD be... [0.0, 10.0]
Whoa (again). This is a quirk of Python that isn't in other languages.
The first listed index in a range is "inclusive" meaning that the first index you ask for is the first you get! (As it should be yes?)
BUT... (and there's always a "but" isn't there?)
The second listed index in a given range is "EXCLUSIVE." That means that it is one PLUS the listed index. So if we want to do the above example and do the first three, it must look like the one below.
#####################################################
#
print("The first three elements of b are *really*... ", b[0:2+1])
print(" or ", b[0:3])
#
#####################################################
The first three elements of b are *really*... [0.0, 10.0, 20.0] or [0.0, 10.0, 20.0]
And who came up with that winning idea?!?¶
I've seen a lot of apologetics for this. The best lest-unconvincing one to me is to accomodate how we think when we count vs how things indexing at zero work:
"index from 0 for the 3 spaces."
I'm still not convinced in part because I've spent years decades explicitly saying 0 to N-1.
Creating Ranges in Python¶
This comes in handy to remember when you work shortly in loops or otherwise have to make a series of numbers to walk through in Python.
The function to do this is called "[range(start,stop+1,[delta])]"(https://docs.python.org/3/library/functions.html#func-range)
if your interval is one then you don't need that last argument.
An example of this making a counting list from 1 to 10 is below. However the data class in which a range is stored is accessed normally only through a loop (which we will need to do next).
#####################################################
#
# Range from 1 to 10
#
range1 = range(1, 10+1)
print("", range1)
for i in range1:
print(i)
#
#####################################################
range(1, 11) 1 2 3 4 5 6 7 8 9 10
Loops¶
And that is a good segue into loops.
There two species of loops
Counting Loops (The For Loop)¶
Counting Loops leverage Ranges which as we saw above have that inclusive exclusive pairing.
And we just did one...
A few things.
- The Loops and If-Elif-Else Blocks start with : at the starter line.
- You must then indent (Jupyter will do it for you).
- When done with the indent the "cue" that you are out of the structure is simply returning to the previous indent level (or hard against the left margin). You'll see a nested system shortly.
#####################################################
#
# Range from 1 to 10
#
N = 5
for i in range(1, N+1):
print("i = ", i, "out of ", N)
print()
for k in range(0, N+1):
print("k = ", k, "out of ", N)
#
#####################################################
i = 1 out of 5 i = 2 out of 5 i = 3 out of 5 i = 4 out of 5 i = 5 out of 5 k = 0 out of 5 k = 1 out of 5 k = 2 out of 5 k = 3 out of 5 k = 4 out of 5 k = 5 out of 5
It also works with lists
#####################################################
#
# For Looping through a List
#
# notice that continuation is just starting a new
# line like you can do in R
#
mousekateeers = ["Sharon",
"Bobby",
"Lonnie",
"Tommy",
"Annette",
"Darlene",
"Cubby",
"Karen",
"Doreen"]
print("Roll Call!")
for mousekateer in mousekateeers:
print(" " + mousekateer + "!")
#
#####################################################
Roll Call! Sharon! Bobby! Lonnie! Tommy! Annette! Darlene! Cubby! Karen! Doreen!
Conditional Loops (The While Loop)¶
This one drops out when the condition is satisfied (this is what we used when we programmed Roots in Mathcad)
And let's do a revisit to our first foray into programming!
#####################################################
#
# While Loop (using our first loop EVER!)
#
i = 2
while (i <= 6):
print("i+1=", i+1)
i = i + 2
print("We're Outahere like Vladimir")
#
#####################################################
i+1= 3 i+1= 5 i+1= 7 We're Outahere like Vladimir
Decision Blocks¶
We often have choices to make when we program... here are the classics that come with Python. Note that if you are used to using a "case" statement which exists in a number of languages, it's not explicitly included with Python.
A Cascading If-ElseIf-Else Block¶
This one is a redux of the vending machine problem from Lecture 2. Remember if you know you have a dime, you don't have to ask again if it's a nickel.
Here Else If is compressed into a single word, "elif."
#####################################################
#
# If-Elif-Else Block
#
coin = "Nickel"
if (coin == "Quarter"):
value = 0.25
elif (coin == "Dime"):
value = 0.10
elif (coin == "Nickel"):
value = 0.05
elif (coin == "Penny"):
value = 0.01
else:
value = "Use the right money"
print("value = ", value)
#
#####################################################
value = 0.05
Single Question If Statements¶
This one is easy... Remember after any of these questions you still have to ask the next questions
#####################################################
#
# Singular If Statement
#
# (also showing multiple conditions)
#
value = 0.05
if (value >= 0) & (value <= 0.10):
print(value, "is between 0.00 and 0.10")
if (value >= 0.10) & (value <= 0.50):
print(value, "is between 0.10 and 0.50")
if (value >= 0.00) & (value < 1.00):
print(value, "is under 1.00")
if (value < 0.50) | (value > 1.00):
print(value, "is less than 0.50 or more than 1.00")
#
#####################################################
0.05 is between 0.00 and 0.10 0.05 is under 1.00 0.05 is less than 0.50 or more than 1.00
Setup for Next Week's Playtime!¶
There are a couple things you can try with the skills you have now. But this one we can use later when we plot things!
Our Pi Case.¶
You've done this before... you can do it here.
Recall that we are using a Reimann Sum method to do this.
Remember the base equation
$$\pi =\frac{1}{N}\sum^{N}_{i=1}\frac{4}{1+x^2}$$
And the pseudocode.
Just enter the block below by declaring a variable n.
Input the value “n”
if n < 1 then
{
print an error statement
}
else
{
h = 1 / n
sum = 0
repeat i from 1 to n by 1
{
x = h * (i - 0.5)
sum = sum + 4 / (1 + x*x)
}
pi = h * sum
return, pi
}
Version Information¶
There was once a very handy tool that would print version information of the Python version, operating system, and the versions of the Python packages you are running. It leveraged a "magic" command in IPython (which is what lies beneath Jupyter and JuptyerLab notebooks).
The developer has moved on to other things, but the resource still has a narrow but ~militant~ ernest fan base (myself included). The original doesn't work with versions of Python above 3.7. So, a couple of us wrote some patches to fix it. You can access my version below by following these instructions.
- If you don't have GIT on your rig yet, you can fetch it via conda (you can do this on the fly in the jupyter notebook by using that leading "!"
!conda install -y -v git
- You can install it using the following command.
!pip install git+https://github.com/wjcapehart/version_information
JupyterLab Caveat¶
For people using Jupyter Lab, the interface does not play well with this "magic" function. It exports the results in the Jupyter Lab notebook as a JSON object with clicky expander arrow buttons. However, if you "Export" your notebook as an HTML or PDF file, it will look like a nice table.
################################################################
#
# Loading Version Information
#
%load_ext version_information
%version_information version_information
#
################################################################
Software | Version |
---|---|
Python | 3.11.4 64bit [Clang 15.0.7 ] |
IPython | 8.14.0 |
OS | macOS 13.5.1 arm64 arm 64bit |
version_information | 1.0.3 |
Tue Sep 05 12:12:49 2023 MDT |