Writing a function that prints a pyramid - two parameters - python

I'm working on this problem, that reads as follows:
Problem: Write a function that draws a pyramid on your screen. The function needs two arguments. The first is the height of the pyramid. The second argument is optional: if not supplied, the symbol "#" should be used to draw the pyramid. Otherwise, if the users enters " * " for example, the pyramid should consist of asterisks.
Attempt: I wrote this program:
def main():
h = int(input("Please enter the height of the pyramid: "))
symbol = str(input("Enter the desired symbol or press enter for standard (#): "))
def pyramid(h,symbol):
if symbol == "" or symbol == "#":
for i in range(h):
pyr = print(" " * (h-i - 1) + "#" * (2 * i + 1))
return pyr
else:
for i in range(h):
pyr = print(" " * (h-i - 1) + symbol * (2 * i + 1))
return pyr
print()
main()
But this is not working properly when I try to call this. Can someone point out my mistakes? Also, I'm not sure how to deal with the 'optional' property of the function. Should I stick to my approach or is there a better way to define that ?

your logic is fine, you can try
def pyramid(h,symbol):
if symbol == "" or symbol == "#":
for i in range(h):
print(" " * (h-i - 1) + "#" * (2 * i + 1))
else:
for i in range(h):
print(" " * (h-i - 1) + symbol * (2 * i + 1))
print()
pyramid(5, "#")
#
###
#####
#######
#########
your problems:
pyr = print(" " * (h-i - 1) + "#" * (2 * i + 1)) .... print function return None, then pyr store None
return pyr statement return pyr variable content and finish pyramid function
pyramid function isn't calling never
Improving code
you can remove unnecessary if,
def pyramid(h,symbol="#"):
for i in range(h):
print(" " * (h-i - 1) + symbol * (2 * i + 1))
print()
pyramid(5)
you can return a str
def pyramid(h,symbol="#"):
out = ""
for i in range(h):
out += (" " * (h-i - 1)) + (symbol * (2 * i + 1)) + "\n"
return out
print(pyramid(5))
or, online solution
def pyramid(h,symbol="#"):
return "\n".join((" " * (h-i - 1)) + (symbol * (2 * i + 1)) for i in range(h))
print(pyramid(5))

Related

Currently taking the freecodecamp python and need help refactoring my solution

I tried my hand at the freecodecamp python algorithm and I came up with a solution for the first question but need help refactoring it. Here is the arithmetic arranger question click here to access the question
The solution can be found below:
import operator
ops = {"+": operator.add, "-": operator.sub, "*": operator.mul}
def arithmetic_arranger(problems, solver=False):
# Check problems does not exceed the given max(5)
if len(problems) > 5:
return "Error: Too many problems."
toptier = ""
bottomtier = ""
lines = ""
totals = ""
for n in problems:
fnumber = n.split()[0]
operator = n.split()[1]
snumber = n.split()[2]
# Handle errors for input:
if operator != "+" and operator != "-":
return "Error: Operator must be '+' or '-'."
if not fnumber.isdigit() or not snumber.isdigit():
return "Error: Numbers must only contain digits."
if len(fnumber) > 4 or len(snumber) > 4:
return "Error: Numbers cannot be more than four digits"
# Get total of correct function
total = ops[operator](int(fnumber), int(snumber))
# Get distance for longest operator
operatorDistance = max(len(fnumber), len(snumber)) + 2
snumber = operator + snumber.rjust(operatorDistance - 1)
toptier = toptier + fnumber.rjust(operatorDistance) + (4 * " ")
bottomtier = bottomtier + snumber + (4 * " ")
lines = lines + len(snumber) * "_" + (4 * " ")
totals = totals + str(total).rjust(operatorDistance) + (4 * " ")
if solver:
print(toptier)
print(bottomtier)
print(lines)
print(totals)
if __name__ == "__main__":
arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])
Moved the post to the CodeReview community as it already works and I just need help refactoring it. If interested click here to follow and help there instead :)

my decoration sometimes appears just outside the triangle

It seems that my decoration sometimes appears just outside the triangle... How can I fix this?
import random
n = int(input('enter n: '))
x = 1
for i in range(n):
if i == 0:
count = 0
else:
count = random.randint(0, x)
print(' ' * (n - i), '*' * count, end = '')
if i == 0:
print('&', end = '')
else:
print('o', end = '')
print('*' * (x - count - 1))
x += 2
What do I get for value n = 10:
&
***o
*o***
o******
******o**
*********o*
*************o
*****o*********
*************o***
******************o
The random number you generate may return x as randint includes the second value in the set of possible values. So pass x - 1 to randint:
count = random.randint(0, x - 1)
It is also a pity that you have a check for i == 0 in your loop. In that case, why not deal with that first case outside of the loop, and start the loop at 1? It will make your code a bit more elegant.
def tree(n):
from random import sample
body = ["&"] + ["".join(sample("o" + "*" * (k:=x*2+1), k=k)) for x in range(1, n)]
spaces = [" " * (x-2) for x in range(n, 1, -1)]
return "\n".join("".join(tpl) for tpl in zip(spaces, body))
print(tree(10))
Output:
&
o**
****o
o******
*******o*
********o**
*******o*****
**************o
o****************
I love christmas tress! This is my take on the question :-)
import random
n = int(input('Enter tree height: '))
print(" " * (n-1) + "&")
for i in range(2, n+1):
decoration = random.randint(1, (i-1)*2 -1)
print(" " * (n - i) + "*" * decoration + "o" + "*" * ((i-1)*2 - decoration))
Enter tree height: 12
&
*o*
**o**
*o*****
*o*******
********o**
*******o*****
***********o***
********o********
****************o**
***o*****************
*********o*************

Python STAR & HASH ODD DIAMOND print with recursion

I want to make a pattern as shown below:
I write this program which is given below. But I couldn't take ODD numbers. Could anybody please explain what the mistake is and what the solution is? Thanks.
*
def printPartten(n, k):
if (n < 0): # Base condition
return;
# Recursive call
printPartten(n - 1, k + 1);
for i in range(0, k): # it makes spaces
print(" ", end="");
for i in range(0, n): # for print *
print("* ", end = "");
print("\n", end=""); # for next line
def printPatternReverse(n, k):
if (n < 0): # Base condition
return;
for i in range(0, k): # it makes spaces
print(" ", end = "")
for i in range(0, n): # for print *
print("#", end = " ")
print("\n", end = "") # for next line
# Recursive calls
printPatternReverse(n - 1, k + 1);
# Call to printPartten function
n = int(input("Please enter the desire value for N: "))
printPartten(n, 0);
print("\n",end="")
printPatternReverse(n,0)
print("Thank You!!!")
*
My Output like this:
You example shows that it skips the even rows, so you could add a check for even rows using a modulus:
if (k % 2 == 0):
Applied to your code:
def printPartten(n, k):
if (n < 0): # Base condition
return;
# Recursive call
printPartten(n - 1, k + 1);
if (k % 2 == 0):
for i in range(0, k): # it makes spaces
print(" ", end="");
for i in range(0, n): # for print *
print("* ", end = "");
if (k > 0):
print("\n", end=""); # for next line
def printPatternReverse(n, k):
if (n < 0): # Base condition
return;
if (k % 2 == 0):
for i in range(0, k): # it makes spaces
print(" ", end = "")
for i in range(0, n): # for print *
print("#", end = " ")
print("\n", end=""); # for next line
# Recursive calls
printPatternReverse(n - 1, k + 1);
# Call to printPartten function
n = int(input("Please enter the desire value for N: "))
printPartten(n, 0);
print("\n",end="")
printPatternReverse(n,0)
print("Thank You!!!")
Output:
Please enter the desire value for N: 9
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
# # # # # # # # #
# # # # # # #
# # # # #
# # #
#
Thank You!!!

how to make pyramid python like that..?

How to make program like this.???
Input : 4
*
* *
* *
* * * *
I would love to know how to do this, it's been bugging me all week but it was only an extra credit question so my teacher never explained how to do it!! :(
http://i.stack.imgur.com/qlyGu.jpg
I thought this would be fun to try, here is my solution:
PROMPT_MSG = "Please enter a whole number, greater than 1"
PROMPT_MSG_ERR = "Oops! Please try again.."
def validate_input(input):
try:
assert int(input) > 1
return int(input)
except (ValueError, AssertionError) as e:
print PROMPT_MSG_ERR + "\n"
main()
def main():
user_input = raw_input("{0}: ".format(PROMPT_MSG))
valid_input = validate_input(user_input)
if valid_input:
print "{0}*".format(" " * valid_input)
for i in range(0, valid_input)[1:-1]:
print "{0}*{1}*".format(
(" " * (valid_input - i)),
(" " * (i + (i-1))),
)
print " *" * valid_input
if __name__ == '__main__':
main()

Calling functions inside other functions in Python

I'm trying to write a simple program that creates a square grid like this:
+ - - - - + - - - - +
| | |
| | |
| | |
| | |
+ - - - - + - - - - +
| | |
| | |
| | |
| | |
+ - - - - + - - - - +
I want it to take an input x, which defines how many cells are in each row/column. The script is as follows:
def repeat(x, f, *args):
for i in range(x): f(*args)
def topx(x):
print x*top + '+'
def midx(x):
print x*mid + '|'
def block(f,g,*args):
f(*args)
g(*args)
top = str('+ - - - - ')
mid = str('| ')
x = 2
repeat(x,block,topx,repeat,x,4,midx,x)
topx()
I get the following error when I try to run the script:
TypeError: topx() takes exactly 1 argument (4 given)
It's something to do with the arguments in the block function, but can't figure out how to get around it.
Thanks in advance.
Edit:
Thanks for the pointers, I rewrote it slightly as follows and it works nicely. I also changed it to allow you to choose the number of columns and rows independently.
def repeat(x, f, *args):
for i in range(x): f(*args)
def topx(x):
print x*top + '+'
def midx(x):
print x*mid + '|'
def row(x):
topx(x)
repeat(4,midx,x)
top = str('+ - - - - ')
mid = str('| ')
x = 3
y = 4
repeat(y,row,x)
topx(x)
def topx(x):
print x*top + '+'
This takes one argument: x. But when you call it:
def block(f,g,*args):
f(*args) # This is what calls topx
g(*args)
You're passing it *args, which contains [x, 4, midx, x]. And that's four arguments right there.
You should probably reconsider your structure to fix this. Perhaps a class?
def grid(x, space=4):
for i in range(x):
print ("+" + "-"*space)*x + "+"
for j in range(space):
print ("|" + " "*space)*x + "|"
print ("+" + "-"*space)*x + "+"
I think this is not best way. but your script can be easily updated to be more readable and working.
cell_number = 2
top = str('+ - - - - ')
mid = str('| ')
def repeat(cell_number, f, *args):
"""
repeat call of function `f` `call_number` times
"""
for i in range(cell_number):
f(*args)
def topx(cell_number):
"""
draw horizontal edge
"""
print cell_number * top + '+'
def midx(cell_number):
"""
draw middle part with vertical edges
"""
print cell_number * mid + '|'
def block(cell_num):
"""
draw one row of `cell_num` cells
"""
topx(cell_num)
repeat((len(top) - 1)/2, midx, cell_num)
repeat(cell_number, block, cell_number)
topx(cell_number)
def box(width, height, cell=1):
print '+' + ('- ' * width + '+') * cell
for x in range(cell):
for x in range(height):
print '|' + (' ' * width + '|') * cell
print '+' + ('- ' * width + '+') * cell

Categories

Resources