From 7dbcd30cc851cbd099836470c064eba950ac6de0 Mon Sep 17 00:00:00 2001 From: Hykilpikonna Date: Wed, 23 Feb 2022 09:49:04 -0500 Subject: [PATCH 1/5] [F] A2 P1 Fix potential tree modification conflict --- assignments/A2/a2_part1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/A2/a2_part1.py b/assignments/A2/a2_part1.py index 69023d6..6b8f590 100644 --- a/assignments/A2/a2_part1.py +++ b/assignments/A2/a2_part1.py @@ -167,7 +167,7 @@ def part1_runner(games_file: str, n: int, black_random: bool) -> None: """ tree = load_game_tree(games_file) white = RandomTreePlayer(tree) - black = a2_minichess.RandomPlayer() if black_random else white + black = a2_minichess.RandomPlayer() if black_random else RandomTreePlayer(tree) a2_minichess.run_games(n, white, black, show_stats=True) From 1c7a9bb028a1504c4dbc34c7b2f2cd3d686126ac Mon Sep 17 00:00:00 2001 From: Hykilpikonna Date: Wed, 23 Feb 2022 12:25:29 -0500 Subject: [PATCH 2/5] [U] Update comment --- assignments/A2/a2_game_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/A2/a2_game_tree.py b/assignments/A2/a2_game_tree.py index a4b4d73..8e77246 100644 --- a/assignments/A2/a2_game_tree.py +++ b/assignments/A2/a2_game_tree.py @@ -89,7 +89,7 @@ class GameTree: return None def add_subtree(self, subtree: GameTree) -> None: - """Add a subtree to this game tree.""" + """Add a subtree to this game tree and updates white win probability.""" self._subtrees.append(subtree) self._update_white_win_probability() From 9bd0441e6e6172e74e33a724aaeb7c3d426a763e Mon Sep 17 00:00:00 2001 From: wuliaozhiji Date: Sun, 6 Mar 2022 19:10:57 -0500 Subject: [PATCH 3/5] [+] Prep8 starter --- practice/prep8.py | 212 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 practice/prep8.py diff --git a/practice/prep8.py b/practice/prep8.py new file mode 100644 index 0000000..0b128cf --- /dev/null +++ b/practice/prep8.py @@ -0,0 +1,212 @@ +"""CSC111 Winter 2022 Prep 8: Programming Exercises + +Instructions (READ THIS FIRST!) +=============================== + +This module contains the graph implementation we studied in lecture, with a few +additional methods for you to implement on this exercise. + +We have marked each place you need to write code with the word "TODO". +As you complete your work in this file, delete each TODO comment. + +You may add additional doctests, but they will not be graded. You should test your work +carefully before submitting it! + +Copyright and Usage Information +=============================== + +This file is provided solely for the personal and private use of students +taking CSC111 at the University of Toronto St. George campus. All forms of +distribution of this code, whether as given or with any changes, are +expressly prohibited. For more information on copyright for CSC111 materials, +please consult our Course Syllabus. + +This file is Copyright (c) 2022 Mario Badr and David Liu. +""" +from __future__ import annotations +from typing import Any + + +class Graph: + """A graph. + """ + # Private Instance Attributes: + # - _vertices: + # A collection of the vertices contained in this graph. + # Maps item to _Vertex object. + _vertices: dict[Any, _Vertex] + + def __init__(self) -> None: + """Initialize an empty graph (no vertices or edges).""" + self._vertices = {} + + def add_vertex(self, item: Any) -> None: + """Add a vertex with the given item to this graph. + + The new vertex is not adjacent to any other vertices. + """ + self._vertices[item] = _Vertex(item, set()) + + def add_edge(self, item1: Any, item2: Any) -> None: + """Add an edge between the two vertices with the given items in this graph. + + Raise a ValueError if item1 or item2 do not appear as vertices in this graph. + + Preconditions: + - item1 != item2 + """ + if item1 in self._vertices and item2 in self._vertices: + v1 = self._vertices[item1] + v2 = self._vertices[item2] + + # Add the new edge + v1.neighbours.add(v2) + v2.neighbours.add(v1) + else: + # We didn't find an existing vertex for both items. + raise ValueError + + def connected(self, item1: Any, item2: Any) -> bool: + """Return whether item1 and item2 are connected vertices in this graph. + + Return False if item1 or item2 do not appear as vertices in this graph. + + >>> g = Graph() + >>> g.add_vertex(1) + >>> g.add_vertex(2) + >>> g.add_vertex(3) + >>> g.add_vertex(4) + >>> g.add_edge(1, 2) + >>> g.add_edge(2, 3) + >>> g.connected(1, 3) + True + >>> g.connected(1, 4) + False + """ + if item1 in self._vertices and item2 in self._vertices: + v1 = self._vertices[item1] + return v1.check_connected(item2, set()) # Pass in an empty "visited" set + else: + return False + + def get_connected_component(self, item: Any) -> set: + """Return a set of all ITEMS connected to the given item in this graph. + + Raise a ValueError if item does not appears as a vertex in this graph. + + >>> g = Graph() + >>> for i in range(0, 5): + ... g.add_vertex(i) + >>> g.add_edge(0, 1) + >>> g.add_edge(1, 2) + >>> g.add_edge(1, 3) + >>> g.add_edge(2, 3) + >>> g.get_connected_component(0) == {0, 1, 2, 3} + True + + Note: we've implemented this method for you, and you should not change it. + Instead, your task is to implement _Vertex.get_connected_component below. + """ + if item not in self._vertices: + raise ValueError + else: + return self._vertices[item].get_connected_component(set()) + + def in_cycle(self, item: Any) -> bool: + """Return whether the given item is in a cycle in this graph. + + Return False if item does not appears as a vertex in this graph. + + KEY OBSERVATION. A vertex v is in a cycle if and only if: + v has two distinct neighbours u and w that are connected to each other + by a path that doesn't use v. + + >>> g = Graph() + >>> for i in range(0, 4): + ... g.add_vertex(i) + >>> g.add_edge(0, 1) + >>> g.add_edge(1, 2) + >>> g.add_edge(1, 3) + >>> g.add_edge(2, 3) + >>> g.in_cycle(1) + True + >>> g.in_cycle(0) + False + + Implementation notes: + 1. This method should call _Vertex.check_connected (following the above + description). + 2. Don't try to make this method recursive, or copy and paste the implementation + of _Vertex.check_connected! That's not necessary here. + """ + # TODO: implement this method + + +class _Vertex: + """A vertex in a graph. + + Instance Attributes: + - item: The data stored in this vertex. + - neighbours: The vertices that are adjacent to this vertex. + + Representation Invariants: + - self not in self.neighbours + - all(self in u.neighbours for u in self.neighbours) + """ + item: Any + neighbours: set[_Vertex] + + def __init__(self, item: Any, neighbours: set[_Vertex]) -> None: + """Initialize a new vertex with the given item and neighbours.""" + self.item = item + self.neighbours = neighbours + + def check_connected(self, target_item: Any, visited: set[_Vertex]) -> bool: + """Return whether this vertex is connected to a vertex corresponding to the target_item, + WITHOUT using any of the vertices in visited. + + Preconditions: + - self not in visited + """ + if self.item == target_item: + # Our base case: the target_item is the current vertex + return True + else: + visited.add(self) # Add self to the set of visited vertices + for u in self.neighbours: + if u not in visited: # Only recurse on vertices that haven't been visited + if u.check_connected(target_item, visited): + return True + + return False + + def get_connected_component(self, visited: set[_Vertex]) -> set: + """Return a set of all ITEMS connected to self by a path that does not use + any vertices in visited. + + The items of the vertices in visited CANNOT appear in the returned set. + + Preconditions: + - self not in visited + + Implementation notes: + 1. This can be implemented in a similar way to _Vertex.check_connected. + 2. This method must be recursive, and will have an implicit base case: + when all vertices in self.neighbours are already in visited. + 3. Use a loop accumulator to store a set of the vertices connected to self. + """ + # TODO: implement this method + + +if __name__ == '__main__': + # Note: we are NOT using python_ta.contracts for this prep. + # (Feel free to ask why in office hours/Campuswire.) + import doctest + doctest.testmod() + + import python_ta + python_ta.check_all(config={ + 'max-line-length': 100, + 'disable': ['E1136'], + 'max-nested-blocks': 4 + }) From 58078aef9dae5d70a4c55856a8950566f3e7b19f Mon Sep 17 00:00:00 2001 From: wuliaozhiji Date: Sun, 6 Mar 2022 19:27:12 -0500 Subject: [PATCH 4/5] [+] Prep8 in_cycle --- practice/prep8.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/practice/prep8.py b/practice/prep8.py index 0b128cf..19680e2 100644 --- a/practice/prep8.py +++ b/practice/prep8.py @@ -122,7 +122,7 @@ class Graph: by a path that doesn't use v. >>> g = Graph() - >>> for i in range(0, 4): + >>> for i in range(0, 5): ... g.add_vertex(i) >>> g.add_edge(0, 1) >>> g.add_edge(1, 2) @@ -132,6 +132,9 @@ class Graph: True >>> g.in_cycle(0) False + >>> g.add_edge(4, 0) + >>> g.in_cycle(0) + False Implementation notes: 1. This method should call _Vertex.check_connected (following the above @@ -139,7 +142,21 @@ class Graph: 2. Don't try to make this method recursive, or copy and paste the implementation of _Vertex.check_connected! That's not necessary here. """ - # TODO: implement this method + # Does not exist + if item not in self._vertices: + return False + v = self._vertices[item] + + # Combinations + for u in v.neighbours: + for w in v.neighbours: + # Distinct combinations + if u == w or u == v or w == v: + continue + + if u.check_connected(w.item, {v}): + return True + return False class _Vertex: From d740d41ea6a8933a7d74b04ca24b1497f7ae2621 Mon Sep 17 00:00:00 2001 From: wuliaozhiji Date: Sun, 6 Mar 2022 19:46:34 -0500 Subject: [PATCH 5/5] [+] Prep8 get_connected_component --- practice/prep8.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/practice/prep8.py b/practice/prep8.py index 19680e2..60889e5 100644 --- a/practice/prep8.py +++ b/practice/prep8.py @@ -211,8 +211,33 @@ class _Vertex: 2. This method must be recursive, and will have an implicit base case: when all vertices in self.neighbours are already in visited. 3. Use a loop accumulator to store a set of the vertices connected to self. + + >>> g = Graph() + >>> for i in range(0, 7): + ... g.add_vertex(i) + >>> g.add_edge(0, 1) + >>> g.add_edge(1, 2) + >>> g.add_edge(1, 3) + >>> g.add_edge(2, 3) + >>> g.get_connected_component(1) == {0, 1, 2, 3} + True + >>> g.add_edge(4, 0) + >>> g.get_connected_component(0) == {0, 1, 2, 3, 4} + True + >>> g.get_connected_component(5) + {5} + >>> g._vertices[5].get_connected_component({g._vertices[5]}) + set() + >>> g._vertices[6].get_connected_component(set()) + {6} """ - # TODO: implement this method + if self in visited: + return set() + visited.add(self) + nums = {self.item} + for u in self.neighbours: + nums = nums.union(u.get_connected_component(visited)) + return nums if __name__ == '__main__':