patternpythonMinor
Triangle Tessellation Project
Viewed 0 times
triangletessellationproject
Problem
I have this Python project to draw tessellated triangles on the screen. It takes the height to form the size of the triangle, cols to specify how many triangles on a line, and rows which is how many lines it outputs.
This program has taken me some time to put together and I'm not sure if this is the best way to do this. The first line is just the normal triangle, the second line and every other line after however only should show half of the triangle on the first and last column.
Here's my .py file:
Here is some sample output:
```
*
This program has taken me some time to put together and I'm not sure if this is the best way to do this. The first line is just the normal triangle, the second line and every other line after however only should show half of the triangle on the first and last column.
Here's my .py file:
import sys
print("make sure shell in full screen so the triangles are viewed properly... or disable word wrap :)")
height = int(input("height"))
cols = int(input("cols"))
rows = int(input("rows"))
MAX_PAGE_WIDTH = 19 * 8
width = height * 2 - 1
if((width * cols) > MAX_PAGE_WIDTH):
print("Triangles not gonna fit on page, please enter smaller params... :/")
sys.exit()
def get_even_number(num):
return num % 2 == 0
triangle = ""
for column_row in range(rows):
half_space = height - 1
stars = 1
for row_of_triangle in range(height):
if(get_even_number(column_row)):
for column in range(cols):
triangle += " " * (half_space + 1) + "*" * stars + " " * half_space
else:
for column in range(cols + 1):
if(not(column == 0)):
triangle += " " * (half_space + 1)
if(column == 0 or column >= cols):
sub = row_of_triangle
if(column >= cols):
sub += 1
triangle += "*" * (stars - sub)
else:
triangle += "*" * stars
if(column < cols):
triangle += " " * half_space
half_space -= 1
stars += 2
triangle += "\n"
print(triangle)Here is some sample output:
input: height: 6 cols: 6 rows: 4```
*
Solution
Using the
It would definitely be a good idea to split the work into functions. The input validation code is unrelated to the output routine. The output routine, in turn, can be decomposed into smaller reusable units. In particular, it is helpful to observe that the odd rows are like the even rows, but upside-down and colour-inverted.
Additional remarks:
-
Using extra spaces to align equals signs is discouraged in PEP 8, the official Python style guide. In this case, I really think you have overdone it.
* operator to repeat strings is smart, but there are still a lot of nested ifs and and fors. In Python, excessive looping can often be remedied using list comprehensions and itertools.It would definitely be a good idea to split the work into functions. The input validation code is unrelated to the output routine. The output routine, in turn, can be decomposed into smaller reusable units. In particular, it is helpful to observe that the odd rows are like the even rows, but upside-down and colour-inverted.
from itertools import chain, cycle, islice
def tesselated_triangles(height, cols, rows):
def triangle_row(height, cols, space=' ', fill='*'):
return [
(
space * (height - i) +
fill * (2 * i + 1) +
space * (height - i - 1)
) * cols
for i in range(height)
]
def alt_triangle_row(height, cols, space=' ', fill='*'):
return reversed(triangle_row(height, cols, space=fill, fill=space))
return '\n'.join(chain.from_iterable(
row(height, cols)
for row in islice(cycle([triangle_row, alt_triangle_row]), rows)
))
print(tesselated_triangles(6, 6, 4))Additional remarks:
- Since strings in Python are immutable, repeated string concatenation should be avoided. Appending just a single character using
+=involves allocating and copying the entire string. For this application, you should use'\n'.join(…). (Doing'\n'.join(…)would also avoid printing two newlines at the end of the output, which is wrong in my opinion.)
- If the program failed, it would be a good idea to call
sys.exit()with a non-zero status code.
- It is uncommon in Python to write
if(…):using parentheses.
-
Using extra spaces to align equals signs is discouraged in PEP 8, the official Python style guide. In this case, I really think you have overdone it.
half_space -= 1
stars += 2
triangle += "\n"get_even_number()is poorly named. You're not retrieving anything; you're testing something. An appropriate name would beis_even_number()or simplyis_even(). You could just eliminate the function, though, since it's so simple.
Code Snippets
from itertools import chain, cycle, islice
def tesselated_triangles(height, cols, rows):
def triangle_row(height, cols, space=' ', fill='*'):
return [
(
space * (height - i) +
fill * (2 * i + 1) +
space * (height - i - 1)
) * cols
for i in range(height)
]
def alt_triangle_row(height, cols, space=' ', fill='*'):
return reversed(triangle_row(height, cols, space=fill, fill=space))
return '\n'.join(chain.from_iterable(
row(height, cols)
for row in islice(cycle([triangle_row, alt_triangle_row]), rows)
))
print(tesselated_triangles(6, 6, 4))half_space -= 1
stars += 2
triangle += "\n"Context
StackExchange Code Review Q#145364, answer score: 5
Revisions (0)
No revisions yet.