4.5. Exercise Solutions#

Solution to Exercise 4.1

# Exercise 4.1
print("\nExercise 4.1\n------------")

for _ in range(10):
    print("hello world")

Output

Exercise 4.1
------------
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world

Solution to Exercise 4.2

# -----------------------------------------------------------------------------
# Exercise 4.2
print("\nExercise 4.2\n------------")
n, n_factorial = 52, 1

for i in range(n):
    n_factorial *= i + 1
    
print(f"{n}! = {n_factorial}")

Output

Exercise 4.2
------------
52! = 80658175170943878571660636856403766975289505440883277824000000000000

Solution to Exercise 4.3

# -----------------------------------------------------------------------------
# Exercise 4.3
print("\nExercise 4.3\n-------------")

import math

x = math.pi / 4
sinx = 0

for n in range(5):
    sinx += (-1) ** n / math.factorial(2 * n + 1) * x ** (2 * n + 1)
    
print(f"sin(pi / 4) = {math.sin(x)}")

Output

Exercise 4.3
-------------
sin(pi / 4) = 0.7071067811865475

Solution to Exercise 4.4

# -----------------------------------------------------------------------------
# Exercise 4.4
print("\nExercise 4.4\n------------")

i = 0
while i < 10:
    print("hello again")
    i += 1

Output

Exercise 4.4
------------
hello again
hello again
hello again
hello again
hello again
hello again
hello again
hello again
hello again
hello again

Solution to Exercise 4.5

# -----------------------------------------------------------------------------
# Exercise 4.5
print("\nExercise 4.5\n------------")

x = 100
num_steps = 0

print(f" step |   n\n--------------\n    0 | {x:4d}")

while x > 1:
    if x % 2 == 0:
        x //= 2
    else:
        x = 3 * x + 1
        
    num_steps += 1
    
    print(f" {num_steps:4d} | {x:4d}")
    
print(f"\nThe sequence took {num_steps} steps to reach 1.")

Output

Exercise 4.5
------------
 step |   n
--------------
    0 |  100
    1 |   50
    2 |   25
    3 |   76
    4 |   38
    5 |   19
    6 |   58
    7 |   29
    8 |   88
    9 |   44
   10 |   22
   11 |   11
   12 |   34
   13 |   17
   14 |   52
   15 |   26
   16 |   13
   17 |   40
   18 |   20
   19 |   10
   20 |    5
   21 |   16
   22 |    8
   23 |    4
   24 |    2
   25 |    1

The sequence took 25 steps to reach 1.

Solution to Exercise 4.6

# -----------------------------------------------------------------------------
# Exercise 4.6
print("\nExercise 4.6\n------------")

import numpy as np

numbers = np.array([1009, 2123, 6269, 8441])

for n in numbers:
    prime = True
    for i in range(2, n):
        if n % i == 0:
            prime = False
            break
    
    if prime:
        print(f"{n} is prime")

    else:
        print(f"{n} is not prime")

Output

Exercise 4.6
------------
1009 is prime
2123 is not prime
6269 is prime
8441 is not prime

Solution to Exercise 4.7

# -----------------------------------------------------------------------------
# Exercise 4.7
print("\nExercise 4.7\n------------")
print("I'm thinking of a number between 0 and 100, guess what it is.")

n = np.random.randint(0, 100)
guesses_left = 5

while True: # Change to False to avoid having to run the game each time
    guess = int(input(f"\nYou have {guesses_left} guesses remaining > "))
    guesses_left -= 1
    
    if guess == n:
        print("Congratulations, you win!")
        break
    
    elif guess < n:
        print("Unlucky, your guess is less than my number.")
        
    elif guess > n:
        print("Unlucky, your guess is greater than my number.")
        
    if guesses_left == 0:
        print("Oh dear, you lose.")
        break

Output

Exercise 4.7
------------
I'm thinking of a number between 0 and 100, guess what it is.

You have 5 guesses remaining > 50
Unlucky, your guess is less than my number.

You have 4 guesses remaining > 75
Unlucky, your guess is greater than my number.

You have 3 guesses remaining > 66
Unlucky, your guess is greater than my number.

You have 2 guesses remaining > 60
Unlucky, your guess is greater than my number.

You have 1 guesses remaining > 57
Unlucky, your guess is less than my number.
Oh dear, you lose.

Solution to Exercise 4.8

# -----------------------------------------------------------------------------  
# Exercise 4.8
print("\nExercise 4.8\n------------")

A = np.array([[3, 2, -1, 4], [7, -4, 0, 2]])
B = np.array([[1, 0], [3, -2], [3, 6], [-1, 4]])
AB = np.zeros((A.shape[0], B.shape[1]))

for i in range(A.shape[0]):
    for j in range(B.shape[1]):
        for k in range(A.shape[1]):
            AB[i,j] += A[i,k] * B[k,j] 
            
print(f"AB = \n\n {AB} \n")

BA = np.zeros((B.shape[0], A.shape[1]))
for i in range(B.shape[0]):
    for j in range(A.shape[1]):
        for k in range(B.shape[1]):
            BA[i,j] += B[i,k] * A[k,j] 
            
print(f"2. BA = \n\n {BA}")

Output

Exercise 4.8
------------
1. AB = 
[[ 2.  6.]
 [-7. 16.]]

2. BA = 
[[  3.   2.  -1.   4.]
 [ -5.  14.  -3.   8.]
 [ 51. -18.  -3.  24.]
 [ 25. -18.   1.   4.]]