# Outputting a graphic using functions

How would you make this piece of code more simple/efficient? The problem should not be solved with one print statement, rather with functions

Could you also give me any advice how I can come to your simplified solution next time?

Code Used

def draw_pattern_1(p,m):
print(p, end=' ')
print(m, end=' ')
print(m, end=' ')
print(m, end=' ')
print(m, end=' ')
print(p, end=' ')
print(m, end=' ')
print(m, end=' ')
print(m, end=' ')
print(m, end=' ')
print(p)

def draw_pattern_2(l):
print(l, end='         ')
print(l, end='         ')
print(l)

def draw_grid(f_1,f_2,p,m,l):
draw_pattern_1(p,m)
draw_pattern_2(l)
draw_pattern_2(l)
draw_pattern_2(l)
draw_pattern_2(l)
draw_pattern_1(p,m)
draw_pattern_2(l)
draw_pattern_2(l)
draw_pattern_2(l)
draw_pattern_2(l)
draw_pattern_1(p,m)

p=  "+"
m = "-"
l = "|"

draw_grid(draw_pattern_1,draw_pattern_2,p,m,l)


Output Generated

+ - - - - + - - - - +
|         |         |
|         |         |
|         |         |
|         |         |
+ - - - - + - - - - +
|         |         |
|         |         |
|         |         |
|         |         |
+ - - - - + - - - - +

• Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. Commented Mar 3, 2022 at 22:21
• draw_grid("unused", NotImplemented, p, m, l) does the same thing as draw_grid(draw_pattern_1, draw_pattern_2, p, m, l), which is probably not what you intended. Commented Mar 3, 2022 at 22:43
• Welcome to Code Review@SE. Have you come across lambda expressions? Commented Mar 3, 2022 at 22:59
• Can you give an example of another draw pattern you might want to use? Are you always wanting a 2x2 grid and the draw patterns will just adjust the size of the cells, or is your goal to print a 3x4 grid given different pattern functions? Were you supposed to print grids of arbitrary sizes? What exactly is the assignment? Commented Mar 4, 2022 at 0:00
• Thanks a lot for your advices! Commented Mar 4, 2022 at 22:26

A potentially problematic part of the code above is that it does not generalize well: in essence, what your code achieves is decomposing the task into drawing lines with corners of the grid in them and drawing lines without those. The code also heavily uses lines like print(p, end=' '): at least in the case of a dash marker, this is fully equivalent to substituting that marker for a dash-space, and that is further equivalent to using print('- '*4, end='') or, indeed, hard-coding the pattern. At the end of the day, this is not much different from using a couple of print statements in the first place:

row_of_cells = '+ - - - - + - - - - +\n' + '|         |         |\n'*4
print(row_of_cells * 2, end='')
print('+ - - - - + - - - - +')


This uses string multiplication to repeat the same pattern multiple times - this is good because the height of the cell and the number of rows become explicit and we do not have to print the cell character-by-character. Still, it looks bulky and, frankly, quite ugly. Another notable issue is that while it is somewhat easy to change how the grid is drawn, the code is heavily reliant on draw_pattern_1 and draw_pattern_2 outputting matching patterns. The benefit in printing the grid with functions as opposed to a fixed, hard-coded string lies elsewhere.

So, how do we get rid of lots and lots and repetitions (DRY: Don't Repeat Yourself!) and the lack of reusability (what if we want to draw a grid of a different size or shape)? Currently, your code allows us to change the symbols used and not much else: to draw a different grid, you would need to define draw_pattern_3 and draw_pattern_4, and then draw_pattern_5... You get the idea. This is only good if you get paid by SLOC.

One approach to handle it somewhat more elegantly would be figuring out algorithmically if the current character lands on the cell border or a corner and outputting a space otherwise:

corner = '+ '
vertical = '| '
horizontal = '- '

def grid(rows, cols, cell_h, cell_w):
for i in range(rows * cell_h + 1):
for j in range(cols * cell_w + 1):
if i % cell_h == 0 and j % cell_w == 0:
c = corner
elif i % cell_h == 0:
c = horizontal
elif j % cell_w == 0:
c = vertical
else:
c = '  '
print(c, end='')
print('')  # newline
$$$$
`
• This is an alternate solution. It is not a review of the code. As described in How do I write a good answer, "Every answer must make at least one insightful observation about the code in the question. Answers that merely provide an alternate solution with no explanation or justification do not constitute valid Code Review answers and may be deleted." Commented Mar 4, 2022 at 17:37
• @AJNeufeld Thank you. I will edit the answer shortly. Commented Mar 4, 2022 at 17:39
• Thanks a lot for your review and your advice! This was a big help Commented Mar 4, 2022 at 22:25