001package edu.pdx.cs410J.whitlock;
002
003import edu.pdx.cs410J.lang.Human;
004
005import java.util.ArrayList;
006import java.util.List;
007
008/**                                                                                 
009 * This class is represents a <code>Student</code>.                                 
010 */                                                                                 
011public class Student extends Human {
012
013  private final double gpa;
014  private List<String> classes;
015  private Gender gender;
016
017  enum Gender {
018    FEMALE, MALE;
019
020    public static Gender genderFromString(String gender) {
021      if (gender.equalsIgnoreCase("male")) {
022        return Gender.MALE;
023
024      } else if (gender.equalsIgnoreCase("female")) {
025        return Gender.FEMALE;
026
027      } else {
028        throw new InvalidGenderException("I don't about the " + gender + " gender");
029      }
030    }
031  }
032
033  /**
034   * Creates a new <code>Student</code>                                             
035   *                                                                                
036   * @param name                                                                    
037   *        The student's name                                                      
038   * @param classes                                                                 
039   *        The names of the classes the student is taking.  A student              
040   *        may take zero or more classes.                                          
041   * @param gpa                                                                     
042   *        The student's grade point average                                       
043   * @param gender                                                                  
044   *        The student's gender
045   */                                                                               
046  public Student(String name, List<String> classes, double gpa, Gender gender) {
047    super(name);
048
049    this.gpa = gpa;
050    this.classes = classes;
051    this.gender = gender;
052  }
053
054  /**
055   * All students say "This class is too much work"
056   */
057  @Override
058  public String says() {                                                            
059    return "This class is too much work";
060  }
061
062  /**
063   * Returns a <code>String</code> that describes this
064   * <code>Student</code>.
065   */
066  public String toString() {
067    return getName() + " has a GPA of " + gpa + " and is taking " +
068      formatNumberOfClasses() + formatClassNames() + " " + getGenderPronoun() +
069      " says \"" + says() + "\".";
070  }
071
072  private String getGenderPronoun() {
073    return (this.gender.equals(Gender.FEMALE) ? "She" : "He");
074  }
075
076  private String formatClassNames() {
077    String s = "";
078    int numberOfClasses = this.classes.size();
079    for (int i = 0; i < numberOfClasses; i++) {
080      String className = this.classes.get(i);
081      s += className;
082
083      if (i != numberOfClasses - 1) {
084        if (numberOfClasses > 2) {
085          s += ",";
086        }
087        s += " ";
088      }
089
090      if (i == numberOfClasses - 2) {
091        s += "and ";
092      }
093    }
094    return s + '.';
095  }
096
097  private String formatNumberOfClasses() {
098    int numberOfClasses = classes.size();
099
100    switch (numberOfClasses) {
101      case 0:
102        return "0 classes";
103
104      case 1:
105        return "1 class: ";
106
107      default:
108        return numberOfClasses + " classes: ";
109    }
110  }
111
112  /**
113   * Main program that parses the command line, creates a
114   * <code>Student</code>, and prints a description of the student to
115   * standard out by invoking its <code>toString</code> method.
116   */
117  public static void main(String[] args) {
118    String name = null;
119    String gender = null;
120    String gpa = null;
121    List<String> classes = new ArrayList<>();
122
123    for (String arg : args) {
124      if (name == null) {
125        name = arg;
126
127      } else if (gender == null) {
128        gender = arg;
129
130      } else if (gpa == null) {
131        gpa = arg;
132
133      } else {
134        classes.add(arg);
135      }
136    }
137
138    if (name == null) {
139      printErrorMessageAndExit("Missing command line arguments");
140
141    } else if (gender == null) {
142      printErrorMessageAndExit("Missing gender");
143
144    } else if (gpa == null) {
145      printErrorMessageAndExit("Missing GPA");
146    }
147
148    Student student = new Student(name, classes, parseGPA(gpa), parseGender(gender));
149
150    System.out.println(student);
151
152    System.exit(0);
153  }
154
155  private static Gender parseGender(String gender) {
156    try {
157      return Gender.genderFromString(gender);
158
159    } catch (InvalidGenderException ex) {
160      return printErrorMessageAndExit("Invalid Gender: " + gender);
161    }
162  }
163
164  private static double parseGPA(String gpa) {
165    try {
166      return Double.parseDouble(gpa);
167
168    } catch (NumberFormatException ex) {
169      //noinspection ConstantConditions
170      return printErrorMessageAndExit("Invalid GPA: " + gpa);
171    }
172  }
173
174  private static <T> T printErrorMessageAndExit(String message) {
175    System.err.println(message);
176    System.exit(1);
177    return null;
178  }
179
180}