Getting average from a random duration - java

I'm trying to print the maximum, minimum and average of the duration at the end of this code but i'm not too sure how to store the random duration in a specific array to display it after at the end. Below is the code:
public void test(){
int max;
int average;
int min;
long duration=2;
try
{ System.out.println("Bus Needs Cleaning" + "\n");
Thread.sleep(1000);
System.out.println("Bus getting cleaned");
Thread.sleep(1000);
duration = (long)(Math.random()*20);
TimeUnit.SECONDS.sleep(duration);
}
catch(InterruptedException iex)
{
}
System.out.println("Cleaner completed cleaning in" + duration + "Seconds");
System.out.println("Bus Leaves");
System.out.println("Average Waiting Time: " + average + " | Maximum: "+ max + " | Minimum" + min +"\n");
}
Any help would be much appreciated thanks!
EDIT: There are 5 buses coming in and going out and displaying different durations and they all go through the cleaning phase

please try this one. as far as I understood
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class BusRandom {
public static void main(String[] args) {
new BusRandom().test();
}
public void test() {
long max = 0;
double average = 0;
long min = Long.MAX_VALUE;
int totalBuses=5;//change accordinly
List<Long> randomList = new ArrayList<>();
long duration = 2;
try {
for (int i = 0; i <totalBuses; i++) {
System.out.println("Bus Needs Cleaning" + "\n");
Thread.sleep(1000);
System.out.println("Bus getting cleaned");
Thread.sleep(1000);
duration = (long) (Math.random() * 20);
randomList.add(duration);
TimeUnit.SECONDS.sleep(duration);
System.out.println("Cleaner completed cleaning in" + duration + "Seconds");
System.out.println("Bus Leaves");
max=max>duration?max:duration;
min=min<duration?min:duration;
}
} catch (InterruptedException iex) {
}
double sum=0;
for(long l:randomList){
sum+=l;
}
average=(double) (sum/randomList.size());
System.out.println("Average Waiting Time: " + average + " | Maximum: " + max + " | Minimum" + min + "\n");
}
}

Related

countApprox() initialValue always return the same bounds

I have a method for calculating and displaying approx number of rows in a dataframe:
public static void countApprox(String csvPath, long timeout, double confidence) {
Dataset<Row> table = spark.read().csv(csvPath);
final PartialResult<BoundedDouble> result = table.javaRDD().countApprox(timeout, confidence);
System.out.println("init mean value: " + result.initialValue().mean()); //is always 0
System.out.println("init value high: " + result.initialValue().high()); //is always infinity
System.out.println("init value low: " + result.initialValue().low()); //is always 0
new Thread(new Runnable() {
public void run() {
System.out.println("calculating final values...");
long initTime = System.currentTimeMillis();
System.out.println("final value high: " + result.getFinalValue().high());
System.out.println("final value low: " + result.getFinalValue().low());
double timeTaken = (System.currentTimeMillis() - initTime)/1000.0;
System.out.println("time taken: " + timeTaken + " second(s)");
}
}).start();
}
The problem is, no matter what parameters I provide for timeout and confidence (timeout value less than actual time taken to count), the results for initialValue low, mean and high values are always same: (0.0, 0.0, infinity).
Any help in figuring out what I'm doing wrong will be greatly appreciated.
Thanks in Advance!

Java Swing Timer getting faster and faster

I'm working on a small turn based RPG. For every turn, one of the two characters tries to hit the other character then 2000ms later, the timer restarts the attack method (to give time to the player to read the outcome of each turn). After the battle, the player goes back to the level map where he can choose to move away or initiate another battle. Here's my problem: Every time the player initiates a new battle, the Timer delay is shorter and shorter so the battle happens too fast at some point. First fight, each turn will be 2 seconds, then 1 second, then 500ms, and so on. Here's my code, what am I missing?
public void attack(Character a, Character d) {
//Calculations//////////////////////////////////////////////
///////////////////unit a (attacker)////////////////////////
Weapon aWep = (Weapon) a.inventory[0];
double aCritRate = (double) (a.skl / 2 + aWep.crit - d.lck) / 100;
double aHitRate = (double) (aWep.acc + (a.skl * 2) + (a.lck / 2)) / 100;
double aAvoidRate = (double) (a.spd * 2 + a.lck) / 100;
int aAttackPower = (a.pow + aWep.dmg);
boolean aTwice = a.spd >= d.spd + 4 ? true : false;
///////////////////unit d (defender)////////////////////////
Weapon dWep = (Weapon) d.inventory[0];
double dCritRate = (double) (d.skl / 2 + dWep.crit - a.lck) / 100;
double dHitRate = (double) (dWep.acc + (d.skl * 2) + (d.lck / 2)) / 100;
double dAvoidRate = (double) (d.spd * 2 + d.lck) / 100;
int dAttackPower = (d.pow + dWep.dmg);
boolean dTwice = d.spd >= a.spd + 4 ? true : false;
int delay = 2000;
Timer timer;
ActionListener repeat = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
switch(bturn){
case(1):attack(d,a); break;
default:break;
}
}
};
timer = new Timer(delay,repeat);
//Battle/////////////////////////
int aDmg = aAttackPower - d.def;
double aHitChance = aHitRate - dAvoidRate;
String sound;
//Turn 1
if (aHitChance >= rngs[rngsIndex]) {
if (aCritRate >= rngs[rngsIndex]) {
aDmg *= 3;
sound="crit.wav";
t.print("Critical Hit! " + a.name + " attacks " + d.name + " for " + aDmg + " damage!");
rngsIndex++;
} else {
sound="hit.wav";
t.print(a.name + " attacks " + d.name + " for " + aDmg + " damage!");
rngsIndex++;
}
d.damageHp(aDmg);
rngsIndex++;
} else {
sound = "miss.wav";
t.print(a.name + " has missed.");
rngsIndex++;
}
playSound(sound);
if (d.isDead) {
String add = t.text.getText();
add+=" " + d.name + " has been killed.";
t.print(add);
a.xp+=35;
charPane.set(a);
grid[d.x][d.y].removeMouseListener(grid[d.x][d.y].hover);
killUnit(d, grid[d.x][d.y]);
}
if (d.faction.equals("e")) {
enemPane.set(d);
} else {
charPane.set(d);
}
//Turn 2
bturn++;
if(!d.isDead && bturn==1){
System.out.println("REACHED");
timer.start();
}
else{
timer.stop();
bturn = 0;
grid[d.x][d.y].removeActionListener(grid[d.x][d.y].targetable);
clearGrid();
loop();
}
}
Try to log which instance of ActionListener repeat caused the attack. I think you will see, that the speedup is caused by having more instances of Timer and ActionListener then you want.
After each run, number of those instances doubles, hence the exponencial growth of number of turns per second.
In absence of logger:
public void actionPerformed(ActionEvent e)
{
System.out.println("" + LocalDateTime.now() + " " + this);
switch(bturn){

Multi Threading - Request input once for all variables (Java)

Below are codes and outputs for a multithreading function whereby there is a counter and functions of add, subtract, multiply and divide. I'm using Eclipse.
4 Threads for each mathematical function:
public class Maths {
public static void main(String args[]){
CalculationThread T1 = new CalculationThread("Addition");
T1.start();
CalculationThread T2 = new CalculationThread("Subtraction");
T2.start();
CalculationThread T3 = new CalculationThread("Multiplication");
T3.start();
CalculationThread T4 = new CalculationThread("Division");
T4.start();
}
}
class CalculationThread extends Thread{
private Thread t;
private String maths;
private int count = 0;
private int resultplus, resultminus, resulttimes, resultdivide = 0;
CalculationThread(String answer){
maths = answer;
}
public void start(){
System.out.println("Starting calculation of " + maths + "\n");
if(t == null){
t = new Thread (this, maths);
t.start();
}
}
Here is where the functions take place, it will use the counters as 2 numbers to perform an equation.
public void run(){
try {
for (int x=0; x<=3 ; x++){
if(maths == "Addition"){
System.out.println("Calculating: " + maths + " of " + count +
" + "+ count + " = " + resultplus + "\n");
Thread.sleep(3000);
count++;
resultplus = count + count;
}
else if(maths == "Subtraction"){
System.out.println("Calculating: " + maths + " of " + count +
" - "+ count + " = " + resultminus + "\n");
Thread.sleep(3000);
count++;
resultminus = count - count;
}
else if(maths == "Multiplication"){
System.out.println("Calculating: " + maths + " of " + count +
" * "+ count + " = " + resulttimes + "\n");
Thread.sleep(3000);
count++;
resulttimes = count * count;
}
else if(maths == "Division"){
System.out.println("Calculating: " + maths + " of " + count +
" / "+ count + " = " + resultdivide + "\n");
Thread.sleep(3000);
count++;
resultdivide = count / count;
}
}
}
catch (InterruptedException e){
System.out.println("Math function failed");
}
if(maths == "Addition"){
System.out.println("Addition completed.");
}
else if(maths == "Subtraction"){
System.out.println("Subtraction completed.");
}
else if(maths == "Multiplication"){
System.out.println("Multiplication completed.");
}
else if(maths == "Division"){
System.out.println("Division completed.");
}
}
}
The output:
Starting calculation of Addition
Starting calculation of Subtraction
Calculating: Addition of 0 + 0 = 0
Starting calculation of Multiplication
Calculating: Subtraction of 0 - 0 = 0
Starting calculation of Division
Calculating: Multiplication of 0 * 0 = 0
Calculating: Division of 0 / 0 = 0
Calculating: Subtraction of 1 - 1 = 0
Calculating: Addition of 1 + 1 = 2
Calculating: Multiplication of 1 * 1 = 1
Calculating: Division of 1 / 1 = 1
Calculating: Addition of 2 + 2 = 4
Calculating: Subtraction of 2 - 2 = 0
Calculating: Division of 2 / 2 = 1
Calculating: Multiplication of 2 * 2 = 4
Calculating: Subtraction of 3 - 3 = 0
Calculating: Addition of 3 + 3 = 6
Calculating: Division of 3 / 3 = 1
Calculating: Multiplication of 3 * 3 = 9
Subtraction completed.
Addition completed.
Division completed.
Multiplication completed.
The code above works whereby all 4 functions will be done simultaneously , but whenever I try including a JOptionPane for user input instead of an automatic counter, each of the 4 threads will request at a time. Thus its not counted as multithreading if the functions are waiting for me to input 2 numbers. How and in what way can I include a user input that only requires user to input at the beginning so that all functions can use the 2 variables.
I'm not sure if I understood it correctly.
If you just want to block the calculation threads and wait for an initial user Input you can use a Semaphore.
The UI Thread that waits for the user input shows the dialog and releases the waiting calculation threads by setting the number of permits / threads.
Here is an example how this could look like (it also uses an more object oriented approach). For simplicity, I've skipped the Multiplication and Division Tasks
import java.util.concurrent.Semaphore;
import javax.swing.JOptionPane;
public class MathSample {
// because updated / read from different threads mark as volatile
private volatile int a, b;
// semaphore with no initial permits i.e.
// the calculations will wait until permits are available.
private Semaphore available = new Semaphore(0);
private abstract class Task implements Runnable {
public abstract void doCalculation();
public abstract String getName();
#Override
public void run() {
try {
// wait until a permit becomes available
available.acquire();
// not sure what should happen here
// wait again for user input?
for (int x = 0; x < 50; ++x) {
a = a + x;
doCalculation();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(String.format("Task %s completed.", getName()));
}
}
private class AdditionTask extends Task {
public void doCalculation() {
System.out.println(String.format("Calculating: Addition of + %d + %d = %d", a, b, a+b));
}
public String getName() {
return "Addition";
}
}
private class SubstractionTask extends Task {
public void doCalculation() {
System.out.println(String.format("Calculating: Substraction of + %d - %d = %d", a, b, a-b));
}
public String getName() {
return "Substraction";
}
}
private void run() {
new Thread(new AdditionTask()).start();
new Thread(new SubstractionTask()).start();
a = Integer.parseInt(JOptionPane.showInputDialog("First value"));
b = Integer.parseInt(JOptionPane.showInputDialog("Second value"));
available.release(2); // let the 2 calculation threads run
}
public static void main(String ...args) {
new MathSample().run();
}
}
As you can see you don't have to overwrite the start method of the Thread to run a different thread.
Your start method of your CalculationThread is at least strange because you overwrite the start method of the Thread class and within that you create another Thread instance where you pass your CalculationThread as Runnable.
Easier / better:
class Calculation implements Runnable {
...
#override
public void run() {
// the name you passed to the thread is your math
// lets get it from the currently running thread where it is stored.
final String math = Thread.currentThread().getName();
...
}
}
// somewhere else
new Thread(new CalculationThread, math).start();
You can refer following codes.
Maybe it will suit your needs according to my understanding on your question. I also applied .equals() to the code according to Hovercraft Full Of Eels suggestion.
import javax.swing.JOptionPane;
public class Maths {
public static void main(String[] args) {
// TODO Auto-generated method stub
String num1 = JOptionPane.showInputDialog("Num1: ");
String num2 = JOptionPane.showInputDialog("Num2: ");
int num11 = Integer.parseInt(num1);
int num22 = Integer.parseInt(num2);
calculationThread T1 = new calculationThread("Addition");
T1.getNumber(num11, num22);
T1.start();
calculationThread T2 = new calculationThread("Subtraction");
T2.getNumber(num11, num22);
T2.start();
calculationThread T3 = new calculationThread("Multiplication");
T3.getNumber(num11, num22);
T3.start();
calculationThread T4 = new calculationThread("Division");
T4.getNumber(num11, num22);
T4.start();
}
}
class calculationThread extends Thread{
private Thread t;
private String maths;
private int a;
private int b;
private int resultplus = 0;
private int resultminus = 0;
private int resulttimes = 0;
private int resultdivide = 0;
public void getNumber(int num1, int num2){
a = num1;
b = num2;
}
calculationThread(String answer){
maths = answer;
}
public void start(){
System.out.println("Starting calculation of " + maths + "\n");
if(t == null){
t = new Thread(this, maths);
t.start();
}
}
public void run(){
try {
for (int x=0; x<=3 ; x++){
if(maths.equals("Addition")){
System.out.println("Calculating: " + maths + " of " + a +
" + "+ b + " = " + resultplus + "\n");
Thread.sleep(3000);
resultplus = a + b;
}
else if(maths.equals("Subtraction")){
System.out.println("Calculating: " + maths + " of " + a +
" - "+ b + " = " + resultminus + "\n");
Thread.sleep(3000);
resultminus = a - b;
}
else if(maths.equals("Multiplication")){
System.out.println("Calculating: " + maths + " of " + a +
" * "+ b + " = " + resulttimes + "\n");
Thread.sleep(3000);
resulttimes = a * b;
}
else if(maths.equals("Division")){
System.out.println("Calculating: " + maths + " of " + a +
" / "+ b + " = " + resultdivide + "\n");
Thread.sleep(3000);
resultdivide = a / b;
}
}
}
catch (InterruptedException e){
System.out.println("Math function failed");
}
finally{
if(maths.equals("Addition")){
System.out.println("Addition completed.");
}
else if(maths.equals("Subtraction")){
System.out.println("Subtraction completed.");
}
else if(maths.equals("Multiplication")){
System.out.println("Multiplication completed.");
}
else if(maths.equals("Division")){
System.out.println("Division completed.");
}
}
}
}

How do I get the military time difference to read correctly?

I am trying to write a program in which the console tells a person the difference between two times WITHOUT IF STATEMENTS, in "military time" or 24 hr time. So far, I have:
import java.util.Scanner;
public class MilTimeDiff {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the first time: ");
String time1 = s.next();
System.out.print("Enter the second time: ");
String time2 = s.next();
String tm1 = String.format("%02d", Integer.parseInt(time1));
String tm2 = String.format("%02d", Integer.parseInt(time2));
int t1 = Integer.parseInt(tm1);
int t2 = Integer.parseInt(tm2);
int difference = t2 - t1;
while (t1 < t2) {
String tmDif = Integer.toString(difference);
System.out.println("The difference between times is " + tmDif.substring(0, 1) + " hours " +
tmDif.substring(1) + " minutes.");
break;
}
}
}
But I have two issues: one: if I make time one 0800, and time two 1700, it gives me the correct 9 hours. But if the difference is 10 hours or more, it gives 1 hour and a lot of minutes. I thought using the String.format method would help, but it doesn't do anything.
two: I'm not sure how to approach a situation where time 1 is later than time 2.
Thanks!
You can try below code which will give Time difference in military format :
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter the first time: ");
String time1 = s.next();
System.out.print("Enter the second time: ");
String time2 = s.next();
String tm1 = String.format("%02d", Integer.parseInt(time1));
String tm2 = String.format("%02d", Integer.parseInt(time2));
String hrs1 = time1.substring(0, 2);
String min1 = time1.substring(2, 4);
String hrs2 = time2.substring(0, 2);
String min2 = time2.substring(2, 4);
// int difference = t2 - t1;
if (Integer.parseInt(time1) < Integer.parseInt(time2)) {
int minDiff = Integer.parseInt(min2) - Integer.parseInt(min1);
int hrsDiff = Integer.parseInt(hrs2) - Integer.parseInt(hrs1);
if (minDiff < 0) {
minDiff += 60;
hrsDiff--;
}
System.out.println("The difference between times is " + hrsDiff + " hours " + minDiff + " minutes.");
} else {
int minDiff = Integer.parseInt(min1) - Integer.parseInt(min2);
int hrsDiff = Integer.parseInt(hrs1) - Integer.parseInt(hrs2);
if (minDiff < 0) {
minDiff += 60;
hrsDiff--;
}
System.out.println("The difference between times is " + hrsDiff + " hours " + minDiff + " minutes.");
}
}

Setting elapsed time and using toString

I want to create a Date object, set its elapsed time to 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, and 100000000000 milliseconds, and display the date and time using the toString() method.
But I am not sure how to create a for loop that manages with the increasing milliseconds value?
This is what I have so far:
public class Date {
public static void main(String[] args) {
long i = 0;
java.util.Date date = new java.util.Date(i);
date.setTime(i);
for (i = 1000; i < 100000000000L; i *= 10) {
System.out.println("Time elapsed: " + i + " milliseconds");
}
System.out.println("Date and time: " + date.toString());
}
}
Just put your date and toString into the for loop
long i = 0;
java.util.Date date = new java.util.Date(i);
for (i = 1000; i < 100000000000L; i *= 10) {
date.setTime(i);
System.out.println("Time elapsed: " + i + " milliseconds");
System.out.println("Date and time: " + date.toString());
}
}
import java.util.Date; // 1
class FoobarTimeMachine {
public static void main(String[] args) {
Date date; // 2
for(long i = 1000l; i <= 100000000000l; i *= 10) { // 3
System.out.println("Time elapsed since epoch: " + i + " milliseconds");
date = new Date(i); // 4
System.out.println("Corresponding date: " + date); // 5
}
}
}
Comments:
We're importing java.util.Date so we can use it later as Date.
We're not initialising the date right now, it's not needed.
With <= so we can reach 100 000 000 000.
Here we are initialising the date.
someString + someObject => someString + someObject.toString()
you can do as :
public static void main(String[] args) {
long i = 0;
Date d=new Date(i);
for (i = 1000; i < 100000000000L; i *= 10) {
System.out.println("Time elapsed: " + i + " milliseconds");
d.setTime(i);
System.out.println("Date and time: " + d.toString());
}
}

Categories