How to duplicate lines in Python - python

I have print (5*"#"), which gives me:
#####
Now if I add \n to it, print (5*"#\n"), it gives me five lines consisting of one # each.
What do I do when I want it to give me this:
Four lines consisting of five # each without having to type ##### in the code?
I tried something like print(5*"#", 4*"\n") but it obviously didn't work.

You can use the following:
(5 * '#' + '\n') * 4
Note that this is much less clear than '#####\n' * 4.

How about you loop over the print statement 4 times?
for _ in range(4):
print(5 * '#')
Or, use + to append the newline, and multiply the result by 4:
print((5 * '#' + '\n') * 4)
Or, use a list and .join() the elements with newlines:
print('\n'.join([5 * '#'] * 4))

for x in [5 * "#"] * 4:
print x
or:
print "\n".join([5 * "#"] * 4)

one line version:
>>> print 4 * ("%s\n" % (5*"#"))
or
>>> print 4 * ( 5*"#" + "\n" )
multiline:
>>> for x in xrange(4):
print "#####"
#####
#####
#####
#####

You could do print "%s\n" % (5*"#")*4

Related

Printing two different squares (made of asterisks) adjacent to each other?

I didn't know how to describe it in the question properly, so I'll try again here.
I have to solve this question where my code should print different types of squares. I have all of that figured out, however, I'm stuck at the printing part.
So, I start by inputting 4 as the size, and it results in different types of squares being made. For example, these two:
first = ""
for j in range(size-1):
first += "*" * size + "\n"
first += "*" * size
two = ""
for j in range(size-1):
if j == 0:
two += "*" * size + "\n"
else:
two += "*" + ((size - 2) * " ") + "*" + "\n"
two += "*" * size
Now, I have to print them like this:
**** ****
**** * *
**** * *
**** ****
separated by a '\t'.
Since these squares are 'stored' in different strings, this is unfamiliar territory for me as the cursor is at the end of the first square. I don't know what to do, help pls.
There are many ways for that, one is here:
>>> v = '\n'.join([i+'\t' + j for i,j in list(zip([i for i in first.split('\n') if i], [ i for i in two.split('\n') if i]))])
>>> print(v)
**** ****
**** * *
**** * *
**** ****
What i did:
Splitted both strings at newline character, then took corresponding parts and joined them by tab in between, then assembled the whole string.
You can change the data structure you use. Let the square will be not a string, but list of strings, where each string is line should be printed.
Then you can for each line write line_first + '\t' + line_two and print it.
This code worked as you expect.
first = []
for j in range(size - 1):
first.append("*" * size)
first.append("*" * size)
two = []
for j in range(size - 1):
if j == 0:
two.append("*" * size)
else:
two.append("*" + ((size - 2) * " ") + "*")
two.append("*" * size)
for f, t in zip(first, two):
print(f + '\t' + t)

Replace characters in a list by column rather than by row

Currently I have the following lists:
counter = [13]
instruments = ['3\t ---', '2\t / \\', '1\t / \\', '0\t--- \\ ---', '-1\t \\ /', '-2\t \\ /', '-3\t ---']
score = ['|*************|']
What I am trying to do is to replace the characters in the instruments list with the characters from the score list (excluding the |).
I am currently experiencing the following issues
The characters are being replaced row by row, rather than column by column.
Instrument List:
3 ---
2 / \
1 / \
0 --- \ ---
-1 \ /
-2 \ /
-3 ---
Score List:
|*************|
EXPECTED OUTPUT:
3 ***
2 * *
1 * *
0 *** *
-1 *
-2 *
-3
Current Output:
3 ***
2 * *
1 * *
0 *** * **
-1
-2
-3
This is how I am currently replacing the characters in the instruments list:
for elements in counter:
current_counter = elements
count = 0
for elements in instrument_wave:
amplitude, form = elements.split('\t')
for characters in form:
if characters in ['-', '/', '\\']:
form = form.replace(characters, '*', 1)
count += 1
if count == current_counter:
break
for characters in form:
if characters in ['-', '/', '\\']:
form = form.replace(characters, '')
if '-' not in amplitude:
amplitude = ' ' + amplitude
new_wave = amplitude + "\t" + form
waveform.append(new_wave)
Any help would be appreciated, especially with regards to how I should fix my replace character to make it go column by column rather than row by row.
To solve your first issue, you need to iterate via columns.
If you zip the lists (via itertools.zip_longest(), as they are not all the same length), you can then go through them in order and truncate the result:
import itertools
cols = list(itertools.zip_longest(*lst, fillvalue=" "))
for i in range(3, 17): # skip negative signs
cols[i] = "".join(cols[i]).replace('-', '*', 1)
cols[i] = "".join(cols[i]).replace('/', '*', 1)
cols[i] = "".join(cols[i]).replace('\\', '*', 1)
fixed = map("".join, zip(*cols[:17])) # no need to zip longest
for l in fixed:
print(l)
See a working example on repl.it, which outputs:
3 ***
2 * *
1 * *
0 *** *
-1 *
-2 *
-3
Note it does pad the lists out with spaces, so you may want to .strip() the results if it isn't just for printing. Adapting that to your score input I'll leave up to you.
Another option, which is probably clearer:
def convert_and_truncate(lst, cutoff):
result = []
for str in lst:
str = str[0] + str[1:].replace('-', '*') # skip the negative signs
str = str.replace('/', '*')
str = str.replace('\\', '*')
result.append(str[:cutoff]) # truncate
return result
Because we're truncating the rest of the list, it doesn't matter that replace is changing them all.
Without itertools, instead self padding to longest part in list:
counter = [16]
instruments = ['3\t ---', '2\t / \\', '1\t / \\', '0\t--- \\ ---', '-1\t \\ /', '-2\t \\ /', '-3\t ---']
score = ['|*************|']
# get longes part list
maxL = max ( len(p) for p in instruments)
#enlarge all to max length
instrum2 = [k + ' '* (maxL-len(k)) for k in instruments]
# mask out leading - to ~ (we reverse it later)
instrum3 = [k if k[0] != '-' else '~'+''.join(k[1:]) for k in instrum2]
# transpose and join to one lengthy sentence, #### are where we later split again
trans = '####'.join(map(''.join,zip(*instrum3)))
# replace the right amount of /-\ with * after that, replace with space instead
cnt = 0
maxCnt = score[0].count('*')
result = []
for t in trans:
if t in '/-\\':
if cnt < maxCnt:
result.append('*')
cnt+=1
else:
result.append(' ')
else:
result.append(t)
# resultlist back to string and split into columns again
result2 = ''.join(result)
trans2 = result2.split('####')
# transpose back to rows and make - correct
trans3 = [''.join(k).replace('~','-') for k in zip(*trans2 )]
for p in trans3:
print(p)
Output:
3 ***
2 * *
1 * *
0 *** *
-1 *
-2 *
-3

Creating pyramid using symbols in Python

This is the assignment:
Write a python function that accepts a character and an integer and then uses that character to create a triangular structure like the example below. Make sure that the number of lines is in the range 1 to 10 and that only the first character in the user entered symbol is used if they enter more than one character.
Symbol? *
Lines? 4
*
* *
* * *
* * * *
I've got all of it except the spacing right... here's what I figured out so far.
def Triangle():
lines = -1
while lines not in range(1,11):
symbol=input("Symbol? ")
lines=input("Lines? ")
for i in range(lines + 1):
spaces = lines - i
print ((' ' * spaces) + (symbol * i))
This prints out:
*
**
***
****
Can't seem to get this right... thoughts?
Also if anyone has ideas on how to ensure only the first character is used as the symbol as noted in the question, that'd be awesome.
You need add in spaces after each symbol:
print ((' ' * spaces) + ((symbol + ' ') * i))

Printing X-type pattern in Python 2.7

I'm trying to print this pattern in Python:
*............*
.**........**
..***....***
...********
...********
..***....***
.**........**
*............*
And came up with this code that does the job:
for row in range(1,5):
print "." * (row -1) + row * "*" + (16 - row * 4) * "." + row * "*"
for row in range (0,4):
print("." * (3-row)+ "*" *(4 -row) + row * 4 * "." +"*" *(4 -row))
My question: is it possible to do this without using two loops? BTW, this is not for homework, I'm just playing around with some exercises from "Think Like a Programmer" by V. Anton Spraul and implementing the solutions in Python rather than C++.
Thanks in advance.
Without changing anything else, you can just do the loop over two ranges:
for row in range(1,5)+range(4,0,-1):
print "." * (row -1) + row * "*" + (16 - row * 4) * "." + row * "*"
Since you can add lists together:
In [8]: range(1,5)
Out[8]: [1, 2, 3, 4]
In [9]: range(4,0,-1)
Out[9]: [4, 3, 2, 1]
In [10]: range(1,5) + range(4,0,-1)
Out[10]: [1, 2, 3, 4, 4, 3, 2, 1]
By the way, you can get rid of the leading dots using spaces:
for row in range(1,5)+range(4,0,-1):
print " " * (row -1) + row * "*" + (16 - row * 4) * "." + row * "*"
*............*
**........**
***....***
********
********
***....***
**........**
*............*
A more elegant thing to do might be to build a list of strings:
X = []
for row in range(1,5):
X.append(" " * (row -1) + row * "*" + (16 - row * 4) * "." + row * "*")
Now, add the bottom half by just duplicating the top half in reverse:
X = X + list(reversed(X))
But when we print it we see a list:
print X
#['*............*', ' **........**', ' ***....***', ' ********', ' ********', ' ***....***', ' **........**', '*............*']
So we can join them together with newlines:
print '\n'.join(X)
*............*
**........**
***....***
********
********
***....***
**........**
*............*
here's an answer with one while loop
def star(size=14): ##size for the star in your post
asterisk=1;
space=0;
def func(x):
x+=1
return x
def decrement(x):
x-=1
return x
while (asterisk > 0):
line=''
line+=' '*space
if((size-(2*space)-(2*asterisk))<=0):
line+='*'*(size-(2*space))
else:
line+='*'*asterisk
line+=' '*(size-(2*space)-(2*asterisk))
line+='*'*asterisk
print ''.join(line)
if((size-(2*space)-(2*asterisk))<=0):
func=decrement ### switch to decreasing number of asterisks after we cross the middle of the star
print ''.join(line)
space=func(space);
asterisk=func(asterisk);
for i in range(20): ##whee
star(i)
I liked askewchan's elegant approach which noticed the symmetry between the top and bottom. There is also left-right symmetry. Here's an attempt to take advantage of that (it does have two loops though):
stars = [" "*(row-1) + "*"*row + " "*(8-row*2) for row in range(1,5)]
for line in stars + list(reversed(stars)):
print line + line[::-1]

Formatting in Python 2.7

I have a column formatting issue:
from math import sqrt
n = raw_input("Example Number? ")
n = float(n)
sqaureRootOfN = sqrt(n)
print '-'*50
print ' # of Decimals', '\t', 'New Root', '\t', 'Percent error'
print '-'*50
for a in range(0,10):
preRoot = float(int(sqaureRootOfN * 10**a))
newRoot = preRoot/10**a
percentError = (n - newRoot**2)/n*100
print ' ', a, '\t\t', newRoot, '\t\t', percentError, '%'
It comes out like:
Not in the same column!?!
#Bjorn has the right answer here, using the String.format specification. Python's string formatter has really powerful methods for aligning things properly. Here's an example:
from math import sqrt
n = raw_input("Example Number? ")
n = float(n)
sqaureRootOfN = sqrt(n)
print '-'*75
print ' # of Decimals', ' ' * 8, 'New Root', ' ' * 10, 'Percent error'
print '-'*75
for a in range(0,10):
preRoot = float(int(sqaureRootOfN * 10**a))
newRoot = preRoot/10**a
percentError = (n - newRoot**2)/n*100
print " {: <20}{: <25}{: <18}".format(a, newRoot, str(percentError) + ' %')
Note that instead of tabs I'm using spaces to space things out. This is because tabs are really not what you want to use here, because the rules for how tabs space things are inconsistent (and depend on what your terminal/viewer settings are).
This is what the answer looks like:
---------------------------------------------------------------------------
# of Decimals New Root Percent error
---------------------------------------------------------------------------
0 9.0 18.1818181818 %
1 9.9 1.0 %
2 9.94 0.198383838384 %
3 9.949 0.0175747474747 %
4 9.9498 0.00149490909092 %
5 9.94987 8.7861717162e-05 %
6 9.949874 7.45871112931e-06 %
7 9.9498743 1.4284843602e-06 %
8 9.94987437 2.14314187048e-08 %
9 9.949874371 1.33066711409e-09 %
Using str.format,
import math
n = float(raw_input("Example Number? "))
squareRootOfN = math.sqrt(n)
print('''\
{dashes}
{d:<16}{r:<15}{p:<}
{dashes}'''.format(dashes = '-'*50, d = ' # of Decimals', r = 'New Root', p = 'Percent error'))
for a in range(0,10):
preRoot = float(int(squareRootOfN * 10**a))
newRoot = preRoot/10**a
percentError = (n - newRoot**2)/n
print(' {d:<14}{r:<15}{p:13.9%}'.format(d = a, r = newRoot, p = percentError))
yields
--------------------------------------------------
# of Decimals New Root Percent error
--------------------------------------------------
0 9.0 18.181818182%
1 9.9 1.000000000%
2 9.94 0.198383838%
3 9.949 0.017574747%
4 9.9498 0.001494909%
5 9.94987 0.000087862%
6 9.949874 0.000007459%
7 9.9498743 0.000001428%
8 9.94987437 0.000000021%
9 9.949874371 0.000000001%
A few tricks/niceties:
Instead of three print statements, you can use one print statement on
a multiline string.
The percent symbol in the format {p:13.9%} lets you leave
percentError as a decimal (without multiplication by 100) and it
places the % at the end for you.
This is how tabs work. To get a correct formatting, you should use string.format. For your example, it could look like this:
print "{0:2d} {1:9.8f} {2:f} %".format(a, newRoot, percentError)

Categories

Resources