# 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), andthe

*date*, of the**current version**.

(See the Title Cell above for example.)