/** * Copyright 2013 Andy Turner, The University of Leeds, UK * * Redistribution and use of this software in source and binary forms, with or * without modification is permitted. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package uk.ac.leeds.ccg.andyt.projects.geog3600.nikita; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StreamTokenizer; import java.util.Iterator; /** * A class for calculating Median Age From Grouped Data. This class was * originally developed for Nikita Dheir for an undergraduate Geography * dissertation at the University of Leeds in 2012. The class is self contained * and relies only on the core Java language. (The program does not rely on any * other libraries to run). The program inputs a file and outputs a file. */ public class MedianAgeFromGroupedData { /** * A name for exception and error handling */ private static final String className = "MedianAgeFromGroupedData"; /** * File directory from which data is read and written to. */ private File directory; /** * Creates a new instance of this class using directory. * * @param directory */ public MedianAgeFromGroupedData(File directory) { this.directory = directory; } /** * This is the main method where the program begins execution. One or no * arguments are expected. A single argument gives the file location of the * input data. Without this argument it is assumed that the program is run * from the location of the input data. The output file is written to this * location. The input data is expected in a file input.csv. * * @param args the command line arguments */ public static void main(String[] args) { // Check args File directory = null; if (args.length == 0) { //directory = new File(System.getProperty("user.dir")); directory = new File("/scratch01/Work/geog3600/Nikita/"); } else { if (args.length == 1) { directory = new File(args[0]); } } if (directory.exists() == false) { System.err.println( "Directory " + directory + " does not exist. Program exiting."); System.exit(2); } else { String inputFilename; inputFilename = "input.csv"; checkForInputFile(directory, inputFilename); } new MedianAgeFromGroupedData(directory).run(); } /** * Checks that the Look up table data file given by directory and filename * exist and exits the program in error if it does not. * * @param files_HashSet * @param directory * @param filename */ private static void checkForInputFile( File directory, String filename) { File file = new File( directory, filename); if (!file.exists()) { System.err.println( "Directory " + directory + " does not contain directory " + filename + " in " + className + ".checkForInputFile(File,String). " + "Program exiting."); System.exit(2); } } public void run() { String filename; File file; Iterator ite; // Read input.csv filename = "input.csv"; File inputFile = new File(directory, filename); filename = "output.csv"; File outputFile = new File(directory, filename); processData(inputFile, outputFile); } /** * Zone Code,Zone Name,All People, * t0-4,t5-7,t8-9,t10-14,t15,t16-17,t18-19,t20-24,t25-29,t30-44,t44-59,t60-64,t65-74,t75-84,t85-89,t90over, * Middle Case, * c0-4,c5-7,c8-9,c10-14,c15,c16-17,c18-19,c20-24,c25-29,c30-44,c44-59,c60-64,c65-74,c75-84,c85-89,c90over */ public void processData(File inputFile, File outputFile) { PrintWriter pw; pw = null; try { pw = new PrintWriter(outputFile); StreamTokenizer aStreamTokenizer = getStreamTokeniser(inputFile); String line = ""; //Skip the first line int tokenType = aStreamTokenizer.nextToken(); while (tokenType != StreamTokenizer.TT_EOL) { tokenType = aStreamTokenizer.nextToken(); } tokenType = aStreamTokenizer.nextToken(); // Write header pw.println("zoneCode,zoneName,total,age0to4,age5to7,age8to9," + "age10to14,age15,age16to17,age18to19,age20to24," + "age25to29,age30to44,age45to59,age60to64,age65to74," + "age75to84,age85to89,age90AndOver,middleCase,age0to7," + "age0to9,age0to14,age0to15,age0to17,age0to19,age0to24," + "age0to29,age0to44,age0to59,age0to64,age0to74,age0to84" + "age0to89,median"); String zoneCode; String zoneName; // 16 age class counts int age0to4; int age5to7; int age8to9; int age10to14; int age15; int age16to17; int age18to19; int age20to24; int age25to29; int age30to44; int age45to59; int age60to64; int age65to74; int age75to84; int age85to89; int age90AndOver; int middleCase; int age0to7; int age0to9; int age0to14; int age0to15; int age0to17; int age0to19; int age0to24; int age0to29; int age0to44; int age0to59; int age0to64; int age0to74; int age0to84; int age0to89; int total; int index; while (tokenType != StreamTokenizer.TT_EOF) { switch (tokenType) { case StreamTokenizer.TT_EOL: System.out.println(line); String[] fields = line.split(","); //System.out.println(fields.length); if (fields.length > 36) { int debug = 1; System.out.println(line); System.out.println(fields.length); zoneCode = fields[0]; zoneName = fields[1] + ", " + fields[2]; index = 3; } else { zoneCode = fields[0]; zoneName = fields[1]; index = 2; } int totalCheck = Integer.valueOf(fields[index]); total = 0; index++; age0to4 = Integer.valueOf(fields[index]); total += age0to4; index++; age5to7 = Integer.valueOf(fields[index]); total += age5to7; age0to7 = total; index++; age8to9 = Integer.valueOf(fields[index]); total += age8to9; age0to9 = total; index++; age10to14 = Integer.valueOf(fields[index]); total += age10to14; age0to14 = total; index++; age15 = Integer.valueOf(fields[index]); total += age15; age0to15 = total; index++; age16to17 = Integer.valueOf(fields[index]); total += age16to17; age0to17 = total; index++; age18to19 = Integer.valueOf(fields[index]); total += age18to19; age0to19 = total; index++; age20to24 = Integer.valueOf(fields[index]); total += age20to24; age0to24 = total; index++; age25to29 = Integer.valueOf(fields[index]); total += age25to29; age0to29 = total; index++; age30to44 = Integer.valueOf(fields[index]); total += age30to44; age0to44 = total; index++; age45to59 = Integer.valueOf(fields[index]); total += age45to59; age0to59 = total; index++; age60to64 = Integer.valueOf(fields[index]); total += age60to64; age0to64 = total; index++; age65to74 = Integer.valueOf(fields[index]); total += age65to74; age0to74 = total; index++; age75to84 = Integer.valueOf(fields[index]); total += age75to84; age0to84 = total; index++; age85to89 = Integer.valueOf(fields[index]); total += age85to89; age0to89 = total; index++; age90AndOver = Integer.valueOf(fields[index]); total += age90AndOver; if (totalCheck != total) { System.out.println("totals don't match"); int debug = 1; } double median = calculateMedian(age0to4, age5to7, age8to9, age10to14, age15, age16to17, age18to19, age20to24, age25to29, age30to44, age45to59, age60to64, age65to74, age75to84, age85to89, age90AndOver, age0to7, age0to9, age0to14, age0to15, age0to17, age0to19, age0to24, age0to29, age0to44, age0to59, age0to64, age0to74, age0to84, age0to89, total); pw.println(zoneCode + ",\"" + zoneName + "\"," + total + "," + age0to4 + "," + age5to7 + "," + age8to9 + "," + age10to14 + "," + age15 + "," + age16to17 + "," + age18to19 + "," + age20to24 + "," + age25to29 + "," + age30to44 + "," + age45to59 + "," + age60to64 + "," + age65to74 + "," + age75to84 + "," + age85to89 + "," + age90AndOver + "," + (double) total / 2.0d + "," + age0to7 + "," + age0to9 + "," + age0to14 + "," + age0to15 + "," + age0to17 + "," + age0to19 + "," + age0to24 + "," + age0to29 + "," + age0to44 + "," + age0to59 + "," + age0to64 + "," + age0to74 + "," + age0to84 + "," + age0to89 + "," + median); System.out.print(", " + median); // String key = fields[0]; // String[] value = new String[4]; // value[0] = fields[2]; break; case StreamTokenizer.TT_WORD: line = aStreamTokenizer.sval; break; } tokenType = aStreamTokenizer.nextToken(); } } catch (IOException aIOException) { System.err.println(aIOException.getMessage() + " in " + this.getClass().getName() + ".readOutputAreaClassification(File)"); System.exit(2); } finally { pw.close(); } } private StreamTokenizer getStreamTokeniser(File file) { StreamTokenizer aStreamTokenizer = null; try { BufferedReader aBufferedReader = new BufferedReader( new InputStreamReader( new FileInputStream(file))); aStreamTokenizer = new StreamTokenizer(aBufferedReader); aStreamTokenizer.resetSyntax(); aStreamTokenizer.wordChars(',', ','); aStreamTokenizer.wordChars('"', '"'); aStreamTokenizer.wordChars('\'', '\''); aStreamTokenizer.wordChars('&', '&'); aStreamTokenizer.wordChars(';', ';'); aStreamTokenizer.wordChars('(', '('); aStreamTokenizer.wordChars(')', ')'); aStreamTokenizer.wordChars('0', '0'); aStreamTokenizer.wordChars('1', '1'); aStreamTokenizer.wordChars('2', '2'); aStreamTokenizer.wordChars('3', '3'); aStreamTokenizer.wordChars('4', '4'); aStreamTokenizer.wordChars('5', '5'); aStreamTokenizer.wordChars('6', '6'); aStreamTokenizer.wordChars('7', '7'); aStreamTokenizer.wordChars('8', '8'); aStreamTokenizer.wordChars('9', '9'); aStreamTokenizer.wordChars('.', '.'); aStreamTokenizer.wordChars('-', '-'); aStreamTokenizer.wordChars('+', '+'); aStreamTokenizer.wordChars('a', 'z'); aStreamTokenizer.wordChars('A', 'Z'); aStreamTokenizer.wordChars('\t', '\t'); aStreamTokenizer.wordChars(' ', ' '); aStreamTokenizer.wordChars('_', '_'); String s = "/"; char c = s.charAt(0); int c_int = (int) c; //System.out.println("s " + s + " c " + c + " c_int " + c_int) ; aStreamTokenizer.wordChars(c_int, c_int); aStreamTokenizer.eolIsSignificant(true); } catch (IOException aIOException) { System.err.println(aIOException.getMessage() + " in " + this.getClass().getName() + ".getStreamTokeniser(File)"); System.exit(2); } return aStreamTokenizer; } public double calculateMedian( int age0to4, int age5to7, int age8to9, int age10to14, int age15, int age16to17, int age18to19, int age20to24, int age25to29, int age30to44, int age45to59, int age60to64, int age65to74, int age75to84, int age85to89, int age90AndOver, int age0to7, int age0to9, int age0to14, int age0to15, int age0to17, int age0to19, int age0to24, int age0to29, int age0to44, int age0to59, int age0to64, int age0to74, int age0to84, int age0to89, int total) { double result = 0.0d; double middleCase = total / 2.0d; if (age0to89 < middleCase) { result = 85 + ((middleCase - (double) age0to89) / (double) age85to89) * 5.0d; return result; } if (age0to84 < middleCase) { result = 75 + ((middleCase - (double) age0to84) / (double) age75to84) * 10.0d; return result; } if (age0to74 < middleCase) { result = 65 + ((middleCase - (double) age0to74) / (double) age65to74) * 10.0d; return result; } if (age0to64 < middleCase) { result = 60 + ((middleCase - (double) age0to64) / (double) age60to64) * 5.0d; return result; } if (age0to59 < middleCase) { result = 45 + ((middleCase - (double) age0to59) / (double) age45to59) * 15.0d; return result; } if (age0to44 < middleCase) { result = 30 + ((middleCase - (double) age0to44) / (double) age30to44) * 15.0d; return result; } if (age0to29 < middleCase) { result = 25 + ((middleCase - (double) age0to29) / (double) age25to29) * 5.0d; return result; } if (age0to24 < middleCase) { result = 20 + ((middleCase - (double) age0to24) / (double) age20to24) * 5.0d; return result; } if (age0to19 < middleCase) { result = 18 + ((middleCase - (double) age0to19) / (double) age18to19) * 2.0d; return result; } if (age0to17 < middleCase) { result = 16 + ((middleCase - (double) age0to17) / (double) age16to17) * 2.0d; return result; } if (age0to15 < middleCase) { result = 15 + ((middleCase - (double) age0to15) / (double) age15) * 1.0d; return result; } if (age0to14 < middleCase) { result = 10 + ((middleCase - (double) age0to14) / (double) age10to14) * 5.0d; return result; } if (age0to9 < middleCase) { result = 8 + ((middleCase - (double) age0to9) / (double) age8to9) * 2.0d; return result; } if (age0to7 < middleCase) { result = 5 + ((middleCase - (double) age0to7) / (double) age5to7) * 3.0d; return result; } if (age0to4 < middleCase) { result = 0 + ((middleCase - 0.0d) / (double) age0to4) * 5.0d; return result; } result = 0 + ((middleCase - (double) total) / (double) age90AndOver) * 10.0d; return result; } }