Search code examples
c#divide-by-zero

Dividing by Zero Exeption, knowing why it gets thrown, not knowing how to fix it


For better understanding I will first post my Program Class.

Program.cs

namespace BeginnersGuidToLifting
{
    class Program
    {
        public static readonly int width = 85;
        public static readonly int height = 35;


        public static readonly User user = new User();
        public static readonly Goal goal = new Goal();
        public static Calories calories = new Calories();
        public static Nutrition nutrition = new Nutrition();
        public static Menu menu = new Menu();

        static void InitUser()
        {
            Console.WriteLine("\n### About You ###\n");

            user.Name = Question.AskString("Name: ");
            user.Age = Question.AskInt("Age: ");
            user.Gender = Question.AskString("Gender(m/f): ");
            user.Height = Question.AskInt("Height(cm): ");
            user.Weight = Question.AskInt("Weight(kg): ");

        }

        static void InitGoals()
        {
            Console.WriteLine("\n### What are your Goals ### \n");

            goal.GainWeight();
            goal.LoseWeight();
            goal.GetStronger();
            goal.GetLeaner();
            goal.StayFit();
            goal.Hypertrophy();

            Console.Write("Answer: ");
            var input = Console.ReadKey();

            switch (input.Key)
            {
                case ConsoleKey.D1:
                    goal.GoalStatusGainWeight = true;
                    goal.GoalMessage = "Your Goal is to Gain Weight";
                    break;
                case ConsoleKey.D2:
                    goal.GoalStatusLoseWeight = true;
                    goal.GoalMessage = "Your Goal is to Lose weight";
                    break;
                case ConsoleKey.D3:
                    goal.GoalStatusGetStronger = true;
                    goal.GoalMessage = "Your Goal is to get Stronger";
                    break;
                case ConsoleKey.D4:
                    goal.GoalStatusGetLeaner = true;
                    goal.GoalMessage = "Your Goal is to get Leaner";
                    break;
                case ConsoleKey.D5:
                    goal.GoalStatusStayFit = true;
                    goal.GoalMessage = "Your Goal is to Stay Fit";
                    break;
                case ConsoleKey.D6:
                    goal.GoalStatusHypertrophy = true;
                    goal.GoalMessage = "Your Goal is Hypertrophy";
                    break;
                default:
                    Console.WriteLine("Error");
                    break;
            }
        }

        static void InitMenu()
        {
            menu.ShowMenu();
            menu.Discalmer = false;
            //menu.Disclamer();

        }

        static void BmiResult()
        {
            var bodyType = user.GetBodyType();

            if (bodyType == User.BodyType.ReallyUnderweight)
            {
                Console.WriteLine("Really Underweigt");
            }
            else if (bodyType == User.BodyType.Underweight)
            {
                Console.WriteLine("Underweight");
            }
            else if (bodyType == User.BodyType.CloseToUnderwight)
            {
                Console.WriteLine("Close to Underweight");
            }
            else if (bodyType == User.BodyType.Healthy)
            {
                Console.WriteLine("at a Healthy Weight");
            }
            else if (bodyType == User.BodyType.Overweight)
            {
                Console.WriteLine("Overweight");
            }
            else if (bodyType == User.BodyType.Obese)
            {
                Console.WriteLine("Obese");
            }
            else if (bodyType == User.BodyType.SeverlyObese)
            {
                Console.WriteLine("Serverley Obese");
            }
            else if (bodyType == User.BodyType.MorbidlyObese)
            {
                Console.WriteLine("Morbidly Obese");
            }
        }

        static void Main(string[] args)
        {


            Console.Title = "Beginers Guide To Lifting";
            Console.SetWindowSize(width, height);
            Console.SetBufferSize(width, height);


            InitMenu();

            var userInput = Console.ReadKey();
            switch (userInput.Key)
            {
                case ConsoleKey.D1:
                    InitUser();
                    InitGoals();
                    break;
                case ConsoleKey.D2:
                    Console.WriteLine("Press 2");
                    break;
                default:
                    Console.WriteLine("Why y no work");
                    break;
            }


            //Status So Far
            Console.WriteLine("\n### Your Stats ### \n");

            Console.WriteLine("Name: {0} \nAge: {1} \nHeight: {2} \nWeight: {3}", user.Name, user.Age, user.Height, user.Weight);
            Console.WriteLine("Goal: {0}", goal.GoalMessage);

            BmiResult();


            Console.Write("\nContinue(y/n) to The Programm?: ");
            if (Console.ReadLine() == "y")
            {
                Console.Clear();
            }

            //Gain Weight Goal
            //Introduce 5x5
            var exercise = new FiveByFive();
            exercise.printIntroduction();

            //Show Exercises
            exercise.printWorkoutWeek1();
            exercise.printWorkoutWeek2();

            //Show Nutrition
            if (goal.GoalStatusGainWeight == true)
            {
                switch (user.Gender)
                {
                    case "male":
                    case "m":
                    case "Male":
                        calories.GainCaloriesMale(user);
                        break;
                    case "female":
                    case "f":
                    case "Female":
                        calories.GainCaloriesFemale(user);
                        break;
                }
            }

            //Lose Weight
            if (goal.GoalStatusLoseWeight == true)
            {
                switch (user.Gender)
                {
                    case "male":
                    case "m":
                    case "Male":
                        calories.LoseCaloriesMale(user);
                        break;
                    case "female":
                    case "f":
                    case "Female":
                        calories.LoseCaloriesFemale(user);
                        break;
                }
            }
        }
    }
}

The Problem is in my Main Method.

        InitMenu();

        var userInput = Console.ReadKey();
        switch (userInput.Key)
        {
            case ConsoleKey.D1:
                InitUser();
                InitGoals();
                break;
            case ConsoleKey.D2:
                Console.WriteLine("Press 2");
                break;
            default:
                Console.WriteLine("Why y no work");
                break;
        }

When I press one, it should happen what it shows. Init User and Init User Goals. How ever when i press 2 it brings me to the User.cs class, where i am doing the Math for the Users BMI.

I dont really understand why it would do that when pressing 2, because all i want to display is "Press 2" Or later to be added A disclamer.

The Exeption

System.DivideByZeroException: 'Attempted to divide by zero.'

Is thrown because it tries to divde 0 with 0 and that is because there is no input from the user yet. Because all i would like to do by pressing 2 is display another window with some text. And that is is.

I really dont understand why it jumps to the User class.

Here is User.cs for better understanding.

namespace BeginnersGuidToLifting
{
    class User
    {
        public enum BodyType
        {
            ReallyUnderweight,
            Underweight,
            CloseToUnderwight,
            Healthy,
            Overweight,
            Obese,
            SeverlyObese,
            MorbidlyObese
        }

        public string Name;
        //private string _gender;
        public string Gender;
        private int _weight;
        private int _height;
        private int _age;

        public int Age
        {
            get => _age;
            set
            {
                if (value >= 0)
                {
                    _age = value;
                }
            }
        }

        public int Weight
        {
            get => _weight;
            set
            {
                if (value >= 0)
                {
                    _weight = value;
                }
            }
        }

        public int Height
        {
            get => _height;
            set
            {
                if (value >= 0)
                {
                    _height = value;
                }
            }
        }

        //TODO
        //public string Gender
        //{

        //    get => _gender;
        //    set
        //    {
        //        if (value == "female" || value == "f" || value == "male" || value == "m" )
        //        _gender = value;
        //        else
        //        {
        //            Console.WriteLine("Value Wrong");
        //        }
        //    }
        //}


        public int GetBmi()
        {
            Console.WriteLine("Weight:"+Weight);
            //var bmi = Math.Round((Weight / Math.Pow(Height, 2)) * 10000);
            int bmi = Weight / (Height * Height) * 10000;
            Console.WriteLine("Your Body Mass Index: " + bmi);
            Console.Write("That Means That you are: ");
            return bmi;
        }

        public BodyType GetBodyType()
        {
            int bmi = GetBmi();

            if (bmi < 16)
                return BodyType.ReallyUnderweight;
            else if (bmi >= 16 && bmi <= 17)
                return BodyType.Underweight;
            else if (bmi >= 17 && bmi <= 18.5)
                return BodyType.CloseToUnderwight;
            else if (bmi >= 18.5 && bmi <= 25)
                return BodyType.Healthy;
            else if (bmi >= 25 && bmi <= 30)
                return BodyType.Overweight;
            else if (bmi >= 30 && bmi <= 35)
                return BodyType.Obese;
            else if (bmi >= 35 && bmi <= 40)
                return BodyType.SeverlyObese;

            return BodyType.MorbidlyObese;
        }
    }
}

Summary

  1. A switch command calls 2 actions when number 1 and number 2 is pressed on the keyboard.
  2. When pressing 1 everything works fine and does what it should.
  3. When pressing 2 it tries to do the math for something there is no input yet, Because input is only asked when pressing 1.

Thank you in advance for taking the time to read this. Any input is welcome. I hope everything is clear to understand.


Solution

  • After you press '2' and it exits the switch, it calls BmiResult(), which calls methods in the user class.

    BmiResult() calls user.GetBodyType(), which calls GetBmi() on the user class. This is where your calculation happens, but since you didn't set any of the values on the user, every thing defaults to zero. Which means you are doing this:

    int bmi = 0 / (0 * 0) * 10000;
    

    Order of operations means it does this:

    int bmi = (0 / 0) * 10000;
    

    because division and multiplication are executed within parantheses first, then left to right.

    However, multiplying zero by anything would still be zero, so you need to check if the divisor would be zero before doing the calculation, or wrap the code in a try/catch and handle it.