I'd like to add a progress indicator to a command-line Java program.
For example, if I'm using wget, it shows:
71% [===========================> ] 358,756,352 51.2M/s eta 3s
Is it possible to have a progress indicator that updates without adding a new line to the bottom?
Thanks.
I use following code:
public static void main(String[] args) {
long total = 235;
long startTime = System.currentTimeMillis();
for (int i = 1; i <= total; i = i + 3) {
try {
Thread.sleep(50);
printProgress(startTime, total, i);
} catch (InterruptedException e) {
}
}
}
private static void printProgress(long startTime, long total, long current) {
long eta = current == 0 ? 0 :
(total - current) * (System.currentTimeMillis() - startTime) / current;
String etaHms = current == 0 ? "N/A" :
String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));
StringBuilder string = new StringBuilder(140);
int percent = (int) (current * 100 / total);
string
.append('\r')
.append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
.append(String.format(" %d%% [", percent))
.append(String.join("", Collections.nCopies(percent, "=")))
.append('>')
.append(String.join("", Collections.nCopies(100 - percent, " ")))
.append(']')
.append(String.join("", Collections.nCopies((int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
.append(String.format(" %d/%d, ETA: %s", current, total, etaHms));
System.out.print(string);
}
The result:
First when you write, don't use writeln(). Use write(). Second, you can use a "\r" to Carriage Return without using \n which is a New line. The carriage return should put you back at the beginning of the line.
Related
I want to be able to calculate remaining time of myHandler2.postDelayed(). I was using this answer but it returns wrong value. Here is my code where the startTime variable is:
public void attackOnChibi(ChibiCharacter cc, boolean able) {
runnable = () -> {
Log.i("a", "a");
};
if (able) {
startTime = System.nanoTime();
myHandler2.postDelayed(runnable, count += 2000);
}
if (!able) {
myHandler2.removeCallbacksAndMessages(null);
count = 0;
}
}
And the code when I calculates and displays this remaining time:
elapsedTime = System.nanoTime() - gs.enemies.get(gs.enemyId - 1).startTime;
remainingTime = gs.enemies.get(gs.enemyId - 1).count + 2000 - TimeUnit.MILLISECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS);
Log.i("elapsed/remaining", elapsedTime + " " + remainingTime);
Why it does not work? Help me please...
I have this homework assignment where i have to input a text file into my java program. the file is a "bed sensor", and tells you if the person is in a deep sleep, a restless sleep, or interrupted sleep(awake), with 0s, 1s, and 2s respectively. each line has a 0, 1, or 2 and there are 86,400 lines (one line for each second of the day).
I have figured out most of the assignment but one part i cannot figure out how to code.
My problem is i have to figure out when the person falls asleep and then output "Sleep time: (answer) hours after midnight".
i've been using counters and if statements and i would like to continue along this path if possible. i've attached my code.. and i feel like this should be pretty simple to figure out based on what i've already done... i just cannot wrap my head around it. i would appreciate any help or advice. thanks
public static void main(String[] args) {
try {
File sleepDataFile = new File("/Users/homeWork3/sleep_data.csv");
Scanner sleepData = new Scanner(sleepDataFile); // scans the data from the file into this java program
double totalSecondsCounter = 0, wakeCounter = 0, timeAwakeCounter = 0, timeAsleepCounter = 0, deepSleepCounter = 0, restlessSleepCounter = 0, interruptedSleepCounter = 0;
double wakeUpTime = 0, sleepTime = 0;
double sleepQuality = 0;
boolean inSleep = false;
while (sleepData.hasNextLine()) // this loop writes data to java as long as there is a next line
{
String data = sleepData.nextLine(); // converts the file data to strings
double val = Double.parseDouble(data); // changes string type to double type
totalSecondsCounter++;
if (inSleep == true) {
timeAsleepCounter++;
}
if (inSleep == false) {
timeAwakeCounter++;
}
if (val == 0) //deep sleep
{
deepSleepCounter++;
inSleep = true;
wakeCounter = 0;
}
if (val == 1) //restless sleep
{
restlessSleepCounter++;
inSleep = true;
wakeCounter = 0;
}
if (val == 2) // interrupted sleep / awake
{
wakeCounter++;
inSleep = false;
}
if (val == 2 && wakeCounter < 1800) {
interruptedSleepCounter++;
inSleep = true;
}
if (val == 2 && wakeCounter > 1800) {
inSleep = false;
}
if (wakeCounter == 1800) // 1800 seconds = 30 minutes. counter is set for 30 min of interrupted sleep.
{
wakeUpTime = totalSecondsCounter;
}
if (val != 2) {
}
}
sleepData.close();
System.out.println("Sleep Report for 24 hour period.");
System.out.println("----------------------------------------------------------");
System.out.println("Wake Time: \t\t\t\t" + wakeUpTime / 60 / 60 + "\t hours after midnight");
System.out.println("Sleep Time: \t\t\t\t" + sleepTime / 60 / 60 + "\t\t\t hours after midnight");
System.out.println("Duration of Deep Sleep: \t\t" + deepSleepCounter / 60 / 60 + "\t hours");
System.out.println("Duration of Restless Sleep: \t\t" + restlessSleepCounter / 60 / 60 + "\t hours");
System.out.println("Duration of Interrupted Sleep: \t\t" + interruptedSleepCounter / 60 / 60 + "\t hours");
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
I'll just give you a (comprehensive) hint, since this is a homework question.
My problem is i have to figure out when the person falls asleep and then output "Sleep time: (answer) hours after midnight".
First of all, you're going to want to initialize two variables before your while loop:
Some boolean flag variable hasFallenAsleepYet
Some double variable fallenAsleepTime
Like so:
boolean hasFallenAsleepYet = false;
double fallenAsleepTime;
Now, inside of your while loop, as you're iterating through sleepData, you're going to want to count the time taken until the person falls asleep, then stop counting.
if(!hasFallenAsleepYet) {
if(val == someInteger || val == someOtherInteger){ // some condition to tell if the person is asleep
hasFallenAsleepYet = true;
fallenAsleepTime = totalSecondsCounter;
}
}
I'll leave you to figure out what the numbers someInteger and someOtherInteger are, but you should be able to figure it out quickly. They key takeaway here is that you need to initialize some flag variable, so that you stop keeping track of fallenAsleepTime after a certain condition is met.
I'd like to add a progress indicator to a command-line Java program.
For example, if I'm using wget, it shows:
71% [===========================> ] 358,756,352 51.2M/s eta 3s
Is it possible to have a progress indicator that updates without adding a new line to the bottom?
Thanks.
I use following code:
public static void main(String[] args) {
long total = 235;
long startTime = System.currentTimeMillis();
for (int i = 1; i <= total; i = i + 3) {
try {
Thread.sleep(50);
printProgress(startTime, total, i);
} catch (InterruptedException e) {
}
}
}
private static void printProgress(long startTime, long total, long current) {
long eta = current == 0 ? 0 :
(total - current) * (System.currentTimeMillis() - startTime) / current;
String etaHms = current == 0 ? "N/A" :
String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));
StringBuilder string = new StringBuilder(140);
int percent = (int) (current * 100 / total);
string
.append('\r')
.append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
.append(String.format(" %d%% [", percent))
.append(String.join("", Collections.nCopies(percent, "=")))
.append('>')
.append(String.join("", Collections.nCopies(100 - percent, " ")))
.append(']')
.append(String.join("", Collections.nCopies((int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
.append(String.format(" %d/%d, ETA: %s", current, total, etaHms));
System.out.print(string);
}
The result:
First when you write, don't use writeln(). Use write(). Second, you can use a "\r" to Carriage Return without using \n which is a New line. The carriage return should put you back at the beginning of the line.
Is it possible to convert the function go into the non-recursive function? Some hints or a start-up sketch would be very helpful
public static TSPSolution solve(CostMatrix _cm, TSPPoint start, TSPPoint[] points, long seed) {
TSPSolution sol = TSPSolution.randomSolution(start, points, seed, _cm);
double t = initialTemperature(sol, 1000);
int frozen = 0;
System.out.println("-- Simulated annealing started with initial temperature " + t + " --");
return go(_cm, sol, t, frozen);
}
private static TSPSolution go(CostMatrix _cm, TSPSolution solution, double t, int frozen) {
if (frozen >= 3) {
return solution;
}
i++;
TSPSolution bestSol = solution;
System.out.println(i + ": " + solution.fitness() + " " + solution.time() + " "
+ solution.penalty() + " " + t);
ArrayList<TSPSolution> nHood = solution.nHood();
int attempts = 0;
int accepted = 0;
while (!(attempts == 2 * nHood.size() || accepted == nHood.size()) && attempts < 500) {
TSPSolution sol = nHood.get(rand.nextInt(nHood.size()));
attempts++;
double deltaF = sol.fitness() - bestSol.fitness();
if (deltaF < 0 || Math.exp(-deltaF / t) > Math.random()) {
accepted++;
bestSol = sol;
nHood = sol.nHood();
}
}
frozen = accepted == 0 ? frozen + 1 : 0;
double newT = coolingSchedule(t);
return go(_cm, bestSol, newT, frozen);
}
This is an easy one, because it is tail-recursive: there is no code between the recursive call & what the function returns. Thus, you can wrap the body of go in a loop while (frozen<3), and return solution once the loop ends. And replace the recursive call with assignments to the parameters: solution=bestSol; t=newT;.
You need to thinkg about two things:
What changes on each step?
When does the algorithm end?
Ans the answer should be
bestSol (solution), newT (t), frozen (frozen)
When frozen >= 3 is true
So, the easiest way is just to enclose the whole function in something like
while (frozen < 3) {
...
...
...
frozen = accepted == 0 ? frozen + 1 : 0;
//double newT = coolingSchedule(t);
t = coolingSchedule(t);
solution = bestSol;
}
As a rule of thumb, the simplest way to make a recursive function iterative is to load the first element onto a Stack, and instead of calling the recursion, add the result to the Stack.
For instance:
public Item recursive(Item myItem)
{
if(myItem.GetExitCondition().IsMet()
{
return myItem;
}
... do stuff ...
return recursive(myItem);
}
Would become:
public Item iterative(Item myItem)
{
Stack<Item> workStack = new Stack<>();
while (!workStack.isEmpty())
{
Item workItem = workStack.pop()
if(myItem.GetExitCondition().IsMet()
{
return workItem;
}
... do stuff ...
workStack.put(workItem)
}
// No solution was found (!).
return myItem;
}
This code is untested and may (read: does) contain errors. It may not even compile, but should give you a general idea.
I'd like to add a progress indicator to a command-line Java program.
For example, if I'm using wget, it shows:
71% [===========================> ] 358,756,352 51.2M/s eta 3s
Is it possible to have a progress indicator that updates without adding a new line to the bottom?
Thanks.
I use following code:
public static void main(String[] args) {
long total = 235;
long startTime = System.currentTimeMillis();
for (int i = 1; i <= total; i = i + 3) {
try {
Thread.sleep(50);
printProgress(startTime, total, i);
} catch (InterruptedException e) {
}
}
}
private static void printProgress(long startTime, long total, long current) {
long eta = current == 0 ? 0 :
(total - current) * (System.currentTimeMillis() - startTime) / current;
String etaHms = current == 0 ? "N/A" :
String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));
StringBuilder string = new StringBuilder(140);
int percent = (int) (current * 100 / total);
string
.append('\r')
.append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
.append(String.format(" %d%% [", percent))
.append(String.join("", Collections.nCopies(percent, "=")))
.append('>')
.append(String.join("", Collections.nCopies(100 - percent, " ")))
.append(']')
.append(String.join("", Collections.nCopies((int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
.append(String.format(" %d/%d, ETA: %s", current, total, etaHms));
System.out.print(string);
}
The result:
First when you write, don't use writeln(). Use write(). Second, you can use a "\r" to Carriage Return without using \n which is a New line. The carriage return should put you back at the beginning of the line.