Section #2: Grids, Strings, and Functions


Written by Juliette Woodrow, Anna Mistele, Elyse Cornwall, and Ashlee Kupor


If you'd like to code and test your solutions in PyCharm, download this starter project. We've included some Doctests for you to test your code with, but you should also add some of your own.

Practice with Grids

Grid Functions

Recall our introduction to grids at the end of Wednesday's lecture and some of the common functions we perform on grids:

          
grid = Grid(3, 2)     # creates a new 3 x 2 grid, with all spaces empty (i.e. None)
grid.width            # gets the width of the grid -> 3
grid.set(2, 0, 'a')   # changes location (2, 0) of the grid from None to 'a'
grid.set(2, 1, 'b')   # changes location (2, 1) of the grid from None to 'b'

grid.get(2, 0)        # returns what's at location (2, 0) -> 'a'
grid.in_bounds(2, 0)  # returns whether location (2, 0) is in bounds of the grid -> True
          
          

Below is a diagram of the grid we'd end up with after running the lines of code above.

Bubble Up

  1. can_bubble_up(grid, x, y)

    Suppose there is a grid where every square is either a bubble ('b)', rock ('r'), or empty (None). Implement a function, can_bubble_up(grid, x, y), that takes in a grid of any size and with any values inside of it, and integers x, y representing coordinates. x, y is guaranteed to be in bounds of grid.

    You must check if the location x, y in grid can be "bubbled up" to the square directly above it. A grid location can be bubbled up if:

    1. The square at that location is a bubble ('b'), and
    2. the location directly above it is in bounds and empty.

    Here is some nice art to help you visualize the problem.

    As a first step to the problem, walk through each cell of the grid and write down by hand (not using code) if it can be bubbled and why. This should help you determine the cases you will need to check in the code. Once you have completed this step, you can move on to coding the solution.

    Implement the function can_bubble_up(grid, x, y) so that it correctly returns True or False depending on which grid and coordinates are passed in.

  2. Analyzing Doctests

    Now that we've written some code, let's see if it works as expected. We can use Doctests to test our functions, and in this section we'll use them to confirm that when can_bubble_up(grid, x, y) is given specific inputs, it returns the expected output. As shown below, the syntax is three greater-than signs followed by a space and then the name of the function and the specific parameters you want to test. On the next line, you put the output you expect. To run a Doctest in PyCharm, right click on the greater than signs and hit Run 'Doctest name_of_function'.

  3. Here is an example of what Doctests for can_bubble_up(grid, x, y) might look like:

                
    def can_bubble_up(grid, x, y):
      """
      Implement this function as described in the handout.
      >>> grid = Grid.build([[None, 'r', 'b'], ['b', 'b', 'b']])  # creates a grid identical to the one above
      >>> can_bubble_up(grid, 0, 1)   # tests can_bubble_up for this grid at location (0, 1)
      True                            # states expected return value
      >>> can_bubble_up(grid, 0, 0)
      False
      >>> can_bubble_up(grid, 2, 1)
      False
      """
    
    

    Which square in the diagram above is each Doctest referring to? Why will can_bubble_up(grid, x, y) return True or False in each case?

  4. row_has_bubble_up(grid, y)

    Now implement a function, row_has_bubble_up(grid, y), which takes in a grid and an integer y identifying a row in the grid. This function should return True if at least one square in row y can be bubbled up and False otherwise. Hint: use the nice function you wrote in part 1 as a helper.

  5. Writing Doctests

    Now, it's your turn to write a Doctest for your function row_has_bubble_up(grid, y). Write one Doctest for the example grid.

    Here's another copy of the grid so you don't have to scroll up :)


Word Guess

Write a function, def guess_letter(in_progress_word, secret_word, guess): that helps us play wordguess. The function takes in 3 parameters:

  • in_progress_word: a string representing what letters we've guessed correctly, with unguessed letters denoted by "-"
  • secret_word: a string representing the word we are trying to guess
  • guess: a string representing the letter we are guessing this round
You may assume that the secret_word and guess will always be lowercase. The function should return a new string that represents our in_progress_word updated by the most recent guess. Make sure to build up that new string letter by letter, starting with an empty string.

As an example, if the word the user is trying to guess is 'python' and they have not guessed any letters so far,
in_progress_word = '------' and secret_word = 'python' . If the user guesses 'o', then guess_letter('------', 'python', 'o') would return '----o-'.

As another example, if the word the user is trying to guess is 'python' and they have already guessed 'o' and 't',
in_progress_word = '--t-o-' and secret_word = 'python' . If the user guesses 'p', then guess_letter('--t-o-', 'python', 'p') would return 'p-t-o-'.

Once you've got it implemented and the Doctests are passing, try running python3 word_guess.py in your terminal to play wordguess with your function! Windows users should use "py" instead of "python3".


Additional Problems

Exclaim (Strings)

Juliette loves to type text messages with lots of punctuation. She's very enthusiastic, so she'll often repeat the exclamation a bunch... Here's one of her recent text conversations:

            Juliette: "Did you see Amanda Gorman at the inauguration?!?!?!?!"
            "Yes, her poem was great. Did you like it?"
            Juliette: "It was wicked cool!!!"
            "Agreed! And she is only 22. What will you have accomplished by the age of 22?"
            Juliette: "......."
          

Juliette is getting tired of repeating the punctuation so much. Help her out by writing a Python function that does it for her! The function should accept a message, msg, the ending punctuation, end, and the number of times to repeat the punctuation, n. The function takes in a string msg, an int n, and a string end. The function definition looks as follows:
def exclaim(msg, end, n)
The function should return the resulting message to the terminal, so Juliette can copy it and paste it into her text messages. For example, calling exclaim('Did you see Amanda Gorman at the inauguration', '?!', 6) would return Did you see Amanda Gorman at the inauguration?!?!?!?!?!?! and calling exclaim('106A is awesome', '!', 5) would return '106A is awesome!!!!!'.

Once you've got it implemented and the Doctests are passing, try running python3 exclaim.py in your terminal to test your function! Windows users should use "py" instead of "python3".

Opening the Black Box (Function Calls)

These series of problems are for people who want to increase their familiarity with parameters and return statements. Implement the following functions and include at least one doc test per function:

  • def in_range(n, low, high), which takes in three integer parameters and returns True if n is between low and high (inclusive of both ends of the range) and False otherwise.
  • def is_even(n), which takes in one integer parameter and returns True if that integer is even, and False otherwise.
  • def longer_str(s1, s2), which takes in two strings and returns whichever string is longer. If they are the same, it can return either string.
  • def is_phone_number(s), which takes in a string and returns True if a string is a phone number, and False otherwise. We say a string is a phone number if it is made of only digits, and has 9 or 10 characters in the string.