This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
ASCII Python Art # 2
i = 10
while i>0:
print i*'*' + 2*(10-i)*' ' + i*'*'
i -=1
for x in range(1,11):
print x* '*' + 2*(10-x)*' '+ x*'*'
x +=1
I am trying to make a asterisk diamond with 19 lines.
I get 20 instead.
This is what I want:
********************
********* *********
******** ********
******* *******
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********************
How can I get rid of the doubling up in height in the middle of the asterix.
cheers.
The basic idea is to decide which loop should print the line with just a single start on each side. Then modify the other loop not to print that line (i.e. end or start with the 2-star line).
Change
for x in range(1,11):
to
for x in range(2,11):
Also, you can get rid of the very last line, as the second loop does all the incrementing of x on its own.
For readabilities sake I'd also switch to just a single kind of loop.
For example you can write the first loop using (notice: this loop will not run the x=1 case, so you'd have to use the unmodified version of your second loop).
for x in range(10, 1, -1):
print x* '*' + 2*(10-x)*' '+ x*'*'
You've already worked out how to print each line.
Now the last part is to generate the correct sequence of number to drive the line printing.
l = range(10,1,-1)
l.extend(range(1,11))
for x in l:
print x*'*' + 2*(10-x)*' ' + x*'*'
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
********************
********* *********
******** ********
******* *******
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********************
I had some difficulty to find the trick:
def diamond(ni):
li = [ i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
li.extend(i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in range(2,ni+1))
return '\n'.join(li)
print diamond(7)
draws
*************
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
*************
Noticing that
li.extend(i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in range(2,ni+1))
does the same (less one line) than
li = [ i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
but in reverse order, we can simplify:
def symetric_diamond(ni):
li = [i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
li.extend(li[-2::-1])
return '\n'.join(li)
Please, note that
print '\n'.join(str(i) for i in xrange(500))
is displayed instantly, because the program computes the string '\n'.join(str(i) for i in xrange(500)) before to print it in one shot, while
for i in xrange(500):
print str(i)
is far longer to be displayed, because the computer prints 500 strings one after the other, and each call to print is long
.
There's another manner to print a diamond,I will write it now.
Plus
def format_diamond(nl):
ni = (nl+1)/2
li = ['{:{fill}{align}{width}}'.format((2*(ni-x) - 1)*' ',fill='*',align='^',width=2*ni-1)
for x in xrange(ni,0,-1)]
li.extend(li[-2::-1])
return '\n'.join(li)
-> all these functions give a diamond of nl-1 lines when nl is even.
Edit
Finally, what I prefer is:
def symetric_diamond(nl):
'''Returns a diamond of nl lines if nl is odd,
and nl-1 lines if nl is even'''
ni = (nl+1)//2
li = [ (2*ni-1) * '*' ]
li.extend(i*'*' + (2*(ni-i) - 1)*' ' +i*'*' for i in xrange(ni-1,0,-1))
li += reversed(li[0:-1]) # in-place extension
return '\n'.join(li)
because of the in-place extensions (with extend and reversed) and the absence of the horrid (i - i//ni)*'*'
x = list(range(0, 20, 2))
x += reversed(x[:-1])
for _ in x:
stars, spaces = "*" * ((20 - _) / 2), " " * _
print stars + spaces + stars
As you are doubling code, you could rewrite your program to
def line(x): print x* '*' + 2*(10-x)*' '+ x*'*'
i = 10
while i>0:
line(i)
i -=1
for x in range(1,11):
line(x)
# x +=1 # unnecessary - happens already due to the for loop
And now, you can make one loop out of the two (removing the function again):
rg = list(range(10, 1, -1)) + list(range(1, 11))
for x in rg:
print x* '*' + 2*(10-x)*' '+ x*'*'
Related
How do I print pattern in python as shown below:
My code:
for outer_loop in reversed(range(1, 5+1)):
for inner_loop in range(0,outer_loop):
# print(inner_loop*' ')
print('*',end='')
print()
Output:
*****
****
***
**
*
I want to give spaces on left side as shown below,
Expected Output:
*****
****
***
**
*
There is a method rjust on strings:
for n in range(5, 0, -1):
print( (n*"*").rjust(5) )
You don't need reversed(), range() can return a reversed range by using a negative step.
You can multiply a string to duplicate it, instead of using a loop.
Add the spaces by printing 5 - n spaces before n asterisks.
for n in range(5, 0, -1):
print(" " * (5-n) + "*" * n)
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
*
**
***
****
***
**
*
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
****
****
****
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 ' *** '.
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)
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
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 want to make this "diamond":
********************
********* *********
******** ********
******* *******
****** ******
***** *****
**** ****
*** ***
** **
* *
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********************
I can make the 4 triangles that make the diamond using while loops:
x = 10
while 0 < x < 11:
print '%10s' % ('*' * x),
x = x - 1
print
x = 0
while x < 11:
print '%10s' % ('*' * x),
x = x + 1
print
x = 10
while 0 < x < 11:
print '%0s' % ('*' * x),
x = x - 1
print
x = 0
while x < 11:
print '%0s' % ('*' * x),
x = x + 1
print
Can I bring together these 4 while loops to make the diamond? Or do I have to do it a different way?
I suggest you do it using string formatting (you can experiment with the parameters):
a = range(0,20,2)+range(20,-1, -2)
for i in a:
print '{:*^30}'.format(' '*i)
[OUTPUT]
******************************
************** **************
************* *************
************ ************
*********** ***********
********** **********
********* *********
******** ********
******* *******
****** ******
***** *****
****** ******
******* *******
******** ********
********* *********
********** **********
*********** ***********
************ ************
************* *************
************** **************
******************************
What the code above does is it first creates a list a that contains the number of spaces for each of the lines. Then the string formatting prints a line for each element in the list of length 30 (the 30 part of {:*^30} which is centered ^ and padded on either sides with *. Hope that helps.
Or just for fun: one-linered:
for i in range(1,20,2)+range(19,-1, -2):print '{:*^30}'.format(' '*i)
A very straightforward way is to use two loops:
def diamond(n):
for i in range(n, 0, -1):
print '*' * i + (' ' * (n-i) * 2) + '*' * i
for i in range(1, n+1):
print '*' * i + (' ' * (n-i) * 2) + '*' * i
I am trying to print out an arrow head using *s.
So far my code looks like this.
def head(n):
while n > 0:
print n * "*"
n = n - 1
print head(input())
and it works but if for example I enter 11, it prints this:
***********
**********
*********
********
*******
******
*****
****
***
**
*
But I want it to print like this:
*
***
*****
*******
*********
***********
Which has less arrows, but I can't figure out how to do it.
It makes the function a little simpler to think in terms of how many lines do you want:
def head(lines):
for n in range(1,lines*2,2): # count 1,3,5...
print(('*'*n).center(lines*2-1))
Output:
>>> head(5)
*
***
*****
*******
*********
Here's an alternate way to use a variable length format that is a little less obvious:
def head(lines):
for n in range(1,lines*2,2):
print('{:^{}}'.format('*'*n,lines*2-1))
use string formatting:
def head(size):
n=1
while n < size+1:
stars = n * "*"
print '{:^30}'.format(stars)
n += 2
it will center your asterisks on the field 30 chars wide.
def printHead(n):
for l in range(1,n):
print " "*(n-l)+"*"*(1 if l==1 else 2*l-1)
Each row has level-1 spaces. Then if it's the first level one start, otherwise it has 2*level-1.
>>> printHead(6)
*
***
*****
*******
*********
def head(n):
total = 2 * n - 1
s = ''
for i in xrange(1, n + 1):
k = 2 * i - 1
s += ' ' * ((total - k) / 2) + '*' * k + '\n'
return s
The number of stars on a line is equal to 2n - 1 where n is the line number.
I wouldn't call the parameter "n" in this function as it is not clear to me whether it refers to lines or stars.
You can use the center function to surround a string with whitespace, based on a specified width. You want the arrow to be centred around the longest line so you need 2 variables, one to keep track of the current line and another to remember the largest line.
You want to iterate in the opposite direction to what you have demonstrated, as you want the arrow to point up, not down.
I think this should work for you:
def head(total_lines):
for current_line in range(1, total_lines + 1):
print ((2 * current_line - 1) * "*").center(2 * total_lines - 1)
I would like to produce this picture in python!
*
**
***
****
*****
******
*******
********
*********
**********
I entered this:
x=1
while x<10:
print '%10s' %'*'*x
x=x+1
Which sadly seems to produce something composed of the right number of dots as the picture above, but each of those dot asterisks are separated by spaced apart from one another, rather than justified right as a whole.
Anybody have a clever mind on how I might achieve what I want?
'%10s' %'*'*x
is being parsed as
('%10s' % '*') * x
because the % and * operators have the same precedence and group left-to-right[docs]. You need to add parentheses, like this:
x = 1
while x < 10:
print '%10s' % ('*' * x)
x = x + 1
If you want to loop through a range of numbers, it's considered more idiomatic to use a for loop than a while loop. Like this:
for x in range(1, 10):
print '%10s' % ('*' * x)
for x in range(0, 10) is equivalent to for(int x = 0; x < 10; x++) in Java or C.
string object has rjust and ljust methods for precisely this thing.
>>> n = 10
>>> for i in xrange(1,n+1):
... print (i*'*').rjust(n)
...
*
**
***
****
*****
******
*******
********
*********
**********
or, alternatively:
>>> for i in reversed(xrange(n)):
... print (i*' ').ljust(n, '*')
...
*
**
***
****
*****
******
*******
********
*********
**********
My second example uses a space character as the printable character, and * as the fill character.
The argument to ljust or rjust is the terminal width. I often use these for separating sections with headings when you have chatty debug printout, e.g. print '--Spam!'.ljust(80, '-').
It's because of the operator precedence, use this one:
x=1
while x<10:
print '%10s' % ('*'*x)
x=x+1
print '\n'.join(' ' * (10 - i) + '*' * i for i in range(10))
To be exact, as your picture ends with 10 asterisks, you need.
for i in range(1, 11):
print "%10s"%('*' *i)