Home > Software design >  Anyone knows an easy way to code this problem?
Anyone knows an easy way to code this problem?

Time:10-29

Write a Python program that prints a diamond made with asterisks where the diamond's height (number of rows) is determined by the value of the variable height You can (optionally) ask the user to enter the value of height.

This value can only have an odd number of rows, so you should print a descriptive message if the user enters an even value.

This is what I have, but I don't understand this... Anyone know an easier way to solve this task?

import math as m

height = int(input("Enter height - odd number: "))

if ((height > 2) and (height % 2 == 1)):
    
    a = list(range(1, m.floor(height/2)   1))
    a.append(m.ceil(height/2))
    a = a   list(reversed(list(range(1, m.floor(height/2)   1))))
    
    for h in a:
        repeat = 2*h-1
        ast = "*"*repeat
        blank = int((height - repeat) /2)
        blk = " "*blank
        print(str(blk)   str(ast)   str(blk))
        
else:
    print("The height must be a positve odd value")

CodePudding user response:

Print the decreasing, then increasing number of spaces with an increasing, then decreasing number of stars:

height = 7

for i in range(1-height,height,2):
    print(abs(i)//2*" "   "*"*(height-abs(i)))

   *
  ***
 *****
*******
 *****
  ***
   *

The progression of i from range(1-height,height,2) will be:

-6 -4 -2 0 2 4 6

which decreases and then increases if you take i's absolute value abs(i):

6 4 2 0 2 4 6

This range progression can be converted to the number of spaces and stars for each line:

spaces: abs(i)//2     = 3 2 1 0 1 2 3
stars:  height-abs(i) = 1 3 5 7 5 3 1

vertically:

spaces  stars  |  result (underlines are spaces)
  3       1    |  ___*
  2       3    |  __***
  1       5    |  _*****
  0       7    |  *******
  1       5    |  _*****
  2       3    |  __***
  3       1    |  ___*

With these numbers you can multiply the corresponding characters and get the repeated strings that you need for the pattern.

Note that it also works for even numbers, although the shape is not as pointy on the left and right sides

The loop can be converted to a comprehension in a one-liner if you want:

h = 7

print(*(i//2*' ' (h-i)*'*' for i in map(abs,range(1-h,h,2))),sep='\n')

or

for i in map(abs,range(1-h,h,2)):print(i//2*' ' (h-i)*'*')

CodePudding user response:

You can declare increasing and decreasing iterators. They tell you how many asterisks to print per row (except for the middle row).

You can easily center the asterisks with the str.center method. It's also possible to center it with a format specifier, but I find the latter less readable.

size = int(input("Enter the size of the diamond: "))
if size%2 == 0:
    raise ValueError("The size must be an odd value")

increasing = range(1, size, 2)
decreasing = reversed(increasing)

for i in increasing:
    print(("*" * i).center(size))
print("*" * size)
for i in decreasing:
    print(("*" * i).center(size))
  • Related