Putting a string into a box of stars - python

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.

Related

taking argument from comprehensions list

How can I take an argument from this list so that I can put it in place of a phone?
a10 = ' ' * (2 + length)+ (' ' * length - len(str(phone))).join([str(x) for x in range(1, boardX + 1)])
The idea is that (' ' * length - len(str(phone))) determine the space between numbers depending on whether the number is one digit, two digit, etc.
In the phone place I would like to take an argument from a list to specify the number of its characters. –
example:
boardX = 14
length = 3
output:
target output:
Use a formatting operator rather than calculating spaces yourself. Yo can specify the field width indirectly using *.
a10 = " " * (2 + length) + "".join("%*d" % (length, x) for x in range(1, boardX + 1))

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).

Hollow diamond in python with an asterisk outline

I have to build a hollow diamond like this one:
******
** **
* *
* *
** **
******
Heres what I have so far,
def hollow_diamond(w):
h=int(w/2)
while 0<h:
print('*'*h)
h=h-1
i=1
while i<(w/2+1):
print(i*'*')
i=i+1
However using the code that i have i only get half of the diamond.
***
**
*
*
**
***
Should I be using for loops instead of while to be able to complete the diamond?
You've already figured out how to print the first set of asterisks for each line; good job so far. Now, you need to figure out how many spaces to print. Let's take the first loop, where you're printing h asterisks in a grid of w lines.
You need h asterisks on the left and h more on the right; that's 2*h asterisks total. This leaves s = w - 2*h spaces in the middle.
So, for each line, you need to print ...
h asterisks
s spaces
h more asterisks
Does that move you toward a useful update of your current code?
Building a hollow diamond means, like you said, probably the following:
A line with full asterisks (0 spaces in the middle)
A line with 2 spaces in the middle
A line with 4 spaces in the middle
...
A line with l-2 spaces in the middle
A line with l-2 spaces in the middle
A line with l-4 spaces in the middle
A line with l-6 spaces in the middle
...
A line with full asterisks (l-l spaces in the middle)
n is the "step", or how many asterisks you "lose" in each iteration. l is the size of your square.
So, you algorithm is composed of two parts, the increasing spaces, and the decreasing spaces.
So, your algorithm should be something like this
for (spaces = 0; spaces < size/2 ; spaces = spaces + 1 )
for (asterisk = 0; asterisk < size/2 - spaces; asterisk = asterisk + 1)
print '*'
for (space = 0; space < spaces*2; space = space + 1)
print ' '
for (asterisk = 0; asterisk < size/2 - spaces; asterisk = asterisk + 1)
print '*'
for (spaces = size/2 - 1; spaces >= 0; spaces = spaces - 1)
# The same inner code as above
I purposedly didn't put the python code there, so you can do your homework properly ;), but once you understand the algorithm, that should be pretty easy.
I won't steal from you the joy to fix your homework but this exercise was quite fun so I'll give you another possible version to give you few ideas:
def cool_diamond(w):
r = []
for y in range(w):
s = '*' * (w - y)
r.append("{0}{1}{0}".format(s, ''.join(['-' for x in range(2 * y)]), s))
return '\n'.join(r + r[::-1])
for i in range(3, 6):
print cool_diamond(i)
print('-' * 80)
I'd strongly recommend you take your time first to fix yours! Otherwise you won't learn nothing from the exercise.
Once you've fixed yours you'll feel pretty satisfied for the effort paying off, and then... just then, you can take think whether you can improve YOUR version or refactoring.
Happy coding!
******
**--**
*----*
*----*
**--**
******
--------------------------------------------------------------------------------
********
***--***
**----**
*------*
*------*
**----**
***--***
********
--------------------------------------------------------------------------------
**********
****--****
***----***
**------**
*--------*
*--------*
**------**
***----***
****--****
**********
--------------------------------------------------------------------------------
Here, remember it is only for even numbers entered else the program will execute a number less than that. I have made a code for your requirement.
n=int(input('Enter a number'))
if n%2==0:
pass
else:
n-=1
print("Works only for even number,so decremented the number by 1")
k=n//2
print(a*n)
for i in range(1,k):
print(a*(k-i),end='')
print(b*(c),end='')
print(a*(k-i),end='')
print()
c=c+2
c=c-2
for i in range(1,k):
print(a*(i),end='')
print(b*(c),end='')
print(a*(i),end='')
print()
c-=2
print(a*n)
You can also use it as function. You can easily convert so. You can use both while and for loop.
Check out while loop.
a='*' ; b=' ';c=2
n=int(input('Enter a number'))
if n%2==0:
pass
else:
n-=1
print("Works only for even number,so decremented the number by 1")
k=n//2
print(a*n)
i=1
while i<k:
print(a*(k-i),end='')
print(b*c,end='')
print(a*(k-i),end='')
print()
c=c+2
i+=1
c-=2
i=1
while i<k:
print(a*i,end='')
print(b*c,end='')
print(a*i,end='')
print()
c-=2
i+=1
print(a*n)
Hope it helps.

How to recreate pyramid triangle?

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

Categories