pythonloopsrangeshapespuzzle

Printing a star shape using loops in python


I was trying to write a python code that would print a star shape using loops but I just can't get the shape right. Please suggest some corrections.

This is my terminal: this is the image of my terminal

This is my code:

for i in range(1,11):
    if i == 1:
        print(' '*39 + '*')
    elif i == 10:
        print(" "*12 +'*'*19+ ' '*17 + '*'*19)
    else :
        print(' '*(4*10-i) + '*' + ' '*(2*i-3) + '*')
for p in range(11,17):
    print(' '*(p*2-9)+'*'+(' '*(63-p) +"*"))

It should a five pointed star but with asterisk:

It should a five pointed star but with asterisk


Solution

  • I would like to educate you about the Bresenham algorithm so that you don't create some bulky code full of magic numbers each time you want to draw a shape.

    Drawing any shape boils down to

    1. Use a character array filled with spaces,
    2. define the coordinates of your shape,
    3. draw into the array
    4. print the array

    Here is some code that gets you started:

    def draw_line(x1, y1, x2, y2, char='*'):
        """Draw a line on a 2D character array using Bresenham's algorithm."""
        dx = abs(x2 - x1)
        dy = abs(y2 - y1)
        sx = 1 if x1 < x2 else -1
        sy = 1 if y1 < y2 else -1
        err = dx - dy
    
        while True:
            lines[y1][x1] = char
            if x1 == x2 and y1 == y2:
                break
            err2 = err * 2
            if err2 > -dy:
                err -= dy
                x1 += sx
            if err2 < dx:
                err += dx
                y1 += sy
    
    # Fill a 2D character array (60x30) with spaces
    lines = [[' ' for _ in range(60)] for _ in range(30)]
    
    # Define the star shape using coordinates
    star_shape = [(30, 0),
                    (35, 10),
                    (59, 10),
                    (40, 17),
                    (50, 29),
                    (30, 22),
                    (10, 29),
                    (20, 17),
                    (0, 10),
                    (25, 10)
    ]
    
    # Draw the star shape
    for i in range(len(star_shape)):
        x1, y1 = star_shape[i]
        x2, y2 = star_shape[(i + 1) % len(star_shape)]
        draw_line(x1, y1, x2, y2)
    
    # Print the star
    for line in lines:
        print(''.join(line))
    

    This outputs:

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

    Nice thing is, you can easily change size, resolution, etc. without having to count characters every time.

    For example, draw_line(x1//2, y1//2, x2//2, y2//2, '+') scales and uses a different marker with just one line changed.