QuizCreator: Whats the best way to safe Questions and Answers? [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want to code a QuizCreator, but I don't really know how I should save the Questions and Answers. Would it be better to save them in one file or separate them into two files?
Also, how could I display the questions and then check if the answers are correct?
I am new to programming, I would greatly appreciate any advice you have.

I would store them in a single file, and I'd use a file format like JSON. The file would look something like this:
[
{ "question": "What is your favorite color?",
"answers": [
{ "correct": true, "Blue" },
{ "correct": false, "Red" },
{ "correct": false, "Green" }
]
},
{ "question": "What is the airspeed of an unladed swallow?",
"answers": [
{ "correct": true, "I don't know that" },
{ "correct": true, "42 mph" },
{ "correct": false, "10 kmh" }
]
}
]
Then you can use a JSON parsing tool like GSON to parse the file for you. You'll have to read the file in, but you'll be able to find tons of examples of how to use GSON.
That's what I would do. Of course, you might want to use a format that's easier for you to parse.
Q: question 1
FA: 1
FA: 2
TA: 3
Q: question 2
...
Then you can just split the line at the : and see if it starts with Q (and new question) or FA/TA (false or true answers) assuming you're doing multiple choice.
You'll need to know how to open and read the contents of a file. If you use GSON, you'll spend some time learning how to use it. Otherwise you can read lines of the file at a time and parse them into your data structure yourself.
This is a pretty good practice program to write.

In my opinion... keep it simple, keep it all in a single Text file regardless of what format you decide to use. One text file per Quiz. This way you can always re-use these files. As a matter of fact, have everything related to a particular quiz in that one particular file. Let the file do the work for you.
For some file examples, one quiz might be a Math Quiz, another Quiz might be on History, and yet another Quiz on Sciences. The rules for each quiz should be displayed to the student before any test starts. These Rules should be contained within each Quiz File so that all your code needs to do is acquire these rules from the Quiz File being run and display them to the Student before the quiz begins. Allow the Student to start the Quiz when ready (after reading the rules).
An Example Math Quiz File (MathTest001.txt):
; QUIZ FILE - For the TimedQuestions class.
; The Quiz Message (optional) - This information is displayed to the User within
; a dialog box before the test begins.
; Quiz Message lines always begin with a Colon (:).
; As you can see below, basic HTML can be used to make the dialog message.
; This can add some pizzaz to your Quiz Message.
; ONLY EVER supply one Quiz Message in any Quiz File! Feel free to copy/paste
; the below message from Quiz File to Quiz File.
; Message Tags (if you decide to use them) are optional and are filled by the
; application:
;
; %flc Number of Quiz Questions in file.
; %sft Number of seconds to answer each Question
:<html>Within this Test there are <font color=blue><b>%flc</b></font> multiple choice questions that need<br>
:to be answered.<br><br>You will have <font color=blue><b>%sft</b></font> seconds to answer each test question
:unless<br>otherwise indicated above the question.<br><br>If a question runs out of time before it is answered
:then that<br>question will be considered as <font color=red><b>WRONG</b></font>.<br><br>
:<center>Press the <b>OK</b> button to start the Test</center><br><br></html>
; As a matter of fact, the above message is default and the lines above
; merely show how to make your own.
; Comment Lines always begin with a semicolon (;) and can go anywhere
; providing they are on their own line.
; Comment and Blank lines are always ignored within a Quiz File.
; MATH QUIZ QUESTIONS:
; The \n in Question Lines forces a CarriageReturn/Linefeed in Console. Format the
; questions as you see fit.
; Question & Multiple Choice Options | Correct Answer | Seconds To Answer Question
1: What is: 1 + 1 = ?\n a: 1 b: 2 c: 3 d: 4\n|b|10
2: What is: 5 + 5 = ?\n a: 1 b: 12 c: 10 d: 15\n|c|20
3: What is: 6 + 4 = ?\n a: 10 b: 11 c: 12 d: 13\n|a
4: What is: 2 + 3 = ?\n a: 3 b: 4 c: 5 d: 6\n|c|10
5: What is: 4 + 3 = ?\n a: 7 b: 6 c: 5 d: 8\n|a|10
An Example History Quiz File (HistoryTest001.txt):
; HISTORY QUIZ QUESTIONS:
; The \n in Question Lines forces a Carraige Return/Linefeed in Console.
; Question & Multiple Choice Options | Correct Answer | Seconds To Answer Question
1: Two of Henry VIII's six wives were executed. Anne Boleyn was one. Who was the second?\n a: Katherine Parr b: Jane Seymour c: Catherine Howard d: Lady Jane Grey\n|c|10
2: Who had his head chopped off in 1649?\n a: James I b: James II c: Charles I d: Charles II\n|c|10
3: When was William Shakespeare born?\n a: 1554 b: 1564 c: 1574 d: 1584\n|b
4: The Merry Wives of ...?\n a: Wandsworth b: Wycombe c: Walberswick d: Windsor\n|d|10
5: Approximately how long ago was Stonehenge built?\n a: 10,000 years b: 7,000 years c: 5,000 years d: 3,000 years\n|c|10
An Example Science Quiz File (ScienceTest001.txt):
; SCIENCE QUIZ QUESTIONS:
; The \n in Question Lines forces a Carraige Return/Linefeed in Console.
; Question & Multiple Choice Options | Correct Answer | Seconds To Answer Question
1: What was the Manhattan Project?\n a: Golf Ball Invention b: First US Satelite c: The development of the Atomic Bomb d: New York Housing Project\n|c|10
2: At what speed does light travel?\n a: 12,000 miles per second b: 186,000 feet per second c: 186,000 miles per second d: 186,000 meters per second\n|c|10
3: What is the largest moon of Saturn called?\n a: Titan b: CRT4 c: Quadra d: Sat76\n|a|12
4: The molecule DNA is described as having which shape?\n a: Sine Wave b: Elipsicle c: Tripple Spiral d: Double Helix\n|d|10
5: Percy Spencer invented which time saving kitchen appliance?\n a: Convection Oven b: The Microwave cooker c: Toaster d: Refridgerator\n|b|10
You will notice that within each of the above Quiz Files there is a value supplied for each question which relates to the number of seconds a Student has in order to answer any one question. The code supplied below contains a mechanism that places a time limit on how long the Student has to answer the question.
And the code to utilize any one of these files as a console application:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
public class TimedQuestions {
private final String ls = System.lineSeparator(); // OS Specific Line Separator for console messages
private boolean questionAnswered = false; // Keeps track of whether a question was answered
private int questionCount = 0; // Keeps count of number of questions asked to User
private int rightAnswers = 0; // Keeps count of questions answered Correctly
private int wrongAnswers = 0; // Keeps count of questions answered Incorrectly
private final int DEFAULTSECONDSFORTIMEOUT = 10; // The default question time limit
private int secondsPerQuestion = 10; // Current set time limit for question (can change by question)
private boolean timeOut = false; // Keeps track of whether or not the question has timed out.
/* If you are going to run this class on its own
through your IDE then supply the Quiz File name
to the testFilePath variable below, for example:
private String testFilePath = "C:\\Quizes\\MathTest001.txt";
*/
private String testFilePath;
// Constructors...
//================================================
public TimedQuestions() {}
public TimedQuestions(String testFilePath, int... secondsPerQuestion) {
this.testFilePath = testFilePath;
if (secondsPerQuestion.length > 0) {
this.secondsPerQuestion = secondsPerQuestion[0];
}
}
// ================================================
public static void main(String[] args) {
/* I like to start the application this way
because I don't like the need for statics. */
new TimedQuestions().startTest(args);
}
public void startTest(String... args) {
/* Get Command Line argument (if supplied) which needs
to be the path and file name of the Quiz File. */
if (args.length > 0) {
File f = new File(args[0]);
if (!f.exists()) {
System.err.println("Quiz Error! The supplied Quiz File can not be "
+ "found!" + ls + "[" + args[0] + "]" + ls);
return;
}
this.testFilePath = args[0];
}
// Start the test...
if (testFilePath == null || testFilePath.equals("")) {
System.err.println("Error! - No Quiz File Supplied!");
return;
}
start(testFilePath);
if (questionCount == 0) { return; }
// Calculate and display score for test...
double scr = (double) ((rightAnswers/questionCount)*100);
int score = (int) Math.ceil((double)rightAnswers/(double)questionCount*100.0);
System.out.println(ls + "======================================================");
System.out.println("Out of a total of " + questionCount + " questions" + ls
+ "you got " + rightAnswers + " questions Correct and" + ls
+ "you got " + wrongAnswers + " questions Wrong." + ls
+ "Your score is " + + score + "% "
+ "which gives you a grade of '" + getLetterGrade(score) + "'.");
System.out.println("======================================================");
// Done.
}
private void start(String testFilePath) {
// Get the number of lines (questions) within the supplied Test file...
int fileLinesCount = getNumberOfQuestions(testFilePath);
if (fileLinesCount == 0) { return; }
// Get Quiz Message from file (if there is any).
String msg = getQuizMessage(testFilePath);
// Display test information to the User via a Message Box
// and allow User to start the test.
if (msg.equals("")) {
// Default Quiz Message in case there is none in file.
msg = "<html>Within this Test there are <font color=blue><b>%flc" +
"</b></font> multiple choice questions that need<br>" +
"to be answered.<br><br>" +
"You will have <font color=blue><b>%sft</b></font> " +
"seconds to answer each test question unless<br>" +
"otherwise indicated above the question.<br><br>" +
"If a question runs out of time before it is answered then that<br>" +
"question will be considered as <font color=red><b>WRONG</b></font>.<br><br>" +
"<center>Press the <b>OK</b> button to start the Test</center><br><br></html>";
}
// Replace any custom tags (%flc and %sft) for their proper values.
// The %flc tag holds the total number of questions within the test file.
// The %sft tag holds the default Seconds For Timeout.
msg = msg.replace("%flc", String.valueOf(fileLinesCount))
.replace("%sft", String.valueOf(secondsPerQuestion));
// Display test information to the User bvia a Message Box
// and allow User to start the test.
JDialog dialog = new JDialog();
dialog.setAlwaysOnTop(true);
int response = JOptionPane.showConfirmDialog (dialog, msg, "Test Information...",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
dialog.dispose();
// If anything but the OK button was selected then quit application
if (response != 0) {
System.exit(0);
}
// Open a Bufferreader to read in questions from the Test file.
try (BufferedReader fileReader = new BufferedReader(new FileReader(testFilePath))) {
// Iterate through the Test file and process one question at a time....
String testFileLine;
while ((testFileLine = fileReader.readLine()) != null) {
// Skip Blank lines, Quiz Message Lines (lines that start with a
// semicolon [;]), and Header Lines (lines that start with a Colon
// [:]).
if (testFileLine.trim().startsWith(";") ||
testFileLine.trim().startsWith(":") ||
testFileLine.trim().equals("")) {
continue;
}
// Split the file line question into specific parts.
// 1st part will be the question itself, 2nd part will be
// the answer and the 3rd part will be the number of seconds
// allowed to answer question. If the 3rd part is not supplied
// within the file line question then a default of 10 seconds
// is used as set by the defaultSecondsForTimout class global
// variable.
String[] fileQuestionParts = testFileLine.split("\\|");
String question = fileQuestionParts[0];
// Allow for newline and tab tags within text string.
question = ls + question.replaceAll("\\\\n", "\n").replaceAll("\\\\t", "\t");
//Get the question answer from file line
String questionAnswer = fileQuestionParts[1];
// If the seconds time out is provided within the question file
// line then grab it for use.
if (fileQuestionParts.length > 2) { secondsPerQuestion = Integer.parseInt(fileQuestionParts[2]); }
// otherwise use the default of 10 seconds.
else { secondsPerQuestion = DEFAULTSECONDSFORTIMEOUT; }
String answerResult;
questionCount++; // Increment the questionCount variable
questionAnswered = false; // Set the qustionAnswered variable
// Ask the retrived question to User....
answerResult = askTimedQuestion(question, secondsPerQuestion);
questionAnswered = true;
// If the User entered then quit the test.
if (answerResult.equalsIgnoreCase("quit")) { break; }
// If the Usert supplied input is the right answer then...
if (answerResult.equalsIgnoreCase(questionAnswer)) {
System.out.print(" CORRECT " + ls);
rightAnswers++; // Increment the rightAnswers variable.
}
// If the Usert supplied input is the wrong answer then...
else {
wrongAnswers++; // Increment the wrongAnswers variable.
System.out.print(" WRONG " + ls); }
}
// Close the file reader.
fileReader.close();
}
catch (IOException e) {
// Display file errors
System.out.println(ls + "ERROR! - " + e.getMessage());
}
}
private int getNumberOfQuestions(String filePath) {
int q = 0;
try (BufferedReader fileReader = new BufferedReader(new FileReader(filePath))) {
// Iterate through the Test file and gather the number
// of file lines that are actually quiz questions.
String testFileLine;
while ((testFileLine = fileReader.readLine()) != null) {
// Skip Non-Quiz Question lines...
if (testFileLine.equals("") ||
testFileLine.startsWith(";") ||
testFileLine.startsWith(":")) {
continue;
}
q++;
}
// Close the file reader.
fileReader.close();
}
catch (IOException e) {
// Display file errors
System.err.println(ls + "ERROR! - " + e.getMessage());
}
return q;
}
private String getQuizMessage(String filePath) {
String msg = "";
try (BufferedReader fileReader = new BufferedReader(new FileReader(filePath))) {
// Iterate through the Test file and the quiz message if there is one.
// Any file line that starts with a colon (:) will be added together
// to create the Quiz Message (regardless of where it is in file). Make
// your Quiz Messsage one of the very first things you place into the
// Test File.
String testFileLine;
while ((testFileLine = fileReader.readLine()) != null) {
if (testFileLine.equals("")) { continue; } // Skip any blank lines
if (testFileLine.startsWith(":")) {
msg+= testFileLine.substring(1);
}
}
// Close the file reader.
fileReader.close();
}
catch (IOException e) {
// Display file errors
System.err.println("\nERROR! - " + e.getMessage());
}
return msg;
}
// Method for asking the questions retrieved from the supplied Test file
private String askTimedQuestion(String question, int secondsPerCurrentQuestion) {
// The secondsPerCurrentQuestion parameter allows you to change
// the number of seconds for each question if seconds are
// applied to a particular question within the Test file.
// (See Test file information)
secondsPerQuestion = secondsPerCurrentQuestion;
// Establish a new Thread for perform our question timing...
#SuppressWarnings("Convert2Lambda")
Thread timerThread = new Thread(new Runnable() {
#Override
#SuppressWarnings("SleepWhileInLoop")
public void run() {
try {
// See if this thread has been interrupted. If it has then
// we stop our timer While/Loop (a gracefull Thread Stop).
while (!Thread.currentThread().isInterrupted()) {
for (int seconds = secondsPerQuestion; seconds >= 1; seconds--){
// Break out of this timer FOR loop if the question
// was answered by using Thread.interrupt().
if (questionAnswered) { Thread.currentThread().interrupt(); break;}
// Show that timer is ticking away...
System.out.print("*");
// ==========================================================
// Or you can use this...
//if (seconds < secondsForTimout) { System.out.print("-"); }
//System.out.print(seconds);
// ==========================================================
Thread.sleep(1000);
}
// If the question wasn't answered and our timer loop has
// expired then inform User that time is up and set the
// timeOut variable to true.
if (!questionAnswered) {
System.out.print("\b\b\b\Your time is up for this question!");
timeOut = true;
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
// Catch Exceptions for BufferReader()/InputStreamReader()...
try {
// Declare a BufferReader object so as to get input from User.
// We use BufferReader along with InputStreamReader(System.in)
// for this.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// Display the supplied Question from file to User...
if (questionCount > 1) {
System.out.println(ls + "------------------------------------------------------");
}
System.out.print("[" + secondsPerQuestion + " seconds]");
System.out.println(question);
// Declare User input variable & initialize to a Null String
String input = "";
// Reset the timeOut variable
timeOut = false;
// Make sure our timer thread is dead before restarting it.
//while (timerThread.isAlive()){}
// Start the Timer Thread
if (secondsPerQuestion > 0) { timerThread.start(); }
// Loop through input from the User
do {
// Wait until we have User input data to complete a readLine()
// or until our timer thread has set the timeOut variable to
// true.
while (!br.ready()) {
// If our timer thread has set the timeOut variable to
// true then let's get outta this question altogether.
// First we get out of our 'wait for input' loop...
if (secondsPerQuestion > 0 && timeOut) { break; }
}
// Then we get out of our Do/While Loop.
if (secondsPerQuestion > 0 && timeOut) { break; }
// No time-out so let's move on...
// Let's see what the User supplied for an answer.
// If just ENTER was supplied then input will contain
// a Null String and the User can still enter an answer
// until the question is timed out.
input = br.readLine();
// remove any unwanted text from System.out.print()
// that had made its way through the timer thread.
System.out.print("\b\b\b\b\b");
} while ("".equals(input));
// Stop the timer thread.
timerThread.interrupt();
return input;
}
catch (IOException ex) { return ""; }
}
// Determine & return the Letter Grade for the
// supplied integer test percentage score. This
// is a typical North American Standard (I think?).
private String getLetterGrade(int score) {
String grade = "";
if (score >= 90) { grade = "A"; }
if (score >= 80 && score <= 89) { grade = "B"; }
if (score >= 70 && score <= 79) { grade = "C"; }
if (score >= 60 && score <= 69) { grade = "D"; }
if (score >= 0 && score <= 59) { grade = "F"; }
return grade;
}
public int getSecondsPerQuestion() {
return secondsPerQuestion;
}
public void setSecondsPerQuestion(int secondsPerQuestion) {
this.secondsPerQuestion = secondsPerQuestion;
}
public String getTestFilePath() {
return testFilePath;
}
public void setTestFilePath(String testFilePath) {
this.testFilePath = testFilePath;
}
public boolean isQuestionAnswered() {
return questionAnswered;
}
public int getQuestionCount() {
return questionCount;
}
public int getRightAnswers() {
return rightAnswers;
}
public int getWrongAnswers() {
return wrongAnswers;
}
public int getDEFAULTSECONDSFORTIMEOUT() {
return DEFAULTSECONDSFORTIMEOUT;
}
}
You can use the above class on its own or add it to another project.
To use on its own within your IDE:
Create a new Project named TimedQuestions;
Create a new Java Class named TimedQuestions;
Copy/paste the above code into the new Class;
Modify the private String testFilePath; class member variable to
private String testFilePath = "Your_Quiz_path_And_File_Name";
Run the project.
To use within an existing Java Project:
Create a new Java Class named TimedQuestions within your project;
Copy/paste the above code into the new Class;
Somewhere within your project code activate the class:
TimedQuestions tq = new TimedQuestions();
tq.startTest("C:\\Quizes\\ScienceTest001.txt");

This is a very broad question and it requires an answer with some amount of opinion.
To address your first concern:
Before you being programming, you should separate the questions and answers into two separate files. One file for questions, one file for answers. Both files should be indexed 1 to N. Also, you should mark each answer to indicate which question it belongs to, and you should mark each answer with incorrect or correct.
Common file types like .txt or .csv are fine (Notepad, Excel). Database systems are good too, but they are more complex (MS SQL, MySql).
How to program the game:
Once this is done, you can use a common programming language like Java to access the question-file and access and display question by line-number. Then, you can access the answer-file and display all associated answers.
Next, you will prompt the user to make an answer-choice. Using the user's response, you will compare it against the correct answer's index. If they are the same, the user has selected correctly. If not, the user's answer is wrong. Whatever the case, you return the result of the user's decision to them.
The actual implantation of this code is pretty straightforward. You will need statements like:
read from file
read from console
write to console
if and else statements
You can find all the documentation for these statements at Java Tutorials

Joseph's answer is pretty good, and you can definitely use his suggestions to great effect. That said, another option is XML. There's a great tutorial here that breaks it down pretty nicely. I suggest you take a look at it.
You could structure your XML something like this:
<quiz>
<question type="mc">
<prompt>What color is an orange?</prompt>
<a>orange</a>
<b>blue</b>
<c>red</c>
<d>yellow</d>
<answer> a </answer>
</question>
<question type="mc">
<prompt>What color is a banana?</prompt>
<a>orange</a>
<b>blue</b>
<c>red</c>
<d>yellow</d>
<answer> d </answer>
</question>
<question type="tf">
<prompt>The sky is blue</prompt>
<a>true</a>
<b>false</b>
<answer> a </answer>
</question>
</quiz>
Of course, you could structure this however you want. But its a good way to get used to the nature of Java while also integrating a robust and customizable solution into your project.

Related

My class got deleted after i saved and closeed [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
After i saved my class while i was working on it last night, it got deleted this morning. I am sure its not corrupted since i am sure i saved it and closed it right. I already tried restore from local history. I also searched google and i found no help...
i worked hard on the class, i really don't want to code it again.ScreenShot
The other classes are fine and they have evreything from last night. its just my main...
UPDATE:
Sorry for posting this here, my bad. I was just really pissed cuz half my code got deleted. Anyways here's some real help i need... Before my code got deleted my Computer Science teacher helped me write the switch code for my main. Now that it's deleted i need some help from you guy's!!! I need my input to be able to read Chars and Int's. This is what i have so far...
public static void main(String[] args) throws InterruptedException {
do {
try {
System.out.println("Enter your birthYear");
birthYear = Integer.parseInt(input.next());
int length = String.valueOf(birthYear).length();
System.out.println(length);
if (length != 4) {
lengthTest = false;
System.out.println("Invalid Choice");
} else {
lengthTest = true;
}
test = true;
} catch (Exception e) {
System.out.println("Invalid Choice");
}
} while (test == true ^ lengthTest != false);
do {
System.out.println("Please enter a number between 1-4 \n"
+ "1 = AreaOfTriangle \n" +
"----------------------------------\n" +
"2 = HoursToDaysAndHours Calculator \n" +
"---------------------------------- \n" +
"3 = CelciusToFahrenheit Calculator \n" +
"----------------------------------\n" +
"4 = BirthdayGame \r\n" +
"----------------------------------");
try {
choice = (char)Integer.parseInt(input.next().toLowerCase());
System.out.println(choice);
switch (choice) {
case 1:
aOT.areaOfTriangle();
break;
case 2:
hTDAH.hoursToDaysAndHours();
break;
case 3:
cTF.celciusToFahrenheit();
case 4:
System.out.println("Code not implemented yet");
break;
case 'e':
repeat = false;
break;
default:
System.out.println("This part of the program has not been implemented");
break;
}
}catch (Exception e) {
System.out.println("Invalid Awnser");
}
} while (repeat == true);
}
It looks like you should setup a version control system e.g. Git. To quote Attlasian What is version control page:
Version control systems are a category of software tools that help a software team manage changes to source code over time. Version control software keeps track of every modification to the code in a special kind of database. If a mistake is made, developers can turn back the clock and compare earlier versions of the code to help fix the mistake while minimizing disruption to all team members.
Windows has a featured to get ancient version of a file i think,
https://hls.harvard.edu/dept/its/restoring-previous-versions-of-files-and-folders/
try this maybe. GL

Program is delayed in writing to a .txt file?

So, I've searched around stackoverflow for a bit, but I can't seem to find an answer to this issue.
My current homework for my CS class involves reading from a file of 5000 random numbers and doing various things with the data, like putting it into an array, seeing how many times a number occurs, and finding what the longest increasing sequence is. I've got all that done just fine.
In addition to this, I am (for myself) adding in a method that will allow me to overwrite the file and create 5000 new random numbers to make sure my code works with multiple different test cases.
The method works for the most part, however after I call it it doesn't seem to "activate" until after the rest of the program finishes. If I run it and tell it to change the numbers, I have to run it again to actually see the changed values in the program. Is there a way to fix this?
Current output showing the delay between changing the data:
Not trying to change the data here- control case.
elkshadow5$ ./CompileAndRun.sh
Create a new set of numbers? Y for yes. n
What number are you looking for? 66
66 was found 1 times.
The longest sequence is [606, 3170, 4469, 4801, 5400, 8014]
It is 6 numbers long.
The numbers should change here but they don't.
elkshadow5$ ./CompileAndRun.sh
Create a new set of numbers? Y for yes. y
What number are you looking for? 66
66 was found 1 times.
The longest sequence is [606, 3170, 4469, 4801, 5400, 8014]
It is 6 numbers long.
Now the data shows that it's changed, the run after the data should have been changed.
elkshadow5$ ./CompileAndRun.sh
Create a new set of numbers? Y for yes. n
What number are you looking for? 1
1 was found 3 times.
The longest sequence is [1155, 1501, 4121, 5383, 6000]
It is 5 numbers long.
My code:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class jeftsdHW2 {
static Scanner input = new Scanner(System.in);
public static void main(String args[]) throws Exception {
jeftsdHW2 random = new jeftsdHW2();
int[] data;
data = new int[5000];
random.readDataFromFile(data);
random.overwriteRandNums();
}
public int countingOccurrences(int find, int[] array) {
int count = 0;
for (int i : array) {
if (i == find) {
count++;
}
}
return count;
}
public int[] longestSequence(int[] array) {
int[] sequence;
return sequence;
}
public void overwriteRandNums() throws Exception {
System.out.print("Create a new set of numbers? Y for yes.\t");
String answer = input.next();
char yesOrNo = answer.charAt(0);
if (yesOrNo == 'Y' || yesOrNo == 'y') {
writeDataToFile();
}
}
public void readDataFromFile(int[] data) throws Exception {
try {
java.io.File infile = new java.io.File("5000RandomNumbers.txt");
Scanner readFile = new Scanner(infile);
for (int i = 0; i < data.length; i++) {
data[i] = readFile.nextInt();
}
readFile.close();
} catch (FileNotFoundException e) {
System.out.println("Please make sure the file \"5000RandomNumbers.txt\" is in the correct directory before trying to run this.");
System.out.println("Thank you.");
System.exit(1);
}
}
public void writeDataToFile() throws Exception {
int j;
StringBuilder theNumbers = new StringBuilder();
try {
PrintWriter writer = new PrintWriter("5000RandomNumbers.txt", "UTF-8");
for (int i = 0; i < 5000; i++) {
if (i > 1 && i % 10 == 0) {
theNumbers.append("\n");
}
j = (int) (9999 * Math.random());
if (j < 1000) {
theNumbers.append(j + "\t\t");
} else {
theNumbers.append(j + "\t");
}
}
writer.print(theNumbers);
writer.flush();
writer.close();
} catch (IOException e) {
System.out.println("error");
}
}
}
It is possible that the file has not been physically written to the disk, using flush is not enough for this, from the java documentation here:
If the intended destination of this stream is an abstraction provided by the underlying operating system, for example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to the operating system for writing; it does not guarantee that they are actually written to a physical device such as a disk drive.
Because of the HDDs read and write speed, it is advisable to depend as little as possible on HDD access.
Perhaps storing the random number strings to a list when re-running and using that would be a solution. You could even write the list to disk, but this way the implementation does not depend on the time the file is being written.
EDIT
After the OP posted more of its code it became apparent that my original answer is not relatede to the problem. Nonetheless it is sound.
The code OP posted is not enough to see when is he reading the file after writing. It seems he is writing to the file after reading, which of course is what is percieved as an error. Reading after writing should produce a program that does what you want.
Id est, this:
random.readDataFromFile(data);
random.overwriteRandNums();
Will be reflected until the next execution. This:
random.overwriteRandNums();
random.readDataFromFile(data);
Will use the updated file in the current execution.

Java! How to display the correct and incorrect answered questions after user finish answering the questions

I have a Java program that asks user questions and totals their scores. I am trying to display the correct total of answered questions at the end of the program. However, I have no idea how to, can some please help me!
Here is an example of how my code looks like l! But this is not my actual code this is from another source!
Import java.util.Scanner;
public class App
{
public static void main(String[] args) {
// The array of questions.
String questions[] = {
"Plants derive most of their dry mass from the air.",
"Aluminium is the most common metal in the Earth's crust.",
"Vitamin C has be shown to prevent colds.",
"We lose the most heat through our heads.",
"Dogs are unable to digest chocolate.",
"Apple pips contain cyanide.",
"Cholesterol is a nat
"When you're on a diet, you lose weight by oxidising fat to a gas and exhaling it.",
"Human beings are unable to sense when the oxygen level of the air is low.",
"Most of the Y chromosome is passed unchanged from father to son" };
// The array of answers. The entries correspond to the questions.
boolean answers[] = { true, true, false, false, false, true, false,
true, true, true };
// Display the opening text.
System.out.println("Answer each of the following questions with 't' (true) or 'f' (false)");
// We'll use this to get user input.
Scanner input = new Scanner(System.in);
// Add up the user's score here as we go along.
int score = 0;
// The is the index into the questions array and the answers array.
int questionNumber = 0;
// Create a blank line.
System.out.println();
// The do-while loop will keep running while questionNumber is less
// than the question array length.
do {
// Display the question
System.out.println(questions[questionNumber]);
// Display a little prompt to make it clearer that the user has to
// enter something.
System.out.print("> ");
// Get the user's answer.
String userAnswer = input.nextLine();
// Check that the user has entered t or f.
if (!userAnswer.equals("t") && !userAnswer.equals("f")) {
System.out.println("Please enter t for true or f for false.\n");
// Invalid input!
// Skip the rest of this loop iteration and ask the same question again.
continue;
}
// Check the answer.
if (userAnswer.equals("t") && answers[questionNumber] == true) {
// If the answer's t and the right answer is "true", the answer was correct.
score++;
System.out.println("correct\n");
} else if (userAnswer.equals("f") && answers[questionNumber] == false) {
// If the answer's f and the correct answer is "false", the answer was correct.
System.out.println("correct\n");
score++;
}
else {
// Wrong answer!
System.out.println("incorrect!\n");
}
// Now we can move to the next question when we go round the loop again.
questionNumber++;
} while (questionNumber < questions.length); // end of do-while.
// This isn't really necessary, but closing the Scanner prevents a warning icon in Eclipse.
input.close();
// Tell the user their score.
System.out.println("You scored: " + score);
// Rank the score! Only one of the alternatives below will execute.
// Java will check them in order from top to bottom.
if(score < 5) {
// Less than 5 -- not so good.
System.out.println("Hmmm, maybe you're the artistic type. Try the test again!");
}
else if(score < 8) {
// The score wasn't less than 5, but it IS less than 8.
System.out.println("Not bad! But have another go.");
}
else if(score <= 9) {
// The score wasn't less than 8, but it IS less than, or equal to, 9.
System.out.println("Pretty good! But no perfect. Try again!");
}
else {
// The score was more than 9 -- must be 10 because we've only got 10 questions.
System.out.println("You're a certified science genius!");
}
}
}
You can use a list and add the question nummer when the user has answered the question correctly.
Before your do-while-loop you have to add
ArrayList<Integer> correctQuestions = new ArrayList<Integer>();
Then in your do-while-loop you have to add when the answer is correct
correctQuestions.add(questionNumber);
At the end of you program (outside the do-while-loop) you can make the output like this:
System.out.println("You answered the following questions correctly");
for (int k : correctQuestions) {
System.out.println(questions[k]);
}
Simply declare a boolean array containing user answers in your class:
public boolean[] userAnswers = new boolean[questions.length]; //remove the access modifier if you want to declare the array inside main instead of the class
Now in your do-while loop, after parsing the user input, do this:
userAnswers[questionNumber] = userAnswer.equals("t");
Outside of your do-while loop (after you close the Scanner), do the following to print all the questions and the user's answer:
for (int i = 0; i < questions.length; i++) {
System.out.println("User answered \"" + userAnswers[i] + "\" on question " + (i + 1) + ": " + questions[i]);
}

Select value from arraylist based on its percentage [duplicate]

This question already has answers here:
How to pick an item by its probability?
(13 answers)
Closed 6 years ago.
I got an arraylist of objects. Each objects got 2 values, content and weight. content is just a simple string while weight decides the percentage of how often the string should be used.
If I have 2 objects in the array:
Object 1:
content: hello
weight: 20
Object 2:
content: hey
weight: 80
First objects content should be used 20% of times while the second objects content should be used 80% of all times.
How would I decide which content gets selected based on the weight?
I got the following code so far:
foreach (ContentModels cont in match_array)
{
if (match_array.Count == 1)
{
match = cont.content;
break;
}
}
which pretty much selects the first content if the arraylist only contains one object but I don't know what do to if there are more than one objects?
Alright, I wanted to take a stab at this without looking at someone else's code. Here's what I came up with.
Btw, I hope it was the Java tag that was in error and not the C# tag :D.
Here's the entire program. What follows below is an explanation of each piece
.NET Fiddle
I chose to take each element to be a portion in a ratio. Therefore, in your example, your total is 100 (20 + 80) meaning that the 20 content model should get chosen 20% of the time. If you want to constrain your content models such that their total weights add up to 100, that should be done at the time that you create them.
So here's my solution.
First the content models:
class ContentModel
{
public string Content { get; set; }
public int Weight { get; set; }
}
And then a list of test cases:
static List<ContentModel> contentOptions = new List<ContentModel>
{
new ContentModel
{
Content = "hello",
Weight = 20
},
new ContentModel
{
Content = "hey",
Weight = 80
},
new ContentModel
{
Content = "yo dawg",
Weight = 90
}
};
Given these test cases we would expect to see 'Hello' appear about 10.5% of the time (20 / (80 + 90 + 20)) * 100. And so on for the rest of the test cases.
Here's the generator that makes that happen:
Here all we're going to do is figure out what the total weight is that we're working with. Then we're going to pick a random number and go through each model asking "Is this number from this content model?" If no, then subtract that content model's weight and move to the next one until we get to a model where the selection - weight is < 0. In this case we have the model that was chosen. I hope that makes sense.
(Note: I chose to recalculate the total weight every time in case you change the source list of options. If you make that list readonly, then you could move that .Sum() call outside the while loop.)
static IEnumerable<string> GetGreetings()
{
Random generator = new Random();
while (true)
{
int totalWeight = contentOptions.Sum(x => x.Weight);
int selection = generator.Next(0, totalWeight);
foreach (ContentModel model in contentOptions)
{
if (selection - model.Weight > 0)
selection -= model.Weight;
else
{
yield return model.Content;
break;
}
}
}
}
And finally, here's the main method which will also test this whole thing:
static void Main(string[] args)
{
List<string> selectedGreetings = new List<string>();
/* This will get 1000 greetings,
* which are the Content property of the models, group them by the greeting,
* count them, and then print the count along with the greeting to the Console.
*/
GetGreetings()
.Take(1000)
.GroupBy(x => x)
.Select(x => new { Count = x.Count(), Content = x.Key })
.ToList()
.ForEach(x => Console.WriteLine("{0} : {1}", x.Content, x.Count));
Console.ReadLine();
}
Here are my results from a run through:

Unexpected outcome with System.out.println

I'm in the process of making a program using input from a text file, it only has 2 lines of text in it which is
120 (this is the time)
2 (this is changes)
My code is meant to read the user's input which converts hours to minutes, and then asks for a number of changes. If the hours entered are 02:00 which is 120 minutes and the changes entered are 2 or less then it will come back saying 'acceptable', and if not it will read 'unacceptable' however I am having a bit of trouble formulating this. If anybody could provide assistance I would appreciate it greatly!
Code to follow:
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class InputOutput {
public static void main(String[] args) throws IOException{
final Scanner S = new Scanner(System.in);
final Scanner inFile = new Scanner(new FileReader("task.txt"));
// open file and associate objects
int IOminutes = Integer.parseInt(inFile.next());
int changes = Integer.parseInt(inFile.next());
// close the input file
inFile.close();
System.out.print("Specify Time (HH:MM): ");
String givenTime = S.next();
System.out.print("Specify Changes: ");
String givenChanges = S.next();
// save the index of the colon
int colon = givenTime.indexOf(':');
// strip the hours preceding the colon then convert to int
int givenHours = Integer.parseInt(givenTime.substring(0, colon));
// strip the mins following the colon then convert to int
int givenMins = Integer.parseInt(givenTime.substring(colon + 1, givenTime.length()));
// calculate the time's total mins
int mins = (givenHours * 60) + givenMins;
// using given time
System.out.println(givenTime + " = " + mins + " minutes");
if (!givenTime.equals(IOminutes) && changes >= 3) {
System.out.println("Time: " + givenTime + ", Changes: " + givenChanges + " = unacceptable!");
} else if (givenTime.equals(IOminutes) && changes <= 2) {
System.out.println("Time: " + givenTime + ", Changes: " + givenChanges + " = acceptable!");
}
S.close();
}
}
Your inputs (file-based and user-based) look reasonable.
By the time you reach your if-elseif logic on line 40, you have the following values (all values based on the problem description in the question):
loaded from "task.txt"...
IOminutes: 120
changes: 2
user input:
givenTime="02:00"
givenChanges=2
givenHours=2
givenMins=0
mins=2*60+0 = 120
Your conversion from strings to integers looks like no problem.
Your desired outcome of "acceptable" / "unacceptable" is hard for me to understand; not what it is doing, but Why it is doing that.
I'm having trouble understanding why you have two "changes".
This would make more sense to me if you just had:
task.txt: IOminutes=120, changes=2
given: time="hh:mm"
Now compute difference (in minutes) between task.txt's IOminutes and user's given time. Let's call that difference givendiff. Then you have something like:
if givendiff > changes then unacceptable.
Examples (user input values more or less made up):
task.txt: IOminutes=120, changes=2
test 1: given time="02:00" (computed givendiff=0, so acceptable)
test 2: given time="01:50" (computed givendiff=-10, so unacceptable)
test 3: given time="02:05" (computed givendiff=5, so unacceptable)
test 3: given time="02:02" (computed givendiff=2, so acceptable)
test 3: given time="01:58" (computed givendiff=-2, so acceptable)
I would encourage you to review the original requirements and verify whether your user is supposed to be give you an extra "changes" in addition to task.txt's changes. Or if you're supposed to compute a the difference between task.txt's IOminutes and the user-entered value, and complain if that difference exceeds task.txt's changes value.
I would go further but this seems like a homework or code-challenge problem; if so, hopefully this is enough to help nudge your perspective to re-thing what "changes" means in the original requirements. Good luck.

Categories