Parker Queen
Parker Queen

Reputation: 619

How to draw this bow tie pattern using Python 2.7?

I need to draw the following pattern using Python While Loops.

enter image description here

I have spent quite a lot of time and came up with this code which prints it perfectly but this code is so much long and I feel like it is not one of those good codes.

If anybody here can help me out shrinking this code or suggesting a better way to output?

here is the code:

#Question 10, Alternate Approach
temp = 1
pattern = ""
innerSpace = 7
starCount = 1
while temp <= 5:
    st = 1
    while st <= starCount:
        pattern = pattern + "*"
        if st != starCount:
            pattern = pattern + " "
        st = st + 1
    sp = 0
    if temp == 5:
            innerSpace = 1
    while sp < innerSpace:
        pattern = pattern + " "
        sp = sp  + 1
    st = 1
    while st <= starCount:
        if temp == 5:
            st = st + 1
        pattern = pattern + "*"
        if st != starCount:
            pattern = pattern + " "
        st = st + 1
    temp = temp + 1
    innerSpace = innerSpace - 2
    pattern = pattern + "\n"
    if temp % 2 == 0:
        pattern = pattern + " "
    else:
        starCount = starCount + 1
starCount = 2
innerSpace = 1
while temp > 5 and temp <= 9:
    st = 1
    while st <= starCount:
        pattern = pattern + "*"
        if st != starCount:
            pattern = pattern + " "
        st = st + 1
    sp = 0
    while sp < innerSpace:
        pattern = pattern + " "
        sp = sp  + 1
    st = 1
    while st <= starCount:
        pattern = pattern + "*"
        if st != starCount:
            pattern = pattern + " "
        st = st + 1
    temp = temp + 1
    innerSpace = innerSpace + 2
    pattern = pattern + "\n"
    if temp % 2 == 0:
        starCount = starCount - 1
        pattern = pattern + " "        
print pattern

Upvotes: 2

Views: 1676

Answers (5)

Joshua Like
Joshua Like

Reputation: 31

Using a stars and spacing and counting variable

counting=1
star_amount=1
space_amount=6
loop_var=7
while loop_var>0:
    loop_var-=1
    if space_amount==0:
        counting*=-1
    stars=" * "*star_amount
    spaces="   "*space_amount
    print(stars+spaces+stars)
    star_amount+=counting
    space_amount-= counting*2

Upvotes: 2

Anil_M
Anil_M

Reputation: 11453

Hopefully by this time HW is done. Since I solved this using dynamic programming, I thought I would list solution here.

Observations: While looking at pattern its observed that bottom half is palindrome of top half. Hence we need to calculate only the top half.

Next we see that for every row count,we have pattern like,
row 1 = 1 , n
row 2 = 2 , n -1
row 3 = 1,3, n-2, n
row 4 = 2, 4 , n-3, n-1
.. and so on.

With iteration index as row count and n as input value we can dynamically calculate remaining values very efficiently.

Source-Code

def get_list(bound, alist):
    tmp_list = []
    for i in xrange(1,bound + 1):
        tmp_list.append(star if i in alist else dot)
    return tmp_list

star = "*"
dot = " "

n = 20 #How large of BowTie do you want?
m = (n * 2) - 1

#get  top half list
th = []
for idx,k in enumerate(xrange(1,n+1)): #run through 1 - n
    row = idx + 1
    tmplst = []
    if row % 2 != 0:
        tmplst.append(i for i in xrange(1,row + 1) if i % 2 != 0)
        tmplst.append(i for i in xrange(m, m-row, -1) if i % 2 != 0)
    else:
        tmplst.append(i for i in xrange(1,row + 1) if i % 2 == 0)
        tmplst.append(i for i in xrange(m, m-row, -1) if i % 2 == 0)
    #append each row value to  top half list.
    th.append(sorted(set([j for i in tmplst for j in i])))

#create palindrome of top half which is our bottom half 
th = th + th[len(th) -2::-1]

#create list of * and blanks
final = [get_list(m, i) for i in th]

#Print BowTie
for i in final:
    print ' '.join(i)

Upvotes: 2

Lorenzo
Lorenzo

Reputation: 162

IMHO you use while loop much as if they where for loops. I don't think that's what your teacher wants.

The idea behind while is to run until a certain condition is met, not necessarily when the number of iterations exceed a certain limit.

The condition does not need to be included in the while statement, you can check it later and use the break command to escape the loop

Try for example this:

start = '*'
while True:
    print start
    if start[0] == '*':
        start = ' ' + start
    else:
        start = '*' + start        
    if (start == '* * *'):
        break

output is just a part of your assignment, think you should be able to work it out to the final, expected result!

Upvotes: 2

wl2776
wl2776

Reputation: 4327

I would use list comprehensions and strings and would exploit the symmetry of the figure.

Not a complete solution, but could be a part of a loop body

In [2]: a = '*' + ' '*8

In [3]: a
Out[3]: '*        '
In [24]: result = ''

In [25]: result += a

In [26]: result
Out[26]: '*        '

In [27]: result += a[-1::-1]

In [28]: result
Out[28]: '*                *'

In [29]: result += '\n'

In [30]: a = ' '+'*' + ' '*7

In [31]: a
Out[31]: ' *       '

In [32]: result += a

In [33]: result += a[-1::-1]

In [34]: result += '\n'

In [36]: print result
*                *
 *              *

Upvotes: 2

user1902824
user1902824

Reputation:

Since this looks like an assignment, I'll give you a hint how I would do it.

Take advantage of the symmetry of the bow. It is symmetrical about the horizontal and vertical axis. Therefore, you really only need to solve 1 corner, then copy/mirror the results to get the rest.

This code gives one way of looking at the problem, which is just shifting a initial string (the middle of the bow) to get the desired shape:

m      = '*'
size   = 4
n      = 5 # must be odd
pad    = ' ' * n
middle = (m + pad) * size
half   = int(n / 2) + 1

print middle
print middle[half*1:]
print middle[half*2:]
print middle[half*3:]
print middle[half*4:]
print middle[half*5:]
print middle[half*6:]

Which yields this:

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

Good luck!

Upvotes: 3

Related Questions