CS50 Mario More Sentimental Python - Not Printing Rows - python

I am attempting to write the CS50 Mario More Sentimental (Python) and I am running across some issues. The code is not performing correctly and is generating some issues as listed below:
Results for cs50/problems/2020/x/sentimental/mario/more generated by check50 v3.1.2
:) mario.py exists.
:) rejects a height of -1
:) rejects a height of 0
:( handles a height of 1 correctly
expected ""# #"", not ""
:( handles a height of 2 correctly
expected "" # #"\n"## ...", not ""
:( handles a height of 8 correctly
expected "" # #"\...", not ""
:( rejects a height of 9, and then accepts a height of 2
expected program to reject input, but it did not
:) rejects a non-numeric height of "foo"
:) rejects a non-numeric height of ""
To see the results in your browser go to https://submit.cs50.io/check50/74938be07d19fd3664e32b052c21717012088526
I am not understanding why it will not display the blocks now...
# make sure there is valid input
while True:
try:
# ask for input
height = int(input("Height: "))
# make sure height is greater than 0 and less than or equal to 8
if height >= 1 and height <= 8:
break
# iterate through height
for counter in range(height):
print(" " * (height - 1 - counter), end="")
print("#" * (counter + 1), end="")
print(" " * 2, end="")
print("#" * (counter + 1), end="")
print(end="\n")
# display error message is value entered is below or above 1 and 8
except ValueError:
print("Please enter a number between 1 and 8. ", end="\n")

Not sure why we need while loop at all. Try taking height input from user without while loop and check if h>=1 & h<=8, if yes: run your for loop else: print error message & exit()
height = int(input("Height: "))
if height >= 1 and height <= 8:
for counter in range(height):
print(" " * (height - 1 - counter), end="")
print("#" * (counter + 1), end="")
print(" " * 2, end="")
print("#" * (counter + 1), end="")
print(end="\n")
else:
print("Please enter height between 1 and 8")
exit()

Related

I no longer have an alignment issue, however, when I print out my X's and O's there will be a 0 next to them. Does anyone know a different solution?

This is what I have so far, if you have any ideas please let me know. It would mean a lot to me.
a_list = list(range(1, squared_input + 1))
turn = 0
Symbol_1 = "X"
Symbol_2 = "O"
while turn <= 9:
X = 1
while X < squared_input + 1 :
print(str(a_list[X - 1]).zfill(2), end= "")
if X%board_size == 0 :
print("")
print(("--+" * (board_size - 1)), end="")
print("--")
else:
print("|", end="")
X = X + 1
turn = turn + 1
Symbol_1, Symbol_2 = Symbol_2, Symbol_1
print("You are user " + Symbol_1 + ".")
user_input = input("Please pick a slot on the game board (using numbers 1 - " + str(squared_input) + "): ")
a_list[int(user_input) - 1] = Symbol_1
The zeros come from your call to zfill which explicitly pads a string with 0 to a requested size. You call zfill(2) with a string that contains a single character. So the function pads that to length two by adding a 0.
To pad with blanks you can for example use the format() function or just something like
'%2d' % a_list[X-1]
which will pad each number to length 2 from the left with blanks, or
'%-2d' % a_list[X-1]
which will pad each number to length 2 from the right with blanks.

Python: Make Pyramid With Numbers

I'm trying to make a pyramid with numbers without reassigning.
I was able to do this with symbols (see below):
def print_pyramid_step_3(heightNum):
ctr = 1
while(ctr <= heightNum):
row_spaces = " " * (heightNum - ctr)
row = (2*ctr-1) * "$"
print(row_spaces + row)
ctr = ctr +1
# Get the input to get the height of the pyramid
heightNum = int(input("Enter the height of the pyramid: "))
print("----"*50)
print("Printing the pyramid by adding spaces to the row")
print("----"*50)
print_pyramid_step_3(heightNum)
Output:
$
$$$
$$$$$
$$$$$$$
$$$$$$$$$
The desired output Im trying to get looks like this when a user types in a pyramid height of 5 and the starting number is 1.
Desired Output:
1
234
56789
10111213141516
171819202122232425
try this:
j = 1
for i in range(height):
for k in range(1,height + i+1):
if (k < height - i):
print(" ", end='')
else:
print(j, end='')
j+=1
print()

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

Printing an ASCII diamond with set width in python

Yes, this is a homework task. But just please, if you're going to give me the code please tell me what you've done in detail. I am extremely new to this.
So the task is to print an ASCII diamond depending on what width the user inputs. I can do the first half of the diamond, just not the bottom half, for some reason I just cannot see how to do it.
Here's my code:
wid = int(input("Width: "))
i = 1
while i <= wid:
print(" " * (wid - i) + "* " * i)
i = i + 1
Which will output the following if wid = 5:
Width: 5
*
* *
* * *
* * * *
* * * * *
I tried to explain the code with comments. I hope it helps.
wid = int(input("Width: "))
#no. of lines will be double the width
#each loop prints a line.
for i in range(wid *2):
#first half of the diamond
if i<=wid:
no_of_spaces = wid - i
no_of_stars = i
print(" "*no_of_spaces + "* "*no_of_stars)
#next half of the diamond
else:
no_of_spaces = i - wid
no_of_stars = 2*wid - i
print(" "*no_of_spaces + "* "*no_of_stars)
i=1
j=input("ENTER NO =")
l=0
for i in range(i,j-((j/2)-1),1):
print (' ' * ((j+1)/2-i)+'*' *(i*2-1))
l=(j/2+1)
while (i==l):
i=1
for i in range(i,j,1):
print (' ' *((i*2)-i)+'*' *(j-i*2))
if [i==j-1]:
l=raw_input('<press enter to exit>')
You start with i = 1 and go until i > wid to make the top. To make the bottom of the diamond, you must do the reverse of what you did for the top. The code is easy, but I won't write it unless you want me to.
after your while
i=i-2
while i>0:
print(" "*(wid-i)+"* "*i)
i=i-1;
One method
The simplest way would probably be have two loops; one counting i up to width, another counting i back down to 1.
width = int(input("Width: "))
i = 1
while i < width:
print " " * (width-i) + "* " * i
i += 1
while i > 0:
print " " * (width-i) + "* " * i
i -= 1
This is a bit unattractive because it's a little clumsy, but it's simple.
Another method
Another method is to have have a loop that counts to twice the width, doing one of two things. What it does depends on if i has passed the point of maximum width or not. So it does 'up' and 'down' in the same loop, counting i from 1 up to width*2.
width = int(input("Width: "))
i = 1
while i < width*2:
if i < width:
print " " * (width-i) + "* " * i
else:
print " " * (i-width) + "* " * (2*width-i)
i += 1
This:
print " " * (width-i) + "* " * i
...is your code. Spaces count from width down to 0, *'s from 1 up to width.
And this:
print " " * (i-width) + "* " * (2*width-i)
...is the same thing but inverted. Spaces count from 0 back up to width, and the *'s go back down from width to 1. This comes into play when i exceeds width.
Width: 4
* # first half does this onward
* *
* * *
* * * *
* * * # second half does the rest downward
* *
*
And another
Another alternative, more complex way is to use a for loop on a list that contains numbers counting up and down. For example: [1, 2, 3, 2, 1]
To make this list, this code has to be. I know, it's a bit ugly:
rows = []
for i in range(1, max+1):
rows.append(i)
rows += rows[-2::-1]
Then, you see, we run the for loop off it.
width = int(input("Width: "))
rows = []
for i in range(1, width+1):
rows.append(i)
rows += rows[-2::-1] # takes a reversed list and adds it on to the end: [1, 2, 3, 2, 1]
for i in rows:
print " " * (width-i) + "* " * i
i iterates through each of the numbers in the rows list, which looks something like [1, 2, 3, 2, 1]. Then we just need one printing gizmo.
In python, there's almost always a shorter and less comprehensible way of doing for loops, and in this case, we can get rid of two extra lines by shortening the first for loop:
width = int(input("Width: "))
rows = [ i for i in range(1, width+1)] # Brain-bending way of doing a for loop
rows += rows[-2::-1]
for i in rows:
print " " * (width-i) + "* " * i
And if you're feeling a bit crazy, here's a mere two line version of the whole thing!
width = int(input("Width: "))
print "\n".join([ " "*(width-i) + "* "*i for i in [ i for i in range(1, width+1) ]+[ i for i in range(1, width+1) ][-2::-1] ])
But I don't recommend this style of coding in general.
Sorry, I got a bit carried away at the end... but the best thing I can say to you now is try everything and play around!
Hope that helps. :)
Since some good methods have been addressed, here are some fun little hacky solutions.
Here's one using Python 2.7 string.center just for shits.
import string
width = int(raw_input("Width:"))
for i in range(width):
print string.center(i * " *", width * 2 )
for i in range(width,0,-1):
print string.center(i * " *", width * 2 )
And here's an outrageous one that ouputs using HTML to center.
file = open('file.html','w')
file.write("<div align='center'>")
for i in range(width):
file.write(i * " *")
file.write("<br>")
for i in range(width,0,-1):
file.write(i * " *")
file.write("<br>")
file.write("</div>")
file.close()
import webbrowser
webbrowser.open("file.html")
check it out (for python 2.7x) :
Filled ASCII Diamond :
width = 1
width += int(raw_input('Width : '))
for i in range (1,width):
for j in range (width,i,-1):
print " ",
for j in range (1,i,1):
print " * ",
print
for i in range (width,1,-1):
for j in range (width,i,-1):
print " ",
for j in range (1,i,1):
print " * ",
print
This works!! But not in any Browser window . . .

Draw inverted triangle of asterisk by using nested loops in 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 :)

Categories

Resources