In our lab we will use Turtle to draw images. But that kind of graphical output can be awkward in programs that are designed to be automated and thus have text-based interfaces (like a lot of scientific software). In those contexts, we can use text for visualization (often termed ASCII art). Today we will use loops to generate some text-based visualizations (Adapted from “CS for All”), including of a Sine wave!
As a starting point, let’s write functions to print a rectangle and a “lower” right triangle. For
print_rect, the parameters will be the
height and the character and for
print_triangle, the parameters will be the
size (width and height) and the character.
>>> print_rect(4, 6, "%") % % % % % % % % % % % % % % % % % % % % % % % %
>>> print_triangle(3, "@") @ @ @ @ @ @
One restriction is that you are not allowed you to use the string multiplication operator (the goal is to practice using loops). As a hint, the
end argument (we will learn more about these default arguments later in the semester). For example, notice the different output from these two code snippets (the semicolon just allows us to have multiple Python statements on one line).
>>> print("%", end = " "); print("%", end = " "); % % >>> print("%"); print("%"); % %
Recall our discussion of syntax vs. semantics. Before we write any code let’s figure out the semantic tools we will use. Some questions for us to answer:
Try implementing both functions before peeking at the code.
def print_rect(width, height, char): """Print an ASCII rectangle Args: width, height: Width in characters, height in rows of rectangle char: Character to print """ for i in range(height): for j in range(width): print(char, end=" ") print() # Go to a new line at end of the row def print_triangle(size, char): """Print an ASCII lower triangle Args: size: Height in rows and with in characters of triangle char: Character to print """ for i in range(size): for j in range(i+1): print(char, end=" ") print()
Imagine you want to plot a sine wave using a similar text rendering, where the rows are the angle and width is the amplitude. That is we want to implement the following, where the parameters are the height, the width, the character and the degrees-per-row.
>>> print_sin(10, 10, "*", 45) * * * * * * * * * *
Again before we start, what semantic tools will we need? Loops (like before) and a way to calculate Sine. Not surprisingly Python has a built-in sin function. Is the input for that function degrees or radians (or both)? And would we find that out? If it is radians, how could we convert from degrees to radians?
We always want to work incrementally (testing as a we go). How could we decompose this large problem into a set of smaller steps? Show a potential set of steps…
math.sinwill produce a
floatin the range [-1,1], but we need an integer number of columns in the approximate range [0,
Now lets work through those steps to implement
print_sin. Show a possible solution…
def print_sin(width, height, char, degrees_per_row): """Print a sine wave (with angle on the vertical) Args: width: Maximum approximate width in characters height: Height in rows char: Character to print sine value degrees_per_row: Increment in angle for each row """ degrees = 0 for i in range(height): amplitude = math.sin(math.radians(degrees)) # Map [-1,1] to width current_width = amplitude * (width / 2) + (width / 2) for j in range(int(current_width)): print(" ", end=" ") print(char) degrees += degrees_per_row # The same as degrees = degrees + degrees_per_row