How to recreate pyramid triangle? - python

I have to write a recursive function asterisk_triangle which takes an integer and then returns an asterisk triangle consisting of that many lines.
As an example this is a 4 line asterisk triangle.
*
**
***
****
I have tried this function:
def asterix_triangle(depth):
rows = [ (depth-i)*' ' + i*2*'*' + '*' for i in range(depth-1) ]
for i in rows:
print i
And the following function:
def asterisk_triangle(rows=n):
pyramid_width = n * 2
for asterisks in range(1, pyramid_width, 2):
print("{0:^{1}}".format("*" * asterisks, pyramid_width))
And neither worked. I am supposed to make tests.py to test the functions and I get errors for e.g
Traceback (most recent call last):
File "C:\Users\akumaukpo\Documents\CISC 106\LAB05\lab05 _test.py", line 19, in <module>
from lab05 import *
File "C:\Users\akumaukpo\Documents\CISC 106\LAB05\lab05.py", line 22
print i
^

Every statement in a block must be indented by at least one space from the start of the block. The print statement in your code is not indented relative to the for block it is contained in, which is why you have the error.
Try this:
def asterix_triangle(depth):
rows = [ (depth-i)*' ' + i*'*' + '*' for i in range(depth) ]
for i in rows:
print i
Which yields:
>>> asterix_triangle(4)
*
**
***
****
EDIT:
I just realised your desired output is to have both halves of a triangle. If so, just mirror the string by adding the same thing to the right side of the string:
def asterix_triangle(depth):
rows = [ (depth-i)*' ' + i*'*' + '*' + i*'*' for i in range(depth) ]
for j in rows:
print j
The output:
>>> asterix_triangle(4)
*
***
*****
*******

If you need to do a pyramid recursively you probably need to do something like this.
def asterix_triangle(i, t=0):
if i == 0:
return 0
else:
print ' ' * ( i + 1 ) + '*' * ( t * 2 + 1)
return asterix_triangle(i-1, t + 1)
asterix_triangle(5)
The idea is that you use two variables. One which is i that that subtract once every time the function is called and is used to end the cycle. The other variable is used to have an incremental increase. You then use i to print the number of spaces, and t the number of stars.
The output would be:
*
***
*****
*******
*********

for i in range(10):
print((' '*(10-i-1))+(('*')*((2*i)-1)))
The output is as shown in the link

Related

Putting a string into a box of stars

I am beginning in python programming and I have this exercise that requires me to put text into a box of stars.
Example :
*******
* I *
* am *
* in *
* a *
* box *
*******
I print this :
********
* I *
* am *
* in *
* a *
* box! *
********
So far I have this, I feel like I am close to the solution.
phrase = "I am in a box!"
phraseSplit = phrase.split(' ')
longuestString = max(phraseSplit, key=len)
#print(len(longuestString))
def maxStars(longuestString):
stars = (len(longuestString)+4) * "*"
print(stars)
maxStars(longuestString)
for i in range(len(phraseSplit)):
delta = len(longuestString) - len(phraseSplit[i])
space = int(delta/2 +1)
print("*" + space * " "+ phraseSplit[i] + space * " " +"*")
maxStars(longuestString)
Help me optimize or find other ways that could be more efficient.
Thank you
Here's how I would do it:
phrase = "I am in a box"
words = phrase.split(' ')
longest = max(words, key=len)
width = len(longest)
pretty = "\n".join(["*"*(width+4),*[f"* {w[::-1].center(width)[::-1]} *" for w in words],"*"*(width+4)])
print(pretty)
*******
* I *
* am *
* in *
* a *
* box *
*******
Now let's break it down!
First we do what you did, splitting the phrase into words and extracting other helpful data:
phrase = "I am in a box"
words = phrase.split(' ')
longest = max(words, key=len)
width = len(longest)
Then comes the real algorithm. Let's make a list of one string per line. Clearly the first and last lines are going to be the length of the longest plus 4 (i.e. (wall + padding)*2).
So at the start and end of the list we put:
"*"*(width+4)
Then we need to fill in the actual meat of the box. We're going to use a list iteration to make as many string as there are lines, and join each line with \n:
[line_contents for w in words]
But we need to actually have line_contents be something for each line. So let's replace that with an f-string.
At the start and end of each line there is the padding (ignoring the extra padding the small words have) and an asterisk. So our f-string is currently f"* {padded_word} *".
To actually make the padded words, we can use str.center(width). This gives the whole f-string as f"* {w.center(width)} *".
Now putting everything together we get:
"\n".join(["*"*(width+4),*[f"* {w.center(width)} *" for w in words],"*"*(width+4)]
NOTE: I used the * operator to unpack the list iteration into the larger list.
If we run the program we get:
*******
* I *
* am *
* in *
* a *
* box *
*******
Looks good! But wait one moment - it seems like str.center is making the off-center words go to the right! This is contrary to your example.
However, there's an easy solution: reverse the word, pad it, then reverse it back. This will make the off-center words go left instead. To reverse any indexable object, you can use slice notation: [start, stop, step] --> [beginning, end, -1] --> [::-1].
Now if we add this into what we have so far, we get what I presented initially.
I finally found my own answer :
phrase = "Hi I am in a box!"
phraseSplit = phrase.split(' ')
longuestString = max(phraseSplit, key=len)
#print(len(longuestString))
def maxStars(longuestString):
stars = (len(longuestString)+4) * "*"
print(stars)
maxStars(longuestString)
for i in range(len(phraseSplit)):
delta = len(longuestString) - len(phraseSplit[i])
space = int(delta/2 +1)
if (delta % 2) != 0:
print("*" + space * " "+ phraseSplit[i] + space * " " +" *")
else:
print("*" + space * " "+ phraseSplit[i] + space * " " +"*")
maxStars(longuestString)
I am aware there are optimal ways to do this and I need to figure it out.

Newline in Separate print statement [duplicate]

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)

How to draw a parallelogram with characters in python?

def parallelogram(a,b):
for i in range(a,0,-1):
for j in range (i,0,-1):
print("*",end='')
for j in range(b,0,-1):
print("+",end='')
for k in range(a-i,0,-1):
print("*",end='')
ı want to write a function which can draw a parallelogram with characters in python.ı couldnt.how can i fix my code?
output must looks like this:
****++++*
***++++**
**++++***
*++++****
With ASCII art you better first analyze the problem. If we want to draw a parallellogram with height a and width w, we first need to think how the first, second, i-th line, etc will look like.
The first line of the prallellogram will contain a asterisks (*), followed by b plusses (+) followed by one asterisk (*). We can write this as:
line1 = '*' * a + '+' * b + '*'
This of course does not solves the entire problem. The second line is almost equal to the first one, except that there is one asterisk less on the left side, and one more on the right side. So:
line2 = '*' * (a-1) + '+' * b + '*' * 2
Every line will remove one asterisk on the left, and add one on the right. So that means that linei has:
linei = '*' * (a+1-i) + '+' * b + '*' * i
Since the parallellogram has a such lines, we can range i from 1 to a+1:
for i in range(1, a+1):
linei = '*' * (a+1-i) + '+' * b + '*' * i
print(linei)
We can simplify this a bit, and write it as:
def parallelogram(a,b):
for i in range(1, a+1):
print('*' * (a+1-i) + '+' * b + '*' * i)
To start with, you are printing with end='', which causes subsequent characters to be printed on the same line. But at some point in your code, you need to add a print() to print on the next line. Start there and see if you figure out where else it needs improvement.

Creating pattern using simple loops?

I am trying to create this pattern in python:
*
* *
* * *
* *
*
This is my program so far that I've come up with:
ster = "*"
space = " "
lines = 0
n = 3
x = 1
while lines <= 5:
print space*n, ster*x
n-= 1
x+= 1
lines += 1
What am I doing wrong?
Okay, first of all you can create a list of numbers which represents the number of stars in each line.
number_of_stars = 5
i_list = list(range(number_of_stars))
# extend the list by its inverse i_list[::-1]
# but exclude the first item
i_list.extend(i_list[::-1][1:])
print(i_list) # prints: [0, 1, 2, 3, 4, 3, 2, 1, 0]
Now you can go thru the list and print a multiple of *
for i in i_list:
print('* ' * i)
But this is not aligned properly. By adding multiple empty spaces to the left one can archive a solution:
for i in i_list:
print(' ' * (number_of_stars - i) + '* ' * i)
Note that in python one can repeat a string by using the multiplication symbol:
print('a'*5) # prints: aaaaa
Thank you for the help, I wrote a functional code for the problem. It was supposed to made using while loop(s).
This is what I did:
width = int(input("Width: "))
i = 1
while i < width*2:
if i < width:
print " " * (width-i) + "* " * i
else:
print " " * (i-width) + "* " * (2*width-i)
i = i + 1
Notice you have
3 spaces for 1 star
2 spaces for 2 stars
1 space for 3 stars.
For the upright triangle part of your diamond (including the large part). Then you have
2 spaces for 2 stars
3 spaces for 1 star
Without throwing out the answer, try analysing a certain pattern in what i've just pointed out. It can be achieved with 2 loops ( for or while, depending on your preference).

Using a for-loop to reference each item in a list (instead of just the last item)

I do not understand how to reference each item in a list as opposed to just the last item when using a for-loop. Here is a simple program where I want to print a n-*'s on a line where n is each number in the stars list. Here is my code:
#!/usr/bin/python
def histogram():
stars = [10,2,3]
for i in stars:
char = "*" * i
return char
print histogram()
The output of this code is only *** (the last number in stars). How can I get it to print out the stars for each number? Please use the simplest syntax and explanation possible.
As it is, your function only returns the last value which was assigned to 'char' - this value will be a single string consisting of stars. What you would like to do, is create a list of the successive values that 'char' takes at each iteration of the loop:
def histogram():
stars = [10,2,3]
characters = []
for i in stars :
cur_stars = "*" * i
characters.append( cur_stars )
print cur_stars
return characters
>>> stars = histogram()
**********
**
***
The above will print out the stars, line by line, and will store the list as the variable, 'stars'.
A faster/cleaner way to do the same thing is a list comprehension (a functional programming structure), which creates your list on the fly:
def histogram():
stars = [10,2,3]
return [ "*" * i for i in stars ]
>>> histogram()
['**********', '**', '***']
>>> print('\n'.join( histogram() ))
**********
**
***
The problem is that for each item in the stars, you are reassigning char. Therefore, by the time that histogram() returns, char is equal to "*" * stars[-1] (the last item in the list). The simplest way to rectify this is to just print char for each element in stars and not return anything.
def histogram():
stars = [10,2,3]
for i in stars:
char = "*" * i
print char
histogram()
**********
**
***
If you would like to instead return the output from histogram, you could add to char instead of assigning it to a new value. To do this, we set char to be an empty string ('') outside of the for-loop, and then inside the for-loop we use char += (which is equivalent to char = char +) to add to char. The '\n' is to add a newline between each item in stars (without it, all of the stars would be on one line in the output).
def histogram():
stars = [10,2,3]
char = ''
for i in stars:
char += "*" * i + '\n'
return char
print histogram()
A much more concise way of writing the above is:
def histogram():
stars = [10,2,3]
return '\n'.join('*' * i for i in stars)
print histogram()
Consider:
def histogram(li):
rtr=[]
for n in li:
rtr.append('*'*n)
return rtr
Then you can do something like:
stars=[10,2,3]
for t in zip(stars, histogram(stars)):
print('{:4d} {}'.format(*t))
Prints:
10 **********
2 **
3 ***
#!/usr/bin/python
def histogram():
stars = [10,2,3]
stars_str = ""
for i in stars :
stars_str += "*" * i + '\n'
return stars_str.strip()
print histogram ()

Categories