4. Python Basics#
Last Revised September 26, 2022
4.1. Using Python interactively#
For some tasks, Python can be used interactively, much like a scientific calculator (and later, like a graphing scientific calculator) and that is how we will work for this section.
There are multiple ways of doing this, and I invite you to experiment with them all at some stage:
With the “bare” IPython console; this is available in many ways, including from the Anaconda Navigator by opening Qt Console
With Spyder, which can be accessed from within the Anaconda Navigator by opening Spyder; within that, there is an interactive Python console frame at bottom-right.
In Jupyter notebooks (like this one), which can be accessed from within the Anaconda Navigator by opening JupyterLab.
I suggest learning one tool at a time, starting with this Jupyter notebook; however if you wish to also one of both of the alternatives above, go ahead.
4.2. Running some or all cells in a notebook#
A Jupyter notebook consists of a sequence of cells, and there are two types that we care about:
Code cells, which contain Python code
Markdown cells (like all the ones so far), which contain text and mathematics, using the Markdown markup notation for text combined with LaTeX markup notation for mathematical formulas.
Running a Code cell executes its Python code; running a Markdown cell formats its content for nicer output.
There are several ways to run a cell:
The “Play” (triangle icon) button above
Typing “Shift-Return” (or “Shift-Enter”)
Both of these run the current cell and then move down to the next cell as “current”.
Also, the menu “Run” above has various options — hopefully self-explanatory, at least after some experimentation.
To get a Markdown cell back from nicely formatted “display mode” back to “edit mode”, double click in it.
It will be convenient to see the value of an expression by simply making it the last line of a cell.
2 + 2
4
To see several values from a cell, put them on that last line, separated by commas; the results will appear also separated by commas, and in parentheses:
2 + 2, 6 - 1
(4, 5)
(As we will see in the next section, these are tuples
; a very convenient way of grouping information.)
4.3. Numbers and basic arithmetic#
Python, like most programming languages distinguishes integers from floating point (“real”) numbers; even “1.0” is different from ‘1’, the decimal point showing that the former is a floating point number.
One difference is that there is a maximum possible floating point number of about \(10^{300}\), whereas Python integers can be arbitrarily large — see below with exponentiation.
Addition and subtraction with “+” and “-” are obvious, as seen above.
2 + 2, 6 - 2
(4, 4)
However, there are a few points to note with multiplication, exponentiation, and division.
4.3.1. Multiplication and exponentiation#
Firstly, the usual multiplication sign not in the standard character setor on standard keyboards, so an asterisk “*” is used instead:
2 * 3
6
Likewise exponentiation needs a special “keyboard-friendly” notation, and it is a dobuble asterisk “**” (not “^”):
2**3
8
Numbers with exponents can be expressed using this exponential notation, but note how Python outputs them:
5.3*10**21
5.3e+21
7*10**-8
7e-08
This “e” notation is the standard way to describe numbers with exponents, and you can input them that way too.
When printing numbers, Python decides if the number is big enough or small enough to be worth printing with an exponent:
2e-10, 3E-5, 3e-4, 5e+4, 10000000000, 6e15, 6e16
(2e-10, 3e-05, 0.0003, 50000.0, 10000000000, 6000000000000000.0, 6e+16)
Aside: note that either “e” or “E” can be used in input of exponents. However in most contexts, Python is case sensitive; we will see an example soon.
4.3.2. Division#
Division is normaly denoted by “/”
6/3
2.0
5/3
1.6666666666666667
but there are a few things to note with integers.
Firstly as you see above, diving two integers always given a floating point number result, not an integer: note the decimal point in “2.0”.
To do integer division, use “//”
6//3
2
5//3
1
and to get the remainder, use “%”
6%3
0
5%3
2
4.3.3. Complex numbers#
Python uses j
for the square root of -1 rather than i
, and complex numbers are writen as a + bj
or just bj
for purely imaginary numbers. (Here ‘a’ and ‘b mut be literal numbers, nt mnakem of variables.)
The coeffcient b
in the imaginary part is always needed, even if it is 1.
2 + 2j, (2+2j)**2, 1j, 1j**2
((2+2j), 8j, 1j, (-1+0j))
but
j
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [16], in <cell line: 1>()
----> 1 j
NameError: name 'j' is not defined
4.4. Boolean values (True-False)#
These are True
and False
, capitalized.
Many other options are allowed, like using 0
for False
and 1
for True
, but for the sake of redability, I discourage that.
The basic logical operations are done wth the usual English words: “and”, “or” and “not”
True and True, True and False, False and False
(True, False, False)
True or True, True or False, False or False
(True, True, False)
Both “and” and “or” are use lazy or “short-circuiting” evaluation:
if the T/F at left determines the overall truth value answer (it is False
with and
, True
with or
) then the term at right is not evaluated.
For example, the following avoids division by zero (the syntax will be explained later, but hopefuly it is mostly clear.)
if q != 0 and -1 < p/q < 1:
print(f"{p}/{q} is a proper fraction")
else:
print(f"{p}/{q} is not a proper fraction")
4.5. Comparisons#
Comparisons of numbers and tests for equality exist, with two catches:
There are no keyboard symbols for \(\leq\), \(\geq\) or \(\neq\), so
<=
,>=
and!=
are usedEquality is indicated with a double equals sign
==
because a single equals sign has another job, as seen below under Naming quantities, and displaying information with print.
So in all:
< <= == != >= >
One convenient difference from most programming languages is that comparisons can be chained, as seen in the example above:
-1 < p/q < 1
is equivalant to
-1 < p/q and p/q < 1
but is both more readable and more efficient, because the middle term is only evaluated once.
Like and
and or
, this is short-circuiting.
Chaining can even be done in cases where usual mathematical style forbids, with reversing of the direction of the inequalities:
2 < 4 > 3
True
4.6. Character strings#
Chunks of text can be described by surrounding them either with double quotes (“real quotation marks”) or so-called ‘single quotes’, (which are actualy apostrophes).
"I recommend using 'double quote' characters, except perhaps when quote marks must appear within a string, like here."
"I recommend using 'double quote' characters, except perhaps when quote marks must appear within a string, like here."
However, using apostrophes (single right quotes) is also allowed by Python, perhaps because they are slightly easier to type.
4.6.1. String concatenation and duplication#
To concatenate two strings, “add” them with +
.
Also, consistent with that, making multiple copies of a string is done by “mutiplication”, with *
greeting = "Hello"
audience = "world"
sentence = greeting + " " + audience + "."
print(sentence)
print(3*(greeting+' '))
Hello world.
Hello Hello Hello
4.7. Naming quantities, and displaying information with print
#
It often helps to give names to quantities, which is done with assignment statements. For example, to solve for \(x\) in the very simple equation \(ax + b = 0\) for given values of \(a\) and \(b\), let us name all three quantities:
a = 3
b = 7
x = -b/a
(Note: this is why testing for equality uses ==
instead of =
.)
Running the above cell just computes the three values with no output.
To see the values, a more flexible alternative to the “last line of a cell” method is the function print
:
print(a, b, x)
3 7 -2.3333333333333335
That output does not explain things very clearly; we can add explanatory text to the printed results in several ways. Most basically:
print("For a =", a, "and b =", b, "the solution of ax + b = 0 is", x)
For a = 3 and b = 7 the solution of ax + b = 0 is -2.3333333333333335
The above prints six items — three text strings (each quoted), three numbers — with the input items separated by commas.
There is an alternative notation for such output, called “f-strings”, which use braces to specify that the value of a variable be inserted into a string of text to display:
print(f"For a = {a} and b = {b} the solution of ax + b = 0 is {x}")
For a = 3 and b = 7 the solution of ax + b = 0 is -2.3333333333333335
In this example each pair of braces inserts the value of a variable; one can instead put an expression in braces to have it evaluated and that value displayed. So in fact we could skip the variable \(x\) entirely:
print(f"For a = {a} and b = {b} the solution of ax + b = 0 is {-b/a}")
For a = 3 and b = 7 the solution of ax + b = 0 is -2.3333333333333335
We can also display the equation more directly:
print(f"The solution of {a} x + {b} = 0 is {-b/a}")
The solution of 3 x + 7 = 0 is -2.3333333333333335
A final shortcut with print
: if an expression in braces ends with =
, both the expression and its value are displayed:
print(f"For {a=} and {b=} the solution of ax + b = 0 is {-b/a=}")
For a=3 and b=7 the solution of ax + b = 0 is -b/a=-2.3333333333333335
4.8. Some mathematical functions and constants: module math
#
Python includes many modules and packages that add useful defintions of functions, constants and such.
For us, the most fundamental is math
, which is a standard part of Python.
Aside: we will soon learn about another package numpy
and then mostly use that instead of math
.
I mention math
for now because it is a core part of Python whereas numpy
is a separate “add-on”,
and you should be aware of math
if only because many references on doing mathematical stuff with Python will refer to it.
We can access specific items with a from
… import
command; to start with, two variables containing famous values:
from math import pi, e
print(f'pi is approximately {pi}')
pi is approximately 3.141592653589793
print(f'e is approximately {e}')
e is approximately 2.718281828459045
Each is accurate to about 16 significant digits; that is the precision of the 64-bit number system standard in most modern computers.
4.8.1. Names (like “e” and “pi”) are case-sensitive#
We can now return to the comment above about case sensitivity. Compare the results of the following two input lines:
print(f'e = {e}')
e = 2.718281828459045
print(f'E = {E}')
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [33], in <cell line: 1>()
----> 1 print(f'E = {E}')
NameError: name 'E' is not defined
4.8.2. Some math
functions#
Module math
also provides a lot of familiar mathematical functions
from math import sin, cos, cosh
which can be used like this:
sin(pi/4)
0.7071067811865475
cos(pi)
-1.0
cosh(0)
1.0
4.8.2.1. Notes#
All Python functions need parentheses around their arguments; no lazy shortcuts with trig. functions and such.
Trig. functions use radians, not degrees.
4.8.3. Importing all of a module#
With the command
import math
we get access to many functions such as tan
, but need to address them by fully qualified name, like math.tan
:
print(f"tan(pi/4) = {math.tan(pi/4)}")
tan(pi/4) = 0.9999999999999999
If we had not already imported pi
above, its full name math.pi
would also be needed, as in:
print(f"tan(pi/4) = {math.tan(math.pi/4)}")
tan(pi/4) = 0.9999999999999999
Aside: The imperfection of computer arithmetic becomes clear: the exact value is 1 of course. However, the precision of about 16 decimal places is far greater than for any experimental measurement (so far), so this is usually not a problem in practice.
4.8.4. Wild imports: avoid, usually#
There is another way of importing all the contents of a module so that they are available on a “first name basis”, called a wild import; it is like the single-item imports above with from math import ...
but no with an asterisk (often called the wild-card character in this context) as the name of the items to import:
from math import *
log(10)
2.302585092994046
Wild imports can be convenient when working interactively (using Python like a scientific calculator) through saving a bit of typing, but I strongly recommend using the previous more specific approaches when creating files and programs.
One reason is that it is then unambiguous where a given item came from, even if multiple import
commands are used.
For example, we will see later than there are both math.cos
and numpy.cos
, and they behave differently in some situations.
Another reason for explicit imports is for internal efficiency in storage and execution time; wild imports can potentially load thousands of items from a large module even if only a few are used.
4.9. Logarithmic functions#
We just saw that there is a function log
in module math
, but which base does it use?
log(10)
2.302585092994046
log(e)
1.0
Evaluating these two expressions reveals that “log()” is the natural logarithm, base \(e\);
what mathematicians usually call “\(\ln\)”.
For the base ten version “\(\log_{10}\)” (sometimes just called “\(\log\)”) use log10
:
log10(100)
2.0
4.9.1. Powers and roots#
A square root can of course be computed using the 1/2 power, as with
16**0.5
4.0
but this function is important enough to have a named form provided by module math
:
sqrt(2)
1.4142135623730951
4.10. Notes on organization and presentation of course work#
If you are doing the exercises in these notes for a course, record both your input and the resulting output, in a document that you will submit for feedback and then grading, suc as a moified copy of this notebook.
I also encourage you to make notes of other things that you learn, beyond what must be submitted — they will help later in the course.
Also, every document that you submit, hand-written or electronic, should start with:
A title,
your name (possibly also with your email address), and
the date, of the current version.
(See the Title Cell above for example.)