How to print a rhomboid shape in Python?
Question:
How can I change this code that instead of printing the shape below, it prints it like a lozenge (rhomboid)?
def star (m):
for i in range (m + 1):
print ("*" * i)
for i in range ( m + 1 ):
print ("*" * (m - 1))
m -= 1
Output
*
**
***
****
***
**
*
Answers:
Is this what you wanted?
def star(m):
for i in range(1, m + 1):
print(("*" * i).center(m))
for i in reversed(range(1, m)):
print(("*" * i).center(m))
star(10)
Output:
*
**
***
****
*****
******
*******
********
*********
**********
*********
********
*******
******
*****
****
***
**
*
I like the following a bit better because it’s more symmetrical:
def star(m):
def star_line(n):
print('{s:^{f:d}s}'.format(s='*'*n, f=m))
for i in range(1,m,2):
star_line(i)
for i in range(m,0,-2):
star_line(i)
star(5)
*
***
*****
***
*
This solution uses the nice feature of Python’s new(er) formatting syntax which enables you to specify the width of a field dynamically as well as the contents of the field: e.g. '{s:^{f:d}}'.format(s='*'*3, f=5)
becomes '{s:^5s}'.format(s='***')
which becomes ' *** '
.
A lozenge is equilateral, a rhomboid typically not. For illustration, I will do a rhomboid, but allow it to be equilateral.
To define a function, you should first specify the domain, in this case positive ints (or include 0 if you wish).
Functions should generally return an object that can be compared with the desired output for a given input. You can then write an automated test for example outputs. In this case, the function should produce an iterable of strings. The desired output can most easily be represented as a tuple or list of strings and the function output converted if necessary.
r43 = (
'****',
' ****',
' ****',
)
def rhom(width, height):
if not(isinstance(width, int) and width > 0 and
isinstance(height, int) and height > 0):
raise ValueError('width and height must be positive ints')
stars = width * '*'
for i in range(height):
yield i * ' ' + stars
out43 = tuple(rhom(4, 3))
print(r43 == out43)
for line in out43:
print(line)
prints
True
****
****
****
def print_lozenge(num):
str = '*'
str_2 = str + (num - 1) * ' *'
size = 2 * num - 1
for n in range(num):
print str.center(size, ' ')
str += ' *'
for n in range(num):
str_2 = str_2[: -2]
print str_2.center(size, ' ')
print_lozenge(5)
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
I think This is what You’re looking for:
for i in range(lines+1):
if i<=middle:
for j in range(0, (middle-i)):
print(end=' ')
for j in range(i):
print('*',end=' ')
else:
for j in range(i+middle, lines+1, -1):
print(end=' ')
for j in range(i, lines+1):
print('*', end=' ')
print()
How can I change this code that instead of printing the shape below, it prints it like a lozenge (rhomboid)?
def star (m):
for i in range (m + 1):
print ("*" * i)
for i in range ( m + 1 ):
print ("*" * (m - 1))
m -= 1
Output
*
**
***
****
***
**
*
Is this what you wanted?
def star(m):
for i in range(1, m + 1):
print(("*" * i).center(m))
for i in reversed(range(1, m)):
print(("*" * i).center(m))
star(10)
Output:
*
**
***
****
*****
******
*******
********
*********
**********
*********
********
*******
******
*****
****
***
**
*
I like the following a bit better because it’s more symmetrical:
def star(m):
def star_line(n):
print('{s:^{f:d}s}'.format(s='*'*n, f=m))
for i in range(1,m,2):
star_line(i)
for i in range(m,0,-2):
star_line(i)
star(5)
*
***
*****
***
*
This solution uses the nice feature of Python’s new(er) formatting syntax which enables you to specify the width of a field dynamically as well as the contents of the field: e.g. '{s:^{f:d}}'.format(s='*'*3, f=5)
becomes '{s:^5s}'.format(s='***')
which becomes ' *** '
.
A lozenge is equilateral, a rhomboid typically not. For illustration, I will do a rhomboid, but allow it to be equilateral.
To define a function, you should first specify the domain, in this case positive ints (or include 0 if you wish).
Functions should generally return an object that can be compared with the desired output for a given input. You can then write an automated test for example outputs. In this case, the function should produce an iterable of strings. The desired output can most easily be represented as a tuple or list of strings and the function output converted if necessary.
r43 = (
'****',
' ****',
' ****',
)
def rhom(width, height):
if not(isinstance(width, int) and width > 0 and
isinstance(height, int) and height > 0):
raise ValueError('width and height must be positive ints')
stars = width * '*'
for i in range(height):
yield i * ' ' + stars
out43 = tuple(rhom(4, 3))
print(r43 == out43)
for line in out43:
print(line)
prints
True
****
****
****
def print_lozenge(num):
str = '*'
str_2 = str + (num - 1) * ' *'
size = 2 * num - 1
for n in range(num):
print str.center(size, ' ')
str += ' *'
for n in range(num):
str_2 = str_2[: -2]
print str_2.center(size, ' ')
print_lozenge(5)
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
I think This is what You’re looking for:
for i in range(lines+1):
if i<=middle:
for j in range(0, (middle-i)):
print(end=' ')
for j in range(i):
print('*',end=' ')
else:
for j in range(i+middle, lines+1, -1):
print(end=' ')
for j in range(i, lines+1):
print('*', end=' ')
print()