I submitted a project and never heard back and I am wondering if my coding style is okay. At the company I work I get feedback, but I'd like to hear from the outside world. It's a drawing tool - the input is in a text file (each on its own line):
C 20 4
L 1 2 6 2
L 6 3 6 4
R 16 1 20 3
It's called as so: python drawingtool.py < input.txt
C = Canvas create, L = Line, R = Rectangle
from collections import defaultdict
import logging
import sys
NEWLINE = '\n'
DATA_SEP = '/'
PARAM_SEP = ' '
DATA_POS = 1
PARAM_POS = 0
class Canvas(object):
_created = 0
def __init__(self, cols, rows):
self.rows = rows
self.cols = cols
Canvas._created += 1
self.surface = self._create_blank_canvas()
def _create_blank_canvas(self):
row_frame_char = '-'
col_frame_char = '|'
canvas = []
top_bottom = [row_frame_char for col in xrange(self.cols+2)]
middle = [self._middle_char(col, col_frame_char, self.cols+1) for col in xrange(self.cols+2)]
for row in xrange(self.rows+2):
if row == 0 or row == self.rows+2:
canvas.append(list(top_bottom))
else:
canvas.append(list(middle))
return canvas
def _middle_char(self, col, col_frame_char, max):
return col_frame_char if col == 0 or col == max else ' '
def print_canvas(self):
for row in self.surface:
print ' '.join(row)
def valid_pos(self, x, y):
ret_val = False
if not self._boundary(x, y) and self._on_canvas(x, y):
ret_val = True
return ret_val
def _boundary(self, x, y):
return (x == 0 or x == self.rows+1) or (y == 0 or y == self.cols+1)
def _on_canvas(self, x, y):
return (x > 0 and x < self.cols+1) or (y > 0 or y < self.rows+1)
def update_cell(self, y, x, val=None):
if self.valid_pos(y, x):
self.surface[int(y)][int(x)] = val #[int(1)]
else:
logging.warning('Invalid position found x=%s y=%s' % (x,y))
class DataUtils(object):
def __init__(self):
self.raw_data = None
def prepare_data(self):
return self.apply_strip(self.raw_data, '\n')
def split_up_by_delimiter(self, data, delim):
return [filter(lambda x:x, map(lambda x:x, y.split(delim))) for y in data]
def read_data_lines(self):
return sys.stdin.readlines()
def write_data_lines(self, data):
self._sys_write(data)
def _sys_write(self, data):
return sys.stdout.write(data)
def _strip(self, text, char):
return text.strip(char)
def apply_strip(self, array_data, char):
return map(lambda x:self._strip(x, char), array_data)
class Drawing_data(DataUtils):
def __init__(self):
self.raw_data = self.read_data_lines()
def process_q(command_q):
MAX_ATTEMPTS = 5
attempts = 0
canvas = None
while command_q and attempts < MAX_ATTEMPTS:
inspect_command = command_q[0]
command = inspect_command[1].split(' ')[0]
if not Canvas._created and command <> 'C':
attempts += 1
logging.error('Cant draw no canvas created skipping') #args[0].split(' ')
else:
request = command_q.pop(0)
function, data = request[0], request[1].split(' ')
if command == 'C' and Canvas._created == 0:
canvas = request[0](data)
else:
request[0](data, canvas)
if Canvas._created > 0:
canvas.print_canvas()
# all calls expect the whole command line
def C(args):
canvas = Canvas(int(args[1]), int(args[2]))
return canvas
def L(args, canvas):
_, startx, starty, finishx, finishy = args
direction_x = False
var, fixed, stop, increment = 0, 0, 0, 1
#if canvas.valid_pos(startx, starty) and canvas.valid_pos(finishx, finishy):
if (int(startx) - int(finishx)): #x is not fixed, y is fixed
increment, var = (-1, int(startx)) if int(finishx) - int(startx) < 0 else (1, int(startx))
fixed = starty
stop = abs(int(finishx) - var) + int(startx)
else: #x is fixed, y is not fixed
increment, var = (-1, int(starty)) if int(finishy) - int(starty) < 0 else (1, int(starty))
fixed = startx
stop = abs(int(finishy) - var) + int(starty)
direction_x = True
while var <= stop:
if direction_x:
canvas.update_cell(var, fixed, 'x')
else:
canvas.update_cell(fixed, var, 'x')
var += increment
#else:
def R(args, canvas):
_, startx, starty, finishx, finishy = args
L(['L', startx, starty, startx, finishy], canvas)
L(['L', startx, starty, finishx, starty], canvas)
L(['L', startx, finishy, finishx, finishy], canvas)
L(['L', finishx, starty, finishx, finishy], canvas)
def B(args, canvas):
pass
def unhandled(args, canvas):
logging.error('unhandled command:%s for canvas %s' % (args, canvas))
if __name__ == '__main__':
drawing_data = Drawing_data()
drawing_data = drawing_data.prepare_data()
dispatcher = {'C':C, 'L':L, 'R':R, 'B':B}
command_q = []
for data in drawing_data:
command = dispatcher.get(data[0], unhandled)
command_q.append([command,data])
process_q(command_q)