Lab 7: Benchmarking Continued

Overview

In this assignment, you incorporate feedback on your previous lab submission from your instructor (if available), and do more thorough benchmarking analysis.

Video introduction for the lab

Assignment

Create a Word document and provide Big-O analysis for the following operations:

Be sure to justify your reasoning.

Incorporate instructor feedback from the previous assignment, if available.

Then modify your program so that it:

By supporting named command line arguments, you can place the arguments in any order. Your program must use the following names:

When named command line arguments are supported, your program can be called as follows:

java -jar lab7username.jar --output=plots/containsLL.png --implementation=java.util.LinkedList --startSize=100 --operation=contains --numberOfSamples=7 --multiplier=5

but the program should now display the benchmarking results of the benchmark in a JavaFX Line Charts.

Generate a benchmark chart for each of the scenarios above, and save each graph as a .png image in a folder called plots in the project folder. The images should be named:

Study the following program that shows how to use named command line arguments, generate line charts, and save them to image files.

/*
 * Course: CSC1120A - 121
 * Spring 2024
 * Lab 7 - Benchmarking Continued
 * Name: Chris Taylor
 * Created: 2/23/2024
 */
package taylor;

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Alert;
import javafx.scene.image.WritableImage;
import javafx.stage.Stage;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.Map;

/**
 * Program that generates a line chart with a facial expression.<br />
 * Command line usage: <code>java FaceMaker --expression=Smile --output=face.png</code>
 *
 * @author taylor
 * @version 20240223
 */
public class FaceMaker extends Application {

    private static final double[][] SMILE = {
                    {2, 6}, {3, 4}, {4, 3}, {5, 3}, {6, 3}, {7, 4}, {8, 6}
    };
    private static final double[][] FROWN = {
            {2, 1}, {3, 2}, {4, 3}, {5, 3}, {6, 3}, {7, 2}, {8, 1}
    };
    private static final double[][] EXPRESSIONLESS = {
            {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {8, 3}
    };
    private static final double[][] LEFT_BROW = {
            {1, 15}, {3, 13}
    };
    private static final double[][] RIGHT_BROW = {
            {7, 13}, {9, 15}
    };
    private static final double[][] NOSE = {
            {4.5, 11}, {4.75, 7.5}, {5.125, 7}, {5.5, 7.5}
    };
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;

    /**
     * Sample program that demonstrates how to:<br />
     * <ul>
     *     <li>Access parameterized command line arguments</li>
     *     <li>Generate a line chart</li>
     *     <li>Save a screenshot of a JavaFX scene</li>
     * </ul>
     * @param stage The main stage for this program
     */
    @Override
    public void start(Stage stage) {
        final Map<String, String> params = getParameters().getNamed();
        final String expression = params.get("expression");
        final String filename = params.get("output");

        stage.setTitle("Face of the Graph");
        final LineChart<Number, Number> lineChart = makeLineChart(expression, "X Axis", "Y Axis");
        addLines(expression, lineChart);
        Scene scene = new Scene(lineChart, WIDTH, HEIGHT);
        lineChart.applyCss();
        lineChart.layout();
        stage.setScene(scene);
        stage.show();
        try {
            saveScreenShot(filename, scene);
        } catch (IOException e) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Error Saving Plot");
            alert.setContentText(e.getMessage());
            alert.show();
        }
    }

    /**
     * Creates a line chart
     * @param title The title for the chart
     * @param xAxisLabel The label for the X axis
     * @param yAxisLabel The label for the Y axis
     * @return a line chart with title and axes labelled
     */
    private static LineChart<Number, Number> makeLineChart(String title, String xAxisLabel,
                                                           String yAxisLabel) {
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        xAxis.setLabel(xAxisLabel);
        yAxis.setLabel(yAxisLabel);
        final LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis);
        lineChart.setAnimated(false);
        lineChart.setTitle(title);
        return lineChart;
    }

    /**
     * Create several lines and places them on the specified line chart
     * @param expression the type of facial expression to generated
     * @param lineChart the line chart on which to place the lines
     */
    private static void addLines(String expression, LineChart<Number, Number> lineChart) {
        final double[][] lipCoordinates = (expression == null) ? EXPRESSIONLESS
                : switch (expression) {
            case "Smile" -> SMILE;
            case "Frown" -> FROWN;
            default -> EXPRESSIONLESS;
        };
        lineChart.getData().add(makeLine("Lips", lipCoordinates));
        lineChart.getData().add(makeLine("Left Brow", LEFT_BROW));
        lineChart.getData().add(makeLine("Right Brow", RIGHT_BROW));
        lineChart.getData().add(makeLine("Nose", NOSE));
    }

    /**
     * Creates a series that represents a single line on to be added to a line chart.
     * @param label the label associated with the line being generated
     * @param values the coordinates of the line represented by the series
     * @return a series that represents a single line on to be added to a line chart
     */
    private static XYChart.Series<Number, Number> makeLine(String label, double[][] values) {
        XYChart.Series<Number, Number> series = new XYChart.Series<>();
        final int x = 0;
        final int y = 1;
        for (double[] value : values) {
            series.getData().add(new XYChart.Data<>(value[x], value[y]));
        }
        series.setName(label);
        return series;
    }

    /**
     * Saves a screenshot of the specified scene
     * @param filename name of the file for the image to be saved
     * @param scene the scene to be captured and saved
     * @throws IOException if an error is encountered while writing the file
     */
    private static void saveScreenShot(String filename, Scene scene) throws IOException {
        WritableImage image = scene.snapshot(null);
        File file = new File(filename == null ? "face.png" : filename);
        ImageIO.write(SwingFXUtils.fromFXImage(image, null), "PNG", file);
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Add these charts to your Word document. Discuss how your Big-O analysis compares with the benchmarking results.

Acknowledgement

This laboratory assignment, developed by Dr. Chris Taylor.

See your professor's instructions for details on submission guidelines and due dates.