Search code examples
javaandroidjsontry-catch

Calculating percentage within a try catch block


I'm trying to calculate the percentage rating for products to use in updating a Bootstrap progress bar but my issue is that it only works when only one rating category returns a none zero value and does not work of more than one rating category returns a none zero value.

Here is what I have tried so far:

StringRequest productRateStringRequest = new StringRequest(Request.Method.POST, NetworkConstants.URL_PRODUCT_RATINGS,
        response -> {
            try{
                JSONObject ratingObject = new JSONObject(response);
                oneStar = ratingObject.getInt("oneStar");
                twoStars = ratingObject.getInt("twoStar");
                threeStars = ratingObject.getInt("threeStar");
                fourStars = ratingObject.getInt("fourStar");
                fiveStars = ratingObject.getInt("fiveStar");
                totalRating = ratingObject.getInt("totalRatings");

                averageRating.setText(String.format("%s/5", ratingObject.getString("averageRating")));
                oneStarCount.setText(String.format("(%s)", oneStar));
                twoStarCount.setText(String.format("(%s)", twoStars));
                threeStarCount.setText(String.format("(%s)", threeStars));
                fourStarCount.setText(String.format("(%s)", fourStars));
                fiveStarCount.setText(String.format("(%s)", fiveStars));
                

                productRatingBar.setRating((float) ratingObject.getDouble("averageRating"));

/*this is the part that is giving abnormal outputs when more than one non-zero value is returned( i.e oneStar and any other variable is none zero) and works well only when only one none-zero value is set (i.e only oneStar is none zero)*/
                Log.d("Progress", "inflateRating: "+ fourStars / totalRating * 100); /* used this to test and it confirms what I thought. This line returns zero if more than one variable has a none zero value. in this case, the value for fourStars and fiveStars is 2*/
                oneStarProgress.setProgress((oneStar / totalRating) * 100);
                twoStarProgress.setProgress((twoStars / totalRating) * 100);
                threeStarProgress.setProgress((threeStars / totalRating) * 100);
                fourStarProgress.setProgress((fourStars / totalRating) * 100);
                fiveStarProgress.setProgress((fiveStars / totalRating) * 100);
                
            }catch (JSONException e){
                e.printStackTrace();
            }
        },
        error -> {
            Log.d("Error", "Failed with error msg:\t" + error.getMessage());
            Log.d("An Error", "Error StackTrace: \t" + Arrays.toString(error.getStackTrace()));
            try {
                byte[] htmlBodyBytes = error.networkResponse.data;
                Log.e("Error", new String(htmlBodyBytes), error);
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }){
    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<>();
        params.put("id", id);
        params.put("api_token", token);
        return params;
    }
};
productRateStringRequest.setRetryPolicy(new DefaultRetryPolicy(
        1000*5,
        3,
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue productRequestQue = Volley.newRequestQueue(this);
productRequestQue.add(productRateStringRequest);

Solution

  • After too much trouble, the following worked

          StringRequest productRateStringRequest = new StringRequest(Request.Method.POST, NetworkConstants.URL_PRODUCT_RATINGS,
                response -> {
                    try{
                        JSONObject ratingObject = new JSONObject(response);
                        oneStar = Integer.parseInt(ratingObject.getString("oneStar"));
                        twoStars = Integer.parseInt(ratingObject.getString("twoStar"));
                        threeStars = Integer.parseInt(ratingObject.getString("threeStar"));
                        fourStars = Integer.parseInt(ratingObject.getString("fourStar"));
                        fiveStars = Integer.parseInt(ratingObject.getString("fiveStar"));
                        totalRating = Integer.parseInt(ratingObject.getString("totalRatings"));
    
                        averageRating.setText(String.format("%s/5", ratingObject.getString("averageRating")));
                        oneStarCount.setText(String.format("(%s)", oneStar));
                        twoStarCount.setText(String.format("(%s)", twoStars));
                        threeStarCount.setText(String.format("(%s)", threeStars));
                        fourStarCount.setText(String.format("(%s)", fourStars));
                        fiveStarCount.setText(String.format("(%s)", fiveStars));
    
                        productRatingBar.setRating((float) ratingObject.getDouble("averageRating"));
                        oneStarProgress.setProgress(calculateRatingPercentage(oneStar, totalRating));
                        twoStarProgress.setProgress(calculateRatingPercentage(twoStars, totalRating));
                        threeStarProgress.setProgress(calculateRatingPercentage(threeStars, totalRating));
                        fourStarProgress.setProgress(calculateRatingPercentage(fourStars, totalRating));
                        fiveStarProgress.setProgress(calculateRatingPercentage(fiveStars, totalRating));
                        if(totalRating < 1){
                            productRateCount.setVisibility(View.GONE);
                        }else if(totalRating > 1){
                            productRateCount.setVisibility(View.VISIBLE);
                            productRateCount.setText(String.format("( %s ratings )", totalRating));
                        }else{
                            productRateCount.setVisibility(View.VISIBLE);
                            productRateCount.setText(String.format("( %s rating )", totalRating));
                        }
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                },
                error -> {
                    Log.d("Error", "Failed with error msg:\t" + error.getMessage());
                    Log.d("An Error", "Error StackTrace: \t" + Arrays.toString(error.getStackTrace()));
                    try {
                        byte[] htmlBodyBytes = error.networkResponse.data;
                        Log.e("Error", new String(htmlBodyBytes), error);
                    } catch (NullPointerException e) {
                        e.printStackTrace();
                    }
                }){
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("id", id);
                params.put("api_token", token);
                return params;
            }
        };
        productRateStringRequest.setRetryPolicy(new DefaultRetryPolicy(
                1000*5,
                3,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        RequestQueue productRequestQue = Volley.newRequestQueue(this);
        productRequestQue.add(productRateStringRequest);
    }
    

    The method called to calculate the percentage rating is implemented as follows

          public int calculateRatingPercentage(int rating, int total){
        int percentage = (int) (((float)(rating) / total) * 100);
        return percentage;
    
    }
    

    Basically what was happening is that the ratings were being returned as strings cast to floating points. the calculation was thus returning NAN as it was difficult converting the ratings to double. In my solution, I did the casting myself and then cast the result back to integer as that was what is needed