Copyright CRC Press 2023 - present CRC Press
Author: Dr Stephen Lynch National Teaching Fellow FIMA SFHEA
Dear Readers: Feel free to contact me if you notice any errors. One of the advantages of showing solutions online is that they can be corrected.
Please note: Chapter 1 covers Python IDLE and you should run the commands below in IDLE.
I've used a jupyter notebook here so that the commands can be shown on the Web.
# 1.1(a): Brackets.
2 * (3 - 4 * (5 - 8))
30
# 1.1(b): Exponential and trig function.
# Import all functions from the math library (module).
# Recall that pi/6 radians = 30 degrees.
from math import *
exp(sin(pi / 6))
1.648721270700128
# 1.1(c): Floor and ceiling functions.
floor(pi) - ceil(exp(1))
0
# 1.1(d): Floating point arithmetic.
3602879701896397 / 2**55
0.1
# 1.1(e): Fractions.
from fractions import Fraction
Fraction(4, 5) - Fraction(1, 7) * Fraction(2, 3)
Fraction(74, 105)
# 1.2(a): Generating data.
l1 = list(range(4 , 401 , 2))
print(l1)
[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 390, 392, 394, 396, 398, 400]
# 1.2(b): Generating data.
l2 = list(range(-9 , 200 , 4))
print(l2)
[-9, -5, -1, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 183, 187, 191, 195, 199]
# 1.2(c): Lists of lists.
A=[[1,2,3] , [4,5,6] , [7,8,9]]
A[1][2]
6
# 1.2(d): Compute the mean.
a = [10, 3, 4, 7, 8, 2, 5, 3, 4, 12]
mean_list = sum(a) / len(a)
print(mean_list)
5.8
# 1.3(a): Convert Fahrenheit to Centigrade.
def F2C():
F = float(input("Enter temperature in degrees Fahrenheit: "))
C = 5 * (F - 32) / 9
print("Temperature in Centigrade is {:08.4f} C".format(C))
F2C()
Enter temperature in degrees Fahrenheit: 113 Temperature in Centigrade is 045.0000 C
# 1.3(b): Sum primes.
def sum_primes(n):
sum_p = 0
for n in range(2, n + 1):
if all(n % i for i in range(2, n)):
sum_p += n
print('The sum of the primes up to {:,} is {:,}'.format(n, sum_p))
sum_primes(100)
The sum of the primes up to 100 is 1,060
# 1.3(c): Guess the number game.
import random # Import the random module.
num_guesses = 0
name = input('Hi! What is your name? ')
number = random.randint(1, 20) # A random integer between 1 and 20.
print('Welcome, {}! I am thinking of an integer between 1 and 20.'.format(name))
while num_guesses < 6:
guess = int(input('Take a guess and type the integer? '))
num_guesses += 1
if guess < number:
print('Your guess is too low.')
if guess > number:
print('Your guess is too high.')
if guess == number:
break
if guess == number:
print('Well done {}! You guessed my number in {} guesses!'.format(name, num_guesses))
else:
print('Sorry, you lose! The number I was thinking of was {}'.format(number))
Hi! What is your name? Ste Welcome, Ste! I am thinking of an integer between 1 and 20. Take a guess and type the integer? 4 Your guess is too low. Take a guess and type the integer? 5 Your guess is too low. Take a guess and type the integer? 15 Your guess is too high. Take a guess and type the integer? 12 Your guess is too high. Take a guess and type the integer? 10 Well done Ste! You guessed my number in 5 guesses!
# 1.3(d): Pythagorean triples.
import math
def pythagorean_triples(i):
for b in range(i):
for a in range(1, b):
c = math.sqrt( a * a + b * b)
n = 1
if c - b == n:
print(a, b, int(c))
pythagorean_triples(101)
import math
def pythagorean_triples(i):
for b in range(i):
for a in range(1, b):
c = math.sqrt( a * a + b * b)
n = 3
if c - b == n:
print(a, b, int(c))
pythagorean_triples(201)
3 4 5 5 12 13 7 24 25 9 40 41 11 60 61 13 84 85 9 12 15 15 36 39 21 72 75 27 120 123 33 180 183
# 1.3(e): Words in a text.
import string
a_string = "One ring to rule them all, one ring to find them, one ring to bring them all, and in the darkness bind them."
# Ignore punctuation.
new_string = a_string.translate(str.maketrans('', '', string.punctuation))
print(new_string)
# Split the words.
words = new_string.split(" ")
long_words = []
count = 0
for j in range(len(words)):
if len(words[j]) >= 5:
count += 1
long_words.append(words[j])
print("There are", count , "words with 5 letters or more.")
print("The words are:", long_words)
One ring to rule them all one ring to find them one ring to bring them all and in the darkness bind them There are 2 words with 5 letters or more. The words are: ['bring', 'darkness']
# 1.4: You must run this cell before the other turtle programs.
# These commands are not needed in IDLE.
!pip install ColabTurtlePlus
from ColabTurtlePlus.Turtle import *
Requirement already satisfied: ColabTurtlePlus in /usr/local/lib/python3.7/dist-packages (2.0.1) Put clearscreen() as the first line in a cell (after the import command) to re-run turtle commands in the cell
# 1.4(a): Variation of the Cantor set.
initializeTurtle()
def cantor3(x , y , length):
speed(13)
if length >= 1:
penup()
pensize(2)
pencolor("blue")
setpos(x , y)
pendown()
fd(length)
y -= 80
cantor3(x , y , length / 5)
cantor3(x + 2 * length / 5 , y , length / 5)
cantor3(x + 4 * length / 5 , y , length / 5)
penup()
setpos(x , y + 80)
cantor3(-300 , 200 , 600)
# 1.4(b): The Koch square.
initializeTurtle()
pensize(1)
rt(90)
def KochSquare(length, level):
speed(13) # Fastest speed.
for i in range(4):
plot_side(length, level)
rt(90)
def plot_side(length, level):
if level==0:
fd(length)
return
plot_side(length/3, level-1)
lt(90)
plot_side(length/3, level-1)
rt(90)
plot_side(length/3, level-1)
rt(90)
plot_side(length/3, level-1)
lt(90)
plot_side(length/3, level-1)
KochSquare(120 , 3)
# 1.4(c): A trifurcating tree.
initializeTurtle()
speed(13)
setheading(90)
penup()
setpos(0 , -200)
pendown()
def FractalTreeColor(length, level):
pensize(length /10) # Thickness of lines.
if length < 20:
pencolor("green")
else:
pencolor("brown")
if level > 0:
fd(length) # Forward
rt(50) # Right turn 50 degrees
FractalTreeColor(length*0.7, level-1)
lt(120) # Left turn 120 degrees
FractalTreeColor(length*0.5, level-1)
rt(60) # Right turn 60 degrees
FractalTreeColor(length*0.5, level-1)
rt(10) # Right turn 10 degrees
penup()
bk(length) # Backward
pendown()
FractalTreeColor(200,6)
# 1.4(d): Sierpinski square.
initializeTurtle()
speed(13)
penup()
setpos(-200 , -200)
pendown()
def SierpinskiSquare(length, level):
if level==0:
return
begin_fill() # Fill shape
color("red")
for i in range(4):
SierpinskiSquare(length/3, level-1)
fd(length/2)
SierpinskiSquare(length/3, level-1)
fd(length/1)
lt(90) # Left turn 90 degrees
end_fill()
SierpinskiSquare(200 , 3)
# 2.1(a): An array. Vectorized computation.
# Sum the elements in each row.
import numpy as np
A = np.arange(100).reshape(10 , 10)
print("A = " , A)
A.sum(axis = 1)
A = [[ 0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29] [30 31 32 33 34 35 36 37 38 39] [40 41 42 43 44 45 46 47 48 49] [50 51 52 53 54 55 56 57 58 59] [60 61 62 63 64 65 66 67 68 69] [70 71 72 73 74 75 76 77 78 79] [80 81 82 83 84 85 86 87 88 89] [90 91 92 93 94 95 96 97 98 99]]
array([ 45, 145, 245, 345, 445, 545, 645, 745, 845, 945])
# 2.1(b): Maxima of rows.
A.max(axis = 1)
array([ 9, 19, 29, 39, 49, 59, 69, 79, 89, 99])
# 2.1(c): Cumulative sum of columns.
A.cumsum(axis = 0)
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [ 10, 12, 14, 16, 18, 20, 22, 24, 26, 28], [ 30, 33, 36, 39, 42, 45, 48, 51, 54, 57], [ 60, 64, 68, 72, 76, 80, 84, 88, 92, 96], [100, 105, 110, 115, 120, 125, 130, 135, 140, 145], [150, 156, 162, 168, 174, 180, 186, 192, 198, 204], [210, 217, 224, 231, 238, 245, 252, 259, 266, 273], [280, 288, 296, 304, 312, 320, 328, 336, 344, 352], [360, 369, 378, 387, 396, 405, 414, 423, 432, 441], [450, 460, 470, 480, 490, 500, 510, 520, 530, 540]])
# 2.1(d): Finding an element in row 10 and column 5.
A[9][4]
94
# 2.1(e): Define a rank 3 tensor. A 2x2x2 array.
Tensor1 = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
print(Tensor1)
Tensor1.ndim
[[[1 2] [3 4]] [[5 6] [7 8]]]
3
# 2.2(a): Simple plot.
import matplotlib.pyplot as plt
x = np.linspace(-5,8,1000)
y = x**2 - 3 * x - 18
plt.plot(x , y)
plt.show()
# 2.2(b): Plot trigonometric function.
y = np.cos(2 * x)
plt.plot(x , y)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
# 2.2(c): Plot.
y = np.sin(x)**2
plt.plot(x , y)
plt.xlabel("x")
plt.ylabel("y")
plt.title("$y=\sin^2(x)$")
plt.show()
# 2.2(d): Plot with point of inflection.
x = np.linspace(-2,2,1000)
y = 4 * x**3 - 3 * x**4
plt.ylim([-6, 2])
plt.plot(x , y)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
# 2.2(e): Coshine graph.
x = np.linspace(-3 , 3 , 1000)
y = np.cosh(x)
plt.ylim([0, 10])
plt.plot(x , y)
plt.xlabel("x")
plt.ylabel("y")
plt.title("y=cosh(x)")
plt.show()
# 2.3(a): Factorize.
from sympy import *
x , y = symbols("x y")
factor(x**3 - y**3)
# 2.3(b): Solve.
# Solve x**2 - 7 * x - 30 = 0.
# With the solve function you do not have to include "=0".
solve(x**2 - 7 * x - 30 , x)
[-3, 10]
# 2.3(c): Partial fractions.
apart(3 * x / ((x-1) * (x+2) * (x-5)))
# 2.3(d): Simplify trig expressions.
trigsimp(sin(x)**4 - 2 * cos(x)**2 * sin(x)**2 + cos(x)**4)
# 2.3(e): Expansion.
expand((y + x - 3) * (x**2 - y + 4))
# 2.4(a): Limits.
limit((1+1 / x)**x , x , oo)
# 2.4(b): Differentiation.
diff(3 * x**4 - 6 * x**3)
# 2.4(c): Higher order differentiation.
diff(3 * x**4 - 6 * x**3 , x , 3)
# 2.4(d): Indefinite integration.
print(integrate(x**2 - 2 * x - 3 , x), "+ c")
x**3/3 - x**2 - 3*x + c
# 2.4(e): Taylor series expansion.
(exp(x) * sin(x)).series(x , 1 , 10)
# 2.5(a): Summation of an infinite series.
# Use oo for infinity.
n = symbols("n")
summation(1 / n , (n , 1 , oo) )
# 2.5(b): Solve linear simultaneous equations.
solve([x-y-2,x+y-1],[x,y])
{x: 3/2, y: -1/2}
# 2.5(c): Solve nonlinear simultaneous equations.
# You should also plot the curves to check the number of intersections.
solve([x**2-y-2,x+y-1],[x,y])
[(-1/2 + sqrt(13)/2, 3/2 - sqrt(13)/2), (-sqrt(13)/2 - 1/2, 3/2 + sqrt(13)/2)]
# 2.5(d): Arithmetic series.
summation(2 + 3 * (n-1) , (n , 1 , 20))
# 2.5(e): Geometric series.
summation(2 * 3**n , (n , 1 , 20))
# 2.6(a): Matrix algebra.
A = Matrix([[-1,2,4],[0,3,2],[1,4,6]])
B = Matrix([[1,-1,1],[2,0,-1],[1,-1,1]])
3 * A - 5 * B
# 2.6(b): Matrix multiplication.
A * B
# 2.6(c): Inverse matrix.
A.inv()
# 2.6(d): Access column 1.
(A**8).col(0)
# 2.6(e): Eigenvalues and multiplicity.
B.eigenvals()
{1: 2, 0: 1}
# 2.6(e): You can also compute the eigenvectors.
# This was not requested in the question.
B.eigenvects()
[(0, 1, [Matrix([ [1/2], [3/2], [ 1]])]), (1, 2, [Matrix([ [1], [1], [1]])])]
# 2.7(a): Complex number arithmetic.
# Generally, mathematicians use i for sqrt(-1) and engineers use j.
z1 , z2 = 1 - 4j, 5 + 6j
3 * z1 - 5 * z2
(-22-42j)
# 2.7(b): Modulus of a complex number.
abs(z1 * z2)
32.202484376209235
# 2.7(c): Complex expand.
(z1 * exp(z2)).expand(complex=True)
# 2.7(d): Complex expand.
(sin(z1)).expand(complex=True)
# 2.7(e): Convert to polar coordinates.
import cmath
cmath.polar(z2)
(7.810249675906654, 0.8760580505981934)
# 3.1(a): Solve dy/dx=-y/x.
from sympy import *
x = symbols("x")
y = symbols("y", cls = Function)
ODE1 = Eq(y(x).diff(x) , - y(x) / x)
sol1 = dsolve(ODE1 , y(x))
print(sol1)
Eq(y(x), C1/x)
# 3.1(b): Solve dy/dx=y/x^2.
ODE2 = Eq(y(x).diff(x) , y(x) / x**2)
sol2 = dsolve(ODE2 , y(x))
print(sol2)
Eq(y(x), C1*exp(-1/x))
# 3.1(c): Solve dx/dt+x^2=1.
t = symbols("t")
x = symbols("x", cls = Function)
ODE3 = Eq(x(t).diff(t) , - x(t)**2 + 1)
sol3 = dsolve(ODE3 , x(t))
print(sol3)
Eq(x(t), -1/tanh(C1 - t))
# 3.1(d): Solve dx/dt+x=sin(t).
ODE4 = Eq(x(t).diff(t) , - x(t) + sin(t))
sol4 = dsolve(ODE4 , x(t))
print(sol4)
Eq(x(t), C1*exp(-t) + sin(t)/2 - cos(t)/2)
# 3.1(e): Solve y"+5y'+6y=10sin(t).
y = symbols("y", cls = Function)
ODE5 = Eq(y(t).diff(t,t) + 5 * y(t).diff(t) + 6 * y(t) , 10 * sin(t))
sol5 = dsolve(ODE5 , y(t))
print(sol5)
Eq(y(t), C1*exp(-3*t) + C2*exp(-2*t) + sin(t) - cos(t))
# 3.2: Animation.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML
# Set up figure.
fig, ax = plt.subplots()
plt.title('Animation')
plt.close()
# Set domain and range.
ax.set_xlim(( -5, 5))
ax.set_ylim((- 5, 5))
# Set line width.
line, = ax.plot([], [], lw=2)
# Initialization function: plot the background of each frame.
def init():
line.set_data([], [])
return (line,)
# Animation function. This is called sequentially.
def animate(n):
x = np.linspace(-5 , 5 , 100)
y = x**3 + (-4 + n * 0.1) * x + 1
line.set_data(x, y)
return (line,)
# Animate, interval sets the speed of animation.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=61, interval=100, blit=True)
# Note: below is the part which makes it work on Colab.
rc('animation', html='jshtml')
anim