# Basic C# calculator code

I have not had any experience with coding before, and after beginning to learn I stated working on this calculator which runs different functions on the console. I'd like to hopefully be taught what I could have done differently or easier.

{

class MainClass

{

public static void Main (string[] args)

{

double num01, num02, num03, Result,Result2;

Random randy= new Random();

Start:

Console.WriteLine ("How could I help you ?" +

"\n01. Add" +

"\n02. Subract " +

"\n03. Multiply " +

"\n04. Divide " +

"\n05. Square of a number" +

"\n06. Square Root of a number" +

"\n07. Cube of a number" +

"\n08. Cube root" +

"\n09. Cº to Fº " +

"\n10. Fº to Cº " +

"\n11. The Area of a Circle " +

"\n12. Circumference of a Circle" +

"\n13. Area of a Rectangle" +

"\n14. Area of a Square "+

"\n15. Area of a Regular Polygon" +

"\n16. Apothem from one side" +

"\n17. Area of a Parallelogram" +

"\n18. Area of a Trapezoid" +

"\n19. Area of a Triangle" +

"\n20. Area of an Ellipse" +

"\n21. Area of a Rhombus" +

"\n22. Surface Area of a Cube" +

"\n23. Surface Area of a Rectangular Prism" +

"\n24. Surface Area of a Sphere" +

"\n25. Surface Area of a Cylinder" +

"\n26. Surface Area of a Rectangular Pyramid" +

"\n27. Surface Area of a Cone" +

"\n28. Volume of a Cube" +

"\n29. Volume of a Rectangular Prism" +

"\n30. Volume of a Sphere" +

"\n31. Volume of a Cylinder" +

"\n32. Volume of a Rectangular Pyramid" +

"\n33. Volume of a Cone" +

"\n34. Sin" +

"\n35. Cos" +

"\n36. Tan" +

"\n37. Csc" +

"\n38. Sec" +

"\n39. Cot" +

"\n40. Natural Log" +

"\n41. Log base 10" +

"\n42. Raise to the Nth. value" +

"\n43. Pythagorean Theorem (find A)" +

"\n44. Pythagorean Theorem (Find B or C)" +

"\n45. Quadratic Formula" +
"\n");

int Choose;
Choose = int.Parse (Console.ReadLine ());
switch (Choose)

{
case 1:
Console.WriteLine("You have chosen addition \nPlease insert your first number");
num01=double.Parse(Console.ReadLine());
Console.WriteLine("Alright, now your second number");
num02= double.Parse (Console.ReadLine());
Result= num01 + num02;
Console.WriteLine(num01+" + " +num02+" equals "+ Result );
break;

case 2:
Console.WriteLine("You have chosen Subtraction \nFirst number please");
num01=double.Parse(Console.ReadLine());
Console.WriteLine ("now your second number please");
num02=double.Parse(Console.ReadLine());
Result=num01-num02;
Console.WriteLine (num01+" - "+num02 +" equals " + Result);
break;

case 3:
Console.WriteLine("You have chosen multiplication \nFirst number please");
num01=double.Parse(Console.ReadLine());
Console.WriteLine ("Now your second number ");
num02=double.Parse(Console.ReadLine());
Result = num01 * num02;
Console.WriteLine (num01+" * " +num02+ " equals "+ Result);
break;

case 4:
Console.WriteLine ("You have chosen division \nPlease provide your first number ");
num01=double.Parse(Console.ReadLine());
Console.WriteLine ("Now your second number ");
num02=double.Parse(Console.ReadLine());
Result= (num01)/(num02);
Console.WriteLine (num01 + " / " + num02+" equals " + Result);
break;

case 5:
Console.WriteLine ("You have chosen to square a number \nPlease  introduce the number to be squared");
num01 = double.Parse (Console.ReadLine ());
Result = num01 * num01;
Console.WriteLine (num01+" squared is "+ Result);
break;

case 6:
Console.WriteLine ("You have chosen square root\nPlease insert a number whose square root to report");
num01 = double.Parse (Console.ReadLine());
Result= Math.Sqrt (num01);
Console.WriteLine ("The Square Root of " + num01 + " is "+ Result);
break;

case 7:
Console.WriteLine ("This is Cubed Root\nWhich number would you like me to cube?");
num01 = double.Parse (Console.ReadLine ());
Result = num01 * num01 * num01;
Console.WriteLine (num01+" cubed is "+ Result);
break;

case 8:
Console.WriteLine ("Hello, this is cubed roots\nWhich number's cubed root would you like to know?");
num01 = double.Parse (Console.ReadLine ());
Result = Math.Round ((Math.Pow (num01, (Double)1 / 3)), 2);
Console.WriteLine ("The cubed root of "+ num01+ " is "+ Result);
break;

case 9: //Celcius to Fahrenheit
Console.WriteLine ("This section is to pass Celcius to Fahrenheit\nWhat will be the degress Celcius to transform?");
num01 = double.Parse (Console.ReadLine ());
Result = 1.8 * num01 + 32;
Console.WriteLine(num01+" Degrees Celcius is equivalent to "+ Result+ " Fahrenheit");
break;

case 10: //Fahrenheit to Celcius
Console.WriteLine ("This portion is to pass degrees Fahrenheit into Celcius \nWhat degrees should I use as Fahrenheit");
num01 = double.Parse (Console.ReadLine ());
Result = (num01 - 32) * (5 / 9);
Console.WriteLine (num01 + " Degrees Fahrenheit is equivalent to " + Result + " Celcius");
break;

case 11:
Console.WriteLine ("Area of a Circle\nPlease input the radius");
num01 = double.Parse (Console.ReadLine ());
Result = Math.PI * num01 * num01;
Console.WriteLine ("The area is " + Result);
break;

case 12:
Console.WriteLine ("Circumference of a circle\nPlease input radius");
num01 = double.Parse (Console.ReadLine());
Result = 2 * Math.PI * num01;
Console.WriteLine ("The Circumference is just " + Result);
break;

case 13:
Console.WriteLine ("This section is for the Area of a rectangle\n Please input base first");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now input height");
num02 = double.Parse (Console.ReadLine ());
Result = num01 * num02;
Console.WriteLine ("The area of this Rectangle is "+Result);
break;

case 14:
Console.WriteLine ("This is for the Area of a square\nPlease input the side");
num01 = double.Parse (Console.ReadLine ());
Result = num01 * num01;
Console.WriteLine ("the area of this square is"+ Result);
break;

case 15:
Console.WriteLine ("This section is for the Area of a Regular Polygon\nPlease insert the Apothem");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Parameter please");
num02 = double.Parse (Console.ReadLine ());
Result = (num01 * num02) / 2;
Console.WriteLine ("The area of this Regular Polygon is "+ Result);
break;

case 16:
Console.WriteLine ("This section will find the Apothem of a Regular Polygon knowing only one side\nPlease input the length of the side");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now please input the number of sides of this Regular Polygon");
num02 = double.Parse (Console.ReadLine ());
Result = (num01) / (2 * Math.Tan (180 / num02));
Console.WriteLine ("The Apothem of this Regular Polygon is "+ Result);
break;

case 17:
Console.WriteLine ("This part is used to find the Area of a Parallelogram\nPlease input the base");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the height please");
num02 = double.Parse (Console.ReadLine ());
Result = num01 * num02;
Console.WriteLine ("The Area of this Parallelogram is "+Result);
break;

case 18:
Console.WriteLine ("This section will serve the purpose of finding the Area of a Trapezoid \nPlease input the height");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the first base (bottom)");
num02 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the second base (top)");
num03 = double.Parse (Console.ReadLine ());
Result = (num01 / 2) * (num02 + num03);
Console.WriteLine ("The area of this Trapezoid is "+Result);
break;

case 19:
Console.WriteLine ("This area is for the Area of a Triangle\nPlease input the base");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the height please");
num02 = double.Parse (Console.ReadLine ());
Result = .5 * num01 * num02;
Console.WriteLine ("The Area of this Triangle is "+ Result);
break;

case 20:
Console.WriteLine ("This section is intended to find the Area of an Ellipse\nPlease input the Major Axis");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Minor Axis");
num02 = double.Parse (Console.ReadLine ());
Result = Math.PI * num01 * num02;
Console.WriteLine ("The Area of this Ellipse is "+ Result);
break;

case 21:
Console.WriteLine ("This section is intended to find the Area of a Rhombus\nPlease input the first diagonal");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the second diagonal");
num02 = double.Parse (Console.ReadLine ());
Result = (num01 * num02) / 2;
Console.WriteLine ("The Area of this Rhombus is "+ Result);
break;

case 22:
Console.WriteLine ("This section is for the Surface Area of a Cube\nPlease input the length of one side");
num01 = double.Parse (Console.ReadLine ());
Result = 6 * (num01*num01);
Console.WriteLine ("The Area of this Cube is "+ Result);
break;

case 23:
Console.WriteLine ("This section is intended to find the Surface Area of a Rectangular Prism\nPlease input the Length");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now Width please");
num02 = double.Parse (Console.ReadLine ());
Console.WriteLine ("And now the Height");
num03 = double.Parse (Console.ReadLine ());
Result = 2 *((num02 * num01) + (num03 * num01) + (num02 * num03));
Console.WriteLine ("The area of this Rectangular Prism is "+ Result);
break;

case 24:
Console.WriteLine ("This section is special for the Surface Area of a Sphere\nPlease input the Radius");
num01 = double.Parse (Console.ReadLine ());
Result = 4 * Math.PI * (num01 * num01);
Console.WriteLine ("The Surface Area of this Sphere is "+ Result);
break;

case 25:
Console.WriteLine ("This part is meant to calculate the Surface Area of a Cylinder\nPlease input the Height");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Radius");
num02 = double.Parse (Console.ReadLine ());
Result = (2 * (Math.PI * (num02 * num02))) + (2 * (Math.PI * num02 * num01));
Console.WriteLine ("The Surface Area of this Cyinder is "+Result);
break;

case 26:
Console.WriteLine ("This block is intended to find the Surface Area of a Rectangular Pyramid\nPlease input the Base Length");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Base Width");
num02 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the  Height please");
num03 = double.Parse (Console.ReadLine ());
Result = (num01 * num02) + num01 * (Math.Sqrt ((num02 / 2) * (num02 / 2) + (num03 * num03))) + num02 * (Math.Sqrt ((num01 / 2) * (num01 / 2) + (num03 * num03)));
Console.WriteLine ("The Surface Area of this Rectangular Pyramid is "+ Result);
break;

case 27:
Console.WriteLine ("This section is made to calculate the Surface Area of a Cone\nPlease input Height");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Radius");
num02 = double.Parse (Console.ReadLine ());
Result= Math.PI*num02*(num02+Math.Sqrt((num01*num01)+(num02*num02)));
Console.WriteLine("The Surface Area of this Cone is "+Result);
break;

case 28:
Console.WriteLine ("This area is dedicated to finding the Volume of a Cube\nPlease insert the side");
num01 = double.Parse (Console.ReadLine ());
Result = num01 * num01 * num01;
Console.WriteLine ("The Volume of this Cube is "+Result);
break;

case 29:
Console.WriteLine ("This block is specifically designed to find the Volume of a Rectangular Prism\nPlease input Length");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Width");
num02 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now a Height please");
num03 = double.Parse (Console.ReadLine ());
Result = num01 * num02 * num03;
Console.WriteLine ("The Volume of this Rectangular Prism is "+ Result);
break;

case 30:
Console.WriteLine ("This part is designed to find the Volume of a Sphere\nEnter the Radius please");
num01 = double.Parse (Console.ReadLine ());
Result = 4 / 3 * Math.PI * (num01 * num01 * num01);
Console.WriteLine ("The Volume of this Sphere should be "+Result);
break;

case 31:
Console.WriteLine ("This section is meant to find the Volume of a Cylinder\nPlease input the Radius");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Height");
num02 = double.Parse (Console.ReadLine ());
Result = Math.PI * (num01 * num01) * num02;
Console.WriteLine ("The Volume of this Cylinder is "+Result);
break;

case 32:
Console.WriteLine ("This area is dedicated to finding the Volume of a Rectangular Pyramid\nPlease input the Base Length");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Base Width");
num02 = double.Parse (Console.ReadLine ());
Console.WriteLine ("And now the Height please");
num03 = double.Parse (Console.ReadLine ());
Result = (num01 * num02 * num03) / 3;
Console.WriteLine ("The Volume of this Rectangular Pyramid is "+Result);
break;

case 33:
Console.WriteLine ("The purpose of this sections is to find the Volume of a Cone\nPlease input the Radius");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the Height please");
num02 = double.Parse (Console.ReadLine ());
Result = (Math.PI * (num01 * num01)) * (num02 / 3);
Console.WriteLine ("The Volume of this Cone is "+ Result);
break;

case 34:
Console.WriteLine ("This area is to be utilized to find the Sin of any number\nPlease input a number");
num01 = double.Parse (Console.ReadLine ());
Result = Math.Sin (num01);
Console.WriteLine ("The Sin of " + num01 + " is " + Result);
break;

case 35:
Console.WriteLine ("This part is to find the Cos of any number \nPlease input a number");
num01 = double.Parse (Console.ReadLine ());
Result = Math.Cos (num01);
Console.WriteLine ("The Cos of " + num01 + " is " + Result);
break;

case 36:
Console.WriteLine ("This section is to find the Tan of any number\nPlease input a number");
num01 = double.Parse (Console.ReadLine ());
Result = Math.Tan (num01);
Console.WriteLine ("The Tan of "+num01+" is "+ Result);
break;

case 37:
Console.WriteLine ("This area is dedicated to finding the Csc of any number\nPlease input a number");
num01 = double.Parse (Console.ReadLine ());
Result = 1 / (Math.Sin (num01));
Console.WriteLine ("The Csc of "+ num01+ " is "+ Result);
break;

case 38:
Console.WriteLine ("This block is to be used to find the Sec of any number\nPlease input a number");
num01 = double.Parse (Console.ReadLine ());
Result = 1 / (Math.Cos (num01));
Console.WriteLine("The Sec of "+ num01+" is "+ Result);
break;

case 39:
Console.WriteLine ("This part is intended to find the Cot of any number \nPlease input a number");
num01 = double.Parse (Console.ReadLine ());
Result = 1 / (Math.Tan (num01));
Console.WriteLine ("The Cot of " + num01 + " is " + Result);
break;

case 40:
Console.WriteLine ("This part's purpose is to find the Natural Log of any number\nInput a number please");
num01 = double.Parse (Console.ReadLine ());
Result = Math.Log (num01);
Console.WriteLine ("The Natural Log of " + num01 + " is " + Result);
break;

case 41:
Console.WriteLine ("This block's purpose is to find the Log base 10 of any number\nInput a number please");
num01 = double.Parse (Console.ReadLine ());
Result = Math.Log10 (num01);
Console.WriteLine ("The Log base 10 of "+ num01+" is "+ Result);
break;

case 42:
Console.WriteLine ("This block is to raise a number to any power \nPlease enter the number that will be raised");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now the power it will be raised to");
num02 = double.Parse (Console.ReadLine ());
Result = Math.Pow (num01, num02);
Console.WriteLine (num01 + " to the " + num02 + " power is " + Result);
break;

case 43:
Console.WriteLine ("This block will use the Pythagorean Theorem to find a missing side of a Triangle(Side A)\nPlease input B");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now C please");
num02 = double.Parse (Console.ReadLine ());
Result = Math.Sqrt ((num01 * num01) + (num02 * num02));
Console.WriteLine ("A in this triangle is "+ Result);
break;

case 44:
Console.WriteLine ("This sections will use the Pythagorean Theorem to find a missing side of a Triangle(Side B or C)\nPlease input A");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now B or C (whichever you can provide");
num02 = double.Parse (Console.ReadLine ());
Result = Math.Sqrt ((num01 * num01) - (num02 * num02));
Console.WriteLine ("The missing side of this triangle is " + Result);
break;

case 45:
Console.WriteLine ("This section will use the Quadratic Formula to find the factors of an equation (provided that you know A,B, and C\nPlease input A");
num01 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now B");
num02 = double.Parse (Console.ReadLine ());
Console.WriteLine ("Now C");
num03 = double.Parse (Console.ReadLine ());
Result = (-num02 + Math.Sqrt ((num02 * num02) - 4 * num01 * num03)) / 2 * num01;
Result2 = (-num02 - Math.Sqrt ((num02 * num02) - 4 * num01 * num03)) / 2 * num01;
Console.WriteLine("The Factors of the equation are "+ Result+ " and " +Result2);
break;

}

Opt:

Console.WriteLine ("\nWhat now? " +

"\n1. Go to the very beginning " +

"\n2. Close" +

"\n3. Clear everything" +

"\n ");

int Choose3;

Choose3= int.Parse (Console.ReadLine ());

switch (Choose3)

{

case 1:
goto Start;

case 2:
break;
case 3:
Console.Clear ();
goto Opt;
break;
}
}
}
}

• Few notes : Avoid goto statements, verify your input. – Denis May 20 '16 at 1:03
• @denis may I ask what you refer to with "verify your input"? – Manny May 20 '16 at 3:34
• @Manny: int.Parse (Console.ReadLine ()) fails if input in not an int (e.g. you type "a" as input). – JanDotNet May 20 '16 at 7:00

## 1 Answer

As mentioned above in comments, you should validate your input... something like:

var input = Console.ReadLine();
int numInput;
if (!int.TryParse(input, out numInput))
{
Console.WriteLine("'" + input + "' is not a number.");
}
else
{
// processing numInput
}


All the code is structured in one big method. To improve readability and maintainability, the logic should be splitted to multiple methods (in a first step). For instance, each case should be one method; The generation of the main text should be one method and so on. Normally, if the level ob abstraction changes, a new method should be creaded. That could result in something like:

//... (not fully functional right now... code was only splitted into methods)

WriteAvailableOperations();

int operation = int.Parse (Console.ReadLine());

HandleOperation(operation);

WriteMainMenuOptions();

int mainMenuOption = int.Parse (Console.ReadLine ());

HandleMainMenuOption(mainMenuOption)

// ...


You see that this structure eill not work with goto's (gotos have to be avoided anyway because they result in complicated and hard to read code flows).

So, lets split the code further to make it work again:

enum ContinueBehavior { ShowOperations, ShowMainMenu, Exit }

public static void Main (string[] args)
{
var state = ContinueBehavior.ShowOperations;

do
{
if (state == ContinueBehavior.ShowOperations)
{
ProcessOperations();
}

state = ProcessMainMenu();
}
while (state != ContinueBehavior.Exit)
}

private static void ProcessOperations()
{
WriteAvailableOperations();

int operation = int.Parse (Console.ReadLine());

HandleOperation(operation);
}

private static ContinueBehavior ShowMainMenu()
{
WriteMainMenuOptions();

var mainMenuOption = int.Parse (Console.ReadLine ());

return HandleMainMenuOption(mainMenuOption)
}


Probably there is is more elegant way to organize the code, but you get the point... Writing maintainable code means to group code that belongs to the same level of abstraction to single code units like methods or classes.

The next step would be to group code that belongs together. The description for each operation is displayed in the method WriteAvailableOperations but the actual logic is handled in the method HandleOperation. Therefore, if you want to add or remove operations, you have to change 2 different locations. That is a error-prone design because it is possible that you forget one.

To fix that, it make sense to create a class Operation that looks similary to:

public abstract class Operation
{
public int Number { get; set; }
public string Description {get; set; }
public abstract void Run();
}


So you coud create a single operation class for each concrete operation:

public class AddOperation
{
public AddOperation()
{
Description = "Add";
Number = 1;
}

public override void Run()
{
Console.WriteLine("You have chosen addition \nPlease insert your first number");
int num01=double.Parse(Console.ReadLine());
Console.WriteLine("Alright, now your second number");
int num02= double.Parse (Console.ReadLine());
int result= num01 + num02;
Console.WriteLine(num01+" + " +num02+" equals "+ result );
}
}


So you have to initialize a list of abstract operations first. The main code can work with that abstractions and must not be modified if an operation changed or if operations were added or removed:

public static void Main (string[] args)
{
var state = ContinueBehavior.ShowOperations;
var operations = GetOperations();
do
{
if (state == ContinueBehavior.ShowOperations)
{
ProcessOperations(operations);
}

state = ProcessMainMenu();
}
while (state != ContinueBehavior.Exit)
}

// ...

public Operation[] GetOperations()
{
return new Operation[]
{
new AddOperation(),
new SubractOperation(),
//...
};
}

public static void WriteAvailableOperations(Operation[] operations)
{
var operations = String.Join(Environment.NewLine, operations.Select(o => o.Number.ToString("00") + ". " o.Description));
Console.WriteLine("How could I help you ?");
Console.WriteLine(operations );
}

public static void HandleOperation(int operationNo, Operation[] operations)
{
var operation = operations.First(o => o.Number == operationNo);
operation.Run();
}