Problem 4.5
Square Grid
Build a hollow square as a 2D list, then print it.
Background
This is the same picture you drew in Square: a
hollow square of hash (#) characters. This time, your program stores
the square in memory first, as a list of rows, and only then prints it
from that list.
Games, images, and spreadsheets all store data this way: rows of columns. Once you can build a grid and read it back, you can do the same with a game board or a tiny picture.
This shows what your program’s output should look like for any size; it doesn’t validate input the way your program needs to.
Learning Objectives
- 2D lists (lists of lists)
- Indexing with
grid[row][col] - Nested loops with
range() - Building lists with
append() - Docstrings and doctests
- A function that returns a value
Specification
Implement a program, square_grid.py, that builds a hollow square of
hash characters as a 2D list, then prints it.
- Prompt the user to enter a square size.
- Validate that the size is an integer between 2 and 8, inclusive. If the user enters something that isn’t an integer, or an integer outside that range, don’t print an error message: just prompt again.
- Implement
build_grid(size), which returns a 2D list: a list ofsizerows, where each row is a list ofsizeone-character strings. Hash (#) goes along the top row, the bottom row, the first column, and the last column, with a space everywhere else in between. Build each row by starting from an empty list and callingappend, and build the grid the same way. - Implement
print_grid(grid), which prints the grid one row per line. Printing a row list directly would show brackets and quotes, so you’ll need to turn each row back into a string first. - Have
main()get a valid size (withget_size(), or an equivalent of your own), callbuild_grid, then callprint_grid.
For example, a size of 3 should print:
###
# #
###
And a size of 4 should print:
####
# #
# #
####
Behind the scenes, build_grid(3) should return this list of three
rows, which print_grid then prints one row at a time:
[['#', '#', '#'], ['#', ' ', '#'], ['#', '#', '#']]
To Get Full Credit
It’s more important that you submit a working solution than that you do everything below. Submit early, then keep improving and resubmit as many times as you like.
build_gridandprint_gridboth exist, and each has a docstring.build_grid’s doctests pass. Check them by runningpython -m doctest square_grid.py -vfrom inside yoursquare_gridfolder; the doctests are already in the starter code below.- At the end of the program, add a comment describing any challenges you ran into or what you’d improve if you did this again. A sentence or two is fine.
Usage
Your program should behave like the demo below.
$ python square_grid.py Size: 0 Size: -1 Size: 9 Size: 2 ## ## $ python square_grid.py Size: 4 #### # # # # ####
Bonus
For extra credit, implement stretch(grid), which returns a taller
version of the square. Use the list method insert() to add a copy of
a middle row, such as grid[1]. Add a doctest of your own to
stretch that shows the number of rows went up. Inserting grid[1]
without copying it first puts the same row in the grid twice, which is
the aliasing bug from the note above.
Then, if you run your program with the single command-line argument
stretch, print the stretched grid instead of the original.
$ python square_grid.py stretch
Size: 3
###
# #
# #
###
Your program should still work fine with zero arguments; check50 needs that to still pass.
Getting Started
Log into cs50.dev, click on your terminal window, and run:
cd
mkdir square_grid
cd square_grid
code square_grid.py
That creates a new folder called square_grid, moves into it, and
opens a new, empty file called square_grid.py for you to edit.
Starter Code
Paste this into square_grid.py to start from. get_size,
build_grid, and print_grid are stubbed out with pass, and
build_grid comes with two >>> doctest examples; run
python -m doctest square_grid.py -v from inside your square_grid
folder to check them. They’ll fail until you replace pass with real
code. With -v, doctest lists every example it ran and ends with a
summary of how many passed.
The last two lines make main() run when you run
python square_grid.py, but not when doctest loads your file to test
it. Leave them at the bottom.
# Student Initials:
"""
Square Grid
Slug: porttack/cs50/problems/py/squaregrid
Doctests: python -m doctest square_grid.py -v
"""
def main():
# Get a valid size, build the grid, then print it, in that order.
pass
def get_size():
"""Prompt until the user enters an integer from 2 to 8, then return it."""
pass
def build_grid(size):
"""
Return a size-by-size 2D list for a hollow square: '#' along the
border and ' ' everywhere else.
>>> build_grid(2)
[['#', '#'], ['#', '#']]
>>> build_grid(3)[1]
['#', ' ', '#']
"""
pass
def print_grid(grid):
"""Print grid, one row per line."""
pass
if __name__ == "__main__":
main()
Style and Submission
Run these one at a time, from inside your square_grid folder.
Check your style:
style50 square_grid.py
Check your correctness:
check50 porttack/cs50/problems/py/squaregrid
Submit your work:
submit50 porttack/cs50/problems/py/squaregrid
Glossary
- loop: A statement that runs one or more statements, often repeatedly. (AP calls this iteration.)
- conditional statement: A statement that controls the flow of execution depending on some condition. Informally, this is usually an if statement, which might include an elif and an else. (AP calls this selection.)
- boolean expression: An expression whose value is either True or False.
- 2D list: A list whose elements are lists; often thought of as rows and columns.
- index: The position of an element in a list, starting at 0 in Python.
- alias: Two names (or two list slots) that refer to the same object.
Version history
- Loading commit history…