Curve-O-Matic

<< Determinant | OtherProjectsTrailIndex | State Applet >>

The runnable jar file is here: CurveOMatic.jar A Mac version is here : http://www.mathorama.com/Curve-O-Matic.dmg

CurveOMatic.java

import java.awt.*;
import java.awt.event.*;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

import javax.swing.*;

@SuppressWarnings("serial")
public class CurveOMatic extends JFrame implements ActionListener
{	
	private Button openButton, curveButton, sortButton;
	private Button saveGQButton, showGQButton;
	Panel centerPanel, listPanel, titlePanel;
	JScrollPane sp;
	BarChart chart;
	ArrayList<LineItem> names;
	TextArea message;
	JTextField raw1=new JTextField();
	JTextField raw2=new JTextField();
	JTextField curve1=new JTextField();
	JTextField curve2=new JTextField();
	int r1,r2,c1,c2;
	String curveExplanation="";
	final JComponent[] inputs = new JComponent[] {
            new JLabel("Map raw score "),
            raw1,
            new JLabel("to "),
            curve1,
            new JLabel("Map raw score "),
            raw2,
            new JLabel("to "),
            curve2
	};
	public CurveOMatic(){
		super("Curve-O-Matic");
		this.setSize(800,600);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		r1=1; c1=1;
		r2=100; c2=100;
		//add buttons and such
		message = new TextArea("Tab to next score, Enter to update\nStudent File format: ID, Last, First");
		message.setPreferredSize(new Dimension (this.getWidth(),80));
		this.setLayout(new BorderLayout());
		this.add(message, BorderLayout.SOUTH);
	    openButton = new Button("Load Student File");
		openButton.addActionListener(this);
		curveButton = new Button("Set Curve");
		curveButton.addActionListener(this);
		sortButton = new Button("Sort");
		sortButton.addActionListener(this);

		saveGQButton = new Button("Save GQ File");
		saveGQButton.addActionListener(this);
		showGQButton = new Button("Show GQ File");
		showGQButton.addActionListener(this);

		Panel north = new Panel(new FlowLayout());
		north.add(openButton);
		north.add(sortButton);
		north.add(curveButton);
		north.add(showGQButton);
		north.add(saveGQButton);
		this.add(north, BorderLayout.NORTH);

		listPanel=new Panel(new GridLayout(0,1));

		names = new ArrayList<LineItem>();
		for (int i=1; i<=32;i++){
			Student s = new Student(i, " Name "+i+" ");
            LineItem item=new LineItem(s, this);
			names.add(item);
    			Panel linePanel=new Panel(new FlowLayout(FlowLayout.LEFT));   			
    			linePanel.add(item.getNameLabel());
    			linePanel.add(item.getRawScoreField());
    			linePanel.add(item.getCurveScore());
    			linePanel.setPreferredSize(new Dimension(370, 23));  			
    			listPanel.add(linePanel);
	    }
		 sp = new JScrollPane(listPanel);

		centerPanel=new Panel(new GridLayout(0,2));
		centerPanel.add(sp);
		chart = new BarChart(names);
		centerPanel.add(chart);
	    add(centerPanel, BorderLayout.CENTER);
	}
	public static void main(String[] args)
	   {
	        CurveOMatic app= new CurveOMatic();
	        app.setVisible(true);
	   }

	public void actionPerformed(ActionEvent e) {

		if (e.getSource()==openButton ){

			try{
				readFile();
			}catch(IOException ex){

			}
		}else if (e.getSource()==sortButton){
			int sortBy=sortDialog();
			if (sortBy>0){
				doSort(sortBy);
			}
		}else if (e.getSource()==curveButton){
			JOptionPane.showMessageDialog(null, inputs, "Set Curve", JOptionPane.PLAIN_MESSAGE);
			try{
			 r1=Integer.parseInt(raw1.getText());
		     r2=Integer.parseInt(raw2.getText());
		     c1=Integer.parseInt(curve1.getText());
		     c2=Integer.parseInt(curve2.getText());
			setCurve();
			chart.repaint();
			}catch( Exception exception){

			}
		}else if (e.getSource()==showGQButton){
			showGQDialog();
		}else if (e.getSource()==saveGQButton){
			saveGQDialog();
		}else { //User typed a return while changing a raw score
			for(int i=0;i<names.size();i++){
				names.get(i).updateRawScore();
			}
			setCurve();
			chart.repaint();
			//System.out.println(e.getActionCommand()+" ");

		}
	}
	private void doSort(int sortBy) {

		if (sortBy==LineItem.NamesAscending)
			Collections.sort(names);
		if (sortBy==LineItem.NamesDescending){
			Comparator<LineItem> comp = Collections.reverseOrder();
			Collections.sort(names, comp);
		}
		if (sortBy==LineItem.ScoresAsecending)
			Collections.sort(names, LineItem.ScoreComparator);
		if (sortBy==LineItem.ScoresDescending){
			Comparator<LineItem> comp = Collections.reverseOrder(LineItem.ScoreComparator);
			Collections.sort(names, comp);
		}
		listPanel=new Panel(new GridLayout(0,1));
		for (int i=0; i<names.size();i++){
			Panel linePanel=new Panel(new FlowLayout(FlowLayout.LEFT));
			linePanel.add(names.get(i).getNameLabel());
    			linePanel.add(names.get(i).getRawScoreField());
    			linePanel.add(names.get(i).getCurveScore());
    			linePanel.setPreferredSize(new Dimension(370, 23));
    			listPanel.add(linePanel);
		}
		sp = new JScrollPane(listPanel);
        remove(centerPanel);
        centerPanel=new Panel(new GridLayout(0,2));
		centerPanel.add(sp);
		setCurve();
		chart = new BarChart(names);
		centerPanel.add(chart);

	    add(centerPanel, BorderLayout.CENTER);
	    validate();
	}
	public void readFile()throws IOException{
		String path = new java.io.File(".").getCanonicalPath();
		path=System.getProperty("user.dir");
		JFileChooser chooser = new JFileChooser(path);
	      if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
	      {
	    	  	names = new ArrayList<LineItem>();
	        FileReader reader = new FileReader(chooser.getSelectedFile());
	        Scanner fileIn = new Scanner(reader);
	        listPanel=new Panel(new GridLayout(0,1));
	        while (fileIn.hasNextLine()){
	        		String line=fileIn.nextLine();
	        		String [] args=line.split(",");
	        		Student s=new Student(args);
	        		LineItem item = new LineItem(s, this);
	        		names.add(item);
	        		Panel linePanel=new Panel(new FlowLayout(FlowLayout.LEFT));
	        		linePanel.add(item.getNameLabel());
	        		linePanel.add(item.getRawScoreField());
	        		linePanel.add(item.getCurveScore());
	        		linePanel.setPreferredSize(new Dimension(370, 23));
				listPanel.add(linePanel);
	        }
	        fileIn.close();
	        sp = new JScrollPane(listPanel);
	        remove(centerPanel);
	        centerPanel=new Panel(new GridLayout(0,2));
			centerPanel.add(sp);
			setCurve();
			chart = new BarChart(names);
			centerPanel.add(chart);

		    add(centerPanel, BorderLayout.CENTER);
		    validate();
	    }
	}
	public void setCurve(){

	    if (r2-r1==0){
	    		message.append( "\nDivision by zero - Try again");
	    		return;
	    }
	    	int rise=c2-c1;
	    	int run=r2-r1;
	    	Rational slope=new Rational(rise,run);
	    	curveExplanation= "Mapping "+r1+" --> "+c1+" and "+r2+" --> "+c2+"\r\n";
	    curveExplanation+="Curve = ("+slope.toString()+")(raw - "+r2+") + "+c2;
	    	message.setText(curveExplanation);

	    	for(int i=0; i<names.size();i++){
	    		int r=names.get(i).getStudent().getRaw();
	    		int c=(int)(c2+slope.value()*(r-r2));
	    		if (r>=0){
	    			names.get(i).getStudent().setCurve(c);
	    			names.get(i).updateCurveScore();
	    		}else {
	    			names.get(i).getStudent().setCurve(-1);
	    			names.get(i).updateCurveScore();
	    		}
	    	}
	    	validate();
	}
	public int sortDialog(){

		JRadioButton na = new JRadioButton("<html><font color=black>Names, Ascending</font></html>");
	    JRadioButton nd = new JRadioButton("<html><font color=black>Names, Descending</font></html>");
	    JRadioButton sa = new JRadioButton("<html><font color=blue>Scores, Ascending</font></html>");
	    JRadioButton sd = new JRadioButton("<html><font color=blue>Scores, Descending</font></html>");
	    na.setSelected(true);
	    ButtonGroup group = new ButtonGroup();
	    group.add(na);
	    group.add(nd);
	    group.add(sa);
	    group.add(sd);
	    Object[] array = {
	            new JLabel("Sort by:"),
	            na,
	            nd,
	            sa,
	            sd
	    };
	    int res = JOptionPane.showConfirmDialog(null, array, "Select", 
                JOptionPane.OK_CANCEL_OPTION);
	    if (res ==  JOptionPane.CANCEL_OPTION) return 0;
	    if (na.isSelected()) return LineItem.NamesAscending;
	    if (nd.isSelected()) return LineItem.NamesDescending;
	    if (sa.isSelected()) return LineItem.ScoresAsecending;
	    return LineItem.ScoresDescending;
	}
	public void showGQDialog(){
		String nameMessage="The output below is in the format GQ uses to \nimport test scores by Student NAME\nRoster starts on line 3";
		nameMessage+="\nName starts on column 1,\nhas 26 characters,\nthe start column for the score is 27\nthe length of the score column is 4";
		String idMessage="The output below is in the format GQ uses to \nimport test scores by Student ID\nRoster starts on line 3";
		idMessage+="\nID starts on column 1,\nhas 10 characters,\nthe start column for the score is 11\nthe length of the score column is 4";

		JRadioButton name = new JRadioButton("<html><font color=black>Scores by NAME</font></html>");
	    JRadioButton id = new JRadioButton("<html><font color=black>Scores by ID</font></html>");
	    name.setSelected(true);
	    ButtonGroup group = new ButtonGroup();
	    group.add(name);
	    group.add(id);
	    Object[] array = {
	            new JLabel("GQ can import scores by NAME or by ID. Choose a method:"),
	            name,
	            id
	    };
	    int res = JOptionPane.showConfirmDialog(this, array, "Show GQ File", 
                JOptionPane.OK_CANCEL_OPTION);
	    if (res ==  JOptionPane.CANCEL_OPTION) return;
		if (res==JOptionPane.CLOSED_OPTION) return;

		if (name.isSelected())
			res = JOptionPane.showConfirmDialog((Component) this, nameMessage,
			        "Import scores by NAME Info", JOptionPane.DEFAULT_OPTION);
		if (id.isSelected())
			res = JOptionPane.showConfirmDialog((Component) this, idMessage,
			        "Import scores by ID Info", JOptionPane.DEFAULT_OPTION);

		setCurve();
		for (int i=0; i< names.size();i++){
			Student s = names.get(i).getStudent();
			if (name.isSelected()) 
				message.append("\r\n"+s.getGQName());
			if (id.isSelected())
				message.append("\r\n"+s.getGQID());
		}
	}
	public void saveGQDialog(){
		String nameMessage="The output below is in the format GQ uses to \nimport test scores by Student NAME\nRoster starts on line 3";
		nameMessage+="\nName starts on column 1,\nhas 26 characters,\nthe start column for the score is 27\nthe length of the score column is 4";
		String idMessage="The output below is in the format GQ uses to \nimport test scores by Student ID\nRoster starts on line 3";
		idMessage+="\nID starts on column 1,\n has 10 characters,\nthe start column for the score is 11\nthe length of the score column is 4";

		JRadioButton name = new JRadioButton("<html><font color=black>Scores by NAME</font></html>");
	    JRadioButton id = new JRadioButton("<html><font color=black>Scores by ID</font></html>");
	    name.setSelected(true);
	    ButtonGroup group = new ButtonGroup();
	    group.add(name);
	    group.add(id);
	    Object[] array = {
	            new JLabel("GQ can import scores by NAME or by ID. Choose a method:"),
	            name,
	            id
	    };
	    int res = JOptionPane.showConfirmDialog(this, array, "Show GQ File", 
                JOptionPane.OK_CANCEL_OPTION);
	    if (res ==  JOptionPane.CANCEL_OPTION) return;
		if (res==JOptionPane.CLOSED_OPTION) return;

		if (name.isSelected()){
			res = JOptionPane.showConfirmDialog((Component) this, nameMessage,
			        "Import scores by NAME Info", JOptionPane.DEFAULT_OPTION);
		}
		if (id.isSelected()){
			res = JOptionPane.showConfirmDialog((Component) this, idMessage,
			        "Import scores by ID Info", JOptionPane.DEFAULT_OPTION);
		}
		setCurve();
		String path = System.getProperty("user.dir");;
		JFileChooser chooser = new JFileChooser(path);
		if (chooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION)
		{

			try {
				PrintWriter out = new PrintWriter(chooser.getSelectedFile());
			    String line=curveExplanation;
			    out.print(line);
				for (int i=0; i< names.size();i++){
					Student s = names.get(i).getStudent();
				if (name.isSelected()) 
					line="\r\n"+s.getGQName();
				if (id.isSelected())
					line="\r\n"+s.getGQID();
				out.print(line);

				}
				out.print("\r\n");
				out.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}

BarChart.java

import java.awt.*;
import java.util.ArrayList;



@SuppressWarnings("serial")
public class BarChart extends Canvas 
{
      int[] raw;
      int[]curve;
      int scale=10;
      ArrayList<LineItem> names;
      Stats rStats,cStats;
      String message1="";
      String message2="";
      public BarChart(ArrayList<LineItem> names)
      {
    	  	super();
    	  	raw=new int[20];
    	  	curve=new int[20];
    	  	for(int i=0;i<20;i++){
    	  		raw[i]=0;
    	  	    curve[i]=0;
    	  	}
    	  	this.names=names;
    	  	message1="";
    	  	message2="";
    	  	rStats=new Stats();
      	cStats=new Stats();
      }
      public void paint(Graphics g){
    	       refresh();
    	       Color c= new Color((int)(255*Math.random()),
    	    		   (int)(255*Math.random()), 
    	    		   (int)(255*Math.random()));
    	       g.setColor(c);
    	       int x1=this.getWidth()/2;
    	       for(int i=0; i<20;i++ ){
    	    	   	  g.fillRect(x1-raw[i]*scale-10,8+20*i, raw[i]*scale, 10);//raw
    	    	   	  g.fillRect(x1+25,8+20*i, curve[i]*scale, 10);//curve
    	       }
    	       //Dimension d= this.getSize();
    	       g.setColor(Color.BLACK);
    	       g.drawString(rStats.outliers(), 20, 20);
    	       g.drawString("n="+rStats.getN(), 20, 40);
    	       g.drawString("mean="+rStats.mean(), 20, 60);
    	       g.drawString("min="+rStats.min(), 20, 80);
    	       g.drawString("Q1="+rStats.q1(), 20, 100);
    	       g.drawString("med="+rStats.med(), 20, 120);
    	       g.drawString("Q3="+rStats.q3(), 20, 140);
    	       g.drawString("max="+rStats.max(), 20, 160);
    	       g.drawString("Before curve: "+rStats.gradeCount(), 20, getHeight()-22);


    	       g.setColor(Color.blue);
    	       g.drawString("After the curve:", 20, getHeight()-182);
    	       g.drawString(cStats.outliers(), 20, getHeight()-162);
    	       g.drawString("mean="+cStats.mean(), 20, getHeight()-142);
    	       g.drawString("min="+cStats.min(), 20, getHeight()-122);
    	       g.drawString("Q1="+cStats.q1(), 20, getHeight()-102);
    	       g.drawString("med="+cStats.med(), 20, getHeight()-82);
    	       g.drawString("Q3="+cStats.q3(), 20, getHeight()-62);
    	       g.drawString("max="+cStats.max(), 20, getHeight()-42);

    	       g.drawString("After curve: "+cStats.gradeCount(), 20, getHeight()-2);

    	       //g.drawString("width = "+this.getWidth(), 20, 60);
    	       g.setColor(Color.black);
    	       for (int i=5;i<=100; i+=5){
    	    	   	g.drawString(""+i, x1, 5+4*i);
    	       }

      }
      public void refresh(){
    	  rStats=new Stats();
    	  cStats=new Stats();
    	  for(int i=0;i<20;i++){
  	  		raw[i]=0;
  	  	    curve[i]=0;
  	  	}
    	  	for(LineItem line:names){
    	  		Student n=line.getStudent();
    	  		int r=n.getRaw();

    	  		if (r>0)
    	  			rStats.add(r);
        	  	if(r>99){
        	  		raw[19]++;
        	  	} else if (r>=0){
        	  		raw[r/5]++;	
    	  		}
        	  	int c=n.getCurve();
        	  	if (c>0)
        	  		cStats.add(c);
        	  	if(c>99){
        	  		curve[19]++;
        	  	} else if (r>=0){
        	  		curve[c/5]++;	
    	  		}
    	  	}

      }
}

Student.java



public class Student implements Comparable<Student>
{
	private String id,last, first;
	private int raw, curve;
	public Student(String[] a){
		id=a[0].trim();
		last=a[1].trim();
		first=a[2].trim();
		first=first.replaceAll("/comma/", ",");
		last=last.replaceAll("/comma/", ",");
		try {
			setRaw(Integer.parseInt(a[3].trim()));
			setCurve(getRaw());
			//System.out.print(a[3]);
		}catch (Exception e){
			setRaw(-1);
			setCurve(-1);
			//System.out.print("'"+a[3]+"'");
		}

	}
	public Student(int i, String n) {
		id =""+i;
		last = n.trim();
		first="";
		setRaw(-1);
		setCurve(-1);
	}
	public String getName(){
		String result= id+" "+first+" "+last;

		return result;
	}
	public String getGQName(){
		String result = last+", "+first;
		while (result.length()<26)
			result+=" ";
		if (curve<0) {
			result+="**";
		}else{
			result+=curveString();
		}
		return result;
	}
	public String getGQID(){
		String result = id;
		while (result.length()<10)
			result+=" ";
		if (curve<0) {
			result+="**";
		}else{
			result+=curveString();
		}
		return result;
	}
	public String getLast(){
		return last;
	}
	public String getFirst(){
		return first;
	}
	public void setRaw(int raw) {
		this.raw = raw;
	}
	public int getRaw() {
		return raw;
	}
	public void setCurve(int score) {
		this.curve = score;
	}
	public int getCurve() {
		return curve;
	}
	public String curveString(){
		String result=""+curve;
		while (result.length()<3)
			result=" "+result;
		return result;
	}
	@Override
	public int compareTo(Student o) {
		String thisLast = last.toUpperCase();
		String thisFirst = first.toUpperCase();
		String otherLast = o.getLast().toUpperCase();
		String otherFirst = o.getFirst().toUpperCase();
		if (thisLast.equals(otherLast)){
			return thisFirst.compareTo(otherFirst);
		}
		return thisLast.compareTo(otherLast);
	}
}

Rational.java

public class Rational {
	private int numerator;
	private int denominator;
	public Rational(String s){
		int fBar=s.indexOf("/");
		if (fBar==-1){
			numerator=Integer.parseInt(s);
			denominator=1;			
		} else {
			numerator=Integer.parseInt(s.substring(0,fBar));
			denominator=Integer.parseInt(s.substring(fBar+1));
			simplify();
		}
	}
	public Rational(int n, int d){
		numerator=n;
		denominator=d;
		simplify();
	}
	public Rational(int n){
		numerator=n;
		denominator=1;
	}
	public Rational(){
		numerator=0;
		denominator=1;
	}
	public Rational (Rational r){
		this.numerator=r.getNumerator();
		this.denominator=r.getDenominator();
	}
	public void setNumerator(int numerator) {
		this.numerator = numerator;
	}
	public int getNumerator() {
		return numerator;
	}
	public void setDenominator(int denominator) {
		this.denominator = denominator;
	}
	public int getDenominator() {
		return denominator;
	}
	public double value(){
		return (double)(numerator)/denominator;
	}
	public String toString(){
		if (denominator ==1)
			return Integer.toString(numerator);
		return Integer.toString(numerator)+"/"+Integer.toString(denominator);
	}
	public Rational multiply(Rational other){
		int n=this.getNumerator()*other.getNumerator();
		int d=this.getDenominator()*other.getDenominator();
		Rational result=new Rational(n,d);
		return result;
	}
	public Rational add(Rational other){
		int n=this.getNumerator()*other.getDenominator()+
		      other.getNumerator()*this.getDenominator();
		int d=this.getDenominator()*other.getDenominator();
		Rational result=new Rational(n,d);
		return result;
	}

	public void simplify(){
		int p=2;
		while (p<= Math.max(numerator, denominator)){
			while(numerator%p==0 && denominator%p==0){
				numerator/=p;
				denominator/=p;	
			}
			if (p==2) p++; else p+=2;
		}
		if (denominator<0){
			denominator*=-1;
			numerator*=-1;
		}
	}
}

LineItem.java

import java.awt.Dimension;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionListener;
import java.util.Comparator;
public class LineItem implements Comparable<LineItem>
{
	private Student student;
	private TextField rawScore;
	private Label curveScore;
	private Label nameLabel;

	public final static int NamesAscending=1;
	public final static int NamesDescending=2;
	public final static int ScoresAsecending=3;
	public final static int ScoresDescending=4;

	public LineItem(Student s, ActionListener al){
		setStudent(s);
		nameLabel = new Label(s.getName());
		nameLabel.setPreferredSize(new Dimension(270, 23));
		rawScore = new TextField(3);
		if (s.getRaw()>=0)
			rawScore.setText(""+s.getRaw());
		rawScore.addActionListener(al);
		setCurveScore(new Label());
		if (s.getCurve()>=0)
			curveScore.setText(""+s.getCurve());
	}
	public void setStudent(Student name) {
		this.student = name;
	}
	public Student getStudent() {
		return student;
	}
	public void setCurveScore(Label curveScore) {
		this.curveScore = curveScore;
	}
	public Label getCurveScore() {
		return curveScore;
	}
	public TextField getRawScoreField() {
		return rawScore;
	}

	public void updateCurveScore(){
		if (student.getCurve()>=0)
			curveScore.setText(""+student.getCurve());
	}
	public void updateRawScore(){
		//make sure student records newly updated score in rawScore TextField
		try{
			student.setRaw(Integer.parseInt(rawScore.getText()));
		}catch (NumberFormatException e){
			student.setRaw(-1);
		}

	}
	public void setNameLabel(Label nameLabel) {
		this.nameLabel = nameLabel;
	}
	public Label getNameLabel() {
		return nameLabel;
	}
	@Override
	public int compareTo(LineItem other) {		
		return getStudent().compareTo(other.getStudent());		
	}
	public static Comparator<LineItem> ScoreComparator = new Comparator<LineItem>(){

		@Override
		public int compare(LineItem o1, LineItem o2) {
			int score1 = o1.getStudent().getRaw();
			int score2 = o2.getStudent().getRaw();
			return score1-score2;
		}

	};

}

Stats.java

import java.util.ArrayList;
import java.util.Collections;


public class Stats 
{
	private ArrayList<Integer> scores;
	private int n;
	private int sum;
	public Stats(){
		scores = new ArrayList<Integer>();
		n=0;
		sum=0;

	}
	public void add(int x){
		scores.add(x);
		sum+=x;
		n++;
	}
	public void add(String s){
		scores.add(Integer.parseInt(s));
	}
	public double mean() {
		if (n==0) return 0;
		return (double)(100*sum/n)/100.0;
	}
	public double med(){
		if (n==0) return 0.0;
		Collections.sort(scores);
		if (n%2==0){
			return (scores.get(n/2-1)+scores.get(n/2))/2.0;
		}
		return (scores.get(n/2));
	}
	public double q1(){
		if (n==0) return 0.0;
		Collections.sort(scores);
		if (n%4==0){
			return (scores.get(n/4-1)+scores.get(n/4))/2.0;
		}
		return (scores.get(n/4));
	}
	public double q3(){
		if (n==0) return 0.0;
		Collections.sort(scores);
		if (n%4==0){
			return (scores.get(3*n/4-1)+scores.get(3*n/4))/2.0;
		}
		return (scores.get(3*n/4));
	}
	public double min(){
		if (n==0) return 0.0;
		Collections.sort(scores);	
		return (scores.get(0));
	}
	public double max(){
		if (n==0) return 0.0;
		Collections.sort(scores);	
		return (scores.get(n-1));
	}
	public int getN() {
		// TODO Auto-generated method stub
		return n;
	}
	public String gradeCount(){
		if (n==0) return "";
		int[] g=new int[5];
		for(int i =0; i<n; i++){
			int s=scores.get(i);
			if (s<60) g[0]++;
			if (s>=60 && s<70) g[1]++;
			if (s>=70 && s<80) g[2]++;
			if (s>=80 && s<90) g[3]++;
			if (s>=90 ) g[4]++;

		}
		return g[4]+" A's, "+g[3]+" B's, "+g[2]+" C's, "+g[1]+" D's, "+g[0]+" F's";
	}
	public String outliers(){
		String result = "Outliers: ";
		double iqr=q3()-q1();
		double low=q1()-1.5*iqr;
		double high=q3()+1.5*iqr;
		for (int i=0; i<n; i++){
			int s=scores.get(i);
			if (s< low || s> high)
				result+=s+" ";
		}
		if (result.length()==10) return "No outliers";
		return result;
	}
}