added docstring to all functions and methods

This commit is contained in:
Gabriel Augendre 2015-01-03 23:26:11 +01:00
parent b2fb7bb25b
commit b1070f42f9

View file

@ -18,12 +18,17 @@ __author__ = 'gaugendre'
import sys import sys
def string_from_list(line) -> str: def string_from_list(line):
""" """
Makes a string from a line of squares. Makes a string from a line of squares.
:param line: A line (list) of squares to make a string from. :param line: A line (list) of squares to make a string from.
:type line: list :type line: list
:return: A string containing all the states of the squares in the list. :return: A string containing all the states of the squares in the list.
:rtype: str
.. warnings:: The items of the list must be squares or have an attribute
called 'state'.
""" """
string = "" string = ""
for square in line: for square in line:
@ -31,12 +36,18 @@ def string_from_list(line) -> str:
return string return string
def non_space_element(line) -> str: def non_space_element(line):
""" """
Returns the number of non space characters in a string. Returns the number of non space characters in a string.
:param line: The line where to count characters. :param line: The line where to count characters.
:type line: str :type line: str
:return: The number of non space characters. :return: The number of non space characters.
:rtype: str
:Example:
>>> non_space_element('Ceci est un test')
13
""" """
return len(line.replace(' ', '')) return len(line.replace(' ', ''))
@ -53,7 +64,7 @@ class Square:
self.vert = vert self.vert = vert
self.switched = False self.switched = False
self.base = base self.base = base
if isinstance(grid, Grid): if not grid or isinstance(grid, Grid):
self.grid = grid self.grid = grid
else: else:
print("Warning : Attribute grid not instance of Grid", print("Warning : Attribute grid not instance of Grid",
@ -67,22 +78,54 @@ class Square:
self._state = ' ' self._state = ' '
def next_horiz(self): def next_horiz(self):
if self.horiz == self.grid.size - 1: """
A method to get the next square horizontally.
:return: The next square, horizontally.
:rtype: Square
.. warnings:: The square must be part of a grid
"""
if not self.grid or self.horiz == self.grid.size - 1:
return None return None
return self.grid.square(self.horiz + 1, self.vert) return self.grid.square(self.horiz + 1, self.vert)
def prev_horiz(self): def prev_horiz(self):
if self.horiz == 0: """
A method to get the previous square horizontally.
:return: The previous square, horizontally.
:rtype: Square
.. warnings:: The square must be part of a grid
"""
if not self.grid or self.horiz == 0:
return None return None
return self.grid.square(self.horiz - 1, self.vert) return self.grid.square(self.horiz - 1, self.vert)
def next_vert(self): def next_vert(self):
if self.vert == self.grid.size - 1: """
A method to get the next square vertically.
:return: The next square, vertically.
:rtype: Square
.. warnings:: The square must be part of a grid
"""
if not self.grid or self.vert == self.grid.size - 1:
return None return None
return self.grid.square(self.horiz, self.vert + 1) return self.grid.square(self.horiz, self.vert + 1)
def prev_vert(self): def prev_vert(self):
if self.vert == 0: """
A method to get the previous square vertically.
:return: The previous square, vertically.
:rtype: Square
.. warnings:: The square must be part of a grid
"""
if not self.grid or self.vert == 0:
return None return None
return self.grid.square(self.horiz, self.vert - 1) return self.grid.square(self.horiz, self.vert - 1)
@ -98,14 +141,17 @@ class Square:
def __repr__(self): def __repr__(self):
return "({}, {}) : '{}'".format(self.horiz, self.vert, self.state) return "({}, {}) : '{}'".format(self.horiz, self.vert, self.state)
def _get_state(self): @property
def state(self):
""" """
Allow to get square state. Allow to get square state.
:return: The square state. Either ' ', 'R' or 'B' :return: The square state. Either ' ', 'R' or 'B'
""" """
return self._state return self._state
def _set_state(self, new_state): @state.setter
def state(self, new_state):
""" """
Changes square state. Accepts only 'R', 'B', or ' '. Changes square state. Accepts only 'R', 'B', or ' '.
Other values are not accepted and the square is not modified. Other values are not accepted and the square is not modified.
@ -116,9 +162,22 @@ class Square:
else: else:
print("Error :", new_state, "not in ('R', 'B', ' ').") print("Error :", new_state, "not in ('R', 'B', ' ').")
state = property(_get_state, _set_state)
def opposite_state(self): def opposite_state(self):
"""
Returns the opposite state of the current Square.
The opposite state of 'R' is 'B', and vice-versa.
The opposite state of ' ' is ' '.
:return: The opposite state of the current square.
:rtype: str
:Example:
>>> Square(None, 0, 0, 'R').opposite_state()
'B
>>> Square(None, 0, 0, ' ').opposite_state()
' ''
"""
if self.state == 'R': if self.state == 'R':
return 'B' return 'B'
elif self.state == 'B': elif self.state == 'B':
@ -127,17 +186,48 @@ class Square:
return ' ' return ' '
def is_empty(self): def is_empty(self):
"""
Simply tells if the square contains nothing or not.
:return: True if the square contains ' ', else False.
:rtype: bool
:Example:
>>> Square(None, 0, 0, ' ').is_empty()
True
>>> Square(None, 0, 0, 'R').is_empty()
False
"""
return self.state == ' ' return self.state == ' '
def all_prev_horiz(self): def all_prev_horiz(self):
"""
Get the list of all previous squares, horizontally.
:return: A list containing all the previous squares horizontally.
:rtype: list
.. seealso:: prev_horiz()
.. warnings:: The square must be part of a grid.
"""
h_prev = self.prev_horiz() h_prev = self.prev_horiz()
all_prev_horiz_list = [] all_prev_horiz_list = []
while h_prev: while h_prev:
all_prev_horiz_list.append(h_prev) all_prev_horiz_list.append(h_prev)
h_prev = h_prev.prev_horiz() h_prev = h_prev.prev_horiz()
return all_prev_horiz_list return all_prev_horiz_list
def all_next_horiz(self): def all_next_horiz(self):
"""
Get the list of all next squares, horizontally.
:return: A list containing all the next squares horizontally.
:rtype: list
.. seealso:: next_horiz()
.. warnings:: The square must be part of a grid.
"""
h_next = self.next_horiz() h_next = self.next_horiz()
all_next_horiz_list = [] all_next_horiz_list = []
while h_next: while h_next:
@ -146,6 +236,15 @@ class Square:
return all_next_horiz_list return all_next_horiz_list
def all_prev_vert(self): def all_prev_vert(self):
"""
Get the list of all previous squares, vertically.
:return: A list containing all the previous squares vertically.
:rtype: list
.. seealso:: prev_vert()
.. warnings:: The square must be part of a grid.
"""
v_prev = self.prev_vert() v_prev = self.prev_vert()
all_prev_vert_list = [] all_prev_vert_list = []
while v_prev: while v_prev:
@ -154,6 +253,15 @@ class Square:
return all_prev_vert_list return all_prev_vert_list
def all_next_vert(self): def all_next_vert(self):
"""
Get the list of all next squares, vertically.
:return: A list containing all the next squares vertically.
:rtype: list
.. seealso:: next_vert()
.. warnings:: The square must be part of a grid.
"""
v_next = self.next_vert() v_next = self.next_vert()
all_next_vert_list = [] all_next_vert_list = []
while v_next: while v_next:
@ -165,7 +273,11 @@ class Square:
""" """
List of squares in the same line. List of squares in the same line.
Does not include the considered square. Does not include the considered square.
:return: The list of the squares in the same line. :return: The list of the squares in the same line.
.. seealso:: all_prev_horiz(), all_next_horiz()
.. warnings:: The square must be part of a grid.
""" """
line_list = [] line_list = []
line_list.extend(self.all_prev_horiz()) line_list.extend(self.all_prev_horiz())
@ -177,7 +289,11 @@ class Square:
""" """
List of squares in the same column. List of squares in the same column.
Does not include the considered square. Does not include the considered square.
:return: The list of the squares in the same column. :return: The list of the squares in the same column.
.. seealso:: all_prev_vert(), all_next_vert()
.. warnings:: The square must be part of a grid.
""" """
line_list = [] line_list = []
line_list.extend(self.all_prev_vert()) line_list.extend(self.all_prev_vert())
@ -186,13 +302,17 @@ class Square:
return line_list return line_list
def solve_three_square(square) -> bool: def solve_three_square(square):
""" """
Prevent 'three in a row'.
Checks before and after the square if there are two squares of the Checks before and after the square if there are two squares of the
same color in order to prevent 'three in a row'. same color in order to prevent 'three in a row'.
:param square: The Square to check :param square: The Square to check
:type square: Square :type square: Square
:return: A boolean : True if something has been done, else False. :return: A boolean : True if something has been done, else False.
:rtype: bool
""" """
solved = False solved = False
if square.is_empty(): if square.is_empty():
@ -284,10 +404,11 @@ class Grid:
self.squares_to_modify = squares_to_modify self.squares_to_modify = squares_to_modify
@property @property
def squares(self) -> list: def squares(self):
""" """
A method to get the squares in the grid. A method to get the squares in the grid.
:return: The squares in the grid. :return: The squares in the grid.
:rtype: list
""" """
return self._squares return self._squares
@ -295,9 +416,12 @@ class Grid:
def squares(self, array): def squares(self, array):
""" """
Replace the squares in the grid with the one provided in the array. Replace the squares in the grid with the one provided in the array.
The array must be a list of list of characters (square array).
:param array: The array to replace the squares. :param array: The array to replace the squares.
:type array: list :type array: list
.. warnings:: The array must be a list containing
lists of characters (square array).
""" """
squares = [] squares = []
i = 0 i = 0
@ -311,14 +435,16 @@ class Grid:
i += 1 i += 1
self._squares = squares self._squares = squares
def square(self, horiz, vert) -> Square: def square(self, horiz, vert):
""" """
Used to get a specific square in the grid. Used to get a specific square in the grid.
:param horiz: The horizontal position of the square to get. :param horiz: The horizontal position of the square to get.
:type horiz: int :type horiz: int
:param vert: The vertical position of the square to get. :param vert: The vertical position of the square to get.
:type vert: int :type vert: int
:return: The square at the given position :return: The square at the given position
:rtype: Square
""" """
return self._squares[vert][horiz] return self._squares[vert][horiz]
@ -333,33 +459,39 @@ class Grid:
representation += "\n" representation += "\n"
return representation return representation
def squares_on_line(self, line_number) -> list: def squares_on_line(self, line_number):
""" """
Returns the squares on a line specified by the number Returns the squares on a line specified by the number
(starting from zero). (starting from zero).
:param line_number: The line to get. :param line_number: The line to get.
:type line_number: int :type line_number: int
:return: The list containing the squares on the required line. :return: The list containing the squares on the required line.
:rtype: list
""" """
return self.squares[line_number] return self.squares[line_number]
def squares_on_column(self, col_number) -> list: def squares_on_column(self, col_number):
""" """
Returns the squares on a column specified by the number Returns the squares on a column specified by the number
(starting from zero). (starting from zero).
:param col_number: The column to get. :param col_number: The column to get.
:type col_number: int :type col_number: int
:return: The list containing the squares on the required column. :return: The list containing the squares on the required column.
:rtype: list
""" """
col = [] col = []
for line in self.squares: for line in self.squares:
col.append(line[col_number]) col.append(line[col_number])
return col return col
def solve_threes(self) -> bool: def solve_threes(self):
""" """
Solves the grid recursively to prevent 'three in a row'. Solves the grid recursively to prevent 'three in a row'.
:return: True if a square has been modified, else False. :return: True if a square has been modified, else False.
:rtype: bool
""" """
solved = False solved = False
for square in self.squares_to_modify: for square in self.squares_to_modify:
@ -368,6 +500,10 @@ class Grid:
return solved return solved
def solve(self): def solve(self):
"""
Solves the grid using 'three in a row', 'same number of red and blue
on the same line or column' and, later, 'no identical line or column'.
"""
solved = True solved = True
while solved: while solved:
if not self.solve_threes(): if not self.solve_threes():
@ -377,6 +513,13 @@ class Grid:
# self.solve_different_lines_or_columns() # self.solve_different_lines_or_columns()
def solve_same_number(self): def solve_same_number(self):
"""
Solves the grid implementing the fact that there is always the same
number of red and blue on the same line or column.
:return: True if a square has been modified, else False.
:rtype: bool
"""
solved = False solved = False
for square in self.square_list: for square in self.square_list:
if square.is_empty(): if square.is_empty():
@ -414,6 +557,15 @@ class Grid:
return solved return solved
def solve_different_lines_or_columns(self): def solve_different_lines_or_columns(self):
"""
Solves the grid implementing the fact that there isn't two identical
lines or columns.
:return: True if a square has been modified, else False.
:rtype: bool
.. warnings:: Function still not finished. DOESN'T WORK.
"""
for square in self.square_list: for square in self.square_list:
line = string_from_list(square.same_line()) line = string_from_list(square.same_line())
col = string_from_list(square.same_column()) col = string_from_list(square.same_column())