import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Set; import java.util.TreeMap; import processing.core.PApplet; /* * Pehr Hovey * MAT259 Project 1 Winter 2009 * * Graph Checkout duration, collection code and time in 2D * * TransactionUtils.java - represent one library transaction. * Store only fields needed for this visualization * * Based on course code from Angus * */ public class TransactionUtils { //sort a List of transactions by the title public static void sortTransactionsByTitle(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; return t1.title.compareToIgnoreCase(t2.title); } } ); } public static void sortTransactionsByTimeStamp(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; Long l1 = new Long(t1.ckitimestamp); Long l2 = new Long(t2.ckitimestamp); return l1.compareTo(l2); } } ); } public static void sortTransactionsByDuration(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; Long l1 = new Long(t1.ckoduration); Long l2 = new Long(t2.ckoduration); return l1.compareTo(l2); } } ); } public static void sortTransactionsBySection(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; String s1 = getSection(t1.collcode); String s2 = getSection(t2.collcode); return s1.compareToIgnoreCase(s2); } } ); } public static void sortTransactionsByItemType(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; String s1 = getItemType(t1.itemtype); String s2 = getItemType(t2.itemtype); return s1.compareToIgnoreCase(s2); } } ); } public static void sortTransactionsByCollection(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; String s1 = getCollection(t1.collcode); String s2 = getCollection(t2.collcode); return s1.compareToIgnoreCase(s2); } } ); } //Sort a counts map (sectionsCount, etc by the counts value //Must do this by creating new map so return it rather than modifying original public static ArrayList sortCountsByCount(ArrayList counts) { Collections.sort(counts, new Comparator(){ public int compare(Object o1, Object o2) { CountEntry e1 = (CountEntry) o1; CountEntry e2 = (CountEntry) o2; Integer i1 = new Integer(e1.count); Integer i2 = new Integer(e2.count); return i2.compareTo(i1); //descending, highest first } } ); return counts; } public static ArrayList sortCountsByLabel(ArrayList counts) { Collections.sort(counts, new Comparator(){ public int compare(Object o1, Object o2) { CountEntry e1 = (CountEntry) o1; CountEntry e2 = (CountEntry) o2; return e2.label.compareTo(e1.label); } } ); return counts; } //reverse order of List public static void reverse(ArrayList transactions) { Collections.reverse(transactions); } public static void filterOutNonAlphabeticalTitles(ArrayList transactions) { for (int i = transactions.size() - 1; i >= 0; i--) { Transaction t = (Transaction) transactions.get(i); if (t.title.length() < 1) { transactions.remove(t); continue; } char firstLetter = t.title.charAt(0); if (! ((firstLetter >= 'a' && firstLetter <= 'z') || (firstLetter >= 'A' && firstLetter <= 'Z')) ) { transactions.remove(t); continue; } } } // create a new transaction obejct from a comma separated line. public static Transaction parseTransaction(String line) { String sections[] = PApplet.split(line, ","); Transaction t = new Transaction(); //store all fields t.itemNumber = sections[0]; t.ckodate = sections[1]; t.ckotime = sections[2]; t.ckidate = sections[3]; t.ckitime = sections[4]; t.collcode = sections[5]; t.itemtype = sections[6]; if(sections.length > 7){ //some transactions don't have a title! t.title = sections[7]; }else{ System.err.println("no title for item#"+t.itemNumber); } t.calculateDuration(); t.calculateTimeStamp(); return t; } //Strip surrounding codes from collcode to get if its childrens, young adult, etc public static String getSection(String collcode){ //First char is book home, 2nd char is what we want. everything else afterwards is variable length return collcode.substring(1,2); } public static String getCollection(String collcode){ //First char is book home, 2nd char is section. everything else afterwards is collection return collcode.substring(2); } public static String getItemType(String itemtype){ //First char controls fine-policy, second char is whether it can be checked out, all following is itemtype return itemtype.substring(2); } //Convenience methods to return a map for getting printable names for codes //Call these during setup() //Info from http://www.mat.ucsb.edu/%7Eg.legrady/academic/courses/08w259/itemTypes.pdf public static HashMap getSectionsMap(){ //What broad section this is in, based on demographics HashMap hm = new HashMap(); hm.put("a","Adult"); hm.put("c","Childrens"); hm.put("y","Young Adult"); return hm; } public static HashMap getCollectionsMap(){ //what lib collection i.e. non-fiction HashMap hm = new HashMap(); hm.put("nf","Nonfict."); hm.put("new","New Items"); hm.put("cd","CD"); hm.put("dvd","DVD"); hm.put("dvdnf","DVD Nonfic."); hm.put("fic","Fict."); hm.put("comic","Comics"); hm.put("kit","Kit"); hm.put("mus","Music Score"); hm.put("cas","Audio Tape"); hm.put("casnf","Audio Tape Nf"); hm.put("vid","Video"); hm.put("vidnf","Video Nonfict. "); return hm; } public static HashMap getItemTypesMap(){ HashMap hm = new HashMap(); hm.put("bk","Book"); hm.put("cd","CD"); hm.put("dvd","DVD"); hm.put("vhs","VHS"); hm.put("cas","Cassette"); hm.put("fold","Folder"); hm.put("disk","Diskette"); hm.put("cdrom","CD-ROM"); hm.put("per","Periodical"); hm.put("art","Framed Art"); hm.put("map","Map"); hm.put("kit","Kit"); hm.put("mfc","Microfiche"); hm.put("mfm","Microfilm"); hm.put("mus","Music Score"); hm.put("np","Newspaper"); hm.put("pam","Pamphlet"); hm.put("photo","Photograph"); hm.put("post","Poster"); hm.put("rec","Record"); hm.put("slide","Slides"); hm.put("illb","Inter-library"); return hm; } //Given two already assembled Gregorian Calendar dates, calc time diff in milliseconds public static long getTimeDifferenceInMillis(java.util.GregorianCalendar gc1, java.util.GregorianCalendar gc2) { return gc2.getTimeInMillis() - gc1.getTimeInMillis(); } //Take date/time in a string format and return greg. cal. public static java.util.GregorianCalendar getGCFromString(String date, String time){ // GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second) //Date, time string format: 2008-05-02 10:43:00 // System.out.println("Parsing d/t: "+date+" / "+time); int year = Integer.valueOf(date.substring(0, 4)).intValue(); int month = Integer.valueOf(date.substring(5,7)).intValue(); int dayOfMonth = Integer.valueOf(date.substring(8,10)).intValue(); int hourOfDay = Integer.valueOf(time.substring(0,2)).intValue(); int minute = Integer.valueOf(time.substring(3,5)).intValue(); int second = Integer.valueOf(time.substring(6,8)).intValue(); // System.out.println(year+" "+month+" "+dayOfMonth+' '+hourOfDay+' '+minute+' '+second); java.util.GregorianCalendar gc = new java.util.GregorianCalendar(year, month-1, dayOfMonth, hourOfDay,minute,second); // System.out.println(gc.getTime()); return gc; } // fill a hashmap with a pairing of itemtype -> # of items with that type //Also helpful in figuring out which itemtypes are represented in the dataset and which are not present public static ArrayList calculateItemTypeCounts(ArrayList transactions) { Transaction t; TreeMap map= new TreeMap(); for (int i = 0; i < transactions.size(); i++) { t = (Transaction)transactions.get(i); //Translate this type. We want all itemtypes containing DVD to count just as DVD String key = TransactionUtils.getItemType(t.itemtype); if(map.containsKey(key)){ Integer val = (Integer)map.get(key); map.put(key, new Integer(val.intValue()+1)); //increment count }else{ map.put(key, new Integer(1)); //first one found } } // Assemble an ArrayList of CountEntries to make it more easily sortable ArrayList result = new ArrayList(); Object[] keys = map.keySet().toArray(); CountEntry entry; String label=""; Integer count; for(int k=0; k < keys.length; k++){ label = (String) keys[k]; count = (Integer)map.get(label); entry = new CountEntry(label, count.intValue()); result.add(k, entry); } return result; } public static ArrayList calculateCollectionCounts(ArrayList transactions) { Transaction t; TreeMap map= new TreeMap(); for (int i = 0; i < transactions.size(); i++) { t = (Transaction)transactions.get(i); //Translate this type. We want all itemtypes containing DVD to count just as DVD String key = TransactionUtils.getCollection(t.collcode); if(map.containsKey(key)){ Integer val = (Integer)map.get(key); map.put(key, new Integer(val.intValue()+1)); //increment count }else{ map.put(key, new Integer(1)); //first one found } } //Assemble an ArrayList of CountEntries to make it more easily sortable ArrayList result = new ArrayList(); Object[] keys = map.keySet().toArray(); CountEntry entry; String label=""; Integer count; for(int k=0; k < keys.length; k++){ label = (String) keys[k]; count = (Integer)map.get(label); entry = new CountEntry(label, count.intValue()); result.add(k, entry); } return result; } public static ArrayList calculateSectionCounts(ArrayList transactions) { Transaction t; TreeMap map= new TreeMap(); for (int i = 0; i < transactions.size(); i++) { t = (Transaction)transactions.get(i); //Translate this type. We want all itemtypes containing DVD to count just as DVD String key = TransactionUtils.getSection(t.collcode); if(map.containsKey(key)){ Integer val = (Integer)map.get(key); map.put(key, new Integer(val.intValue()+1)); //increment count }else{ map.put(key, new Integer(1)); //first one found } } // Assemble an ArrayList of CountEntries to make it more easily sortable ArrayList result = new ArrayList(); Object[] keys = map.keySet().toArray(); CountEntry entry; String label=""; Integer count; for(int k=0; k < keys.length; k++){ label = (String) keys[k]; count = (Integer)map.get(label); entry = new CountEntry(label, count.intValue()); result.add(k, entry); } return result; } //Make a deep copy of an ArrayList of transactions //deep copy means all the objects inside are new instances so modifying the source //will not affect the destination public static ArrayList copyTransactions(ArrayList source){ ArrayList dest = new ArrayList(source.size()); for(int i=0; i< source.size(); i++){ dest.add(i,new Transaction((Transaction)source.get(i))); //put it in the same place } return dest; } }