/home/wpollock1/public_html/restricted/Java1/Histogram.java
/* A Java non-GUI program that displays a histogram. This program
* can be used to show how many students answered each question
* incorrectly on an exam of 25 questions. Note the array is
* declared with a size of 25+1; this is so I can use indexes
* of 1..25 instead of 0..24. Also note the way I printed
* either one or two leading spaces, so the output would line up.
*
* To create a runnable jar: jar -cfe Histogram.jar Histogram Histogram.class
* (Note there's no trivial way to include utils.jar in Histogram.jar!)
*
* Written 2000 Wayne Pollock, Tampa, FL USA.
* Modified 2006 to include Scanner and other features.
* Modified 2020 some minor refactoring done.
* TODO: Detect if stdin or stdout is redirected using System.console;
* if so, don't print a prompt else print one.
*/
import java.util.*;
import utils.*;
class Histogram {
private static final int NUM_QUESTIONS = 25;
public static void main ( String [] args ) {
int[] questionFreq = collectFrequencyData();
System.out.println( "\n\t Histogram showing how many students" );
System.out.println( "\t answered each question wrong:\n\n" );
System.out.print( generateHistogram( questionFreq ) );
}
/** Reads data points (numbers 1..24) from standard input and
* calulates the frequency of each one.
* @returns the frequency data
*/
private static int[] collectFrequencyData () {
int[] question = new int[ NUM_QUESTIONS + 1 ]; // Use indexes 1..25
Scanner in = new Scanner( System.in );
System.err.println( "Enter integers <= " + NUM_QUESTIONS
+ ", one per line, hit the EOF char when done:" );
for ( ; ; ) {
// System.out.print( "==> " ); // Prints a prompt
try {
int num = in.nextInt();
if ( num < 1 || num > NUM_QUESTIONS ) {
System.err.println( "### Numbers must be between 1 and "
+ NUM_QUESTIONS + "!" );
continue;
}
++question[num]; // Increment the "num-th" counter.
}
catch ( InputMismatchException ime ) {
System.err.println( "### Please enter whole numbers only!" );
in.nextLine(); // Throw away the rest of the (bad) input.
continue;
}
catch ( Exception e ) {
break;
}
}
return question;
}
/** Generates a horizontal non-GUI bar chart (a histogram) from the
* frequency data passed in.
* @param data counts for each data point (the array index is the data point)
* @returns the historgram
*/
private static String generateHistogram( int[] data ) {
// Calculate max amount of padding needed:
int padLength = Integer.toString( NUM_QUESTIONS ).length();
StringBuilder histogram = new StringBuilder();
for ( int i = 1; i < data.length; ++i ) {
histogram.append( TextKit.pad(i, padLength) + ": "
+ TextKit.lineOfStars(data[i]) + "\n" );
}
return histogram.toString();
}
}