-1

So I'm trying to start coding again(done a year in college before and thinking of going back but need to get back into swing of things. Doing this simple console application and getting this error.

Use of unassigned local variable

I tried setting calories to null, 0, 200 etc in different parts of code but none of it seems to help.

    static void Main(string[] args)
    {
        Console.WriteLine("Gender: Male(M)/Female(F)?");
        string gender = Console.ReadLine().ToLower();
        Console.WriteLine("Age?");
        int age = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("Height?");
        int height = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("Weight in KG?");
        int weightKG = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("How active are you?(Choose by inserting the number)");
        Console.WriteLine("1.No exercise");
        Console.WriteLine("2.Little to no exercise");
        Console.WriteLine("3.Light exercise(1-3 days a week)");
        Console.WriteLine("4.Moderate exercise(3-5 days a week");
        Console.WriteLine("5.Heavy exercise(6-7days a week)");
        Console.WriteLine("6.Very heavy exercise(Twice per day, extra heavy workouts");
        int activityLevel = Convert.ToInt32(Console.ReadLine());

        if (gender == "m")
        {
            int calories = Convert.ToInt32(66.4730 + (13.7516 * weightKG) + (5.0033 * height) - (6.7550 * age));
           // Console.WriteLine("Your daily calories are: {0}kcal",calories);
        }
        else if (gender == "f")
        {
            int calories = Convert.ToInt32(655.0955 + (9.5634 * weightKG) + (1.8496 * height) - (4.6756 * age));
           // Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else
        {
            Console.WriteLine("Please choose correct gender Male(M) or Female(F).");
        }

        if (activityLevel == 0)
        {
            int calories = Convert.ToInt32(calories * 1);
            Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else if (activityLevel == 1)
        {
            int calories = Convert.ToInt32(calories * 1.2);
            Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else if (activityLevel == 2)
        {
            int calories = Convert.ToInt32(calories * 1.375);
            Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else if (activityLevel == 3)
        {
            int calories = Convert.ToInt32(calories * 1.55);
            Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else if (activityLevel == 4)
        {
            int calories = Convert.ToInt32(calories * 1.725);
            Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else if (activityLevel == 5)
        {
            int calories = Convert.ToInt32(calories * 1.9);
            Console.WriteLine("Your daily calories are: {0} kcal", calories);
        }
        else
        {
            Console.WriteLine("Please choose a number between 0 and 5");
        }


    }
}

}

  • There’s many errors here and you haven’t specified where exactly the error you mention happens. Hint: you really don’t want to have local variables inside the ifs – Sami Kuhmonen Sep 15 '19 at 18:37
  • I don’t see the issue with creating a local variable inside the if block if its scope is just that block. But equally I can’t see which variable is unassigned in that rather long code snippet. Can you enlighten us @Bart Bartowski? – iakobski Sep 15 '19 at 18:48
  • Sorry I forgot to say the errors only occur in the second IF statement. And its the calories variable. – Bart Bartowski Sep 15 '19 at 18:54
  • The compiler's emitting that error because of exactly what the error says: you are attempting to use the `calories` variable before you've set its value to anything. See marked duplicate for at least a little more detail (not that any really ought to be required). – Peter Duniho Sep 15 '19 at 23:57

3 Answers3

0

You are declaring a variable and then using it in a calculation.

int calories = Convert.ToInt32(calories * 1);

This effectively the same as 0*n;

Should the variable hold a value then move it the declaration to below this line:

int activityLevel = Convert.ToInt32(Console.ReadLine());

So...int calories = 0;

static void Main(string[] args)
{
    Console.WriteLine("Gender: Male(M)/Female(F)?");
    string gender = Console.ReadLine().ToLower();
    Console.WriteLine("Age?");
    int age = Convert.ToInt32(Console.ReadLine());
    Console.WriteLine("Height?");
    int height = Convert.ToInt32(Console.ReadLine());
    Console.WriteLine("Weight in KG?");
    int weightKG = Convert.ToInt32(Console.ReadLine());
    Console.WriteLine("How active are you?(Choose by inserting the number)");
    Console.WriteLine("1.No exercise");
    Console.WriteLine("2.Little to no exercise");
    Console.WriteLine("3.Light exercise(1-3 days a week)");
    Console.WriteLine("4.Moderate exercise(3-5 days a week");
    Console.WriteLine("5.Heavy exercise(6-7days a week)");
    Console.WriteLine("6.Very heavy exercise(Twice per day, extra heavy workouts");
    int activityLevel = Convert.ToInt32(Console.ReadLine());
    int calories = 0;

    if (gender == "m")
    {
        calories = Convert.ToInt32(66.4730 + (13.7516 * weightKG) + (5.0033 * height) - (6.7550 * age));
        // Console.WriteLine("Your daily calories are: {0}kcal",calories);
    }
    else if (gender == "f")
    {
        calories = Convert.ToInt32(655.0955 + (9.5634 * weightKG) + (1.8496 * height) - (4.6756 * age));
        // Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else
    {
        Console.WriteLine("Please choose correct gender Male(M) or Female(F).");
    }

    if (activityLevel == 0)
    {
        calories = Convert.ToInt32(calories * 1);
        Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else if (activityLevel == 1)
    {
        calories = Convert.ToInt32(calories * 1.2);
        Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else if (activityLevel == 2)
    {
        calories = Convert.ToInt32(calories * 1.375);
        Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else if (activityLevel == 3)
    {
        calories = Convert.ToInt32(calories * 1.55);
        Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else if (activityLevel == 4)
    {
        calories = Convert.ToInt32(calories * 1.725);
        Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else if (activityLevel == 5)
    {
        calories = Convert.ToInt32(calories * 1.9);
        Console.WriteLine("Your daily calories are: {0} kcal", calories);
    }
    else
    {
        Console.WriteLine("Please choose a number between 0 and 5");
    }
}
Simon Wilson
  • 9,929
  • 3
  • 27
  • 24
0

This happens because you are actualy creating new int variable in each block. When you define variable and assigne value to it, that variable and its value "exists" only in current context - for simplicity think of this context as everything between direct parent {} braces. So when you define

if (gender == "m")
{
   int calories = Convert.ToInt32(66.4730 + (13.7516 * weightKG) + (5.0033 * height) - (6.7550 * age));
   // Console.WriteLine("Your daily calories are: {0}kcal",calories);
}

the calories variable is visible only inside the if statement {} bracers. So easy fix to this is to declare calories variable outside of {}.

int baseCalories = 0;
if (gender == "m")
{
   baseCalories = Convert.ToInt32(66.4730 + (13.7516 * weightKG) + (5.0033 * height) - (6.7550 * age));
   // Console.WriteLine("Your daily calories are: {0}kcal",calories);
}
else if (gender == "f")
{
   baseCalories = Convert.ToInt32(655.0955 + (9.5634 * weightKG) + (1.8496 * height) - (4.6756 * age));
   // Console.WriteLine("Your daily calories are: {0} kcal", calories);
}
else
{
   Console.WriteLine("Please choose correct gender Male(M) or Female(F).");
}

and then use this baseCalories variable inside other if statements. To learn more about the scopes of variables read for example this.

Marmellad
  • 301
  • 2
  • 12
0

As for your question (about the error). Basically, the variable is visible inside the blocks that you declare it in. if you declare it inside an if block, then it will be visible only inside that if block. if you declare it inside a class block, it'll be visible inside that class and its methods, and also possible other classes if you use the correct access modifiers.

So, if you need to access a variable, you need to choose where to declare it based on its usage.

However, this is not the only issue you have. You're taking user input and using it directly. This is not the best practice. you'll need to validate the values before using them. Otherwise, you'll be dealing with a lot of exceptions that will be thrown on each point of your code, and the bigger the application the worse it'll get.

here is some points that will help you improve your code :

Validate user input before using it, this means you'll store the user input inside a temporary variable, then pass it into your validation logic, if passed the validation process, then assign its value to the original variable.

Model your application. C# is Object-Oriented-Programming language. It's easier to build a code structure that makes it easier to read, maintain, and expand. For instance, if your application depends on certain values (like gender, age, height, weight), why not creating a model that will store these values, and then you can pass this model on your code back and forth.

public class PersonInfo
{
    public string Gender { get; set; }

    public int Age { get; set; }

    public int Height { get; set; }

    public int Weight { get; set; }

    public int ActivityLevel { get; set; }

    public double Calories { get; set; }

}

With this, you'll always use this model in your code, and you'll know the values are store inside this model, which can make your work much easier.

Make use of Enum enum is there for a reason. It'll be useful to use it. in your case, you can use it for the type of input like this :

public enum InputType { Age, Height, Weight, ActivityLevel }

Don't convert the source values You need to keep the source as is. If you need to display the values in different types such as from decimals to int. You can convert them at run-time, but don't touch the source. This is because you may need to re-use the source values somewhere else in the code. So, if you convert the source, it'll mess things up.

Use the proper methods sometimes, you'll hit a point where you'll need to use for instance loops, but for some reason you just skip that needs. This will probably causes some bugs and issues in the code logic. For instance, your application required age, height, weight, and activity level in order to calculate the calories. If one of them is missing, then the formula is wrong, and if the formula is wrong. if you only get the value onetime, and never go back if invalid, then there is no reason of using the formula at all, since the values are wrong. So, for this, you want to make sure you'll get each one of them before run the formula. Either you create a loop and keep tracking of user input, if invalid just force the user to input valid value. Or simply exit the application.

Code Reuse Always code with the intention of reusing the same code even if you know it won't be reused anywhere else. This means, you'll take some parts of the code and place them in a position where it can be reused and maintained easily. An example of that, gender, you can put it in a method and recall it. Calories formula also can be used as method, and so on.

Finally, I put together a sample of these points to give more visual thoughts, and I hope it'll help.

// Person Information Model
public class PersonInfo
{
    public string Gender { get; set; }

    public int Age { get; set; }

    public int Height { get; set; }

    public int Weight { get; set; }

    public int ActivityLevel { get; set; }

    public double Calories { get; set; }

}
class Program
{
    private static PersonInfo info = new PersonInfo();

    public enum InputType { Age, Height, Weight, ActivityLevel }


    static void Main(string[] args)
    {

        // default is null, to tell the application is invalid input
        string _gender = null;

        // keep the user inside this loop as long as the input is invalid.
        while (_gender == null)
        {
            Console.WriteLine("Gender: Male(M)/Female(F)?");
            _gender = GetGender(Console.ReadLine());

            if (_gender == null)
                Console.WriteLine("Gender has not been specified correctly. Please retype it.");
        }

        // it'll not go out of the loop until the user input is correct.
        info.Gender = _gender;

        // Create an array of inputs that you'll take from the user. 
        InputType[] inputs = { InputType.Age, InputType.Height, InputType.Weight, InputType.ActivityLevel };


        bool hasError = false;
        // Loop over the required inputs, and don't go to the next one until the user input a correct value.
        for (int x = 0; x < inputs.Length; x++)
        {
            double userinput;

            if (hasError)
                x--;

            if (inputs[x] != InputType.ActivityLevel)
            {
                Console.WriteLine("{0}? {1} ", inputs[x].ToString(), x);
                userinput = GetInt(Console.ReadLine(), inputs[x]);
            }
            else
            {
                Console.WriteLine("How active are you?(Choose by inserting the number)");
                Console.WriteLine("1.No exercise");
                Console.WriteLine("2.Little to no exercise");
                Console.WriteLine("3.Light exercise(1-3 days a week)");
                Console.WriteLine("4.Moderate exercise(3-5 days a week");
                Console.WriteLine("5.Heavy exercise(6-7days a week)");
                // Console.WriteLine("6.Very heavy exercise(Twice per day, extra heavy workouts");

                userinput = GetInt(Console.ReadLine(), InputType.ActivityLevel);

                if (userinput >= 0 && userinput < 6)
                {
                    info.ActivityLevel = (int)userinput;
                    info.Calories = GetCalories(info.Gender, info.Weight, info.Height, info.Age, info.ActivityLevel);
                }
                else
                {
                    //reset input 
                    userinput = -1;
                    Console.WriteLine("Please choose a number between 0 and 5");
                }


            }

            if (userinput != -1)
            {
                SetValues((int)userinput, inputs[x]);
                hasError = false;
            }
            else
            {
                Console.WriteLine("{0} has not been specified correctly. Please retype it.", inputs[x].ToString());
                hasError = true;
            }
        }


        // Now, you can show the user info with the calories as well. 

        Console.WriteLine("Your Gender\t\t:\t{0}", info.Gender);
        Console.WriteLine("Your Age\t\t:\t{0}", info.Age);
        Console.WriteLine("Your Height\t\t:\t{0}", info.Height);
        Console.WriteLine("Your Weight\t\t:\t{0}", info.Weight);
        Console.WriteLine("Your Activity Level\t:\t{0}", info.ActivityLevel);
        Console.WriteLine("Your daily calories\t:\t{0} kcal", Math.Round(info.Calories));


        Console.ReadLine();

    }


    public static string GetGender(string input)
    {
        if (!string.IsNullOrEmpty(input))
        {
            switch (input.ToLower())
            {
                case "m":
                case "male":
                    return "m";
                case "f":
                case "female":
                    return "f";
                default:
                    return null;
            }
        }
        else
        {
            return null;
        }

    }

    public static double GetActivityLevel(int level)
    {
        switch (level)
        {
            case 0:
                return 1;
            case 1:
                return 1.2;
            case 2:
                return 1.375;
            case 3:
                return 1.55;
            case 4:
                return 1.725;
            case 5:
                return 1.9;
            default:
                return -1;
        }

    }

    public static int GetInt(string input, InputType type)
    {
        if (!string.IsNullOrEmpty(input))
        {
            if (int.TryParse(input, out int result))
            {
                return result;
            }
            else
            {
                return -1;
            }
        }
        else
        {
            Console.WriteLine(type.ToString() + " is empty");
            return -1;
        }
    }


    public static void SetValues(int input, InputType type)
    {
        switch (type)
        {
            case InputType.Age:
                info.Age = input;
                break;
            case InputType.Weight:
                info.Weight = input;
                break;
            case InputType.Height:
                info.Height = input;
                break;
        }
    }

    public static double GetCalories(string gender, int weight, int height, int age, int activityLevel)
    {

        if (string.IsNullOrEmpty(gender))
        {
            Console.WriteLine("Gender has not been specified");
            return -1;
        }
        else
        {
            double _cal;

            var _level = GetActivityLevel(activityLevel);

            if (gender == "m")
                _cal = (66.4730 + (13.7516 * weight) + (5.0033 * height) - (6.7550 * age));
            else
                _cal = (655.0955 + (9.5634 * weight) + (1.8496 * height) - (4.6756 * age));

            //check first Activity Level, if is it -1 then it's invalid input, those it'll return it.
            return _level != -1 ? _cal * _level : -1;

        }

    }
iSR5
  • 3,274
  • 2
  • 14
  • 13