John Delin
John Delin

Reputation: 31

Iteratively Drawing a 'Bow Tie' in Python

I am trying to make a code that draws a bow tie with a given input.

A bow tie:

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

I am working on 2 methods here. Can anyone tell me if I am on the correct path? I seem to be lost...

num = int(input("Enter an odd number greater than 4: "))

row = 1
row_space = row*2-1
space_tot = num*2 - row_space*2
stars = int((num*2 - space_tot)/2)

space = ""

for x in range(num):
    print("*"*stars+" "*space_tot+"*"*stars)
    row += 1
    space_tot -= 2


def triangle(n):
   for x in range(n,0,2):
        print ('*'*x)
   for x in range(n,0,-2):
        print ('*'*x)
        n -= 1


triangle(num)

Upvotes: 1

Views: 2012

Answers (3)

ssm
ssm

Reputation: 5373

When you are learning Python, it is good to look through its library functions. In Python, everything is an object. And every object has methods. Here is a link to everything you need to know about strings in Python.

https://docs.python.org/2/library/string.html

You'll get a number of functions here which directly relate to your problem. The more familier you are with the objects in Python, the better you become in programming in Python. This is true for any language. If you want to become better at a particular language, learn its specifics.

For your problem, you can learn about the methods ljust(), rjust() and join(). How do you use them?

In [126]: '[' + 'abcd'.ljust(10) + ']'
Out[126]: '[abcd      ]'

In [127]: '[' + 'abcd'.rjust(10) + ']'
Out[127]: '[      abcd]'

In [134]: '-][-'.join(['A', 'list', 'of', 'strings'])
Out[134]: 'A-][-list-][-of-][-strings'

Of course, you can replace the 'abcd' with '*'s. In this case, you have,

In [129]: ('*'*3).ljust(5) + ('*'*3).rjust(5)
Out[129]: '***    ***'

Now, you just replace the 3 with a counter for your choice. Note that your numbers increments in 2s. Before you do that, I hope you know about list comprehension. If not, you can just learn about it here:

https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions

In [132]: [('*'*i).ljust(5) + ('*'*i).rjust(n)  for i in range(1, n+2, 2)]
Out[132]: ['*        *', '***    ***', '**********']

Let us now save this in a variable, and join them together ...

    In [135]: l = [('*'*i).ljust(5) + ('*'*i).rjust(n)  for i in range(1, n+2, 2)]

    In [137]: print '\n'.join(l)
    *        *
    ***    ***
    **********

Of course, you need the other half as well. For that you will need to use nearly all of the list you created above as l. Notice:

In [138]: l # Original list
Out[138]: ['*        *', '***    ***', '**********']

In [139]: l[:-1] # Original list - the last value in the list
Out[139]: ['*        *', '***    ***']

In [140]: l[:-1][::-1] # reverse that one
Out[140]: ['***    ***', '*        *']

In [141]: l + l[:-1][::-1] # join the reversed list to the original list
Out[141]: ['*        *', '***    ***', '**********', '***    ***', '*        *']

Finally, we can join the two lists and form the bwotie:

In [143]: print '\n'.join(l + l[:-1][::-1])
*        *
***    ***
**********
***    ***
*        *

So in summary, you need 3 lines to print a bowtie:

n = 5 # Or a user input here ...
l = [('*'*i).ljust(5) + ('*'*i).rjust(n) for i in range(1, n+2, 2)]
print '\n'.join(l + l[:-1][::-1])

Hopefully, you see that it pays to go through the documentation in Python. You will be able to get a lot of useful methods, which can make coding very easy. The more familier you are with Python libraries, the better your coding. Most of these libraries are fine-tuned for a particular system, so it will be difficult to beat their effeciency as well. So you get twice the advantage, for the same amount of effort :).

Good luck with your programming.

Upvotes: 1

John Delin
John Delin

Reputation: 31

def triangle(n):
   for x in range(n,0,2):
        print ('*'*x)
   for x in range(n,0,-2):
        print ('*'*x)
        n -= 1

Upvotes: 0

John1024
John1024

Reputation: 113844

num = int(input("Enter an odd number greater than 4: "))
center = (num - 1)//2
for row in range(num):
    nspaces = 2*abs(row - center)
    nstars = num - nspaces
    print nstars*'*' + 2*nspaces*' ' + nstars*'*'

How it works

Let's look at the desired output (with row numbers added) for the case num=5:

0 *        *
1 ***    ***
2 **********
3 ***    ***
4 *        *

Let us think about this as a left half and a right half. Observe each half has num stars in the center row. The number of spaces in the center row is zero. The number of spaces in each half increases by two for each row that we move away from the center. Expressed mathematically:

nspaces = 2*abs(row - center)

Each half is num columns wide. So, if a half has nspaces spaces, then the number of stars in that half is:

nstars = num - nspaces

Having computed both of those, it is only a matter of printing it all out:

print nstars*'*' + 2*nspaces*' ' + nstars*'*'

This is done once for each row.

Upvotes: 4

Related Questions