Unexpected outcome with System.out.println - java

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.

Related

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

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.

Java Beginner Rental Program

I'm quite new to programming. I'm trying to make a program for a bike rental service. And the issue is that there are two tariffs (1 and 2) for a specific time.
Tariff 1 : 00:00 to 07:00 and 17:00 to 24:00. (1$)
Tariff 2 : 07:00 to 17:00. (2$)
I need to use the scanner, so I write the two numbers, and it must calculate me the number of hours in tariff 1 and tariff 2, as well as the total cost. The issue is that I have no idea how to write the program so it detects how much hours are the in one tariff or another.
The program must work the following way :
Input 1
Input 2
Calculate the amount of hours in Tarif 1 and 2, and give a total.
Give the total price.
So here's the code :
import java.util.Scanner;
public class Bike {
public static void main(String[] args) {
Scanner clavier = new Scanner(System.in);
System.out.print("Give the starting hour : ");
int start = clavier.nextInt();
System.out.print("Give the ending hour : ");
int finish = clavier.nextInt();
if (start < 0 || start > 24) {
System.out.println("Hours must be within 0 and 24 !");
}
if (start == finish) {
System.out.println("Strange, you didn't take it long enough !");
}
if (start >= 24 || start > finish) {
System.out.println("Strange, the starting hour is after the end ...");
}
int total = finish - start;
if (total > 0) {
System.out.println("You have rented the bike for " + total + " hours.");
}
//This is where it becomes complicated.
if ((start >= 0 && start < 7)||(start >= 17 && start <= 23)) {
System.out.println("Amount of hours in Tariff 1 is : " + ((7 - start) +(finish - 17)));
} else {
System.out.println("Amount of hours in Tariff 2 is : "
System.out.print("Total amount to pay is : ");
System.out.println(" dollars.");
{
}
Ok, you're new to programming so I'm going to try and keep this simple. The issue here isn't syntax or some secret in java, its just missing logic. I can see from what you've written that you're either in high/middle school just starting programming or someone who has just started learning to code.
So I'm going to try and keep it simple and not give you too many hints.
You cannot have tariff 2 only in the else. I would recommend creating 2 ints, tariffOne and tariffTwo (or whatever names you like),make them = 0. Calculate them using some if statements. Then, when you have the values use them in the System.out.
This is good because you can add simply add whatever you want to the ints and you will always have their values.
The reason this question is being downvoted is because you've got all the tools to answer the question and you've just not got a grasp of the logic required, its not generally good practice to do this since it seems lazy, even if you've tried really hard.

displaying a certain output for a multi dice roller

I am very new to java and I set a goal for myself to make a dice rolling program (keeping it small). The end goal is to be able to roll a user-selected amount of dice and be able to have each die have a different amount of side if need be and I have it get the number of dice and how many sides each has. This is the code I made for it (Might be really bad, sorry if it is) :
public class Roller {
public final Random rando;
public final int faces;
public Roller(int faces) {
this.rando = new Random();
this.faces = faces;
}
public int roll() {
return 1 + rando.nextInt(faces);
}
//above code is not mine I built off what my friend wrote cause i didnt know if i still need it
public static void main(String[] args) {
Random rand = new Random();
Scanner scan = new Scanner(System.in);
System.out.print("How many dice do you want to roll?\n");
int D6 = scan.nextInt();
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < D6; i++) {
System.out.print("How many sides does die " + (i + 1) + " have?\n");
Roller dice = new Roller(scan.nextInt());
list.add(dice.roll());
}
}
}
Now I'm at the point where I want to display the ArrayList but I want to display it as
"Dice 1 rolled #
Dice 2 rolled #"
etc. and I'm lost on how to do that especially with the varying number of dice. Any help is very appreciated.
Let's assume you ran this and now have a List of values, [1, 3, 5, 2, 4] and you want to display them as you described.
In your main method, you have the list, so you could do some looping and string formatting to get your desired output. (edited to use printf() rather than String.format())
// in main...
// after list has all it's values
for (int i = 0; i < list.size(); i++) {
System.out.printf("Dice #%d rolled %d", i+1, list.get(i));
}
Note that the below statements are still valid, and can still be applied to printf(...)
To walk through it, String formatting is just a fancy way to format your strings (funny how that works out). The first %d corresponds to the first value given to format(), which is i+1. It's i+1 as opposed to plain i because otherwise you'd see "Dice #0 rolled ..." first, since you start indexing arrays and lists at 0. With the second %d in the format() call, you pass in list.get(i) which is the value in the list at the given index. This should correspond nicely to the order of the rolls.
This didn't have to be done with String formatting. I find it tends to be better and easier to read personally, but it is easily substituted with String concatenation.
//replace the print statement with this if you want
System.out.println("Dice #" + (i+1) + " rolled " + list.get(i));
It seems sloppier to me IMO, and needing to remember to leave spaces, or omit spaces between concatenated parts can be annoying.

Invalid Character Constant in Java?

Here is my code:
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.text.DecimalFormat;
/*
Medium Speed
Air 1100 feet per second
Water 4900 feet per second
Steel 16,400 feet per second
Write a program that asks the user to enter "air", "water", or "steel", and the distance that a sound wave will
travel in the medium. The program should then display the amount of time it will take.
You can calculate the amount of time it takes sound to travel in air with the following formula:
Time = Distance / 1100
You can calculate the amount of time it takes sound to travel in water with the following formula:
Time = Distance / 4900
You can calculate the amount of time it takes sound to travel in steel with the following formula:
Time = Distance / 16400
*/
public class SpeedOfSound
{
public static void main(String[] args)
{
String input;
char timeTraveled;
Scanner keyboard = new Scanner(System.in);
double distance;
double time;
double time2;
double time3;
time = (distance/ 1100);
time2 = (distance/ 4900);
time3 = (distance/ 16400);
DecimalFormat formatter = new DecimalFormat("#0.00");
System.out.println("Enter air, water, or steel: ");
input = keyboard.nextLine();
System.out.print("Enter distance: ");
distance = keyboard.nextDouble();
switch(timeTraveled)
{
case 'air':
System.out.printf("The total time traveled is " + formatter.format(time) + ".");
break;
case "water":
System.out.printf("The total time traveled is " + formatter.format(time2) + ".");
break;
case "steel":
System.out.printf("The total time traveled is " + formatter.format(time3) + "seconds.");
timeTraveled = input.charAt(0);
break;
keyboard.close();
}
} // main()
} // class SpeedOfSound
Why is case 'air': giving me the error invalid character constant twice? My professor has a different example for a different program and it's almost the same as what I'm doing but he doesn't get the error. Why do I get this error?
You've got several problems here.
First, single quotes are reserved for single characters, like 'a'. Whole strings need to be placed in double quotes.
Second, timeTraveled is never assigned anything anyway by the time you use it, so it "might" not have been initialized by the time you try to run it (and get things to compile). You probably want to use input instead.
This is to say, as long as you're using Java 7 or newer, you should write this as your switch argument:
switch(input) {
// statements to follow
}
I'm not sure what that assignment at the end of your "steel" case is meant to do, but you may want to move its logic out of the switch statement entirely.
In some programming languages, single quotes (') and double quotes (") are interchangeable. In Java (and also in C and C++), they are not.
If you want to specify a multi-character string literal, use double quotes: "air".
Additionally, it is not clear what do expect to happen when you compare a char (timeTraveled) to a string ("air").
I dont understand the logic of this program. If U need to enter the word and then do something depending on it try to make something like
String timeTraveled;
if (timeTraveled.equals("air")){
//do something
} else if (timeTraveled.equals("water")) {
//do something
} ...
I found multiple issue in your code:
It should be "air" not 'air' (solution for your op).
Datatype of timeTraveled is char but you are trying to match it with String (like "air", "water", etc.).
timeTraveled is not initialized.
distance is not initialized while doing calculation for time, time1 & time2.
keyboard.close(); is unreachable code. Move it outside the switch block or add it in default case.
Ideally, you should be using chars in your switch case or create enum for better clarity.
#justaregularguy - You are getting this error because you have taken air as a character.
mention air as String and you will be fine.
This will help you to - in case you will try non permitted values.
"Cannot switch on a value of type Float. Only convertible int values, strings or enum variables are permitted"
'air' is using single quotes. Single quotes denote a character constant. What you're looking for is "air", a String constant.
You seem to be a new programmer. I made some improvements to your program, and I'll show you them here:
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.text.DecimalFormat;
/*
Medium Speed
Air 1100 feet per second
Water 4900 feet per second
Steel 16,400 feet per second
Write a program that asks the user to enter "air", "water", or "steel", and the distance that a sound wave will
travel in the medium. The program should then display the amount of time it will take.
You can calculate the amount of time it takes sound to travel in air with the following formula:
Time = Distance / 1100
You can calculate the amount of time it takes sound to travel in water with the following formula:
Time = Distance / 4900
You can calculate the amount of time it takes sound to travel in steel with the following formula:
Time = Distance / 16400
*/
public class SpeedOfSound {
public static void main(String[] args) {
char timeTraveled; //what is this even doing here?
Scanner scanner = new Scanner(System.in);
double time = (distance/ 1100);
double time2 = (distance/ 4900);
double time3 = (distance/ 16400);
DecimalFormat formatter = new DecimalFormat("#0.00");
System.out.println("Enter air, water, or steel: ");
String material = scanner.nextLine();
System.out.print("Enter distance: ");
double distance = scanner.nextDouble();
switch (material) {
case "air":
System.out.printf("The total time traveled is " + formatter.format(time) + ".");
break;
case "water":
System.out.printf("The total time traveled is " + formatter.format(time2) + ".");
break;
case "steel":
System.out.printf("The total time traveled is " + formatter.format(time3) + "seconds.");
timeTraveled = material.charAt(0); //what is this even doing here?
break;
}
scanner.close();
} // main()
} // class SpeedOfSound
Made the spacing and indenting more consistent
Renamed your Scanner object. "keyboard" is not an appropriate name for a Scanner object, since scanner works with not only keyboard input, but also string and file input.
I combined the declaration of your "time" variables and the definition
E.g.
double time; //a declaration of "time"
time = (distance/ 1100); //a definition of "time"
//becomes:
double time = (distance/ 1100); //a declaration AND definition of "time"
changed 'air' to "air"", also, changed the switch case variable to "material" (which used to be called "input", and is the string that holds the user's input), rather than it using timeTraveled (some miscellaneous character?)
Since your program is only going to be displaying one time of the three possibilities, why calculate all 3? I suggest you rework your algorithm as follows:
Ask the user for the material and distance they want. Set a variable "speed" equal to 1100, 4900, or 16400 depending on the user's choice of air, water or steel. Then, calculate time as distance / speed.
This saves you from repeating 3 identical System.out.println() statements, saves you from having 3 time variables (when you only need 1),

Array and Java string error: [Ljava.lang.String;#19c42c4b

I've created a program that allows a user to enter in Journal entries (up to 7 days) and then allows a person to call up one of those days after they enter in an entry. Unfortunately, this has left me with some weird string error that I'm not familiar with.
Code as follows:
public class eDiary{
public static void main (String args[]){
int[] days = new int[7];//get our days
days[0] = 1;//start with 1 and not 0
days[1] = 2;
days[2] = 3;
days[3] = 4;
days[4] = 5;
days[5] = 6;
days[6] = 7;
String [] events = new String[7];//events for the days
int i = 0;
//asks for input and counts
for(i=0; i<7; i++){
String event = Console.readString("Tell me the major event of day " + days[i] + "\n");
events[i] = event;
}
int journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
while (journal_entry != 0) {
System.out.println(events);
journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
//get r dun!
The input and output:
Tell me the major event of day 1
one
Tell me the major event of day 2
two
Tell me the major event of day 3
thre
Tell me the major event of day 4
four
Tell me the major event of day 5
five
Tell me the major event of day 6
six
Tell me the major event of day 7
seven
Enter what day you want to hear or Enter 0 to stop
1
[Ljava.lang.String;#10181f5b
Enter what day you want to hear or Enter 0 to stop
0
Howdy y'all!
Thanks a lot for the quick responses. One thing it seems to be doing now is when replacing
System.out.println(events);
with
System.out.println(events[journal_entry]);
Now gives me input such as this:
Tell me the major event of day 1
first day
Tell me the major event of day 2
second day
Tell me the major event of day 3
third day
Tell me the major event of day 4
fourth day
Tell me the major event of day 5
fifth day
Tell me the major event of day 6
sixth day
Tell me the major event of day 7
seventh day
Enter what day you want to hear or Enter 0 to stop
1//the day im asking for
second day//spitting out the next day's entry instead of the first day's entry
Enter what day you want to hear or Enter 0 to stop
0//this is me stopping it
It's not an error.
System.out.println(events);
In this line you are trying to print the array, but that statement doesn't print the array contents, it only prints the object class name followed by its hashcode.
To print the array content you have to use
System.out.println(Arrays.toString(events));
Or, if you want, loop through the array and print its values
The [Ljava.lang.String;#10181f5b stuff is what you get when you explicitly or implicitly call Object.toString() and the target object's class doesn't override toString(). In this case, the issue is that Java array types do not override toString().
If you want to output an array, use java.util.Arrays.toString(...) to convert it to a String, then output that.
But in this case, you actually need to output a specific entry, not the entire array. The fix is to change
System.out.println(events);
to
System.out.println(events[journal_entry]);
For the record, the stuff above consists of the classes internal name ("[Ljava.lang.String;") and the object's identity hashcode (in hexadecimal).
This is not a "weird error string".
The output you are getting is because:
In Java, each object has toString() method, the default is displaying the class name representation, then adding # and then the hashcode.
You should use Arrays#toString(), which is implemented this way:
3860 public static String toString(int[] a) { {
3861 if (a == null)
3862 return "null";
3863 int iMax = a.length - 1;
3864 if (iMax == -1)
3865 return "[]";
3866
3867 StringBuilder b = new StringBuilder();
3868 b.append('[');
3869 for (int i = 0; ; i++) {
3870 b.append(a[i]);
3871 if (i == iMax)
3872 return b.append(']').toString();
3873 b.append(", ");
3874 }
3875 }
This will help you to better understand arrays.
Of course you can manually loop on the array and print it:
for(String event: events) {
System.out.println(event);
}
There is nothing wrong and that's not an error message.
Instead, it's the string representation of an array. Consider this line:
System.out.println(events);
You are printing the whole array, so you get that representation -- which happens to be a bit ugly, indeed. You want to print only one element, the one corresponding to the selected day. Use:
System.out.println(events[journal_entry]);
And perform bound checks.
This is not an error. You want to print the value of variable events. [Ljava.lang.String;#10181f5b means that events is an array of type java.lang.String and 10181f5b is hashcode of this variable. What you want to println is event[i] where i is the number of a day.
In java array's are consider as object. you are printing the event array object that's not what you want.
You need to print name of the day in a week. You need to replace
System.out.println(events);
to
System.out.println(events[journal_entry]);
It won't print out the answer correctly because you just pointed System.out.println() to events which is supposed to be an array pointer and not the actual variable. You should just replace this line with
System.out.println(events[journal_entry]);
For it to make sense. Run it with the conmmand and see if it will run properly.
Thanks for all the responses! I was able to resolve the issue. Here's the code if anyone is curious:
public static void main (String args[]){
int[] days = new int[7];//get our days
days[0] = 1;//start with 1 and not 0
days[1] = 2;
days[2] = 3;
days[3] = 4;
days[4] = 5;
days[5] = 6;
days[6] = 7;
String [] events = new String[7];//events for the days
int i = 0;
//asks for input and counts
for(i=0; i<7; i++){
String event = Console.readString("Tell me the major event of day " + days[i] + "\n");
events[i] = event;
int journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");
while (journal_entry != 0) {
System.out.println("On day " + days[i = 0] + " " + events[journal_entry - 1]);
journal_entry = Console.readInt("Enter what day you want to hear or Enter 0 to stop \n");

Categories