Having an issue calling methods from another class - c#

I'm having an issue with calling methods from another class in C#. I haven't been doing this long (3 weeks to be exact) and don't get the ideas behind calling methods. I have declared everything as public to try to make it easier but it isn't working for me just yet. Any help at all would be very much appreciated. Here is the code in question, I want to use a method in an if statement to calculate the area of various simple shapes however at the output stage I get "That is not a valid choice"
namespace Area_Calculator
{
public class Area
{
public static int Square(int side)
{
int i, A;
Console.WriteLine("Please enter the length of the side of the square");
i = Convert.ToInt16(Console.ReadLine());
A = i * i;
return A;
}
public static int Rectangle(int width, int height)
{
int i, j, A;
Console.WriteLine("Please enter the width of the rectangle");
i = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Please enter the height of the rectangle");
j = Convert.ToInt16(Console.ReadLine());
A = i * j;
return A;
}
public static double Triangle(int width, int height)
{
double i, j, A;
Console.WriteLine("Please enter the width of the triangle");
i = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Please enter the height of the triangle");
j = Convert.ToDouble(Console.ReadLine());
A = (.5 * i * j);
return A;
}
public static double Circle(int radius)
{
int i;
double A;
Console.WriteLine("Please enter the radius of the circle");
i = Convert.ToInt16(Console.ReadLine());
A = (i * Math.PI);
return A;
}
}
class Program
{
static void Main(string[] args)
{
int x, i, j;
i = 0;
j = 0;
Console.WriteLine("Please select what type of shape you wish to find the area of:\n1. Square\n2. Rectangle\n3. Triangle\n4. Circle\n");
x = Convert.ToInt16(Console.ReadLine());
Area r = new Area();
if (x == 1)
{
Area.Square(i);
}
if (x == 2)
{
Area.Rectangle(j, i);
}
if (x == 3)
{
Area.Triangle(j, i);
}
if (x == 4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
Console.ReadKey();
}
}
}

You'll currently always see "That is an invalid choice" unless x is 4... because the final if/`else is disconnected from all the rest.
You could change it to use else if everywhere, like this:
if (x == 1)
{
...
}
else if (x == 2)
{
...
}
else if (x == 3)
{
...
}
else if (x == 4)
{
...
}
else
{
...
}
... but it would be simpler to use a switch statement:
switch (x)
{
case 1:
...
break;
case 2:
...
break;
case 3:
...
break;
case 4:
...
break;
default:
...
break;
}
That better expresses your intention of "I want to execute exactly one of these branches, based on a simple selection on x, with a "default" branch if x isn't any of the known values."

Your main issue is, what others have mentioned, about the if statements. Another thing is that you calculate the area but never print it out.
if (x == 1)
{
Console.WriteLine(Area.Square(i));
}
else if (x == 2)
{
Console.WriteLine(Area.Rectangle(j, i));
}
else if (x == 3)
{
Console.WriteLine(Area.Triangle(j, i));
}
else if (x == 4)
{
Console.WriteLine(Area.Circle(i));
}
else
{
Console.WriteLine("That is an invalid choice");
}

Initially, you have to change a bit your if statements, like below:
if (x == 1)
{
Area.Square(i);
}
else if (x == 2)
{
Area.Rectangle(j, i);
}
else if (x == 3)
{
Area.Triangle(j, i);
}
else if (x == 4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
Doing so, you will get the message that you get know in all cases, where x is not 4, also in the rest cases 1, 2 and 3.

Your code is checking if x equals 4, otherwise using the code in the else block.
This will be run every time unless x=4!
Try this instead:
x = Convert.ToInt16(Console.ReadLine());
Area r = new Area();
if (x == 1)
{
Area.Square(i);
}
else if (x==2)
{
Area.Rectangle(j, i);
}
else if (x == 3)
{
Area.Triangle(j, i);
}
else if (x==4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
or even better:
x = Console.ReadLine();
switch x
{
case "1":
Area.Square(i);
break;
case "2":
Area.Rectangle(j, i);
break;
case "3":
Area.Triangle(j, i);
break;
case "4":
Area.Circle(i);
break;
default:
console.WriteLine("That is an invalid choice");
break;
}

The problem is with your if statement, you need to be using else if instead of if:
if (x == 1)
{
Area.Square(i);
}
else if (x==2)
{
Area.Rectangle(j, i);
}
else if (x == 3)
{
Area.Triangle(j, i);
}
else if (x==4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
The issue when using if is that it got to the very last if and the else was true, so it would print "That is an invalid choice".
And some notes on your implementation...
In your main program, its unnecessary to have an Area object, Area r = new Area(), since you don't use r anywhere.
All of the methods in Area take in values (which you pass in) but then completely ignore them and ask for the values again. I would either remove the parameters from the methods, or ask the user in the main program and pass in the values. The input logic can be put inside the if statement for each different calculation. Last, you don't do anything with the return value of the function, so you don't display the area to the user. You need to edit your functions to write it to the console, for example:
Console.WriteLine("The square area is {0}", Area.Square());
Inside the if statement, or because you are doing user input in the calculation, you could have a similar line in each Area method.

enum AreaEnum
{
Square,
Rectangle,
Triangle,
Circle,
};
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please select what type of shape you wish to find the area of:\n1. Square\n2. Rectangle\n3. Triangle\n4. Circle\n");
int x = Convert.ToInt16(Console.ReadLine());
AreaEnum myValueAsEnum = (AreaEnum)x;
Calculate(myValueAsEnum);
}
static double Calculate(AreaEnum a)
{
int x, i, j;
i = 0;
j = 0;
Area area = new Area();
switch (a)
{
case AreaEnum.Square:
{
return Area.Square(i);
}
case AreaEnum.Rectangle:
{
return Area.Rectangle(j, i);
}
case AreaEnum.Triangle:
{
return Area.Triangle(j, i);
}
case AreaEnum.Circle:
{
return Area.Circle(i);
}
default:
{
Console.WriteLine("That is an invalid choice");
return 0;
}
}
}
}

Related

switch while won't loop

This is part of a program I'm writting. My main porblem is that once it goes trough one of the cases, tit won't loop so it's useless as it is. Any help? (Sorry for the variables in Spanish, also a couple of functions i created appear in the cose which are in the program and work just fine so I don't thin they have anything to do with the problem).
static void Main(string[] args)
{
int minutos_restantes = 480;
int opcion;
int valorComercial = 0;
Tarea[] listado_tareas = new Tarea[10];
CrearTareas(ref listado_tareas);
Console.WriteLine("1. Mostrar tareas. \n2. Asignar tarea \n3. Salir, \n Elige opción: ");
opcion = Convert.ToInt32(Console.ReadLine());
switch (opcion)
{
case 1:
Imprimirtareas(listado_tareas);
break;
case 2:
Console.WriteLine("Seleccionar número de tarea: ");
int n = Convert.ToInt32(Console.ReadLine())-1;
if (n < 0 || n > 10)
{
Console.WriteLine("TAREA INEXISTENTE");
}
else if (listado_tareas[n].realizada == true)
{
Console.WriteLine("TAREA YA REALIZADA");
}
else if((minutos_restantes - listado_tareas[n].tiempo) <= 0)
{
Console.WriteLine("TIEMPO INSUFICIENTE");
}
else
{
listado_tareas[n].realizada = true;
minutos_restantes -= listado_tareas[n].tiempo;
}
break;
} while (opcion != 3) ;
}
I don't think you can loop over a switch like this.
Try doing the while separate:
do
{
switch (opcion)
{
case 1:
Imprimirtareas(listado_tareas);
break;
case 2:
Console.WriteLine("Seleccionar número de tarea: ");
int n = Convert.ToInt32(Console.ReadLine())-1;
if (n < 0 || n > 10)
{
Console.WriteLine("TAREA INEXISTENTE");
}
else if (listado_tareas[n].realizada == true)
{
Console.WriteLine("TAREA YA REALIZADA");
}
else if((minutos_restantes - listado_tareas[n].tiempo) <= 0)
{
Console.WriteLine("TIEMPO INSUFICIENTE");
}
else
{
listado_tareas[n].realizada = true;
minutos_restantes -= listado_tareas[n].tiempo;
}
break;
}
}while (opcion != 3) ;
There's no such construct:
switch
{
} while (...);
In C#. What you've actually written is:
switch
{
}
while (...);
Which is another way of writing
switch
{
}
while (...)
{
}
I suspect you want to put your switch statement inside a while or a do...while loop.
Go for something like this:
int opcion = 0;
do
{
opcion = Convert.ToInt32(Console.ReadLine());
switch (opcion)
{
...
}
} while (opcion != 3);
Check this one too: While Loop in C# with Switch Statement
This is broken code.
You have a switch() {} statement (without default and those breaks cause you to fall out of its scope) and a while (condition) /*do nothing*/; statement.
The intention is do{switch(){}}while() ?
Time to do some reading...
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/while
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/do
You should do :-
while (condition)
{
switch
{
}
}

How do I save information reached through a method to a variable?

I am making a program to calculate someone's GPA based user input. For one of the methods I am writing, I ask the user to enter a letter grade. I then convert the letter to the corresponding GPA. How do I save this GPA to a variable? Would I save it as a variable when I call the method in the program or in the method itself?
public static double GetGradePoint(string LetterGrade)
{
Console.WriteLine("Enter your letter grade for each class");
string letter = Console.ReadLine();
if (letter == "A")
{
return 4;
}
if (letter == "A-")
{
return 3.7;
}
if (letter == "B+")
{
return 3.3;
}
if (letter == "B")
{
return 3;
}
if (letter == "B-")
{
return 2.7;
}
if (letter == "C+")
{
return 2.3;
}
if (letter == "C")
{
return 2;
}
if (letter == "C-")
{
return 1.7;
}
if (letter == "D+")
{
return 1.3;
}
if (letter == "D")
{
return 1;
}
if (letter == "F")
{
return 0;
}
}
You could try two different things:
Approach One (Not Recommended)
Use this approach if you will only be using your input data once and won't require to use it anywhere else in your logic. Take not of the parameters. You do not need to declare a parameter on this case
public static double GetGradePoint()
{
Console.WriteLine("Enter your letter grade for each class");
string letter = Console.ReadLine();
//... your if statements/ switch statement here
if (letter == "A")
{
return 4;
}
//...
}
Then inside your main()
double Grade = GetGradePoint();
Approach Two (Recommended)
Use this approach and treat your GetGradePoint as a pure function that takes a parameter and return a result. Take note of the parameter.
public static double GetGradePoint(string LetterGrade)
{
//... your if statements/ switch statement here
if (LetterGrade== "A")
{
return 4;
}
//...
}
Then inside your main()
Console.WriteLine("Enter your letter grade for each class");
string letter = Console.ReadLine();
//pass letter as parameter to get the GradePoint
double Grade = GetGradePoint(letter);
Note:
Always try to treat your methods as pure functions. functions that receive information via parameters and return computed result.

C# - Keep program running after catch and convert int in method to float?

I just recently started programming and am trying to work through a code that doesn't quite agree with me.
My main problems are:
After the catch is activated, I'd like for the program to run again, so that new numbers can be typed in, but instead right now it's simply closing it.
I'd like the FahrenheitToCelsius to convert into float, while being inserted as an int first.
I've tried many different options from similar questions I found here but right now I've reached a stand still since none of it seemed to work in my code (Probably because I'm not seeing the whole picture yet).
Here's my code so far, without all the failed attempts in it to make it easier to overlook.
class Program
{
//METHOD: CONVERTS FAHRENHEIT TO CELSIUS
public static int FahrenheitToCelsius (int fahrenheit)
{
int celsius = ((fahrenheit - 32) * 5) / 9;
return celsius;
}
public static void Main(string[] args)
{
try
{
//===============INTRO AND METHOD CALLING============
Console.WriteLine("Skriv in temperaturen i Fahrenheit: ");
int fahrenheit = int.Parse(Console.ReadLine());
int cel = FahrenheitToCelsius(fahrenheit);
//==============-NOT ACCEPTABLE TEMPERATURES==============
do
//ABOVE ACCEPTABLE TEMP
if (cel > 77)
{
Console.WriteLine("This is too hot. Turn down the temperature.");
int cel3 = int.Parse(Console.ReadLine());
cel = FahrenheitToCelsius(cel3);
}
//BELOW ACCEPTABLE TEMPERATURE
else if (cel < 73)
{
Console.WriteLine("This is too cold. Turn up the temperature");
int cel2 = int.Parse(Console.ReadLine());
cel = FahrenheitToCelsius(cel2);
}
while (cel < 73 || cel > 77);
//================ACCEPTABLE TEMPS===================
//Acceptable but not perfect temp
if (cel == 73 || cel == 74 || cel == 76 || cel == 77)
{
Console.WriteLine("Acceptable temperature.");
}
//PERFECT TEMPERATURE
else if (cel == 75)
{
Console.WriteLine("Perfect temperature!");
}
}
//================EXCEPTION=================
catch (Exception)
{
Console.WriteLine("Error. Only numbers acceptable.");
}
Console.ReadKey();
}
}
}
As I said, I'm super new to programming so the answer is probably right in front of me, but after twelve hours of trying on these two problems alone, I think I need some help!
If you want a float instead of an int, you can use float.Parse() instead of int.Parse.
If you want to continue the flow on invalid input, you could use TryParse instead of Parse, something like this:
float fahrenheit = 0;
float cel;
while (fahrenheit == 0)
{
if (float.TryParse(Console.ReadLine(), out farhenheit)
cel = fahrenheit;
else
Console.WriteLine("Error. Only numbers acceptable.");
}
Welcome to the Stack Overflow )
Adding method that validates input values will help you here
private static int GetUserInput()
{
while (true)
{
int outputValue;
Console.WriteLine("Skriv in temperaturen i Fahrenheit: ");
var inputValue = Console.ReadLine();
var userInputIsInteger = int.TryParse(inputValue, out outputValue);
if (!userInputIsInteger)
{
Console.WritLine("Only integer values can be accepted as input");
}
if (userInputIsInteger || inputValue == "q") // in user type Q he wants to exit an app
{
return outputValue;
}
}
}
and then use it here
//===============INTRO AND METHOD CALLING============
var fahrenheit = GetUserInput();
int cel = FahrenheitToCelsius(fahrenheit);
Might even remove try catch from you code.
Try this:
public static int Ask(string message)
{
int result = -1;
bool valid = false;
while (!valid)
{
Console.WriteLine(message);
valid = int.TryParse(Console.ReadLine(), out result);
}
return result;
}
Then you can do this:
public static void Main(string[] args)
{
int cel = -1;
while (cel < 73 || cel > 77)
{
Console.WriteLine();
int fahrenheit = Ask("Skriv in temperaturen i Fahrenheit: ");
cel = FahrenheitToCelsius(fahrenheit);
if (cel > 77)
{
Console.WriteLine("This is too hot. Turn down the temperature.");
}
else if (cel < 73)
{
Console.WriteLine("This is too cold. Turn up the temperature");
}
}
if (cel == 75)
{
Console.WriteLine("Perfect temperature!");
}
else
{
Console.WriteLine("Acceptable temperature.");
}
Console.ReadLine();
}
Please, do not cram all the matter into a single Main, extract methods:
private static float FahrenheitToCelsius(float t) {
return (t - 32.0f) / 5.0f * 9.0f ;
}
private staic float ObtainFarenheight() {
while (true) {
Console.WriteLine("Skriv in temperaturen i Fahrenheit: ");
float result = 0.0f;
if (float.TryParse(Console.ReadLine(), out result))
return result;
Console.WriteLine("Error. Only numbers acceptable.");
}
}
private static float AcceptableCelsius() {
while (true) {
float result = FahrenheitToCelsius(ObtainFarenheight());
if (result > 77)
Console.WriteLine("This is too hot. Turn down the temperature.")
else if (result < 73)
Console.WriteLine("This is too cold. Turn up the temperature");
else
return result;
}
}
And you'll have
public static void Main(string[] args) {
float cel = AcceptableCelsius();
//DONE: please, notice that perfect temperatures is a range, not a set
if (cel > 74.5 && cel < 75.5)
Console.WriteLine("Perfect temperature!");
else
Console.WriteLine("Acceptable temperature.");
Console.ReadKey();
}
Footnote: I'd rather used double (it's more convenient - at least not f suffixes) when working with temperatures, but float is OK as well.

C# How do I get out of this loop? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
How do I get out of this loop?
I wrote a program that checks to see if corresponding places in the numbers are the same total. The console output should be true or false. I wrote that, and then added the top part that interacts with the user, and now I get stuck in a loop. How do I get out of it?
using System;
namespace DeliverablePart1
{
class DeliverablePart1
{
static void Main(string[] args)
{
string gameAnswer;
bool repeat1 = true, repeat2 = true;
while (repeat1 == true)
{
repeat2 = true;
Console.WriteLine("Would you like to compare 2 numbers to see if their corresponding place is same total?");
gameAnswer = Console.ReadLine();
while (repeat2 == true)
{
if (gameAnswer == "yes" || gameAnswer == "yes" || gameAnswer == "YES")
{
Console.WriteLine("Please enter a three digit whole number");
string firstValue = Console.ReadLine();
int firstNumber = ValidInteger(firstValue);
Console.WriteLine("Please enter a second three digit whole number");
string secondValue = Console.ReadLine();
int secondNumber = ValidInteger(secondValue);
repeat1 = false;
repeat2 = false;
}
else if (gameAnswer == "no" || gameAnswer == "No" || gameAnswer == "NO")
{
Console.WriteLine("Okay, exiting now");
repeat1 = false;
repeat2 = false;
}
else
{
Console.WriteLine("I do not understnad what you have said");
repeat2 = false;
}
void Add(int firstNumber, int secondNumber)
{
int length1 = firstNumber.ToString().Length;
int length2 = secondNumber.ToString().Length;
string userInput;
if (length1 == length2)
{
string Answer = Convert.ToString(Compare(firstNumber, secondNumber, length1));
}
else
{
userInput = "invalid user input - Check number of digits next time.";
Console.WriteLine(userInput);
Console.ReadKey();
}
Console.ReadKey();
}
int ValidInteger(string digit1)
{
int value = 0;
string notInt = "This is not an integer.";
{
bool successfullyParsed = int.TryParse(digit1, out value);
if (successfullyParsed)
{
int firstNumber = Convert.ToInt32(value);
return value;
}
else
{
Console.WriteLine(notInt);
Console.ReadKey();
Environment.Exit(0);
return value;
}
}
}
string Compare(int a, int b, int c)
{
int lastDigitA;
int lastDigitB;
lastDigitA = (a % 10);
lastDigitB = (b % 10);
int sumStatic = lastDigitA + lastDigitB;
do
{
lastDigitA = (a % 10);
lastDigitB = (b % 10);
a = a / 10;
b = b / 10;
c--;
int sumCompare = lastDigitA + lastDigitB;
if (sumCompare != sumStatic)
{
Console.WriteLine("False");
return "False";
}
}
while (c != 0);
Console.WriteLine("True");
return "True";
}
}
}
}
}
}
From my understanding, it looks like you want the user to enter in three ints (with some input validation), and put the three ints through the Compare() function. If the function returns true, then say "True" to the console, and if it's false then say "False" to the console. If that's the case, I refactored your code into this (and it doesn't get stuck in a loop):
using System;
namespace DeliverablePart1
{
internal class DeliverablePart1
{
private static void Main(string[] args)
{
Console.WriteLine("Would you like to compare 2 numbers to see if their corresponding place is same total?");
var shouldContinue = Console.ReadLine();
if (shouldContinue != null && shouldContinue.Equals("yes", StringComparison.CurrentCultureIgnoreCase))
{
var firstNum = GetIntFromUser("Please enter a three digit whole number");
var secondNum = GetIntFromUser("Please enter a three digit whole number");
var thirdNum = GetIntFromUser("Please enter a three digit whole number");
Console.WriteLine(Compare(firstNum, secondNum, thirdNum) ? "True" : "False");
}
else
{
Console.WriteLine("Exiting");
}
// waits for the user to press a key to exit the app, so that they can see their result
Console.ReadKey();
}
/// <summary>
/// Makes the user enter in a three digit number, and exits if they say "no"
/// </summary>
/// <param name="msg">The message prompt to ask for the integer</param>
/// <returns>System.Int32., or will exit</returns>
public static int GetIntFromUser(string msg)
{
while (true)
{
Console.WriteLine(msg);
var valFromUser = Console.ReadLine()?.Trim();
if (valFromUser != null)
{
int result;
if (int.TryParse(valFromUser.Trim(), out result) && valFromUser.Length == 3)
{
return result;
}
if (valFromUser.Equals("no", StringComparison.CurrentCultureIgnoreCase))
{
Console.WriteLine("Exiting.");
Environment.Exit(0);
}
}
Console.WriteLine("Hmm, that's not a three digit number. Try again.");
}
}
public static bool Compare(int a, int b, int c)
{
var lastDigitA = a % 10;
var lastDigitB = b % 10;
var sumStatic = lastDigitA + lastDigitB;
do
{
lastDigitA = a % 10;
lastDigitB = b % 10;
a = a / 10;
b = b / 10;
c--;
var sumCompare = lastDigitA + lastDigitB;
if (sumCompare != sumStatic)
{
return false;
}
} while (c != 0);
return true;
}
}
}

Avoid goto statement in C#

I don't want to use some sort of goto statement, but I want the user to return to the main menu when the default case is executed. How?? I know this is a simple problem, but there must be lots of newbie who come across something very similar.
static void buycoffee()
{
Double price = 0;
int x = 0;
while (x == 0)
{
Console.WriteLine("Pick a coffee Size");
Console.WriteLine("1: Small");
Console.WriteLine("2: Medium");
Console.WriteLine("3: Large");
int Size = int.Parse(Console.ReadLine());
switch (Size)
{
case 1:
price += 1.20;
break;
case 2:
price += 1.70;
break;
case 3:
price += 2.10;
break;
default:
Console.WriteLine("This option does not exist");
///how to return to the main menu here
break;
}
Console.WriteLine("Would you like to buy more coffee?");
String Response = Console.ReadLine().ToUpper();
if (Response.StartsWith("Y"))
{
Console.Clear();
}
else
{
x += 1;
}
}
Console.WriteLine("The total bill comes to £{0}", price.ToString("0.00"));
}
}
replace your commented line with: continue;
As Nico Schertier said, you can accomplish this with something like the following:
int Size = -1;
while (Size == -1) {
Console.WriteLine("Pick a coffee Size");
Console.WriteLine("1: Small");
Console.WriteLine("2: Medium");
Console.WriteLine("3: Large");
Size = int.Parse(Console.ReadLine());
switch (Size)
{
case 1:
price += 1.20;
break;
case 2:
price += 1.70;
break;
case 3:
price += 2.10;
break;
default:
Size = -1;
Console.WriteLine("This option does not exist");
break;
}
}
Beside #Abion47 and #Dogu Arslan's answers you can also create a function for your menu and also one for your switch.
In this example it will create an infinite loop menu
static void Menu()
{
Console.WriteLine("Menu");
Console.WriteLine("1) Take me to My fancy menu");
}
static void SwitchFunc(string input)
{
switch (input)
{
case "1":
Menu();
string inputB = Console.ReadLine();
SwitchFunc(inputB);
break;
}
}
static void Main(string[] args)
{
Menu();
string input = Console.ReadLine();
SwitchFunc(input);
}

Categories

Resources