Draw inverted triangle of asterisk by using nested loops in Python - python

I've to write a program that get a series of valid inputs from user and then uses the nested loops to draw the inverted triangle.
I've managed to work out the triangle but I struggling on inverted triangle. Can anyone give me some hint on how to draw the inverted triangle by only print a single charater of * and without using * * rowlength?
Global constant
L = 10
Get rows number
rows = int(input ( 'Enter a number of rows: ' ) )
Rows cannot less than 10 or greater than 100
while rows < 10 or rows > 100:
if rows < L:
print( 'The number is too Low.' )
else:
print( 'The number is too high.' )
rows = int(input ( 'Enter the correct value: ' ) )
Display the triangle
for r in range(rows):
for c in range(r + 1):
print('*', end='')
print()

This is very similar to a question I had to do for class once, but we were implementing it in C. Actually, quite cool to go back now, reimplement it in python and look at the difference.
The problem we had in class was very similar. My python code to make this work is:
while True:
rows = input('Enter the number of rows: ')
if 3 <= rows <= 33:
break
else:
continue
padding = ' '*rows
while rows > 0:
print(padding[rows:] + '*'*rows)
rows = rows - 1
-- modified below, to print outline of inverted triangle:
# print the outline of an inverted triangle:
height = rows
# inner padding for min height (3)
inner_buffer = [0, 1, 3]
while len(inner_buffer) <= rows:
inner_buffer.append(inner_buffer[-1]+2)
while height > 0:
outer_padding = ' '*(rows - height)
if height == 1:
print(outer_padding + '*')
else:
inner_padding = ' '*(inner_buffer.pop()-2)
print(outer_padding + '*' + inner_padding + '*')
height = height - 1
There has got to be a more elegant want to code this, but simply a working hack to see if we are on the right track.
New revision below:
-- function that will produce a regular triangle, or inverted triangle as defined
def get_rows():
while True:
rows = input('Enter the number of rows: ')
if 3 <= rows <= 33:
return rows
def triangle(rows, regular=False, invert=True):
if invert:
height = -1 * rows
else:
height = 0
# inner padding for min height (3)
inner_buffer = [0, 1, 3]
while len(inner_buffer) <= rows:
inner_buffer.append(inner_buffer[-1]+2)
level = 0
while level <= rows:
outer_padding = ' '*(rows - abs(height))
if height == 0:
print(outer_padding + '*')
else:
inner_padding = ' '*( inner_buffer[ abs(height) ] )
print(outer_padding + '*' + inner_padding + '*')
height += 1
level += 1
Let me know :)

Related

How to make pyramid of a string?

I want to make a pyramid of a string for an exercise.
I just don't know how to do it.
For example:
string = "these***are***just***random***words*"
and the pyramid I want to make is:
t
hes
e***a
re***ju
st***rand
om***words*
How do I do this?
def draw_pyramid(string, size):
if size > 15:
size = 15
if size < 5:
size = 5
l = string * size
for i in range(size + 1):
stars = i
p = l[0:stars]
spaces = size - i
print(" " * spaces + p)
def main():
size = int(input("How many layers do you want it to be?: "))
string = "these***are***just***random***words*"
draw_pyramid(string, size)
if __name__ == '__main__':
main()
Result:
t
th
the
thes
these
these*
these**
these***
these***a
these***ar
You can use string.center() to get the strings nicely aligned in the center. To get the right characters from l I use a start and an end variable:
def draw_pyramid(string, size):
if size > 15:
size = 15
if size < 5:
size = 5
length = size * 2 - 1
l = string * size
start = 0
end = 0
for stars in range(1, size + 1):
end += stars * 2 - 1
p = l[start:end]
start = end
print(p.center(length))
Output :
How many layers do you want it to be?: 10
t
hes
e***a
re***ju
st***rand
om***words*
these***are**
*just***random*
**words*these***a
re***just***random*
The way you are indexing l is wrong, based on what you want to achieve. If you study your desired output, you see that on the first row you want the substring l[0:1], on the second row l[1:4], then l[4:9], l[9:16] etc. The starting index is the sum of the first i odd elements, i.e. 1+3+5+.. and the stopping index is the sum of the first i+1 odd elements. Thus, at each step, you want l[i**2:(i+1)**2], with i starting at 0.
So your function should look like this
def draw_pyramid(string, size):
if size > 15:
size = 15
if size < 5:
size = 5
l = string * size
for i in range(size + 1):
p = l[i**2:(i+1)**2]
spaces = size - i
print(" " * spaces + p)
and it produces the desired output

how can i generate circles in the Pascal's triangle?

Our assignment task is on recursion to develop the Pascal Triangle and circle the generated numbers in a red font. I managed to generate the Pascal triangle after user input, however how do K proceed to make the numbers have a red font and be circled?
I used recursion to achieve the pascal triangle after user enters no. of rows, but now am stuck on how to make the numbers encircled. Below is the code I used.
rows = int(input("enter number of rows:"))
list1 = [] #empty list
for i in range(rows):
list2 = [] #sublist to print numbers
for col in range(i+1):
if col == 0 or col == i:
list2.append(1)
else:
list2.append(list1[i - 1][col - 1] + list1[i - 1][col])
list1.append(list2)
for col in range(rows-1-i):
print(format("","<2"), end='')
for col in range(i+1):
print(format(list1[i][col],"<3"), end='')
print()
```
In order to make the console text red you can use:
print("\033[31m" + string)
The details on how it works you can find here: https://stackabuse.com/how-to-print-colored-text-in-python/
I don't really understand what is the expecting "circle" output but you can play with this script:
list_of_all_elements = []
for item in list1:
list_of_all_elements.extend(item)
half_length = len(list_of_all_elements) // 2 + 1
symbol = " "
for i in range(half_length):
# Number of symbols in the start of the row.
temp = symbol * (half_length//2 - i if i <= half_length//2 else i - half_length//2)
# First row.
if i == 0:
temp += str(list_of_all_elements[i])
# Both "elifs" - last row.
elif i == half_length - 1 and len(list_of_all_elements) % 2 == 0:
temp += " " + str(list_of_all_elements[half_length-1])
elif i == half_length - 1 and len(list_of_all_elements) % 2 != 0:
temp += str(list_of_all_elements[half_length-1]) + " " + str(list_of_all_elements[half_length])
# Middle rows.
else:
number_of_middle_symbols = symbol*(2*i-1 if i <= half_length//2 else 4*half_length//2 - 2*i - 1)
temp += str(list_of_all_elements[i]) + number_of_middle_symbols + str(list_of_all_elements[-i])
# Printing the current row in red.
print("\033[31m" + temp)
Here list1 is the list generated by your code. I would say it provides the output which looks more like a rombus than a circle, but this script could be a place to start with.

Can't get my python pyramid to show up correctly

Here's the code I've been working with
def pyramid(n):
print('Pyramid Output')
if (n%2 != 0 and n > 0):
for i in range(1,n-1,1):
spaces = int(.5*n - i + .5)
sides = (i-1)
print(spaces*' ' + sides*"-" + '-' +sides*"-")
But past a certain value, the pyramid becomes left justified and starts adding values to the right side. Any help would be much appreciated
Your spaces computation (and also your range) is wrong. To build a 5 tiles high pyramid you need to add 4,3,2,1,0 spaces in front:
4444-
333---
22-----
1-------
---------
For bigger n your spaces computation is simply wrong. Lets take n=51:
# on row 20:
spaces = int(0.5*51 - 20 + .5) # => 25.5 -20 + 0.5 = 6 ... still 31 rows to go
# on row 26:
spaces = int(0.5*51 - 26 + .5) # => 25.5 -26 + 0.5 = 0 ... still 21 rows to go
# on row 30:
spaces = int(0.5*51 - 30 + .5) # => 25.5 -30 + 0.5 is negative ... how add negative space?
Fix:
def pyramid(n):
print('Pyramid Output')
if (n%2 != 0 and n > 0): # no even row numbers pyramids allowed!
for i in range(1,n+1,1): # for n=5 yours is 1,2,3 - probably shold be range(1,n+1)
spaces = n-i
sides = 2*(i-1)+1 # optimized
print(spaces*' ', sides*'-', sep="") # optimized
pyramid(51)

W by H grid tiles?

Imagine that we have a w by h grid, where the tiles are numbered starting at 1 in the top left corner. w (for width) and h (for height) have been stored in a function. You have access to these stored values, as long as you call them w and h. Write a program to return: The column number of a tile number given by the user. Start counting columns at column 1.
import subprocess
def template(w, h, t):
#w and h are memory locations that already contain values
tile = t
sum = ((t - 1) // w) + 1
#END OF YOUR CODE
failed = 0
width = 1
while width <= 3:
height = 1
while height <= 3:
tile = 1
while tile <= width * height:
result = template(width, height, tile)
col = (tile - 1) % width + 1
if (result == col):
print "On a " + str(width) + " by " + str(height) +" board, with tile " + str(tile) +", col is " + str(col) + ", you got it RIGHT!"
else:
print "On a " + str(width) + " by " +:str(height)%+" board, with tile " + str(tile)%+", col is " + str(col) + ", you got: " + str(result)
failed = 1
tile += 1
height += 1
width += 1
if (failed == 0):
print "Your code is CORRECT!"
print "Please check your code, at least one test case did not pass."
I am almost there I think, but this formula isn't quite right and I'm out of ideas.
See below pseudo code, this approach should work for you,
# divide t by h, the tile should reside in the next row
tileRow = (t/h)+1
# get the reminder of the division, that's the column number
tileColumn = t%h
see the sample code I tried below
>>> w = 5
>>> h = 10
>>> t =36
>>> tileRow = (t/h)+1
>>> tileRow
4 # the tile is in the 4th row
>>> tileColumn = t%h
>>> tileColumn
6 # the tile is in the 6th column
>>>
You may also have to check if the tile number is within in range, in the above example its w x h (50)
Please comment if you need anymore clarification. If this resolves your problem you may accept and vote the answer
To create the grid, use a list comprehension.
grid=[list(range(x,x+w))for x in range(1,w*h,w)]
To find the column number of t, find the remainder of t divided by w:
t%w
So the function would be:
def template(w,h,t):
grid=[list(range(x,x+w))for x in range(1,w*h,w)]
return t%w
Example:
template(6,5,22)
Output:
4

leading number groups between two numbers

(Python) Given two numbers A and B. I need to find all nested "groups" of numbers:
range(2169800, 2171194)
leading numbers: 21698XX, 21699XX, 2170XX, 21710XX, 217110X, 217111X,
217112X, 217113X, 217114X, 217115X, 217116X, 217117X, 217118X, 2171190X,
2171191X, 2171192X, 2171193X, 2171194X
or like this:
range(1000, 1452)
leading numbers: 10XX, 11XX, 12XX, 13XX, 140X, 141X, 142X, 143X,
144X, 1450, 1451, 1452
Harder than it first looked - pretty sure this is solid and will handle most boundary conditions. :) (There are few!!)
def leading(a, b):
# generate digit pairs a=123, b=456 -> [(1, 4), (2, 5), (3, 6)]
zip_digits = zip(str(a), str(b))
zip_digits = map(lambda (x,y):(int(x), int(y)), zip_digits)
# this ignores problems where the last matching digits are 0 and 9
# leading (12000, 12999) is same as leading(12, 12)
while(zip_digits[-1] == (0,9)):
zip_digits.pop()
# start recursion
return compute_leading(zip_digits)
def compute_leading(zip_digits):
if(len(zip_digits) == 1): # 1 digit case is simple!! :)
(a,b) = zip_digits.pop()
return range(a, b+1)
#now we partition the problem
# given leading(123,456) we decompose this into 3 problems
# lows -> leading(123,129)
# middle -> leading(130,449) which we can recurse to leading(13,44)
# highs -> leading(450,456)
last_digits = zip_digits.pop()
low_prefix = reduce(lambda x, y : 10 * x + y, [tup[0] for tup in zip_digits]) * 10 # base for lows e.g. 120
high_prefix = reduce(lambda x, y : 10 * x + y, [tup[1] for tup in zip_digits]) * 10 # base for highs e.g. 450
lows = range(low_prefix + last_digits[0], low_prefix + 10)
highs = range(high_prefix + 0, high_prefix + last_digits[1] + 1)
#check for boundary cases where lows or highs have all ten digits
(a,b) = zip_digits.pop() # pop last digits of middle so they can be adjusted
if len(lows) == 10:
lows = []
else:
a = a + 1
if len(highs) == 10:
highs = []
else:
b = b - 1
zip_digits.append((a,b)) # push back last digits of middle after adjustments
return lows + compute_leading(zip_digits) + highs # and recurse - woohoo!!
print leading(199,411)
print leading(2169800, 2171194)
print leading(1000, 1452)
def foo(start, end):
index = 0
is_lower = False
while index < len(start):
if is_lower and start[index] == '0':
break
if not is_lower and start[index] < end[index]:
first_lower = index
is_lower = True
index += 1
return index-1, first_lower
start = '2169800'
end = '2171194'
result = []
while int(start) < int(end):
index, first_lower = foo(start, end)
range_end = index > first_lower and 10 or int(end[first_lower])
for x in range(int(start[index]), range_end):
result.append(start[:index] + str(x) + 'X'*(len(start)-index-1))
if range_end == 10:
start = str(int(start[:index])+1)+'0'+start[index+1:]
else:
start = start[:index] + str(range_end) + start[index+1:]
result.append(end)
print "Leading numbers:"
print result
I test the examples you've given, it is right. Hope this will help you
This should give you a good starting point :
def leading(start, end):
leading = []
hundreds = start // 100
while (end - hundreds * 100) > 100:
i = hundreds * 100
leading.append(range(i,i+100))
hundreds += 1
c = hundreds * 100
tens = 1
while (end - c - tens * 10) > 10:
i = c + tens * 10
leading.append(range(i, i + 10))
tens += 1
c += tens * 10
ones = 1
while (end - c - ones) > 0:
i = c + ones
leading.append(i)
ones += 1
leading.append(end)
return leading
Ok, the whole could be one loop-level deeper. But I thought it might be clearer this way. Hope, this helps you...
Update :
Now I see what you want. Furthermore, maria's code doesn't seem to be working for me. (Sorry...)
So please consider the following code :
def leading(start, end):
depth = 2
while 10 ** depth > end : depth -=1
leading = []
const = 0
coeff = start // 10 ** depth
while depth >= 0:
while (end - const - coeff * 10 ** depth) >= 10 ** depth:
leading.append(str(const / 10 ** depth + coeff) + "X" * depth)
coeff += 1
const += coeff * 10 ** depth
coeff = 0
depth -= 1
leading.append(end)
return leading
print leading(199,411)
print leading(2169800, 2171194)
print leading(1000, 1453)
print leading(1,12)
Now, let me try to explain the approach here.
The algorithm will try to find "end" starting from value "start" and check whether "end" is in the next 10^2 (which is 100 in this case). If it fails, it will make a leap of 10^2 until it succeeds. When it succeeds it will go one depth level lower. That is, it will make leaps one order of magnitude smaller. And loop that way until the depth is equal to zero (= leaps of 10^0 = 1). The algorithm stops when it reaches the "end" value.
You may also notice that I have the implemented the wrapping loop I mentioned so it is now possible to define the starting depth (or leap size) in a variable.
The first while loop makes sure the first leap does not overshoot the "end" value.
If you have any questions, just feel free to ask.

Categories

Resources