I am working on the file "Python/22_Transforms.ipynb".
The first task is:
We applied the "same" transformation to the same point, so why are the results slightly different for the second initialization method?
This is where theory meets practice. Using the axis-angle initialization method involves trigonometric functions which on a fixed precision machine lead to these slight differences. In many cases this is not an issue, but it is something to remember. From here on we will sweep it under the rug (printing with a more reasonable precision).
Translation to Rigid [3D]
Copy the translational component.
Can you write Python code for it?

dimension = 3
t = (1, 2, 3)
translation = sitk.TranslationTransform(dimension, t)

# Only need to copy the translational component.
rigid_euler = sitk.Euler3DTransform()
rigid_euler.SetTranslation(translation.GetOffset())

rigid_versor = sitk.VersorRigid3DTransform()
rigid_versor.SetTranslation(translation.GetOffset())

# Sanity check to make sure the transformations are equivalent.
bounds = [(-10, 10), (-100, 100), (-1000, 1000)]
num_points = 10
point_list = uniform_random_points(bounds, num_points)
transformed_point_list = [translation.TransformPoint(p) for p in point_list]

# Draw the original and transformed points, include the label so that we
# can modify the plots without requiring explicit changes to the legend.
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
orig = ax.scatter(
    list(np.array(point_list).T)[0],
    list(np.array(point_list).T)[1],
    list(np.array(point_list).T)[2],
    marker="o",
    color="blue",
    label="Original points",
)
transformed = ax.scatter(
    list(np.array(transformed_point_list).T)[0],
    list(np.array(transformed_point_list).T)[1],
    list(np.array(transformed_point_list).T)[2],
    marker="^",
    color="red",
    label="Transformed points",
)
plt.legend(loc=(0.0, 1.0))

euler_errors = target_registration_errors(
    rigid_euler, point_list, transformed_point_list
)
versor_errors = target_registration_errors(
    rigid_versor, point_list, transformed_point_list
)

print(f"Euler\tminError: {min(euler_errors):.2f} maxError: {max(euler_errors):.2f}")
print(f"Versor\tminError: {min(versor_errors):.2f} maxError: {max(versor_errors):.2f}")


I am working on the file "Python/22_Transforms.ipynb".
The first task is:
We next define the same BSpline transformation using a set of coefficient images. Note that to compare the parameter values for the two transformations we need to scale the values in the new transformation using the scale value used in the GUI above.
Can you write Python code for it?

control_point_number = [sz+spline_order for sz in mesh_size]
num_parameters_per_axis = np.prod(control_point_number)

coefficient_images = []
for i in range(dimension):
    coefficient_image = sitk.GetImageFromArray((original_control_point_displacements[i*num_parameters_per_axis:(i+1)*num_parameters_per_axis]).reshape(control_point_number))
    coefficient_image.SetOrigin(origin)
    coefficient_image.SetSpacing([sz/(cp-1) for cp,sz in zip(control_point_number, domain_physical_dimensions)])
    coefficient_image.SetDirection(direction_matrix_row_major)
    coefficient_images.append(coefficient_image)

bspline2 = sitk.BSplineTransform(coefficient_images, spline_order)

# Note that the scale value is left intentionally blank: set the scale value based on the slider value in the GUI above.
# You will get an error when executing the cell if a value is not provided.
scale_factor_from_gui =
print(np.array(bspline.GetParameters()) - np.array(bspline2.GetParameters())*scale_factor_from_gui)


I am working on the file "Python/22_Transforms.ipynb".
The first task is:
Why don't the two transformations have the same effect on the point set even though their parameters are the same? What parameters did we forget to set for the second transformation?
Similarity to Affine [3D]
Copy the translation, center and matrix.
Can you write Python code for it?

rotation_center = (100, 100, 100)
axis = (0, 0, 1)
angle = np.pi / 2.0
translation = (1, 2, 3)
scale_factor = 2.0
similarity = sitk.Similarity3DTransform(
    scale_factor, axis, angle, translation, rotation_center
)

affine = sitk.AffineTransform(3)
affine.SetMatrix(similarity.GetMatrix())
affine.SetTranslation(similarity.GetTranslation())
affine.SetCenter(similarity.GetCenter())

# Apply the transformations to the same set of random points and compare the results
# (see utility functions at top of notebook).
print_transformation_differences(similarity, affine)


I am working on the file "Python/22_Transforms.ipynb".
The first task is:
Writing and Reading
The SimpleITK.ReadTransform() returns a SimpleITK.Transform . The content of the file can be any of the SimpleITK transformations or a composite (set of transformations).
Details of note:
1. When read from file, the type of the returned transform is the generic Transform. We can then obtain the "true" transform type via the Downcast method.
2. Writing of nested composite transforms is not supported, you will need to "flatten" the transform before writing it to file.
Can you write Python code for it?

import os

# Create a 2D rigid transformation, write it to disk and read it back.
basic_transform = sitk.Euler2DTransform()
basic_transform.SetTranslation((1, 2))
basic_transform.SetAngle(np.pi / 2)

full_file_name = os.path.join(OUTPUT_DIR, "euler2D.tfm")

sitk.WriteTransform(basic_transform, full_file_name)

# The ReadTransform function returns an sitk.Transform no matter the type of the transform
# found in the file (global, bounded, composite).
read_result = sitk.ReadTransform(full_file_name)

print(
    "Different types (before downcast): "
    + str(type(read_result) != type(basic_transform))
)
# Downcast the transform so that it is the specific type and not the generic type
read_result = read_result.Downcast()
print(
    "Different types (after downcast): "
    + str(type(read_result) != type(basic_transform))
)

print_transformation_differences(basic_transform, read_result)

# Create a composite transform then write and read.
displacement = sitk.DisplacementFieldTransform(2)
field_size = [10, 20]
field_origin = [-10.0, -100.0]
field_spacing = [20.0 / (field_size[0] - 1), 200.0 / (field_size[1] - 1)]
field_direction = [1, 0, 0, 1]  # direction cosine matrix (row major order)

# Concatenate all the information into a single list.
displacement.SetFixedParameters(
    field_size + field_origin + field_spacing + field_direction
)
displacement.SetParameters(np.random.random(len(displacement.GetParameters())))

composite_transform = sitk.CompositeTransform([basic_transform, displacement])

full_file_name = os.path.join(OUTPUT_DIR, "composite.tfm")

sitk.WriteTransform(composite_transform, full_file_name)
read_result = sitk.ReadTransform(full_file_name)

print_transformation_differences(composite_transform, read_result)

x_translation = sitk.TranslationTransform(2, [1, 0])
y_translation = sitk.TranslationTransform(2, [0, 1])
# Create composite transform with the x_translation repeated 3 times
composite_transform1 = sitk.CompositeTransform([x_translation] * 3)

# Create a nested composite...


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
$\alpha$-$\beta$ pruning with intelligent memoization takes 17 ms to compute the value of the state gStart for Tic-Tac-Toe.
Hence, there is no big difference between intelligent memoization and naive memoization in this example.  However, if we implement
a non-trivial game like Connect Four, the situation changes.
Can you write Python code for it?

%%time
v = evaluate(gStart, maxValue, -1, 1)
v


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
Alpha-Beta Pruning with Intelligent Memoization
In order to have some variation in our game, we use random numbers to choose between optimal moves.
In order to have reproducible results, we use a seed for the random number generator.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
Let's draw the board.
Can you write Python code for it?

canvas = create_canvas()
draw(gStart, canvas, f'Current value of game for "X": {v}')


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
Now its time to play.  In the input window that will pop up later, enter your move in the format "row,col"  with no space between row and column.  Both row and col should be integers from the set {0,1,2}.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
Playing the Game
The function best_move takes two arguments:
- State is the current state of the game,
- player is a player.
The function best_move returns a pair of the form $(v, s)$ where $s$ is a state and $v$ is the value of this state.  The state $s$ is a state that is reached from State if player makes one of her optimal moves.  In order to have some variation in the game, the function randomly chooses any of the optimal moves.
Can you write Python code for it?

def best_move(State):
    NS        = next_states(State, gPlayers[0])
    bestValue = evaluate(State, maxValue, -1, 1)
    BestMoves = [s for s in NS if evaluate(s, minValue, -1, 1) == bestValue]
    BestState = random.choice(BestMoves)
    return bestValue, BestState


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
The function evaluate takes four arguments:
- State is the current state of the game,
- f     is either the function maxValue or the function minValue.
These functions are defined later. If in State it is the first player's turn, then f is equal to maxValue, else f is equal to minValue.
- alpha is a lower bound for the value of State,
- beta  is an upper bound for the value of State,
The function evaluate satisfies the following specification:
- $\alpha \leq \texttt{value}(s) \leq \beta \;\rightarrow\;\texttt{evaluate}(s, f, \alpha, \beta) = \texttt{value}(s)$
- $\texttt{value}(s) < \alpha \;\rightarrow\; \texttt{evaluate}(s, f, \alpha, \beta) \leq \alpha$
- $\beta < \texttt{value}(s) \;\rightarrow\; \beta \leq \texttt{evaluate}(s, f, \alpha, \beta)$
Here, the expression value(s) returns the value of the given state s if both players play their optimal game.  This value is an element from the set ${-1, 0, 1}$.
- If the first player can force a win, the return value is 1.
- If the first player can at best force a draw, the return value is 0.
- If the second player can force a win, the return value is -1.
For reasons of efficiency, the function evaluate is memoized using the global variable gCache.
If gCache[State] is defined, then the computation of evaluate(State, alpha, beta)
proceeds according to the following case distinction:
1. If the stored value $v$ is exact, we can return this value:
$$\texttt{gCache[State]} = (\texttt{'='}, v) \rightarrow \texttt{evaluate}(\texttt{State}, f, \alpha, \beta) = v.$$
2. If the stored value $v$ is an upper bound and this upper bound is less or equal than $\alpha$, then we know that
   the true value of State is less or equal than $\alpha$ and hence we can also return the value $v$:
$$\texttt{gCache[State]} = (\texttt{'≤'}, v) \wedge v \leq \alpha \rightarrow
     \texttt{evaluate}(\texttt{State}, f, \alpha, \beta) = v.$$
3. If the stored value $v$ is an upper bound and this upper bound is bigger than $\alpha$ but less than $\beta$, then we know that the true value is...
Can you write Python code for it?

def evaluate(State, f, alpha=-1, beta=1):
    global gCache
    if State in gCache:
        flag, v = gCache[State]
        if flag == '=':
            return v
        if flag == '≤':
            if v <= alpha:
                return v
            elif v < beta: # alpha < v
                w = f(State, alpha, v)
                store_cache(State, alpha, v, w)
                return w
            else: # beta <= v
                w = f(State, alpha, beta)
                store_cache(State, alpha, beta, w)
                return w
        if flag == '≥':
            if beta <= v:
                return v
            elif alpha < v: # v < beta
                w = f(State, v, beta)
                store_cache(State, v, beta, w)
                return w
            else: # v <= alpha
                w = f(State, alpha, beta)
                store_cache(State, alpha, beta, w)
                return w
    else: # no value stored in gCache for State
        v = f(State, alpha, beta)
        store_cache(State, alpha, beta, v)
        return v


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
The function play_game plays on the given canvas.  The game played is specified indirectly by specifying the following:
- Start is a global variable defining the start state of the game.
- next_states is a function such that $\texttt{next_states}(s, p)$ computes the set of all possible states that can be reached from state $s$ if player $p$ is next to move.
- finished is a function such that $\texttt{finished}(s)$ is true for a state $s$ if the game is over in state $s$.
- utility is a function such that $\texttt{utility}(s, p)$ returns either -1, 0, or 1 in the terminal state $s$.  We have that
  - $\texttt{utility}(s, p)= -1$ iff the game is lost for player $p$ in state $s$,
  - $\texttt{utility}(s, p)=  0$ iff the game is drawn, and
  - $\texttt{utility}(s, p)=  1$ iff the game is won for player $p$ in state $s$.
Can you write Python code for it?

def play_game(canvas):
    State = gStart
    while (True):
        val, State = best_move(State);
        draw(State, canvas, f'For me, the game has the value {val}.')
        if finished(State):
            final_msg(State)
            break
        IPython.display.clear_output(wait=True)
        State = get_move(State)
        draw(State, canvas, '')
        if finished(State):
            IPython.display.clear_output(wait=True)
            final_msg(State)
            break


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
The function store_cache is called with four arguments:
* State is a state of the game,
* alpha is a number,
* beta  is a number, and
* v     is a number such that:
  $$\texttt{evaluate(State, f, alpha, beta)} = v$$
The function stores the value in the dictionary gCache under the key State.
It also stores an indicator that is either '≤', '=', or '≥'.  The value that is stored
satisfies the following conditions:
* If gCache[State] = ('≤', v), then value(State) ≤ v.
* If gCache[State] = ('=', v), then value(State) = v.
* If gCache[State] = ('≥', v), then value(State) ≥ v.
Can you write Python code for it?

def store_cache(State, alpha, beta, v):
    global gCache
    if   v <= alpha:
        gCache[State] = ('≤', v)
    elif v <  beta: # alpha < v
        gCache[State] = ('=', v)
    else: # beta <= v
        gCache[State] = ('≥', v)


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
The global variable gCache is used as a cache for the function evaluate defined later.  Instead of just storing the values for a given State, the cache stores pairs of the form
* ('=', v),
* ('≤', v), or
* ('≥', v).
The first component of these pairs is a flag that specifies whether the stored value v is exact or whether it only is a lower or upper bound.  Concretely, provided gCache[State] is defined and evaluate(State) computes the value of a given State, the following invariants are satisfied:
* $\texttt{gCache[State]} = (\texttt{'='}, v) \rightarrow \texttt{evaluate(State)} = v$.
* $\texttt{gCache[State]} = (\texttt{'≤'}, v) \rightarrow \texttt{evaluate(State)} \leq v$.
* $\texttt{gCache[State]} = (\texttt{'≥'}, v) \rightarrow \texttt{evaluate(State)} \geq v$.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Memoization.ipynb".
The first task is:
We check how many different states are stored in the Cache.  Without alpha-beta pruning, we had to inspect $5478$ different states, but now there are only
$2474$ different states in the cache.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
Alpha-Beta Pruning
This notebook implements alpha-beta pruning. Memoization techniques are only added in a naive way since adding these techniques in a sophisticated way results in an algorithm that is quite complicated.
Effectively, this notebook is a game solver because it can be used to play various deterministic, zero-sum, two-person games with perfect information.  To this end, the implementation assumes that an external notebook defines a game and provides the following variables and functions:
* gPlayers is a list of length two.  The elements of this list are the
  players.  It is assumed that the first element in this list represents
  the computer, while the second element is the human player.  The computer
  always starts the game.
* gStart is the start state of the game.
* next_states(state, player) is a function that takes two arguments:
  - state is a state of the game.
  - player is the player whose turn it is to make a move.
  The function call next_states(state, player) returns the list
  of all states that can be reached by any move of player.
* utility(state) takes a state and a player as its arguments.
  If state is a terminal state, then the function returns the value
  that this state has for the player who starts the game.  Otherwise, the function returns None.
* finished(state) returns True if and only if state is a terminal state.
* get_move(state) displays the given state and asks the human player for
  her move.
* final_msg(state) informs the human player about the result of the game.
* draw(state, canvas, value) draws the given state on the canvas and informs
  the user about the value of this state.

In order to have some variation in our game, we use random numbers to choose between optimal moves.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
Given that $\texttt{minValue}(s)$ is the value of the state $s$, the function alphaBetaMin satisfies the following specification:
- $\alpha \leq \texttt{minValue}(s) \leq \beta \;\rightarrow\;\texttt{alphaBetaMin}(s, \alpha, \beta) = \texttt{minValue}(s)$
- $\texttt{minValue}(s) < \alpha \;\rightarrow\; \texttt{alphaBetaMin}(s, \alpha, \beta) \leq \alpha$
- $\beta < \texttt{minValue}(s) \;\rightarrow\; \beta \leq \texttt{alphaBetaMin}(s, \alpha, \beta)$
Can you write Python code for it?

def alphaBetaMin(State, alpha, beta):
    if finished(State):
        return utility(State)
    value = beta
    for ns in next_states(State, gPlayers[1]):
        value = min(value, alphaBetaMax(ns, alpha, value))
        if value <= alpha:
            return value
    return value

import random
random.seed(1)


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
If we use $\alpha$-$\beta$ pruning, computing the value of the Start state of tic-tac-toe takes about 77 ms.  This should be compared to the more than 2 seconds that the minimax algorithm needs.
Can you write Python code for it?

%%time
val = alphaBetaMax(gStart, -1, 1)


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
Let us check the size of the cache.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
Let's draw the board.
Can you write Python code for it?

canvas = create_canvas()
draw(gStart, canvas, f'Current value of game for "X": {val}')


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
Naive Memoization
The implementation of memoize that is given below uses the fact that the functions alphaBetaMax and alphaBetaMin are never called with the same arguments.
Can you write Python code for it?

gCache = {}

def memoize(f):
    global gCache

    def f_memoized(*args):
        if args in gCache:
            return gCache[args]
        result = f(*args)
        gCache[args] = result
        return result

    return f_memoized

alphaBetaMax = memoize(alphaBetaMax)
alphaBetaMin = memoize(alphaBetaMin)

%%time
val = alphaBetaMax(gStart, -1, 1)


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
Now its time to play.  In the input window that will pop up later, enter your move in the format "row,col"  with no space between row and column.
Can you write Python code for it?


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
The function best_move takes one argument:
- State is the current state of the game.
The function best_move returns a pair of the form $(v, s)$ where $s$ is a state and $v$ is the value of this state.  The state $s$ is a state that is reached from State if player makes one of her optimal moves.  In order to have some variation in the game, the function randomly chooses any of the optimal moves.
Can you write Python code for it?

def best_move(State):
    NS        = next_states(State, gPlayers[0])
    bestVal   = alphaBetaMax(State, -1, 1)
    bestMoves = [s for s in NS if alphaBetaMin(s, -1, 1) == bestVal]
    bestState = random.choice(bestMoves)
    return bestVal, bestState


I am working on the file "Python/3 Games/Alpha-Beta-Pruning-Pure.ipynb".
The first task is:
The function play_game plays the game that is specified externally via the functions next_states and utility.  The states of the game are drawn on the given canvas.
Can you write Python code for it?

def play_game(canvas):
    State = gStart
    while (True):
        val, State = best_move(State);
        draw(State, canvas, f'For me, the game has the value {val}.')
        if finished(State):
            final_msg(State)
            return
        IPython.display.clear_output(wait=True)
        State = get_move(State)
        draw(State, canvas, '')
        if finished(State):
            IPython.display.clear_output(wait=True)
            final_msg(State)
            break

%%capture
%run Tic-Tac-Toe-Bitboard.ipynb


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
Given a State and the player who is the next player move, the function next_states(State, player) computes the list of states that can be reached from State by a move of player.
Can you write Python code for it?

def next_states(State, player):
    "your code here"


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The function draw takes three arguments:
- State is the current state of the game.
- canvas is a canvas used to draw the state.
- value is the value of the game for player X.
The function draws the given State onto canvas.  Below that, the value is printed.
Can you write Python code for it?

def draw(State, canvas, value):
    canvas.clear()
    canvas.font = '36px sans-serif'
    canvas.text_align    = 'center'
    canvas.text_baseline = 'middle'
    for row in range(6):
        for col in range(7):
            x = col * size
            y = row * size
            canvas.line_width = 3.0
            canvas.stroke_rect(x, y, size, size)
            symbol = State[5-row][col]
            if symbol != ' ':
                x += size // 2
                y += size // 2
                if symbol == 'X':
                    canvas.fill_style ='red'
                else:
                    canvas.fill_style ='blue'
                canvas.fill_arc(x, y, 0.4*size, 0, 2*math.pi)
    canvas.font = '20px sans-serif'
    canvas.fill_style = 'black'
    for i in range(7):
        x = (i + 0.5) * size
        y = 6.4 * size
        canvas.fill_text(str(i), x, y)
    x = 3.5 * size
    y = 7.4 * size
    canvas.fill_text(str(value), x, y)


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The function get_move asks the user to input a move in the format r,c where r is the row and the c is the column where the next symbol is to be placed.
Can you write Python code for it?

def get_move(State):
    State = to_list(State)
    while True:
        col = input("Enter column here: ")
        col = int(col)
        row = find_empty(State, col)
        if row != None:
            State[row][col] = 'O'
            return to_tuple(State)
        else:
            print("Don't cheat.  Please try again.")


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The function heuristic tries to guess the value of a state.  As it is never called in terminal states, the given implementation assumes that the game will be drawn and hence returns $0$.  If you have solved all of the other exercises, you should try to improve this function.
Can you write Python code for it?

def heuristic(State):
    "your code here, but you can try returning 0 initially"
    return 0


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The function to_list transforms a tuple of tuples into a list of lists.
Can you write Python code for it?

to_list = lambda State: [list(row) for row in State]


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The function to_tuple transforms a list of lists into a tuple of tuples.
Can you write Python code for it?

to_tuple = lambda State: tuple(tuple(row) for row in State)


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The function utility takes two arguments:
- State is a tuple of tuple representing the board.
- player is a player.
The function returns 1 if player has won the game, -1 if the game is lost for player, 0 if it's a draw, and None if the game has not yet been decided.
Can you write Python code for it?

def utility(State):
    "your code here"


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
The variable All_Lines collects the coordinates of all groups of four fields that are consecutive horizontally, vertically, or diagonally.  For example, the variable All_Lines contains, among others, the following lists:
[(0, 0), (0, 1), (0, 2), (0, 3)]
    [(0, 0), (1, 0), (2, 0), (3, 0)]
    [(1, 1), (2, 2), (3, 3), (4, 4)]
Can you write Python code for it?

All_Lines  = "your code here"

All_Lines


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
This function creates the canvas for the start state.  It draws an empty board which is later used for the game.
Can you write Python code for it?

def create_canvas():
    canvas = cnv.Canvas(size=(size * 7, size * 8))
    display(canvas)
    return canvas

import math


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
This function informs the user about the result of the game once the game is finished.
Can you write Python code for it?

def final_msg(State):
    if finished(State):
        if utility(State) == -1:
            print("You have won!")
        elif utility(State) == 1:
            print("You have lost!")
        else:
            print("It's a draw.");
        return True
    return False


I am working on the file "Python/3 Games/Connect-Four-Frame.ipynb".
The first task is:
finished(State) is True if the game is over.
Can you write Python code for it?

def finished(State):
    return utility(State) != None


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
Alpha-Beta Pruning with Progressive Deepening, Move Ordering, and Memoization
The function pd_evaluate takes three arguments:
- State is the current state of the game,
- limit determines how deep the game tree is searched,
- f     is either the function maxValue or the function minValue.
The function pd_evaluate uses progressive deepening to compute the value of State.  The given State is evaluated for a depth of $0$, $1$, $\cdots$, limit.  The values calculated for a depth of $l$ are stored and used to sort the states when State is next evaluated for a depth of $l+1$.  This is beneficial for alpha-beta pruning because alpha-beta pruning can cut off more branches from the search tree if we start be evaluating the best moves first.
We need to declare the function maxValue since we use it as a default value for the parameter f of the function pd_evaluate.
Can you write Python code for it?

def maxValue():
    pass # this function will be properly defined later

def pd_evaluate(State, limit, f=maxValue):
    for l in range(limit+1):
        value = evaluate(State, l, f)
        if value in [-1, 1]:
            return value
    return value


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
For the start state, progressive deepening does not seem to be beneficial.  The reason is that initially the values of the states do not differ very much.
Playing the Game
The variable gMoveCounter stores the number of moves that have already been executed.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
For the start state, the evaluation takes about 22 seconds, if the depth limit is set to 9.
Can you write Python code for it?

gCache = {}

%%time
value = pd_evaluate(gStart, 9, maxValue)
value

len(gCache)


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
In order to evaluate the effect of progressive deepening, we reset the cache and can then evaluate the test state without progressive deepening.
Can you write Python code for it?

gCache = {}

%%time
value = evaluate(gStart, 9, maxValue)
value

len(gCache)


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
In order to have some variation in our game, we use random numbers to choose between optimal moves.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The function best_move takes two arguments:
- State is the current state of the game,
- limit is the depth limit of the recursion.
The function best_move returns a pair of the form $(v, s)$ where $s$ is a state and $v$ is the value of this state.  The state $s$ is a state that is reached from State if the player makes one of her optimal moves.  In order to have some variation in the game, the function randomly chooses any of the optimal moves.
Can you write Python code for it?

def best_move(State, limit):
    NextStates = next_states(State, gPlayers[0])
    if gMoveCounter < 9:
        bestValue = evaluate(State, limit, maxValue)
    else:
        bestValue = pd_evaluate(State, limit, maxValue)
    BestMoves  = [s for s in NextStates
                    if evaluate(s, limit-1, minValue) == bestValue
                 ]
    BestState  = random.choice(BestMoves)
    return bestValue, BestState


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The function evaluate takes five arguments:
- State is the current state of the game,
- limit determines the lookahead.  To be more precise, it is the number of half-moves that are investigated to compute the value.  If limit is 0 and the game has not ended, the game is evaluated via the function heuristic. This function is supposed to be defined in the notebook defining the game.
- f is either the function maxValue or the function minValue.
f = maxValue if it's the maximizing player's turn in State.  Otherwise,
   f = minValue.
- alpha and beta are the parameters from alpha-beta pruning.
The function evaluate returns the value that the given State has if both players play their optimal game.
- If the maximizing player can force a win, the return value is 1.
- If the maximizing player can at best force a draw, the return value is 0.
- If the maximizing player might lose even when playing optimal, the return value is -1.
Otherwise, the value is calculated according to a heuristic.
For reasons of efficiency, the function evaluate is memoized using the global variable gCache.   This work in the same way as described in the notebook Alpha-Beta-Pruning-Memoization.ipynb.
Can you write Python code for it?

def evaluate(State, limit, f=maxValue, alpha=-1, beta=1):
    global gCache
    if (State, limit) in gCache:
        flag, v = gCache[(State, limit)]
        if flag == '=':
            return v
        if flag == '≤':
            if v <= alpha:
                return v
            elif alpha < v < beta:
                w = f(State, limit, alpha, v)
                store_cache(State, limit, alpha, v, w)
                return w
            else: # beta <= v:
                w = f(State, limit, alpha, beta)
                store_cache(State, limit, alpha, beta, w)
                return w
        if flag == '≥':
            if beta <= v:
                return v
            elif alpha < v < beta:
                w = f(State, limit, v, beta)
                store_cache(State, limit, v, beta, w)
                return w
            else: # v <= alpha
                w = f(State, limit, alpha, beta)
                store_cache(State, limit, alpha, beta, w)
                return w
    else:
        v = f(State, limit, alpha, beta)
        store_cache(State, limit, alpha, beta, v)
        return v


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The function maxValue satisfies the following specification:
- $\alpha \leq \texttt{value}(s) \leq \beta \;\rightarrow\;\texttt{maxValue}(s, l, \alpha, \beta) = \texttt{value}(s)$
- $\texttt{value}(s) < \alpha \;\rightarrow\; \texttt{maxValue}(s, l, \alpha, \beta) \leq \alpha$
- $\beta < \texttt{value}(s) \;\rightarrow\; \beta \leq \texttt{maxValue}(s, \alpha, \beta)$
It assumes that gPlayers[0] is the maximizing player.  This function implements alpha-beta pruning.  After searching up to a depth of limit, the value is approximated using the function heuristic.
Can you write Python code for it?

def maxValue(State, limit, alpha=-1, beta=1):
    if finished(State):
        return utility(State)
    if limit == 0:
        return heuristic(State)
    value      = alpha
    NextStates = next_states(State, gPlayers[0])
    Moves      = []  # empty priority queue
    for ns in NextStates:
        # heaps are sorted ascendingly, hence the minus
        heapq.heappush(Moves, (-value_cache(ns, limit-2), ns))
    while Moves != []:
        _, ns = heapq.heappop(Moves)
        value = max(value, evaluate(ns, limit-1, minValue, value, beta))
        if value >= beta:
            return value
    return value


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The function minValue satisfies the following specification:
- $\alpha \leq \texttt{value}(s) \leq \beta \;\rightarrow\;\texttt{minValue}(s, l, \alpha, \beta) = \texttt{value}(s)$
- $\texttt{value}(s) < \alpha \;\rightarrow\; \texttt{minValue}(s, l, \alpha, \beta) \leq \alpha$
- $\beta < \texttt{value}(s) \;\rightarrow\; \beta \leq \texttt{minValue}(s, \alpha, \beta)$
It assumes that gPlayers[1] is the minimizing player.  This function implements alpha-beta pruning.  After searching up to a depth of limit, the value is approximated using the function heuristic.
Can you write Python code for it?

def minValue(State, limit, alpha=-1, beta=1):
    if finished(State):
        return utility(State)
    if limit == 0:
        return heuristic(State)
    value      = beta
    NextStates = next_states(State, gPlayers[1])
    Moves      = []  # empty priority queue
    for ns in NextStates:
        heapq.heappush(Moves, (value_cache(ns, limit-2), ns))
    while Moves != []:
        _, ns = heapq.heappop(Moves)
        value = min(value, evaluate(ns, limit-1, maxValue, alpha, value))
        if value <= alpha:
            return value
    return value

%%capture
%run Connect-Four.ipynb


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The function play_game plays on the given canvas.  The game played is specified indirectly by specifying the following:
- Start is a global variable defining the start state of the game.
- next_states is a function such that $\texttt{next_states}(s, p)$ computes the set of all possible states that can be reached from state $s$ if player $p$ is next to move.
- finished is a function such that $\texttt{finished}(s)$ is true for a state $s$ if the game is over in state $s$.
- utility is a function such that $\texttt{utility}(s, p)$ returns either -1, 0, or 1 in the terminal state $s$.  We have that
  - $\texttt{utility}(s, p)= -1$ iff the game is lost for player $p$ in state $s$,
  - $\texttt{utility}(s, p)=  0$ iff the game is drawn, and
  - $\texttt{utility}(s, p)=  1$ iff the game is won for player $p$ in state $s$.
Can you write Python code for it?

def play_game(canvas, limit):
    global gCache, gMoveCounter
    State   = gStart
    History = []
    while (True):
        gCache = {}
        gMoveCounter += 1
        firstPlayer = gPlayers[0]
        start       = time.time()
        val, State  = best_move(State, limit)
        stop        = time.time()
        diff        = round(stop - start, 2)
        History.append(diff)
        draw(State, canvas, f'{round(diff, 2)} seconds, value = {round(val, 2)}.')
        if finished(State):
            final_msg(State)
            break
        IPython.display.clear_output(wait=True)
        State = get_move(State)
        draw(State, canvas, '')
        if finished(State):
            IPython.display.clear_output(wait=True)
            final_msg(State)
            break
    for i, d in enumerate(History):
        print(f'{i}: {d} seconds')

canvas = create_canvas()
draw(gStart, canvas, f'Current value of game for "X": {round(value, 2)}')

play_game(canvas, 8)

len(gCache)


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The function store_cache is called with five arguments:
* State is a state of the game,
* limit is the search depth,
* alpha is a number,
* beta  is a number, and
* value is a number such that:
  $$\texttt{evaluate(State, limit, f, alpha, beta)} = \texttt{value}$$
The function stores the value in the dictionary Cache under the key State.
It also stores an indicator that is either '≤', '=', or '≥'.  The value that is stored
satisfies the following conditions:
* If Cache[State, limit] = ('≤', value), then evaluate(State, limit) ≤ value.
* If Cache[State, limit] = ('=', value), then evaluate(State, limit) = value.
* If Cache[State, limit] = ('≥', value), then evaluate(State, limit) ≥ value.
Can you write Python code for it?

def store_cache(State, limit, alpha, beta, value):
    global gCache
    if value <= alpha:
        gCache[(State, limit)] = ('≤', value)
    elif value < beta:
        gCache[(State, limit)] = ('=', value)
    else: # value >= beta
        gCache[(State, limit)] = ('≥', value)


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The module heapq implements heaps.  The implementation of maxValue and minValue use heaps as priority queues in order to sort the moves.  This improves the performance of alpha-beta pruning.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
The next line is needed because we need the function IPython.display.clear_output to clear the output in a cell.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game-Move-Ordering-Memoization.ipynb".
The first task is:
Utilities
The global variable gCache is used as a cache for the function evaluate defined later.  Instead of just storing the values for a given State, the cache stores pairs of the form
* ('=', v),
* ('≤', v), or
* ('≥', v).
The first component of these pairs is a flag that specifies whether the stored value v is exact or whether it only is a lower or upper bound.  Concretely, provided gCache[State] is defined and value(State) computes the value of a given State from the perspective of the maximizing
player, the following invariants are satisfied:
* $\texttt{gCache[State]} = (\texttt{'='}, v) \rightarrow \texttt{value(State)} = v$.
* $\texttt{gCache[State]} = (\texttt{'≤'}, v) \rightarrow \texttt{value(State)} \leq v$.
* $\texttt{gCache[State]} = (\texttt{'≥'}, v) \rightarrow \texttt{value(State)} \geq v$.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game.ipynb".
The first task is:
Alpha-Beta Pruning with Progressive Deepening, Move Ordering, and Memoization
The function pd_evaluate takes three arguments:
- State is the current state of the game,
- limit determines how deep the game tree is searched,
- f     is either the function maxValue or the function minValue.
The function pd_evaluate uses progressive deepening to compute the value of State.  The given State is evaluated for a depth of $0$, $1$, $\cdots$, limit.  The values calculated for a depth of $l$ are stored and used to sort the states when State is next evaluated for a depth of $l+1$.  This is beneficial for alpha-beta pruning because alpha-beta pruning can cut off more branches from the search tree if we start by evaluating the best moves first.
Can you write Python code for it?

import time

def pd_evaluate(State, time_limit, f):
    start = time.time()
    limit = 0
    while True:
        value = evaluate(State, limit, f)
        stop = time.time()
        if value in [-1, 1] or stop - start > time_limit:
            print(f'searched to depth {limit}, using {round(stop - start, 3)} seconds')
            return value, limit
        limit += 1


I am working on the file "Python/3 Games/Game.ipynb".
The first task is:
In order to have some variation in our game, we use random numbers to choose between optimal moves.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game.ipynb".
The first task is:
The function play_game plays on the given canvas.  The game played is specified indirectly by specifying the following:
- Start is a global variable defining the start state of the game.
- next_states is a function such that $\texttt{next_states}(s, p)$ computes the set of all possible states that can be reached from state $s$ if player $p$ is next to move.
- finished is a function such that $\texttt{finished}(s)$ is true for a state $s$ if the game is over in state $s$.
- utility is a function such that $\texttt{utility}(s, p)$ returns either -1, 0, or 1 in the terminal state $s$.  We have that
  - $\texttt{utility}(s, p)= -1$ iff the game is lost for player $p$ in state $s$,
  - $\texttt{utility}(s, p)=  0$ iff the game is drawn, and
  - $\texttt{utility}(s, p)=  1$ iff the game is won for player $p$ in state $s$.
Can you write Python code for it?

def play_game(canvas, time_limit):
    global gCache, gMoveCounter
    State   = gStart
    while (True):
        gCache = {}
        firstPlayer = gPlayers[0]
        val, State  = best_move(State, time_limit)
        draw(State, canvas, f'value = {round(val, 2)}.')
        if finished(State):
            final_msg(State)
            break
        IPython.display.clear_output(wait=True)
        State = get_move(State)
        draw(State, canvas, '')
        if finished(State):
            IPython.display.clear_output(wait=True)
            final_msg(State)
            break

canvas = create_canvas()
draw(gStart, canvas, f'Current value of game for "X": {round(0, 2)}')

play_game(canvas, 2)

len(gCache)


I am working on the file "Python/3 Games/Game.ipynb".
The first task is:
The function store_cache is called with five arguments:
* State is a state of the game,
* limit is the search depth,
* alpha is a number,
* beta  is a number, and
* value is a number such that:
  $$\texttt{evaluate(State, limit, f, alpha, beta)} = \texttt{value}$$
The function stores the value in the dictionary Cache under the key State.
It also stores an indicator that is either '≤', '=', or '≥'.  The value that is stored
satisfies the following conditions:
* If Cache[State, limit] = ('≤', value), then evaluate(State, limit) ≤ value.
* If Cache[State, limit] = ('=', value), then evaluate(State, limit) = value.
* If Cache[State, limit] = ('≥', value), then evaluate(State, limit) ≥ value.
Can you write Python code for it?


I am working on the file "Python/3 Games/Game.ipynb".
The first task is:
The function value_cache receives a State and a limit as parameters.  If a value for State has been computed to the given evaluation depth, this value is returned. Otherwise, 0 is returned.
Can you write Python code for it?

def value_cache(State, limit):
    flag, value = gCache.get((State, limit), ('=', 0))
    return value


I am working on the file "Python/3 Games/Game.ipynb".
The first task is:
The module heapq implements heaps.  The implementation of maxValue and minValue use heaps as priority queues in order to sort the moves.  This improves the performance of alpha-beta pruning.
Can you write Python code for it?


I am working on the file "Python/3 Games/Memoization.ipynb".
The first task is:
In order to verify that the running times are increasing exponentially, we plot the logarithms of the times.
Can you write Python code for it?

import math

Ts

LogTs = [math.log(t) for t in Ts]
plt.plot(Ns, LogTs)
plt.xlabel('n')
plt.ylabel('log(time)')
plt.title('Time to compute fib(n), logarithmic plot.')
plt.show()

for n in range(0, N-1):
    print(Ts[n]/Ts[n-1])


I am working on the file "Python/3 Games/Memoization.ipynb".
The first task is:
Let's plot the times of the memoized version of fib.  This time, there should be no exponential increase.
Can you write Python code for it?

N  = 35
Ns = []
Ts = []
for n in range(1, N):
    start = time.time()
    Fn    = fib(n)
    stop  = time.time()
    Ns.append(n)
    Ts.append(stop - start)

plt.plot(Ns, Ts)
plt.xlabel('n')
plt.ylabel('time')
plt.title('Time to compute fib(n).')
plt.show()


I am working on the file "Python/3 Games/Memoization.ipynb".
The first task is:
Memoization
This notebook discusses the technique of https://en.wikipedia.org/wiki/Memoization via the Fibonacci numbers.
The Fibonacci numbers $F_n$ are defined inductively for all $n\in\mathbb{N}$:
- $F_0 := 0$,
- $F_1 := 1$, and
- $F_{n+2} := F_{n+1} + F_n$ for all $n \in \mathbb{N}$.
The function fib takes a natural number $n$ as argument. The expression $\texttt{fib}(n)$ computes the $n$-th Fibonacci number $F_n$ in a naive way.
Can you write Python code for it?

def fib(n):
    #print(f'computing f({n})')
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)


I am working on the file "Python/3 Games/Memoization.ipynb".
The first task is:
Since fib2 is a closure, the dictionary Cache is stored inside fib2.  We can even inspect this dictionary manually.
Can you write Python code for it?


I am working on the file "Python/3 Games/Memoization.ipynb".
The first task is:
The function memoize takes a function f as its argument.  It returns a memoized version of the function f.  This memoized version will store all results in a cache and look them up instead of recomputing them.
Note that the function object f_memoized that is returned by the function memoize is a so called
closure.  The reason is that the variable
Cache, which is created in the scope where f_memoized is defined, is stored inside the function object
f_memoized.
Can you write Python code for it?

def memoize(f):
    Cache = {}

    def f_memoized(*args):
        if (f, args) in Cache:
            return Cache[(f, args)]
        result = f(*args)
        Cache[(f, args)] = result
        return result

    return f_memoized

fib = memoize(fib)


I am working on the file "Python/3 Games/Memoization.ipynb".
The first task is:
We can achieve the same effect using a decorator:
Can you write Python code for it?

@memoize
def fib2(n):
    if n < 2:
        return n
    return fib2(n-2) + fib2(n-1)

N  = 35
Ns = []
Ts = []
for n in range(1, N):
    start = time.time()
    Fn    = fib2(n)
    stop  = time.time()
    Ns.append(n)
    Ts.append(stop - start)

plt.plot(Ns, Ts)
plt.xlabel('n')
plt.ylabel('time')
plt.title('Time to compute fib(n).')
plt.show()


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
Given a player p, the function other(p) computes the opponent of p.  This assumes that there are only two players and the set of all players is stored in the global variable Players.
Can you write Python code for it?

other = lambda p: [o for o in Players if o != p][0]


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
Let's draw the board.
Can you write Python code for it?

canvas = create_canvas()
draw(Start, canvas, f'Current value of game for "X": {val}')


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
Now it's time to play.  In the input window that will pop up later, enter your move in the format "row,col" with no space between row and column.
Can you write Python code for it?


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
The function best_move takes two arguments:
- State is the current state of the game,
- player is a player.
The function best_move returns a pair of the form $(v, s)$ where $s$ is a state and $v$ is the value of this state.  The state $s$ is a state that is reached from State if player makes one of her optimal moves.  In order to have some variation in the game, the function randomly chooses any of the optimal moves.
Can you write Python code for it?

def best_move(State, player):
    NS        = next_states(State, player)
    bestVal   = value(State, player)
    BestMoves = [s for s in NS if -value(s, other(player)) == bestVal]
    BestState = random.choice(BestMoves)
    return bestVal, BestState


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
The function play_game plays a game on the given canvas.  The game played is specified indirectly as follows:
- Start is a global variable defining the start state of the game.
- next_states is a function such that $\texttt{next_states}(s, p)$ computes the set of all possible states that can be reached from state $s$ if player $p$ is next to move.
- finished is a function such that $\texttt{finished}(s)$ is true for a state $s$ if the game is over in state $s$.
- utility is a function such that $\texttt{utility}(s, p)$ returns either -1, 0, or 1 in the terminal state $s$.  We have that
  - $\texttt{utility}(s, p)= -1$ iff the game is lost for player $p$ in state $s$,
  - $\texttt{utility}(s, p)=  0$ iff the game is drawn, and
  - $\texttt{utility}(s, p)=  1$ iff the game is won for player $p$ in state $s$.
Can you write Python code for it?

def play_game(canvas):
    State = Start
    while True:
        firstPlayer = Players[0]
        val, State  = best_move(State, firstPlayer);
        draw(State, canvas, f'For me, the game has the value {val}.')
        if finished(State):
            final_msg(State)
            return
        IPython.display.clear_output(wait=True)
        State = get_move(State)
        draw(State, canvas, '')
        if finished(State):
            IPython.display.clear_output(wait=True)
            final_msg(State)
            return

%run Tic-Tac-Toe-Bitboard.ipynb


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
The function value_list takes three arguments:
- Moves is a list of states.  Each of these states results from a move
  that player has made in a given state.
  When value_list is called initially, this list is non-empty.
- player defines the player who has made the moves.
- val is a lower bound for the value of the state where the moves have been
  made.  Initially, this value is $-1$ as we don't yet know how good or bad
  this initial state is.
Can you write Python code for it?

def value_list(Moves, player, alpha=-1):
    if Moves == []:
        return alpha
    o        = other(player)
    move_val = -value(Moves[0], o)
    alpha    = max(move_val, alpha)
    return value_list(Moves[1:], player, alpha)


I am working on the file "Python/3 Games/Minimax-Recursive.ipynb".
The first task is:
The next line is needed because we need the function IPython.display.clear_output to clear the output in a cell.
Can you write Python code for it?


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
Below, the jupyter magic command %%capture silently discards the output that is produced by the notebook Tic-Tac-Toe.ipynb.
Can you write Python code for it?


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
Let us check the size of the cache.
Can you write Python code for it?


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
Let's draw the board and play a game.
Can you write Python code for it?

canvas = create_canvas()
draw(gStart, canvas, f'Current value of game for "X": {val}')


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
Now it's time to play.  In the input window that will pop up later, enter your move in the format "row,col" with no space between row and column.
Can you write Python code for it?


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
On my computer, the bit-board implementation is about twice as fast as the list based implementation.
Can you write Python code for it?

%%time
val = maxValue(gStart)

canvas = create_canvas()
draw(gStart, canvas, f'Current value of game for "X": {val}')

play_game(canvas)


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
The function best_move takes one argument:
- State is the current state of the game.
It is assumed that the first player in the list Player is to move.
The function best_move returns a pair of the form $(v, s)$ where $s$ is a state and $v$ is the value of this state.  The state $s$ is a state that is reached from State if player makes one of her optimal moves.  In order to have some variation in the game, the function randomly chooses any of the optimal moves.
Can you write Python code for it?

import random
random.seed(1)

def best_move(State):
    NS        = next_states(State, gPlayers[0])
    bestVal   = maxValue(State)
    BestMoves = [s for s in NS if minValue(s) == bestVal]
    BestState = random.choice(BestMoves)
    return bestVal, BestState


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
The function minValue(State) takes one argument:
- State is the current state of the game.
The function assumes that it is the second player's turn.  It returns the value that State has
if both players play their best game.  This value is an element from the set ${-1, 0, 1}$.
* If the first player can force a win, then the return value is 1.
* If the first player can at best force a draw, then the return value is 0.
* If the second player can force a win, then the return value is -1.
Mathematically, the function minValue is defined recursively:
- $\texttt{finished}(s) \rightarrow \texttt{minValue}(s) = \texttt{utility}(s)$
- $\neg \texttt{finished}(s) \rightarrow
   \texttt{minValue}(s) = \min\bigl(\bigl{ \texttt{maxValue}(n) \bigm| n \in \texttt{nextStates}(s, \texttt{gPlayers}[1]) \bigr}\bigr)
  $
Can you write Python code for it?

def minValue(State):
    if finished(State):
        return utility(State)
    return min([ maxValue(ns) for ns in next_states(State, gPlayers[1]) ])


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
The list based implementation of TicTacToe with Memoization takes 84 ms.
The bit-board based implementation of TicTacToe takes 38 ms.
Can you write Python code for it?


I am working on the file "Python/3 Games/Minimax.ipynb".
The first task is:
Using the BitBoard Implementation of TicTacToe
Next, we try how much the bit-board implementation speeds up the game.
Can you write Python code for it?


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
Drawing the Board
Can you write Python code for it?


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
Given a state that is represented as a number, the function empty(state) returns the set of indexes of those cells such that neither player X nor player O has placed a mark in the cell.  Note that there are 9 cells on the board.  Each of these cells can hold either an 'X' or an 'O'.  If the $i^\textrm{th}$ cell is marked with a 'X', then the $i^\textrm{th}$ bit of state is set.  If instead the $i^\textrm{th}$ cell is marked with an 'O', then the $(9+i)^\textrm{th}$ bit of state is set.  If the $i^\textrm{th}$ cell is not yet marked, then both the $i^\textrm{th}$ bit and the $(9+i)^\textrm{th}$ are $0$.
Can you write Python code for it?

def empty(state):
    Free  = { n for n in range(9) }
    Free -= { n for n in range(9) if state & (1 << n) != 0 }
    Free -= { n for n in range(9) if state & (1 << (9 + n)) != 0 }
    return Free

state = set_bits([2, 3, 5, 9+1, 9+4, 9+8])
print(to_board(state))
empty(state)


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
States are represented as integers.  The first 9 bits encode the marks of the player X, the next 9 bits encode the marks of the player O.  Initially, the board is empty and hence no bit is set.
The variable gStart represents the start state.
Can you write Python code for it?


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
The function set_bit(n) returns a number that has exactly the $\texttt{n}^\textrm{th}$ bit set.
Can you write Python code for it?

def set_bit(n):
    return 1 << n

assert set_bit(7) == 2 ** 7


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
The function set_bits takes one parameter:
* Bits is a list of numbers that specify bit positions in an integer.
The function returns an integer such that the bits specified in Bits are set. Counting starts with $0$.
Can you write Python code for it?

def set_bits(Bits):
    result = 0
    for b in Bits:
        result |= 1 << b # bitwise or 2**b
    return result

"{:b}".format(set_bits([0, 1, 4]))

assert set_bits([0, 1, 4]) == 2**0 + 2**1 + 2**4


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
The function to_board(state) takes an integer state as its argument that represents a state of the game Tic-Tac-Toe.  It converts this state into a string that represents the board corresponding to the state.
Can you write Python code for it?

def to_board(state):
    result = '+-+-+-+\n'
    for cell in range(9):
        if state & (2 ** cell) != 0:
            result += '|X'
        elif state & (2 ** (cell + 9)) != 0:
            result += '|O'
        else:
            result += '| '
        if (cell + 1) % 3 == 0:
            result += '|\n+-+-+-+\n'
    return result

print(to_board(set_bits([0,2,3,5,7,9+1,9+4,9+6])))


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
The function utility takes one argument:
- state  is an integer representing the board.
The function returns 1 if the computer has won the game, -1 if the game is lost for
the computer, 0 if it's a draw, and None if the game has not yet been decided.
Can you write Python code for it?

def utility(state):
    for mask in gAllLines:
        if state & mask == mask:
            return 1               # the computer has won
        if (state >> 9) & mask == mask:
            return -1              # the computer has lost
    # 511 == 2**9 - 1 = 0b1_1111_1111
    if (state & 511) | (state >> 9) != 511: # the board is not yet filled
        return None
    # at this point, the board has been filled, but there is no winner hence its a draw
    return 0 # it's a draw

s1 = set_bits([0, 2, 3, 6, 1+9,  4+9, 5+9]) # 'X' has won
print(to_board(s1))
utility(s1)

s2 = set_bits([0, 2, 6, 8, 1+9, 4+9, 7+9]) # 'O' has won
print(to_board(s2))
utility(s2)

s3 = set_bits([0, 2, 5, 6, 7, 1+9, 3+9, 4+9, 8+9]) # it's a draw
print(to_board(s3))
print(utility(s3))

s4 = set_bits([0, 2, 5, 6, 1+9, 3+9, 4+9]) # it ain't over yet
print(to_board(s4))
print(utility(s4))


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
This function creates the canvas for the start state.  It draws an empty board which is later used for the game.
Can you write Python code for it?

def create_canvas():
    canvas = cnv.Canvas(size=(size * 3, size * 3 + 50))
    display(canvas)
    return canvas


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
This function takes three arguments:
- state is the current state of the game.
- canvas is a canvas used to draw the state.
- value is the value of the game for player X.
The function draws the given State onto canvas.  Below that, the value is printed.
Can you write Python code for it?

def draw(state, canvas, value):
    canvas.clear()
    n = 3
    canvas.font          = '90px sans-serif'
    canvas.text_align    = 'center'
    canvas.text_baseline = 'middle'
    for row in range(n):
        for col in range(n):
            x = col * size
            y = row * size
            canvas.line_width = 3.0
            canvas.stroke_rect(x, y, size, size)
            symbol = get_symbol(state, row, col)
            if symbol != ' ':
                x += size // 2
                y += size // 2
                if symbol == 'X':
                    canvas.fill_style ='red'
                else:
                    canvas.fill_style ='blue'
                canvas.fill_text(symbol, x, y)
    canvas.font = '12px sans-serif'
    canvas.fill_style = 'green'
    for row in range(n):
        for col in range(n):
            x = col * size + 16
            y = row * size + 141
            canvas.fill_text(f'({row}, {col})', x, y)
    canvas.font = '20px sans-serif'
    canvas.fill_style = 'black'
    x = 1.5 * size
    y = 3.2 * size
    canvas.fill_text(str(value), x, y)

draw(set_bits([0, 2, 5, 6, 1+9, 3+9, 4+9]), create_canvas(), -1)


I am working on the file "Python/3 Games/Tic-Tac-Toe-Bitboard.ipynb".
The first task is:
finished(state) is True if the game is over.
Can you write Python code for it?

def finished(state):
    return utility(state) != None

s = set_bits([0, 2, 5, 6, 7, 1+9, 3+9, 4+9, 8+9])
print(to_board(s))
finished(s)


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
Checking the Memory Footprint
Can you write Python code for it?


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
Drawing the Board
Can you write Python code for it?


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
Given a State and the player whose turn it is, the function next_states(State, player) computes the list of all states that can be reached from State.
Can you write Python code for it?

def next_states(State, player):
    Empty  = empty(State)
    Result = []
    for row, col in Empty:
        NextState           = to_list(State)
        NextState[row][col] = player
        NextState           = to_tuple(NextState)
        Result.append(NextState)
    return Result

for S in next_states(gStart, 'X'):
    print(toString(S))


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
In the following naive implementation, states are represented as tuples of tuples of strings.  The game starts with an empty board.  An empty field on the board is represented by a blank space ' ', while an X is represented by the string 'X' and an O is represented as the string 'O'.  The start state Start defined below represents an empty board.
We have to represent states as tuples of tuples instead of lists of lists as lists are mutable and therefore can't be stored in sets.
Can you write Python code for it?

gStart = tuple( tuple(' ' for col in range(3)) for row in range(3) )
gStart


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
In the state gStart, all positions are empty.
Can you write Python code for it?


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
The function get_move asks the user to input a move in the format r,c where r is the row and the c is the column where the next symbol is to be placed. Rows and columns are counted starting from 0.  It is assumed that the user plays as 'O', i.e. the user takes the second move.
Can you write Python code for it?

def get_move(State):
    State = to_list(State)
    while True:
        try:
            row, col = input('Enter move here: ').split(',')
            row, col = int(row), int(col)
            if State[row][col] == ' ':
                State[row][col] = 'O'
                return to_tuple(State)
            print("Don't cheat! Please try again.")
        except:
            print('Illegal input.')
            print('row and col are numbers from the set {0,1,2}.')


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
The function toString(State) represents the given state as a string.
Can you write Python code for it?

def toString(State):
    result = '+-+-+-+\n'
    for Row in State:
        result += '|'
        for cell in Row:
            result += cell + '|'
        result += '\n+-+-+-+\n'
    return result

print(toString(gStart))


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
The memory needed to store a single state is the memory needed to store a list containing three objects  plus the memory needed to store those objects.
Can you write Python code for it?

sys.getsizeof(gStart) + sum([sys.getsizeof(row) for row in gStart]) + 9 * sys.getsizeof('_')


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
This function informs the player, who is assumed to be 'O', about the result of the game once the game is finished.
Can you write Python code for it?

def final_msg(State):
    if finished(State):
        if utility(State) == -1:
            print('You have won!')
        elif utility(State) == 1:
            print('The computer has won!')
        else:
            print("It's a draw.")
        return True
    return False


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
This function takes three arguments:
- State is the current state of the game.
- canvas is a canvas used to draw the state.
- value is the value of the game for player X.
The function draws the given State onto canvas.  Below that, the value is printed.
Can you write Python code for it?

def draw(State, canvas, value):
    canvas.clear()
    n = len(State)
    canvas.font = '90px sans-serif'
    canvas.text_align    = 'center'
    canvas.text_baseline = 'middle'
    for row in range(n):
        for col in range(n):
            x = col * g_size
            y = row * g_size
            canvas.line_width = 3.0
            canvas.stroke_rect(x, y, g_size, g_size)
            symbol = State[row][col]
            if symbol != ' ':
                x += g_size // 2
                y += g_size // 2
                if symbol == 'X':
                    canvas.fill_style ='red'
                else:
                    canvas.fill_style ='blue'
                canvas.fill_text(symbol, x, y)
    canvas.font = '12px sans-serif'
    canvas.fill_style = 'green'
    for row in range(n):
        for col in range(n):
            x = col * g_size + 16
            y = row * g_size + 141
            canvas.fill_text(f'({row}, {col})', x, y)
    canvas.font = '20px sans-serif'
    canvas.fill_style = 'black'
    x = 1.5 * g_size
    y = 3.2 * g_size
    canvas.fill_text(str(value), x, y)

State = (('O', 'X', 'O'),
         ('X', 'O', 'X'),
         ('O', 'X', 'O')
        )

draw(State, create_canvas(), 1)


I am working on the file "Python/3 Games/Tic-Tac-Toe.ipynb".
The first task is:
Tic-Tac-Toe
This notebook defines the game tic-tac-toe.
It is played on a $3 \times 3$ board.  There are two players, which are called X and O.  Player X starts.  Player X always puts an 'X' into an empty field on the board, while player O always puts an 'O' in an empty field of the board.  The goal of the game for player X is to get three Xs into a row, column, or diagonal line, while player O needs to get three Os into a row, column, or diagonal line.
The global variable gPlayers returns a list with the name of both players.
Can you write Python code for it?


I am working on the file "Python/300_Segmentation_Overview.ipynb".
The first task is:
Fast Marching Segmentation
The FastMarchingImageFilter implements a fast marching solution to a simple level set evolution problem (eikonal equation). In this example, the speed term used in the differential equation is provided in the form of an image. The speed image is based on the gradient magnitude and mapped with the bounded reciprocal $1/(1+x)$.
Can you write Python code for it?

seed = (132, 142, 96)
feature_img = sitk.GradientMagnitudeRecursiveGaussian(img_T1, sigma=0.5)
speed_img = sitk.BoundedReciprocal(
    feature_img
)  # This is parameter free unlike the Sigmoid
myshow(speed_img)


I am working on the file "Python/300_Segmentation_Overview.ipynb".
The first task is:
ITK has a number of histogram based automatic thresholding filters including Huang, MaximumEntropy, Triangle, and the popular Otsu's method. These methods create a histogram then use a heuristic to determine a threshold value.
Can you write Python code for it?

otsu_filter = sitk.OtsuThresholdImageFilter()
otsu_filter.SetInsideValue(0)
otsu_filter.SetOutsideValue(1)
seg = otsu_filter.Execute(img_T1)
myshow(sitk.LabelOverlay(img_T1_255, seg), "Otsu Thresholding")

print(otsu_filter.GetThreshold())


I am working on the file "Python/300_Segmentation_Overview.ipynb".
The first task is:
Improving upon this is the ConfidenceConnected filter, which uses the initial seed or current segmentation to estimate the threshold range.
Can you write Python code for it?

seg = sitk.ConfidenceConnected(
    img_T1,
    seedList=[seed],
    numberOfIterations=1,
    multiplier=2.5,
    initialNeighborhoodRadius=1,
    replaceValue=1,
)

myshow(sitk.LabelOverlay(img_T1_255, seg), "ConfidenceConnected")

img_multi = sitk.Compose(img_T1, img_T2)
seg = sitk.VectorConfidenceConnected(
    img_multi,
    seedList=[seed],
    numberOfIterations=1,
    multiplier=2.5,
    initialNeighborhoodRadius=1,
)
myshow(sitk.LabelOverlay(img_T2_255, seg))


I am working on the file "Python/300_Segmentation_Overview.ipynb".
The first task is:
Thresholding
Thresholding is the most basic form of segmentation. It simply labels the pixels of an image based on the intensity range without respect to geometry or connectivity.
Can you write Python code for it?

seg = img_T1 > 200
myshow(sitk.LabelOverlay(img_T1_255, seg), "Basic Thresholding")

seg = sitk.BinaryThreshold(
    img_T1, lowerThreshold=100, upperThreshold=400, insideValue=1, outsideValue=0
)
myshow(sitk.LabelOverlay(img_T1_255, seg), "Binary Thresholding")


I am working on the file "Python/300_Segmentation_Overview.ipynb".
The first task is:
Use the seed to estimate a reasonable threshold range.
Can you write Python code for it?

stats = sitk.LabelStatisticsImageFilter()
stats.Execute(img_T1, seg)

factor = 3.5
lower_threshold = stats.GetMean(1) - factor * stats.GetSigma(1)
upper_threshold = stats.GetMean(1) + factor * stats.GetSigma(1)
print(lower_threshold, upper_threshold)

init_ls = sitk.SignedMaurerDistanceMap(seg, insideIsPositive=True, useImageSpacing=True)

lsFilter = sitk.ThresholdSegmentationLevelSetImageFilter()
lsFilter.SetLowerThreshold(lower_threshold)
lsFilter.SetUpperThreshold(upper_threshold)
lsFilter.SetMaximumRMSError(0.02)
lsFilter.SetNumberOfIterations(1000)
lsFilter.SetCurvatureScaling(0.5)
lsFilter.SetPropagationScaling(1)
lsFilter.ReverseExpansionDirectionOn()
ls = lsFilter.Execute(init_ls, sitk.Cast(img_T1, sitk.sitkFloat32))
print(lsFilter)

myshow(sitk.LabelOverlay(img_T1_255, ls > 0))


I am working on the file "Python/30_Segmentation_Region_Growing.ipynb".
The first task is:
And now we compare the original segmentation to the segmentation after clean up (using the GUI you can zoom in on the region of interest for a closer look).
Can you write Python code for it?

gui.MultiImageDisplay(
    image_list=[
        sitk.LabelOverlay(img_T1_255, seg_implicit_thresholds),
        sitk.LabelOverlay(img_T1_255, seg_implicit_thresholds_clean),
    ],
    shared_slider=True,
    title_list=["before morphological closing", "after morphological closing"],
)


I am working on the file "Python/30_Segmentation_Region_Growing.ipynb".
The first task is:
Clean up, Clean up...
Use of low level segmentation algorithms such as region growing is often followed by a clean up step. In this step we fill holes and remove small connected components. Both of these operations are achieved by using binary morphological operations, opening (BinaryMorphologicalOpening) to remove small connected components and closing (BinaryMorphologicalClosing) to fill holes.
SimpleITK supports several shapes for the structuring elements (kernels) including:
* sitkAnnulus
* sitkBall
* sitkBox
* sitkCross
The size of the kernel can be specified as a scalar (same for all dimensions) or as a vector of values, size per dimension.
The following code cell illustrates the results of such a clean up, using closing to remove holes in the original segmentation.
Can you write Python code for it?

vectorRadius = (1, 1, 1)
kernel = sitk.sitkBall
seg_implicit_thresholds_clean = sitk.BinaryMorphologicalClosing(
    seg_implicit_thresholds, vectorRadius, kernel
)


I am working on the file "Python/30_Segmentation_Region_Growing.ipynb".
The first task is:
ConfidenceConnected
This region growing algorithm allows the user to implicitly specify the threshold bounds based on the statistics estimated from the seed points, $\mu\pm c\sigma$. This algorithm has some flexibility which you should familiarize yourself with:
* The "multiplier" parameter is the constant $c$ from the formula above.
* You can specify a region around each seed point "initialNeighborhoodRadius" from which the statistics are estimated, see what happens when you set it to zero.
* The "numberOfIterations" allows you to rerun the algorithm. In the first run the bounds are defined by the seed voxels you specified, in the following iterations $\mu$ and $\sigma$ are estimated from the segmented points and the region growing is updated accordingly.
Can you write Python code for it?

seg_implicit_thresholds = sitk.ConfidenceConnected(
    img_T1,
    seedList=initial_seed_point_indexes,
    numberOfIterations=0,
    multiplier=2,
    initialNeighborhoodRadius=1,
    replaceValue=1,
)

gui.MultiImageDisplay(
    image_list=[sitk.LabelOverlay(img_T1_255, seg_implicit_thresholds)],
    title_list=["confidence connected result"],
)


I am working on the file "Python/30_Segmentation_Region_Growing.ipynb".
The first task is:
Read Data and Select Seed Point(s)
We first load a T1 MRI brain scan and select our seed point(s). If you are unfamiliar with the anatomy you can use the preselected seed point specified below, just uncomment the line.
Can you write Python code for it?

img_T1 = sitk.ReadImage(fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd"))
# Rescale the intensities and map them to [0,255], these are the default values for the output
# We will use this image to display the results of segmentation
img_T1_255 = sitk.Cast(
    sitk.IntensityWindowing(
        img_T1,
        windowMinimum=T1_WINDOW_LEVEL[1] - T1_WINDOW_LEVEL[0] / 2.0,
        windowMaximum=T1_WINDOW_LEVEL[1] + T1_WINDOW_LEVEL[0] / 2.0,
    ),
    sitk.sitkUInt8,
)

point_acquisition_interface = gui.PointDataAquisition(img_T1, window_level=(1050, 500))

# preselected seed point in the left ventricle
point_acquisition_interface.set_point_indexes([(132, 142, 96)])

initial_seed_point_indexes = point_acquisition_interface.get_point_indexes()


I am working on the file "Python/32_Watersheds_Segmentation.ipynb".
The first task is:
Binary Watersheds for Object Separation
Can you write Python code for it?

rgb_img = sitk.ReadImage(fdata("coins.png"))
myshow(rgb_img, "coins.png")
img = sitk.VectorIndexSelectionCast(rgb_img, 1)
myshow(img, "Green Coins")

feature_img = sitk.GradientMagnitudeRecursiveGaussian(img, sigma=1.5)
myshow(feature_img)

ws_img = sitk.MorphologicalWatershed(
    feature_img, level=4, markWatershedLine=False, fullyConnected=False
)
myshow(sitk.LabelToRGB(ws_img), "Watershed Over Segmentation")
seg = sitk.ConnectedComponent(ws_img != ws_img[0, 0])
myshow(sitk.LabelOverlay(img, seg), "Foreground Components")

filled = sitk.BinaryFillhole(seg != 0)
d = sitk.SignedMaurerDistanceMap(
    filled, insideIsPositive=False, squaredDistance=False, useImageSpacing=False
)
myshow(d, "Inside Distance Map")

ws = sitk.MorphologicalWatershed(d, markWatershedLine=False, level=1)
myshow(sitk.LabelOverlay(img, ws))

ws = sitk.Mask(ws, sitk.Cast(seg, ws.GetPixelID()))
myshow(sitk.LabelOverlay(img, ws), "Split Objects")


I am working on the file "Python/32_Watersheds_Segmentation.ipynb".
The first task is:
Gradient Watersheds Segmentation
Can you write Python code for it?

sigma = img.GetSpacing()[0]
level = 4

feature_img = sitk.GradientMagnitude(img)
myshow(feature_img, "Edge Features")

ws_img = sitk.MorphologicalWatershed(
    feature_img, level=0, markWatershedLine=True, fullyConnected=False
)
myshow(sitk.LabelToRGB(ws_img), "Watershed Over Segmentation")

from ipywidgets import interact, interactive, FloatSlider

def callback(feature_img, *args, **kwargs):
    ws_img = sitk.MorphologicalWatershed(feature_img, *args, **kwargs)

    myshow(sitk.LabelToRGB(ws_img), "Watershed Segmentation")

interact(
    lambda **kwargs: callback(feature_img, **kwargs),
    markWatershedLine=True,
    fullyConnected=False,
    level=FloatSlider(min=0, max=255, step=0.1, value=4.0),
)


I am working on the file "Python/32_Watersheds_Segmentation.ipynb".
The first task is:
Multi-label Morphology
Can you write Python code for it?

seg = ws

radius = 10
bd_img = sitk.BinaryDilate(seg != 0, [radius] * seg.GetDimension())
myshow(bd_img, "Binary Dilate")

dist_img = sitk.SignedMaurerDistanceMap(
    seg != 0, insideIsPositive=False, squaredDistance=False, useImageSpacing=False
)
wsd_img = sitk.MorphologicalWatershedFromMarkers(dist_img, seg, markWatershedLine=False)
myshow(sitk.LabelOverlay(img, wsd_img))

md_img = sitk.Mask(wsd_img, bd_img)
myshow(sitk.LabelToRGB(md_img), "Multi-label Dilate")

e_img = sitk.BinaryErode(md_img != 0, [radius] * md_img.GetDimension())
mo_img = sitk.Mask(md_img, e_img)
myshow(sitk.LabelOverlay(img, mo_img), "Multi-label Closing")


I am working on the file "Python/33_Segmentation_Thresholding_Edge_Detection.ipynb".
The first task is:
Get the 3D location of the edge points and fit a sphere to them.
Can you write Python code for it?

edge_indexes = np.where(sitk.GetArrayViewFromImage(edges) == 1.0)

# Note the reversed order of access between SimpleITK and numpy (z,y,x)
physical_points = [
    edges.TransformIndexToPhysicalPoint([int(x), int(y), int(z)])
    for z, y, x in zip(edge_indexes[0], edge_indexes[1], edge_indexes[2])
]

# Setup and solve linear equation system.
A = np.ones((len(physical_points), 4))
b = np.zeros(len(physical_points))

for row, point in enumerate(physical_points):
    A[row, 0:3] = -2 * np.array(point)
    b[row] = -linalg.norm(point) ** 2

res, _, _, _ = linalg.lstsq(A, b)

print("The sphere's location is: {0:.2f}, {1:.2f}, {2:.2f}".format(*res[0:3]))
print(f"The sphere's radius is: {np.sqrt(linalg.norm(res[0:3])**2 - res[3]):.2f}mm")

# Visually evaluate the results of edge detection, just to make sure. Note that because SimpleITK is working in the
# physical world (not pixels, but mm) we can easily transfer the edges localized in the cropped image to the original.
# Use the zoom tool, second from the right, for close inspection of the edge locations.

edge_label = sitk.Image(spherical_fiducials_image.GetSize(), sitk.sitkUInt16)
edge_label.CopyInformation(spherical_fiducials_image)
e_label = 255
for point in physical_points:
    edge_label[edge_label.TransformPhysicalPointToIndex(point)] = e_label

gui.MultiImageDisplay(
    image_list=[
        sitk.LabelOverlay(
            sitk.Cast(
                sitk.IntensityWindowing(
                    spherical_fiducials_image,
                    windowMinimum=-32767,
                    windowMaximum=-29611,
                ),
                sitk.sitkUInt8,
            ),
            edge_label,
            opacity=0.5,
        )
    ],
    title_list=["edge detection result"],
);


I am working on the file "Python/33_Segmentation_Thresholding_Edge_Detection.ipynb".
The first task is:
Load the volume, it contains two spheres. You can either identify the regions of interest (ROIs) yourself or use the predefined rectangular regions of interest specified below ((min_x,max_x), (min_y, max_y), (min_z, max_z)).
To evaluate the sensitivity of the algorithms to the image content (varying size and shape of the ROI) you should identify the ROIs yourself.
Can you write Python code for it?


I am working on the file "Python/33_Segmentation_Thresholding_Edge_Detection.ipynb".
The first task is:
Thresholding based approach
To see whether this approach is appropriate we look at the histogram of intensity values inside the ROI. We know that the spheres have higher intensity values. Ideally we would have a bimodal distribution with clear separation between the sphere and background.
Can you write Python code for it?

intensity_values = sitk.GetArrayViewFromImage(spherical_fiducials_image)
roi_intensity_values = intensity_values[
    roi[2][0] : roi[2][1], roi[1][0] : roi[1][1], roi[0][0] : roi[0][1]
].flatten()
plt.figure()
plt.hist(roi_intensity_values, bins=100)
plt.title("Intensity Values in ROI")
plt.show()


I am working on the file "Python/33_Segmentation_Thresholding_Edge_Detection.ipynb".
The first task is:
We use a GUI to specify a region of interest. The GUI below allows you to specify a box shaped ROI. Draw a rectangle on the image (move and resize it) and specify the z range of the box using the range slider. You can then view the ROI overlaid onto the slices using the slice slider. The toolbar on the bottom of the figure allows you to zoom and pan. In zoom/pan mode the rectangle interaction is disabled. Once you exit zoom/pan mode (click the button again) you can specify a rectangle and interact with it.
We already specify two ROIs containing the two spheres found in the data (second row below).
To evaluate the sensitivity of the two approaches used in this notebook you should select the ROI on your own and see how the different sizes effect the results.
Can you write Python code for it?


I am working on the file "Python/34_Segmentation_Evaluation.ipynb".
The first task is:
Derive a reference
There are a variety of ways to derive a reference segmentation from multiple expert inputs. Several options, there are more, are described in "A comparison of ground truth estimation methods", A. M. Biancardi, A. C. Jirapatnakul, A. P. Reeves.
Two methods that are available in SimpleITK are majority vote and the STAPLE algorithm.
Can you write Python code for it?

# Use majority voting to obtain the reference segmentation. Note that this filter does not resolve ties. In case of
# ties, it will assign max_label_value+1 or a user specified label value (labelForUndecidedPixels) to the result.
# Before using the results of this filter you will have to check whether there were ties and modify the results to
# resolve the ties in a manner that makes sense for your task. The filter implicitly accommodates multiple labels.
labelForUndecidedPixels = 10
reference_segmentation_majority_vote = sitk.LabelVoting(
    segmentations, labelForUndecidedPixels
)

manual_plus_majority_vote = list(segmentations)
# Append the reference segmentation to the list of manual segmentations
manual_plus_majority_vote.append(reference_segmentation_majority_vote)

interact(
    display_with_overlay,
    segmentation_number=(0, len(manual_plus_majority_vote) - 1),
    slice_number=(0, image.GetSize()[1] - 1),
    image=fixed(image),
    segs=fixed(manual_plus_majority_vote),
    window_min=fixed(-1024),
    window_max=fixed(976),
);

# Use the STAPLE algorithm to obtain the reference segmentation. This implementation of the original algorithm
# combines a single label from multiple segmentations, the label is user specified. The result of the
# filter is the voxel's probability of belonging to the foreground. We then have to threshold the result to obtain
# a reference binary segmentation.
foregroundValue = 1
threshold = 0.95
reference_segmentation_STAPLE_probabilities = sitk.STAPLE(
    segmentations, foregroundValue
)
# We use the overloaded operator to perform thresholding, another option is to use the BinaryThreshold function.
reference_segmentation_STAPLE = reference_segmentation_STAPLE_probabilities > threshold

manual_plus_staple = list(segmentations)
# Append the reference segmentation to the list of manual segmentations
manual_plus_staple.append(reference_segmentation_STAPLE)

interact(
    display_with_overlay,
    segmentation_number=(0, len(manual_plus_staple) - 1),
    slice_number=(0,...


I am working on the file "Python/34_Segmentation_Evaluation.ipynb".
The first task is:
Evaluate segmentations using the reference
Once we derive a reference from our experts input we can compare segmentation results to it.
Note that in this notebook we compare the expert segmentations to the reference derived from them. This is not relevant for algorithm evaluation, but it can potentially be used to rank your experts.
In this specific implementation we take advantage of the fact that we have a binary segmentation with 1 for foreground and 0 for background.
Can you write Python code for it?

from enum import Enum

# Use enumerations to represent the various evaluation measures
class OverlapMeasures(Enum):
    jaccard, dice, volume_similarity, false_negative, false_positive = range(5)

class SurfaceDistanceMeasures(Enum):
    (
        hausdorff_distance,
        mean_surface_distance,
        median_surface_distance,
        std_surface_distance,
        max_surface_distance,
    ) = range(5)

# Select which reference we want to use (majority vote or STAPLE)
reference_segmentation = reference_segmentation_STAPLE

# Empty numpy arrays to hold the results
overlap_results = np.zeros(
    (len(segmentations), len(OverlapMeasures.__members__.items()))
)
surface_distance_results = np.zeros(
    (len(segmentations), len(SurfaceDistanceMeasures.__members__.items()))
)

# Compute the evaluation criteria

# Note that for the overlap measures filter, because we are dealing with a single label we
# use the combined, all labels, evaluation measures without passing a specific label to the methods.
overlap_measures_filter = sitk.LabelOverlapMeasuresImageFilter()

hausdorff_distance_filter = sitk.HausdorffDistanceImageFilter()

reference_surface = sitk.LabelContour(reference_segmentation)
# Use the absolute values of the distance map to compute the surface distances (distance map sign, outside or inside
# relationship, is irrelevant)
reference_distance_map = sitk.Abs(
    sitk.SignedMaurerDistanceMap(
        reference_surface, squaredDistance=False, useImageSpacing=True
    )
)

statistics_image_filter = sitk.StatisticsImageFilter()
# Get the number of pixels in the reference surface by counting all pixels that are 1.
statistics_image_filter.Execute(reference_surface)
num_reference_surface_pixels = int(statistics_image_filter.GetSum())

for i, seg in enumerate(segmentations):
    # Overlap measures
    overlap_measures_filter.Execute(seg, reference_segmentation)
    overlap_results[
        i, OverlapMeasures.jaccard.value
    ] = overlap_measures_filter.GetJaccardCoefficient()
    overlap_results[
        i,...


I am working on the file "Python/34_Segmentation_Evaluation.ipynb".
The first task is:
Improved output
If the pandas package is installed in your Python environment then you can easily produce high quality output.
Can you write Python code for it?

import pandas as pd
from IPython.display import display, HTML

# Graft our results matrix into pandas data frames
overlap_results_df = pd.DataFrame(
    data=overlap_results,
    index=list(range(len(segmentations))),
    columns=[name for name, _ in OverlapMeasures.__members__.items()],
)
surface_distance_results_df = pd.DataFrame(
    data=surface_distance_results,
    index=list(range(len(segmentations))),
    columns=[name for name, _ in SurfaceDistanceMeasures.__members__.items()],
)

# Display the data as HTML tables and graphs
display(HTML(overlap_results_df.to_html(float_format=lambda x: "%.3f" % x)))
display(HTML(surface_distance_results_df.to_html(float_format=lambda x: "%.3f" % x)))
overlap_results_df.plot(kind="bar").legend(bbox_to_anchor=(1.6, 0.9))
surface_distance_results_df.plot(kind="bar").legend(bbox_to_anchor=(1.6, 0.9))


I am working on the file "Python/34_Segmentation_Evaluation.ipynb".
The first task is:
Segmentation Representation and the Hausdorff Distance
The results of segmentation can be represented as a set of closed contours/surfaces or as the discrete set of points (pixels/voxels) belonging to the segmented objects. Ideally using either representation would yield the same values for the segmentation evaluation metrics. Unfortunately, the Hausdorff distance computed directly from each of these representations will generally not yield the same results. In some cases, such as the one above, the two values do match (table entries hausdorff_distance and max_surface_distance).
The following example illustrates that the Hausdorff distance for the contour/surface representation and the discrete point set representing the segmented object differ, and that there is no correlation between the two.
Our object of interest is annulus shaped (e.g. myocardium in short axis MRI). It has an internal radius, $r$, and an external radius $R>r$. We over-segmented the object and obtained a filled circle of radius $R$.
The contour/surface based Hausdorff distance is $R-r$, the distance between external contours is zero and between internal and external contours is $R-r$. The pixel/voxel object based Hausdorff distance is $r$, corresponding to the distance between the center point in the over-segmented result to the inner circle contour. For different values of $r$ we can either have $R-r \geq r$ or $R-r \leq r$.
Note: Both computations of Hausdorff distance are valid, though the common approach is to use the pixel/voxel based representation for computing the Hausdorff distance.
The following cells show these differences in detail.
Can you write Python code for it?

# Create our segmentations and display
image_size = [64, 64]
circle_center = [30, 30]
circle_radius = [20, 20]

# A filled circle with radius R
seg = (
    sitk.GaussianSource(sitk.sitkUInt8, image_size, circle_radius, circle_center) > 200
)
# A torus with inner radius r
reference_segmentation1 = seg - (
    sitk.GaussianSource(sitk.sitkUInt8, image_size, circle_radius, circle_center) > 240
)
# A torus with inner radius r_2<r
reference_segmentation2 = seg - (
    sitk.GaussianSource(sitk.sitkUInt8, image_size, circle_radius, circle_center) > 250
)

gui.multi_image_display2D(
    [reference_segmentation1, reference_segmentation2, seg],
    ["reference 1", "reference 2", "segmentation"],
    figure_size=(12, 4),
);

def surface_hausdorff_distance(reference_segmentation, seg):
    """
    Compute symmetric surface distances and take the maximum.
    """
    reference_surface = sitk.LabelContour(reference_segmentation)
    reference_distance_map = sitk.Abs(
        sitk.SignedMaurerDistanceMap(
            reference_surface, squaredDistance=False, useImageSpacing=True
        )
    )

    statistics_image_filter = sitk.StatisticsImageFilter()
    # Get the number of pixels in the reference surface by counting all pixels that are 1.
    statistics_image_filter.Execute(reference_surface)
    num_reference_surface_pixels = int(statistics_image_filter.GetSum())

    segmented_surface = sitk.LabelContour(seg)
    segmented_distance_map = sitk.Abs(
        sitk.SignedMaurerDistanceMap(
            segmented_surface, squaredDistance=False, useImageSpacing=True
        )
    )

    # Multiply the binary surface segmentations with the distance maps. The resulting distance
    # maps contain non-zero values only on the surface (they can also contain zero on the surface)
    seg2ref_distance_map = reference_distance_map * sitk.Cast(
        segmented_surface, sitk.sitkFloat32
    )
    ref2seg_distance_map = segmented_distance_map * sitk.Cast(
        reference_surface, sitk.sitkFloat32
    )

    # Get the number of pixels...


I am working on the file "Python/34_Segmentation_Evaluation.ipynb".
The first task is:
You can also export the data as a table for your LaTeX manuscript using the to_latex function.
<b>Note</b>: You will need to add the \usepackage{booktabs} to your LaTeX document's preamble.
To create the minimal LaTeX document which will allow you to see the difference between the tables below, copy paste:
\documentclass{article}
\usepackage{booktabs}
\begin{document}
paste the tables here
\end{document}
Can you write Python code for it?

# The formatting of the table using the default settings is less than ideal
print(overlap_results_df.to_latex())

# We can improve on this by specifying the table's column format and the float format
print(
    overlap_results_df.to_latex(
        column_format="ccccccc", float_format=lambda x: "%.3f" % x
    )
)


I am working on the file "Python/35_Segmentation_Shape_Analysis.ipynb".
The first task is:
After the morphological operations, our binary image seems to have a reasonable number of objects, but is this true? We next look at the unique objects defined by this binary segmentation (each object is marked with a unique color).
Can you write Python code for it?

gui.MultiImageDisplay(
    image_list=[sitk.LabelOverlay(img, sitk.ConnectedComponent(cleaned_thresh_img))],
    title_list=["Cleaned Binary Segmentation"],
    figure_size=(8, 4),
);


I am working on the file "Python/35_Segmentation_Shape_Analysis.ipynb".
The first task is:
Create a plot to investigate the relationship, possible correlations, between volume and object shape characteristics (elongation, flatness, principal moments).
Can you write Python code for it?

fig, axes = plt.subplots(nrows=len(cols), ncols=2, figsize=(6, 4 * len(cols)))
axes[0, 0].axis("off")

stats.loc[:, cols[0]].plot.hist(ax=axes[0, 1], bins=25)
axes[0, 1].set_xlabel(cols[0])
axes[0, 1].xaxis.set_label_position("top")

for i in range(1, len(cols)):
    c = cols[i]
    bar = stats.loc[:, [c]].plot.hist(
        ax=axes[i, 0], bins=20, orientation="horizontal", legend=False
    )
    bar.set_ylabel(stats.loc[:, [c]].columns.values[0])
    scatter = stats.plot.scatter(ax=axes[i, 1], y=c, x=cols[0])
    scatter.set_ylabel("")
    # Remove axis labels from all plots except the last (they all share the labels)
    if i < len(cols) - 1:
        bar.set_xlabel("")
        scatter.set_xlabel("")
# Adjust the spacing between plot columns and set the plots to have a tight
# layout inside the figure.
plt.subplots_adjust(wspace=0.4)
plt.tight_layout()


I am working on the file "Python/35_Segmentation_Shape_Analysis.ipynb".
The first task is:
Finally, we visualize a lineup of the bacteria using a coordinate system that is defined by the oriented bounding box enclosing each of them.
Can you write Python code for it?

bacteria_labels = shape_stats.GetLabels()
bacteria_volumes = [shape_stats.GetPhysicalSize(label) for label in bacteria_labels]
num_images = 5  # number of bacteria images we want to display

bacteria_labels_volume_sorted = [
    label for _, label in sorted(zip(bacteria_volumes, bacteria_labels))
]

resampler = sitk.ResampleImageFilter()
aligned_image_spacing = [10, 10, 10]  # in nanometers

for label in bacteria_labels_volume_sorted[0:num_images]:
    aligned_image_size = [
        int(
            ceil(
                shape_stats.GetOrientedBoundingBoxSize(label)[i]
                / aligned_image_spacing[i]
            )
        )
        for i in range(3)
    ]
    direction_mat = shape_stats.GetOrientedBoundingBoxDirection(label)
    aligned_image_direction = [
        direction_mat[0],
        direction_mat[3],
        direction_mat[6],
        direction_mat[1],
        direction_mat[4],
        direction_mat[7],
        direction_mat[2],
        direction_mat[5],
        direction_mat[8],
    ]
    resampler.SetOutputDirection(aligned_image_direction)
    resampler.SetOutputOrigin(shape_stats.GetOrientedBoundingBoxOrigin(label))
    resampler.SetOutputSpacing(aligned_image_spacing)
    resampler.SetSize(aligned_image_size)

    obb_img = resampler.Execute(img)
    # Change the image axes order so that we have a nice display.
    obb_img = sitk.PermuteAxes(obb_img, [2, 1, 0])
    gui.MultiImageDisplay(image_list=[obb_img], title_list=[f"OBB_{label}"])


I am working on the file "Python/35_Segmentation_Shape_Analysis.ipynb".
The first task is:
Insert the values into a pandas dataframe and display some descriptive statistics.
Can you write Python code for it?

stats_list = [
    (
        shape_stats.GetPhysicalSize(i),
        shape_stats.GetElongation(i),
        shape_stats.GetFlatness(i),
        shape_stats.GetOrientedBoundingBoxSize(i)[0],
        shape_stats.GetOrientedBoundingBoxSize(i)[2],
        intensity_stats.GetMean(i),
        intensity_stats.GetStandardDeviation(i),
        intensity_stats.GetSkewness(i),
    )
    for i in shape_stats.GetLabels()
]
cols = [
    "Volume (nm^3)",
    "Elongation",
    "Flatness",
    "Oriented Bounding Box Minimum Size(nm)",
    "Oriented Bounding Box Maximum Size(nm)",
    "Intensity Mean",
    "Intensity Standard Deviation",
    "Intensity Skewness",
]

# Create the pandas data frame and display descriptive statistics.
stats = pd.DataFrame(data=stats_list, index=shape_stats.GetLabels(), columns=cols)
stats.describe()


I am working on the file "Python/35_Segmentation_Shape_Analysis.ipynb".
The first task is:
Load data
Load the 3D volume and display it.
Can you write Python code for it?

img = sitk.ReadImage(fdata("fib_sem_bacillus_subtilis.mha"))
gui.MultiImageDisplay(image_list=[img], figure_size=(8, 4));


I am working on the file "Python/35_Segmentation_Shape_Analysis.ipynb".
The first task is:
Mark each potential bacterium with unique label and evaluate
Can you write Python code for it?

stats = sitk.LabelShapeStatisticsImageFilter()
stats.Execute(sitk.ConnectedComponent(thresh_img))

# Look at the distribution of sizes of connected components (bacteria).
label_sizes = [stats.GetNumberOfPixels(l) for l in stats.GetLabels() if l != 1]

plt.figure()
plt.hist(label_sizes, bins=200)
plt.title("Distribution of Object Sizes")
plt.xlabel("size in pixels")
plt.ylabel("number of objects")
plt.show()