Exercise 04, "rotate me", carries a red warning: you must do the transpose yourself — no library is allowed for it. That constraint is the whole point. It forces you to understand what a transpose actually is, instead of calling a one-liner.
What a transpose does
The transpose swaps the axes of an array. For a 2D array, element (i, j) moves to position (j, i) — rows become columns and columns become rows. A shape of (3, 5) becomes (5, 3).
1 2 3 1 4
4 5 6 -> 2 5
3 6
(2 x 3) (3 x 2)
Geometrically, transposing reflects the image across its main diagonal. For the square raccoon crop in the subject, that diagonal flip is the visible "rotation".
First, cut a square
A transpose of a non-square image changes its shape (H×W becomes W×H), so the subject has you cut a square region first — reusing the slicing skill from exercise 03:
from load_image import ft_load
image = ft_load("animal.jpeg")
square = image[0:400, 0:400] # a 400x400 region
print("The shape of image is:", square.shape)
Implementing transpose yourself
No .T, no np.transpose, no np.swapaxes. Build the output by hand. The rule is simply out[j][i] = in[i][j]:
def ft_transpose(matrix):
"""Return the transpose of a 2D matrix (out[j][i] = in[i][j])."""
rows = len(matrix)
cols = len(matrix[0])
result = [[0] * rows for _ in range(cols)]
for i in range(rows):
for j in range(cols):
result[j][i] = matrix[i][j]
return result
Read it carefully: the output has cols rows and rows columns — the dimensions are swapped — and each value is copied to its mirrored position. This is the literal definition of a transpose, written out as code.
A NumPy-friendly version
If you are working with a NumPy array but still must avoid the built-in transpose, you can use fancy indexing with explicit index grids — you are still doing the index swap yourself:
import numpy as np
def ft_transpose(a):
"""Transpose a 2D NumPy array without np.transpose / .T."""
h, w = a.shape
out = np.empty((w, h), dtype=a.dtype)
for i in range(h):
for j in range(w):
out[j, i] = a[i, j]
return out
The double loop is O(H×W). For a 400×400 image that is 160,000 assignments — instant. The point is comprehension, not micro-optimization.
Print the result and display it
The subject wants the new shape and the transposed data printed, then the image shown:
import matplotlib.pyplot as plt
result = ft_transpose(square[:, :, 0]) # one channel -> clean 2D
print("New shape after Transpose:", result.shape)
print(result)
plt.imshow(result, cmap="gray")
plt.show()
On screen the raccoon appears mirrored across the diagonal — the visual proof your transpose is correct.
Transpose vs rotation (the nuance)
Strictly, a transpose is a diagonal reflection, not a true rotation. A real 90° rotation is a transpose plus a flip of one axis (rotated = transpose(image)[:, ::-1]). The exercise calls it "rotate" loosely; knowing the precise difference is exactly the kind of detail a good defense will probe.
Takeaways
- Transpose swaps axes:
(i, j) -> (j, i), shape(H, W) -> (W, H). - Implement it with a double loop — the banned library call is the learning objective.
- Cut a square first so the shape stays manageable.
- A pure transpose is a diagonal mirror; a true rotation also flips an axis.