Plotting the First JavaScript Assignment

In this assignment, you'll use the plotly library to plot some simple functions.

Purpose

In this assignment, you'll show your command of these concepts and skills

  • defining a function
  • using arrays of numbers
  • using functions as arguments
  • returning functions
  • anonymous functions

Solution

To see the general organization of the solution, you are welcome to look at my solution

Note that that page will be empty. To use it, you will open up a JS console and run each of the following functions:

curve1();
curve2();
curve3();
curve4();
curve5();
curve1a();
curve2a();
curve3a();
curve2b();
curve3b();
strongList();
emList();

Note that I have "obfuscated" the code for number-functions.js and string-functions.js. That allows you to run my code and see what your code is supposed to do without seeing my solution code.

Do not reverse engineer my solution code. You are to write your own code. I will consider it a violation of the honor code to attempt to reverse engineer my code.

The Provided Functions

Take a moment to explore the code in provided.js. (Find it using the solution above.)

There is a function called newPlot that takes an array of x values and an array of y values and plots them, erasing any existing plot. A similar function called addPlot takes the same arguments and plots them, but doesn't erase any existing plots, so you can plot multiple curves at once.

There's also a function called addPlotFunction that takes an array of x values and a function, and it plots the function on those inputs. It adds the curve to any existing curves that are already plotted. The function argument should be a unary numeric function, taking a number as its sole argument and returning a number.

Finally, there is a function range that is similar to the Python function of the same name: it returns an array of numbers from zero to one less than the argument. Try this in the console.

Do not copy this code into your files. Just load my file into your html file, using the script tag that is already in the assign.htmlfile, below.

Reference Information

This assignment is mostly about defining functions and using the map method. It's also our first JS assignment, so make sure you remember some practical info A quick reminder:

  • put scripts at the bottom
  • use code in other files; don't copy it

You might also refresh your memory about:

To Do

Note that from now on, all your solutions will be in your cs204-assignments folder.

  1. make a working directory for this assignment in your cs204-assignments folder: plotting
  2. create an assign.html file in that folder; you can copy the HTML source code from my solution, above.
  3. create your own, empty, number-functions.js and string-functions.js files
  4. Implement the functions above, as described in the next sections

In step 2 above, you can copy my HTML file to get started:

cd ~/public_html/cs204-assignments/plotting/
cp ~cs204/pub/assignments/plotting/solution/assign.html assign.html

Number functions

You will implement a series of functions that will allow us to plot some curves. In no case is any of the functions very long, and you will never use a for loop.

Three numeric functions.

All of these functions take in a number as their sole argument and return a number. You can test these functions by comparing their output to my solution on the same inputs.

  • Implement a function name sqrt to return the square root of the input. You can use the Math.sqrt() function. This function is quite easy, so don't look for complexity here.
  • Implement a function named hill that computes -2(x-4)(x-16). That function is a quadratic with roots at 4 and 16.
  • Implement a function named wiggle that computes 10(x-1)(x-5)(x-9), which is a cubic with roots of 1, 5, and 9.

Five Plots

In this section, you'll implement functions that will plot some curves, including the ones above, using the newPlot function that we provide. That sentence has the word "function" in it a lot; don't get confused. None of these functions take any input; they plot the curve over a range that I will specify, and they return no value. You should use the provided range function to get an array of inputs, and you should use the .map() method to get the array of outputs. You can test them by running them and visually comparing them to the ones in my solution.

  • Implement a function curve1() that plots the sqrt function over the range 0-29.
  • Implement a function curve2() that plots the hill function over the range 0-20.
  • Implement a function curve3() that plots the wiggle function over the range 0-10.
  • Implement a function curve4() that plots the curve 5 cos(0.2x) over the range 0-99. You must use a function literal for the curve function.
  • Implement a function curve5() that plots the square of the previous curve over the same range.
    • Think of how you can make the coding for that function clear using additional functions.
    • Note that curve4 and curve5 should be independent functions that happen to use the 5 cos(0.2x) function. That means you may and should copy the code for the anonymous function literal from curve4 to curve5.

Three Curve Plots

The previous section had you write functions that used newPlot to show the curve, given two arrays. Now you'll use addPlotFunction that we supplied. That function takes two arguments: an array of input values, and a unary math numeric function. You will use it to create plots identical to several of the ones in the last section. In fact, you can check that they are the same by doing two plots. First, use newPlot to generate a plot just like last time, and then use addPlotFunction to superimpose the new curve. They should be identical. Again, you can test this by comparing to mine.

  • Implement a function curve1a() that plots the sqrt function on top of the curve1 plot.
  • Implement a function curve2a() that plots the hill function on top of the curve2 plot.
  • Implement a function curve3a() that plots the wiggle function on top of the curve3 plot.

Each of these should call their twin to do the first plot, and then use addPlotFunction to superimpose another identical curve on top of it.

Functions returning functions

Let's kick this up a notch in abstraction. The hill and wiggle functions are polynomials, defined by a constant factor and their two or three roots. In this section, you will define functions that return polynomials like hill and wiggle, defined as an anonymous function.

  • write a function quadratic that takes a constant factor and two roots and returns an anonymous function that computes that curve. In other words, quadratic(-2,4,16) should return an anonymous function that behaves the same as hill.
  • write a function curve2b() that invokes curve2a() and then uses addPlotFunction and quadratic to plot the hill function yet again, superimposing it on the first two.
  • write a function cubic that takes a constant factor and three roots and returns a function that computes that curve. In other words, cubic(10,1,5,9) should return an anonymous function that behaves the same as wiggle.
  • write a function curve3b() that invokes curve3a() and then uses addPlotFunction and cubic to superimpose another curve identical to the first two wiggle curves.

More information on quadratic

I said that quadratic(-2,4,16) should return a function that behaves the same as hill. Let's see what that means. Using the obfuscated solution, we can do the following in the JS console to test its behavior, namely, create an anonymous function and save it in a variable. Here, I've called it f. We can run f on the same inputs as hill to compare. They should be the same.

> f = quadratic(-2,4,16);
>f(0)
-128
> hill(0)
-128
> f(4)
0
> hill(4)
0

And so on. You can compare cubic to wiggle the same way.

Strings

We've done a lot with numbers and made some fun plots (multiple times!). Let's switch to operations on strings. You'll write the following functions in the string-functions.js file.

JavaScript used to have some (now deprecated) methods to wrap a string with a tag. For example, "foo".big() returns "<big>foo</big>". We will do some operations like that.

Write a function called wrapString(inString, tag) that returns a string wrapped in the given tag. For example, wrapString('foo','em') would return"<em>foo</em>"`

Now, let's kick that up a notch of abstraction.

  • Write a function makeWrapper(tag) that returns a one-argument anonymous function that wraps a string with the given tag.
  • Write a function wrapStrings that takes an array of strings and a tag (a string), and returns an array of strings where each is wrapped with the given tag. Your implementation will use the map() method and the makeWrapper function.

You can test those in the JavaScript console and compare them to my reference solution. We can also add those wrapped strings to the page. The setList() function that we provide takes an array of strings and adds each as an LI to an OL on the page.

  • Write a function wrapStringsTest that takes an array of strings and a tag, creates an array of wrapped strings, and then uses setList to add it to the page
  • Write a function strongList() which takes no arguments and uses wrapStringsTest to take a hard-coded list, ['apple','banana', 'chocolate'], wraps them all with the strong tag, and adds them to the page.
  • Write a nearly identical function emList() which wraps all the strings in the same list with em and adds them to the page.

That's it!

Documentation

Each function should be documented. Here's a checklist:

  • what the purpose or effect of the function is
  • parameters, their type and meaning
  • return value, its type and meaning
  • the function's side-effects, if any. "Side-effects" means what it does, rather than what it returns

In writing documentation, think about your audience: other programmers (or yourself) who want to use your function/method. So, it's important to describe how to use the function, rather than how it is implemented. (Implementation can be described with comments.)

I'm not going to be rigid about formatting, but JSDoc has some nice ideas for formating and comprehensiveness.

For most of these functions, the documentation will be very short, but it's important to get into the habit.

Final Checklist

  • author name at the top of each .js file
  • "use strict"; at the top of each .js file
  • sqrt, hill and wiggle
  • curve1 through curve5
  • curve1a, curve2a and curve3a
  • quadratic and cubic
  • curve2a and curve2b
  • wrapString, makeWrapper, wrapStrings, wrapStringsTest, strongList, emList
  • all functions documented
  • Submit a Gradescope item, so (1) I know you are done, (2) I have a consistent rubric, and (3) you can easily see feedback on your work.

How to turn this in

We will grade the code you have in your account. No need to drop a tar file.

Solution

Tutors can look at the sample solution

Time and Work

Finally, when you have completed the assignment, make sure you fill out the Time and Work report. That report is required.