How to ensure consistent spacing in creating number pyramid (Python) - python

I'm trying to create a number pyramid in python, and none of the solutions I've found on Stack Overflow are quite what I'm looking for. Here is the code I have so far:
for i in range(1, height+1):
for j in range(1, height-i+1):
if j > 9:
print(len(str(j)) * " ", end=" ")
else:
print(" ", end=" ")
for j in range(i, 0, -1):
print(j, end=" ")
for j in range(2, i + 1):
print(j, end=" ")
print()
And here is the output:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
From what I can see, the code works fine with heights <= 9, but once double digits come in, the alignment fails. I also need to ensure that the spacing between each number is consistent (ONE space in between each number), but the workarounds that I've looked at involve adding more than one space.
Please let me know if there is anything I should clarify, and thank you in advance for your time!

You can use string formatting to define a fixed width for a field, padded by either whitespace or zeroes.
field_len = len(str(height))
for i in range(1, height+1):
for j in range(1, height-i+1):
print(" " * field_len, end=" ")
for j in range(i, 0, -1):
print(f"{j:{field_len}}", end=" ")
for j in range(2, i + 1):
print(f"{j:{field_len}}", end=" ")
print()
which produces
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
and which will auto-adjust the spacing depending on if the number of digits change.
This keeps the slope of the pyramid the same, though the alignment appears to get more sparse with interior numbers, as they're padded into two spaces.
A solution to that is just to use the width of the current number as the number of spaces - which we can do by changing the arguments to range() where it prints the spaces, to actually count down from the height.
for i in range(1, height+1):
for j in range(i, height):
print(" " * len(str(j + 1)), end=" ")
for j in range(i, 0, -1):
print(j, end=" ")
for j in range(2, i + 1):
print(j, end=" ")
print()
This produces a pyramid with uneven slopes but even spacing.
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

just for completeness I will provide another approach to this problem.
the main idea is to keep track of the length of the current line and use rjust to pad with whatever delimeter you wish (I chose the default whitespace)
height = 16
max_line_len = len(' '.join([str(i) for i in range(height,0,-1)] + [str(i) for i in range(2,height+1)]))
half_max_line_len = int((max_line_len+1)/2)
list_of_nums = [str(1)]
print('creating pyramid...')
for num in range(1, height+1):
print(' '.join(list_of_nums).rjust(half_max_line_len))
list_of_nums = [str(num+1)] + list_of_nums + [str(num+1)]
half_max_line_len += len(str(num+1))+1
output:
creating pyramid...
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Related

modifiedSentence = a solved sudoku well it will print it close to each other i want it to be every 3 on col or row make a advanced space it means boxs

for i in range(9):
for j in range(9):
print(modifiedSentence[i][j], end=" ")
print()
modifiedSentence =
7 8 1 2 6 9 3 4 5
3 2 4 7 1 5 6 9 8
5 6 9 4 3 8 1 2 7
2 9 7 3 5 4 8 1 6
4 5 3 1 8 6 9 7 2
8 1 6 9 7 2 5 3 4
9 3 8 6 4 7 2 5 1
6 4 2 5 9 1 7 8 3
1 7 5 8 2 3 4 6 9
and i want it :
7 8 1 2 6 9 3 4 5
3 2 4 7 1 5 6 9 8
5 6 9 4 3 8 1 2 7
2 9 7 3 5 4 8 1 6
4 5 3 1 8 6 9 7 2
8 1 6 9 7 2 5 3 4
9 3 8 6 4 7 2 5 1
6 4 2 5 9 1 7 8 3
1 7 5 8 2 3 4 6 9
means every box in this sudoku has a emptiness in his colum and row as a box
You need to add a space every third iteration of the inner loop, and a newline every 3rd iteration of the outer loop:
for i in range(9):
if i > 0 and i % 3 == 0:
print("")
for j in range(9):
if j > 0 and j % 3 == 0:
print("", end = " ")
print(modifiedSentence[i][j], end=" ")
print()

irregular spaces making pattern abnormal

I have a pattern which i printed using below code
Code :
n=5
def pyramidupdown(n):
cnt=0
space=2
lst= [str(row) for row in reversed(range(1,n+1))]
for i in range(1,n+1):
if i == 1:
s=' '.join(lst)
print(s)
else:
lst[cnt]=' '
s=' '.join(lst)
print(s)
cnt = cnt + 1
It prints the pattern below as output :
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
But my issue is with spaces when the n value is defined 2 digit like 15
the pattern is not printed properly
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
14 13 12 11 10 9 8 7 6 5 4 3 2 1
13 12 11 10 9 8 7 6 5 4 3 2 1
12 11 10 9 8 7 6 5 4 3 2 1
11 10 9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1
6 5 4 3 2 1
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
Expected output :
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
14 13 12 11 10 9 8 7 6 5 4 3 2 1
13 12 11 10 9 8 7 6 5 4 3 2 1
12 11 10 9 8 7 6 5 4 3 2 1
11 10 9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1
6 5 4 3 2 1
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
what changes do i need to make in existing code to print properly the pattern
I would just do it like this:
def pyramidupdown(n):
for i in range(n,0,-1): # loop n rows (in descending order)
lst = []
for j in range(n,0,-1): # loop n numbers (in descending order)
s = str(j)
# at the i-th row replace the first i string numbers
# (i.e. where j > i)
# by as many spaces as there are characters in that string
if j <= i:
lst.append(s)
else:
lst.append(' '*len(s))
print(" ".join(lst))
you can even make it a 1-liner (just for the fun):
def pyramidupdown(n):
print('\n'.join([" ".join([str(j) if j <= i else ' '*len(str(j)) for j in range(n,0,-1)]) for i in range(n,0,-1)]))
Now that I understand your code: here's the minimal tweak to make it work:
def pyramidupdown(n):
cnt=0
lst= [str(row) for row in reversed(range(1,n+1))]
for i in range(1,n+1):
if i == 1:
s=' '.join(lst)
print(s)
else:
lst[cnt]=' '*len(lst[cnt]) # here replace by correct number of spaces
s=' '.join(lst)
print(s)
cnt = cnt + 1

Table in python

In python I tried to make table like this
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
I tried this code:
for i in range(1, 11):
for j in range(1,10):
print(j, end=" ")
print(i)
but it outputs:
1 2 3 4 5 6 7 8 9 1
1 2 3 4 5 6 7 8 9 2
1 2 3 4 5 6 7 8 9 3
1 2 3 4 5 6 7 8 9 4
1 2 3 4 5 6 7 8 9 5
1 2 3 4 5 6 7 8 9 6
1 2 3 4 5 6 7 8 9 7
1 2 3 4 5 6 7 8 9 8
1 2 3 4 5 6 7 8 9 9
1 2 3 4 5 6 7 8 9 10
Your outer loop is only used to count the number of rows that will be printed. Seems like you want a 10x10 table, so you have 10 rows.
for row in range(10):
Then you want the numbers 1 through 10 printed on each row:
for column in range(1,11):
print(column, end=' ')
Then you want to write a newline so that each row shows up on a new line.
print()
That should do it.
for i in range(10):
for j in range(1,11):
print(j, end=" ")
print()
or
for i in range(10):
for j in range(1,11):
print(j, end=" ")
print()
You don't actually want to print i in the outer loop. You only need the print statement there for your line break. You can change how many columns there are y modifying the range in the inner loop (j loop)

Reducing code with a for loop to one line in Python

n=20
a=""
for i in range(1,n+1):
a+=str(i)+" "
print (a)
I don't know about lambda expression.Please Help me?
If you are looking for a lambda, you'll need one which returns a string. This means you'll need a generator comprehension to generate your string.
Consequently, you'll need 2 levels of str.join:
In [856]: f = lambda x: '\n'.join(' '.join(map(str, range(1, i))) for i in range(1, x + 1))
In [857]: print(f(20))
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
It looks complicated but it is the same as a loop, condensed into a generator comprehension. We generate each line using ' '.join(map(str, range(1, i))) for each i and then all such lines are joined by the newline \n.
I suggest
[print(*range(1, i+1)) for i in range(1, 20)] and None

pyramid of numbers in python

Write a program that prompts the user to enter an integer from 1 to 15 and displays a pyramid, as shown in the following sample run:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
I have the following:
num = eval(raw_input("Enter an integer from 1 to 15: "))
if num < 16:
for i in range(1, num + 1):
# Print leading space
for j in range(num - i, 0, -1):
print(" "),
# Print numbers
for j in range(i, 0, -1):
print(j),
for j in range(2, i + 1):
print(j),
print("")
else:
print("The number you have entered is greater than 15.")
This yields a misalignment for numbers greater than or equal to 10.
I have tried print(format(j, "4d")) and all the numbers become misaligned.
Any tips?
Thanks.
Use a leading space for a number ("01" - "09", "10", ...)
num = eval(raw_input("Enter an integer from 1 to 15: "))
def as_str(i):
s = ""
if i <10: s = " "
return s + str(i)
#num = 15
allrows = ""
for j in range(1,num+2):
#leading spaces
row = " "*3*(num-j+1)
#backward
for i in range(j-1,1,-1):
s = as_str(i)
row+=s + " "
#forward
for i in range(1,j):
s = as_str(i)
row+=s + " "
row +="\n"
allrows +=row
print allrows
Output
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
using string formatting, and it works for any value of n>=1:
num=int(raw_input())
max_width=len(" ".join(map(str,range(num,0,-1)))+" ".join(map(str,range(2,num+1))))+1
#max_width is the maximum width, i.e width of the last line
print "{0:^{1}}".format("1",max_width) #print 1 , ^ is used to place the
#string in the center of the max_width
for i in range(2,num+1): #print rest of the numbers from 2 to num
range1=range(i,0,-1)
strs1=" ".join(map(str,range1))
range2=range(2,i+1)
strs2=" ".join(map(str,range2))
print "{0:^{1}}".format(" ".join((strs1,strs2)),max_width) # use ^ again with max_width
outputs:
monty#monty-Aspire-5050:~$ python so27.py
5
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
monty#monty-Aspire-5050:~$ python so27.py
10
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
monty#monty-Aspire-5050:~$ python so27.py
20
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
This is more compact solution:
num = eval(raw_input("Enter an integer from 1 to 15: "))
allrows = ""
for j in range(1,num+2):
#leading spaces
formatter = lambda x: str(x).ljust(3)
#shift to left
row = " "*4*(num+2-j)
#count backward
row+=" ".join(map(formatter, range(1,j)[-1::-1])) + " "
#count forward
row+= " ".join(map(formatter, range(2,j))) + '\n'
allrows +=row
print allrows
This code outputs:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
This isn't a code golf entry, but it does show both bases.
Note the decimal version has 3-space indentation, and the hex version only 2-space indentation.
def triangle(n):
def indent(i):
return ' '*3*(n-(i+1))
def row(i):
lhs = ['%2d' % j for j in range(i,0,-1)]
rhs = lhs[:-1]
rhs.reverse()
return lhs+rhs
rows = [indent(i)+' '.join(row(i)) for i in range(n)]
return '\n'.join(rows)
def triangle_hex(n):
def indent(i):
return ' '*2*(n-(i+1))
def row(i):
lhs = ['%x' % j for j in range(i,0,-1)]
rhs = lhs[:-1]
rhs.reverse()
return lhs+rhs
rows = [indent(i)+' '.join(row(i)) for i in range(n)]
return '\n'.join(rows)
if __name__=='__main__':
print triangle(11)
print triangle_hex(15)
num = eval(raw_input("Enter an integer from 1 to 15: "))
if num < 16:
for i in range(1, num + 1):
# Print leading space
for j in range(num - i, 0, -1):
print(" "),
# Print numbers
for j in range(i, 0, -1):
print(format(j, "4d")),
for j in range(2, i + 1):
print(format(j, "4d")),
print
else:
print("The number you have entered is greater than 15.")
This is the cleanest and quickest way to do it:
num = 5
space = " "
for i in range(1, num+1):
for num_of_spaces in range(i+1, 1, -num):
x = (i-1)
spaces = space*(num-x)
print(spaces, end="")
for inv_rec in range(i, 1, -1):
print(inv_rec, end="")
for rec in range(1, i+1):
print(rec, end="")
print("")
Output is:
1
212
32123
4321234
543212345
65432123456
7654321234567
876543212345678
Process finished with exit code 0

Categories