- To help you learn some Python essentials and programming skills to enjoy the remainder of this course.

**How it works:**

- Complete the notebook below, as follows. Click on a question, then from the menu select Insert -> Insert Cell Below. From the dropdown box (next to the "stop" symbol) choose whether you wish to insert 'Code' or 'Markdown'. Save regularly!
- Press Shift-Enter to execute the code in a cell.
- Submit the .ipynb file via http://somas-uploads.shef.ac.uk/mas212 by 23.59pm on Sun 7th Oct 2018.
*If you are off-campus, you will need to use a VPN to submit.* - Your lecturer will mark each question as either 2 (good), 1 (needs revision), 0 (not attempted/wrong).
- This is an open-book test, which means you may consult books, notes and internet resources.
**Do not discuss or share your test with anyone**. Copy-and-pasting is**not permitted**.*Please give answers in your own words.* - Some of these questions are relatively straightforward, and some are harder (e.g. Q10, 11, 13, 19, 20). Please don't spend any longer than a maximum of 3 hours on this test, as it is for a relatively small amount of credit.

**Key Resources:**

- Lecture materials and links on course web page: http://sam-dolan.staff.shef.ac.uk/mas212/

**1. True or False?
(i) Python is case-sensitive.
(ii) Strings are mutable.
**

Statement (i) is **True** and statement (ii) is **False**.

`list`

and `set`

containers, highlighting at least one similarity and one difference between them.

**3. What is "vectorization"? What is a Universal Function, also known as a ufunc?**

Vectorization is the practice of replacing for loops with array expressions, so that batch operations are implemented efficiently in a fast compiled language such as C. A Universal Function is a function that can act on a whole array, in an element-by-element fashion.

For example, suppose I wanted to apply "sin" to every element in an array `A`

. I could do this by looping over the array, and applying `math.sin`

to each element in turn. A better, vectorized way to do this is by applying a ufunc: `np.sin(A)`

.

**4. Broadcasting. Let A, B and C be arrays with shapes (3,3,4), (1,4) and (4,4), respectively. Which of the following products exist, under the rules of broadcasting?**

(i)

`A\*A`

; (ii) `A\*B`

; (iii) `A\*C`

.Products (i) and (ii) exist (`A\*A`

and `A\*B`

). The product (iii) `A\*C`

does **not** exist.

(Please answer the following questions in "code" cells).

In [6]:

```
import math, cmath
[6*2, (3**2+5**2)**(1/3), (3+5*1j)**3, cmath.exp(-1j*math.pi/4)]
```

Out[6]:

`print()`

your result to 12 decimal places.

In [9]:

```
mysum=sum([k**(-k) for k in range(1,11)])
print("%.12f" % mysum)
```

In [12]:

```
tot = 0
for k in range(1,500000):
tot += 1/k*(-1)**(k+1)
print("%.5f" % tot)
```

**8. Write code to generate a list of the first 15 Triangular Numbers:** [1,3,6,10,15, $\ldots$, 120]

In [13]:

```
[k*(k+1)//2 for k in range(1,16)]
```

Out[13]:

**9. Write code to save your name and registration number, on separate lines, into a file "me.txt".**

In [17]:

```
f = open("me.txt", "w")
f.write("Sam Dolan\n")
f.write("012345679")
f.close()
```

`pascal(n)`

to calculate the `n`

-th row of Pascal's triangle as a list. For example, `pascal(3)`

should return the list `[1,3,3,1]`

.`print()`

the `20`

th row.

In [24]:

```
def pascal(n):
row = [1,1]
for i in range(1,n):
row = [1] + [row[i+1]+row[i] for i in range(len(row)-1)] + [1]
return row
print(pascal(20))
```

In [25]:

```
x0, x1 = 2.1, 2.5
def f(x):
return x**3 - 5*x - 1
maxits =10
tol = 1e-6
for k in range(maxits):
xnew = (x0*f(x1) - x1*f(x0))/(f(x1) - f(x0))
x0, x1 = x1, xnew
if abs(x1-x0) < tol:
break
print("%.5f" % ((x0+x1)/2))
```

In [27]:

```
s = "A man, a plan, a canal - Panama!"
print(s)
```

**12. Write code to count how many times the first letter of the alphabet appears in the string above** (case insensitive: count both 'a' and 'A').

In [28]:

```
s.count('a') + s.count('A')
```

Out[28]:

**13. Write a function checkpalindrome(s) which returns True if the phrase in s is a palindrome, and False otherwise. Check your function works by using the string above.** (Task: remove all punctuation and spaces from the string; change it to lowercase; then check whether the string is equal to its reverse).

In [32]:

```
def checkpalindrome(s):
punc = ",.!- "
for c in punc:
s = s.replace(c, "")
s = s.lower()
print(s)
palin = False
if s == s[::-1]:
palin = True
return palin
print(checkpalindrome(s))
```

`numpy`

and linear algebraIn [33]:

```
import numpy as np
xs = np.array([0.868, 0.836, 0.410, 0.657, 0.071, 0.602, 0.806, 0.325, 0.872, 0.475])
```

`xs`

(above) by using the formula $$\langle x\rangle = \frac{1}{n} \sum_i x_i$$

In [35]:

```
xmean = xs.sum() / len(xs)
print(xmean)
```

**15. Write code to find the variance of the data set xs by using the formula
$$\text{var} = \langle x^2 \rangle - \langle x \rangle^2$$**
[N.B. Do not use the functions

`xs.mean()`

or `xs.var()`

in Q14 and Q15].In [38]:

```
x2mean = (xs**2).sum() / len(xs)
var = x2mean - xmean**2
print(var)
```

Make a conjecture about the entries in $A^n$.

In [42]:

```
A = np.matrix([[1,1],[1,0]])
A10 = A**10
print(A10)
# Conjecture: The entries of A^n are the Fibonacci numbers F_{n+1} (top left),
# F_n (top right & bottom left) and F_{n-1} (bottom right).
```

In [43]:

```
A = np.matrix("-1,2,3 ; 2,4,1 ; 3,1,-3")
eigs = np.linalg.eig(A)[0]
print("The eigenvalues are %.6f, %.6f and %.6f" % tuple(eigs))
print("The sum of eigenvalues is %.4e, which is zero to within machine precision." % sum(eigs))
```

In [44]:

```
from numpy.polynomial import Polynomial
p = Polynomial([3,2,1]) # This is a quadratic polynomial: x^2 + 2x + 3.
p**2 # p^2 is a quartic polynomial: (x^2 + 2x + 3)^2 = x^4 + 4x^3 + 10x^2 + 12x + 9
```

Out[44]:

**18. Use the Polynomial class (imported above) to find the roots of the quartic polynomial
$$
p(x) = 2 x^4 + 5x^3 - 18x^2 - 27x + 54 .
$$
**
Hint: p.roots()

In [54]:

```
p = Polynomial([54,-27,-18,5,2])
rts = p.roots()
print("The roots of the quartic polynomial are: [%.3f, %.3f, %.3f, %.3f]" % tuple(rts) )
```

**19. Check that the polynomial $y(x) = 35 x^4 - 30 x^2 + 3$ is a solution of Legendre's differential equation for $n=4$, by substituting it into the left-hand side of the differential equation below, and showing that the LHS is zero.
$$
\frac{d}{dx} \left[ (1 - x^2) \frac{d y}{d x} \right] + n(n+1) y = 0 .
$$
**
(*Hint*: Use p.deriv() to take the derivative of a polynomial p.)

In [56]:

```
y = Polynomial([3,0,-30,0,35])
tmp = Polynomial([1,0,-1])*y.deriv()
n = 4
tmp2 = tmp.deriv() + n*(n+1)*y
print(tmp2)
```

**20. The name of a Fields Medallist has been scrambled using a One-Time Pad with a key made from the digits of $\pi$. Write code to unscramble the ciphertext to find a person's name. The ciphertext is: PBVZFVOOWCFSQHWL.**

(

`chr()`

and `ord()`

useful.)In [67]:

```
ciphertext = "PBVZFVOOWCFSQHWL"
pidigits = "3141592653589793"
plaintext = ""
for i in range(len(ciphertext)):
c = ciphertext[i]
shift = int(pidigits[i])
plaintext += chr((ord(c) - shift - 65) % 26 + 65)
print(plaintext)
```

In [ ]:

```
```