A Variable doesn't exist in the current context - c#

(I'm a beginner and just started learning C# in college/A-level, so my code is really inefficient).
Anyway, the code below is just a part of my "CinemaBookingSystem" and because my variable filmName is declared outside of my switch case, it says that "filmName" does not do not exist in this context. I tried using the "public static string filmname = "example";" method but that won't work because I'm declaring filmname more than once inside different if statements.
if (filmNum == 1)
string filmName = "Teenage Horror Film";
if (filmNum == 2)
;
string filmName = "How I Live Now";
switch (filmNum)
{
case 1:
case 2:
if (Age >= 15)
{
Console.WriteLine("What date do you want to watch the film? (Format : dd/mm/yyyy) :");
DateTime dateChoice = DateTime.Parse(Console.ReadLine());
DateTime now = DateTime.Now;
DateTime limit = now.AddDays(7);
if (dateChoice >= now && dateChoice <= limit)
{
Console.WriteLine("--------------------");
Console.WriteLine("Aquinas Multiplex");
Console.WriteLine("Film : {0}", filmName);
Console.WriteLine("Date : {0}", dateChoice);
Console.WriteLine("--------------------");
}
else
{
Console.WriteLine("Access denied - date is invalid");
}
}
while (Age < 15)
{
Console.WriteLine("Access denied - You are too young");
}
break;
}

Kenny, since you declare variable filmName in condition statement it is not accessible in switch. You need to declare it before if:
string filmName = string.empty;
if (filmNum == 1) ;
{
filmName = "Teenage Horror Film";
}
if (filmNum == 2) ;
{
filmName = "How I Live Now";
}
switch (filmNum)
{
case 1: case 2:
if (Age >= 15)
{
Console.WriteLine("What date do you want to watch the film? (Format : dd/mm/yyyy) :");
DateTime dateChoice = DateTime.Parse(Console.ReadLine());
DateTime now = DateTime.Now;
DateTime limit = now.AddDays(7);
if (dateChoice >= now && dateChoice <= limit)
{
Console.WriteLine("--------------------");
Console.WriteLine("Aquinas Multiplex");
Console.WriteLine("Film : {0}", filmName);
Console.WriteLine("Date : {0}", dateChoice);
Console.WriteLine("--------------------");
}
else
{
Console.WriteLine("Access denied - date is invalid");
}
}
while (Age < 15)
{
Console.WriteLine("Access denied - You are too young");
}
break;
}
}
}

You need to declare it outside of the if statements and just asign the value inside (make sure there is a default value in case neither if gets triggered).
Also you have semicolons right behind your if statements.

Related

Why cant I later add a value to my string variable through if-statements and run the output code in C#?

I want to run the gradeStatus in the Console.WriteLine but I fail...
I've almost checked all posts to some extent relevant but none have resolved my problem, please guide?
Console.WriteLine("Type in grade to get stats!");
int gradeScore = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Grade Score: {0}", gradeScore);
bool isPassed;
if (gradeScore >= 50)
{
isPassed = true;
}
else
{
isPassed = false;
}
Console.WriteLine("Passed: {0}", isPassed);
string gradeStatus;
if(gradeScore == 50)
{
gradeStatus = "Okay";
}
else if (gradeScore == 60)
{
gradeStatus = "Good";
}
else if (gradeScore >= 70)
{
if (gradeScore == 70)
{
gradeStatus = "Great";
}
else if (gradeScore == 80)
{
gradeStatus = "Great";
}
}
else if (gradeScore == 90)
{
gradeStatus = "Excellent";
}
else if (gradeScore == 100)
{
gradeStatus = "Ace!";
}
Console.WriteLine("Grade Status: {0}", gradeStatus);
The problem is with your if statements. What you are probably wanting is the below portion of code for your set of if else statements.
if(gradeScore <= 50)
{
gradeStatus = "Okay";
}
else if (gradeScore <= 60)
{
gradeStatus = "Good";
}
else if (gradeScore <= 70)
{
gradeStatus = "Great";
}
else if (gradeScore <= 80)
{
gradeStatus = "Great";
}
else if (gradeScore <= 90)
{
gradeStatus = "Excellent";
}
else if (gradeScore <= 100)
{
gradeStatus = "Ace!";
}
For a problem like this one, it is often much easier to break the logic into a separate function. When you use a separate function, you can use early return to avoid else. That makes the logic much more plain and easy to read, and less prone to error.
For example, you could write a function like this one:
static string GetGradeStatus(int score)
{
if (score <= 50) return "Okay";
if (score <= 60) return "Good";
if (score <= 70) return "Great";
if (score <= 80) return "Great";
if (score <= 90) return "Excellent";
return "Ace";
}
And modify your code to use it:
Console.WriteLine("Type in grade to get stats!");
int gradeScore = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Grade Score: {0}", gradeScore);
var isPassed = gradeScore > 50;
Console.WriteLine("Passed: {0}", isPassed);
var gradeStatus = GetGradeStatus(gradeScore);
Console.WriteLine("Grade Status: {0}", gradeStatus);
This is easier to read and makes it very plain if you've got a logic error (e.g. it is obvious that "Great" is used twice, which is what your existing code does).
I also made two other changes:
I changed = to <= since there is nothing preventing the user from entering a number that is not a multiple of 10. That was just a guess. You might need to tweak the logic to meet your requirements correctly.
I changed the if/else assignment of isPassed to a simple Boolean assignment, which is idiomatic for c# and easier to read once you get used to it.

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
A switch command calls 2 actions when number 1 and number 2 is
pressed on the keyboard.
When pressing 1 everything works fine and
does what it should.
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.
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.

How to save a variables value when leaving the method?

I have a method which counts the amount of times a user has withdrawn from the atm(as there is a limit) and also counts up the amount of money the user has withdrawn in the day. However the values in the count var and in the amountWithdrawn variable are both lost upon leaving the method, how do I keep them "saved"? Also as a side note, I have a class called Account which has the balance and such, would it be best to put them there? But would also like to know if it is possible to save the variables in the method for future reference.
public decimal WithDraw()
{
int timesWithdrawn = 9;
decimal amountWithdrawnToday = 0;
decimal money = 0;
bool success = false;
if (timesWithdrawn < 10)
{
do
{
//Console.WriteLine("{0} available to withdraw.", FundsAvailable);
Console.WriteLine("How much would you like to withdraw?");
try
{
money = decimal.Parse(Console.ReadLine());
if (money % 5 == 0 && money <= account.CurrentBalance && money <= 1000)
{
success = true;
}
if (money == 0)
{
bool exit = true;
Console.WriteLine("Do you want to exit? Type \"yes\", or \"no\".");
while (exit == true)
{
string response = Console.ReadLine();
if (response.ToLower() == "yes")
{
break;
}
else
{
exit = false;
}
}
}
}
catch (FormatException)
{
Console.WriteLine("Please enter a number to withdraw.");
}
} while (success == false);
//do while this is true
Console.WriteLine(account.CurrentBalance);
Console.WriteLine("Withdrawing {0} pounds.", money);
Console.WriteLine("You have {0} remaining in your account.", account.CurrentBalance - money);
amountWithdrawnToday += money;
timesWithdrawn += 1;
Console.WriteLine("{0} pounds withdrawn today", amountWithdrawnToday);
return account.CurrentBalance -= money;
}
else
{
Console.WriteLine("You have exceeded daily withdrawls. You have withdrawn {0}", amountWithdrawnToday);
return amountWithdrawnToday;
}
}
I will suggest you need to put those variable in the Account class, also I suggest that you could put the withdraw method itself in the Account class, This could be more OOP friendly.
and to save the timesWithdrawn number, you just need to make it as class instance vairable instead of making it local variable
here is the code
class Account
{
public decimal CurrentBalance { get; set; }
public int timesWithdrawn { get; set; } = 9;
public decimal WithDraw()
{
decimal amountWithdrawnToday = 0;
decimal money = 0;
bool success = false;
if (timesWithdrawn < 10)
{
do
{
//Console.WriteLine("{0} available to withdraw.", FundsAvailable);
Console.WriteLine("How much would you like to withdraw?");
try
{
money = decimal.Parse(Console.ReadLine());
if (money % 5 == 0 && money <= CurrentBalance && money <= 1000)
{
success = true;
}
if (money == 0)
{
bool exit = true;
Console.WriteLine("Do you want to exit? Type \"yes\", or \"no\".");
while (exit == true)
{
string response = Console.ReadLine();
if (response.ToLower() == "yes")
{
break;
}
else
{
exit = false;
}
}
}
}
catch (FormatException)
{
Console.WriteLine("Please enter a number to withdraw.");
}
} while (success == false);
//do while this is true
Console.WriteLine(CurrentBalance);
Console.WriteLine("Withdrawing {0} pounds.", money);
Console.WriteLine("You have {0} remaining in your account.", CurrentBalance - money);
amountWithdrawnToday += money;
timesWithdrawn += 1;
Console.WriteLine("{0} pounds withdrawn today", amountWithdrawnToday);
return CurrentBalance -= money;
}
else
{
Console.WriteLine("You have exceeded daily withdrawls. You have withdrawn {0}", amountWithdrawnToday);
return amountWithdrawnToday;
}
}
}
as you notice from the code, I removed the reference to the account variable and made the CurrentBalance as instance variable and also the timesWithdrawn.
this could preserve the value of the timesWithdrawn even after the method has been finished.
As long as the program is running it is saved there, but once quite it resets, so yes you have to save it somewhere in a database a excel table or in a text document
Saving data to a file in C#
check this out if you need some help how to do stuff like this
You could pass an 'out' parameter to the function, it's basically a variable you send to the function, which holds its value outside the function.
For example:
public void WithDraw(out int c) {
c = something ; //c must receive a value during the call
}
int myvar; // the parameter which will hold the value when the function returns
WithDraw(out myvar); //call to the function
myvar //will now hold a value from the function (something)
You could also consider returning a tuple, or putting the value you wish to save into a 'global variable'.

FormatException C#

so I'm currently taking a course on C# programming to get freshened up.
Turned out I forgot some important things!
namespace FitnessFrog
{
class Program
{
static void Main()
{
int runningTotal = 0;
bool keepGoing = true;
while(keepGoing)
{
// Prompt the user for minutes exercised
Console.Write("Enter how many minutes you exercised or type \"quit\" to exit: ");
string input = Console.ReadLine();
if (input == "quit")
{
keepGoing = false;
}
else
{
try
{
int minutes = int.Parse(input);
runningTotal = runningTotal + minutes;
if(minutes <= 0)
{
Console.WriteLine("Eh, what about actually exercising then?");
continue;
}
else if(minutes <= 10)
{
Console.WriteLine("Better than nothing, am I right?");
}
else if (minutes <= 24)
{
Console.WriteLine("Well done, keep working!");
}
else if (minutes <= 60)
{
Console.WriteLine("An hour, awesome! Take a break, ok?");
}
else if (minutes <= 80)
{
Console.WriteLine("Woah, remember to drink if you're going to exercise THAT long!");
}
else
{
Console.WriteLine("Okay, now you're just showing off!");
}
Console.WriteLine("You've exercised for " + runningTotal + " minutes");
}
catch(FormatException)
{
Console.WriteLine("That is not valid input");
continue;
}
// Repeat until the user quits
}
}
}
}
}
So I'm trying to make it say "This is not valid input" when you type a string instead of an integer.
Thanks in advance! <3
int minutes = int.Parse(input); - you should use TryParse() instead of Parse()
int minutes;
bool parsed = int.TryParse(input, out minutes);
if (parsed)
{
// your if statements
}
else
{
Console.WriteLine("That is not valid input");
}
You should use int.TryParse instead for Parse, since it having internal exception handling mechanisms, And you can use it's return value(true/false)to check whether the operation is successful or not, for a successful conversion it will return true, and the return value for a failure conversion will be false
int minutes;
if(!int.TryParse(input,out minutes)
{
Console.WriteLine("invalid input");
}
else
{
// Proceed
}
If you are receiving input from your users, you will want to consider actually using the Int32.TryParse() method to determine if the parse was successful or not :
int minutes;
// Attempt the parse here
if(Int32.TryParse(input, out minutes))
{
// The parse was successful, your value is stored in minutes
}
else
{
// The parse was unsuccessful, consider re-prompting the user
}

Having trouble with code to convert number into a month

here is my source code, everything is good until i get to the output and I cant get this to work. Visual Studio doesn't like what I have in the output section, labeled //OUTPUT.
What do I need to add or change to get this to work?
static void Main(string[] args)
{
int monthNumber;
string monthName;
//INPUT
Console.WriteLine("Please enter the number of the month");
monthNumber = Convert.ToInt16(Console.ReadLine());
//PROCCESSESS
if (monthNumber == 1)
{
monthName = "January";
}
else if (monthNumber == 2)
{
monthName = "February";
}
else if (monthNumber == 3)
{
monthName = "March";
}
else if (monthNumber == 4)
{
monthName = "April";
}
else if (monthNumber == 5)
{
monthName = "May";
}
else if (monthNumber == 6)
{
monthName = "June";
}
else if (monthNumber == 7)
{
monthName = "July";
}
else if (monthNumber == 8)
{
monthName = "August";
}
else if (monthNumber == 9)
{
monthName = "September";
}
else if (monthNumber == 10)
{
monthName = "October";
}
else if (monthNumber == 11)
{
monthName = "November";
}
else if (monthNumber == 12)
{
monthName = "December";
}
//space to increase readability
Console.WriteLine(Environment.NewLine);
//OUTPUT
Console.WriteLine("Month:" + monthName);
Console.ReadLine();
}
monthName must be initialized before use. So you can change the declaration line as
string monthName = null;
That's because the code does not guarantee that monthName gets assigned. For example what if the input number is 13?
You have a lot of else if, but in the end, there's no else to cover the case where none of the if apply. Therefore the compiler can't guarantee that monthName was ever assigned. Maybe the user typed "28"?
It would look better to use a switch statement with twelve case sections and one default section.
But also, the month names are built into the framework. So with using System.Globalization; you could simply say
monthName = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(monthNumber);
or
monthName = CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(monthNumber);
You can also get a DateTime directly from the input:
DateTime dateTime = DateTime.ParseExact(Console.ReadLine(), "%M", null);
Then
monthName = dateTime.ToString("MMMM");
a) declare a variable
b) if you are using month names, and you want some specific names, try using enum. really eazy and functional.
You can make your own setup of names/markings with your own pace of numbering those names/markings.
For Eg.
enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

Categories