How to Create Code in Ruby to Draw a Rectangle

By Christopher Haupt

In Ruby, you can create a rectangle on the screen using ASCII art. If you were going to draw a rectangle on paper that was filled in with a pattern, what would you need to do? First, you might draw the outline of the rectangle, and then you might color in the inside.

But for your program in Ruby, you’ll want to instead draw the shape from the top to the bottom, one line at a time. How would you describe how to do that? Like this:

  1. Draw the top of the rectangle using the outside (or edge) pattern for the first line.

  2. For each of the lines that make up the sides and inside of the rectangle, draw the left edge, all of the middle, and then the right edge.

    Repeat this step until you need to draw the bottom of the rectangle.

  3. Draw the bottom of the rectangle exactly as you drew the top edge.

This is an algorithm for drawing rectangles line by line from top to bottom.

An algorithm is just a sequence of steps you follow to accomplish some task or calculation. In this case, you’ve written out the sequence to draw a rectangle by scanning across from top to bottom, line by line.

The Ruby version of your algorithm reads a lot like the English version:

  1. Set up two variables that make it easier to see what’s going on. You’ll use the user’s choice for shape size as both the height and width of the figure you’re going to draw:

    height = shape_size
    width = shape_size
  2. You’ll be drawing the rectangle line by line, so set up a loop that will repeat your code for each row (so, that means you need your drawing code to run height times):

    1.upto(height) do |row|
    # Drawing code goes here
    end

    Loops are a powerful way to repeat code some number of times (or even an infinite number of times)! Ruby has several ways to program a loop. The upto method is an easy way to count from a starting number to a final number. For the rectangle, you want to count starting at 1 for the first row and finishing counting when you reach the number represented by height.

  3. Now, for the algorithm to work, you need to check to see what row you want the program to print. You have three cases: the first row, the middle rows, and the last row. Add in the case for the first row in the middle of your loop:

    if row == 1
        puts outside_letter * width
    end

    If the row variable is equal to one, the program will use puts to print your choice for the outside_letter a number of times equal to width.

    You use if statements when you want to see if some condition is true or false. The symbol == in Ruby asks the question: “Is the thing on the left side equal to the thing on the right side of the == symbol?” If it is, then Ruby will run the lines of code up until either another condition or an end keyword.

  4. Next, add in a check to see if this is the last row. The elsif keyword starts another condition test, and you place it right before the previous end keyword. That isn’t a spelling mistake, by the way. Ruby just has a funny way of saying “else if”! The whole thing will look like this:

    if row == 1
        puts outside_letter * width
    elsif row == height
        puts outside_letter * width
    end
  5. Finally, you need to handle the display of all the rows in the middle, so add one last condition using Ruby’s else keyword. This code goes right before the end keyword. Here’s the whole block of Ruby:

    if row == 1
      puts outside_letter * width
    elsif row == height
      puts outside_letter * width
    else
      middle = inside_letter * (width - 2)
      puts "#{outside_letter}#{middle}#{outside_letter}"
    end

    The middle case looks complicated. What’s it doing? Well, according to your algorithm, it needs to draw the left and right edges and everything in the middle.

    The middle variable is calculating the string that represents the center of the rectangle. If you take away one for the left edge character and one for the right edge character, the final width of the middle is the full width minus two characters.

    The final puts statement uses string processing to create the combined row.

  6. Run your program and see if you have any errors. Do you get something like what’s shown here? If you see an error that says something like comparison of Fixnum with String failed, this means Ruby had a hard time using the value inside shape_size as a number.

    Ruby isn't sure how to use strings for numbers.
    Ruby isn’t sure how to use strings for numbers.

    Why is that a problem if you typed in a number? Well, gets reads in your input, but it reads all the characters you type as a string. You have to help Ruby convert the string to a number.

  7. Change the two lines where you set the height and width variables to use the to_i method, which means convert this variable’s contents into an integer (number):

    height = shape_size.to_i
    width = shape_size.to_i

    Run your code again. Success!

    Is this the world's most exciting rectangle?
    Is this the world’s most exciting rectangle?