Main.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;
/**
* A quiz program
*/
public class Main {
private static ArrayList<Question> questions;
private static HashMap<String, User> users;
/**
* Reads the questions
*/
private static void readQuestions(File questionsFile) throws IOException {
if (!questionsFile.exists()) questionsFile.createNewFile();
Scanner sc = new Scanner(new FileInputStream(questionsFile));
Question q;
while ((q = Question.readQuestion(sc)) != null) {
questions.add(q);
}
sc.close();
}
/**
* Reads the users
*/
private static void readUsers(File usersFile) throws IOException {
if (!usersFile.exists()) usersFile.createNewFile();
Scanner sc = new Scanner(new FileInputStream(usersFile));
User u;
while ((u = User.readUser(sc)) != null) {
users.put(u.getName(), u);
}
sc.close();
}
/**
* Saves the users
*/
private static void saveQuestions(File questionsFile) throws IOException {
PrintStream ps = new PrintStream(new FileOutputStream(questionsFile, false));
for (Question q : questions) {
q.save(ps);
}
ps.close();
}
/**
* Saves the users
*/
private static void saveUsers(File usersFile) throws IOException {
PrintStream ps = new PrintStream(new FileOutputStream(usersFile, false));
for (User u: users.values()) {
u.save(ps);
}
ps.close();
}
public static void main(String[] args) {
// get parameters
File questionsFile = new File("questions.txt");
File usersFile = new File("users.txt");
if (args.length >= 1) {
questionsFile = new File(args[0]);
}
if (args.length >= 2) {
usersFile = new File(args[1]);
}
// get databases
try {
questions = new ArrayList<Question>();
users = new HashMap<String, User>();
readQuestions(questionsFile);
readUsers(usersFile);
} catch (IOException e) {
System.err.println("Unable to access a file: " + e.getMessage());
}
// start the actual quiz
Scanner sc = new Scanner(System.in);
System.out.println("Welcome to the Quiz Program! Good Luck!");
System.out.printf("Please enter your username (for example, your name): ");
String username = sc.nextLine();
if (!users.containsKey(username)) {
users.put(username, new User(username, 0, 0));
System.out.println("Welcome, new user! An account has automatically been created for you.");
} else {
System.out.println("Welcome back, " + username + "!");
}
// ask questions
User u = users.get(username);
int answers[] = new int[questions.size()];
int nRight = 0;
for (int i = 0; i < questions.size(); ++i) {
Question q = questions.get(i);
System.out.println();
System.out.printf("Question %d:\n", i);
System.out.println(q);
int ans;
do {
System.out.printf("Your answer? (enter a number): ");
ans = sc.nextInt();
if (ans < 0 || ans > q.getAnswers().length) {
System.out.println("Invalid answer number. Please try again.");
}
} while (ans < 0 || ans > q.getAnswers().length);
if (ans == q.getCorrectAnswer()) {
q.recordCorrectAnswer();
u.recordCorrectAnswer();
++nRight;
} else {
q.recordWrongAnswer();
u.recordWrongAnswer();
}
answers[i] = ans;
}
// results!
System.out.println();
System.out.println("Thanks for your answers!");
System.out.println("Here are your results:");
for (int i = 0; i < questions.size(); ++i) {
Question q = questions.get(i);
System.out.println();
System.out.printf("Question: %s\n", q);
System.out.printf("Answer: %s\n", q.getAnswers()[q.getCorrectAnswer()]);
System.out.printf("Player Guess: %s\n", q.getAnswers()[answers[i]]);
System.out.printf("\tResult: %s\n", answers[i] == q.getCorrectAnswer() ?
"CORRECT! Great Work!" : "INCORRECT! Remember the answer for next time!");
}
// statistics
System.out.println("\nYour overall performance was:");
System.out.printf("\tRight: %d\n", nRight);
System.out.printf("\tWrong: %d\n", questions.size() - nRight);
System.out.printf("\tPct: %f\n", nRight/(double)questions.size());
System.out.println("\nYour cumulative performance is:");
System.out.printf("\tRight: %d\n", u.getnCorrect());
System.out.printf("\tWrong: %d\n", u.getnTried() - u.getnCorrect());
System.out.printf("\tPct: %f\n", u.getPercentRight());
System.out.println("\nHere are some cumulative statistics (ordered easiest to hardest):");
// Sorted by percentage right
Collections.sort(questions);
for (Question q : questions) {
System.out.println(q.getStatistics());
}
System.out.println("\nEasiest Question:");
System.out.println(questions.get(0).getStatistics());
System.out.println("Hardest Question:");
System.out.println(questions.get(questions.size()-1).getStatistics());
sc.close();
// save!
try {
saveQuestions(questionsFile);
saveUsers(usersFile);
} catch (IOException e) {
System.err.println("Unable to access a file: " + e.getMessage());
}
}
}
Question.java
import java.io.PrintStream;
import java.util.Scanner;
/** Represents a quiz question */
public class Question implements Comparable<Question> {
private String body;
private String[] answers;
private int correctAnswer;
private int nTried;
private int nCorrect;
// constructors
public Question(String body, String[] answers, int correctAnswer,
int nTried, int nCorrect) {
super();
this.body = body;
this.answers = answers;
this.correctAnswer = correctAnswer;
this.nTried = nTried;
this.nCorrect = nCorrect;
}
public Question(String body, String[] answers, int correctAnswer) {
this(body, answers, correctAnswer, 0, 0);
}
/**
* Reads a question (and creates the corresponding Question object)
* from the given Scanner.
*/
public static Question readQuestion(Scanner sc) {
if (!sc.hasNext()) return null;
String body = sc.nextLine();
int n = sc.nextInt();
sc.nextLine();
String[] answers = new String[n];
for (int i = 0; i < n; ++i) {
answers[i] = sc.nextLine();
}
int k = sc.nextInt();
int t = sc.nextInt();
int c = sc.nextInt();
sc.nextLine();
return new Question(body, answers, k, t, c);
}
/**
* Saves the question to the given PrintStream
*/
public void save(PrintStream ps) {
ps.println(body);
ps.println(answers.length);
for (int i = 0; i < answers.length; ++i) {
ps.println(answers[i]);
}
ps.println(correctAnswer);
ps.println(nTried);
ps.println(nCorrect);
}
/**
* @return the body
*/
public String getBody() {
return body;
}
/**
* @return the answers
*/
public String[] getAnswers() {
return answers;
}
/**
* @return the correctAnswer
*/
public int getCorrectAnswer() {
return correctAnswer;
}
/**
* @return the nTried
*/
public int getnTried() {
return nTried;
}
/**
* @return the nCorrect
*/
public int getnCorrect() {
return nCorrect;
}
/**
* @return percent of correct answers
*/
public double getPercentRight() {
return nTried == 0 ? 1 : nCorrect/(double)nTried;
}
/**
* Records a correct answer
*/
public void recordCorrectAnswer() {
++nCorrect;
++nTried;
}
/**
* Records a wrong answer
*/
public void recordWrongAnswer() {
++nTried;
}
/** Compares two questions based on % correct */
public int compareTo(Question q) {
// cross multiplication to avoid special cases and doubles
return -nCorrect*q.nTried + q.nCorrect*nTried;
}
/**
* Returns a string representation of this question
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(body + "\n");
sb.append("Answers:\n");
for (int i = 0; i < answers.length; ++i) {
sb.append(i + ": " + answers[i] + "\n");
}
return sb.toString();
}
/** Returns the statistics of this question as a string */
public String getStatistics() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Question: %s\n", getBody()));
sb.append(String.format("\tTimes tried: %d\n", getnTried()));
sb.append(String.format("\tTimes correct: %d\n", getnCorrect()));
sb.append(String.format("\tPercent correct: %f\n", getPercentRight()));
return sb.toString();
}
}
User.java
import java.io.PrintStream;
import java.util.Scanner;
/**
* Represents a user of the program
*/
public class User {
private String name;
private int nTried;
private int nCorrect;
public User(String name, int nTried, int nCorrect) {
super();
this.name = name;
this.nTried = nTried;
this.nCorrect = nCorrect;
}
/** Reads a user from the given Scanner */
public static User readUser(Scanner sc) {
if (!sc.hasNext()) return null;
User u = new User(sc.nextLine(), sc.nextInt(), sc.nextInt());
sc.nextLine();
return u;
}
/** Saves the user to the given PrintStream */
public void save(PrintStream ps) {
ps.println(name);
ps.println(nTried);
ps.println(nCorrect);
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the nTried
*/
public int getnTried() {
return nTried;
}
/**
* @return the nCorrect
*/
public int getnCorrect() {
return nCorrect;
}
/**
* @return the percentage of correct answers
*/
public double getPercentRight() {
return nTried == 0 ? 1 : nCorrect/(double)nTried;
}
/**
* Records a correct answer
*/
public void recordCorrectAnswer() {
++nCorrect;
++nTried;
}
/**
* Records a wrong answer
*/
public void recordWrongAnswer() {
++nTried;
}
}
This is the questions.txt:
Which of the following cannot parse a context free grammar?
4
Deterministic Finite Automaton
Nondeterministic Finite Automaton
Nondeterministic Pushdown Automaton
Turing Machine
0
2
1
What class of languages can a Nondeterministic Pushdown Automaton recognize?
3
Regular languages
Context Free Grammars
Recursively enumerable languages
1
2
1
Which of the following data structures can be used to efficiently compute and update prefix sums in O(log n) time?
4
Van Emde Boas Tree
Fenwick Tree
Quadtree
Suffix Tree
1
2
1
What is the halflife of Uranium-235?
4
700 seconds
700 minutes
700 years
700 million years
3
2
1
How many planets are there in the Solar System?
5
6
7
8
9
10
2
2
1
This is the users.txt:
John Doe
5
1
Jane Doe
5
4

New Topic/Question
Reply



MultiQuote







|