These notes are adapted from the Python tutorial available at: https://docs.python.org/3/tutorial/.

Here we see the basic functionality of Python by using it as a fancy calculator.

Many of the examples in these tutorials, even those entered at the interactive prompt, include comments. Comments in Python start with the hash character, #, and extend to the end of the physical line. A comment may appear at the start of a line or following whitespace or code, but not within a string literal. A hash character within a string literal is just a hash character. Since comments are to clarify code and are not interpreted by Python, they may be omitted when typing in examples.

In [1]:

```
# this is the first comment
spam = 1 # and this is the second comment
# ... and now a third!
text = "# This is not a comment because it's inside quotes."
```

The interpreter acts as a simple calculator: you can type an expression at it and it will write the value. Expression syntax is straightforward: the operators +, -, * and / work just like in most other languages (for example, Pascal or C); parentheses (()) can be used for grouping. For example:

In [2]:

```
2 + 2
```

Out[2]:

In [3]:

```
50 - 5*6
```

Out[3]:

In [4]:

```
(50 - 5*6) / 4
```

Out[4]:

In [5]:

```
8 / 5 # division always returns a floating point number
```

Out[5]:

The integer numbers (e.g. 2, 4, 20) have type int, the ones with a fractional part (e.g. 5.0, 1.6) have type float.

Division (/) always returns a float. To do floor division and get an integer result (discarding any fractional result) you can use the // operator; to calculate the remainder you can use %:

In [6]:

```
17 / 3 # classic division returns a float
```

Out[6]:

In [7]:

```
17 // 3 # floor division discards the fractional part
```

Out[7]:

In [8]:

```
17 % 3 # the % operator returns the remainder of the division
```

Out[8]:

In [9]:

```
5 * 3 + 2 # result * divisor + remainder
```

Out[9]:

With Python, it is possible to use the ** operator to calculate powers:

In [10]:

```
5 ** 2 # 5 squared
```

Out[10]:

In [11]:

```
2 ** 7 # 2 to the power of 7
```

Out[11]:

The equal sign (=) is used to assign a value to a variable. Afterwards, no result is displayed before the next interactive prompt:

In [12]:

```
width = 20
height = 5 * 9
width * height
```

Out[12]:

If a variable is not “defined” (assigned a value), trying to use it will give you an error:

In [13]:

```
n # try to access an undefined variable
```

Make sure that you review these notes several times, particularly if you have not prior experience with programming.

For these practice problems using Python as a calculator, we are
going to approximate the trigonometric function $sin$ using a
Taylor series. To start, run the following block of code to load
the `sin`

function in Python (more on this next time):

In [14]:

```
from math import sin
```

The Taylor series of $sin(x)$ around zero gives a first order approximation of:

$$ sin(x) \approx x $$

If you think about the shape of the `sin`

function, this should
make sense. In the next block of code define a variable named
`x`

and set this value to `0.1`

In [15]:

```
x = 0.1
```

Now, create a new variable `err`

(for error) that computes the
absolute error in the first order approximation of $sin(x)$ for
the current value of x. Note that Python has the function `abs`

to compute the absolute value. Print out the value of `err`

at
the end of the code chunk.

In [16]:

```
err = abs(sin(x) - x)
err
```

Out[16]:

Now, in the code block below, combine the assignment of `x`

and the
calculation of `err`

together. Copy this code five times, but set `x`

to `0.2`

, `0.3`

, `0.4`

, and `0.5`

, running each chunk.

In [17]:

```
x = 0.1
err = abs(sin(x) - x)
err
```

Out[17]:

In [18]:

```
x = 0.2
err = abs(sin(x) - x)
err
```

Out[18]:

In [19]:

```
x = 0.3
err = abs(sin(x) - x)
err
```

Out[19]:

In [20]:

```
x = 0.4
err = abs(sin(x) - x)
err
```

Out[20]:

In [21]:

```
x = 0.5
err = abs(sin(x) - x)
err
```

Out[21]:

Describe the pattern you see above. Where is the approximation best? Where is worst? (Note: double click on the cell below to input your answer)

**Answer:** The error gets worse as x increases away from zero.

The third order approximation of $sin$ is given as:

$$ sin(x) \approx x - \frac{x^3}{6} $$

Again set `x`

equal to `0.1`

. Store the first order approximation
error as the variable `err1`

and the third order approximation as
`err3`

. Print out the value `err1/err3`

.

In [22]:

```
x = 0.1
err1 = abs(sin(x) - (x))
err3 = abs(sin(x) - (x - x**3 / 6))
err1/err3
```

Out[22]:

Describe in words what the value of the output above means.

**Answer:** It shows that the error of the third order approximation is 2000 times
smaller than the first order approximation.

When you see an "Extra Practice" section, these are optional questions meant to stretch your understanding. They are often geared for students with prior programming experience.

More generally, we can write the sin function using an infinite Taylor series:

$$ sin(x) = \sum_{n=0}^\infty (-1)^{n} \cdot \frac{x^{2n + 1}}{(2n + 1)!} $$

We can get the factorial function from the math library:

In [23]:

```
from math import factorial
```

Let's set a value for `x`

and `n`

:

In [24]:

```
n = 2
x = 1
```

Write out the $n$'th term of this approximation in Python code using the variable
`n`

and variable `x`

. You can assign $n$ to an integer in order to test it:

In [25]:

```
(-1)**n * x**(2*n + 1) / factorial(2 * n + 1)
```

Out[25]:

If you have some prior experience programming, try to write a function (a quick
search will show the syntax in Python) called `sin_approx`

that takes a value of `n`

and a
value of `x`

and returns the n-term approximation to the `sin`

function at `x`

.

In [26]:

```
def sin_approx(x, n):
val = 0
for m in range(n):
val += (-1)**m * x**(2 * m + 1) / factorial(2 * m + 1)
return val
```

How well does your approximation work at `x=1`

for various values of `n`

?

In [27]:

```
for n in range(10):
err = abs(sin(x) - sin_approx(1, n=n))
print("n={0:d} err={1:0.016f}".format(n, err))
```

**Answer**: The error decreases as n increases, and is zero to 16 decimal places for
n=9 (and presumably, higher values as well).

Finally, copy the `sin_approx`

function below and add a *docstring* with the conventions
according to PEP 257.

In [28]:

```
def sin_approx(x, n):
"""Compute Taylor series approximation of the sine function.
Args:
x: Numeric value at which to approximate the function.
n: Positive integer. Number of terms to include in the
Taylor series.
Returns:
The numeric approximation.
"""
val = 0
for m in range(n):
val += (-1)**m * x**(2 * m + 1) / factorial(2 * m + 1)
return val
```

In [29]:

```
help(sin_approx)
```