Kind of pyramid numbers pattern exercise - python

Can you help to simplify this code and make it more efficient? Mine seems like it's not the best version; what can I improve?
1
232
34543
4567654
567898765
678901109876
This is the code I made:
c = -1
for y in range(1, 7):
print()
print((6-y) * " ", end="")
c += 1
for x in range(1, y+1):
print(y%10, end="")
y += 1
while y - c > 2:
print(y-2, end="")
y -= 1

First of all, I'm guessing that you didn't really want to print that y value of 10; that you really wanted the base-10 reduction to 0. Note that you have an extra character in the pyramid base.
Do not change the value of a loop parameter while you're inside the loop. Specifically, don't change y within the for y loop.
Get rid of c; you can derive it from the other values.
For flexibility, make your upper limit a parameter: you have two constants (6 and 7) that depend on one concept (row limit).
Here's my version:
row_limit = 7
for y in range(1, row_limit):
print()
print((row_limit-y-1) * " ", end="")
for x in range(y, 2*y):
print(x%10, end="")
for x in range(2*(y-1), y-1, -1):
print(x%10, end="")
print()
Output:
1
232
34543
4567654
567898765
67890109876
If you really want to push things, you can shorten the loops with string concatenation and comprehension, but it's likely harder to read for you.
for y in range(1, row_limit):
print()
print((row_limit-y-1) * " " + ''.join([str(x%10) for x in range(y, 2*y)]) + \
''.join([str(x%10) for x in range(2*(y-1), y-1, -1)]), end="")
print()
Each of the loops is turned into a list comprehension, such as:
[str(x%10) for x in range(y, 2*y)]
Then, this list of characters is joined with no interstitial character; this forms half of the row. The second half of the row is the other loop (counting down). In front of all this, I concatenate the proper number of spaces.
Frankly, I prefer my first form.

Here's my implementation.
Python 2:
def print_triangle(n):
for row_num in xrange(1, n + 1):
numbers = [str(num % 10) for num in xrange(row_num, 2 * row_num)]
num_string = ''.join(numbers + list(reversed(numbers))[1:])
print '{}{}'.format(' ' * (n - row_num), num_string)
Python 3:
def print_triangle(n):
for row_num in range(1, n + 1):
numbers = [str(num % 10) for num in range(row_num, 2 * row_num)]
num_string = ''.join(numbers + list(reversed(numbers))[1:])
print('{}{}'.format(' ' * (n - row_num), num_string))
Input:
print_triangle(5)
print_triangle(6)
print_triangle(7)
Output:
1
232
34543
4567654
567898765
1
232
34543
4567654
567898765
67890109876
1
232
34543
4567654
567898765
67890109876
7890123210987

n = int(input())
i = 1
while i <= n:
j = 1
spaces = 1
p = i
while spaces <= n - i:
print (" ", end ="")
spaces += 1
while j <= i:
print(p, end = "")
j += 1
p += 1
p -= 2
while p >= i:
print(p, end = "")
p -= 1
print()
i += 1

Related

Hollow Inverted Half Pyramid

I have to print a hollow inverted pyramid:
******
* *
* *
* *
**
*
Following is my code:
n = int(input())
for i in range(n,0,-1):
if i == n:
print(n*'*', end = '')
if i > 1 and i <n:
print('*'+(i-2)*' '+'*')
else:
print('*')
print()
For input as 6 I am not sure why my code is printing 7 stars.
If anyone could help explain what I am doing wrong or missing would be really great!
There are two problems here:
There is no need for the , end=''. You still want a newline to print after this line of stars.
You used if not elif for the second condition, so the third block of code in the else will still run even if the first condition is true.
Here is the corrected code:
n = int(input())
for i in range(n, 0, -1):
if i == n:
print(n * "*")
elif 1 < i < n:
print("*" + (i - 2) * ' ' + '*')
else:
print('*')
If the first iteration of the loop, there are two print calls executing: the first one and the last, so that makes a total of 7 stars in that first line of output.
As the first and last case are different from the other cases, it is easier to just deal with those outside of the loop:
n = int(input())
print(n*'*')
for i in range(n - 3, -1, -1):
print('*' + i*' ' + '*')
if n > 1:
print('*')
There is still one if here to ensure it still works correctly for n equal to 1 or even 0.
To do it without that if, you could do this:
n = int(input())
print(n*'*')
s = '*' + n*' '
for i in range(n - 2, -1, -1):
print(s[:i] + '*')
another type of inverted hollow matrix:
54321
4 1
3 1
2 1
1
Answers:
Hollow Right-angled triangle!!!
n=int(input())
for i in range(n,0,-1):
for k in range(n,0,-1):
if i==n or i==k or k==n-(n-1):
print(k,end=" ")
else:
print(end=" ")
print()

Hollow triangle using while loops python

Trying to make a program that asks the user for a height and a character, and then outputs a hollow triangle to that height using that character. Was trying to firstly make a solid triangle, then solve it from there, but so far have only managed to make a half triangle.
Also, using only for loops and no '*' operator
H = int(input("Enter height of triangle: "))
C = str(input("Character: "))
if C == "":
C = "*"
rows = 1
count = 0
while rows <= H:
spaces = 0
while spaces <= (H - rows):
print(" ", end="")
spaces += 1
count = 0
while count < rows:
print(C, end="")
count += 1
print()
rows += 1
this results in this:
*
**
***
****
*****
my goal is this:
*
* *
* *
* *
*********
any help would be appreciated!
Slightly changed your script:
H = int(input("Enter height of triangle: "))
C = str(input("Character: "))
if C == "":
C = "*"
rows = 1
count = 0
while rows <= H:
spaces = 0
while spaces <= (H - rows):
print(" ", end="")
spaces += 1
count = 0
while count < 2*rows-1:
count += 1
if count == 1 or count == 2*rows-1 or rows == H:
print(C, end="")
else:
print(" ", end="")
print()
rows += 1
H = int(input("Enter height of triangle: "))
C = str(input("Character: "))
for i in range(H):
for j in range(H - i):
print(' ', end='')
for j in range(2 * i + 1):
if j == 0 or j == 2 * i or i == H - 1:
print(C, end='')
else:
print(' ', end='')
print()
There's already an answer, but considering that I had fun doing this little program, and that our solution are not the same :
H = int(input("Enter height of triangle: "))
C = str(input("Character: "))
if C == "":
C = "*"
rows = 0
while rows <= H:
cols = 0
if rows == H:
while cols <= H*2:
print(C, end="")
cols += 1
else:
while cols <= H*2:
if rows + cols == H or cols - rows == H:
print(C, end="")
else:
print(" ", end="")
cols += 1
print()
rows += 1
Note that I did this with for loops, and just swapped to while loops to paste it here.
The way to get a hollow triangle is to print spaces in a loop.
If you observe the output you need, you'll see that except for the top and bottom lines, every line has only 2 asterisks (*). That means you need a logic that handles spaces.
There are several ways to write the logic, such as treating each vertical halves as blocks of fixed length and just varying the position of the star or actually counting the spaces for each line. You can explore the different ways to achieve what you need at your convenience. I'll present one soln.
H = int(input("Enter height of triangle: "))
C = str(input("Character: "))
if len(C) != 1:
C = "*"
rows = 1
count = 0
while rows < H:
str = ""
for i in range(H - rows):
str += " "
str += C
if rows > 1:
for i in range(2 * rows - 3):
str += " "
str += C
print(str)
rows += 1
str = ""
for i in range(2 * H - 1):
str += C
print(str)
I have made a change about checking the character. You should not allow characters of more than length 1. Otherwise, the spacing will get messed up
These exercises are meant for you to understand the logic and get comfortable with manipulating code, so do try different variations
This is probably not the most optimized solution but, remember that printing is in general slow as it has to interact with a peripheral (monitor), so try to print in bulk whenever possible. This improves the speed

Python program to print the pattern 1 121 12321 12 1 for n rows [duplicate]

This question already has answers here:
print a diamond of numbers in python
(3 answers)
Closed 1 year ago.
When n = 5 the pattern must be:
1
121
12321
121
1
What I tried till now:
# Pattern 1-121-12321 pyramid pattern
# Reading number of rows
row = int(input('Enter how many lines? '))
# Generating pattern
for i in range(1,row+1):
# for space
for j in range(1, row+1-i):
print(' ', end='')
# for increasing pattern
for j in range(1,i+1):
print(j, end='')
# for decreasing pattern
for j in range(i-1,0,-1):
print(j, end='')
# Moving to next line
print()
Output I am getting:
1
121
12321
1234321
123454321
I know the logic for similar such patterns like:
*
***
*****
*******
But the number pattern seems to be confusing and I am not able to get the logic.
TL;DR
Python Program for generating the following Pattern for printing n rows:
eg. When n=7:
1
121
12321
1234321
12321
121
1
How about this code:
for i in range(n):
temp = 0 # Store the value of the number to square (so 1, 11,...)
if (i < n / 2):
for j in range(i + 1):
temp += 10 ** j # Construct the number (1 = 1, 11 = 1 + 10, 111 = 1 + 10 + 10 ^ 2,...)
for _ in range(int(n / 2 - i)):
print(' ', end = '') # Add space indentation
else:
for j in range(n - i): # Count in reverse now
temp += 10 ** j # Construct the number (1 = 1, 11 = 1 + 10, 111 = 1 + 10 + 10 ^ 2,...)
for _ in range(int(i - n / 2) + 1):
print(' ', end = '') # Add space indentation
print(temp ** 2) # Square the temporary value
(Fun mathematical fact: the string you print have a property of:
1 = 1 ^ 2; 121 = 11 ^ 2; 12321 = 111 ^ 2;...)
I will also give my suggestion. So here I initially just outsource the production of the line into a method. I first calculate the length of the current line and depending on the maximum number of lines you want to print determine the padding to get this star shape. Then I produce the actual string, which is dependent on the middle point of the string, so as soon as I exceed this, I decrease the numbering again.
from math import ceil
def produce_line(line, maximum):
middle = ceil(maximum / 2)
padding = abs(middle - line)
line_width = maximum - 2 * padding
half_lw = ceil(line_width / 2)
res = (" " * padding) + "".join([str(a) if a <= half_lw else str(abs(2 * half_lw - a)) for a in range(1, line_width + 1)])
return res
lines = 9
for i in range(1, lines + 1):
print(produce_line(i, lines))
You could add an if statement and start from a count with a new variable c:
row = int(input('Enter how many lines? '))
c = row // 2
for i in range(1,row+1):
if i <= (row // 2 + 1):
# for space
for j in range(1, row+1-i):
print(' ', end='')
# for increasing pattern
for j in range(1,i+1):
print(j, end='')
# for decreasing pattern
for j in range(i-1,0,-1):
print(j, end='')
else:
for j in range(1, i):
print(' ', end='')
# for increasing pattern
for j in range(1, c):
print(j, end='')
# for decreasing pattern
for j in range(c, 0, -1):
print(j, end='')
c -= 1
# Moving to next line
print()
Output:
Enter how many lines? 7
1
121
12321
1234321
12321
121
1
Here is a short solution with a single loop an without test, it generates the range/string only once, all the rest is calculating the indices and slicing:
n = 5
n2 = (n+3)//2 # half length +1 e.g. 4 for n=5
s = ''.join(map(str,range(1, n2))) # generate '123' for n=5
for i in range(n):
stop = n//2-abs(i-n//2) # calculate length of half-string 0,1,2,1,0 for n=5
S = s[:stop+1] # slice string
print(S.rjust(n2)+S[-2::-1]) # print line e.g. '123' + '21'
output:
1
121
12321
121
1
You can try it:
for i in range(1, row+1):
if i > (row+1)/2:
i = (row+1)-i
# for space
for j in range(1, row+1-i):
print(' ', end='')
# for increasing pattern
for j in range(1, i+1):
print(j, end='')
# for decreasing pattern
for j in range(i-1, 0, -1):
print(j, end='')
# Moving to next line
print()
input:
9
output:
1
121
12321
1234321
123454321
1234321
12321
121
1
input:
7
output:
1
121
12321
1234321
12321
121
1
You can also try to simplify the problem be writing a function to get one line. And when you have that working, calling this for each line.
def create_line(number, spaces):
return ''.join([' ' for s in range(spaces)] +
[str(x) for x in range(1, number)] +
[str(x) for x in range(number, 0, -1)] +
[' ' for s in range(spaces)])
def print_pattern(n):
highest_number = (n + 1) // 2
for line_no in range(1, n + 1):
print(create_line(highest_number - abs(highest_number - line_no),
abs(highest_number - line_no)))
row = int(input('Enter how many lines? '))
print_pattern(row)
With the same approach you have taken if you have divided the problem into two as first half and second half you can generate the pattern easily with your initial approach. I have provided an easy way to break your problem like below.
# Reading number of rows
row = int(input('Enter how many lines? '))
def firsthalf(rows):
for i in range(1, rows + 1):
# for space
for j in range(1, rows + 1 - i):
print(' ', end='')
# for increasing pattern
for j in range(1, i + 1):
print(j, end='')
# for decreasing pattern
for j in range(i - 1, 0, -1):
print(j, end='')
# Moving to next line
print()
def bottomHalf(rows):
for i in range(rows, 0, -1):
# for space
for j in range(1, rows + 2 - i):
print(' ', end='')
# for increasing pattern
for j in range(1, i + 1):
print(j, end='')
# for decreasing pattern
for j in range(i - 1, 0, -1):
print(j, end='')
def pattern(rows):
firsthalf((rows // 2) + 1)
bottomHalf(rows // 2)
pattern(row)

How do I print the following pattern using nested loops in python?

I'm a beginner in python and I've been trying to print this for the past 40 minutes. Any help on how I can do this would be greatly appreciated.
The first line has 11 spaces, the second has 7 spaces, the third has 3 spaces, and the last has no spaces.
for row in range(4):
for column in range(row + 1):
print(column, end='')
print("")
So far I have two loops. This one prints: (image)
The other one is: n = 3 k = 3 for i in range(0,n+1): for j in range(k-i, -1, -1): print(j, end='') print()
That prints:
this. stack.imgur.com/IAIHk.png
I'm stuck on what to do, but I think I have a general idea. Please help!
This should work if you use a monospaced font
for i in range(1, 5):
j = 0
spaces = 2 * (4 - i) - 1
while j < i:
print(j, end = "")
j += 1
if spaces == -1:
j -= 1
else:
print(" " * spaces, end = "")
while j > 0:
j -= 1
print(j, end = "")
print()
If you want this work for any number you can define a function like
def f(n):
for i in range(1, n + 1):
j = 0
spaces = 2 * (n - i) - 1
while j < i:
print(j, end = "")
j += 1
if spaces == -1:
j -= 1
else:
print(" " * spaces, end = "")
while j > 0:
j -= 1
print(j, end = "")
print()
For example, f(6) will print
0 0
01 10
012 210
0123 3210
01234 43210
01234543210
Hope I helped

Print asterisk arrow using only While loops in Python

I am trying to create an arrow out of asterisk's, where the amount of columns is entered by the user. Yes, I do know how to use for loops to accomplish this:
columns = int(input("How many columns? "))
while columns <= 0:
print ("Invalid entry, try again!")
columns = int(input("How many columns? "))
x = 1
for x in range(1, columns):
for x in range(x):
print(" ", end="")
print("*")
for x in range(columns,0,-1):
for x in range(x):
print(" ", end="")
print("*")
#output looks like
"""
How many columns? 3
*
*
*
*
*
"""
However my question is, how would I accomplish the same outcome using only while loops?
Thanks
Edit: I was going to post what I had thus far in trying to work it out myself, but it is now of no use!
Thank you all for your efficient varying answers! Much appreciated!
Just for fun, here's a version that doesn't loop using indexing.
def print_arrow(n):
a = '*'.ljust(n + 1)
while a[-1] != '*':
print(a)
a = a[-1] + a[:-1]
a = a[1:]
while a[0] != '*':
a = a[1:] + a[0]
print(a)
# Test
print_arrow(4)
output
*
*
*
*
*
*
*
This should do:
columns = int(input("How many columns? "))
while columns <= 0:
print ("Invalid entry, try again!")
columns = int(input("How many columns? "))
x = 1
while x < columns:
y = 0
while y < x:
print(" ", end="")
y += 1
print("*")
x += 1
x = columns
while x > 0:
y = 0
while y < x:
print(" ", end="")
y += 1
print("*")
x -= 1
First, it's better to use functions. And easier if you know that character*number returns that character concatenated number times.
Example:
'*'*10
returns
'**********'
So your program using whiles would follow the same logic.
def print_arrow(k):
i = 0
while(i < k-1):
print(i*' ' + '*')
i +=1
while(i >= 0):
print(i*' ' + '*')
i -= 1
The first while prints the upper part, the last one uses the fact that i = k-1, so just do same in the reversed order.
Example:
print_arrow(3)
returns
*
*
*
*
*
n = int(input( ))
n1 = n//2 + 1
i = 1
while i <= n1:
space = 1
while space <= i - 1:
print(" ",end="")
space += 1
j = 1
p = "*"
while j <= i:
if j == i:
print(p,end="")
else:
print("* ",end="")
j += 1
print()
i += 1
i = n - n1
while i >= 1:
space = 1
while space <= i - 1:
print(" ",end="")
space += 1
j = 1
p = "*"
while j <= i:
if j == i:
print(p,end="")
else:
print("* ",end="")
j += 1
print()
i -= 1
Arrow pattern of asterisk
-Remember the n value here is always odd
for n = 5
output will be

Categories

Resources