diff --git a/src/Main.java b/src/Main.java index db3c0ff20b675352bdde51d4eabd7f5230222477..ec16db1494800f43bae2ba9076e14ad40522fa79 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,13 +1,28 @@ import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.json.simple.parser.ParseException; import data.BioTree; import data.DataStore; +import data.Date; import data.FileProcessor; import data.Record; +import data.WormsAPI; +import search.BST; import search.BasicSearch; +import search.BasicSearchResult; +import search.Histogram; +import sort.Bound; +import sort.GeneralRange; import sort.KDT; +import sort.RangeHelper; +import utils.Stopwatch; public class Main { public static void main(String[] args) { @@ -27,7 +42,7 @@ public class Main { BioTree.write("data/biotree/"); DataStore.records.writeToFile("data/kdt.ser"); }; - BasicSearch.init(); + init(); } private static void printLogo() { @@ -53,4 +68,135 @@ public class Main { " `-' `````````"); System.out.println("Loading......."); } + + public static void init() { + System.out.println("Welcome!"); + while(true) { + System.out.println("Main Menu"); + System.out.println("Available commands:"); + System.out.println("\ttree [taxonId / scientific name]"); + System.out.println("\trecords (taxonId / scientific name) [-t start end]"); + System.out.print("> "); + Pattern pat = Pattern.compile("([a-zA-Z]+)[ ]?([0-9a-zA-Z ]+[0-9a-zA-Z])?[ ]?[-]?([a-zA-Z])?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?"); + Scanner s = new Scanner(System.in); + String line = s.nextLine(); + Matcher matcher = pat.matcher(line); + if (!matcher.find()) continue; + + //tree + //tree taxonId + //tree scientific name + //records taxonId + //records scientific name + String command = matcher.group(1); + + if (command.equals("records")) + rangeSearch(matcher); + else if (command.equals("tree")) + printTree(matcher); + } + } + + private static void rangeSearch(Matcher matcher) { + Integer start = null; + Integer end = null; + if (matcher.group(3) != null) + if (matcher.group(3).equals("t")) { + if (matcher.group(4) != null) + start = Integer.parseInt(matcher.group(4)); + if (matcher.group(5) != null) + end = Integer.parseInt(matcher.group(5)); + } + + Integer taxonId = null; + try { + taxonId = Integer.parseInt(matcher.group(2)); + } catch (NumberFormatException e) { + if (taxonId == null) { + try { + taxonId = WormsAPI.nameToRecordID(matcher.group(2)); + } catch (IOException e1) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ParseException e1) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + BasicSearchResult result = BasicSearch.range(taxonId, start, end); + + System.out.println("Found " + result.n() + " records in " + result.time() + " seconds."); + + while(true) { + System.out.println("Available commands: list, histogram, sum, exit"); + System.out.print("> "); + + Scanner s = new Scanner(System.in); + String command = s.nextLine(); + + if (command.equals("list")) + printRecords(result.results()); + else if (command.equals("histogram")) { + printHistogram(result.histogram()); + } else if (command.equals("exit")) + return; + else if (command.equals("sum")) { + System.out.println(result.sum()); + } + } + } + + private static void printRecords(Iterable<Record> results) { + String format = "|%1$-45s|%2$-15s|%3$-15s|%4$-15s|%5$-15s|%6$-15s\n"; + System.out.format(format, "Scientific Name", "IndividualCount", "Latitude", "Longitude","Year","Month","Day"); + for (Record r: results) { + System.out.println(r); + } + } + + private static void printTree(Matcher matcher) { + Integer taxonId; + String name; + if (matcher.group(2) == null) + BioTree.printTree(); + else { + name = matcher.group(2); + try { + taxonId = Integer.parseInt(name); + BioTree.printTree(taxonId); + } catch (Exception e) { + BioTree.printTree(name); + } + } + System.out.println(); + } + + /** + * Prints a histogram based on a BST of records + * + * @param record -An BST of records + */ + public static void printHistogram(BST<Integer,Integer> record) { + int max = 0; + int scale = 100; + Iterable<Integer> results = record.keys(); + for (Integer year: results) { + if (max < record.get(year)) max =record.get(year); + + } + System.out.println(" |" + (new String(new char[scale]).replace('\0', '-')) + "|"); + String format = "%1$-5d|%2$-" + (scale + 1) + "s"; + for (Integer year: results) { + String s = "="; + int loopc = (int) ((float)(record.get(year)/ (float) max) * scale); + for (int j=0; j< loopc; j++) { + s+="="; + } + System.out.format(format, year, s); + System.out.println("| " + record.get(year)); + } + System.out.format("Scale: one = is %d individuals.\n", max / scale); + } } diff --git a/src/search/BasicSearch.java b/src/search/BasicSearch.java index 97cdb49d90124c76e19b0a2b4023a232cc1988eb..ec7894aa92b82a9f8d845bf7091c968987bfc82c 100644 --- a/src/search/BasicSearch.java +++ b/src/search/BasicSearch.java @@ -1,84 +1,37 @@ package search; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.json.simple.parser.ParseException; - import utils.Stopwatch; import data.BioTree; import data.DataStore; import data.Date; import data.Record; -import data.WormsAPI; import sort.Bound; import sort.GeneralRange; import sort.RangeHelper; +/** + * Provides functionality for range searching the Record database. + * @author Christopher W. Schankula + * + */ public class BasicSearch { - public static void init() { - System.out.println("Welcome!"); - while(true) { - System.out.println("Main Menu"); - System.out.println("Available commands:"); - System.out.println("\ttree [taxonId / scientific name]"); - System.out.println("\trecords (taxonId / scientific name) [-t start end]"); - System.out.print("> "); - Pattern pat = Pattern.compile("([a-zA-Z]+)[ ]?([0-9a-zA-Z ]+[0-9a-zA-Z])?[ ]?[-]?([a-zA-Z])?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?([A-Za-z0-9]+)?[ ]?"); - Scanner s = new Scanner(System.in); - String line = s.nextLine(); - Matcher matcher = pat.matcher(line); - if (!matcher.find()) continue; - - //tree - //tree taxonId - //tree scientific name - //records taxonId - //records scientific name - String command = matcher.group(1); - - if (command.equals("records")) - rangeSearch(matcher); - else if (command.equals("tree")) - printTree(matcher); - } - } - - private static void rangeSearch(Matcher matcher) { - Integer start = null; - Integer end = null; + /** + * Returns all records matching any of the children of the given TaxonID and in the + * date range given + * @param taxonId The TaxonID for which to search + * @param yearLo The lower bound on the year range + * @param yearHi The upper bound on the year range + * @return + */ + public static BasicSearchResult range(Integer taxonId, Integer yearLo, Integer yearHi){ GeneralRange<Record> a0 = RangeHelper.date(Bound.ANY); - if (matcher.group(3) != null) - if (matcher.group(3).equals("t")) { - if (matcher.group(4) != null) - start = Integer.parseInt(matcher.group(4)); - if (matcher.group(5) != null) - end = Integer.parseInt(matcher.group(5)); - Date lower = new Date(start,01,01); - Date upper = new Date(end+1,01,01); - - a0 = RangeHelper.date(Bound.LOWHIGH, lower, upper); - } - Integer taxonId = null; - try { - taxonId = Integer.parseInt(matcher.group(2)); - } catch (NumberFormatException e) { - if (taxonId == null) { - try { - taxonId = WormsAPI.nameToRecordID(matcher.group(2)); - } catch (IOException e1) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ParseException e1) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + if ((yearLo != null) && (yearHi != null)) { + Date lower = new Date(yearLo,01,01); + Date upper = new Date(yearHi+1,01,01); + a0 = RangeHelper.date(Bound.LOWHIGH, lower, upper); } GeneralRange<Record> a2 = r -> 0; @@ -86,9 +39,9 @@ public class BasicSearch { GeneralRange<Record> a1; - Stopwatch sw = new Stopwatch(); Iterable<Integer> searches = BioTree.getNonEmptyChildren(taxonId); + Stopwatch sw = new Stopwatch(); ArrayList<Record> results = new ArrayList<Record>(); for (Integer txId: searches) { a1 = RangeHelper.taxonID(Bound.EQUALS, txId); @@ -98,53 +51,8 @@ public class BasicSearch { results.addAll((Collection<? extends Record>) DataStore.records.rangeSearch(axes)); } + double time = sw.elapsedTime(); - double elapsed = sw.elapsedTime(); - - System.out.println("Found " + ((ArrayList<Record>) results).size() + " records in " + elapsed + " seconds."); - - while(true) { - System.out.println("Available commands: list, histogram, sum, exit"); - System.out.print("> "); - - Scanner s = new Scanner(System.in); - String command = s.nextLine(); - - if (command.equals("list")) - printRecords(results); - else if (command.equals("histogram")) { - Histogram.printHistogram(Histogram.histogram(results)); - } else if (command.equals("exit")) - return; - else if (command.equals("sum")) { - int sum = Histogram.sum(results); - System.out.println(sum); - } - } - } - - private static void printRecords(Iterable<Record> results) { - String format = "|%1$-45s|%2$-15s|%3$-15s|%4$-15s|%5$-15s|%6$-15s\n"; - System.out.format(format, "Scientific Name", "IndividualCount", "Latitude", "Longitude","Year","Month","Day"); - for (Record r: results) { - System.out.println(r); - } - } - - private static void printTree(Matcher matcher) { - Integer taxonId; - String name; - if (matcher.group(2) == null) - BioTree.printTree(); - else { - name = matcher.group(2); - try { - taxonId = Integer.parseInt(name); - BioTree.printTree(taxonId); - } catch (Exception e) { - BioTree.printTree(name); - } - } - System.out.println(); + return new BasicSearchResult(results, time); } } diff --git a/src/search/BasicSearchResult.java b/src/search/BasicSearchResult.java new file mode 100644 index 0000000000000000000000000000000000000000..c32548625c5495301b84a63c670785c47a91ca17 --- /dev/null +++ b/src/search/BasicSearchResult.java @@ -0,0 +1,44 @@ +package search; + +import java.util.ArrayList; + +import data.Record; + +public class BasicSearchResult { + private ArrayList<Record> results; + private final double time; + private BST<Integer, Integer> histogram; + private Integer sum; + + public BasicSearchResult(ArrayList<Record> results, double time) { + this.results = results; + this.time = time; + } + + public Iterable<Record> results() { + return (Iterable<Record>) results; + } + + public int n() { + return results.size(); + } + + public double time() { + return time; + } + + public BST<Integer, Integer> histogram() { + if (this.histogram == null) + this.histogram = Histogram.histogram(results()); + return histogram; + } + + public int sum() { + if (sum == null) { + sum = 0; + for (Record r: results()) + sum += r.getCount(); + } + return this.sum; + } +} diff --git a/src/search/Histogram.java b/src/search/Histogram.java index 3e8ef105d2187c466f6dc3cf167c22ce6f742a71..f514a9866df93ea9c28b65cc47186fa899121faa 100644 --- a/src/search/Histogram.java +++ b/src/search/Histogram.java @@ -27,35 +27,7 @@ public class Histogram { tree.put(year, rec.getCount()); } return tree; - } - - /** - * Prints a histogram based on a BST of records - * - * @param record -An BST of records - */ - public static void printHistogram(BST<Integer,Integer> record) { - int max = 0; - int scale = 100; - Iterable<Integer> results = record.keys(); - for (Integer year: results) { - if (max < record.get(year)) max =record.get(year); - - } - System.out.println(" |" + (new String(new char[scale]).replace('\0', '-')) + "|"); - String format = "%1$-5d|%2$-" + (scale + 1) + "s"; - for (Integer year: results) { - String s = "="; - int loopc = (int) ((float)(record.get(year)/ (float) max) * scale); - for (int j=0; j< loopc; j++) { - s+="="; - } - System.out.format(format, year, s); - System.out.println("| " + record.get(year)); - } - System.out.format("Scale: one = is %d individuals.\n", max / scale); - } - + } public static int sum(Iterable<Record> records) { int sum = 0;