This is my code to update the Status:
String[] status = new String[] {"Version: 1.5.0", "https://discord.gg/arWEM2h", "Love Backxtar", "You want me!", "Type: ~help", "User Counter: %members"};
int next = 60;
public void onSecond() {
if(next%5 == 0) {
if(!hasStarted) {
hasStarted = true;
StatChannelCommand.onStartUp();
}
Random rand = new Random();
int i = rand.nextInt(status.length);
shardMan.getShards().forEach(jda -> {
String text = status[i].replaceAll("%members", "" + jda.getUsers().size());
jda.getPresence().setActivity(Activity.playing(text));
});
StatChannelCommand.checkStats();
if(next == 0) {
next = 60;
}
}
else {
next--;
}
}
But the String is running every second. I thought it was every 5 seconds. I did 60 sec % 5. What is wrong with this code?
When you enter the method onSecond() for the first time, the condition next%5 == 0 will be true. The variable next will not be updated, because this happens only in the else part. So, on next run of the method next will still be 60.
Related
I've been having an issue with the following program:
public class PrimeFinder implements Runnable {
Thread go;
StringBuffer primes = new StringBuffer();
int time = 0;
public PrimeFinder() {
start();
while (primes != null) {
System.out.println(time);
try {
Thread.sleep(1000);
} catch (InterruptedException exc) {
// do nothing
}
time++;
}
}
public void start() {
if (go == null) {
go = new Thread(this);
go.start();
}
}
public void run() {
int quantity = 1_000_000;
int numPrimes = 0;
// candidate: the number than might be prime
int candidate = 2;
primes.append("\nFirst ").append(quantity).append(" primes:\n\n");
while (numPrimes < quantity) {
if (isPrime(candidate)) {
primes.append(candidate).append(" ");
numPrimes++;
}
candidate++;
}
System.out.println(primes);
primes = null;
System.out.println("\nTime elapsed: " + time + " seconds");
}
public static boolean isPrime(int checkNumber) {
double root = Math.sqrt(checkNumber);
for (int i = 2; i <= root; i++) {
if (checkNumber % i == 0) {
return false;
}
}
return true;
}
public static void main (String[] arguments) {
new PrimeFinder();
}
}
The program will count the time it takes to Print all Primes to the console.
beginning at 0 seconds to x (when the program completes)
Then will print x number of prime numbers (line 29: quantity = 1_000_000).
Then will print "Time Elapsed: x seconds
when I run the program with a smaller quantity (ex:10) it will print up to '29' (the 10th prime).
I'm assuming there is some limitation in eclipse that is preventing a large quantity of numbers from being printed to the console.
Edit: at exactly 5572 the output to the console will be cleared
this is the output:
how many primes would you like to see?
5572
0 //this is time the program has ran
First 5572 primes:
Time elapsed: 0 seconds.
when copy and pasting here the numbers carried over, so its just disappeared from the console.
Your console output is probably limited. In Eclipse, got to...
Window > Preferences > Run/Debug > Console
Uncheck the Limit console output check box.
console output was being printed on one line, added "\n" for the if statement on lines: (41-46)
if (isPrime(candidate)) {
primes.append(candidate+ "\n").append(" "); //if candidate is prime, print # then space " "
numPrimes++;
}
candidate++;
}
Now prints vertically.
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 have found that my method called checkForErrors takes around 80x longer to run on the first execution only, and I can't seem to figure out why.
D/guess: adhl
D/checkerror: checking for errors took 4760743ns // first run
D/validity: checking guess validity took 7141114ns
D/guess: agkl
D/checkerror: checking for errors took 61035ns // every other run takes around this long
D/validity: checking guess validity took 732422ns
I have looked through the code and I don't see anything that would take longer on the first run only so I'm stumped.
Button on click listener:
submitBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String Guess = guess_txt.getText().toString();
Log.d("guess", Guess);
if(checkGuessValidity(Guess)){ // <--
submitValidGuess(Guess);
int bulls = game.getBullsAndHits()[0];
int hits = game.getBullsAndHits()[1];
if(!game.gameWon) //if game is not won, submit the guess with bulls and hits
guessSubmittedListener.guessSubmitted(Guess, bulls, hits);
else //if game is won, call gameWon() method
gameEnd();
}
if((game.getCurrentTry() > game.getMaxTries()) && (!Guess.equals(game.getHiddenWord()))) gameEnd(); //if user is out of tries, call gameLost method
triesLeft.setText("Tries Left: " + (game.getMaxTries() - game.getCurrentTry() + 1)); //update tries left on main fragment
guess_txt.setText("");
}
});
checkGuessValidity:
public boolean checkGuessValidity(String Guess){
long start = System.nanoTime();
long start2 = System.nanoTime();
ErrorList Status = checkForErrors(Guess); // <--
long end2 = System.nanoTime();
Log.d("checkerror", "checking for errors took " + (end2 - start2) + "ns");
. . . more code . . .
checkForErrors:
public ErrorList checkForErrors(String Guess){
if(Guess.length() != game.getHiddenWordLength()) return ErrorList.Wrong_Length;
else if(!isValidInput(Guess)) return ErrorList.Invalid_Characters;
else if(!isIsogram(Guess)) return ErrorList.Not_Isogram;
else if(!isLowercase(Guess)) return ErrorList.Not_Lowercase;
else return ErrorList.OK;
}
isValidInput, isIsogram and isLowercase:
public boolean isIsogram(String Guess){
Map<Character, Boolean> map = new HashMap();
for(int i = 0; i < Guess.length(); i++){
if(map.get(Guess.charAt(i)) == null) //if the value for the key (character) is null (has not been changed since map initialization)
map.put(Guess.charAt(i), true); //then set it to true (indicating that it has been seen)
else { //else (if the value at the character HAS been changed since initialization, ie. it has been seen)
Log.d("Character repeated", "" + Guess.charAt(i));
return false; //return false
}
}
return true; //if loop completes no duplicates were found and guess is an isogram
}
public boolean isLowercase(String Guess){
if(Guess.equals(Guess.toLowerCase())) return true;
else return false;
}
public boolean isValidInput(String Guess){
char[] chars = Guess.toCharArray();
for(int i = 0; i < chars.length; i++){
if(!isLatinLetter(chars[i])) return false;
}
return true;
}
public static boolean isLatinLetter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
It doesn't seem like any of the methods should be impacted by when they are run, so I don't know why it takes extra long on the first execution. I'm still a beginner to programming so please excuse any poor formatting or horribly optimized code :p .
edit: CPU usage graph: https://prnt.sc/ftjokq
I want the code to trigger the JOptionPane.
Here is the code for the working clock:
new Thread() {
public void run() {
while (true) {
GregorianCalendar cal = new GregorianCalendar();
int hour = cal.get(GregorianCalendar.HOUR);
int min = cal.get(GregorianCalendar.MINUTE);
int sec = cal.get(GregorianCalendar.SECOND);
int AM_PM = cal.get(GregorianCalendar.AM_PM);
String day_night;
if (AM_PM == 1) {
day_night = "PM";
} else {
day_night = "AM";
}
String time = hour + ":" + min + ":" + sec + " " + day_night;
lblClock.setText(time);
}
}
}.start();
Here is code I wrote to trigger alarm, but no 'play sound' is coded yet, because I can't even get the JOptionPane to appear. Why? I want to get the values from spinners, than compare to real time until they meet and than trigger alarm and exit thread. How to fix it?
btnAlarm.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
new Thread() {
public void run() {
txtAlarmSet.setVisible(true);
boolean flag = false;
GregorianCalendar g = new GregorianCalendar();
int hour = Integer.parseInt(spinnerHour.getModel().getValue().toString());
int minute = Integer.parseInt(spinnerMinute.getModel().getValue().toString());
int second = Integer.parseInt(spinnerSecond.getModel().getValue().toString());
int AMorPM;
if (rdbtnAm.isSelected()) {
AMorPM = 0;
} else
AMorPM = 1;
while (flag == false) {
int realHour = g.get(GregorianCalendar.HOUR);
int realMinute = g.get(GregorianCalendar.MINUTE);
int realSecond = g.get(GregorianCalendar.SECOND);
int realAM_PM = g.get(GregorianCalendar.AM_PM);
if (hour == realHour && minute == realMinute && second == realSecond
&& AMorPM == realAM_PM) {
JOptionPane.showMessageDialog(null, "WORKS!"); // <- this doesn't appear!
flag = true;
}
}
txtAlarmSet.setVisible(false);
}
}.start();
}
});
In your checking loop, you need to reacquire the Calendar on every pass, otherwise, you'll just end up re-checking the same time value over and over. Move the line
GregorianCalendar g = new GregorianCalendar();
inside the loop.
Note: This is not a particularly good approach to this problem. What you're doing is called "busy waiting" and it's generally not good for much other than making the CPU get hot. A better approach would be to use an event-driven approach, but that's beyond the scope of this answer.
One major problem I notice is missing } after AMorPM = 1; making it impossible to work for AM.
In my program, I have a while loop that will display a list of shops and asks for an input, which corresponds with the shop ID. If the user enters an integer outside the array of shops, created with a Shop class, it will exit the loop and continue. Inside this loop is another while loop which calls the sellItem method of my Shop class below:
public Item sellItem()
{
displayItems();
int indexID = Shop.getInput();
if (indexID <= -1 || indexID >= wares.length)
{
System.out.println("Null"); // Testing purposes
return null;
}
else
{
return wares[indexID];
}
}
private void displayItems()
{
System.out.println("Name\t\t\t\tWeight\t\t\t\tPrice");
System.out.println("0. Return to Shops");
for(int i = 0; i < wares.length; i++)
{
System.out.print(i + 1 + ". ");
System.out.println(wares[i].getName() + "\t\t\t\t" + wares[i].getWeight() + "\t\t\t\t" + wares[i].getPrice());
}
}
private static int getInput()
{
Scanner scanInput = new Scanner(System.in);
int itemID = scanInput.nextInt();
int indexID = itemID - 1;
return indexID;
}
The while loop in my main class method is as follows:
boolean exitAllShops = true;
while(exitAllShops)
{
System.out.println("Where would you like to go?\nEnter the number which corresponds with the shop.\n1. Pete's Produce\n2. Moore's Meats\n3. Howards Hunting\n4. Foster's Farming\n5. Leighton's Liquor\n6. Carter's Clothing\n7. Hill's Household Products\n8. Lewis' Livery, Animals, and Wagon supplies\n9. Dr. Miller's Medicine\n10. Leave Shops (YOU WILL NOT BE ABLE TO RETURN)");
int shopInput = scan.nextInt();
if(shopInput >= 1 && shopInput <= allShops.length)
{
boolean leaveShop = true;
while(leaveShop)
{
allShops[shopInput - 1].sellItem();
if(allShops == null)
{
System.out.println("still null"); // Testing purposes
leaveShop = false;
}
}
}
else
{
System.out.println("Are you sure you want to leave?\n1. Yes\n2. No");
int confirm = scan.nextInt();
if(confirm == 1)
{
exitAllShops = false;
}
}
The problem is here:
boolean leaveShop = true;
while(leaveShop)
{
allShops[shopInput - 1].sellItem();
if(allShops == null)
{
System.out.println("still null"); // Testing purposes
leaveShop = false;
}
}
No matter what I do, I can't get "still null" to print to confirm that I'm correctly calling the return statement of the method sellItem of the class Shop. What am I doing wrong?
After calling allShops[...].sellItem(), allShops is still a valid array reference -- there's no way it could be null! You probably want to test the return value from sellItem:
if(allShops[shopInput-1].sellItem() == null)