Java: Using a timer with a quiz - java

I'm trying to implement a time limit a user has to answer a question in a quiz. Although I have found quite a bit on timmers I don't know how to piece it all together.
I want the user to have 15 seconds to answer the question. If they answer it in time, it checks if answer the answer is correct and then asks them if they want to continue to the next question.
If the user gives no response in the 15 seconds then it should say that the answer is incorrect and gives them the option to move to the next question.
Here is what I have so far.
for(int i=0; i<quiz.getQuizQuestions().size(); i++){
super.getQuestion(i);
//While timer is less than 15 seconds
getResponse(i, questionStart);
//If time has run out output "You have run out of time"
super.nextQuestion();
}
It is probably worth knowing:
super.getQuestion(i) is just printing the question being asked
getResponse() is waiting for keyboard input. if something is entered then it checks to see if the user is correct.
super.nextQuestion() asks the user is they want to move onto the next question
Thanks in advance
EDIT: It would also be amazing if it was easy to implement a counter that counted down from 15 when converting this into a GUI.

uses ExecutorService and Future to make sure we read a line or interrupt it. Code is a little longer than I expected... Let me know if something is unclear:
import java.util.concurrent.*;
import java.io.*;
public class Test {
public static void main(String[] args) throws java.io.IOException {
Question q = new Question();
System.out.println("You have 5 seconds: " + q.toString());
String userAnswer = null;
ExecutorService ex = Executors.newSingleThreadExecutor();
try {
Future<String> result = ex.submit(new GetInputLineCallable());
try {
userAnswer = result.get(5, TimeUnit.SECONDS);
if (Integer.valueOf(userAnswer) == q.getAnswer()){
System.out.println("good!");
}
else{
System.out.println("Incorrect!");
}
} catch (ExecutionException e) {
e.getCause().printStackTrace();
} catch (TimeoutException e){
System.out.println("too late!");
return;
} catch (InterruptedException e){
System.out.println("interrupted?");
e.getCause().printStackTrace();
}
} finally {
ex.shutdownNow();
}
}
}
class GetInputLineCallable implements Callable<String> {
public String call() throws IOException {
BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
String input = "";
while ("".equals(input)) {
try {
while (!inp.ready()) {
Thread.sleep(100);
}
input = inp.readLine();
} catch (InterruptedException e) {
return null;
}
}
return input;
}
}
class Question{
int p1, p2;
public Question(){
p1 = 2;
p2 = 3;
}
public String toString(){
return String.format("%d + %d = ?", p1, p2);
}
public int getAnswer(){
return p1+p2;
}
}

long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime < 15000){
if(userAnswered){
break; // if there is an answer we stop waiting
}
Thread.sleep(1000); // otherwise we wait 1 sec before checking again
}
if(userAnswered){
goToNextQuestion();
}
else {
handleTimeOut();
}

Related

Elevator: User input

I'm trying to make an application which copy an elevator operation (2 floors). But when I ask the user which floor he want to go, there are 2 differents possibilities. The first one, user enter a floor and the elevator move. The second one, after 10 secondes, still no response from user, at this point, the elevator have to close his door and turn off the light.
So my probleme is with the timeout, because I want my "while" to continue.
My main:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class TP5 {
private String floorAsk = "";
TimerTask task = new TimerTask() {
public void run() {
if (floorAsk.equals("")) {
System.out.println("No response ...");
task.cancel();
}
}
};
public boolean getInput() throws Exception {
Timer timer = new Timer();
timer.schedule(task, 10 * 1000);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
floorAsk = in.readLine();
timer.cancel();
System.out.println("Floor ask " + floorAsk);
return true;
}
/**
* main.
* #param args ceci est un String[]
*/
public static void main(String[] args) {
Controller c = new Controller();
Door p = new Door();
Light l = new Light();
Engine m = new Engine();
Button b = new CallButton();
while (true) {
Scanner sc = new Scanner(System.in);
System.out.println("What is your floor ?");
String actualFloorString = sc.nextLine();
int actualFloor = Integer.parseInt(actualFloorString);
if (actualFloor == 0 || etageAct == 1) {
System.out.println("You are at floor " + actualFloorString);
if (actualFloor != c.getShaft()) {
if (actualFloor > c.getShaft()) {
m.up();
} else if (actualFloor < c.getShaft()) {
m.down();
}
}
if (!l.isOn()) {
l.on();
}
if (!p.isOpen()) {
p.open();
}
System.out.println("Which floor do you want to go ?");
try {
(new TP5()).getInput();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("test");
} else {
System.out.println("Please enter a valid floor (0 or 1)");
}
}
}
}
I try to use this solution: Time limit for an input
but I want to go back in my "while" and I don't know how to do it or if I'm using the right way to do it.
I also have some other class, Contoleur, Lumiere, Moteur, Porte, Bouton. But I haven't code the functions yet.
Thanks for you answer
EDIT
Ok I maybe find a way, I modify my code and now I have a function which take in parameter the scanner and a String:
public static int ask(Scanner sc, String t) {
System.out.println(t);
return sc.nextInt();
}
And I was wondering that maybe it's possible to put a timeout on a function. Do you know if it's possible ?
I would suggest the use of the Timer class.
https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
After a 10 second timeout, have the timer call a method that "closes" the elevator door.
The Timer can be canceled if the user inputs a valid integer. A new timer can be created when the door opens.
Edit: I didn't see you were already using the Timer object as I was scrolled down to the main method.

How to stop waiting for user input?

I'm building a programm to ask multiplication and I want to set up a timer to force the person to give its answer in a given time :
if the person answers before the end of the timer : go next multiplication
if the timer reach its end, stop waiting user input : go next multiplication
For the moment, case 1 can be done, but 2 not, I was thinking about a way to return; from the method within like a Thread or something, bu I don't know how
So I'm facing a problem, if a Scanner is open, waiting for input, how to stop it ? I've tried putting it in a Thread and interrupt() it or using boolean as flags, but it doesn't stop the Scanner
class Multiplication extends Calcul {
Multiplication() { super((nb1, nb2) -> nb1 * nb2); }
#Override
public String toString() { return getNb1() + "*" + getNb2(); }
}
abstract class Calcul {
private int nb1, nb2;
private boolean valid;
private boolean inTime = true;
private boolean answered = false;
private BiFunction<Integer, Integer, Integer> function;
Calcul(BiFunction<Integer, Integer, Integer> f) {
this.nb1 = new Random().nextInt(11);
this.nb2 = new Random().nextInt(11);
this.function = f;
}
void start() {
Scanner sc = new Scanner(System.in);
System.out.println("What much is " + this + " ?");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (!answered) {
inTime = false;
}
}
}, 5 * 1000);
int answer = Integer.parseInt(sc.nextLine());
if (inTime) {
checkAnswer(answer);
timer.cancel();
}
}
private void checkAnswer(int answer) {
System.out.println("You said " + answer);
valid = (function.apply(nb1, nb2) == answer) && inTime;
answered = true;
}
int getNb1() { return nb1; }
int getNb2() { return nb2; }
boolean isValid() { return valid; }
public static void main(String[] args) {
List<Calcul> l = Arrays.asList(new Multiplication(), new Multiplication(), new Multiplication());
l.forEach(Calcul::start);
}
}
You can check for System.in.available() > 0 to see if there is a line to read. Only if this returns true call the sc.nextLine() to actually receive the input.
An example:
Scanner sc = new Scanner(System.in);
long sTime = System.currentTimeMillis();
while (System.currentTimeMillis() - sTime < 5000)
{
if (System.in.available() > 0)
{
System.out.println(sc.nextLine());
}
}
sc.close();
This reads from the console for 5 seconds if there is something to read and just prints it out again. Note: When actually using this you would probably throw a sleep in the loop to not hug to many system resources.
Please note that this is a can work solution: available() tends to be an unreliable method that does some estimation and can be in the wrong. I would probably not rely on it in a time-critical system, etc.
Also to further expand, this approach relies on the console to work the way most consoles work (in other words: All consoles that I know of): Only when the user enters a newline (by e.g. pressing enter) the line is actually given to System.in to process. Else available() would already return true when only one character gets typed.
have you tried to use close, you can check if the input is "" when the time is up and close it, might help;
if(scanner!=null)
{
scanner.close();
}

Relaunch a list of record in a program

I am new to Java. I am trying to create a Java Program that has the ability to retry itself when an exception occur in the program (which work fine). Now the problem I have now is in the for loop. In this code, when something went wrong in the for loop, the program itself will jump out of that loop and go to the catch method. After that if the retry is less than MAX_RETRIES, then the program will relaunch from the beginning. This is what I am struggling with. What I want is let say if there is an exception occur in the for loop when printing let say 5, I want the program to retry where the exception in the for loop occur not relaunch from the beginning. Are there ways to do it? I am struggling with this for a while and cannot seems to find a way to do it. Help and code for reference will be appreciated. This is the best way I can think of to simplify my code. In my real application, the for loop I have right now is to Iterate though a list of record from the database.
main.java
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
try {
while (retry <= MAX_RETRIES) {
//method1
//stuff code
//more code
//method2
for (int i = 0; i < 11; i++) {
System.out.println("i");
}
}
System.out.println("-----Finish Process-----");
break;
} catch (Exception e) {
e.printlnStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
I think it solve your problem
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
while (retry <= MAX_RETRIES) {
try {
//method1
//stuff code
//more code
//method2
int i=0;
while (i < 11) {
try {
System.out.println(i);
i++;
} catch (Exception e) {
e.printStackTrace();
i++;
if (i == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
retry++;
} catch (Exception e) {
e.printStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
System.out.println("-----Finish Process-----");
}
}
I have an idea that might help. I can't show any example code, but it might be possible to set up a flag/signal1 after you complete each step in executing the program. Then, when the program retries, it can automatically skip to that point in code where it last stopped.
1: I don't know what it's called in java

Having trouble using locks correctly

I thought I had a fairly decent understanding of locks and basic multi-threading concepts, but I'm royally messing something up here.
All the program is supposed to do is receive a filename for a text file and the number of threads you want to use from the user, and then count the number of "http" links in that file before returning that number to the user.
For the life of me, however, I can't get my threads to count properly. I've tried making the "count" variable an atomic integer and using the "incrementAndGet()" function, I've tried placing locks in the code where I thought they should be, and I've tried specifying the necessary functions are synchronized, all to no avail.
I've been doing the reading that I can on locks, concurrency, and whatnot, but I'm apparently doing something very wrong. Could someone explain to me where/why I need to be placing locks in my code (or how to properly use atomic integers, if that would be more effective)?
I originally had a lock for when the "count" variable was used (outside of any loops so it actually did something), but I'm receiving all kinds of numbers when I run the program.
My code looks like this:
import java.io.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Count
{
static String fname;
static int count = 0;
public static void main(String[] arg)
{
Scanner in = new Scanner(System.in);
int numthreads;
if( arg.length > 0 )
{
fname = arg[0];
numthreads = Integer.parseInt(arg[1]);
}
else
{
System.out.println("File?");
fname = in.nextLine();
System.out.println("Num threads?");
numthreads = in.nextInt();
}
RandomAccessFile raf;
try
{
raf = new RandomAccessFile(fname,"r");
Thread[] T = new Thread[numthreads];
for(int i=0;i<numthreads;++i)
{
T[i] = new Thread(new Task(i,numthreads,raf));
T[i].start();
}
for(Thread t : T)
{
try
{
t.join();
}
catch (InterruptedException e)
{
System.out.println("Thread join failed!");
e.printStackTrace();
System.exit(0);
}
}
System.out.println("The total is: "+count);
}
catch(IOException e)
{
System.out.println("Could not read file");
}
}
}
class Task implements Runnable
{
int myid;
int totaltasks;
RandomAccessFile raf;
ReentrantLock L = new ReentrantLock();
public Task(int myid, int totaltasks, RandomAccessFile raf)
{
this.myid=myid;
this.totaltasks=totaltasks;
this.raf = raf;
}
#Override
public void run()
{
try
{
long filesize = raf.length(); //length of the entire file
long sz = filesize / totaltasks; //length of entire file divided by number of threads gives thread size
long start = myid*sz; // thread's number * size of thread. How we find start of thread in the file
raf.seek(start);
if(start != 0 )
{
raf.readLine();
}
while(raf.getFilePointer() < (start+sz))
{
String s = raf.readLine();
Scanner sc = new Scanner(s);
while(sc.hasNext())
{
String w = sc.next();
if( w.startsWith("http://"))
{
Count.count++;
}
}
}
}
catch(IOException e)
{
System.out.println("IO error!");
}
}
}
If there's bigger issues at work here than me needing to use locks in the proper places, please let me know and I'll at least have something to work with, but as far as I'm aware it should just be a matter of performing locks properly and I'm either not understanding how they work correctly or just putting them in all the wrong places.

while loop with exception handling

This is my first time using exception handling so be gentle. I have a simple blob class that accepts an ID, the id must be between 30 and 50 or else an exception is thrown.
public class Blob {
int id;
public Blob() {
}
public Blob(int id) throws Exception {
this.id = id;
if (id < 30 || id > 50)
throw new Exception ("id = " +id+ ", must be between 30 and 50 inclusive");
}
}
It should prompt the user to enter an id, and throw the exception if it's not between 30 and 50, and should continue until the user enters a valid input and then simply displays the id number.
public class BlobCreator {
public static void main(String[] args) {
int id;
Scanner scan = new Scanner(System.in);
System.out.println("Enter ID number: ");
id = scan.nextInt();
do {
try {
Blob b = new Blob(id);
}
catch (Exception e) {
System.out.println(e);
}
System.out.println("Enter a different ID: ");
id = scan.nextInt();
}
while(true);
}
System.out.println("Blob ID: " +id);
}
I think that I am using the throw and catch correctly, but my loop isn't working correctly so I think that should be a simple fix but I can't get it just right. Also is using a while loop like I have the best way for this situation or is there a better way to loop through throw and catch?
Thanks for any and all help
You should place the break; after the code is executed successfully.
do {
try {
Blob b = new Blob(id);
break;
}
catch (Exception e) {
System.out.println(e);
}
System.out.println("Enter a different ID: ");
id = scan.nextInt();
} while(true);
So each time the loop would reach the end of its body, it would break out of the loop. You only should break after the blob is created successfully. Although I dont see why you put a break anyway. The while loop can check if the entered input was valid and simply stop the loop.
I modified the while in a do-while loop... By using true the loop will run forever, unless no exception is thrown by the constructor... This makes the code more generic (if you modify the conditions of the blob-construction, you don't have to modify the condition of the while loop).
Sorry, its kind of late to the party. Hope users who endup here may find this useful.
The use of break keyword is discouraged
Here is a very simple implementation to break away after implementing a retry mechanism
This iterates over the loop for the specified number of times and also if the exception still persists, then the exception is thrown. This can be leveraged for an actual real world scenario where the resttemplate might actually result in IO/Network errors and can be retried in those cases
public class TestClass {
public static void main(String[] args) throws Exception {
try {
int c = anotherM();
System.out.println("Now the value is" + c);
} catch (Exception e) {
System.out.println("Inside" + e);
}
}
public static int anotherM() throws Exception {
int i = 4;
Exception ex = null;
while (i > 0) {
try {
System.out.println("print i" + i);
throw new IOException();
// return i;
} catch (Exception e) {
System.out.println(e);
i--;
if (i == 1) {
ex = new Exception("ttt");
}
}
}
if (ex != null) {
throw new Exception("all new");
} else {
return i;
}
}
}

Categories

Resources