countApprox() initialValue always return the same bounds - java

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!

Related

Getting average from a random duration

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");
}
}

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){

Parsing text file

I am trying to convert this .txt file into SQL queries that I can read into an SQLite Database, problem is that I can't get the information I need printed out when I need it.
The problem from this code is that it will print out when it reaches the prob property, and then print the same line again when it reaches the min/max property, just this time with the correct values found in the file.
There is only 1 item with this ID but it prints twice:
0908100 ItemID: 2060000 Prob: 0.108 Min: 1 Max: 1
0908100 ItemID: 2060000 Prob: 0.108 Min: 10 Max: 20
The whole file is properly structured so should always follow the same pattern so when it reaches "prob" I have been trying to find a way to check if the next value is min/max and if it isn't print, otherwise print after reading min/max, I haven't been able.
The output I want from the program would be like this when it finds a min/max property:
INSERT INTO `test`.`drops` (mobID, itemID, prob, min, max);
VALUES (0908100, 2060000, 0.108, 10, 20);
If there is no min/max after prob then the same line should be like this instead:
INSERT INTO `test`.`drops` (mobID, itemID, prob, min, max)
VALUES (0908100, 2060000, 0.108, 1, 1);
Money will always be itemID 0 with min/max being default to the value of money.
so:
INSERT INTO `test`.`drops` (mobID, itemID, prob, min, max)
VALUES (0908100, 0, 0.65, 87, 87);
.
public static void main(String[] args) throws FileNotFoundException {
int radNmr = 0;
String mobID = "";
String money = "";
String item = "";
String prob = "";
String min = "1";
String max = "1";
Scanner sc = new Scanner(new File("Monster_Drops1.txt"));
while (sc.hasNext()) {
String namn = sc.next();
String namn1 = sc.next();
if ("m".equals(namn.substring(0, 1)) && !"money".equals(namn) && !"max".equals(namn) && !"min".equals(namn) ) {
mobID = namn.substring(1);
}
switch(namn) {
case "money":
money = namn1;
break;
case "item":
item = namn1;
break;
case "prob":
if (!money.equals("")) {
money = "";
break;
} else if (money.equals("")){
prob = namn1;
System.out.println(mobID + " ItemID: " + item + " Prob " + prob + " Min: " + min + " Max: " + max);
break;
}
case "max":
if (min.equals("1")) {
max = namn1;
break;
} else if (!min.equals("1")) {
max = namn1;
System.out.println(mobID + " ItemID: " + item + " Prob " + prob + " Min: " + min + " Max: " + max);
max = "1";
min = "1";
break;
}
case "min":
if (max.equals("1")) {
min = namn1;
break;
} else if (!max.equals("1")) {
min = namn1;
System.out.println(mobID + " ItemID: " + item + " Prob " + prob + " Min: " + min + " Max: " + max);
break;
}
}
}
}
The Monster_Drops1.txt comes in this sort of format, the start/end tags after the monster ID has no relevance and I just added it because of the Scanner throwing errors at me when that line only had one value.
m0908100 Start
money 87
prob 0.65
item 2340802
prob 0.4
item 2640002
prob 0.1
item 2040002
prob 0.00003
item 2041001
prob 0.00003
item 2060000
prob 0.54
min 10
max 20
item 9010000
prob 0.98
m0740101 end
money 80
prob 0.55
item 6050000
prob 0.9
item 2041006
prob 0.00003
item 3014000
prob 0.41
I want to thank everone who took the time to help me out, it was very very helpful!
I did find an answer to this problem, and it was rather simple really, I read the file into an ArrayList using a Scanner, and then just modified that Switch to give me the correct output.

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());
}
}

Java: convert seconds into day, hour, minute and seconds using TimeUnit

I am using TimeStamp class to convert seconds into Day,Hours,Minutes,Seconds. I used following code
public static void calculateTime(long seconds) {
int day = (int)TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) - TimeUnit.SECONDS.toHours(TimeUnit.SECONDS.toDays(seconds));
long minute = TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.SECONDS.toMinutes(TimeUnit.SECONDS.toHours(seconds));
long second = TimeUnit.SECONDS.toSeconds(seconds) - TimeUnit.SECONDS.toSeconds(TimeUnit.SECONDS.toMinutes(seconds));
System.out.println("Day " + day + " Hour " + hours + " Minute " + minute + " Seconds " + second);
}
But I am not getting right result.
For example when I called this method as calculateTime(3600) it gives me the result as Day 0 Hour 1 Minute 60 Seconds 3540 instead of Day 0 Hour 1 Minute 0 Seconds 0.
What is the wrong with my logic? Please help me.
It should be like
int day = (int)TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) - (day *24);
long minute = TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds)* 60);
long second = TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) *60);
EDIT
Explanation:
Day calculation is correct, it does not require explanation.
TimeUnit.SECONDS.toHours(seconds) will give you direct conversion from seconds to hours without consideration for days you have already calculated. Minus the hours for days you already got i.e, day*24. You now got remaining hours.
Same for minute and second. You need to minus the already got hour and minutes respectively.
You can do like this to only use TimeUnit:
public static void calculateTime(long seconds) {
int day = (int) TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) -
TimeUnit.DAYS.toHours(day);
long minute = TimeUnit.SECONDS.toMinutes(seconds) -
TimeUnit.DAYS.toMinutes(day) -
TimeUnit.HOURS.toMinutes(hours);
long second = TimeUnit.SECONDS.toSeconds(seconds) -
TimeUnit.DAYS.toSeconds(day) -
TimeUnit.HOURS.toSeconds(hours) -
TimeUnit.MINUTES.toSeconds(minute);
System.out.println("Day " + day + " Hour " + hours + " Minute " + minute + " Seconds " + second);
}
or the slightly shorter but maybe not as intuitive
public static void calculateTime(long seconds) {
int day = (int) TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) -
TimeUnit.DAYS.toHours(day);
long minute = TimeUnit.SECONDS.toMinutes(seconds) -
TimeUnit.HOURS.toMinutes(TimeUnit.SECONDS.toHours(seconds));
long second = TimeUnit.SECONDS.toSeconds(seconds) -
TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(seconds));
System.out.println("Day " + day + " Hour " + hours + " Minute " + minute + " Seconds " + second);
}
Simple method:
public static void calculateTime(long seconds) {
long sec = seconds % 60;
long minutes = seconds % 3600 / 60;
long hours = seconds % 86400 / 3600;
long days = seconds / 86400;
System.out.println("Day " + days + " Hour " + hours + " Minute " + minutes + " Seconds " + sec);
}
Here is a code i created : (For 3600 seconds it shows "Days:0 Hours:1 Minutes:0 Seconds:0")
public class TimeConvert
{
public static void main(String[] args)
{
int fsec,d,h,m,s,temp=0,i;
fsec=3600;
//For Days
if(fsec>=86400)
{
temp=fsec/86400;
d=temp;
for(i=1;i<=temp;i++)
{
fsec-=86400;
}
}
else
{
d=0;
}
//For Hours
if(fsec>=3600)
{
temp=fsec/3600;
h=temp;
for(i=1;i<=temp;i++)
{
fsec-=3600;
}
}
else
{
h=0;
}
//For Minutes
if(fsec>=60)
{
temp=fsec/60;
m=temp;
for(i=1;i<=temp;i++)
{
fsec-=60;
}
}
else
{
m=0;
}
//For Seconds
if(fsec>=1)
{
s=fsec;
}
else
{
s=0;
}
System.out.println("Days:"+d+" Hours:"+h+" Minutes:"+m+" Seconds:"+s);
}
}
Hope it answers your question.
Late but helpful
get time in the format 00:00:00
/**
* The time in format.
*
* in The Format of 00:00:00
*/
public String getTimeInFormat(long _SECONDS)
{
if(TimeUnit.SECONDS.toHours(_SECONDS)>0)
{
return String.format("%02d:%02d:%02d",
TimeUnit.SECONDS.toHours(_SECONDS),
TimeUnit.SECONDS.toMinutes(_SECONDS) -
TimeUnit.HOURS.toMinutes(TimeUnit.SECONDS.toHours(_SECONDS)),
TimeUnit.SECONDS.toSeconds(_SECONDS) -
TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(_SECONDS)));
}
else {
return String.format("%02d:%02d",
TimeUnit.SECONDS.toMinutes(_SECONDS) -
TimeUnit.HOURS.toMinutes(TimeUnit.SECONDS.toHours(_SECONDS)),
TimeUnit.SECONDS.toSeconds(_SECONDS) -
TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(_SECONDS)));
}
}
Try this
public static void calculateTime(long seconds) {
int day = (int)TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) ;
long tempSec = seconds - (TimeUnit.HOURS.toSeconds(hours) );
System.out.println("after hours calculation "+ tempSec);
long minute = TimeUnit.SECONDS.toMinutes(tempSec);
if(tempSec > TimeUnit.MINUTES.toSeconds(minute)){
tempSec = tempSec - (TimeUnit.MINUTES.toSeconds(minute) );
}else{
tempSec = TimeUnit.MINUTES.toSeconds(minute) - tempSec;
}
System.out.println("after min calculation "+ tempSec);
long second = TimeUnit.SECONDS.toSeconds(tempSec) ;
System.out.println("Day " + day + " Hour " + hours + " Minute " + minute + " Seconds " + second);
}
This is my code:
public static String secondsToString(TimeUnit greatestUnit, long sourceDuration, TimeUnit sourceUnit) {
int ordinal = greatestUnit.ordinal();
if(ordinal<=sourceUnit.ordinal())
return String.format("%02d", sourceDuration);
final long greatestDuration = greatestUnit.convert(sourceDuration, sourceUnit);
final long rest = sourceDuration - sourceUnit.convert(greatestDuration, greatestUnit);
return String.format("%02d:", greatestDuration) + secondsToString(TimeUnit.values()[--ordinal], rest, sourceUnit);
}
or by loop
public static String secondsToStringByLoop(TimeUnit greatestUnit, long sourceDuration, TimeUnit sourceUnit) {
final StringBuffer sb = new StringBuffer();
int ordinal = greatestUnit.ordinal();
while(true){
if(ordinal<=sourceUnit.ordinal()) {
sb.append(String.format("%02d", sourceDuration));
break;
}
final long greatestDuration = greatestUnit.convert(sourceDuration, sourceUnit);
// if(greatestDuration>0 || sb.length()>0)
sb.append(String.format("%02d:", greatestDuration));
sourceDuration -= sourceUnit.convert(greatestDuration, greatestUnit);
greatestUnit = TimeUnit.values()[--ordinal];
};
return sb.toString();
}
usage example:
String str = secondsToString(TimeUnit.DAYS, 1000, TimeUnit.SECONDS);
function returns: "00:00:16:40" (days:hours:minutes:seconds)
str = UnitsConverter.secondsToString(TimeUnit.DAYS, 1000, TimeUnit.MINUTES);
returns: "00:16:40" (days:hours:minutes)
str = UnitsConverter.secondsToString(TimeUnit.MINUTES, 1000, TimeUnit.SECONDS);
returns: "16:40" (minutes:seconds)
public static void timeCalculator(){
Scanner input = new Scanner(System.in);
System.out.print("Enter length of time in seconds: ");
int n = input.nextInt();
int nDay = n/86400;
int nHours = (n%86400)/3600;
int nMin = ((n%86400)%3600) /60;
int nSec =(((n%86400)%3600)%60);
System.out.println();
System.out.print("That is "+ nDay+ " day(s),"+nHours+" hour(s), "+nMin+" minute(s), and "+nSec+" second(s). ");
}

Categories