Before you turn this problem in, make sure everything runs as expected. First, restart the kernel (in the menubar, select Kernel \(\rightarrow\) Restart) and then run all cells (in the menubar, select Cell \(\rightarrow\) Run All).
Make sure you fill in any place that says YOUR CODE HERE or “YOUR ANSWER HERE”, as well as your name and collaborators below:
NAME = ""
COLLABORATORS = ""
Tutorial 4#
Task 1#
In the Rock-Paper-Scissors game, two players choose one of three action: Rock (\(0\)), Paper (\(1\)) and Scissors (\(2\)). The rules of the game are that:
Rock (\(0\)) beats Scissors (\(2\)).
Paper (\(1\)) beats Rock (\(0\)).
Scissors (\(2\)) beat Paper (\(1\)).
When both players choose the same move, it is a tie.
Your first taks is to crate a function create_rps_game_matrix() that returns a \(3×3\) NumPy array representing the game rules.
Use the following convention for the outcomes:
\(0\) is a Tie
\(1\) is a Win (when the player’s move beats the opponent’s)
\(-1\) is a Loss (when the player’s move loses to the opponent’s)
The rows of the matrix represent the player’s move, and the columns represent the opponent’s move.
import numpy as np
def create_rps_game_matrix():
# YOUR CODE HERE
raise NotImplementedError()
rps_matrix = create_rps_game_matrix()
assert type(rps_matrix) == np.ndarray, "Must return a numpy array"
assert rps_matrix.shape == (3, 3), "Must create a 3x3 array"
assert rps_matrix[0, 0] == 0, "Rock ties with Rock"
assert rps_matrix[0, 1] == -1, "Rock loses to Paper"
assert rps_matrix[0, 2] == 1, "Rock beats Scissors"
assert rps_matrix[1, 0] == 1, "Paper beats Rock"
assert rps_matrix[1, 1] == 0, "Paper ties with Paper"
assert rps_matrix[1, 2] == -1, "Paper loses to Scissors"
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
Cell In[4], line 1
----> 1 rps_matrix = create_rps_game_matrix()
3 assert type(rps_matrix) == np.ndarray, "Must return a numpy array"
4 assert rps_matrix.shape == (3, 3), "Must create a 3x3 array"
Cell In[3], line 4, in create_rps_game_matrix()
1 def create_rps_game_matrix():
2
3 # YOUR CODE HERE
----> 4 raise NotImplementedError()
NotImplementedError:
Task 2#
Your second task is to create a function called simulate_rps that simulates a series of Rock-Paper-Scissors games where the player always uses fixed_move, and the opponent selects moves at random. The parameters should be:
num_games(int): Number of games to simulate.fixed_move(int): The player’s fixed move (0: Rock, 1: Paper, 2: Scissors).
The function should return a numpy.ndarray of the form [num_wins, num_ties, num_losses].
Hint: To implement randomly choosing an action, use the function numpy.random.randint
def simulate_rps(num_games, fixed_move):
"""
Simulates a series of Rock-Paper-Scissors games where the player always uses fixed_move,
and the opponent selects moves at random.
Parameters:
num_games (int): Number of games to simulate.
fixed_move (int): The player's fixed move (0: Rock, 1: Paper, 2: Scissors).
Returns:
numpy.ndarray: Array [num_wins, num_ties, num_losses].
"""
# Validate inputs
if num_games < 0:
raise ValueError("num_games must be non-negative.")
if fixed_move not in [0, 1, 2]:
raise ValueError("fixed_move must be 0 (Rock), 1 (Paper), or 2 (Scissors).")
# Edge case: no games to simulate
if num_games == 0:
return np.array([0, 0, 0])
# Retrieve the game matrix
rps_game = create_rps_game_matrix()
############
## DO NOT REMOVE OR CHANGE THIS WHEN SUBMITTING.
## You can change it when testing to get different results,
## but note that some of the assert statements will fail
## unless the random number seed is set to 42.
##
np.random.seed(42)
##
############
# YOUR CODE HERE
raise NotImplementedError()
result = simulate_rps(100, 0) # Player always chooses Rock.
assert isinstance(result, np.ndarray), "simulate_games should return a numpy array."
assert result.shape == (3,), "The returned array should have three elements (wins, ties, losses)."
assert result.sum() == 100, "The total outcomes should sum up to the number of games played."
assert result[0] == 31, "The number of wins should be 31. Make sure np.random.seed(42) is called"
assert result[1] == 33, "The number of ties should be 33. Make sure np.random.seed(42) is called"
assert result[2] == 36, "The number of losses should be 36. Make sure np.random.seed(42) is called"
# Hidden tests
Task 3#
The sigmoid function is a key function used in many machine learning algorithms. It is defined as:
where \(e\) is the natural logarithm. The derivative of the sigmoid function is given by:
You should implement the Sigmoid Function and the derivative of the Sigmoid Function:
Write a function
sigmoid(z)that computes the sigmoid of an input z.Input: A scalar, vector, or NumPy array.
Output: The sigmoid of the input, computed in a vectorized way.
Write a function
sigmoid_derivative(z)that computes the derivative of the sigmoid function using the formula above.Input: A scalar, vector, or NumPy array.
Output: The derivative of the sigmoid of the input, computed in a vectorized way.
def sigmoid(z):
"""
Compute the sigmoid of z.
Parameters:
z (scalar, np.ndarray): Input value or array.
Returns:
np.ndarray: The sigmoid of the input.
"""
# YOUR CODE HERE
raise NotImplementedError()
assert sigmoid(0) == 0.5
assert np.isclose(sigmoid(np.array([0, 0, 0, 0])), np.array([0.5, 0.5, 0.5, 0.5])).all()
assert np.isclose(sigmoid(np.array([[0, 0], [0, 0]])), np.array([[0.5, 0.5], [0.5, 0.5]])).all()
def derivative_sigmoid(z):
"""
Compute the derivative of the sigmoid function with respect to z.
Parameters:
z (scalar, np.ndarray): Input value or array.
Returns:
np.ndarray: The derivative of the sigmoid function with respect to z.
"""
# YOUR CODE HERE
raise NotImplementedError()
assert derivative_sigmoid(0) == 0.25
assert np.isclose(derivative_sigmoid(np.array([0, 0, 0, 0])), np.array([0.25, 0.25, 0.25, 0.25])).all()
assert np.isclose(derivative_sigmoid(np.array([[0, 0], [0, 0]])), np.array([[0.25, 0.25], [0.25, 0.25]])).all()
### After implementing the sigmoid function above,
## you can run the following code to plot the function and the derivative
import matplotlib.pyplot as plt
z = np.linspace(-10, 10, 1000)
sig = sigmoid(z)
dsig = derivative_sigmoid(z)
plt.figure(figsize=(10, 5))
plt.plot(z, sig, label='sigmoid')
plt.plot(z, dsig, label='derivative sigmoid')
plt.xlabel('z')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.legend(frameon=False)
plt.show()