Thursday, November 11, 2010

More Lectures by Better Lecturers

If you think that listening to a better lecturer will help you learn the material better then, you are in luck! As you probably know, all major Universities have their CS101-type courses online. I highly recommend MIT's 6.00: Introduction to Computer Science lectures. Another good one is Harvard's CS50.

Below is their video for binary search (using recursion, of course), which I will be talking about today.

Tuesday, November 9, 2010

Lab 19 - section 5 and section 6

Problem 3 - page 787

HW 7: Fractals

In this homework you will practice recursion by drawing some well-known fractal curves. You have to use the Point and Vector classes I provide below to do your arithmetic. I will explain them in class today. The code below also creates a window and draws a line. You will use that as a starting point for your project.
The first curve you will implement is known as the Levy C Curve and its stages are shown on the first figure. A level 0 curve is just a line between two points:start and end. At level 1, instead of drawing a line between the two points, we
  1. find the midpoint between the two points,
  2. find the vector that is perpendicular to the line, scale it by .5
  3. add the perpendicular vector to the midpoint to get a new point, call it NP
  4. recursively draw a c-curve from the start to NP and another one from NP to the end point.
The above set of steps is pseudo-code for the Java recursive function you will write to draw the C Curve.
The second curve you will implement is the Dragon Curve which is nearly identical to the C curve expect that sometimes we use one perpendicular (right) and sometimes the other (left). You will implement another method which draws the Dragon curve.
The third fractal you will implement is the Sierpinsky triangle. This one is different in that, instead of drawing a line by breaking it up into two pieces, you will be drawing a triangle by breaking it up into three smaller triangles. The recursion will be similar but the drawing code will be different.
Finally, after you get these to run then go back and change them so that they calculate and printout the length of the fractal they have just drawn. That is, the sum of the length of all the little line segments.
This homework is due on Thursday, November 18 @9am. Below is the code for Point and Vector which you must use as well as a short program that draws a line, to get you started.
public class Point {
 
 public double x;
 public double y;
 
 /**
  * We return the nearest int to the current x value.
  * By keeping points as double we increase the precision of the final plot.
  * We only convert to int when absolutely necessary, that is, when plotting on screen.
  * @return
  */
 public int getX() {
  return (int) Math.round(x);
 }
 
 public int getY() {
  return (int) Math.round(y);
 }
 
 public Point(int x, int y) {
  this.x = x;
  this.y = y;
 }
 
 public Point(double x, double y) {
  this.x = x;
  this.y = y;
 }
 
 public String toString() {
  return x + "," + y;
 }
 
 /**
  * Make a vector from this point to other
  * @param other
  * @return a new Vector
  */
 public Vector getVectorTo(Point other) {
  return new Vector(other.x - x,other.y - y);
 }
 
 /**
  * Returns a Point that lies midway on the line between this point and other
  * @param other
  * @return a new Point
  */
 public Point getMidPoint(Point other) {
  return new Point((x + other.x)/ 2, (y +other.y)/ 2);
 }

 /**
  * Move this point by vector v.
  * @param v
  * @return a new Point
  */
 public Point addVector(Vector v) {
  return new Point(x + v.x, y + v.y);
 }
 
}


public class Vector extends Point {

 public Vector(double x, double y) {
  super(x,y);
 }

 /**
  * The magnitude
  * @return the magnitude.
  */
 public double getMagnitude() {
  return Math.sqrt(x*x+y*y);
 }

 /**
  * Creates a new vector that is perpendicular to this one, pointing to the right.
  * @return a new vector
  */
 public Vector getPerpendicularRight() {
  return new Vector(-y, x);
 }

 /**
  * Creates a new vector that is perpendicular to this one, pointing to the left.
  * @return a new vector
  */
 public Vector getPerpendicularLeft() {
  return new Vector(y, -x);
 }

 /**
  * Creates a new vector like this one but scaling both coordinates by d
  * @param d
  * @return a new vector
  */
 public Vector multiplyBy(double d) {
  return new Vector(x*d, y*d);
 }

}

/** Jose M Vidal 
 * If that's not me on the line above then I deserve 0 points on this homework. */

import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JOptionPane;

public class Fractal extends JPanel{

 public int numLevels;

 public void paintComponent(Graphics g) {
  g.setColor(Color.black);
  System.out.println("Drawing");
  g.drawLine(200, 200, 400, 200);
 }
 
 /**
  * @param args
  */
 public static void main(String[] args) {
  JFrame frame = new JFrame("Fractal Curve");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  Fractal panel = new Fractal();

  frame.add(panel);
  frame.setSize(600,600);
  frame.setVisible(true);
  try {
   do {
    String userInput = JOptionPane.showInputDialog("How Many Levels?");
    panel.numLevels = Integer.parseInt(userInput);
    frame.repaint(); //don't forget to re-paint it !
   } while (true);
  } catch (NumberFormatException e) {
   //ignore it, just exit program
   System.exit(0);
  }
 }
}

HW6 Solution

Below is my solution to HW6:
public class FileTooBigException extends Exception {
 public FileTooBigException(String msg) {
  super(msg);
 }
}

public class NotEnoughDataException extends Exception { 
 public NotEnoughDataException(String msg) {
  super(msg);
 }
}

import java.util.Scanner;
public class Day {
 private String date;
 private double open;
 private double high;
 private double low;
 private double close;
 private long volume;
 
 public double getClose() {
  return close;
 }
 
 public double getVolume() {
  return volume;
 }
 
 /**
  * Creates a new Day object by reading values from istream:
  *   date, open, high, log, close, volume: in that order.
  * We assume the delimiter has been correctly set on istream so values can be read
  *   by calling nextX()
  * @param istream
  */
 public Day (Scanner istream) {
  date = istream.next();
  open = istream.nextDouble();
  high = istream.nextDouble();
  low = istream.nextDouble();
  close = istream.nextDouble();
  volume = istream.nextLong();
 }

 public String toString() {
  return date + " " + close + " " + volume;
 }
}


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Scanner;

public class Security {

 private Day[] day;

 private int lastDay;

 private static final int DAY_ARRAY_SIZE = 1000;

 /**
  * Add day d to the history, but only if its volume > 0.
  * @param d
  * @throws FileTooBigException 
  */
 public void addDay(Day d) throws FileTooBigException {
  if (d.getVolume() > 0) {
   if (lastDay >= DAY_ARRAY_SIZE) {
    throw new FileTooBigException("You cannot have more than " + DAY_ARRAY_SIZE + " days.");
   }
   day[lastDay++] = d;
  }
 }

 public Security () {
  day = new Day[DAY_ARRAY_SIZE];
  lastDay = 0;
 }

 /** Read historical values for this security from a csv stream.
  * 
  * @param file
  * @throws FileTooBigException 
  */
 public void readFromStream(Scanner istream) throws FileTooBigException {
  istream.useDelimiter("[,\\s]"); //separate on , or on whitespace
  if (istream.hasNext()) {
   istream.nextLine(); //ignore first line
  }
  String w = null;
  while (istream.hasNext()) {
   //System.out.println("----" + istream.next());
   Day nextDay = new Day(istream);
   addDay(nextDay);
  }
 }

 public double getVolatility(int numDays) throws NotEnoughDataException {
  if (numDays > lastDay) {
   throw new NotEnoughDataException("Need more historical data");
  }
  double average = getAverageClose(numDays);
  double squareDifference = 0;
  for (int i=0; i < numDays; i++) {
   squareDifference += Math.pow(day[i].getClose() - average, 2);
  }
  double deviation = squareDifference / (double) numDays;
  return Math.sqrt(deviation);
 }

 public double getAverageClose(int numDays) {
  double sum = 0;
  for (int i=0; i< numDays;i++) {
   sum += day[i].getClose();
  }
  return sum / (double)numDays;
 }

 public String toString() {
  String result = "";
  for (int i= 0; i < lastDay; i++) {
   result += day[i] + "\n";
  }
  return result;
 }

 public double getMinClose(int numDays) {
  double min = Double.MAX_VALUE; //assume no stock price is ever this high
  for (int i = 0; i < numDays; i++) {
   if (day[i].getClose() < min)
    min = day[i].getClose();
  }
  return min;
 }

 public double getMaxClose(int numDays) {
  double max = -1;
  for (int i = 0; i < numDays; i++) {
   if (day[i].getClose() > max)
    max = day[i].getClose();
  }
  return max;
 }
 /**
  * Returns a price distribution array, where the index of the array is the price - getMinClose(numDays)
  * whose contents are the number of days we closed at that price within the last numDays.
  * @param numDays
  * @return array with getMaxClose(numDays) - getMinClose(numDays) + 1 values 
  */

 public int[] getPriceDistribution(int numDays) {
  int min = (int) getMinClose(numDays);
  int max = (int) getMaxClose(numDays);
  int[] result = new int[max-min + 1];
  for (int i =0; i < numDays; i++) {
   result[(int)day[i].getClose() - min]++;
  }
  return result;
 }

 public void savePriceDistribution(String outFile,int numDays) throws FileNotFoundException {
  PrintWriter out = new PrintWriter(new FileOutputStream(outFile, true));
  int min = (int) getMinClose(numDays);
  int[] distribution = getPriceDistribution(numDays);
  for (int i =0; i < distribution.length; i++) {
   int p = min + i;
   out.write(p + "," + distribution[i] + "\n");
  }
  out.close();
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  Scanner istream = null;
  String inputFile = "/Users/jmvidal/data.csv";
  try {
   istream = new Scanner(new File(inputFile));
  } catch (FileNotFoundException e) {
   System.out.println("Ooops, no such input file:" + inputFile);
   System.exit(1);
  }

  Security s = new Security(); //Security class will hold all the data
  try {
   s.readFromStream(istream); //read the contents from istream
  } catch (FileTooBigException e1) { //file is to big to read
   System.out.println(e1.getMessage());
   System.exit(1);
  }

  System.out.println(s); //print out all the contents. Note: no days with 0 volume.

  try {
   System.out.println("Volatility in the last 10 days = " + s.getVolatility(10));
   System.out.println("Volatility in the last 1000 days = " + s.getVolatility(1000));

  } catch (NotEnoughDataException e) {
   System.out.println("Sorry, not enough data." + e.getMessage());
  }

  System.out.println("Price Distribution for the last 10 days.");
  System.out.println("price\tnumber of days");
  int[] priceDistribution = s.getPriceDistribution(10); //get the distribution array
  int minClose = (int)s.getMinClose(10);
  for (int i=0; i < priceDistribution.length; i++) { //we need this loop to print it out
   int p = minClose + i;
   System.out.println(p + "\t" + priceDistribution[i]);
  }

  try {
   //now, save the distribtion for the last 20 days to a file.
   s.savePriceDistribution("/Users/jmvidal/distribution-20.csv",20); 
  } catch (FileNotFoundException e) {
   System.out.println("Ooops, bad output file name.");
   System.exit(1);
  }
 }
}

Monday, November 8, 2010

Chapter 11 Video: Recursion

Chapter 11 deals with the topic of recursion. Recursion is not a language feature, it is simply having a method call itself. All programming languages are capable of recursion. Recursion is a technique that makes certain algorithms much easier to write and understand.

CSCE 145: Chapter 11 from Jose Vidal on Vimeo.

Here are the slides from the textbook:

Thursday, November 4, 2010

Java 4-Ever!

Already nominated for a Developers' Choice award:

Chapter 10 Video

Below is the screencast for the chapter 10 which deals with reading and writing streams to files. I/O operations like these are slightly different on every programming language, but the basic ideas are the same.

CSCE 145: Chapter 10 from Jose Vidal on Vimeo.

The textbook slides are below.

Lab 18 -- File Handling -- File Read/Write

Assume you are the owner of Tower Records, which sells music CDs and albums, and you decide to hold a sale to try to reduce your inventory of old records. Write a Java program to read from your inventory text file (refer below for an example file "albums.txt"), which contains information about albums and CDs, including their cost. If an album is between one year and five years old, change the cost to show a discount of 5%. If an album is between 5 years old and 10 years old, give a discount of 10%. If it is more than 10 years old, give a discount of 50%. The album information with the new pricing should be written into a new text file newalbums.txt.

Each record is represented by four lines of text in the files. The first line is the title of the album, the next line is the artist/group name, the next is the year of release, and the next is the price of the album.

Hints: Once you read in each line as a String you can parse the year of release Integer.parseInt(String s) to an int and check how old it is and give a discount on the parsed price (double). Use the substring(int index) method of the String class to get rid of the $ sign in the front of price. Use a loop to do it for all albums.

Lab 18 -- FileHandling -- albums.txt

Rock Steady
No Doubt
2002
$18.98
Revolver
The Beatles
1966
$14.00
Dangerously in Love
Beyonce featuring Jean Paul
2003
$18.50
Blood on the Dance Floor: History in the Making
Michael Jackson
1997
$16.50

Wednesday, November 3, 2010

The Java Posse

These guys have had a podcast for five years. I'm a fan.