I am working on the file "Python/1 Search/N-Queens-Frame.ipynb".
The first task is:
The 8-Queens Puzzle
We represent solutions to the 8-queens puzzle as tuples of the form
$$ (r_0, \cdots, r_7), $$
where $r_i$ is the row of the queen in column $i$.  We start counting from $0$ because this is the way it is done in Python.
In general, states are defined as tuples of the form
$$ s = (r_0, \cdots, r_{c-1}). $$
In the state $s$, there are $c$ queens on the board.
The state start is the empty tuple.
Can you write Python code for it?


I am working on the file "Python/1 Search/N-Queens-Frame.ipynb".
The first task is:
The function next_states takes a tuple $S$ representing a state
and tries to extend this tuple by placing an additional queen on the board.  It returns the set of all such states that do not lead to a conflict.  It might be easier if you make use of an auxiliary function in order to implement the function next_states.
Can you write Python code for it?

def next_states(S):
    "your code here"


I am working on the file "Python/1 Search/N-Queens-Frame.ipynb".
The first task is:
The global variable Solutions is a list that collect all solutions to the 8-Queens puzzle.
Can you write Python code for it?


I am working on the file "Python/1 Search/N-Queens-Frame.ipynb".
The first task is:
This function takes a state, which is represented as tuple of integers and displays it as a chess board with n queens
Can you write Python code for it?

from IPython.core.display import display

def display_state(state):
    board = chess.Board(None)  # create empty chess board
    queen = chess.Piece(chess.QUEEN, True)
    for col in range(len(state)):
        row = state[col]
        field_number = row * 8 + col
        board.set_piece_at(field_number, queen)
    display(board)

# Print the first solution
display_state(Solutions[0])


I am working on the file "Python/1 Search/N-Queens-Frame.ipynb".
The first task is:
Visualization
The following code assumes that you have installed python-chess.  After activating the appropriate
Python environment, this can be done using the following command:
pip install python-chess
Can you write Python code for it?


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
Animation
The package ipycanvas, which is imported below, can be installed using the following command:
conda install -c conda-forge ipycanvas
This package is useful for drawings and animations.  Its documentation can be found at:
  https://ipycanvas.readthedocs.io/en/latest/.
Can you write Python code for it?


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
Below is an instance of the $4 \times 4$ puzzle that can be solved in 36 steps.
Can you write Python code for it?


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
Below, we have defined the start state, which is the state shown in the figure above on the left.
Can you write Python code for it?


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
For informed search we need to implement a
heuristic that estimates to distance between two states.
The function manhattan implemented below takes as argument two states of the sliding puzzle and computes the Manhattan distance between these states.
Basically, the manhattan distance measure the number of moves that it would take to transform stateA into stateB if we were allowed to slide different tiles on top of each other.
Can you write Python code for it?

def manhattan(stateA, stateB):
    n = len(stateA)
    PositionsB = {}
    for row in range(n):
        for col in range(n):
            tile = stateB[row][col]
            PositionsB[tile] = (row, col)
    result = 0
    for rowA in range(n):
        for colA in range(n):
            tile = stateA[rowA][colA]
            if tile != 0:
                rowB, colB = PositionsB[tile]
                result += abs(rowA - rowB) + abs(colA - colB)
    return result

manhattan(start, goal)


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
Given a State of the sliding puzzle, the function next_states(State) computes all those states that can be reached from State in one step.
Can you write Python code for it?

def next_states(State):
    n          = len(State)
    row, col   = find_tile(0, State)
    New_States = set()
    Directions = [ (1, 0), (-1, 0), (0, 1), (0, -1) ]
    for dx, dy in Directions:
        if row + dx in range(n) and col + dy in range(n):
            New_States.add(move_dir(State, row, col, dx, dy))
    return New_States


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
Given a State that satisfies
State[row][col] == 0
and a direction (dx, dy) that is an element from the set
$\bigl{ (1, 0), (-1, 0), (0, 1), (0, -1) \bigr}$,
the function move_dir moves the empty tile in the direction (dx, dy).
Can you write Python code for it?

def move_dir(State, row, col, dx, dy):
    State = to_list(State)
    State[row     ][col     ] = State[row + dx][col + dy]
    State[row + dx][col + dy] = 0
    return to_tuple(State)


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
Given a list of states representing a solution to the sliding puzzle, the function call
animation(Solution) animates the solution.
Can you write Python code for it?

def animation(Solution):
    start = Solution[0]
    n = len(start)
    canvas = create_canvas(n)
    draw(start, canvas, 0, 0, 0, 0)
    m = len(Solution)
    display(canvas)
    for i in range(m-1):
        state = Solution[i]
        tile, dx, dy = tile_and_direction(state, Solution[i+1])
        for offset in range(size+1):
            draw(state, canvas, dx, dy, tile, offset)
            time.sleep(delay)


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
The function draw(State, canvas, dx, dy, tile, x) draws a given State of the sliding puzzle, where tile has been moved by offset pixels into the direction (dx, dy).
Can you write Python code for it?

def draw(State, canvas, dx, dy, tile, offset):
    canvas.text_align    = 'center'
    canvas.text_baseline = 'middle'
    with cnv.hold_canvas(canvas):
        canvas.clear()
        n = len(State)
        for row in range(n):
            for col in range(n):
                tile_to_draw = State[row][col]
                color = Colors[tile_to_draw]
                canvas.fill_style = color
                if tile_to_draw not in (0, tile):
                    x = col * size
                    y = row * size
                    canvas.fill_rect(x, y, size, size)
                    canvas.line_width = 3.0
                    x += size // 2
                    y += size // 2
                    canvas.stroke_text(str(tile_to_draw), x, y)
                elif tile_to_draw == tile:
                    x = col * size + offset * dx
                    y = row * size + offset * dy
                    canvas.fill_rect(x, y, size, size)
                    canvas.line_width = 3.0
                    x += size // 2
                    y += size // 2
                    if tile_to_draw != 0:
                        canvas.stroke_text(str(tile_to_draw), x, y)

def create_canvas(n):
    canvas = cnv.Canvas(size=(size * n, size * n))
    canvas.font = '100px serif'
    return canvas


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
The global variable Colors specifies the colors of the tiles.
Can you write Python code for it?

Colors = ['white', 'lightblue', 'pink', 'magenta', 'orange', 'red', 'yellow', 'lightgreen', 'gold',
          'CornFlowerBlue', 'Coral', 'Cyan', 'orchid', 'DarkSalmon', 'DeepPink', 'green'
         ]


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
The global variable delay controls the speed of the animation.
Can you write Python code for it?


I am working on the file "Python/1 Search/Sliding-Puzzle.ipynb".
The first task is:
The global variable size specifies the size of one tile in pixels.
Can you write Python code for it?


I am working on the file "Python/1 Search/Sphere-Search.ipynb".
The first task is:
Display Code
Below, we ensure that we only import graphviz if this notebook is not loaded from another notebook.  This works by checking that the variable file is not set.
Can you write Python code for it?

try:
    __file__
except NameError:
    import graphviz as gv


I am working on the file "Python/1 Search/Sphere-Search.ipynb".
The first task is:
Given a state and a parent dictionary Parent, the function path_to returns a path leading to the given state.
Can you write Python code for it?

def path_to(state, Parent):
    p = Parent[state]
    if p == state:
        return [state]
    return path_to(p, Parent) + [state]


I am working on the file "Python/1 Search/Sphere-Search.ipynb".
The first task is:
In the figures shown below, the nodes in the set Visited are colored blue, while the nodes in the set Frontier are colored red.
Can you write Python code for it?

try:
    __file__
except NameError:
    main(9)


I am working on the file "Python/1 Search/Sphere-Search.ipynb".
The first task is:
Sphere Search
Can you write Python code for it?

def search(start, goal, next_states):
    if goal == start:
        return [start]
    previous = basic_search(start, goal, next_states)
    if previous:
        return search(start, previous, next_states) + [goal]

def basic_search(start, goal, next_states):
    Frontier = { start }
    Visited  = set()
    while Frontier:
        NewFrontier = set()
        for s in Frontier:
            for ns in next_states(s):
                if ns not in Visited and ns not in Frontier:
                    NewFrontier.add(ns)
                    if ns == goal:
                        return s
        Visited  = Frontier
        Frontier = NewFrontier
        print(len(Visited))


I am working on the file "Python/1 Search/Sphere-Search.ipynb".
The first task is:
Testing
Can you write Python code for it?

def next_states_test(node):
    x, y = node
    return { (x+1, y), (x, y+1) }

def create_edges(n):
    Edges = {}
    for row in range(n):
        for col in range(n):
            if (row, col) != (n-1, n-1):
                Edges[(row, col)] = list(next_states_test((row, col)))
    for k in range(n-1):
        Edges[(k, n-1)] = [(k+1, n-1)]
        Edges[(n-1, k)] = [(n-1, k+1)]
    return Edges

def search_show(start, goal, next_states, Edges):
    Visited  = set()
    Frontier = { start }
    Parent   = { start: start }
    while len(Frontier) > 0:
        display(toDot(start, goal, Edges, Frontier, Visited))
        NewFrontier = set()
        Visited    |= Frontier
        for s in Frontier:
            for ns in next_states(s):
                if not (ns in Visited):
                    NewFrontier.add(ns)
                    Parent[ns] = s
                    if ns == goal:
                        display(toDot(start, goal, Edges, NewFrontier, Visited, Parent))
                        return
        Frontier = NewFrontier

def main(n):
    Edges = create_edges(n)
    search_show((0,0), (n-1,n-1), next_states_test, Edges)


I am working on the file "Python/1 Search/Sphere-Search.ipynb".
The first task is:
The function $\texttt{toDot}(\texttt{source}, \texttt{Edges}, \texttt{Fringe}, \texttt{Visited})$ takes a graph that is represented by
its Edges, a set of nodes Fringe, and set Visited of nodes that have already been visited.
Can you write Python code for it?

def toDot(source, goal, Edges, Frontier, Visited, Parent=None):
    V = set()
    for x, L in Edges.items():
        V.add(x)
        for y in L:
            V.add(y)
    dot = gv.Digraph(node_attr={'shape': 'record', 'style': 'rounded'})
    dot.attr(rankdir='LR', size='8,5')
    for x in V:
        if x == source:
            dot.node(str(x), color='blue', shape='doublecircle')
        elif x in Frontier and x == goal:
            dot.node(str(x), label=str(x), color='magenta')
        elif x in Frontier:
            dot.node(str(x), label=str(x), color='red')
        elif x in Visited:
            dot.node(str(x), label=str(x), color='blue')
        else:
            dot.node(str(x), label=str(x))
    if Parent:
        Path = path_to(goal, Parent)
    for u in V:
        if Edges.get(u):
            for v in Edges[u]:
                if Parent and v in Path and Parent[v] == u:
                    dot.edge(str(u), str(v), color='brown', style='bold')
                else:
                    dot.edge(str(u), str(v))
    return dot


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Again, we solve the resulting search problem and remember the actions that transformed Start2 into Goal2.  We apply these actions to the state State and end up with State being transformed into the state shown below.
Can you write Python code for it?


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Given a State of the sliding puzzle, the function next_states(State) computes all those states that can be reached from State in one step.
Can you write Python code for it?

def next_states(State):
    n          = len(State)
    row, col   = find_tile('0', State)
    NewStates  = set()
    Directions = [ (1, 0), (-1, 0), (0, 1), (0, -1) ]
    for dx, dy in Directions:
        if row + dy in range(n) and col + dx in range(n):
            NewStates.add(move_dir(State, row, col, dx, dy))
    return NewStates


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Given a State that satisfies
State[row][col] == '0'
and a direction (dx, dy) that is an element from the set
$\bigl{ (1, 0), (-1, 0), (0, 1), (0, -1) \bigr}$,
the function move_dir moves the empty tile in the direction (dx, dy).
Can you write Python code for it?

def move_dir(State, row, col, dx, dy):
    State = to_list(State)
    State[row     ][col     ] = State[row + dy][col + dx]
    State[row + dy][col + dx] = '0'
    return to_tuple(State)


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Given a list of extended states PatternList of the form
$$ \texttt{PatternList} = [P_1, P_2, \cdots, P_n] $$
the function extract_move_list computes a list of actions $[a_1, a_2, \cdots, a_{n-1}]$ such that
applying action $(a_i)$ to state $P_i$ results in state $P_{i+1}$.
The actions are pairs of the form (dx, dy) that specify how the empty tile is to be moved.
Can you write Python code for it?

def extract_move_list(PatternList):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Given the list of actions MoveList of the form $[a_1, a_2, \cdots, a_{n-1}]$, the function
apply_move_list takes a state State and applies these action to State one by one.  The list of all
states produced this way is returned.  This list starts with the given state State.
Can you write Python code for it?

def apply_move_list(State, MoveList):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Given two extended states Pattern1 and Pattern2 the function extract_move returns a pair (dx, dy) such that we have:
(row, col) = find_tile('0', Pattern1) -> move_dir(Pattern1, row, col, dx, dy) == Pattern2
Hence extract_move(Pattern1, Pattern2) computes the action that is necessary to transform Pattern1 into
Pattern2.  This action is encoded as a direction (dx, dy).  This is the direction to move the empty tile in Pattern1 to reach Pattern2.
Can you write Python code for it?

def extract_move(Pattern1, Pattern2):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
In order to view these states more conveniently, we define a number of auxiliary functions in the following subsection.
Animation
Can you write Python code for it?


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Our next goal is to move the tiles numbered with 12 and 13 into their final position.  To this end we define the
extended states Start2 and Goal2 as shown below.
Can you write Python code for it?


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Proceeding in this way we can solve the given instance of the 15-puzzle.  The solution that we find will not be optimal, but it won't be too far from the optimal solution.
Auxiliary Functions for the Sliding Puzzle
The function call find_tile(tile, State) finds the coordinates of the given tile in State.  The tile is represented as a string from the set
{'0', '1', ..., '15'},
where '0' represents the empty tile.
Nota bene:
We have to represent the tiles as strings instead of numbers as we will later replace some of these tiles by the wildcard
character '*'.  The class Set that we use to represent sets of states does not permit inhomogeneous sets, i.e. sets that
contain both numbers and strings.
The parameter State is a tuple of tuples that specifies the positions of the tiles.  If (row, col) is the result returned by find_tile, then we have:
State[row][col] == tile
Can you write Python code for it?

def find_tile(tile, State):
    n = len(State)
    for row in range(n):
        for col in range(n):
            if State[row][col] == tile:
                return row, col


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Putting It All Together
Let's draw the start state and animate the solution that has been found.
Can you write Python code for it?

def main():
    TilesList   = [['14', '15'],
                   ['12', '13'],
                   ['10', '11'],
                   [ '8',  '9'],
                   [ '3',  '7'],
                   [ '2',  '6'],
                   ['0', '1', '4', '5']
                  ]
    PatternList = intermediate_goals(Goal, TilesList)
    State       = Start
    Solution    = []
    print('Start state:')
    draw_state(Start)
    for Pattern in PatternList:
        print('Trying to reach the following pattern:')
        draw_state(Pattern)
        Tiles = find_tiles(Pattern)
        ExtendedState = replace_numbers(State, Tiles + ['0'])
        Path = search(ExtendedState, Pattern, next_states, manhattan)
        MoveList = extract_move_list(Path)
        Path = apply_move_list(State, MoveList)
        print(f'The following state is reached after {len(Path)-1} steps:');
        State = Path[-1]
        draw_state(State)
        Solution += Path[:-1]
    Solution += [ Goal ]
    return Solution

%%time
Path = main()
print(len(Path)-1)

animation(Path)

def shorten(Solution):
    shorterSolution = []
    k = 0
    while k < len(Solution) - 1:
        shorterSolution.append(Solution[k])
        if k + 2 < len(Solution) and Solution[k] == Solution[k + 2]:
            k += 3
        else:
            k += 1
    shorterSolution += [Solution[-1]]
    return shorterSolution

animation(shorten(Path))

len(shorten(Path))-1


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Taoistc Search: Detailed Explanation
Let us begin by our explanation by drawing both the states Start and Goal of our search problem.
Can you write Python code for it?


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
Taoistic Search
The holy book of Taoism, the Tao Te Ching, contains the following wisdom:

        A yourney of a thousand miles begins but with a single step.

Taoistic search is based on this principle:
- Split the search problem into subproblems that can be readily solved.
- Solve these problems one by one.
- Combine the solutions of the subproblems to a solution of the given search problem.
We will use taoistic search to solve the search problem for the 15-puzzle where the states Start and Goal are defined
as follows.
Can you write Python code for it?


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function call tile_and_direction(state, next_state) takes a state and the state that follows this state and returns a triple (tile, dx, dy) where tile is the tile that is moved to transform state into next_state and (dx, dy) is the direction in which this tile is moved.
Can you write Python code for it?

def tile_and_direction(state, next_state):
    row0, col0 = find_tile('0', state)
    row1, col1 = find_tile('0', next_state)
    return state[row1][col1], col0-col1, row0-row1


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function draw(State, canvas, dx, dy, tile, x) draws a given State of the sliding puzzle, where tile has been moved by offset pixels into the direction (dx, dy).
Can you write Python code for it?

def draw(State, canvas, dx, dy, tile, offset):
    canvas.text_align    = 'center'
    canvas.text_baseline = 'middle'
    with cnv.hold_canvas(canvas):
        canvas.clear()
        n = len(State)
        for row in range(n):
            for col in range(n):
                tile_to_draw = State[row][col]
                if tile_to_draw != '*':
                    color = Colors[int(tile_to_draw)]
                else:
                    color = 'lightyellow'
                canvas.fill_style = color
                if tile_to_draw not in ('0', tile):
                    x = col * size
                    y = row * size
                    canvas.fill_rect(x, y, size, size)
                    canvas.stroke_rect(x, y, size, size)
                    canvas.line_width = 3.0
                    x += size // 2
                    y += size // 2
                    canvas.stroke_text(str(tile_to_draw), x, y)
                elif tile_to_draw == tile:
                    x = col * size + offset * dx
                    y = row * size + offset * dy
                    canvas.fill_rect(x, y, size, size)
                    canvas.stroke_rect(x, y, size, size)
                    canvas.line_width = 3.0
                    x += size // 2
                    y += size // 2
                    if tile_to_draw != 0:
                        canvas.stroke_text(str(tile_to_draw), x, y)

def create_canvas(n):
    canvas = cnv.Canvas(size=(size * n, size * n))
    canvas.font = '60px serif'
    return canvas

def draw_state(State):
    n = len(State)
    canvas = create_canvas(n)
    draw(State, canvas, 0, 0, '+', 0)
    display(canvas)


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function find_tiles takes a pattern Pattern as input and returns the
list of all tiles in Pattern that are labeled with a number.
Can you write Python code for it?

def find_tiles(Pattern):
    Result = []
    n = len(Pattern)
    for row in range(n):
        for col in range(n):
            tile = Pattern[row][col]
            if tile != '*':
                Result.append(tile)
    return Result


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function intermediate_goals is called with two parameters:
- Goal is a state of the 15-puzzle,
- TilesList is a list of list of numbers.
   For example, TilesList could be the list [ [14, 15], [12, 13] ].
   This list would specify that we want to create two intermediate
   goals.
   - The first goal would only have the tiles numbered 14 and 15,
     while all other tiles would be replaced by wildcards.
   - The second goal would only have the tiles numbered 12, 13, 14,
     and 15, while all other tiles would be replaced by wildcards.
The function returns the list of intermediate goals.
Can you write Python code for it?

def intermediate_goals(Goal, TilesList):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function manhattan implemented below takes as argument two extended states State1 and State2
possibly containing wildcards and computes the Manhattan distance between these
extended states. Basically, the manhattan distance measure the number of moves that it would take to transform stateA into stateB if we were allowed to slide different tiles on top of each other.
When computing these distances,  tiles that are numbered with a wildcard are ignored.
Can you write Python code for it?

def manhattan(State1, State2):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function matches(Pattern, State) checks, whether the pattern Pattern matches the state State.  A pattern is like a state but instead of numbers, some entries of the list of lists have the form '*'.  The idea is that the string '*' is a wildcard that matches anything.
Note that State can also be an extended state.
Can you write Python code for it?

def matches(Pattern, State):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function replace_numbers takes two arguments:
- Pattern is an extended state,
- Tiles is a list of numbered tiles.
The state Pattern is transformed by replacing all tiles that are not a member of the list Tiles
with the wildcard character *.
Can you write Python code for it?

def replace_numbers(Pattern, Tiles):
    "your code here"


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The function stateToString is useful for debugging purposes to transform a given state into a string.
Can you write Python code for it?

def stateToString(state):
    n      = len(state)
    indent = " " * 4;
    line   = indent + "+---" * n + "+\n"
    result = line
    for row in range(n):
        result += indent + "|"
        for col in range(n):
            cell = state[row][col]
            if isinstance(cell, str) and cell != '*':
                cell = int(cell)
            if cell == "*":
                result += " * "
            elif cell >= 10:
                result += str(cell) + " "
            elif cell > 0 and cell < 10:
                result += " " + str(cell) + " "
            else:
                result += "   "
            result += "|"
        result += "\n"
        result += line
    return result


I am working on the file "Python/1 Search/Taoistic-Search-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/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The global variable Colors specifies the colors of the tiles.
Can you write Python code for it?

Colors = ['white', 'lightblue', 'pink', 'magenta', 'orange', 'red', 'yellow', 'lightgreen', 'gold',
          'CornFlowerBlue', 'Coral', 'Cyan', 'orchid', 'DarkSalmon', 'DeepPink', 'green'
         ]


I am working on the file "Python/1 Search/Taoistic-Search-Frame.ipynb".
The first task is:
The global variable size specifies the size of one tile in pixels.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
10. Select the rows where the age is missing, i.e. is NaN.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
12. Select the rows the age is between 2 and 4 (inclusive).
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
13. Change the age in row 'f' to 1.5.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
16. Append a new row 'k' to df with your choice of values for each column. Then delete that row to return the original DataFrame.
Can you write Python code for it?

df.loc['k'] = [5.5, 'dog', 'no', 2]

# and then deleting the new row...

df = df.drop('k')


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
19. The 'priority' column contains the values 'yes' and 'no'. Replace this column with a column of boolean values: 'yes' should be True and 'no' should be False.
Can you write Python code for it?

df['priority'] = df['priority'].map({'yes': True, 'no': False})


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
2. Print the version of pandas that has been imported.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
20. In the 'animal' column, change the 'snake' entries to 'python'.
Can you write Python code for it?

df['animal'] = df['animal'].replace('snake', 'python')


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
21. For each animal type and each number of visits, find the mean age. In other words, each row is an animal, each column is a number of visits and the values are the mean ages (hint: use a pivot table).
Can you write Python code for it?

df.pivot_table(index='animal', columns='visits', values='age', aggfunc='mean')


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
25. How do you count how many unique rows a DataFrame has (i.e. ignore all rows that are duplicates)?
Can you write Python code for it?

len(df) - df.duplicated(keep=False).sum()

# or perhaps more simply...

len(df.drop_duplicates(keep=False))


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
27. A DataFrame has a column of groups 'grps' and and column of numbers 'vals'. For example:
python
df = pd.DataFrame({'grps': list('aaabbcaabcccbbc'),
                   'vals': [12,345,3,1,45,14,4,52,54,23,235,21,57,3,87]})
For each group, find the sum of the three greatest values.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
30. Consider a DataFrame containing rows and columns of purely numerical data. Create a list of the row-column index locations of the 3 largest values.
Can you write Python code for it?

df.unstack().sort_values()[-3:].index.tolist()

# http://stackoverflow.com/questions/14941261/index-and-column-for-the-max-value-in-pandas-dataframe/
# credit: DSM


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
31. Given a DataFrame with a column of group IDs, 'grps', and a column of corresponding integer values, 'vals', replace any negative values in 'vals' with the group mean.
Can you write Python code for it?

def replace(group):
    mask = group<0
    group[mask] = group[~mask].mean()
    return group

df.groupby(['grps'])['vals'].transform(replace)

# http://stackoverflow.com/questions/14760757/replacing-values-with-groupby-means/
# credit: unutbu


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
34. Find the sum of the values in s for every Wednesday.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
36. For each group of four consecutive calendar months in s, find the date on which the highest value occurred.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
37. Create a DateTimeIndex consisting of the third Thursday in each month for the years 2015 and 2016.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
39. The From_To column would be better as two separate columns! Split each string on the underscore delimiter _ to give a new temporary DataFrame with the correct values. Assign the correct column names to this temporary DataFrame.
Can you write Python code for it?

temp = df.From_To.str.split('_', expand=True)
temp.columns = ['From', 'To']


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
40. Notice how the capitalisation of the city names is all mixed up in this temporary DataFrame. Standardise the strings so that only the first letter is uppercase (e.g. "londON" should become "London".)
Can you write Python code for it?

temp['From'] = temp['From'].str.capitalize()
temp['To'] = temp['To'].str.capitalize()


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
41. Delete the From_To column from df and attach the temporary DataFrame from the previous questions.
Can you write Python code for it?

df = df.drop('From_To', axis=1)
df = df.join(temp)


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
42. In the Airline column, you can see some extra puctuation and symbols have appeared around the airline names. Pull out just the airline name. E.g. '(British Airways. )' should become 'British Airways'.
Can you write Python code for it?

df['Airline'] = df['Airline'].str.extract('([a-zA-Z\s]+)', expand=False).str.strip()
# note: using .strip() gets rid of any leading/trailing spaces


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
45. Check the index of s is lexicographically sorted (this is a necessary proprty for indexing to work correctly with a MultiIndex).
Can you write Python code for it?

s.index.is_lexsorted()

# or more verbosely...
s.index.lexsort_depth == s.index.nlevels


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
46. Select the labels 1, 3 and 6 from the second level of the MultiIndexed Series.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
48. Sum the values in s for each label in the first level (you should have Series giving you a total for labels A, B and C).
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
5. Display a summary of the basic information about this DataFrame and its data.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
52. For this DataFrame df, create a new column of zeros (safe) and ones (mine). The probability of a mine occuring at each location should be 0.4.
Can you write Python code for it?

# One way is to draw samples from a binomial distribution.

df['mine'] = np.random.binomial(1, 0.4, X*Y)


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
53. Now create a new column for this DataFrame called 'adjacent'. This column should contain the number of mines found on adjacent squares in the grid.
(E.g. for the first row, which is the entry for the coordinate (0, 0), count how many mines are found on the coordinates (0, 1), (1, 0) and (1, 1).)
Can you write Python code for it?

# Here is one way to solve using merges.
# It's not necessary the optimal way, just
# the solution I thought of first...

df['adjacent'] = \
    df.merge(df + [ 1,  1, 0], on=['x', 'y'], how='left')\
      .merge(df + [ 1, -1, 0], on=['x', 'y'], how='left')\
      .merge(df + [-1,  1, 0], on=['x', 'y'], how='left')\
      .merge(df + [-1, -1, 0], on=['x', 'y'], how='left')\
      .merge(df + [ 1,  0, 0], on=['x', 'y'], how='left')\
      .merge(df + [-1,  0, 0], on=['x', 'y'], how='left')\
      .merge(df + [ 0,  1, 0], on=['x', 'y'], how='left')\
      .merge(df + [ 0, -1, 0], on=['x', 'y'], how='left')\
       .iloc[:, 3:]\
        .sum(axis=1)

# An alternative solution is to pivot the DataFrame
# to form the "actual" grid of mines and use convolution.
# See https://github.com/jakevdp/matplotlib_pydata2013/blob/master/examples/minesweeper.py

from scipy.signal import convolve2d

mine_grid = df.pivot_table(columns='x', index='y', values='mine')
counts = convolve2d(mine_grid.astype(complex), np.ones((3, 3)), mode='same').real.astype(int)
df['adjacent'] = (counts - mine_grid).ravel('F')


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
54. For rows of the DataFrame that contain a mine, set the value in the 'adjacent' column to NaN.
Can you write Python code for it?

df.loc[df['mine'] == 1, 'adjacent'] = np.nan


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
58.  What if we want to plot multiple things?  Pandas allows you to pass in a matplotlib Axis object for plots, and plots will also return an Axis object.
Make a bar plot of monthly revenue with a line plot of monthly advertising spending (numbers in millions)
df = pd.DataFrame({"revenue":[57,68,63,71,72,90,80,62,59,51,47,52],
                   "advertising":[2.1,1.9,2.7,3.0,3.6,3.2,2.7,2.4,1.8,1.6,1.3,1.9],
                   "month":range(12)
                  })
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
60. Now that you have your properly-formatted data, try to plot it yourself as a candlestick chart.  Use the plot_candlestick(df) function above, or matplotlib's plot documentation if you get stuck.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
7. Select just the 'animal' and 'age' columns from the DataFrame df.
Can you write Python code for it?

df.loc[:, ['animal', 'age']]

# or

df[['animal', 'age']]


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
8. Select the data in rows [3, 4, 8] and in columns ['animal', 'age'].
Can you write Python code for it?

df.loc[df.index[[3, 4, 8]], ['animal', 'age']]


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
9. Select only the rows where the number of visits is greater than 3.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
And another approach using a groupby:
Can you write Python code for it?

df['Y'] = df.groupby((df['X'] == 0).cumsum()).cumcount()
# We're off by one before we reach the first zero.
first_zero_idx = (df['X'] == 0).idxmax()
df['Y'].iloc[0:first_zero_idx] += 1


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
Cleaning Data
Making a DataFrame easier to work with
Difficulty: easy/medium
It happens all the time: someone gives you data containing malformed strings, Python, lists and missing data. How do you tidy it up so you can get on with the analysis?
Take this monstrosity as the DataFrame to use in the following puzzles:
python
df = pd.DataFrame({'From_To': ['LoNDon_paris', 'MAdrid_miLAN', 'londON_StockhOlm',
                               'Budapest_PaRis', 'Brussels_londOn'],
              'FlightNumber': [10045, np.nan, 10065, np.nan, 10085],
              'RecentDelays': [[23, 47], [], [24, 43, 87], [13], [67, 32]],
                   'Airline': ['KLM(!)', '<Air France> (12)', '(British Airways. )',
                               '12. Air France', '"Swiss Air"']})
(It's some flight data I made up; it's not meant to be accurate in any way.)
38. Some values in the the FlightNumber column are missing. These numbers are meant to increase by 10 with each row so 10055 and 10075 need to be put in place. Fill in these missing numbers and make the column an integer column (instead of a float column).
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
DataFrame basics
A few of the fundamental routines for selecting, sorting, adding and aggregating data in DataFrames
Difficulty: easy
Note: remember to import numpy using:
python
import numpy as np
Consider the following Python dictionary data and Python list labels:
``` python
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
        'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
        'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
        'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
```
(This is just some meaningless data I made up with the theme of animals and trips to a vet.)
4. Create a DataFrame df from this dictionary data which has the index labels.
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
DataFrames: beyond the basics
Slightly trickier: you may need to combine two or more methods to get the right answer
Difficulty: medium
The previous section was tour through some basic but essential DataFrame operations. Below are some ways that you might need to cut your data, but for which there is no single "out of the box" method.
22. You have a DataFrame df with a column 'A' of integers. For example:
python
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})
How do you filter out rows which contain the same integer as the row immediately above?
Can you write Python code for it?


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
Minesweeper
Generate the numbers for safe squares in a Minesweeper grid
Difficulty: medium to hard
If you've ever used an older version of Windows, there's a good chance you've played with [Minesweeper](https://en.wikipedia.org/wiki/Minesweeper_(video_game). If you're not familiar with the game, imagine a grid of squares: some of these squares conceal a mine. If you click on a mine, you lose instantly. If you click on a safe square, you reveal a number telling you how many mines are found in the squares that are immediately adjacent. The aim of the game is to uncover all squares in the grid that do not contain a mine.
In this section, we'll make a DataFrame that contains the necessary data for a game of Minesweeper: coordinates of the squares, whether the square contains a mine and the number of mines found on adjacent squares.
51. Let's suppose we're playing Minesweeper on a 5 by 4 grid, i.e.
X = 5
Y = 4
To begin, generate a DataFrame df with two columns, 'x' and 'y' containing every coordinate for this grid. That is, the DataFrame should start:
x  y
0  0  0
1  0  1
2  0  2
Can you write Python code for it?

p = pd.tools.util.cartesian_product([np.arange(X), np.arange(Y)])
df = pd.DataFrame(np.asarray(p).T, columns=['x', 'y'])


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
Now we're finally ready to create a candlestick chart, which is a very common tool used to analyze stock price data.  A candlestick chart shows the opening, closing, highest, and lowest price for a stock during a time window.  The color of the "candle" (the thick part of the bar) is green if the stock closed above its opening price, or red if below.

This was initially designed to be a pandas plotting challenge, but it just so happens that this type of plot is just not feasible using pandas' methods.  If you are unfamiliar with matplotlib, we have provided a function that will plot the chart for you so long as you can use pandas to get the data into the correct format.
Your first step should be to get the data in the correct format using pandas' time-series grouping function.  We would like each candle to represent an hour's worth of data.  You can write your own aggregation function which returns the open/high/low/close, but pandas has a built-in which also does this.
The below cell contains helper functions.  Call day_stock_data() to generate a DataFrame containing the prices a hypothetical stock sold for, and the time the sale occurred.  Call plot_candlestick(df) on your properly aggregated and formatted stock data to print the candlestick chart.
Can you write Python code for it?

#This function is designed to create semi-interesting random stock price data

import numpy as np
def float_to_time(x):
    return str(int(x)) + ":" + str(int(x%1 * 60)).zfill(2) + ":" + str(int(x*60 % 1 * 60)).zfill(2)

def day_stock_data():
    #NYSE is open from 9:30 to 4:00
    time = 9.5
    price = 100
    results = [(float_to_time(time), price)]
    while time < 16:
        elapsed = np.random.exponential(.001)
        time += elapsed
        if time > 16:
            break
        price_diff = np.random.uniform(.999, 1.001)
        price *= price_diff
        results.append((float_to_time(time), price))

    df = pd.DataFrame(results, columns = ['time','price'])
    df.time = pd.to_datetime(df.time)
    return df

def plot_candlestick(agg):
    fig, ax = plt.subplots()
    for time in agg.index:
        ax.plot([time.hour] * 2, agg.loc[time, ["high","low"]].values, color = "black")
        ax.plot([time.hour] * 2, agg.loc[time, ["open","close"]].values, color = agg.loc[time, "color"], linewidth = 10)

    ax.set_xlim((8,16))
    ax.set_ylabel("Price")
    ax.set_xlabel("Hour")
    ax.set_title("OHLC of Stock Value During Trading Day")
    plt.show()


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
Plotting
Visualize trends and patterns in data
Difficulty: medium
To really get a good understanding of the data contained in your DataFrame, it is often essential to create plots: if you're lucky, trends and anomalies will jump right out at you. This functionality is baked into pandas and the puzzles below explore some of what's possible with the library.
56. Pandas is highly integrated with the plotting library matplotlib, and makes plotting DataFrames very user-friendly! Plotting in a notebook environment usually makes use of the following boilerplate:
python
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
matplotlib is the plotting library which pandas' plotting functionality is built upon, and it is usually aliased to plt.
%matplotlib inline tells the notebook to show plots inline, instead of creating them in a separate window.
plt.style.use('ggplot') is a style theme that most people find agreeable, based upon the styling of R's ggplot package.
For starters, make a scatter plot of this random data, but use black X's instead of the default markers.
df = pd.DataFrame({"xs":[1,5,2,8,1], "ys":[4,2,1,9,6]})
Consult the documentation if you get stuck!
Can you write Python code for it?

import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')

df = pd.DataFrame({"xs":[1,5,2,8,1], "ys":[4,2,1,9,6]})

df.plot.scatter("xs", "ys", color = "black", marker = "x")


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
Series and DatetimeIndex
Exercises for creating and manipulating Series with datetime data
Difficulty: easy/medium
pandas is fantastic for working with dates and times. These puzzles explore some of this functionality.
33. Create a DatetimeIndex that contains each business day of 2015 and use it to index a Series of random numbers. Let's call this Series s.
Can you write Python code for it?

dti = pd.date_range(start='2015-01-01', end='2015-12-31', freq='B')
s = pd.Series(np.random.rand(len(dti)), index=dti)


I am working on the file "Python/100-pandas-puzzles-with-solutions.ipynb".
The first task is:
The next three puzzles are slightly harder...
26. You have a DataFrame that consists of 10 columns of floating--point numbers. Suppose that exactly 5 entries in each row are NaN values. For each row of the DataFrame, find the column which contains the third NaN value.
(You should return a Series of column labels.)
Can you write Python code for it?


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
Most filters which take multiple images as arguments require that the images occupy the same physical space. That is the pixel you are operating must refer to the same location. Luckily for us our image and labels do occupy the same physical space, allowing us to overlay the segmentation onto the original image.
Can you write Python code for it?

myshow(sitk.LabelOverlay(img1, img1_seg), title="Label Overlayed")


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
This image does not appear bigger.
There are numerous improvements that we can make:

support 3d images
include a title
use physical pixel size for axis labels
show the image as gray values
Can you write Python code for it?

def myshow(img, title=None, margin=0.05, dpi=80):
    nda = sitk.GetArrayViewFromImage(img)
    spacing = img.GetSpacing()

    if nda.ndim == 3:
        # fastest dim, either component or x
        c = nda.shape[-1]

        # the the number of components is 3 or 4 consider it an RGB image
        if not c in (3, 4):
            nda = nda[nda.shape[0] // 2, :, :]

    elif nda.ndim == 4:
        c = nda.shape[-1]

        if not c in (3, 4):
            raise Runtime("Unable to show 3D-vector Image")

        # take a z-slice
        nda = nda[nda.shape[0] // 2, :, :, :]

    ysize = nda.shape[0]
    xsize = nda.shape[1]

    # Make a figure big enough to accommodate an axis of xpixels by ypixels
    # as well as the ticklabels, etc...
    figsize = (1 + margin) * ysize / dpi, (1 + margin) * xsize / dpi

    fig = plt.figure(figsize=figsize, dpi=dpi)
    # Make the axis the right size...
    ax = fig.add_axes([margin, margin, 1 - 2 * margin, 1 - 2 * margin])

    extent = (0, xsize * spacing[1], ysize * spacing[0], 0)

    t = ax.imshow(nda, extent=extent, interpolation=None)

    if nda.ndim == 2:
        t.set_cmap("gray")

    if title:
        plt.title(title)

myshow(sitk.Expand(img2, [2, 2]), title="Big Visibile Human Head")


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
Tips and Tricks for 3D Image Visualization
Now lets move on to visualizing real MRI images with segmentations. The Surgical Planning Laboratory at Brigham and Women's Hospital provides a wonderful Multi-modality MRI-based Atlas of the Brain that we can use.
Please note, what is done here is for convenience and is not the common way images are displayed for radiological work.
Can you write Python code for it?

img_T1 = sitk.ReadImage(fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT1.nrrd"))
img_T2 = sitk.ReadImage(fdata("nac-hncma-atlas2013-Slicer4Version/Data/A1_grayT2.nrrd"))
img_labels = sitk.ReadImage(
    fdata("nac-hncma-atlas2013-Slicer4Version/Data/hncma-atlas.nrrd")
)

myshow(img_T1)
myshow(img_T2)
myshow(sitk.LabelToRGB(img_labels))

size = img_T1.GetSize()
myshow(img_T1[:, size[1] // 2, :])

slices = [
    img_T1[size[0] // 2, :, :],
    img_T1[:, size[1] // 2, :],
    img_T1[:, :, size[2] // 2],
]
myshow(sitk.Tile(slices, [3, 1]), dpi=20)

nslices = 5
slices = [img_T1[:, :, s] for s in range(0, size[2], size[0] // (nslices + 1))]
myshow(sitk.Tile(slices, [1, 0]))


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
Tips and Tricks for Visualizing Segmentations
We start by loading a segmented image. As the segmentation is just an image with integral data, we can display the labels as we would any other image.
Can you write Python code for it?

img1_seg = sitk.ReadImage(fdata("2th_cthead1.png"))
myshow(img1_seg, "Label Image as Grayscale")


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
Two ways to solve our problem: (1) resample the labels onto the image grid (2) resample the image onto the label grid. The difference between the two from a computation standpoint depends on the grid sizes and on the interpolator used to estimate values at non-grid locations.
Note interpolating a label image with an interpolator that can generate non-label values is problematic as you may end up with an image that has more classes/labels than your original. This is why we only use the nearest neighbor interpolator when working with label images.
Can you write Python code for it?

# Option 1: Resample the label image using the identity transformation
resampled_img_labels = sitk.Resample(
    img_labels,
    img_T1,
    sitk.Transform(),
    sitk.sitkNearestNeighbor,
    0.0,
    img_labels.GetPixelID(),
)
# Overlay onto the T1 image, requires us to rescale the intensity of the T1 image to [0,255] and cast it so that it can
# be combined with the color overlay (we use an alpha blending of 0.5).
myshow3d(
    sitk.LabelOverlay(
        sitk.Cast(sitk.RescaleIntensity(img_T1), sitk.sitkUInt8),
        resampled_img_labels,
        0.5,
    ),
    yslices=range(50, size[1] - 50, 20),
    zslices=range(50, size[2] - 50, 20),
    dpi=30,
)

# Option 2: Resample the T1 image using the identity transformation
resampled_T1 = sitk.Resample(
    img_T1, img_labels, sitk.Transform(), sitk.sitkLinear, 0.0, img_T1.GetPixelID()
)
# Overlay onto the T1 image, requires us to rescale the intensity of the T1 image to [0,255] and cast it so that it can
# be combined with the color overlay (we use an alpha blending of 0.5).
myshow3d(
    sitk.LabelOverlay(
        sitk.Cast(sitk.RescaleIntensity(resampled_T1), sitk.sitkUInt8), img_labels, 0.5
    ),
    yslices=range(50, size[1] - 50, 20),
    zslices=range(50, size[2] - 50, 20),
    dpi=30,
)


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
We can also map the scalar label image to a color image as shown below.
Can you write Python code for it?

myshow(sitk.LabelToRGB(img1_seg), title="Label Image as RGB")


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
We can also overlay the labels as contours.
Can you write Python code for it?


I am working on the file "Python/10_matplotlibs_imshow.ipynb".
The first task is:
We next visualize the T1 image with an overlay of the labels.
Can you write Python code for it?

# Why doesn't this work? The images do overlap in physical space.
myshow3d(
    sitk.LabelOverlay(img_T1, img_labels),
    yslices=range(50, size[1] - 50, 20),
    zslices=range(50, size[2] - 50, 20),
    dpi=30,
)


I am working on the file "Python/11_Energy.ipynb".
The first task is:
A more sophisticated approach
As can be seen from the figure above, a large difference in wind speed can occur between the top and the bottom of the rotor plane, and therefore a more realistic approach might give different results.
The wind speed is a function of altitude. The area of the rotor plane can also be expressed as a function of altitude, namely by integrating the width of the rotor plane with respect to $z$:
$$
A = \int_{h-r}^{h+r} 2x(z) dz
$$
Here, $h$ is the hub height of the wind turbine, $r$ is the rotor radius, and $x(z)$ is the horizontal distance from the edges of the rotor plane to the vertical axis. An expression for $x(z)$ is given below:
$$
x(z) = \sqrt{r^2-(z-h)^2}
$$
If $z-h$ becomes larger than $r$ in the formula above, then the square root will not have real solutions. Thus, $x(z)$ is only defined in the rotor plane and it is set to 0 at all other altitudes. To find the estimated wind power, we evaluate the following summation:
$$
\sum_z \rho x(z)u(z)^3 \Delta z
$$
Can you write Python code for it?

# Vertical levels
dz = 1
z = np.arange(0,300+dz,dz)+dz

# Turbine characteristics
r = 75 # rotor radius
h = 100 # hub height
x = np.where(np.abs(z-h)<r,np.sqrt(r**2-(z-h)**2),0) # the error is only due to the construction of `np.where`

# Logprofile
ust = 0.25
u = logprofile(z,ust)+np.random.normal(0,.1,len(z))

# Energy
rho = 1.2
es = sum(u**3*x)*rho*dz*1e-6 #sophisticated method
eb = .5 * rho * np.pi * r**2 * u[h]**3 / 1e6 #basic method

print 'Wind power with basic formula: %.2f MW'%eb
print 'Wind power with sophicsticated formula: %.2f MW'%es
print 'Difference: %.2f MW'%(es-eb)


I am working on the file "Python/11_Energy.ipynb".
The first task is:
A simple uncertainty analysis
Below I will create 10000 randomly disturbed wind profiles, and perform the two power calculations for all these wind profiles. With this, I can make an estimate of the uncertainty in the power calculation that results from the uncertainty in the wind. Moreover, by comparing the two power estimates, I can compute some statistics on the error that is introduced by neglecting the vertical variability of the wind.
Can you write Python code for it?

# Vertical levels
dz = 1
z = np.arange(0,300+dz,dz)+dz

# Turbine characteristics
r = 75 # rotor radius
h = 100 # hub height
x = np.where(np.abs(z-h)<r,np.sqrt(r**2-(z-h)**2),0) # the error is only due to the construction of `np.where`

# Store the output in these lists:
output_basic = []
output_sophisticated = []

# Perform 10000 load calculations
for i in range(10000):
    # Logprofile
    ust = 0.25
    u = logprofile(z,ust)+np.random.normal(0,.1,len(z))

    # Energy
    rho = 1.2
    es = sum(u**3*x)*rho*dz*1e-6
    output_sophisticated.append(es)

    eb = .5 * rho * np.pi * r**2 * u[h]**3 / 1e6
    output_basic.append(eb)

# Some statistics
output_sophisticated = np.asarray(output_sophisticated)
print 'Sophisticated method:'
print 'Mean power: %.2f MW'%output_sophisticated.mean()
print 'Standard deviation: %.4f MW'%output_sophisticated.std()

output_basic = np.asarray(output_basic)
print '\nBasic method:'
print 'Mean power: %.2f MW'%output_basic.mean()
print 'Standard deviation: %.4f MW'%output_basic.std()

errors = output_basic-output_sophisticated
print '\nError statistics:'
print 'Mean absolute error: %.2f MW'%(np.mean(np.abs(errors)))
print 'Root mean squar error: %.2f MW' %(np.sqrt(np.mean(errors*errors)))


I am working on the file "Python/11_Progress.ipynb".
The first task is:
A Reusable class for IPython Progress
There currently are too many caveats without support for Abort. Let us create a reusable class which will automatically generate the UUID and just display the progress.
Can you write Python code for it?

import uuid
from IPython.display import HTML, Javascript, display

class HTMLProgressWatcher:
    def __init__(self, po):
        self.processObject = po
        self.abort = False

        po.AddCommand(sitk.sitkStartEvent, lambda: self.cmdStartEvent())
        po.AddCommand(sitk.sitkProgressEvent, lambda: self.cmdProgressEvent())
        po.AddCommand(sitk.sitkEndEvent, lambda: self.cmdEndEvent())

    def cmdStartEvent(self):
        global sitkIPythonProgress_UUID
        self.abort = False
        self.divid = str(uuid.uuid4())

        try:
            sitkIPythonProgress_UUID[self.divid] = self
        except NameError:
            sitkIPythonProgress_UUID = {self.divid: self}

        html_progress_abort = f"""

{self.processObject.GetName()}:

"""

        display(HTML(html_progress_abort + javascript_abort))

    def cmdProgressEvent(self):
        p = self.processObject.GetProgress()
        display(Javascript("$('div#%s').width('%i%%')" % (self.divid, int(p * 100))))
        if self.abort:
            self.processObject.Abort()

    def cmdEndEvent(self):
        global sitkIPythonProgress_UUID
        del sitkIPythonProgress_UUID[self.divid]
        del self.divid

filter.RemoveAllCommands()
watcher = HTMLProgressWatcher(filter)

filter.Execute()

?threading.Thread.start


I am working on the file "Python/11_Progress.ipynb".
The first task is:
A reference to the Command object must be maintained, or else it will be removed from the ProcessObject.
Can you write Python code for it?

filter.AddCommand(sitk.sitkStartEvent, MyCommand("stack scope"))
print("Before Execution")
filter.Execute()


I am working on the file "Python/11_Progress.ipynb".
The first task is:
Deriving from the Command class
The traditional way of using Commands in ITK involves deriving from the Command class and adding to the ProcessObject.
Can you write Python code for it?

class MyCommand(sitk.Command):
    def __init__(self, msg):
        # required
        super(MyCommand, self).__init__()
        self.msg = msg

    def __del__(self):
        print(f'MyCommand begin deleted: "{self.msg}"')

    def Execute(self):
        print(self.msg)

cmd1 = MyCommand("Start")
cmd2 = MyCommand("End")
filter.RemoveAllCommands()  # this line is here so we can easily re-execute this code block
filter.AddCommand(sitk.sitkStartEvent, cmd1)
filter.AddCommand(sitk.sitkEndEvent, cmd2)
filter.Execute()


I am working on the file "Python/11_Progress.ipynb".
The first task is:
Support for Bi-direction JavaScript
It's possible to get button in HTML to execute python code...
Can you write Python code for it?

import uuid
from IPython.display import HTML, Javascript, display

g_Abort = False
divid = str(uuid.uuid4())

html_progress_abort = f"""

FilterName:

<button onclick="set_value()" style="margin:5px" >Abort</button>

"""

javascript_abort = """

"""

def command_js_progress_abort(processObject):
    p = processObject.GetProgress()
    display(Javascript("$('div#%s').width('%i%%')" % (divid, int(p * 100))))
    if g_Abort:
        processObject.Abort()

def command_js_start_abort():
    g_Abort = False

g_Abort = False
filter.RemoveAllCommands()
filter.AddCommand(sitk.sitkStartEvent, command_js_start_abort)
filter.AddCommand(
    sitk.sitkStartEvent, lambda: display(HTML(html_progress_abort + javascript_abort))
)
filter.AddCommand(sitk.sitkProgressEvent, lambda: command_js_progress_abort(filter))


I am working on the file "Python/11_Progress.ipynb".
The first task is:
The ProcessObject interface for the Invoker or Subject
SimpleITK doesn't have a large heirachy of inheritance. It has been kept to a minimal, so there is no common Object or LightObject base class as ITK has. As most of the goals for the events have to do with observing processes, the "Subject" interface of the Observer patter or the "Invoker" part of the Command design pattern, has been added to a ProcessObject base class for filters.
The ProcessObject base class has the following methods of handling commands: AddCommand, RemoveAllCommands, and HasCommand.
Adding these functionalities are not available in the procedural interface available for SimpleITK. They are only available through the Object Oriented interface, and break the method chaining interface.
Can you write Python code for it?


I am working on the file "Python/11_Progress.ipynb".
The first task is:
Utilizing Jupyter Notebooks and Commands
Utilization of commands and events frequently occurs with advanced integration into graphical user interfaces. Let us now export this advanced integration into Jupyter Notebooks.
Jupyter notebooks support displaying output as HTML, and execution of javascript on demand. Together this can produce animation.
Can you write Python code for it?

import uuid
from IPython.display import HTML, Javascript, display

divid = str(uuid.uuid4())

html_progress = f"""

FilterName:

"""

def command_js_progress(processObject):
    p = processObject.GetProgress()
    display(Javascript("$('div#%s').width('%i%%')" % (divid, int(p * 100))))

filter.RemoveAllCommands()
filter.AddCommand(sitk.sitkStartEvent, lambda: display(HTML(html_progress)))
filter.AddCommand(sitk.sitkProgressEvent, lambda: command_js_progress(filter))

filter.Execute()


I am working on the file "Python/11_Progress.ipynb".
The first task is:
We need to add a command to display the progress reported by the ProcessObject::GetProgress method during the sitkProgressEvent. This involves three components:

Events
ProcessObject's methods
Commands

We'll look at some examples after a brief explanation of these components.
Events
The avaiable events to observed are defined in a namespace enumeration.

sitkAnyEvent	Occurs for all event types.

sitkAbortEvent	Occurs after the process has been aborted, but before exiting the Execute method.

sitkDeleteEvent	Occurs when the underlying itk::ProcessObject is deleted.

sitkEndEvent	Occurs at then end of normal processing.

sitkIterationEvent	Occurs with some algorithms that run for a fixed or undetermined number of iterations.

sitkProgressEvent	Occurs when the progress changes in most process objects.

sitkStartEvent	Occurs when then itk::ProcessObject is starting.

sitkUserEvent	Other events may fall into this enumeration.

The convention of pre-fixing enums with "sitk" is continued, although it's getting a little crowded.
C++ is more strongly typed than Python it allows for implicit conversion from an enum type to an int, but not from an int to an enum type. Care needs to be made to ensure the correct enum value is passed in Python.
ProcessObject's methods
To be able to interface with the ProcessObject during execution, the object-oriented interface must be used to access the method of the ProcessObject. While any constant member function can be called during a command call-back there are two common methods:

ProcessObject::GetProgress()
ProcessObject::Abort()

The methods are only valid during the Command while a process is being executed, or when the process is not in the Execute method.
Additionally it should be noted that follow methods can not be called during a command or from...
Can you write Python code for it?

help(sitk.Command)

class MyCommand(sitk.Command):
    def __init__(self):
        # required
        super(MyCommand, self).__init__()

    def Execute(self):
        print("MyCommand::Execute Called")

cmd = MyCommand()
cmd.Execute()

help(sitk.PyCommand)

cmd = sitk.PyCommand()
cmd.SetCallbackPyCallable(lambda: print("PyCommand Called"))
cmd.Execute()


I am working on the file "Python/11_Progress.ipynb".
The first task is:
While the lambda command are convenient, the lack for having an object to hold data can still be problematic. For example in the above code the uuid, is used to uniquely identify the HTML element. So if the filter is executed multiple times then the JavaScript update will be confused on what to update.
Can you write Python code for it?

#### The following shows a failure that you will want to avoid.
threading.Thread(target=lambda: filter.Execute()).start()


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Backtracking is simulated by raising the Backtrack exception.  We define this new class of exceptions so that we can distinguish Backtrack exceptions from ordinary exceptions.  This is done by creating a new, empty class that is derived from the class Exception.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Backtracking takes about $10$ seconds to solve the Zebra Puzzle.
We develop a better algorithm soon.
Can you write Python code for it?

%%time
Solution = solve(zebra)

show_solution(Solution)


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Below, dir(__builtins__) returns a list containing all predefined variables, functions, and classes.
Can you write Python code for it?

dir(__builtins__)

collect_variables('abs(x - y) + abs(z1 - z2)')


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Ensure that running times are reproducible.
Can you write Python code for it?

import os
os.environ['PYTHONHASHSEED'] = '0'


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Map Coloring
Can you write Python code for it?

%%capture
%run Map-Coloring.ipynb

P = map_coloring_csp()
P

Solution = solve(P, True)


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Solving the Cypto-Arithmetic Puzzle
Can you write Python code for it?

%run Crypto-Arithmetic.ipynb

csp = crypto_csp()
csp


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
Solving the Zebra Puzzle
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
The Backtracking Solver
The procedure solve(P) takes a constraint satisfaction problem
P as input.  Here P is a triple of the form
$$ \mathcal{P} = \langle \mathtt{Variables}, \mathtt{Values}, \mathtt{Constraints} \rangle $$
where
- Variables is a set of strings which serve as variables,
- Values is a set of values that can be assigned
  to the variables in the set Variables.
- Constraints is a set of formulas from first order logic.
  Each of these formulas is  called a constraint of $\mathcal{P}$.
The main purpose of the function solve is to convert the CSP P into an
augmented CSP where every constraint $f$ is annotated with
the variables ocurring in $f$.  This annotates CSP is then solved using the function
backtrack_search.
Can you write Python code for it?

def solve(P, debug=False):
    Variables, Values, Constraints = P
    csp = (Variables, Values, [(f, collect_variables(f)) for f in Constraints])
    try:
        return backtrack_search({}, csp, debug)
    except Backtrack:
        return None


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
The function backtrack_search takes two arguments:
- Assignment is a partial variable assignment that is represented as a dictionary.  Initially, this assignment will be the empty dictionary.  Every recursive call of backtrack_search adds the assignment of one variable to the given assignment.  The important invariant of recursive calls of backtrack_search is that Assignment is consistent, i.e. all constraints $f$ that contain only variables from the set $\mathtt{dom}(\mathtt{Assignment})$ are satisfied.
- P is an augmented constraint satisfaction problem,
   i.e. P is a triple of the form
   $$ \mathcal{P} = \langle \mathtt{Vars}, \mathtt{Values}, \mathtt{Constraints} \rangle $$
    where
    - $\mathtt{Vars}$ is a set of strings which serve as variables,
    - $\mathtt{Values}$ is a set of values that can be assigned
      to the variables in $\mathtt{Vars}$.
    - $\mathtt{Constraints}$ is a set of pairs of the form $(f, V)$ where $f$ is a Boolean Python
      expression, while $V$ is the set of variables occuring in $f$.
The function backtrack_search tries to find a solution of P by recursively augmenting Assignment.
Normally, the Variables stored in the CSP are represented as a set.  However, for didactical purposes it is also possible to store the variables as a list.  This way, the order in which variables are chosen can be controlled.
Can you write Python code for it?

def backtrack_search(Assignment, P, debug):
    if debug:
        print(Assignment)
    Variables, Values, Constraints = P
    if len(Assignment) == len(Variables):
        return Assignment
    if isinstance(Variables, set):
        var = arb(Variables - Assignment.keys())
    else: # below we choose the first unassigned variable
        var = [x for x in Variables if x not in Assignment][0]
    for value in Values:
        try:
            if is_consistent(var, value, Assignment, Constraints):
                NewAss = Assignment.copy()
                NewAss[var] = value
                return backtrack_search(NewAss, P, debug)
        except Backtrack:
            continue
    raise Backtrack()


I am working on the file "Python/2 Constraint Solver/Backtrack-Solver.ipynb".
The first task is:
The function collect_variables(expr) takes a string expr that can be interpreted as a Python expression as input and collects all variables occurring in expr.  It takes care to remove the function symbols from the names returned by extract_variables.
Can you write Python code for it?

def collect_variables(expression):
    tree = ast.parse(expression)
    return {node.id for node in ast.walk(tree)
                    if  isinstance(node, ast.Name)
                    if  node.id not in dir(__builtins__)
           }


I am working on the file "Python/2 Constraint Solver/Brute-Force-Solver.ipynb".
The first task is:
Brute Force CSP Solver
Utility Functions
The function arb(S) takes a set S as input and returns an arbitrary element from
this set.  The set S is not changed.
Can you write Python code for it?

def arb(S):
    for x in S:
        return x


I am working on the file "Python/2 Constraint Solver/Brute-Force-Solver.ipynb".
The first task is:
Brute force search takes about 30 seconds on my desktop to solve the eight queens puzzle.
Can you write Python code for it?

%%time
gCounter = 0
Solution = solve(P)
print(f'Solution = {Solution}')
gCounter

8 ** 8

show_solution(Solution)


I am working on the file "Python/2 Constraint Solver/Brute-Force-Solver.ipynb".
The first task is:
In the $8$ queens problem we have to test $8^8$ different assignments.  The $7$ queens problem only has $7^7$ assignments.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Brute-Force-Solver.ipynb".
The first task is:
N Queens Problem
The notebook N-Queens-Problem-CSP.ipynb provides the function
create_csp(n) that returns a CSP encoding the
n queens puzzle.
Can you write Python code for it?

%%capture
%run N-Queens-Problem-CSP.ipynb

P = create_csp(8)
P


I am working on the file "Python/2 Constraint Solver/Brute-Force-Solver.ipynb".
The first task is:
The procedure solve(P) takes a constraint satisfaction problem
P as input.  Here P is a triple of the form
$$ \mathcal{P} = \langle \mathtt{Vars}, \mathtt{Values}, \mathtt{Constraints} \rangle $$
where
- $\mathtt{Vars}$ is a set of strings which serve as variables,
- $\mathtt{Values}$ is a set of values that can be assigned
  to the variables in $\mathtt{Vars}$.
- $\mathtt{Constraints}$ is a set of formulas that are represented as Boolean expressions.
  Each of these formulas is  called a constraint of $\mathcal{P}$.
The sole purpose of the function solve is to call the function brute_force_search, which needs an additional argument.  This argument is a partial variable assignment that is initially empty.  Every recursive iteration of the function brute_force_search assigns one additional variable.
Can you write Python code for it?

gCounter = 0

def solve(P):
    return brute_force_search({}, P)


I am working on the file "Python/2 Constraint Solver/Brute-Force-Solver.ipynb".
The first task is:
Therefore, the time needed to solve the $7$ queens problem should be smaller by a factor of $\displaystyle\frac{8^8}{7^7}$:
Can you write Python code for it?

30 / (8**8 / 7**7)

P = create_csp(7)

%%time
gCounter = 0
Solution = solve(P)
print(f'Solution = {Solution}')
gCounter


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
A Constraint Propagation Solver with Consistency Maintenance
The procedure solve(P, check_consistency) takes two arguments:
* P is a constraint satisfaction problem
  Here P is a triple of the form
  $$ \mathcal{P} = \langle \mathtt{Variables}, \mathtt{Values}, \mathtt{Constraints} \rangle $$
  where
  - $\mathtt{Variables}$ is a set of strings which serve as variables,
  - $\mathtt{Values}$ is a set of values that can be assigned
    to the variables in the set $\mathtt{Variables}$.
  - $\mathtt{Constraints}$ is a set of formulas from first order logic.
    Each of these formulas is  called a constraint of $\mathcal{P}$.
* check_consistency is a Boolean flag.  If this flag is True, then consistency maintenance is used
  as a preprocessing step.
Before trying to solve the given CSP, solve checks whether the set of variables occurring in
the constraints is the same as the set Variables.  If this is not the case, then this is most likely due to
a spelling error and a warning message is printed.  Then, the function solve converts the CSP P into an augmented CSP where every constraint $f$ is annotated with the variables occurring in $f$.  Furthermore, the function solve maintains the following data structures:

VarsInConstrs is the set of all variables occurring in any constraint.
ValuesPerVar is a dictionary mapping variables to sets of values.  For every variable x occurring in a constraint of P, the expression ValuesPerVar[x] is the set of values that can be used to instantiate the variable x.  Initially, ValuesPerVar[x] is set to Values, but as the search for a solution proceeds, the sets ValuesPerVar[x] are reduced by removing any values that cannot be part of a solution.
Annotated is a dictionary.  For every constraint f we have that Annotated[f] is the set of all variables occurring in f.
UnaryConstrs is a set of pairs of the form (f, V) where f is a constraint containing only a single variable and V is the set containing just this variable.
OtherConstrs is a set of pairs of the form (f, V) where f is...
Can you write Python code for it?

def solve(P, check_consistency=True, lcv=False):
    Variables, Values, Constraints = P
    VarsInConstrs  = union([ collect_variables(f) for f in Constraints ])
    MisspelledVars = (VarsInConstrs - Variables) | (Variables - VarsInConstrs)
    if MisspelledVars:
        print("Did you misspell any of the following Variables?")
        for v in MisspelledVars:
            print(v)
    ValuesPerVar = { x: Values for x in Variables }
    Annotated    = { f: collect_variables(f) for f in Constraints }
    UnaryConstrs = { (f, V) for f, V in Annotated.items() if len(V) == 1 }
    OtherConstrs = { (f, V) for f, V in Annotated.items() if len(V) >= 2 }
    Connected    = {}
    Var2Formulas = variables_2_formulas(OtherConstrs)
    for x in Variables:
        Connected[x] = union([ V for f, V in Annotated.items() if x in V ]) - { x }
    try:
        for f, V in UnaryConstrs:
            var               = arb(V)
            ValuesPerVar[var] = solve_unary(f, var, ValuesPerVar[var])
        if check_consistency:
            enforce_consistency(ValuesPerVar, Var2Formulas, Annotated, Connected)
            for x, Values in ValuesPerVar.items():
                print(f'{x}: {Values}')
        return backtrack_search({}, ValuesPerVar, OtherConstrs, lcv)
    except Backtrack:
        return None


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
For the hard version of the crypto-arithmetic puzzle, consistency maintenance decreases the total running time considerably.
Can you write Python code for it?

%%time
Solution = solve(csp, check_consistency=False)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
Given a list of sets L, the function union(L) returns the set of all elements occurring in some set $S$ that is itself a member of the list L, i.e. we have
$$ \texttt{union}(L) = { x \mid \exists S \in L : x \in L }. $$
Can you write Python code for it?

def union(L):
    return { x for S in L
               for x in S
           }

union([ {1, 2}, {'a', 'b'}, {1, 'a'} ])


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
If we want to have reproducible results, the environment variable PYTHONHASHSEED has to be set to a fixed value, for example to 0.
Below we check that this environment is set so that results are reproducible.
In order to set this variable we have to use the following sequence of commands in the anaconda shell.
conda activate ai
conda env config vars set PYTHONHASHSEED=0
conda activate ai
It is necessary to reactivate the environment ai for the setting to take effect.
Consistency Checking
Utility Functions
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
Solving a Crypto-Arithmetic Puzzle
Can you write Python code for it?

%run Crypto-Arithmetic.ipynb

csp = crypto_csp()


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
Solving the Eight-Queens-Puzzle
Can you write Python code for it?

%%capture
%run N-Queens-Problem-CSP.ipynb

P = create_csp(8)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
Solving the Zebra Puzzle
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The consistency solver takes about 11 milliseconds to solve the zebra puzzle without consistency maintenance.
Can you write Python code for it?

%%time
Solution = solve(zebra, check_consistency=False)

show_solution(Solution)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The consistency solver takes about 23 milliseconds on my desktop to solve the eight queens puzzle.  Hence, for the eight queens puzzle, consistency maintenance does not help.
Can you write Python code for it?

%%time
Solution = solve(P, check_consistency=True)
Solution
print(f'Solution = {Solution}')

show_solution(Solution)

%%time
Solution = solve(P, check_consistency=False)
print(f'Solution = {Solution}')

P = create_csp(32)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function all_assignments returns the list of all possible assignments for the variables in the set Vars.
For every variable x, the values for x are taken from ValuesPerVar[x].
Can you write Python code for it?

def all_assignments(Variables, ValuesPerVar):
    if not Variables:
        return [ {} ]  # list containing empty assignment
    var         = Variables.pop()
    Values      = ValuesPerVar[var]
    Assignments = all_assignments(Variables, ValuesPerVar)
    return [ extend(A, var, val) for A in Assignments
                                 for val in ValuesPerVar[var]
           ]

ValuesPerVar = { 'x': {1, 2}, 'y': {2, 3} }
Variables    = { 'x', 'y' }
all_assignments(Variables, ValuesPerVar)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function arb(S) takes a set S as input and returns an arbitrary element from
this set.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function backtrack_search takes three arguments:
- Assignment is a partial variable assignment that is represented as a
   dictionary.  Initially, this assignment will be the  empty dictionary.
   Every recursive call of backtrack_search adds the assignment of one
   variable to  the given assignment.
- ValuesPerVar is a dictionary.  For every variable x, ValuesPerVar[x] is the set of values that still might be assigned to x.
- Constraints is a set of pairs of the form (f, V) where f is a constraint and V is the set of variables occurring in f.
The function backtrack_search uses the most constrained variable heuristic in order to choose the next variable.  It uses the least constraining value heuristic to choose the value that is assigned to this variable.
Can you write Python code for it?

def backtrack_search(Assignment, ValuesPerVar, Constraints, lcv):
    if len(Assignment) == len(ValuesPerVar):
        return Assignment
    x = most_constrained_variable(Assignment, ValuesPerVar)
    if lcv and len(ValuesPerVar[x]) > 1:
        ValueList = least_constraining(x, ValuesPerVar, Assignment, Constraints)
    else:
        ValueList = ValuesPerVar[x]
    for v in ValueList:
        try:
            NewValues = propagate(x, v, Assignment, Constraints, ValuesPerVar)
            NewAssign = Assignment.copy()
            NewAssign[x] = v
            return backtrack_search(NewAssign, NewValues, Constraints, lcv)
        except Backtrack:
            continue
    raise Backtrack()


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function collect_variables(expr) takes a string expr that can be interpreted as a Python expression as input and collects all variables occurring in expr.  It takes care to eliminate the function symbols from the names returned by extract_variables.
Can you write Python code for it?

def collect_variables(expression):
    tree      = ast.parse(expression)
    Variables = { node.id for node in ast.walk(tree)
                          if  isinstance(node, ast.Name)
                          if node.id not in dir(__builtins__)
                }
    return frozenset(Variables)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function enforce_consistency takes 4 arguments:
- ValuesPerVar is a dictionary.  For every variable x we have that ValuesPerVar[x] is the set of values that can be substituted for x.
- Var2Formulas is a dictionary.  For every variable x we have that Var2Formulas[x] is the set of those formulas that mention the variable x.
- Annotated is a dictionary.  For every constraint F, Annotated[F] is the set of variables occurring in F.
- Connected is a dictionary.  For every variable x we have that Connected[x] is the set of those variables y that are directly connected with the variable x.  Two variables x and y are directly connected if there is a constraint F such that both x and y occur in F.  In this case, F is connecting x and y.
The function enforce_consistency shrinks the sets ValuesPerVar[x] such that the values in ValuesPerVar[x] are consistent for x for all constraints.
Can you write Python code for it?

def enforce_consistency(ValuesPerVar, Var2Formulas, Annotated, Connected):
    UncheckedVars = set(Var2Formulas.keys())
    while UncheckedVars:
        variable    = UncheckedVars.pop()
        Constraints = Var2Formulas[variable]
        Values      = ValuesPerVar[variable]
        RemovedVals = set()
        for f in Constraints:
            OtherVars = Annotated[f] - { variable }
            for value in Values:
                if not exists_values(variable, value, f, OtherVars, ValuesPerVar):
                    RemovedVals   |= { value }
                    UncheckedVars |= Connected[variable]
        Remaining = Values - RemovedVals
        if not Remaining: # the problem is unsolvable
            raise Backtrack()
        ValuesPerVar[variable] = Remaining


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function least_constraining takes four arguments:
* x is a variable.
* ValuesPerVar is a dictionary.  For every variable var, ValuesPerVar[var] is the set of values that can be assigned to var.
* Assignment is a partial variable assignment.
* Constraints is a set of annotated constraints.
This function returns a list of values that can be substituted for the variable x.
This list is sorted so that the least constraining values are at the beginning of this list.
Can you write Python code for it?

def least_constraining(x, ValuesPerVar, Assignment, Constraints):
    NumbersValues = []
    for value in ValuesPerVar[x]:
        ReducedValues = ValuesPerVar.copy()
        num_removed = number_removed_values(x, value, Assignment, ReducedValues, Constraints)
        if num_removed != math.inf:
            NumbersValues.append( (num_removed, value) )
    NumbersValues.sort(key=lambda p: p[0])
    return [val for _, val in NumbersValues]


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function most_constrained_variable takes two parameters:
- Assigment is a partial variable assignment that assigns values to variables.  It is represented as a dictionary.
- ValuesPerVar is a dictionary that has variables as keys.  For every variable x, ValuesPerVar[x] is the set of values that
  can still be assigned to the variable x.
The function returns an unassigned variable x such that the number of values in ValuesPerVar[x] is minimal among all other unassigned variables.
Hence, this variable is a most constraint variable.
* In order to find this variable, the set Unassigned is computed.  This is a set of pairs of the form (x, n)
  where x is a variable that is not yet assigned and n is the number of values that can still be assigned to x.
* minSize is the number of values that can be assigned to a most constrained variable.
Can you write Python code for it?

def most_constrained_variable(Assignment, ValuesPerVar):
    Unassigned = { (x, len(U)) for x, U in ValuesPerVar.items()
                               if  x not in Assignment
                 }
    minSize = min(lenU for x, lenU in Unassigned)
    for x, lenU in Unassigned:
        if lenU == minSize:
            return x


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function propagate takes five arguments:
- x is a variable,
- v is a value that is supposed to be assigned to x.
- Assignment is a partial assignment that contains assignments for variables that are different from x.
- Constraints is a set of annotated constraints.
- ValuesPerVar is a dictionary assigning sets of values to all variables.  For every unassigned variable z,  ValuesPerVar[z] is the set of values that still might be assigned to z.
The purpose of the function  propagate is to compute how the sets ValuesPerVar[z] can be shrunk when the value v is assigned to the variable x.  The dictionary ValuesPerVar with appropriately reduced sets ValuesPerVar[z] is returned.
Can you write Python code for it?

def propagate(x, v, Assignment, Constraints, ValuesPerVar):
    ValuesDict = ValuesPerVar.copy()
    ValuesDict[x] = { v }
    BoundVars = set(Assignment.keys())
    for F, Vars in Constraints:
        if x in Vars:
            UnboundVars = Vars - BoundVars - { x }
            if len(UnboundVars) == 1:
                y = arb(UnboundVars)
                Legal = set()
                for w in ValuesDict[y]:
                    NewAssign = Assignment.copy()
                    NewAssign[x] = v
                    NewAssign[y] = w
                    if eval(F, NewAssign):
                        Legal.add(w)
                if not Legal:
                    raise Backtrack()
                ValuesDict[y] = Legal
    return ValuesDict


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
The function solve_unary takes a unary constraint f, a variable x and the set of values Values that can be assigned to x.  It returns the subset of values that can be substituted for x such that $f[x\mapsto v]$ evaluates as True.
Can you write Python code for it?

def solve_unary(f, x, Values):
    Legal = { value for value in Values if  eval(f, { x: value }) }
    if not Legal:
        raise Backtrack()
    return Legal


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
With consistency checking the time to solve the crypto arithmetic puzzle is reduced to less than 150 milliseconds.
Can you write Python code for it?

%%time
Solution = solve(csp, check_consistency=True)

show_solution(Solution)


I am working on the file "Python/2 Constraint Solver/Consistency-Solver.ipynb".
The first task is:
Without consistency checking, the problem takes 1.45 seconds.
Can you write Python code for it?

%%time
Solution = solve(csp, check_consistency=False)

csp = crypto_csp_hard()
csp

%%time
Solution = solve(csp, check_consistency=True)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
A Backtracking Solver with Constraint Propagation
Utility Functions
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint Propagation with the least constraining value heuristic takes about 27 milliseconds on my Windows desktop to solve the eight queens puzzle.
Can you write Python code for it?

%%time
Solution = solve(P, lcv=True)
print(f'Solution = {Solution}')

show_solution(Solution)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint Propagation without the least constraining value heuristic takes only 13 milliseconds on my desktop to solve the eight queens puzzle.
Can you write Python code for it?

%%time
Solution = solve(P)
print(f'Solution = {Solution}')

P = create_csp(32)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint propagation can solve the 32 queens problem in less than $2.2$ seconds, if the least constraining value heuristic is used.
Can you write Python code for it?

%%time
Solution = solve(P, True)
print(f'Solution = {Solution}')


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint propagation can solve the 32 queens problem in less than $264$ milliseconds, if the least constraining value heuristic is not used.
The $n$-queens problem is a relatively easy CSP and hence the least constraining value is not useful.
Can you write Python code for it?

%%time
Solution = solve(P)
print(f'Solution = {Solution}')


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint propagation takes about 1.1 seconds if the least constraining value heuristic is not used.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint propagation takes about 118 milliseconds to solve the crypto-arithmetic puzzle if the
least constraining value heuristic is used.
Can you write Python code for it?

%%time
Solution = solve(csp, True)

show_solution(Solution)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint propagation with the least constraining value heuristic takes about 112 milliseconds to solve
the given sudoku.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Constraint propagation without the least constraining value heuristic takes 133 milliseconds to solve
the given sudoku. Hence, in this case the least constraining value heuristic is useful.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Given a list of sets L, the function union(L) returns the set of all elements occurring in some set $S$ that is itself a member of the list L, i.e. we have
$$ \texttt{union}(L) = { x \mid \exists S \in L : x \in L }. $$
Can you write Python code for it?

def union(L):
    return { x for S in L
               for x in S
           }

union([ {1, 2}, {'a', 'b'}, {1, 'a'} ])


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
If the least constraining value heuristic is not used, it takes about 12 milliseconds to solve the Zebra Puzzle.
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
If we want to have reproducible results, the environment variable PYTHONHASHSEED has to be set to a fixed value, for example to 0.
Below we check that this environment is set so that results are reproducible.
In order to set this variable we have to use the following sequence of commands in the anaconda shell.
conda activate ai
conda env config vars set PYTHONHASHSEED=0
conda activate ai
It is necessary to reactivate the environment ai for the setting to take effect.
Can you write Python code for it?

import os
os.getenv('PYTHONHASHSEED')

assert hash("test") == 4418353137104490830, "You python hash seed is not correct, results might differ"


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Let us try the hard version of the puzzle.
Can you write Python code for it?

csp = crypto_csp_hard()

%%time
Solution = solve(csp, True)

%%time
Solution = solve(csp)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Let's check whether the solution is unique.
Can you write Python code for it?

csp = find_alternative(csp, Solution)
csp

%%time
Solution = solve(csp)
if Solution:
    print('There is another solution.')
else:
    print('The solution is unique!')


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Solving a Sudoku Puzzle
Can you write Python code for it?

%run Sudoku-Frame.ipynb

csp = sudoku_csp(Sudoku)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Solving the Eight-Queens-Puzzle
Can you write Python code for it?

%%capture
%run N-Queens-Problem-CSP.ipynb

P = create_csp(8)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
Solving the Zebra Puzzle
Can you write Python code for it?


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
The function collect_variables(expr) takes a string expr that can be interpreted as a Python expression as input and collects all variables occurring in expr.  It takes care to eliminate the function symbols from the names returned by extract_variables.
Can you write Python code for it?

def collect_variables(expression):
    tree      = ast.parse(expression)
    Variables = { node.id for node in ast.walk(tree)
                          if  isinstance(node, ast.Name)
                          if node.id not in dir(__builtins__)
                }
    return frozenset(Variables)


I am working on the file "Python/2 Constraint Solver/Constraint-Propagation-Solver.ipynb".
The first task is:
The function least_constraining takes four arguments:
* x is a variable.
* ValuesPerVar is a dictionary.  For every variable var, ValuesPerVar[var] is the set of values that can be assigned to var.
* Assignment is a partial variable assignment.
* Constraints is a set of annotated constraints.
This function returns a list of values that can be substituted for the variable x.
This list is sorted so that the least constraining values are at the beginning of this list.
Can you write Python code for it?

def least_constraining(x, ValuesPerVar, Assignment, Constraints):
    NumbersValues = []
    for value in ValuesPerVar[x]:
        ReducedValues = ValuesPerVar.copy()
        num_removed = shrinkage(x, value, Assignment, ReducedValues, Constraints)
        if num_removed != math.inf:
            NumbersValues.append( (num_removed, value) )
    NumbersValues.sort(key=lambda p: p[0])
    return [val for _, val in NumbersValues]