Using for loop to stylize strings into ASCII art - python

I am trying to get this output:
+-+-+-+-+-+-+
|P|Y|T|H|O|N|
+-+-+-+-+-+-+
Is it possible to get that output without adding new lines in the code?
def art(name):
for i in range(len(name[0]), len(name) + 1):
head = "+" + i * "-+"
middle = "|" + i * "{}|".format(name[0].upper())
bottom = "+" + i * "-+"
print(head + "\n" + middle + "\n" + bottom)
art("Python")
Actual output:
+-+-+-+-+-+-+
|P|P|P|P|P|P|
+-+-+-+-+-+-+
I can't figure out how to manipulate it in order to get it to work. I've tried to use use index() and i as a variable but I get errors such as: "IndexError: string index out of range"

You have hardcoded the index 0 when you're looking up the character to print:
def art(name):
for i in range(len(name[0]), len(name) + 1):
head = "+" + i * "-+"
middle = "|" + i * "{}|".format(name[0].upper())
^-- here
bottom = "+" + i * "-+"
print(head + "\n" + middle + "\n" + bottom)
art("Python")
Instead, you can use i to reference the actual character in name:
middle = "|" + i * "{}|".format(name[i].upper())
You also have an error in your range. There is no need to use len(name[0]) - this will always be 1, and will cause your loop to run one iteration longer than the length of name (since indexes start on 0). This is the cause of your IndexError.
Instead, use 0 as the start - which is the same as not giving a start argument at all:
for i in range(len(name)):
But you don't actually need the index; there is no need to iterate over the name to do what you want. You can instead join each letter in name with | as the separator. The header/footer can be created by repeating +- the same amount of time as the length of name. So your loop can be replaced with:
print('+-' * len(name) + '+')
print('|' + '|'.join(name.upper()) + '|')
print('+-' * len(name) + '+')
.. or assigned to head, middle, bottom if you want that instead.

head and bottom don't need to be in the for loop, because they calculate the full string all at once. For that matter, because they're the same string, there's no reason for them to be two separate variables at all.
Your loop doesn't need to loop over indexes -- it can loop over characters, so you can directly add those characers yourself; and using an f-string is somewhat unnecessarily overcomplicated.
Anyhow -- if you're going to be using a loop, you should be additively constructing your string; just overwriting the whole thing on every iteration makes there no point to using a loop at all.
def art(name):
head = "+" + len(name) * "-+"
middle = ''
for character in name:
middle += '|{}'.format(character.upper())
print(head + "\n" + middle + "|\n" + head)
art("Python")

Related

How to move a white space in a string?

I need to move a whitespace in a string one position to the right.
This is my code:
for i in range(0,len(resultaat)):
if resultaat[i] == " ":
string = resultaat[:i] + resultaat[i+1] + " " + resultaat[i+2:]
E.g.:
If resultaat =
"TH EZE NO FPYTHON."
Than my output needs to be:
'THE ZEN OF PYTHON.'
, but the output that I get is:
"TH EZE NO F PYTHON."
I think this happened because the loop undid the action where it moved the previous space.
I don't know how to fix this problem.
Can someone help me with this?
Thanks!
Each time through the loop you're getting slices of the original resultaat string, without the changes you've made for previous iterations.
You should copy resultaat to string first, then use that as the source of each slice so you accumulate all the changes.
string = resultaat
for i in range(0,len(resultaat)):
if resultaat[i] == " ":
string = string[:i] + string[i+1] + " " + string[i+2:]
You could do something like this:
# first get the indexes that the character you want to merge
indexes = [i for i, c in enumerate(resultaat) if c == ' ']
for i in indexes: # go through those indexes and swap the characters as you have done
resultaat = resultaat[:i] + resultaat[i+1] + " " + resultaat[i+2:] # updating resultaat each time you want to swap characters
Assuming the stated input value actually has one more space than is actually needed then:
TXT = "TH EZE NO FPYTHON."
def process(s):
t = list(s)
for i, c in enumerate(t[:-1]):
if c == ' ':
t[i+1], t[i] = ' ', t[i+1]
return ''.join(t)
print(process(TXT))
Output:
THE ZEN OF PYTHON.

How to print in a single line without using end =''

I have a task to create a row of numbers. what I have now works and prints on one line. I want to try to use it without end. What I've tried already is creating a variable new_line = "" and adding that / equaling that to the string in the print line. I also need to be able to print another "|" at the end of the string only and I can't do that with end.
def print_row(n, max_power, column_width):
count = 0
exponent = max_power
max_power = 0
while count < exponent:
max_power = max_power + 1
value = power(n, max_power)
print("|",padded(value, column_width),end='')
count = count + 1
You're using the loop to control the wrong thing. Use the loop to build a list of values to be combined using | as a separator, then print that string with one call to print.
def print_row(n, max_power, column_width):
values = [padded(power(n, p), column_width) for p in range(max_power)]
print("|" + "|".join(values), end="|")
The initial "|" can be added to the value to actually print (as shown), or could be output with a preceding call to print("|", end='').

Int object is not subscriptable error even though proper conversions have been made?

I am trying to create a program that is sort of an "expander". If you were to give it a number like 1234, it should return "1000 + 200 + 30 + 4". However, I keep getting an int object is not subscript able error even thought I made proper conversions.
I have tried having new_str = num[int(i)] ... but that still doesn't work.
def expanded_form(num):
count = len(str(num))-1
new_str = ""
for i in range(0,len(str(num))):
new_str += num[i] * 10**count + " + "
count -= 1
return new_str
print(expanded_form(1234))
The problem is inside the for loop, you're writing num[i], that's what's giving you the error since num is an int and you can't really access an index of an int.
You're trying to get the number on that index and multiply it by 10 ** count. To do that should try this
new_str += str(int(str(num)[i]) * 10 ** count) + ' + '
You first have to turn num into a string to get the number on that position, but it returns it as a string, so you have to parse it back to int in order to multiply it with 10 ** count, and then you have to turn it into a string again in order to concatenate it with ' + '.
If you want to avoid parsing it so many times try doing this inside the for loop
new_str = str(num)[i] + '0' * count + ' + '
Instead of mutiplying it by a power of 10 you can use the fact that count is the number of zeros that should follow str(num)[i]
Your error is telling you that you cannot subscript an integer. Here: num[i]. num is an integer. You should cast it again to a string.
This said, to do what you want you need to recast the digit num[i] to an int in order to do the math.
def expanded_form(num):
count = len(str(num))-1
new_str = []
for i in range(0,len(str(num))):
new_str.append(int(str(num)[i]) * 10**count)
count -= 1
return ' + '.join(map(str, new_str))
print(expanded_form(1234))
Note that I made new_str a list and use join to build the string with the sum, to get rid of the extra '+' at the end. I also needed map to convert back all the integers to string otherwise join does not work.

error defining a string

I am trying to make a program that adds a number to a string and prints it. Here is my code:
n1 = 5
n2 = 6
statement = "number 1: ",n1,") (number 2: ",n2,")"
print(statement)
I want it to print (number1: 5 ) * (number2: 6 ).
EDIT:
The problem I had was my items were separated by commas, not plus signs. This caused an error becuase you need to seperate things with plus signs.
3 ways to get around this would be:
A:% formatting
number = 1
statement = "Your number is %s." % (number)
B:{} formatting
number = 2
statement = "Your number is {}.".format(number)
C:Converting to a string
number = 3
statement = "Your number is "+str(number) + "."
You are trying to join strings using the comma operator. This creates a tuple, not a string. Strings are concatenated using the + operator, like so:
statement = "(x +" + str(n1) + ") * (x +" + str(n2) + ")"
But it would be even easier to use the string formatting operators:
statement = "(x + {}) * (x + {})".format(n1,n2)
or
statement = "(x + %s) * (x + %s)" % (n1, n2)
Your syntax in line 4, where you build the statement, is one that constructs a list from comma-separated elements. You need to convert the integers to strings somehow, and work in the spaces you want. Here's the closest equivalent, I think:
statement = "(x + " + str(n1) + " ) * (x + " + str(n2) + " )"
This prints the output you requested.
When you construct your "statement" variable, you are building a tuple, not a string (those commas are the culprit).
Build that variable as a string, and you'll be able to add it to the other string.
statement = "(x + {n1}) * x +{n2})".format(n1=n1, n2=n2)

python asterisk triangle without using y* "*"

I'm trying to create a iso triangle (one that starts in the middle).
I have a code but the problem is that I'm not allowed to use Y* "*" 5 in my code.
(The y is a variable there)
Also I may only use one print statement at the end of my code.
Can you please help me out.
f = int(raw_input("enter"))
for i in range(f):
print " " * (f-i-1) + "*" * (2*i+1)
creats this triangle
*
***
*****
*******
*********
***********
However, you are not allowed to use the *-operator on string and int. So for example ''***'' * 3 is not allowed, but 3 * 4 is
This just creates a continuous string and then prints it at the end
f = int(raw_input("Enter height: "))
s = ''
for i in xrange(f):
for j in xrange(f-i-1):
s += ' '
for j in xrange(2*i+1):
s += '*'
s += '\n'
print s
This is a solution which i think is very easy to understand. You can make the parameter of range() variable, to make it more dynamic.
from __future__ import print_function
for i in range(1,12,2):
count=(11-i)/2
for j in xrange(count):
print(" ",end='')
for j in xrange(i):
print("*",end='')
for j in xrange(count):
print(" ",end='')
print(end="\n")
I think the best solution is using the center() string method:
f = int(raw_input("How many rows to print in the triangle? "))
star = "*"
full_string = ""
for X in xrange(f):
star += "**" if X>0 else ""
full_string += star.center(2*f-1) + "\n"
print full_string[:-1]
The str.center() documentation:
https://docs.python.org/2/library/string.html#string.center
EDIT: If you can't use the print statement within the for loop, you could concatenate the string during the loop and print it at the end:
f = int(raw_input("How many rows to print in the triangle? "))
star = "*"
full_string = ""
for X in xrange(f):
# the first row should take only one star
star += "**" if X>0 else ""
star2 = star.center(2*f-1)
full_string += star2 + "\n"
# slice the string to delete the last "\n"
print full_string[:-1]
I noticed that using a for loop add a newline character. If you want to avoid this, you can slice the string before printing.
There is no problem with this code, i just checked it and it worked fine. If you would post the error message we might be able to help a bit more.

Categories

Resources