Asterisk art in python - python

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)

Related

Is it possible to nest all 4 of these nested For loops into one For loop with an extra level?

I'm learning Python from a textbook and one of the exercises (there is no answer key available!) wants you to create 4 patterns of asterisks. This code creates the correct output.
As you can see it is 4 separate code blocks each with nested For Loops. My question is to whether it is possible to put it all into 1 For loop that is nested one level deeper (e.g. For group in range(4) > For row in range(10) > For asterisk in range(etc.)? Or since the output of each code block is different, is this most granular I could go?
Any insight is much appreciated!
for row in range(10):
for asterisk in range(row + 1):
print('*', end='')
print()
print()
for row in range(10):
for asterisk in range(10 - row):
print('*', end='')
print()
print()
for row in range(10):
print(' ' * row, end='')
for asterisk in range(10 - row):
print('*', end='')
print()
print()
for row in range(10):
print(' ' * (9 - row), end='')
for asterisk in range(row + 1):
print('*', end='')
print()
Before trying to push the code into another level of for loops, let's try to make a function that represents the needed logic for each part.
Start with one version of the code, and stub out the parts that change. Add a function header, and stub out the parameters for now.
def triangle(...):
for row in range(10):
...
for asterisk in range(...):
print('*', end='')
print()
Notice that I did not include the print in between the triangles. That has separate logic (we want to do it every time except the first; not because of what kind of triangle we're drawing)
Before we try to figure out how to fill in the blanks, let's try to simplify the code by using what we already know. The existing code uses print(' ' * row, end='') or print(' ' * (9 - row), end='') to print a specific number of spaces (determined by row). The for loop is used to print a specific number of asterisks. Clearly, we can use the * technique instead. So:
def triangle(...):
for row in range(10):
...
print('*' * ..., end='')
print()
And having done that, we see that we have a print that deliberately suppresses the newline at the end, immediately followed by an empty print used only to display a newline. That doesn't make a lot of sense. We could just:
def triangle(...):
for row in range(10):
...
print('*' * ...)
Much better.
Next: is our logic actually conditional? In the original versions of the code, we sometimes had a print for some spaces, and other times not. But we can unify that: "not printing spaces" is the same thing as "printing zero spaces"; so really all we need is a rule that tells us how many spaces to print, and then we can use the same structure every time:
def triangle(...):
for row in range(10):
print(' ' * ..., end='')
print('*' * ...)
In fact, we can combine these prints. We want to print two things one right after the other (i.e. with an empty sep in between), and we want the default newline to be printed after that. So:
def triangle(...):
for row in range(10):
print(' ' * ..., '*' * ..., sep='')
Much better. On to the part where we actually fill in the blanks.
First off, what information do we have to pass in? We need to know two things: whether to right-align the triangle, and whether to print it upside-down or not. So those are our parameters:
def triangle(upside_down, right):
for row in range(10):
print(' ' * ..., '*' * ..., sep='')
What is the rule that tells us how many stars to print?
If the triangle is right-side-up, then we print row + 1 stars. Otherwise we need 10 - row stars. That matches the values that were passed to range in the original code.
def triangle(upside_down, right):
for row in range(10):
stars = 10 - row if upside_down else row + 1
print(' ' * ..., '*' * stars, sep='')
What is the rule that tells us how many spaces to print?
If the triangle is right-aligned, then we should print some spaces. How many? Well, for an upside-down triangle we used the row number directly. For a right-side-up triangle we need 9 - row stars. But we can simplify this, by thinking in terms of the remaining space after we account for the stars. We want a total of 10 stars plus spaces, so we can simply subtract 10 - stars to get the space count.
If the triangle is left-aligned, of course, then we print zero spaces.
def triangle(upside_down, right):
for row in range(10):
stars = 10 - row if upside_down else row + 1
spaces = 10 - stars if right else 0
print(' ' * spaces, '*' * stars, sep='')
Simple. Let's use it:
triangle(False, False)
print()
triangle(True, False)
print()
triangle(True, True)
print()
triangle(False, True)
By extracting the code first, it becomes much clearer how to iterate that code: we just need to change the arguments for the triangle calls, and take care of the intermediate prints. We have a clearly defined function that does one thing and has a reasonable name - in accordance with all the principles that a good programming book tries to teach you.
How do we repeatedly call a function with differing, constant (i.e. pre-calculated) arguments? Simple: we put those arguments in some data structure, and iterate over that. To print after each triangle except the last, our trick is to instead print before each triangle except the first, using some simple flag logic (a variable that tells us what to display - either a newline, or nothing - which changes unconditionally after displaying it).
So, for example:
# This tells us which values we will use to call `triangle` each time.
configurations = ((False, False), (True, False), (True, True), (False, True))
# This tells us what we will display before each `triangle`.
before_triangle = ''
for upside_down, right in configurations:
print(before_triangle, end='')
before_triangle = '\n'
triangle(upside_down, right)
Going over the n×n grid and letting a pattern expression decide whether to print an *:
n = 10
h = n / 2
patterns = [
lambda: i >= j,
lambda: i+j < n,
lambda: j >= i,
lambda: i+j >= n-1,
]
for p in patterns:
for i in range(n):
for j in range(n):
print(' *'[p()], end='')
print()
print()
Output (Try it online!):
*
**
***
****
*****
******
*******
********
*********
**********
**********
*********
********
*******
******
*****
****
***
**
*
**********
*********
********
*******
******
*****
****
***
**
*
*
**
***
****
*****
******
*******
********
*********
**********
Bonus patterns:
lambda: max(i,j) >= h,
lambda: abs(i-h)+abs(j-h) < h,
lambda: (i//2 | j//2) % 2,
Output:
*****
*****
*****
*****
*****
**********
**********
**********
**********
**********
*
***
*****
*******
*********
*******
*****
***
*
** **
** **
**********
**********
** **
** **
**********
**********
** **
** **
Here is one way to factor common logic out of your four for loops, and also to use string multiplication to eliminate the inner loops:
patterns = [
[(1,1), None],
[(-1,10), None],
[(-1,10), (1, 0)],
[(1,1), (-1,9)]
]
begun = False
for (sign, plus), leftPat in patterns:
print('', end = '\n' * begun)
begun = True
leftSign, leftPlus = leftPat if leftPat else (0,0)
for row in range(10):
print(' ' * (row * leftSign + leftPlus), '*' * (row * sign + plus), sep='')
Explanation:
We populate patterns with a list of pairs of tuples (also pairs) that are asterisk params (required) and space params (optional, in other words: can be None)
We iterate over the patterns
For each pattern, we use default values of (0,0) if the space params (leftPat) are None
We then use string multiplication to print the indicated number of spaces followed by the indicated number of asterisks for each row in the pattern
There is additional logic using begun to print blank lines between each pattern
If an extra blank line at the end were acceptable, this could be simplified further to:
for (sign, plus), leftPat in patterns:
leftSign, leftPlus = leftPat if leftPat else (0,0)
for row in range(10):
print(' ' * (row * leftSign + leftPlus), '*' * (row * sign + plus), sep='')
print()

How to Print Pattern Shown?

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 do I print a specifc character pattern using Python?

I am trying to print a pattern using Python but I cannot seem to figure out what I am doing wrong.
# The Pattern I am trying to create is as follows:
*******
******
*****
****
***
**
*
#Using the following code:
base = 8
for rows in range(base):
for columns in range(7,1,-1):
print('*',end='')
print()
for columns in range(7,1,-1) always prints 6 times. Maybe you meant for columns in range(7,rows,-1)? However this is easier:
for i in range(7,0,-1):
print('*' * i)
Another solution using "reverse order" slicing:
base = 8
for i in range(1, base)[::-1]:
print('*' * i)
The output:
*******
******
*****
****
***
**
*
Try the following:
for i in range(8):
print("*" * i)
That will actually print in wrong order, sorry, overlooked that.
for i in range(8,0,-1):
print("*" * i)
solution 1
for i in range(4,0,-1):
for j in range(0,i):
print('#',end=" ")
print()
solution 2
for i in range(0,4):
for j in range(0,4-i):
print('#',end=" ")
print()
You don't need to use Nested Loop You can easily do it with a simple for loop
base = 8
for rows in range(base,0,-1):
print("*"*rows)

Printing an arrow head using stars

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)

Diamond python with exactly 19 lines [duplicate]

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*'*'

Categories

Resources