From: Eevee Date: Sat, 13 Dec 2008 05:10:35 +0000 (-0800) Subject: Moved stringify cruft into a render module. X-Git-Url: http://git.veekun.com/pseudoku.git/commitdiff_plain/54fb37a3a35cbc8ae38e3d96d2a2775e12b37c04 Moved stringify cruft into a render module. Called pseudoku.render; currently contains classes for rendering to a single line, a simple grid of symbols, or an ascii-art grid. --- diff --git a/pseudoku/__init__.py b/pseudoku/__init__.py index 3b6eeb9..853904b 100644 --- a/pseudoku/__init__.py +++ b/pseudoku/__init__.py @@ -1,4 +1,5 @@ from grid import Grid +import render.text def main(): grid = Grid.from_string(""" @@ -13,8 +14,9 @@ def main(): 1...6...9 """) - print grid + r = render.text.AsciiArtGridRenderer() + print r.render_grid(grid) grid.solve() - print grid + print r.render_grid(grid) diff --git a/pseudoku/grid/__init__.py b/pseudoku/grid/__init__.py index 2f77aaf..9370dd6 100644 --- a/pseudoku/grid/__init__.py +++ b/pseudoku/grid/__init__.py @@ -117,14 +117,6 @@ class Cell(object): self.normalize() - def __str__(self): - """Stringification for pretty-printing.""" - if self.value != None: - return symbols[self.value] - - return '.' - - class Grid(object): """Represents a Sudoku grid.""" @@ -302,31 +294,3 @@ class Grid(object): """Normalizes every cell in the grid.""" for cell in self._cells: cell.normalize() - - - def __str__(self): - """Pretty-printing.""" - divider = '+' - for box in xrange(self._box_height): - for col in xrange(self._box_width): - divider += '-' - divider += '+' - - res = '' - for row in xrange(self._size): - if row % self._box_height == 0: - res += divider - res += "\n" - - for col in xrange(self._size): - if col % self._box_width == 0: - res += '|' - res += str(self.cell(row, col)) - - res += '|' - res += "\n" - - res += divider - res += "\n" - - return res diff --git a/pseudoku/render/__init__.py b/pseudoku/render/__init__.py new file mode 100644 index 0000000..fb700bd --- /dev/null +++ b/pseudoku/render/__init__.py @@ -0,0 +1,94 @@ +from ..grid import symbols + +class GridRenderer(object): + """Class that renders a grid in some human-consumable form. + + This base class's methods result in a flat string of symbols, but it's easy + to create a more useful rendering by just overriding a few methods. + """ + + def render_grid(self, grid): + """Renders the entire grid. Code on the outside probably only needs to + call this. + + Returns a string. + """ + parts = [] + + parts.append(self.before_grid(grid)) + for idx, row in enumerate(grid._rows): + if idx and idx % grid._box_height == 0: + parts.append(self.inside_grid(grid)) + parts.append(self.render_row(row)) + parts.append(self.after_grid(grid)) + + return ''.join(parts) + + def render_row(self, row): + """Renders a single row.""" + parts = [] + + parts.append(self.before_row(row)) + for idx, cell in enumerate(row.cells): + if idx and idx % row._grid._box_width == 0: + parts.append(self.inside_row(row)) + parts.extend(self.render_cell(cell)) + parts.append(self.after_row(row)) + + return ''.join(parts) + + def render_cell(self, cell): + """Renders a single cell.""" + return ''.join([ + self.before_cell(cell), + self.inside_cell(cell), + self.after_cell(cell), + ]) + + + def before_grid(self, grid): + """Content prepended before the entire grid.""" + return self.inside_grid(grid) + + def inside_grid(self, grid): + """Content inserted within the grid, between boxes.""" + return '' + + def after_grid(self, grid): + """Content appended after the entire grid.""" + return self.inside_grid(grid) + + + def before_row(self, row): + """Content prepended before each row.""" + return self.inside_row(row) + + def inside_row(self, row): + """Content inserted within each row, between boxes.""" + return '' + + def after_row(self, row): + """Content appended after each row. + + Note that newlines are not assumed; you must provide one if you want + one included in the rendering. + """ + + return self.inside_row(row) + + + def before_cell(self, cell): + """Content prepended before each cell in a row.""" + return '' + + def inside_cell(self, cell): + """Content used to represent the actual cell value.""" + if cell.value: + return symbols[cell.value] + else: + return '.' + + def after_cell(self, cell): + """Content appended after each row in a cell.""" + return '' + diff --git a/pseudoku/render/text.py b/pseudoku/render/text.py new file mode 100644 index 0000000..aab6c36 --- /dev/null +++ b/pseudoku/render/text.py @@ -0,0 +1,37 @@ +from . import GridRenderer +from ..grid import symbols + +class LineGridRenderer(GridRenderer): + """Renders a grid into a flat string, as puzzles are often presented in + plaintext collections. + """ + pass + + +class SquareGridRenderer(GridRenderer): + """Renders a grid as a square of characters.""" + + def after_row(self, row, new_box=False): + return '\n' + + +class AsciiArtGridRenderer(SquareGridRenderer): + """Renders a questionably-pretty ASCII art drawing of a grid, with dividers + between rows and columns. + """ + + def inside_grid(self, grid): + box_header = '+' + '-' * grid._box_width + return box_header * grid._box_height + '+\n' + + def inside_row(self, row): + return '|' + + def after_row(self, row): + return '|\n' + + def inside_cell(self, cell): + if cell.value: + return symbols[cell.value] + else: + return ' '