Homework Seven and Lab Eight are bothering us. 

Let's start with what is needed for Homework Seven. 

int[] u; 

int[][] a; // declaration 

int[][] b = { {4, 9, 2},
              {3, 5, 7},
              {8, 1, 6} 
            }; 

a = new int[3][3]; // allocation 

a[0][0] = 4; // initialization 
a[0][1] = 9; 
a[0][2] = 2; 
a[1][0] = 3; 
a[1][1] = 5; 
a[1][2] = 7; 
a[2][0] = 8; 
a[2][1] = 1; 
a[2][2] = 6; 

ArrayList<Integer> a; // declaration 

a = new ArrayList<Integer>(); // allocation 

a.add(1); // initialization 

Given this I would like to solve a problem. 

This problem should help you with Homework Seven. 

The part I am going to focus on is 

  converting an int[][] into an ArrayList<ArrayList<Integer>>

Here's the code we wrote: 

-bash-4.1$ cat One.java
import java.util.*;

class One {
  public static void main(String[] args) {

    int[][] b = { {4, 9, 2},
                  {3, 5, 7},
                  {8, 1, 6}
                };

    for (int[] rctmpx : b) {
      System.out.println( Arrays.toString( rctmpx ) );
    }

    System.out.println("----------------------");

    for (int row = 0; row < b.length ; row = row + 1) {
      System.out.println( Arrays.toString( b[row] ) );
    }

    System.out.println("----------------------");

    ArrayList<ArrayList<Integer>> numbers; // declaration

    numbers = new ArrayList<ArrayList<Integer>>();

    System.out.println(numbers);

    System.out.println("----------------------");

    for (int row = 0; row < b.length; row = row + 1) {
      ArrayList<Integer> bag = new ArrayList<Integer>();
      for (int col = 0; col < b[row].length; col = col + 1) {
        bag.add( b[row][col] );
      }
      numbers.add( bag );
      System.out.println( numbers );
      System.out.println("----------------------");
    }

  }
}
-bash-4.1$ javac One.java
-bash-4.1$ java One
[4, 9, 2]
[3, 5, 7]
[8, 1, 6]
----------------------
[4, 9, 2]
[3, 5, 7]
[8, 1, 6]
----------------------
[]
----------------------
[[4, 9, 2]]
----------------------
[[4, 9, 2], [3, 5, 7]]
----------------------
[[4, 9, 2], [3, 5, 7], [8, 1, 6]]
----------------------
-bash-4.1$

So this is the part about the Homework Seven. 

Now let's solve a problem like the lab. 

Assume a file like this: 

  Mitt Romney 3
  Mitt Romney -7
  Barack Hussein Obama II 4
  Trump 6
  Mitt Romney 9
  Barack Hussein Obama II 5

Assume further that someone has summarized it like this: 

  Mitt Romney 3 5 
  Barack Hussein Obama II 2 9  
  Trump 1 6

My job is to read lines from this file. 

Create a Candidate object for each line, place in an ArrayList<Candidate>, sort. 

So we start like this:

-bash-4.1$ cat data.txt
Mitt Romney 3 5
Barack Hussein Obama II 2 9
Trump 1 6
-bash-4.1$ cat Program.java
import java.io.*;
import java.util.*;

class Program {
  public static void main(String[] args) throws Exception {
    String file = args[0];
    File f = new File(file);
    Scanner duke = new Scanner(f);
    while (duke.hasNextLine()) {
      String line = duke.nextLine();
      System.out.println( "***(" + line + ")***" );
    }
  }
}
-bash-4.1$ javac Program.java
-bash-4.1$ java Program
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
        at Program.main(Program.java:6)
-bash-4.1$ java Program votes.txt
Exception in thread "main" java.io.FileNotFoundException: votes.txt (No such file or directory)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.util.Scanner.<init>(Scanner.java:656)
        at Program.main(Program.java:8)
-bash-4.1$ java Program data.txt
***(Mitt Romney 3 5)***
***(Barack Hussein Obama II 2 9)***
***(Trump 1 6)***
-bash-4.1$

Let's take a detour through Perl now:

-bash-4.1$ ls -ld one
-rw-r--r-- 1 dgerman faculty 94 Oct 25 14:30 one
-bash-4.1$ chmod u+x one
-bash-4.1$ ls -ld one
-rwxr--r-- 1 dgerman faculty 94 Oct 25 14:30 one
-bash-4.1$ ./one
Mitt Romney 3 5
Barack Hussein Obama II 2 9
Trump 1 6
-bash-4.1$ cat one
#!/usr/bin/perl

open (AB, "data.txt");
while ($line = <AB>) {
  print $line;
}
close(AB);
-bash-4.1$

Here's what we need to be able to do in Java: 

-bash-4.1$ cat data.txt
Mitt Romney 3 5
Barack Hussein Obama II 2 9
Trump 1 6
-bash-4.1$ cat one
#!/usr/bin/perl

open (AB, "data.txt");
while ($line = <AB>) {
  # print $line;
  if ($line =~ /^((\w+\s+)+)(\d+)\s+(-{0,1}\d+)\s*$/) {
    $name = $1;
    $count = $3;
    $sum = $4;
    print qq{
Candidate: $name has $count votes (sum is $sum)
    };
  }
}
close(AB);
-bash-4.1$ ./one

Candidate: Mitt Romney  has 3 votes (sum is 5)

Candidate: Barack Hussein Obama II  has 2 votes (sum is 9)

Candidate: Trump  has 1 votes (sum is 6)
    -bash-4.1$

The name for this is "Regular Expressions" and the reference:

http://docs.oracle.com/javase/tutorial/essential/regex/index.html

Here's the program we developed:

-bash-4.1$ cat data.txt
Mitt Romney 3 5
Barack Hussein Obama II 2 9
Trump 1 6
Bad Guy 3 -20
-bash-4.1$ cat Program.java
import java.util.regex.Pattern;
import java.util.regex.Matcher;

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

class Program {
  public static void main(String[] args) throws Exception {
    String file = args[0];
    File f = new File(file);
    Scanner duke = new Scanner(f);

    Pattern pattern = Pattern.compile("^((\\w+\\s+)+)(\\d+)\\s+(-{0,1}\\d+)\\s*$");

    ArrayList<Candidate> candidates = new ArrayList<Candidate>();

    while (duke.hasNextLine()) {
      String line = duke.nextLine();
      System.out.println( "***(" + line + ")***" );
      Matcher matcher = pattern.matcher(line);
      if (matcher.find()) {
        String name = matcher.group(1);
        int count = Integer.parseInt( matcher.group(3) );
        int sum = Integer.parseInt( matcher.group(4) );
        // System.out.println( name + ", " + count + ", " + sum );

        Candidate c = new Candidate( name, count, sum );

        candidates.add( c );
        System.out.println( candidates );
      }
      Collections.sort( candidates );
      System.out.println( candidates );
    }
  }
}
-bash-4.1$ cat Candidate.java
public class Candidate implements Comparable<Candidate> {
  String name;
  int count;
  int sum;
  public String toString() {
    return this.name + "(" + this.sum + "/" + this.count + ")";
  }
  Candidate(String name, int count, int sum) {
    this.name = name;
    this.count = count;
    this.sum = sum;
  }
  public int compareTo(Candidate other) {
    if (this.sum > other.sum) return -1;
    else if (this.sum < other.sum) return 1;
    return this.name.compareTo(other.name);
  }
}
-bash-4.1$ javac Program.java
-bash-4.1$ java Program data
Exception in thread "main" java.io.FileNotFoundException: data (No such file or directory)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.util.Scanner.<init>(Scanner.java:656)
        at Program.main(Program.java:11)
-bash-4.1$ java Program data.txt
***(Mitt Romney 3 5)***
[Mitt Romney (5/3)]
[Mitt Romney (5/3)]
***(Barack Hussein Obama II 2 9)***
[Mitt Romney (5/3), Barack Hussein Obama II (9/2)]
[Barack Hussein Obama II (9/2), Mitt Romney (5/3)]
***(Trump 1 6)***
[Barack Hussein Obama II (9/2), Mitt Romney (5/3), Trump (6/1)]
[Barack Hussein Obama II (9/2), Trump (6/1), Mitt Romney (5/3)]
***(Bad Guy 3 -20)***
[Barack Hussein Obama II (9/2), Trump (6/1), Mitt Romney (5/3), Bad Guy (-20/3)]
[Barack Hussein Obama II (9/2), Trump (6/1), Mitt Romney (5/3), Bad Guy (-20/3)]
-bash-4.1$

What about the other ordering? 

Answer: use Comparator's.

http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

--

Here's this last part:

-bash-4.1$ ls -ld Candidate.java Program.java Judge.java data.txt
-rw-r--r-- 1 dgerman faculty  579 Oct 25 15:10 Candidate.java
-rw-r--r-- 1 dgerman faculty   68 Oct 25 14:41 data.txt
-rw-r--r-- 1 dgerman faculty  319 Oct 25 15:12 Judge.java
-rw-r--r-- 1 dgerman faculty 1185 Oct 25 15:10 Program.java
-bash-4.1$ cat Candidate.java
public class Candidate implements Comparable<Candidate> {
  String name;
  int count;
  int sum;
  public String toString() {
    return this.name + "(" + this.sum + "/" + this.count + ")";
  }
  Candidate(String name, int count, int sum) {
    this.name = name;
    this.count = count;
    this.sum = sum;
  }
  public double average() {
    return (double) this.sum / this.count;
  }
  public int compareTo(Candidate other) {
    if (this.sum > other.sum) return -1;
    else if (this.sum < other.sum) return 1;
    return this.name.compareTo(other.name);
  }
}
-bash-4.1$ cat data.txt
Mitt Romney 3 5
Barack Hussein Obama II 2 9
Trump 1 6
Bad Guy 3 -20
-bash-4.1$ cat Judge.java
import java.util.*;

public class Judge implements Comparator<Candidate> {
  public int compare(Candidate a, Candidate b) {
    if ( a.average() > b.average() ) {
      return -1;
    } else if ( a.average() < b.average() ) {
      return 1;
    } else {
      return a.name.compareTo(b.name);
    }
  }
}
-bash-4.1$ cat Program.java
import java.util.regex.Pattern;
import java.util.regex.Matcher;

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

class Program {
  public static void main(String[] args) throws Exception {
    String file = args[0];
    File f = new File(file);
    Scanner duke = new Scanner(f);

    Pattern pattern = Pattern.compile("^((\\w+\\s+)+)(\\d+)\\s+(-{0,1}\\d+)\\s*$");

    ArrayList<Candidate> candidates = new ArrayList<Candidate>();

    while (duke.hasNextLine()) {
      String line = duke.nextLine();
      System.out.println( "***(" + line + ")***" );
      Matcher matcher = pattern.matcher(line);
      if (matcher.find()) {
        String name = matcher.group(1);
        int count = Integer.parseInt( matcher.group(3) );
        int sum = Integer.parseInt( matcher.group(4) );
        // System.out.println( name + ", " + count + ", " + sum );

        Candidate c = new Candidate( name, count, sum );

        candidates.add( c );
        System.out.println( candidates );
      }
      Collections.sort( candidates );
      System.out.println( candidates );
      Collections.sort( candidates, new Judge() );
      System.out.println( candidates );
    }
  }
}
-bash-4.1$ javac Program.java
-bash-4.1$ java Program data.txt
***(Mitt Romney 3 5)***
[Mitt Romney (5/3)]
[Mitt Romney (5/3)]
[Mitt Romney (5/3)]
***(Barack Hussein Obama II 2 9)***
[Mitt Romney (5/3), Barack Hussein Obama II (9/2)]
[Barack Hussein Obama II (9/2), Mitt Romney (5/3)]
[Barack Hussein Obama II (9/2), Mitt Romney (5/3)]
***(Trump 1 6)***
[Barack Hussein Obama II (9/2), Mitt Romney (5/3), Trump (6/1)]
[Barack Hussein Obama II (9/2), Trump (6/1), Mitt Romney (5/3)]
[Trump (6/1), Barack Hussein Obama II (9/2), Mitt Romney (5/3)]
***(Bad Guy 3 -20)***
[Trump (6/1), Barack Hussein Obama II (9/2), Mitt Romney (5/3), Bad Guy (-20/3)]
[Barack Hussein Obama II (9/2), Trump (6/1), Mitt Romney (5/3), Bad Guy (-20/3)]
[Trump (6/1), Barack Hussein Obama II (9/2), Mitt Romney (5/3), Bad Guy (-20/3)]
-bash-4.1$


Notice that: 

  (a) Candidates are able to calculate and report their average(s)
  (b) there is now a Judge Comparator<Candidate> type for sorting by average 
  (c) Program.java now sorts twice, the second time via a Judge() object

The average order is different from the sum order: 

  Trump has the largest average 
  Obama now second, though still ahead of Romney 
  Bad Guy the only one with a negative average is last

--