Homework 2: Plotting Example Data
In this step, you will use a Turtle object to plot a small data set.
The resulting plot will be added to a rectangular patch by using your rect function from the previous step.
Implementation Steps
Setup and Reading Input Data
You’ll be writing the code for this part in the function plotExampleData().
Constant Definitions
Your function should start by declaring the constants from the previous part as well as the following:
constexpr int PLOT_STEP = 1;
constexpr int NUM_DATA_POINTS = 59;
const string INPUT_NAME = "/home/student/data/hw2/us_population_growth.txt";
const string OUTPUT_NAME = "example_data.dst";
If we have the same constants in two functions, isn't that duplicated code and bad style?
In principle, we can change the values of these constants to be different in the different functions. If, when you're done, you have a constant that is the same everywhere, you can make just one global constant outside of all the functions if you like. But mostly don't worry about it, as the benefit of named constants outweighs the duplication.
Hay! Why are the integer constants
constexprbut the strings are justconst? What's up with that?
Full-blown C++
std::stringobjects are complicated things, and creating one is something that can only be done when the program actually runs. Because it can't be figured out by the compiler ahead of time, it can't be a compile-time constant.
There are alternatives to
std::stringthat can be figured out at compile time, but we won't go down the rabbit hole of exploring them.
Declaring the Array
Then create a statically-sized array of floats that is big enough to hold NUM_DATA_POINTS values.
Reading the Values into the Array
We want to read NUM_DATA_POINTS values from the file INPUT_NAME into your array of floats.
The data set you will plot in this part of the assignment is a text file with one floating point value per line. The values represent 59 years of US population growth.
To read values from the text file, you will need to create an ifstream (short for input file stream) object. You can use the parameterized constructor for the ifstream class that takes one argument: a string representing the name of the file to read from. The syntax is
ifstream inputFile{"mytextfile.txt"};
Of course you should replace inputFile and "mytextfile.txt" with the variable name you prefer and the name of the file you want to read, respectively. Once you have your ifstream object, the >> operator will read one value at a time from the file. For example, if we have a float called myFloat, the following line would read the first float from the file and store it in myFloat:
inputFile >> myFloat;
Once you have read all of the values from the file, you should call the close member function of your ifstream object to let the system know that you are done reading from the file.
Normalizing by the Largest Value
When you plot the data, you’ll want it to be appropriately scaled when visualized in your patch. To accomplish this, you’ll normalize the data by its largest value. You’ll also be excluding the rectangular border for the patch from the available visualization space.
Find the Largest Value
You should implement a loop-based approach to finding the largest float in your array.
Generate Normalized Data
Since the height of your patch is fixed, we want to make sure that all of the data points we plot will fit on the patch. To do that, we will normalize all of the values so that they fall between 0 and the largest available y-axis value.
- First, calculate the
availableHeighton the patch: thePATCH_HEIGHTminus the size of the edge stitching,EDGE_STEP. - Create a new statically sized array of
floats to store the normalized data values. - Then scale each float in your array of data values so that it falls between
0andavailableHeight.
Plotting the Points
Now you’ll use the Turtle to draw a border for the plot and plot the data.
Draw the Border
Create a Turtle object and draw a satin-stitched rectangle that is PATCH_WIDTH wide, PATCH_HEIGHT tall, and has a step size of EDGE_STEP. Be sure to use your rect function!
Plot the Line
Next you’ll generate a line plot with the values from the normalized array of floats. To plot the data:
- First, calculate how much width is available for each data point, and store that number in a variable. You will use that value to calculate the
xposition for each point in your plot. The total available width for all the points isPATCH_WIDTH - EDGE_STEP. - Get ready to plot: Lift the pen (so you can jump to the first plot point) and set the
Turtle’s step size toPLOT_STEP; satin stitch should still be on. - Loop through the values in your normalized array of floats. For each, have the turtle
gotopoint(x, y)wherexis calculated from the available width for each point andycomes from the array of scaled floats. You’ll likely want the points to start at a slight offset to the right so as not to overlap the rectangle border. It may take some trial and error to get the line plot roughly centered inside the rectangle.
Note: Be sure that after the Turtle goes to the location of the first data point, the pen is down. Otherwise, you won’t see any of the points you plot! Also, these directions assume the Turtle’s position at the end of rect() is the bottom left corner of the rectangle.
Annotate the Plot
We can add labels to interesting points in our plots. For this step, label the peak in the middle of the plot with the year it corresponds to, 1992, by using gotopoint() and choosing a point to write the text. Aim to have the beginning of the first 9 of 1992 aligned vertically with the middle peak; again, you'll have to do some experimentation. You can view our example patch below in the next step.
Save the Plot to a File
Save the resulting embroidery pattern to example_data.dst. Then convert the pattern to example_data.svg and confirm that it looks right. When you are done, your patch should look something like

Helpful Hints
What were those tips that were on the previous page? I think they still apply!
Don't Forget to Recompile (and Re-convert!)
Remember that every time you change embroidery.cpp, you need to recompile it, relink it, run ./homework2 again and regenerate the .svg file with convert before you can see the results. (If you fix a bug in the code and the output image doesn’t change, you probably forgot one of these steps.)
Pay Attention to Warnings (from clang++ and cpplint)
We recommend that you fix compiler warnings immediately, rather than waiting until the end. Even if most warnings are about issues that don’t cause trouble in practice, sometimes warnings reflect very serious errors in your code!
Similarly, cpplint is pretty picky about how you write your code, so your life will be better if you occasionally run it and correct the formatting as you go, rather than waiting until the end to fix dozens (or for larger programs, hundreds) of small annoying errors.
Visual Studio Code Is Sometimes Clueless
When working on C++ code, sometimes your editor, like VS Code, will try to “help” you. For this assignment, it may complain to you that it does not find turtle-related libraries on your system. This is OK, since VS Code does not really know what is inside of our special CS70 Docker image. When you compile inside of Docker, it will definitely be able to find them.
Want to Look at the Provided Data?
The data is located in the Docker image in /home/student/data/hw2/. If you want to take a look at it to make sure you are correctly reading data, you can use the cat command (short for ‘concatenate’). This command concatenates the contents of all the files specified in its arguments and dumps the result to the terminal. So, on the Docker command line you can try cat /home/student/data/hw2/us_population_growth.txt
Other Useful Unix Commands
Some other useful Unix commands, similar to cat, for looking at files on the command line are
head— view the first few lines of a filetail— view the last few lines of a filemore— view a file pausing at each screenful
Feel free to try them out to see what they do; for example, run
head /home/student/data/hw2/us_population_growth.txt
tail /home/student/data/hw2/us_population_growth.txt
more /home/student/data/hw2/us_population_growth.txt
Another very useful command is man, which displays a “manual page” for the command you specify. So, for example, man man would show you the manpage for man itself, and man more shows you the manpage for more. Manpages show you what options and arguments a command takes, what they do, and sometimes include examples of how to use the command.
(When logged in, completion status appears here.)