CISC 3115
Modern Programming Techniques
Lecture 1
Prep


Overview

We introduce the notion of a class. The basic idea is to bundle together state (i.e., variables) and behavior (methods) into a logical entity that presents or models specific logical behavior. Our initial fundamental change will be to take the principal values of our proposed object and place them at the class level rather than as local variables; in effect making them available to all the methods in the class (assuming we remove the static keyword from their header — see below). Most of the other changes are then a consequence of this change.

Modelling 'Things': A Bank Account (01-BankAccount)

First Implementation (01-BankAccount/01-baseline)

class BankAccount {
	public void deposit(int amount) {balance += amount;}
	public void withdraw(int amount) {balance -= amount;}

	public String toString() {return "$" + balance;}

	private int balance = 0;

	public static void main(String [] args) {
		BankAccount bankAccount = new BankAccount();
		System.out.println("After creation: " + bankAccount);
		bankAccount.deposit(200);
		System.out.println("After deposit of $200: " + bankAccount);
		bankAccount.withdraw(50);
		System.out.println("After withdrawal of $50: " + bankAccount);
		bankAccount.withdraw(70);
		System.out.println("After withdrawal of $70: " + bankAccount);
	}	
}

Notes

A Second Implementation — File Input (01-BankAccount/02-from-input)


class BankAccount {
	public void deposit(int amount) {balance += amount;}
	public void withdraw(int amount) {balance -= amount;}

	public String toString() {return "$" + balance;}

	private int balance = 0;
}

import java.io.File;
import java.util.Scanner;

class BankAccountApp {
	public static void main(String [] args) throws Exception {
		Scanner scanner = new Scanner(new File("bank_actions.text"));

		BankAccount bankAccount = new BankAccount();

		while (scanner.hasNext()) {
			String action = scanner.next();
			int amount = scanner.nextInt();

			if (action.equals("D")) {
				bankAccount.deposit(amount);
				System.out.println("Balance after deposit of $" + amount + ": " + bankAccount);
			}
			else if (action.equals("W")) {
				bankAccount.withdraw(amount);
				System.out.println("Balance after withdrawal of $" + amount + ": " + bankAccount);
			}
		}
	}	
}

Notes

A Third Implementation — No Overdraft Withdrawals (01-BankAccount/03-no-overdraft)

class BankAccount {
	public int deposit(int amount) {balance += amount;}
	public int withdraw(int amount) {if (balance >= amount) balance -= amount;}

	private int balance = 0;
}

Notes

Summary

Some Things to Think About

Modelling Things with Several (Logically-Related) Elements: A Container (02-Container)

Write an app that reads values from a file and places them into a container, i.e., a data entity that contains other items of data. The methods to be provided are:

class Container {
	public int add(int value) {
		values[size] = value;
		size++;
		return size;
	}

	public int size() {return size;}

	public boolean isEmpty() {return size() == 0;}

	public int find(int value) {
		for (int i = 0; i < size; i++)
			if (values[i] == value) return i;
		return -1;
	}

	public int get(int index) {return values[index];}

	public String toString() {
		String result = "{";
		for (int i = 0; i < size; i++)
			result += values[i] + (i < size-1 ? ", " : "");
		return result + "}";
	}
	
	private static final int CAPACITY = 100;
	private int [] values = new int[CAPACITY];
	private int size = 0;
}

Notes

import java.io.File;
import java.util.Scanner;

class ContainerApp {
	public static void main(String [] args) throws Exception {
		Scanner scanner = new Scanner(new File("container_actions.text"));

		Container container = new Container();

		while (scanner.hasNext()) {
			String action = scanner.next();
			int value;
			int index;

			switch (action) {
				case "A":
					value = scanner.nextInt();
					container.add(value); 
					System.out.print("After adding " + value + ": " + container);
					break;

				case "F":
					value = scanner.nextInt();
					int pos = container.find(value);
					if (pos >= 0) 
						System.out.println(value + " is at position " + pos + " of the container");
					else
						System.out.println(value + " is not in the container");
					break;

				case "G":
					index = scanner.nextInt();
					value = container.get(index);
					System.out.println("The value at location " + index + " is " + value);
					break;

				default:
					System.out.println("*** Error *** unknown action: " + action);
			}
		}
	}	
}

Modelling Related and Hierarchical Things: Points, Lines & Line Pairs (03 Points, Lines, Line Pairs)

Points (Points)

Model a point in 2-dimensional space (i.e., the 2D plane). A point is represented as a pair of values (we'll stick with integers … at least for now) representing the x and y components of the point.

We will support the methods:

public class Point {
	Point(int x, int y) {
		this.x = x;
		this.y = x;
	}

	public String quadrantStr() {
		switch (quadrant()) {
			case 0: return "Origin";
			case 1: return "Quadrant 1"; 
			case 2: return "Quadrant 2";
			case 3: return "Quadrant 3"; 
			case 4: return "Quadrant 4"; 
			case 5: return "Positive x axis"; 
			case 6: return "Positive y axis"; 
			case 7: return "Negative x axis"; 
			case 8: return "Negative y axis"; 
			default: return "???";
		}
	}
			
	public int quadrant() {
		if (x == 0 && y == 0) return 0;
		if (x > 0 && y > 0) return 1;
		if (x < 0 && y > 0) return 2;
		if (x < 0 && y < 0) return 3;
		if (x > 0 && y < 0) return 4;
		if (x > 0 && y == 0) return 5;
		if (x == 0 && y > 0) return 6;
		if (x < 0 && y == 0) return 7;
		if (x == 0 && y < 0) return 8;
		return -1;
	}

	public String toString() {return "(" + x + ", " + y + ")";}

	private int x, y;
	public static final Point ORIGIN = new Point(0, 0); 
}

Notes

import java.io.*;
import java.util.*;

public class PointApp {
	public static void main(String [] args) throws Exception {
		Scanner scanner = new Scanner(new File("points.data"));

		System.out.println(" --- From the file");
		System.out.println();

		while (scanner.hasNextInt()) {
			int 
				x = scanner.nextInt(),
				y = scanner.nextInt();
			doIt(x, y);
		}

		Random r = new Random(12345);

		System.out.println();
		System.out.println(" --- Some random points between 0 and 9");
		System.out.println();

		for (int i = 1; i <= 20; i++) {
			int 
				x = r.nextInt(19)-9,
				y = r.nextInt(19)-9;
			doIt(x, y);
		}
	}


	public static void doIt(int x, int y) throws Exception{
		System.out.println(x + " " + y);

		Point p =  new Point(x, y);
		System.out.println("p: " + p);

		System.out.println("Quadrant: " + p.quadrantStr() + " (" + p.quadrant() + ")");
	}
}

More on Constructors

The Names of the Constructor Parameters
Overloaded Constructors
Leveraged Constructors
Default Constructor
Copy Constructor

Lines (Lines)

Model a line in 2-dimensional space (i.e., the 2D plane). A line is represented as two pair of values (i.e., points)

We will support the methods:

public class Line {
	Line(Point endPoint1, Point endPoint2) {
		this.endPoint1 = endPoint1;
		this.endPoint2 = endPoint2;
	}

	Line(int x1, int y1, int x2, int y2) {this(new Point(x1, y1), new Point(x2,  y2));}

	public double length() {return Math.sqrt((Math.pow(endPoint1.getX() - endPoint2.getX(), 2) + Math.pow(endPoint1.getY() - endPoint2.getY(), 2)));}
	public boolean isVertical() {return endPoint1.getX() == endPoint2.getX();}
	public double slope() {return (endPoint1.getY() - endPoint2.getY()) / (double)(endPoint2.getX() - endPoint1.getX());}

	public String toString() {return endPoint1 + " - " + endPoint2;}

	private Point endPoint1, endPoint2;
}

Notes

public class Point {

	…

	public int getX() {return x;}
	public int getY() {return y;}

	…

	private int x, y;
}

import java.io.*;
import java.util.*;

public class LineApp {
	public static void main(String [] args) throws Exception {
		Scanner scanner = new Scanner(new File("lines.data"));

		while (scanner.hasNextInt()) {
			int 
				x1 = scanner.nextInt(),
				y1 = scanner.nextInt(),
				x2 = scanner.nextInt(),
				y2 = scanner.nextInt();
			doIt(x1, y1, x2, y2);
		}
		
		Random r = new Random(12345);

		System.out.println();
		System.out.println(" --- Some random points between 0 and 9");
		System.out.println();

		for (int i = 1; i <= 20; i++) {
			int 
				x1 = r.nextInt(19)-9,
				y1 = r.nextInt(19)-9,
				x2 = r.nextInt(19)-9,
				y2 = r.nextInt(19)-9;
			doIt(x1, y1, x2, y2);
		}
	}

	public static void doIt(int x1, int y1, int x2, int y2) throws Exception {
		System.out.println(x1 + ", " + y1 + ", " + x2 + ", " + y2);

		Point p1 = new Point(x1, y1);
		Point p2 = new Point(x2, y2);
		Line line = new Line(p1, p2);

		System.out.println("p1: " + p1 + " p2: " + p2);
		System.out.println("line: " + line);

		printQuadrantInfo(p1);
		printQuadrantInfo(p2);

		System.out.println("The length of the line is: " + line.length());
		if (line.isVertical())
			System.out.println("Vertical line, no slope");
		else
			System.out.println("The slope of the line is: " + line.slope());
		System.out.println();
	}

	public static void printQuadrantInfo(Point p) {
		System.out.println(p + " Quadrant: " + p.quadrantStr() + " (" + p.quadrant() + ")");
	}
}

Notes

Line Pairs(Line Pair)

Model a pair of lines in 2-dimensional space (i.e., the 2D plane). A pair of lines line is represented as four pair of values (i.e., two lines of two endpoints)

We will support the methods:

public class LinePair {
	LinePair(Line l1, Line l2) {
		line1 = l1;
		line2 = l2;
	}

	public boolean isParallel() {return line1.slope() == line2.slope();}
	public boolean isPerpendicular() {return line1.slope() == -1/line2.slope();}

	public String toString() {return "line1: " + line1 + "/" + "line2: " + line2;}

	Line line1, line2;
}

Notes

import java.io.*;
import java.util.*;

public class LinePairApp {
	public static void main(String [] args) throws Exception {
		Scanner scanner = new Scanner(new File("line_pairs.data"));

		while (scanner.hasNextInt()) {
			int 
				x11 = scanner.nextInt(),
				y11 = scanner.nextInt(),
				x12 = scanner.nextInt(),
				y12 = scanner.nextInt(),
		
				x21 = scanner.nextInt(),
				y21 = scanner.nextInt(),
				x22 = scanner.nextInt(),
				y22 = scanner.nextInt();
			doIt(x11, y11, x12, y12, x21, y21, x22, y22);
		}
	}
	
	public static void doIt(int x11, int y11, int x12, int y12, int x21, int y21, int x22, int y22) throws Exception {
		System.out.println("x11: " + x11 + " y11: " + y11 + " x12: " + x12 + " y12: " + y12 + " / " + 
						" x21: " + x21 + " y21: " + y21 +  "x22: " + x22 + " y22: " + y22);

		Point p1 = new Point(x11, y11);
		Point p2 = new Point(x12, y12);
		Line line1 = new Line(p1, p2);
		Point p3 = new Point(x21, y21);
		Point p4 = new Point(x22, y22);
		Line line2 = new Line(p2, p2);
		LinePair linePair = new LinePair(line1, line2);

		System.out.println("linr pair: " + linePair);

		printQuadrantInfo(p1);
		printQuadrantInfo(p2);
		printQuadrantInfo(p3);
		printQuadrantInfo(p4);

		System.out.println("The length of the first line is: " + line1.length());
		System.out.println("The length of the second line is: " + line2.length());
		double m1 = line1.slope();
		double m2 =  line2.slope();
		System.out.println("The slope of the first line is: " + m1);
		System.out.println("The slope of the second line is: " + m2);

		if (linePair.isParallel()) System.out.println("The two lines are parallel");
		else if (linePair.isPerpendicular()) System.out.println("The two lines are perpendicular");
		System.out.println();
	}

	public static void printQuadrantInfo(Point p) {
		System.out.println(p + ") Quadrant: " + p.quadrantStr() + " (" + p.quadrant() + ")");
	}
}

Notes

Modelling Many Thing with Many Elements: Phonebook (Phonebook)

Given the file, "phonebook.text" containing phone entries in the format last-name phone-number, write an application that allows the user to look up a phone number via the last name. You can assume no two entries have the same last name.

An Overview

This example goes a step further than the previous ones in that there are two 'multiple's here: the multiple attributes of the entries of the phone book (name and number), and multiple entries forming the phonebook. What follows is a standard way of structuring and implementing such a situation. The will be three classes:

PhonebookEntry

class PhonebookEntry {
	PhonebookEntry(String name, String number) {
		this.name = name;
		this.number = number;
	}

	String getName() {return name;}
	String getNumber() {return number;}

	public String toString() {return name + ": " + number;}

	String name;
	String number;
}

Notes

Phonebook

import java.io.*;
import java.util.*;

public class Phonebook {
	public void read(String filename) throws IOException {
		Scanner scanner = new Scanner(new File(filename));

		while (scanner.hasNext()) {
			if (size == CAPACITY) {
				System.out.println("Phonebook capacity exceeded - increase size of underlying array");
				System.exit(1);
			}
			String name = scanner.next();
			String number = scanner.next();
			PhonebookEntry entry = new PhonebookEntry(name, number);
			entries[size] = entry;
			size++;
		}
	}

	public String lookup(String name) {
		for (int i = 0; i < size; i++)
			if (entries[i].getName().equals(name)) return entries[i].getNumber();
		return null;
	}

	public String toString() {
		String result = "{";
			for (int < = 0; i  size; i++)
			result += entries[i] + (i < size-1 ? ", " : "");
		result += "}";
		return result;
	}
	

	private static final int CAPACITY = 100;
	private PhonebookEntry [] entries = new PhonebookEntry[CAPACITY];
	private int size = 0;
}

Notes

PhonebookEntry

import java.io.*;
import java.util.*;

public class PhonebookApp {
	public static void main(String [] args) throws Exception {
		final String FILENAME = "phonebook.text";

		Phonebook phonebook = new Phonebook();

		phonebook.read(FILENAME);
		
		System.out.println(phonebook);

		Scanner scanner = new Scanner(System.in);

		System.out.print("name? ");
		while (scanner.hasNext()) {
			String name = scanner.next();
			String number = phonebook.lookup(name);
			if (!number.equals("")) 
				System.out.println(number);
			else
				System.out.println("Not found");
			System.out.print("name? ");
		}
	}
}

Notes

Sample Test Run

For example if the file phonebook.text cntains:

Arnow       123-456-7890
Harrow      234-567-8901
Jones       345-678-9012
Augenstein  456-789-0123
Sokol       567-890-1234
Tenenbaum   678-901-2345
Weiss       789-012-3456
Cox         890-123-4567
Langsam     901-234-5678
Thurm       012-345-6789

Here is a sample execution of the program.
User input is in bold. Your program should replicate the prompts and output:

{Arnow:123-456-7890, Harrow:234-567-8901, Jones:345-678-9012, Augenstein:456-789-0123, Sokol:567-890-1234, Tenenbaum:678-901-2345, Weiss:789-012-3456, Cox:890-123-4567, Langsam:901-234-5678, Thurm:012-345-6789}
name? Weiss
789-012-3456
name? Arnow
123-456-7890
name? Washington
Not found
name? Jones
345-678-9012
name? Thrum
Not found
name? Thurm
012-345-6789
name?

Code Used in this Lecture