0

UPDATE - solution below

I'm new to java (and programming as a whole) and could really use some help.

I'm working on a fragment that includes a timer and counter. The user punches a number into an edit text and hits a "set" button to set the timer to that number in minutes. There's also a frequency counter that increases by 1 each time it's clicked. When the timer reaches zero, I want a "rate" text view to show the result of dividing the number of times the button was clicked by the number of minutes; rate = frequency/minute. For example: If minutes = 5 and frequency = 7, I want the rate text view to display "0.71".

So far, I've gotten the timer and counter to work, but I can't get the rate calculation to work. I keep getting "infinity," which from what I've read means I'm dividing by an integer. What I can't figure out is which number is still an integer. I'm also uncertain that the layout of my code is correct (maybe I'm declaring something where I shouldn't?)

Any help would be greatly appreciated. Thanks in advance!

I've tried using a try/catch statement to avoid dividing by 0. In XML, I've tried setting the input type to "numberDecimal" I've tried converting the edit text to an integer and text view to a string before converting to doubles I've tried converting the edit text and counter directly as doubles. I've searched stackoverflow, Quora, and YouTube to make sure I'm calculating correctly.

Solution

@Override
            public void onFinish() {
                mTimerRunning = false;
                button_start_pause.setText("Start");
                button_start_pause.setVisibility(android.view.View.INVISIBLE);
                button_reset.setVisibility(android.view.View.VISIBLE);
                text_view_rate.setVisibility(android.view.View.VISIBLE);
                calculaterate();
            }
        }.start();

        mTimerRunning = true;
        button_start_pause.setText("Pause");
    }

    public void pauseTimer() {
        countDownTimer.cancel();
        mTimerRunning = false;
        button_start_pause.setText("Start");
        updateCountDownText();
    }

    public void resetTimer() {
        if (mTimerRunning) {
            countDownTimer.cancel();
            mTimeLeftInMillis = (mStartTimeInMillis + 1000);
            updateWatchInterface();
            startTimer();
        } else {
            mTimeLeftInMillis = (mStartTimeInMillis);
            updateCountDownText();
            updateWatchInterface();
            button_reset.setVisibility(android.view.View.VISIBLE);
            button_start_pause.setVisibility(android.view.View.VISIBLE);
        }
    }

    public void calculaterate() {
        double numerator = Double.parseDouble(text_view_frequency.getText().toString());
        double denominator = (mStartTimeInMillis/1000)/60;
        double rate = (numerator)/(denominator);
        DecimalFormat df = new DecimalFormat("#.00");
        String ratecalc = df.format(rate);
        text_view_rate.setText(ratecalc);
    }

Fragment and component IDs

public class fragmentrate extends Fragment {
    private EditText edit_text_input;
    private TextView text_view_countdown;
    private TextView text_view_frequency;
    private TextView text_view_rate;
    private TextView rate_equals;
    private Button button_start_pause;
    private Button button_reset;
    private Button button_set;
    private Button button_frequency;
    private Button button_reset_frequency;
    private CountDownTimer countDownTimer;
    private boolean mTimerRunning;
    private long mStartTimeInMillis;
    private long mTimeLeftInMillis = mStartTimeInMillis;
    private long mEndTime;
    private int mCounter;
    private double denominator;

    View View;

    public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @NonNull Bundle savedInstanceState) {
        View = inflater.inflate(R.layout.rate_fragment, container, false);

        text_view_countdown = View.findViewById(R.id.text_view_countdown);
        button_start_pause = View.findViewById(R.id.button_start_pause);
        button_reset = View.findViewById(R.id.button_reset);
        button_frequency = View.findViewById(R.id.button_frequency);
        button_reset_frequency = View.findViewById(R.id.button_reset_frequency);
        edit_text_input = View.findViewById(R.id.edit_text_input);
        button_set = View.findViewById(R.id.button_set);
        text_view_frequency = View.findViewById(R.id.text_view_frequency);
        text_view_rate = View.findViewById(R.id.text_view_rate);
        rate_equals = View.findViewById(R.id.rate_equals);

Frequency counter

button_frequency.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                mCounter ++;
                text_view_frequency.setText(Integer.toString(mCounter));
            }
        });

        button_reset_frequency.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                mCounter = 0;
                text_view_frequency.setText(Integer.toString(mCounter));
            }
        });

Timer and rate calculation

button_set.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                String input = edit_text_input.getText().toString();
                if (input.length() == 0) {
                    Toast.makeText(getActivity(), "Please enter a number", Toast.LENGTH_SHORT).show();
                    return;
                }
                long millisInput = Long.parseLong(input) * 60000;
                if (millisInput == 0) {
                    Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
                    return;
                }

                setTime(millisInput);
                edit_text_input.setText("");
            }
        });

        button_start_pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                if (mTimerRunning) {
                    pauseTimer();
                } else {
                    startTimer();
                }
            }
        });

        button_reset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(android.view.View view) {
                if(mTimerRunning) {
                    resetTimer();
                } else{
                    resetTimer();
                }
            }
        });
        return View;
    }

    private void setTime(long milliseconds) {
        mStartTimeInMillis = milliseconds;
        resetTimer();
    }

    private void startTimer() {
        mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
        countDownTimer = new CountDownTimer(mTimeLeftInMillis, 100) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMillis = millisUntilFinished;
                updateCountDownText();
            }

            @Override
            public void onFinish() {
                mTimerRunning = false;
                button_start_pause.setText("Start");
                button_start_pause.setVisibility(android.view.View.INVISIBLE);
                button_reset.setVisibility(android.view.View.VISIBLE);

                 try {
                double denominator = Integer.parseInt(edit_text_input.getText().toString());
                double rate = ((double)mCounter/denominator);
                text_view_rate.setText(Double.toString(rate));
            }
            catch (NumberFormatException e)
            {

            }
        }
    }.start();
mTimerRunning = true;
        button_start_pause.setText("Pause");
    }

    private void pauseTimer() {
        countDownTimer.cancel();
        mTimerRunning = false;
        updateCountDownText();
        button_start_pause.setText("Start");
    }

    private void resetTimer() {
        if (mTimerRunning) {
            countDownTimer.cancel();
            mTimeLeftInMillis = (mStartTimeInMillis + 1000);
            updateWatchInterface();
            startTimer();
        } else {
        }
        mTimeLeftInMillis = (mStartTimeInMillis);
        updateCountDownText();
        updateWatchInterface();
        button_reset.setVisibility(android.view.View.VISIBLE);
        button_start_pause.setVisibility(android.view.View.VISIBLE);
    }

    private void updateCountDownText() {
        int minutes = (int) (mTimeLeftInMillis/1000)/60;
        int seconds = (int) (mTimeLeftInMillis/1000)%60;

        String timeLeftFormatted = String.format(Locale.getDefault(),
                timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds));
        text_view_countdown.setText(timeLeftFormatted);
    }

I expect the output of 5/7 to be 0.71, but the actual output is "Infinity"

Alex Elfont
  • 115
  • 1
  • 12
  • why are you setting denominator to 0 when you catch an error in parsing... that would result in dividing by 0 in the next step, which is just setting up another error. – Gus Aug 30 '19 at 21:36
  • incidentally, that's also probably why you're seeing infinity as a result : https://stackoverflow.com/questions/51801054/what-decides-nan-and-infinity-in-java-division-operations – Gus Aug 30 '19 at 21:38
  • also, it looks like you're declaring new variables with the same name of `denominator`, so even if it parsed correctly you wouldn't get the correct result... change `double denominator = ` to `denominator = ` – Gus Aug 30 '19 at 21:41
  • @Gus thanks for your help with this! I removed "denominator = 0" per your suggestion. When I went to change "double denominator" to "denominator," it says "cannot resolve symbol" for the first and second line after "try" – Alex Elfont Aug 30 '19 at 21:52
  • well, in your new edit `onFinish()` looks OK -- are you still getting Infinity every time? I'm assuming that the value from `edit_text_input` is being set to a number-like value... (an aside -- don't just catch an exception and do nothing; At least print a message somewhere, to keep future you from going insane when that exception occurs) – Gus Aug 30 '19 at 22:13
  • @Gus Now when I run the program I don't get anything; where "infinity" once displayed is now blank. – Alex Elfont Aug 31 '19 at 00:18

0 Answers0