I currently working on CS50. There is a problem where we need to recreate half-pyramids using hashes (#). The hashes are to substitute blocks like in Mario.
This is also the first time I'm using Python. I don't really know Python. So I just try to calculate myself based on my experience from C language.
from sys import exit
from cs50 import get_int
def main():
while True:
num = get_int("Height: ")
if num >= 1 and num <= 8:
break
print_pyramid(num)
exit(0)
def print_pyramid(n):
for i in range(n):
print_spaces(i, n) # calling two function that print spaces and hash
print_hash(i) # after print every spaces and hash in each row,
print() # print new line for new row
def print_spaces(i, n):
for j in range(n-(i+1)): # those calculation means that we print space one less than the height ......# (seven spaces)
print(" ", end="") # if height = 8 8-(i+1) 'i' is increment from above function .....## (six spaces)
def print_hash(i):
for l in range(i+1): # print the hash by increasing it (i+1)
print("#", end="") # i = 0 # / i = 1 ##
l = 1 # there's two spaces between two pyramid. at the print_spaces function range(n - i+1)
n = 4 # so initialize l = 1 and n = 4, would always give (4-(1+1)) = 2
print_spaces(l, n)
for l in range(i+1): # print rigth hash 'pyramid'
print("#", end="")
main()
I always love to work with complicated idea using a lot of function for their different purpose.
I also got a 98% score from CS50.
What do you think of my code? Since this is my first time using Python, are there any Pythonic ways to simplify my program? (especially using function like I did).
Height: 4
# #
## ##
### ###
#### ####
-
4\$\begingroup\$ for those (like me) who don't know: what is CS50? \$\endgroup\$hjpotter92– hjpotter922020年09月28日 11:15:01 +00:00Commented Sep 28, 2020 at 11:15
-
1\$\begingroup\$ @hjpotter92 It's a course Harvard University provides. The website is cs50.harvard.edu \$\endgroup\$Peilonrayz– Peilonrayz ♦2020年09月28日 11:24:28 +00:00Commented Sep 28, 2020 at 11:24
2 Answers 2
Your code is quite nice. Your use of functions seem quite reasonable. And your style is nice too. Good job!
Calling
print
is expensive. To improve performance we can build the strings without using the for loop. For example to build \$n-(i + 1)\$ spaces we can use:>>> n = 12; i = 1 >>> " " * (n - (i + 1)) ' '
To build the pyramid you can delegate the creation of the spaces to Python by using
str.ljust
andstr.rjust
. These functions allow an easy to use way to build the pyramid.>>> 'abc'.ljust(10) 'abc ' >>> 'abc'.rjust(10) ' abc'
Using
print_spaces(l, n)
is harder to understand thanprint(" ")
.Your use of comments are not great. Most of them can be understood by just reading the code.
I only found one of your comments to help. Because it explains something that isn't particuarly clear in clear English.
# there's two spaces between two pyramid. at the print_spaces function range(n - i+1) # so initialize l = 1 and n = 4, would always give (4-(1+1)) = 2
However this is a sign that your code is complicated. Which if you fix will make your comment redundent.
If we put these together we can greatly simplify your code.
from sys import exit
from cs50 import get_int
def main():
while True:
num = get_int("Height: ")
if num >= 1 and num <= 8:
break
print_pyramid(num)
exit(0)
def print_pyramid(n):
for i in range(n):
hashes = "#" * (i + 1)
print(hashes.rjust(n) + " " + hashes)
main()
There are still some more improvements that can be made.
Using
sys.exit(0)
is abnormal. It is normally best to just let Python handle that for you.We can add an
if __name__ == "__main__"
guard to prevent your code from running if you import it accidentally.This is because if you use
import filename
you can import this program by accident and we don't want to run themain
function if that happens.I personally am a fan of always using the
<
operator. It just feels natural to see numbers ordered from smallest to largest, left to right.We can Pythonify the print in
print_pyramid
by using the Format Specification Mini-Language.There are three parts to this.
By using a format string we can enter values where we want them in a formatted string.
>>> a = 1; b = 2; c = 3 >>> f"{b}:{a} -> {c}" '2:1 -> 3' >>> "{b}:{a} -> {c}" # Not a format string '{b}:{a} -> {c}' >>> "{b}:{a} -> {c}".format(a=a, b=b, c=c) # Old style format strings '2:1 -> 3'
We can use the alignment option to align the values where we want them to.
>>> a = 1; b = 2; c = 3 >>> f"{b:>3}:{a:<3} -> {c:^3}" ' 2:1 -> 3 '
We can enter the width using the same
{}
syntax as the values.>>> a = 1; b = 2; c = 3; width = 3 >>> f"{b:>{width}}:{a:<{width}} -> {c:^{width}}" ' 2:1 -> 3 '
from sys import exit
from cs50 import get_int
def main():
while True:
num = get_int("Height: ")
if 1 <= num and num <= 8:
break
print_pyramid(num)
def print_pyramid(n):
for i in range(n):
hashes = "#" * (i + 1)
print(f"{hashes:>{n}} {hashes}")
if __name__ == "__main__":
main()
-
\$\begingroup\$ Thank you so much. Your code is so simple. I'll try to understand it more deeply. \$\endgroup\$Kevin Mahendra– Kevin Mahendra2020年10月01日 17:55:36 +00:00Commented Oct 1, 2020 at 17:55
- You use three different names for the same thing. You ask for
Height
, then call itnum
, then call itn
. I'd just call the variablesheight
, both to be consistent and to be meaningful. At least inmain
andprint_pyramid
, as there it really means height. Inprint_spaces
it's perhaps better to keep calling the parametern
, as that function doesn't need to know about pyramids and heights. num >= 1 and num <= 8
can be the nicer1 <= num <= 8
(or rather1 <= height <= 8
).- Your actual output does not match the claimed/desired(?) output you showed. You do not have those extra spaces at the start of each line to fill up the left pyramid half to width 8. Which I guess you should, as that would match the
<= 8
condition, so that seems intended. - You use
i
at three places, and every single time you add1
to it. Probably clearer to do that in the range right away, i.e.,for i in range(1, n+1):
instead offor i in range(n):
.
Explore related questions
See similar questions with these tags.