Pair Programming with Nic

This weekend I made the trip to Morris, MN to do some pair programming with UMM professor & friend Nic McPhee. The objective of the day was to help me on my path back to programming.

I knew I want to do a few things, 1. re-awaken my Java brain cells 2. learn Eclipse, and 3. get started on learning Ruby, anything else would be a blessing. Current UMM and Nic is in a unique to help me with all three. UMM uses Java as the main language for programming classes and most of the students are now using Eclipse (in my day we used Emacs and some used Vim). Luckily Nic is contemplating a switch to Ruby for the Intro to Computer Science class down the road, but more imediately for the Software Engineering course this fall for upper-division students. This change has required Nic to spend a good chunk of his summer learning Ruby, so I’m going to use that knowledge to get some Ruby exposure.

Nic and I worked on a problem that I see a lot at work, fiding the matches between two lists of users. Now for this venue I’ve changed the list of names to those who have a much lower expecation of privacy.


List 1:
Castillo, Louis
Morneau, Justin
Mauer, Joe
Cuddyer, Micheal
Hunter, Tori
Punto, Nick
White, Rondell
Ford, Lew
Stewart, Shannon
Kubel, Justin
Tyner, Justin
Liriano, Francisco
Santana, Johan
Silva, Carlos

List 2:
Mauer, Joe
Konerko, Paul
Thome, Jim
Cano, Robinson
Lopez, Jose
Glaus, Troy
Tejada, Miguel
Young, Michael
Dye, Jermaine
Matthews, Jr, Gary
Ordonez, Magglio
Ramirez, Manny
Rios, Alex
Sizemore, Grady
Liriano, Francisco
Rivera, Mariano
Ryan, B.J.
Santana, Johan
Zito, Barry

As you may have guessed I’m using players from the Twins roster and the 2006 AL All-Star roster.

Here is the Java code:


public class MySearchClass {

private List mnTwins;
private List allStars;

public static void main(String[] args) throws Exception {
MySearchClass searchClass = new MySearchClass();
searchClass.compareFiles(args);
}

private void compareFiles(String[] args) throws Exception {
mnTwins = openAndReadFile(args[0]);
allStars = openAndReadFile(args[1]);

Collections.sort(mnTwins);
Collections.sort(allStars);
int twinsIndex = 0;
int allStarIndex = 0;

while(hasEntries(twinsIndex, allStarIndex)){
String twinsPlayer = mnTwins.get(twinsIndex);
String allStarName = allStars.get(allStarIndex);
if(nameMatch(twinsIndex, allStarIndex)){
System.out.println(twinsPlayer + "t"+ allStarName);
allStarIndex++;
} else if(twinsPlayer.compareTo(allStarName) < 0) {
twinsIndex++;
} else {
allStarIndex++;
}
}
}

private boolean nameMatch(int termedIndex, int activeIndex) {
return allStars.get(activeIndex).startsWith(mnTwins.get(termedIndex));
}

private boolean hasEntries(int twinsIndex, int allStarIndex) {
return twinsIndex < mnTwins.size() && allStarIndex < allStars.size();
}

private static List openAndReadFile(String fileName) throws Exception {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);

String line = bufferedReader.readLine();
List names = new ArrayList();
while(line != null){
names.add(line);
line = bufferedReader.readLine();
}
return names;
}
}

For some reason the List are typed properly they should be a String. Check out MySearchClass is written correctly and that it will compile.

Now here is the Ruby code we wrote afterwords:


class TwinsAllStars
attr :mnTwins
attr :allStarRoster

def read_names(file_name)
names = Array.new
File.open(file_name) do |file|
file.each_line { |line| names << line }
end
return names
end

def initialize
@mnTwins = read_names("mnTwins.txt").sort
@allStarRoster = read_names("allStarRosterList.txt").sort
end

def processFiles
puts @mnTwins & @allStarRoster
twinsIndex = 0
allStarIndex = 0
termedName = @mnTwins[twinsIndex]
allStarName = @allStarRoster[allStarIndex]

while hasEntries(twinsIndex, allStarIndex) do
if allStarName.match(/^#{termedName}.*/)
puts termedName + "t" + allStarName
allStarIndex += 1
allStarName = @allStarRoster[allStarIndex]
elsif termedName < allStarName
twinsIndex += 1
termedName = @mnTwins[twinsIndex]
else
allStarIndex += 1
allStarName = @allStarRoster[allStarIndex]
end
end
end

def hasEntries(twinsIndex, allStarIndex)
twinsIndex < mnTwins.size and allStarIndex < allStarRoster.size
end
end

user_conflict = UserConflict.new

user_conflict.processFiles

Now as you can see it is nearly a duplicate of the way we solved the problem in the same way we solved it with Java. After some thought we looked at the problem again and realized we could do a better job with a different data structure, istead of Lists we would use Sets. Here is our new Ruby code:



def read_names(file_name)
names = Array.new
File.open(file_name) do |file|
file.each_line { |line| names << line }
end
return names
end

mnTwins = read_names("mnTwins.txt").sort
allStarRoster = read_names("allStarRosterList.txt").sort

puts mnTwins & allStarRoster

Ahh, now that looks right. A nice simple way to find the matches.

Please let me know if you have any comments and if we could have done it better.

Also read...

Leave a Reply

Your email address will not be published. Required fields are marked *