Number pattern using nested loop - python

Here is my code which prints a particular number pattern. I want my number pattern to be in perfect triangular arrangement like:
a = int(input('Enter number: '))
base = a
while base > 0:
for j in range(1, a + 1):
print(' ' * (2 * j - 2), end = '')
for i in range(1, base + 1):
print(str(i), end = ' ')
print()
base -= 1
The output:
Enter number: 5
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
Enter number: 7
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
The program works fine for numbers < 10 but when I input a number > 10 it gives a distorted pattern.
For example:
Enter number: 15
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
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
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
So is there a way to make the pattern right?

If you want to have the same result for two digit numbers, you have to format your string. Here how it also works for two digit results:
a = int(input('Enter number: '))
base = a
while base > 0:
for j in range(1, a + 1):
print(' ' * (2 * j - 2), end = '')
for i in range(1, base + 1):
print('{0:>2}'.format(str(i)), end = ' ')
print()
base -= 1
Result for 15:
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
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
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1

Some adjustments and str.rjust will do the trick:
a = base = 15
while base > 0:
for j in range(a):
print(' ' * 3 * j, end='')
for i in range(base):
print(str(i+1).rjust(3), end='')
print()
base -= 1
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
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
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1

You might use rjust method of str, it does:
Return a right-justified string of length width. Padding is done using
the specified fill character (default is a space).
Simple example usage:
numbers = [1, 10, 10, 1000, 10000]
for n in numbers:
print(str(n).rjust(5))
Output:
1
10
10
1000
10000
Note that rjust requires at least one argument: width, if original str is shorther than width leading spaces (or other characters if specified) will be added to get str of length equal to width, otherwise original str will be returned.

Related

space tower in python with loops

1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 7 6 5 4 3 2 1
1 2 3 4 5 6 6 5 4 3 2 1
1 2 3 4 5 5 4 3 2 1
1 2 3 4 4 3 2 1
1 2 3 3 2 1
1 2 2 1
1 1
How can I code this in python?
So far this is my code but I can't figure out the spaces.
number = int(input("enter a number to create your triangle: "))
for col in range(number,0,-1):
for row in range(1,col):
print(row, end=" ")
if col<number:
print(" "*(row*2), end="")
for row in range(col-1,0,-1):
print(row, end=" ")
print()
Instead of looping multiple times, you could create a base list containing all numbers as strings, iterate once to print each row and the reverse:
number = 9
base = [str(n) for n in range(1, number+1)]
for i, idx in enumerate(range(len(base)-1, 0, -1)):
if i == 0:
print(' '.join(base + base[::-1]))
base[idx] = ' '
print(' '.join(base + base[::-1]))
Out:
1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 7 6 5 4 3 2 1
1 2 3 4 5 6 6 5 4 3 2 1
1 2 3 4 5 5 4 3 2 1
1 2 3 4 4 3 2 1
1 2 3 3 2 1
1 2 2 1
1 1
As I've pointed in this comment, using all "power" of print() and unpacking you can make it really easy.
By default all arguments passed to print() will be separated with space, so we can just unpack there range from 1 to current index, string of spaces and reverse range from current index to 1:
number = int(input("enter a number to create your triangle: "))
for i, n in enumerate(range(number, 0, -1)):
print(*range(1, n + 1), *(" " * (i * 2)), *range(n, 0, -1))
Output:
1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 7 6 5 4 3 2 1
1 2 3 4 5 6 6 5 4 3 2 1
1 2 3 4 5 5 4 3 2 1
1 2 3 4 4 3 2 1
1 2 3 3 2 1
1 2 2 1
1 1
Important notice: Code above will work properly only for number below 10.

How to print out square numbers like this?

i need output like this:
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
this is what i can do but it's not right
size=int(input())
for row in range(1,size+1):
for col in range(1,size+1):
print(row,end=' ')
print(col)
only use forloop
You can do:
size = int(input())
for i in range(1, size+1):
print(' '.join(str(max(i, j)) for j in range(1, size+1)))
Example for size of 9:
1 2 3 4 5 6 7 8 9
2 2 3 4 5 6 7 8 9
3 3 3 4 5 6 7 8 9
4 4 4 4 5 6 7 8 9
5 5 5 5 5 6 7 8 9
6 6 6 6 6 6 7 8 9
7 7 7 7 7 7 7 8 9
8 8 8 8 8 8 8 8 9
9 9 9 9 9 9 9 9 9
It however doesn't print nicely for double digits:
1 2 3 4 5 6 7 8 9 10
2 2 3 4 5 6 7 8 9 10
3 3 3 4 5 6 7 8 9 10
4 4 4 4 5 6 7 8 9 10
5 5 5 5 5 6 7 8 9 10
6 6 6 6 6 6 7 8 9 10
7 7 7 7 7 7 7 8 9 10
8 8 8 8 8 8 8 8 9 10
9 9 9 9 9 9 9 9 9 10
10 10 10 10 10 10 10 10 10 10
So you can find the number of digits, and pad the strings:
import math
max_n = 10
digits = int(math.log10(max_n))+1
for i in range(1, max_n+1):
print(' '.join(str(max(i, j)).rjust(digits) for j in range(1, max_n+1)))
1 2 3 4 5 6 7 8 9 10
2 2 3 4 5 6 7 8 9 10
3 3 3 4 5 6 7 8 9 10
4 4 4 4 5 6 7 8 9 10
5 5 5 5 5 6 7 8 9 10
6 6 6 6 6 6 7 8 9 10
7 7 7 7 7 7 7 8 9 10
8 8 8 8 8 8 8 8 9 10
9 9 9 9 9 9 9 9 9 10
10 10 10 10 10 10 10 10 10 10
Single loop:
size=int(input())
for i in range(1, size + 1):
print(' '.join([str(max([i, j])) for j in range(1, size + 1)]))
Here is an easy to understand example :
num = int(input("Input a number : "))
for i in range(1, num+1):
row = ""
for j in range(1, num+1):
row += " " + str(j if j > i else i)
print(row)
I make a list for each row. If the row number is i then the row starts with i i's. After that it counts up to the given size.
size = int(input())
for row in range(1, size + 1):
lst = [row] * row + list(range(row + 1, size + 1))
print(' '.join([str(i) for i in lst]))
Output for size = 5:
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
A solution following your code's logic:
for row in range(1,size+1):
cnt = 1
for col in range(1,size+1):
if(cnt < row):
printNum = row
else:
printNum = cnt
cnt = cnt + 1
if(printNum > 9):
print(printNum,end=' ')
else:
print(printNum,end=' ')
print("\n")
Yet another variation:
size = input()
width = len(size)
size = int(size)+1
for i in range(1, size):
print(*(f'{max(i, j):>{width}}' for j in range(1, size)))
This does it:
size=int(input())
for col in range(1,size+1):
for row in range(1,size+1):
if row <= col:
print(col, end=' ')
else:
print(row, end=' ')
print()
It's not the most elegant answer but it works for any size.
Walrus to rescue. For Python 3.8+
(size := int(input("Input a number : ")) + 1)
for i in range(1, size):
print(' '.join(str(max(i, j)) for j in range(1, size)))
Result:
Enter a number : 5
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
# write a program to traverse every element of the two-dimensional array in Python.
dt = [ [1, 2, 3, 4, 5], [2, 2, 3, 4, 5], [3, 3, 3, 4, 5 ], [4, 4, 4, 4, 5], [5, 5, 5, 5, 5] ]
# Use for loop to print the entire elements of the two dimensional array.
for x in dt: # outer loop
for i in x: # inner loop
print(i, end = " ") # print the elements
print()
This code will give you output like this:
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
but you have to input the array manually

How to merge blocks of rows to single rows in pandas?

Assume I have a dataframe like this, for example:
0 1 2 3 4 5 6 7 8 9
0 8 9 2 1 6 2 6 8 6 3
1 1 1 8 3 1 6 3 6 3 9
2 1 4 3 5 9 3 5 9 2 3
3 4 6 3 8 4 3 1 5 1 1
4 1 8 5 3 9 6 1 7 2 2
5 6 6 7 9 1 8 2 3 2 8
6 8 3 6 9 9 5 8 4 7 7
7 8 3 3 8 7 1 4 9 7 2
8 7 6 1 4 8 1 6 9 6 6
9 3 3 2 4 8 1 8 1 1 8
10 7 7 5 7 1 4 1 8 8 6
11 6 3 2 7 6 5 7 4 8 7
I would like to put rows to certain "blocks" of given length and the flatten them to single rows. So for example, if the block length would be 3, the result here would be:
0 1 2 3 4 5 6 7 8 9 10 ... 19 20 21 22 23 24 25 26 27 28 29
2 8 9 2 1 6 2 6 8 6 3 1 ... 9 1 4 3 5 9 3 5 9 2 3
5 4 6 3 8 4 3 1 5 1 1 1 ... 2 6 6 7 9 1 8 2 3 2 8
8 8 3 6 9 9 5 8 4 7 7 8 ... 2 7 6 1 4 8 1 6 9 6 6
11 3 3 2 4 8 1 8 1 1 8 7 ... 6 6 3 2 7 6 5 7 4 8 7
How to achieve this?
I think need reshape:
n_blocks =3
df = pd.DataFrame(df.values.reshape(-1, n_blocks *df.shape[1]))
print (df)
0 1 2 3 4 5 6 7 8 9 ... 20 21 22 23 24 25 26 27 \
0 8 9 2 1 6 2 6 8 6 3 ... 1 4 3 5 9 3 5 9
1 4 6 3 8 4 3 1 5 1 1 ... 6 6 7 9 1 8 2 3
2 8 3 6 9 9 5 8 4 7 7 ... 7 6 1 4 8 1 6 9
3 3 3 2 4 8 1 8 1 1 8 ... 6 3 2 7 6 5 7 4
28 29
0 2 3
1 2 8
2 6 6
3 8 7
[4 rows x 30 columns]
I found this solution, maybe someone comes up with a better one:
def toBlocks(df, blocklen):
shifted = [df.shift(periods=p) for p in range(blocklen)]
return pd.concat(shifted, axis=1)[blocklen-1:]

islice and cycle with multiple levels

UPDATE:
Added the pattern required as asked
I have 2 lists and the expected output is different than the last time
Numberset1 = [10,11,12]
Numberset2 = [1,2,3,4,5]
and i want to display output by manipulating the lists, the expected output is
10 1 1
10 1 2
10 1 3
10 1 4
10 1 5
10 2 2
10 2 3
10 2 4
10 2 5
10 2 1
10 3 3
10 3 4
10 3 5
10 3 1
10 3 2
10 4 4
10 4 5
10 4 1
10 4 2
10 4 3
10 5 5
10 5 1
10 5 2
10 5 3
10 5 4
11 2 2
11 2 3
11 2 4
11 2 5
11 2 1
11 3 3
11 3 4
11 3 5
11 3 1
11 3 2
11 4 4
11 4 5
11 4 1
11 4 2
11 4 3
11 5 5
11 5 1
11 5 2
11 5 3
11 5 4
11 5 1
11 1 1
11 1 2
11 1 3
11 1 4
11 1 5
12 3 3
12 3 4
12 3 5
12 3 1
12 3 2
12 4 4
12 4 5
12 4 1
12 4 2
12 4 3
12 4 4
12 4 5
12 5 5
12 5 1
12 5 2
12 5 3
12 1 1
12 1 2
12 1 3
12 1 4
12 1 5
12 2 2
12 2 3
12 2 4
12 2 5
12 2 1
The code i have tried is as follows, this was suggested in previous question and i tried using it for the next level of looping but i could not get the desired output
Numberset1 = [10,11,12]
Numberset2 = [1,2,3,4,5]
from itertools import cycle, islice
it = cycle(Numberset2)
for i in Numberset1:
for a in Numberset2:
for j in islice(it, len(Numberset2)):
print(i, a,j)
skipped1 = next(it)
skipped1 = next(it)
The output i am getting is
10 1 1
10 1 2
10 1 3
10 1 4
10 1 5
10 2 2
10 2 3
10 2 4
10 2 5
10 2 1
10 3 3
10 3 4
10 3 5
10 3 1
10 3 2
10 4 4
10 4 5
10 4 1
10 4 2
10 4 3
10 5 5
10 5 1
10 5 2
10 5 3
10 5 4
11 1 2
11 1 3
11 1 4
11 1 5
11 1 1
11 2 3
11 2 4
11 2 5
11 2 1
11 2 2
11 3 4
11 3 5
11 3 1
11 3 2
11 3 3
11 4 5
11 4 1
11 4 2
11 4 3
11 4 4
11 5 1
11 5 2
11 5 3
11 5 4
11 5 5
12 1 3
12 1 4
12 1 5
12 1 1
12 1 2
12 2 4
12 2 5
12 2 1
12 2 2
12 2 3
12 3 5
12 3 1
12 3 2
12 3 3
12 3 4
12 4 1
12 4 2
12 4 3
12 4 4
12 4 5
12 5 2
12 5 3
12 5 4
12 5 5
12 5 1
Please note the change when the number 11 starts in the first column than the expected output
How can we use cycle and islice for multiple levels
Pattern:
The first column should be in order of numbers in Numberset1, the second column for first number in Numberset1 should be in order of numbers in Numberset2, the 3rd column for first number in Numberset1 should be in order of numbers in NUmberset2 but when the 2nd column for first number in Numberset1 changes it should also change and print from 2ndnumber in Numberset2 list and so on
Here's a version that accomplishes the task using cycle and islice. To make the code cleaner I've created a generator function aligned_cycle which cycles through the items yielded by cycle until we get the one we want to start the current cycle with.
This updated version can cope with Numberset1 having greater length than Numberset2.
from itertools import cycle, islice
def aligned_cycle(seq, start_item):
''' Make a generator that cycles over the items in `seq`.
The first item yielded equals `start_item`.
'''
if start_item not in seq:
raise ValueError("{} not in {}".format(start_item, seq))
it = cycle(seq)
for u in it:
if u == start_item:
break
yield u
yield from it
Numberset1 = [10, 11, 12]
Numberset2 = [1, 2, 3, 4, 5]
cycle_length = len(Numberset2)
for i, u in zip(Numberset1, cycle(Numberset2)):
for j in islice(aligned_cycle(Numberset2, u), cycle_length):
for k in islice(aligned_cycle(Numberset2, j), cycle_length):
print(i, j, k)
output
10 1 1
10 1 2
10 1 3
10 1 4
10 1 5
10 2 2
10 2 3
10 2 4
10 2 5
10 2 1
10 3 3
10 3 4
10 3 5
10 3 1
10 3 2
10 4 4
10 4 5
10 4 1
10 4 2
10 4 3
10 5 5
10 5 1
10 5 2
10 5 3
10 5 4
11 2 2
11 2 3
11 2 4
11 2 5
11 2 1
11 3 3
11 3 4
11 3 5
11 3 1
11 3 2
11 4 4
11 4 5
11 4 1
11 4 2
11 4 3
11 5 5
11 5 1
11 5 2
11 5 3
11 5 4
11 1 1
11 1 2
11 1 3
11 1 4
11 1 5
12 3 3
12 3 4
12 3 5
12 3 1
12 3 2
12 4 4
12 4 5
12 4 1
12 4 2
12 4 3
12 5 5
12 5 1
12 5 2
12 5 3
12 5 4
12 1 1
12 1 2
12 1 3
12 1 4
12 1 5
12 2 2
12 2 3
12 2 4
12 2 5
12 2 1
Jon Clements has written a more robust and more efficient version of aligned_cycle:
def aligned_cycle(iterable, start_item):
a, b = tee(iterable)
b = cycle(b)
for u, v in zip(a, b):
if u == start_item:
break
else:
return
yield u
yield from b
Thanks, Jon!

nested loops results bunched together Python

for j in range(10):
for i in range(10):
print(j,end=" ")
My results are bunched together and I need to have 10 numbers per line. I cant use a print("0123456789"). I have tried print(j,j,j,j,j,j,j,j,j) and I get the results that I'm looking for but I'm sure this isn't the proper way to write the code.
If print(j,j,j,j,j,j,j,j,j) works then you simply need to add another print() after each iteration:
for j in range(10):
for i in range(10):
print(j,end=" ")
print()
Output:
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
Or simply:
for j in range(10):
print(" ".join(str(j) * 10))
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
Why are you using a nested for loop when you can use a single for loop:
for i in range(10):
print('{} '.format(i) * 10)
This is similar to Malik Brahimi's solution, except it doesn't put a space after the last digit on each line:
for i in range(10):
print(' '.join([str(i)]*10))
output
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
Just for fun, here's another way to do it with a single loop, this time using a format string with numbered fields.
fmt = ('{0} ' * 10)[:-1]
for i in range(10):
print(fmt.format(i))

Categories

Resources