Last Updated: 2017-11-05 Sun 20:21

CSCI 1103 Lab09: Equations Object-Oriented Objects

CODE DISTRIBUTION: lab09-code.zip

  • Download the code distribution every lab
  • See further setup instructions below

CHANGELOG:

1 Rationale

The primary purpose of object-oriented programming is define data types and operations on them that preserves the consistency of the data. This often means restricting access to the internal data of an object by making fields private. Values for internal data are retrieved via accessor methods ("getters") and changes to the data are made through mutator methods ("setters"). Mastering these principles is a primary focus of any education on modular, abstract programming.

This lab illustrates these concepts by creating a simple class and using accessor and mutator methods to interact with it.

Associated Reading

Material from Eck Ch 5 is covered in this lab.

2 Download Lab Code and Setup

As in Lab01, download the code pack linked at the top of the page. Unzip this which will create a folder and create your files in that folder.

File State Notes
PARTNERS.txt Edit Fill in your name and the name of your partner in this text file
TextIO.java Provided Allows easy input calls like TextIO.getInt()
KTests.java Testing Utility routines for all tests
junit-1103.jar Testing For testing, don't try to edit this one
SlopeInterceptLE.java Create Class to write for the lab
SlopeInterceptTests.java Testing Tests for equations

3 Overview

3.1 Background on Linear Equations

Throughout much of your Mathematics education, you've likely spent time using linear equations to represent the relationship between things and solved them as parts of larger problems. We like to solve problems with computers, so a good first step could be developing our own library of classes to represent these equations.

The primary motivation of the object-oriented programming paradigm is to guarantee that operations on data preserve internal invariants for that data. Most of us know that the radius and diameter of a circle have the relationship \(r = 2d\). If circles are represented using both radius and diameter, changing one must affect the other: a circle with radius 5 and diameter 322 badly violates our notion of what constitutes a proper circle. This is the essence of the object-oriented paradigm, to only allow access to manipulate an object via certain methods which will preserve the internal consistency of the object's state.

In this lab we will be representing linear equations with real number coefficients in a standard format. We need a representation that keeps track of the different variables and constants, and that also maintains the relationship between them as the variables are changed. We consider first the slope intercept form.

Should you need a math refresher, Wikipedia's Linear Equations article contains useful reminders of terminology and formulas.

3.2 Good old Em ex plus Bee

A linear equation is in slope intercept form if it is written \[ y = m x + b \] where \(m\) and \(b\) are constants that do not change while \(x\) and \(y\) are variables that do change. Importantly, if x changes, y must change to maintain the equality. It is frequent that objects should maintain relationships between their parts, sometimes called an invariant. The purpose of object-oriented programming is to control access to data so that such relationships can be maintained.

Completing this lab will create a class which models a linear equation in slope intercept form where any changes to the x or y variables will result in changes to the other variable.

4 SlopeInterceptLE Class

Write all your code int he SlopeInterceptLE.java file. Importantly, all of the fields of this class should have private access modifiers. This prevents changes to those variables by entities outside the class and allows the relationships between the variables to be preserved.

4.1 Sample Session

Examine the following session which shows how instances of the SlopeInterceptLE class behave. This session gives insight into which methods need to be in the class and how they affect the object.

Welcome to DrJava.
> SlopeInterceptLE si = new SlopeInterceptLE(1.0,2.0)        // first constructor, x defaults to 0.0
> si.toString()                                              // show pretty printing version                    
"y = 1.00 * x + 2.00"
> si                                                         // in DrJava don't need to invoke toString()
y = 1.00 * x + 2.00

> si.x                                                       // directly look at x??
Static Error: No field in SlopeInterceptLE has name 'x'      // fields are private
> si.getX()                                                  // ask for x with an accessor
0.0
> si.getY()                                                  // ask for y with an accessor
2.0
> si.value()                                                 // ask value on both sides of equation with accessor
2.0
> si.setX(4)                                                 // change for x with an accessor
> si.value()                                                 // value should have changed with x
6.0
> si.getY()                                                  // changes to x affect y
6.0

> SlopeIntercept2 si2 = new SlopeInterceptLE(0.25, 10.25, 1.0);  // second constructor takes inital x
> si2.getX()                                                 // check x, should be 1 from constructor
1.0
> si2.getY()                                                 // check y, should match be affected by y
10.5

> si2                                                        // si2 has its own distinct values
y = 0.25 * x + 10.25
> si                                                         // si has its own distinct values
y = 1.00 * x + 2.00

> si2.setY(4.5)                                              // change y value
> si2.getY()                                                 // check change
4.5
> si2.getX()                                                 // changes to y should alter x
-23.0
> si2
y = 0.25 * x + 10.25
> si2.value()                                                // changes to variables affect value
4.5

> si2 = new SlopeInterceptLE(-0.25, -10.25, -1.0);           // re-assign si2 to a new equation
> si2.toString()
y = -0.25 * x + -10.25
> si2 = new SlopeInterceptLE(0.67512, -1.999, -1.0);         // and again
> si2.toString()
y = 0.68 * x + -2.00

4.2 Class Structure of SlopeInterceptLE

Below is an overview of the fields and methods in the SlopeInterceptLE class. Each of these will need to be implemented to complete the lab.

public class SlopeInterceptLE {
// A class to model linear equations of two variable (x and y) in
// slope intercept form which is
//
//  m*x + b = y
//
// The coefficients m and b are set during the constructor and never
// change.  The variables x and y can be changed using public methods.
// Changes to x automatically update y and changes to y automatically
// update x. The "value" of this equation can change based changes to
// x and y but both left and right sides will always be equal.  No
// public fields should be present and all changes to the state of the
// object should happen via public methods.

  // FIELDS
  private double m;  // the slope of the linear equation, never changes
  private double b;  // the intercept of the linear equation, never changes
  private double x;  // the x (left side) variable which can change
  private double y;  // the y (right side) variable which can change

  // METHODS

  public SlopeInterceptLE(double m, double b);
  // Public constructor that accepts values for the slope m and
  // intercept b, defaults the value of x to 0.0 and sets y
  // appropriately.

  public SlopeInterceptLE(double m, double b, double x);
  // Public constructor that accepts values for the slope m and
  // intercept b and initial value of x and sets y appropriately.

  public double value();
  // Return the numeric value of the equation which is the numeric
  // quantity that should be on both left and right sides of the equal
  // sign.

  public double getX();
  // Return the current value of x

  public double getY();
  // Return the current value of y

  public void setX(double x);
  // Set the value of x and change y accordingly to preserve the
  // equation.

  public void setY(double y);
  // Set the value of $y$ and change $x$ accordingly to preserve the
  // equation.

  public String toString();
  // Return a =String= version of the general form of the equation.
  // The pretty version's general format should be as follows.
  // 
  //   y = M.MM * x + B.BB
  //
  // M.MM is the slope with 2 digits of accuracy and B.BB is the
  // intercept with two digits of accuracy.  Make use of
  // String.format() to assist with formatting the string.
  //
  // Examples:
  //    y = 1.23 * x + 122.41
  //    y = -1.23 * x + -122.41

}

4.3 Implementation Notes

Make sure that all fields are private as this prevents outside entities changing the x or y parts of the equation without affecting the other. Such changes should be done through the setX(val) / setY(val) methods which will change the other variable to maintain the equality of left and right hand sides.

During the first constructor

public SlopeInterceptLE(double m, double b)

set x to be 0.0 and calculate what y should be. The second constructor

public SlopeInterceptLE(double m, double b, double x)

is given an initial x which should be honored.

The toString() method is very common for classes in Java.

public String toString()

In this case, it should return a String version of the general form of the equation. This string's general format should be

y = M.MM * x + B.BB

where M.MM is replaced with the value of \(m\) with 2 decimal digits of accuracy and similarly for B.BB being replaced by \(b\). For example, if \(m = 1.23, b= 122.408\), the appropriate string to produce is

y = 1.23 * x + 122.41

If \(m = -1.23, b= -122.408\), the appropriate string to produce is

y = -1.23 * x + -122.41

This task is significantly easier if you examine the String.format() method and learn a few things about format strings for producing nice looking output. Format strings are used with System.out.printf() which is derived from the C language printf function. There are several places to learn about them.

5 Getting Credit for this Lab

5.1 Demonstrate your code to Lab Staff (40%)

You should feel free at any time to get help from lab staff as you get stuck on the exercises.

By the end of the lab, make sure to demonstrate your code to a staff member. This will ensure that you receive full credit on the lab. Staff might ask you to

  • Change what is printed
  • Compile and run on the command line
  • Run tests in DrJava or on the command line
  • Show how to zip the folder with your programs in it

Be ready to do any or all of these.

5.2 Zip and Submit (60%)

Ensure that file PARTNERS.txt has your name and the name of your partner in it. This fill is located with the other Java files for the lab and can be edited with DrJava.

Once your are confident your code is working, you are ready to submit. Ensure your folder has all of the required files. Create a zip archive of your lab folder and submit it to blackboard.

On Canvas:

  • Click on the Assignments section
  • Click on the appropriate link for this lab
  • Scroll down to "Attach a File"
  • Click "Browse My Computer"
  • Select you Zip file and press OK

Author: Chris Kauffman (kauffman@cs.gmu.edu)
Date: 2017-11-05 Sun 20:21