we will review just one of the drawing functions to give flavor of how the drawing is donesince our primary concern is with the implementation of the module here is the add_horizontal_line(functionsplit into two partsdef add_horizontal_line(rowcolumn column char="-")"""adds horizontal line to the grid using the given char add_horizontal_line( "="char_at( =char_at( ="=true add_horizontal_line( traceback (most recent call last)rowrangeerror ""the docstring has two testsone that is expected to work and another that is expected to raise an exception when dealing with exceptions in doctests the pattern is to specify the "tracebacklinesince that is always the same and tells the doctest module an exception is expectedthen to use an ellipsis to stand for the intervening lines (which vary)and ending with the exception line we expect to get the char_at(function is one of those provided by the moduleit returns the character at the given row and column position in the grid assert len(char= _char_assert_template format(chartryfor column in range(column column )_grid[row][columnchar except indexerrorif not <row <_max_rowsraise rowrangeerror(raise columnrangeerror(the code begins with the same character length check that is used in the resize(function rather than explicitly checking the row and column argumentsthe function works by assuming that the arguments are valid if an indexerror exception occurs because nonexistent row or column is accessedwe catch the exception and raise the appropriate module-specific exception in its place this style of programming is known colloquially as "it' easier to ask forgiveness than permission"and is generally considered more pythonic (good python programming stylethan "look before you leap"where checks are made in advance relying on exceptions to be raised rather than checking in advance is more efficient when exceptions are rare (assertions don' count as "look before you leapbecause they should never occur--and are often commented out--in deployed code