Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error Method is too complex to analyze by data flow algorithm

Tags:

java

android

css

This is the method that is causing the issue. I am creating a BMI calculator that uses Age, weight and height to calculate the end result. I'm not sure if my logic is wrong or if there's another issue going on

public void calculateClickHandler(View view) {   
    String Outcome;
    Outcome = null;

    age = Float.parseFloat(txtHowOld.getText().toString());
    feet = Float.parseFloat(txtFt.getText().toString());
    inches = Float.parseFloat(txtIn.getText().toString());
    pounds = Float.parseFloat(txtWeight.getText().toString());
    height = (feet * 12) + inches;
    double BMI1 = (pounds / (height * height)) * 703.0;


    if (btnF.isChecked()) {
        if (age >= 20 && age <= 40) {
            if (BMI1 < 21) {
                Outcome = "Underweight";
            } else if (BMI1 >= 21 && BMI1 <= 33) {
                Outcome = "Healthy";
            }
            else if (BMI1 > 33 && BMI1 <= 39) {
                Outcome = "Overweight";
            } else if (BMI1 > 39) {
                Outcome = "Obese";
            } else if (age >= 41 && age <= 60) {
                if (BMI1 < 23) {
                    Outcome = "Underweight";
                } else if (BMI1 >= 23 && BMI1 <= 35) {
                    Outcome = "Healthy";
                } else if (BMI1 > 35 && BMI1 <= 40) {
                    Outcome = "Overweight";
                } else if (BMI1 > 40) {
                    Outcome = "Obese";
                }
            } else if (age >= 61 && age <= 79) {
                if (BMI1 < 24) {
                    Outcome = "Underweight";
                } else if (BMI1 >= 24 && BMI1 <= 36) {
                    Outcome = "Healthy";
                } else if (BMI1 > 36 && BMI1 <= 42) {
                    Outcome = "Overweight";
                } else if (BMI1 > 42) {
                    Outcome = "Obese";
                }

            }
        }

        if (btnM.isChecked()) {
            if (age >= 20 && age <= 40) {
                if (BMI1  < 8) {
                    Outcome = "Underweight";
                } else if (BMI1  >= 8 && BMI1  <= 19) {
                    Outcome = "Healthy";
                } else if (BMI1  > 19 && BMI1  <= 25) {
                    Outcome = "Overweight";
                } else if (BMI1  > 25) {
                    Outcome = "Obese";
                }
            } else if (age >= 41 && age <= 60) {
                if (BMI1  < 11) {
                    Outcome = "Underweight";
                } else if (BMI1  >= 11 && BMI1  <= 22) {
                    Outcome = "Healthy";
                } else if (BMI1  > 22 && BMI1  <= 27) {
                    Outcome = "Overweight";
                } else if (BMI1  > 27) {
                    Outcome = "Obese";
                }
            } else if (age >= 61 && age <= 79) {
                if (BMI1  < 13) {
                    Outcome = "Underweight";
                } else if (BMI1  >= 14 && BMI1  <= 25) {
                    Outcome = "Healthy";
                } else if (BMI1  > 25 && BMI1  <= 27) {
                    Outcome = "Overweight";
                } else if (BMI1  > 27) {
                    Outcome = "Obese";
                }
            }


            BMI2.setText(Outcome);
        }
    }
}

}
like image 200
connor Avatar asked Apr 30 '15 23:04

connor


1 Answers

Your logic is fine. Android Studio (or whatever?) is just complaining that there are too many branches to calculate a numeric complexity for the method.

If you want to alleviate the error, create a new class to resolve the BMI value (and perhaps a boolean or enum for gender (I assume that's what btnM means)) into a separate class or method.

--- EDIT

You can see in the below code that the redundant range checking code is eliminated by first finding the appropriate bounds, then evaluating the bounds and BMI1 into an outcome.

In the process of making these, you will also notice you had a bug in your grandpa ranges (13/14) and have no calculations for ages 19- or 80+.

public void calculateClickHandler(View view) {
    boolean male = btnM.isChecked() && !btnF.isChecked();
    age, feet, inches, pounds, BMI1 = whatever;
    String outcome = findOutcome(male, BMI1);
    // display outcome somewhere
}

static final int[] bmiRangesLady = { 21, 33, 39 };
static final int[] bmiRangesMom = { 23, 35, 40 };
static final int[] bmiRangesGma = { 24, 36, 42 };

static final int[] bmiRangesMan = { 8, 19, 25 };
static final int[] bmiRangesDad = { 11, 22, 27 };
static final int[] bmiRangesGpa = { 13, 25, 30 };

public static String findOutcome(boolean male, double bmi) {

    int[] bmiRangesToUse;

    if (!male) {
        if (age >= 20 && age <= 40) {
            bmiRangesToUse = bmiRangesLady;
        } else if (age > 40 && age <= 60) {
            bmiRangesToUse = bmiRangesMom;
        } else if (age > 60) {
            bmiRangesToUse = bmiRangesGma;
        }
    } else {
        if (age >= 20 && age <= 40) {
            bmiRangesToUse = bmiRangesMan;
        } else if (age > 40 && age <= 60) {
            bmiRangesToUse = bmiRangesDad;
        } else if (age > 60) {
            bmiRangesToUse = bmiRangesGpa;
        }
    }
    // if you still get hi complexity, the above code can be moved into another method.

    // fge suggests converting the below (or the bmiRanges themselves) into a RangeMap.
    if (bmi < bmiRangesToUse[0]) {
        outcome = "Underweight";
    } else if (bmi >= bmiRangesToUse[0] && bmi <= bmiRangesToUse[1]) {
        outcome = "Healthy";
    } else if (bmi > bmiRangesToUse[1] && bmi <= bmiRangesToUse[2]) {
        outcome = "Overweight";
    } else if (bmi > bmiRangesToUse[2]) {
        outcome = "Obese";
    }

    return outcome;
}
like image 96
Barett Avatar answered Nov 05 '22 19:11

Barett