Skip to content

Instantly share code, notes, and snippets.

@grevych
Last active October 31, 2019 00:54
Show Gist options
  • Save grevych/5babb9fcfe4d61deb9c95404ce7c4b49 to your computer and use it in GitHub Desktop.
Save grevych/5babb9fcfe4d61deb9c95404ce7c4b49 to your computer and use it in GitHub Desktop.
ASCII Printer
class Board(object):
def __init__(self, wide, tall):
self.__wide__ = wide
self.__tall__ = tall
self.__area__ = [[None for _ in range(wide)] for _ in range(tall)]
self.__validate_wide__(wide)
self.__validate_tall__(tall)
def __validate_wide__(self, wide):
if wide <= 0:
raise Exception('Wide must be greater than zero')
def __validate_tall__(self, tall):
if tall <= 0:
raise Exception('Tall must be greather than zero')
def __validate_ranges__(self, left, top, right, bottom):
if left < 0:
raise Exception('Left must be greater than zero')
if right >= self.__wide__:
raise Exception('Right must be less than {0}'.format(self.__wide__))
if top < 0:
raise Exception('Top must be greater than zero')
if bottom >= self.__tall__:
raise Exception('Bottom must be less than {0}'.format(self.__tall__))
if left > right:
raise Exception('Left must be less than right')
if top > bottom:
raise Exception('Bottom must be less than top')
def __validate_position__(self, index_j, index_i):
if index_j < 0:
raise Exception('X must be greater than zero')
if index_j >= self.__wide__:
raise Exception('X must be less than {0}'.format(self.__wide__))
if index_i < 0:
raise Exception('Y must be greater than zero')
if index_i >= self.__tall__:
raise Exception('Y must be less than {0}'.format(self.__tall__))
def area(self):
return self.__area__
def fill_area(self, char, left, top, right, bottom):
self.__validate_ranges__(left, top, right, bottom)
# index_j controls left and right
# index_i controls top and bottom
for index_i in range(top, bottom + 1):
for index_j in range(left, right + 1):
self.__area__[index_i][index_j] = char
def fill_position(self, char, index_j, index_i):
self.__validate_position__(index_j, index_i)
self.__area__[index_i][index_j] = char
def clear_position(self, index_j, index_i):
self.__validate_position__(index_j, index_i)
self.__area__[index_i][index_j] = None
from pprint import pprint
from printer import Printer
p = Printer()
p.draw_rectangle('L', 1, 1, 4, 4)
# pprint([board.area() for board in p.__boards__])
p.print_canvas()
p.draw_rectangle('R', 2, 1, 4, 4)
# pprint([board.area() for board in p.__boards__])
p.print_canvas()
p.erase_area(3, 2, 3, 3)
# pprint([board.area() for board in p.__boards__])
p.print_canvas()
p.drag_and_drop(1, 1, 2, 2)
# pprint([board.area() for board in p.__boards__])
p.print_canvas()
p.bring_to_front(3, 2, 4, 3)
# pprint([board.area() for board in p.__boards__])
p.print_canvas()
from board import Board
class Printer(object):
ERASE_CHAR = ' '
EMPTY_CHAR = ' '
def __init__(self):
self.__boards__ = []
self.__wide__ = 10
self.__tall__ = 6
def __add_board__(self, board):
# We may need to verify if its a printable board
self.__boards__.append(board)
def __get_last_filled_board_position__(
self, index_j, index_i, initial_board_index = None
):
if initial_board_index is None:
initial_board_index = len(self.__boards__) - 1
# Iterate boards from last to first
for board_index in range(initial_board_index, -1, -1):
board_area = self.__boards__[board_index].area()
if board_area[index_i][index_j] is not None:
return board_area[index_i][index_j]
return Printer.EMPTY_CHAR
def __extract_last_filled_board_position__(
self, index_j, index_i, initial_board_index = None
):
if initial_board_index is None:
initial_board_index = len(self.__boards__) - 1
# Iterate boards from last to first
for board_index in range(initial_board_index, -1, -1):
board_area = self.__boards__[board_index].area()
if board_area[index_i][index_j] is not None:
char = board_area[index_i][index_j]
self.__boards__[board_index].clear_position(index_j, index_i)
return char
return None
def draw_rectangle(self, char, left, top, right, bottom):
# Each draw will create a new board
board = Board(self.__wide__, self.__tall__)
board.fill_area(char, left, top, right, bottom)
self.__add_board__(board)
def erase_area(self, left, top, right, bottom):
for index_i in range(top, bottom + 1):
for index_j in range(left, right + 1):
for board in self.__boards__:
board.clear_position(index_j, index_i)
def print_canvas(self):
x_axis = ['{0}'.format(index_j) for index_j in range(self.__wide__)]
print(' ' + ' '.join(x_axis))
for index_i in range(self.__tall__):
# Y axis
row = '{0} '.format(index_i)
for index_j in range(self.__wide__):
row += self.__get_last_filled_board_position__(index_j, index_i)
row += ' '
print(row)
def drag_and_drop(self, initial_left, initial_top, final_left, final_top):
board = Board(self.__wide__, self.__tall__)
for index_i in range(initial_top, self.__tall__):
for index_j in range(initial_left, self.__wide__):
char = self.__extract_last_filled_board_position__(
index_j, index_i
)
if char is None:
continue
try:
left = index_j + final_left - initial_left
top = index_i + final_top - initial_top
board.fill_position(char, left, top)
except:
pass
self.__add_board__(board)
def bring_to_front(self, left, top, right, bottom):
board = Board(self.__wide__, self.__tall__)
for index_i in range(top, bottom + 1):
for index_j in range(left, right + 1):
char = self.__extract_last_filled_board_position__(
index_j, index_i, initial_board_index=len(self.__boards__) - 2
)
if char is None:
self.__boards__[-1].clear_position(index_j, index_i)
else:
board.fill_position(char, index_j, index_i)
self.__add_board__(board)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment