C# Class Inheritance Issue with Simple Calculator - c#

I am beginner to C# and am trying to get my second class, MyCalc2, to inherit from MyCalc. But I encounter the following error message in regards to MyCalc2:
There is no argument given that corresponds to the required formal parameter 'x' of 'MyCalc.MyCalc(int, int, string, string)'
The goal here is to just add another class that inherits from the base class.
I know that I need to add something like 'MyCalc: base(x)' to my base class but am lost to where to place the parameter (if that is even the correct thing to do). Any guidance would be appreciated. Here is what I have so far:
using System;
class MyCalc
{
// class variable
public int x;
public int z;
public string y;
public string n;
// constructor
public MyCalc(int x, int z, string y, string n)
{
this.x = x; // assign the parameter passed to the class variable
this.z = z;
this.y = y;
this.n = n;
}
// calculate the operations
public int GetAdd()
{
return (this.x + this.z);
}
public int GetSubtract()
{
return (this.x - this.z);
}
public int GetMultiply()
{
return (this.x * this.z);
}
public int GetDivide()
{
return (this.x / this.z);
}
public string GetYes()
{
return (this.y);
}
public string GetNo()
{
return (this.n);
}
}
class MyCalc2:MyCalc //where the error is occurring
{
static void Main(string[] args)
{
bool repeat = false;
do
{
repeat = false;
int x = 0; int z = 0; string y; string n;
Console.WriteLine("Enter the First Number");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the Second Number");
z = Convert.ToInt32(Console.ReadLine());
//Using a switch statement to perform calculation:
Console.WriteLine("Enter operator\r");
switch (Console.ReadLine())
{
case "+":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "-":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
case "*":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "/":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
}
//Repeat or Exit program using the do-while loop:
string input = Console.ReadLine();
Console.WriteLine("Do you want another operation(Y / N) ?");
input = Console.ReadLine();
repeat = (input.ToUpper() == "Y");
}
while (repeat);
Console.WriteLine("Thanks for using our system.");
Console.ReadKey();
}
}

MyCalc2 does not have a way of initializing MyCalc (Base Class) Because in your BaseClass you do not have a parameter less constructor.
Solution:
Add a param less constructor in Base Class
Add a constructor in Derived class which has a way of calling base class constructor
for your code below should work:
class MyCalc2 : MyCalc
{
public MyCalc2 () : base(0, 0, "", "")
{
}
}

MyCalc2 has no explicit constructor. Which means it has only one implicit constructor which takes no arguments and sets no values. If made explicitly it would look like this:
public MyCalc2()
{
}
However, MyCalc does have an explicit constructor. Which means it has no implicit constructor. And its constructor does take arguments:
public MyCalc(int x, int z, string y, string n)
{
this.x = x; // assign the parameter passed to the class variable
this.z = z;
this.y = y;
this.n = n;
}
So when you create an instance of MyCalc2 it has no way of providing any values to MyCalc. You essentially have three options:
Add a constructor to MyCalc (you can have as many constructors as you want, as long as the parameters differ) which takes no parameters. However, in that case the class-level values for MyCalc would all be default values. You'd have to set them explicitly after constructing the object.1
Add a constructor to MyCalc2 which accepts those values and passes them to the parent constructor, or at least passes default values to the parent constructor.
Don't use inheritance here.
Honestly, in this case I'd go with the third option. What is inheritance meant to accomplish here? MyCalc2 isn't meaningfully an instance of MyCalc. All it does it hold the initial entry point of the application (the Main method), and that's really all it should do.
The logic in your Main method should create and use an instance of MyCalc, but the class which has that Main method shouldn't try to be an instance of MyCalc. That will only cause more confusion than solve any meaningful problems.
1 Side Note: Public class fields are historically a bad habit to get into in object-oriented programming. There's a variety of talk on the subject, and you'll see this often as you continue in your experience. In general you want your objects to expose behaviors, not values. The methods on the object look somewhat Java-like in convention. For C# conventions consider using properties (which compile down to methods themselves, the syntax is just semantically different). You can have { get; set; } auto-properties for the values themselves, and explicit read-only { get { /*...*/ } } properties for the calculated values.

Here is a possible solution. There are two classes MyClass, for the calculator (you may want to rename it) and Propram. Program holds just the method Main, which get your program started. It works like this, but there are some bugs left. I leave it to you to fix them. Except that you miss a clear understanding of the concepts class and inheritance, your code is not too bad for a beginner. It is almost working.
using System;
namespace TestCalculator
{
class MyCalc
{
// class variable
public int x;
public int z;
public string y;
public string n;
// constructor
public MyCalc(int x, int z, string y, string n)
{
this.x = x; // assign the parameter passed to the class variable
this.z = z;
this.y = y;
this.n = n;
}
// calculate the operations
public int GetAdd()
{
return (this.x + this.z);
}
public int GetSubtract()
{
return (this.x - this.z);
}
public int GetMultiply()
{
return (this.x * this.z);
}
public int GetDivide()
{
return (this.x / this.z);
}
public string GetYes()
{
return (this.y);
}
public string GetNo()
{
return (this.n);
}
}
class Program
{
static void Main(string[] args)
{
bool repeat = false;
do
{
repeat = false;
int x = 0; int z = 0; string y; string n;
Console.WriteLine("Enter the First Number");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the Second Number");
z = Convert.ToInt32(Console.ReadLine());
//Using a switch statement to perform calculation:
Console.WriteLine("Enter operator\r");
switch (Console.ReadLine())
{
case "+":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "-":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
case "*":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "/":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
}
//Repeat or Exit program using the do-while loop:
string input = Console.ReadLine();
Console.WriteLine("Do you want another operation(Y / N) ?");
input = Console.ReadLine();
repeat = (input.ToUpper() == "Y");
}
while (repeat);
Console.WriteLine("Thanks for using our system.");
Console.ReadKey();
}
}
}

Related

Beginner question about a task in a course in C#

The code
class Program
{
static int Add(int x, int y)
{
x = 4;
y = 3;
int f = x + y;
return f;
}
static void Main(string[] args)
{
int x = 4;
int y = 3;
Console.WriteLine("Answer: ");
Add(x, y);
}
}
Doing a beginner course in C# and I have been stuck at this question for two days now.
I know its probably really simple, but I have tried so many different things that I think I have made it harder for me than it really.
I fixed to call strings in methods, but numbers seems hard.
The task is about to take two numbers in and that return the answer.
Tried searching around all the different errors I got with all the different tries, but didn't find the help, or the answers I understand.
You almost did all of it, just with 2 issues.
You should relay on the numbers you pass from Main to Add and not reassign the values inside Add otherwise passing them is useless and unusable for other numbers.
Add returns a value but you never save it + print it.
Example for #1
static int Add(int x, int y)
{
int f = x + y;
return f;
}
Example of #2
var result = Add(x, y);
Console.WriteLine(result);
Corrected Example:
class Program
{
static int Add(int x, int y)
{
// You don't need to redefine the variables x and y,
// because you get them when you call the method
// You can shorten the last part
// and just return the Addition
return x + y;
}
static void Main(string[] args)
{
int x = 4;
int y = 3;
// Prints the Word Answer
// as well as the Addition result into the Console now
Console.WriteLine("Answer: " + Add(x, y));
}
}
Your Errors:
You never printed the Result into the Console!
You shouldn't redefine the variables in the Function, because if you do that you don't need to use a function in the first place
You can shorten the return statement (you don't have to)
You can add Add(x,y) into the Console.WriteLine because it returns a Integer, therefore it is basically like writting Console.WriteLine("Answer: " + 7);
Here is an working version with explaination:
class Program
{
static int Add(int x, int y)
{
//x = 4; these are passed in as parameter, no need to set it
//y = 3;
int f = x + y;
return f;
}
static void Main(string[] args)
{
int someX = 4; //these are only known inside the scope of "Main"
int someY = 3;
int result = Add(someX, someY); //these are passed inside the function,
//the value is copied
Console.WriteLine("Answer: " + result.ToString());
}
}
You can do it even easier and simple In addition , this answer is more dynamic as you can choose the two numbers every time you run the program:
class Program
{
static int Add(int x, int y)
{
return x + y;
}
static void Main(string[] args)
{
Console.WriteLine("Answer: " + Add(Convert.ToInt32(Console.ReadLine()),
Convert.ToInt32(Console.ReadLine())).ToString());
Console.ReadLine(); //In order to be able to see the result in the screen
}
}

Calculator using delegates in C#.net .(arithmetic is unassigned)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ArithmaticOperation
{
class Program
{
delegate double ArithmaticDelegate(double x, double y);
static void Menu()
{
Console.WriteLine("Select an arithmatic operation");
Console.WriteLine("1)Addition");
Console.WriteLine("2)Subtraction");
Console.WriteLine("3)Multiplication");
Console.WriteLine("4)Division");
Console.WriteLine("5)Remainder");
Console.WriteLine("6)Quit");
}
static double Add(double a, double b)
{
return a + b;
}
static double Subtract(double a, double b)
{
return a - b;
}
static double Multiply(double a, double b)
{
return a * b;
}
static double Divide(double a, double b)
{
return a / b;
}
static double Modulus(double a, double b)
{
return a % b;
}
static void Main(string[] args)
{
int operation;
ArithmaticDelegate arithmatic;
double x, y;
do
{
Console.WriteLine("Enter two numbers seperated by Enter");
x = double.Parse(Console.ReadLine());
y = double.Parse(Console.ReadLine());
Console.Clear();
Menu();
operation = int.Parse(Console.ReadLine());
switch (operation)
{
//Addition
case 1:
arithmatic = new ArithmaticDelegate(Add);
break;
//Subtraction
case 2:
arithmatic = new ArithmaticDelegate(Subtract);
break;
//Multiplication
case 3:
arithmatic = new ArithmaticDelegate(Multiply);
break;
//Division
case 4:
arithmatic = new ArithmaticDelegate(Divide);
break;
//Remainder
case 5:
arithmatic = new ArithmaticDelegate(Modulus);
break;
default:
Console.WriteLine("Exiting program");
break;
}
Console.Clear();
Console.WriteLine(arithmatic(x, y));
Console.WriteLine("Press any key to continue");
Console.ReadKey(true);
Console.Clear();
} while (operation != 6);
}
}
}
I am trying to write a simple calculator using delegates. The code below would give an error at the line 81 "Console.WriteLine(arithmatic(x,y));" reporting that the variable arithmatic is unassigned local variable. I believe the cause has something to do with the variable scope in the do-while and the switch body, however the variable is declared outside the do-while so its scope should span the entire main method, and anything assigned to it from within the do-while and switch statement should remain in effect after its outside. Yet the compiler still report its uninitialized/unassigned
You are getting error message because arithmatic is not initialized in all the cases of switch statement (meaning not assigned in all execution paths).
To fix this issue:
either have some dummy method and assign that dummy method in default
static double DummyMethod(double a, double b)
{
return 6; // or any number other than 1 through 5
}
and in default case, arithmatic = DummyMethod;
(or) initialze as below:
So, to fix the error: please modify your programs to initialize arithematic as below:
ArithmaticDelegate arithmatic = null;
and then surround your arithematic call with if as below:
if (arithmatic != null)
{
Console.WriteLine(arithmatic(x, y));
}
or return in default case to skip the execution path when control enters into default case.

C# - invalid outputs

I am using enums in C# to calculate the areas of different shapes. Below is my code:
using System;
class Area
{
public enum Shape{Circle,Square};
public void AreaShape(int x,Shape ob1)
{
double a;
switch(x)
{
case (int)Shape.Circle:
a=Math.PI*x*x;
Console.WriteLine("Circle "+a);
break;
case (int)Shape.Square:
a=x*x;
Console.WriteLine("Square "+a);
break;
default:
Console.WriteLine("Invalid");
break;
}
}
}
class MyTestOne
{
public static void Main(String[] a)
{
Area obj1=new Area();
obj1.AreaShape(15,Area.Shape.Circle);
obj1.AreaShape(15,Area.Shape.Square);
}
}
The following produces an error:
obj1.AreaShape(15,Shape.Circle);
obj1.AreaShape(15,Shape.Square);
How can I get the following output?
Circle 225*pi
Square 225
When I use Area.Shape.Circle and Area.Shape.Square, the output is:
Invalid
Invalid
Pass Shape enum class not int x variable
switch (ob1)
{
case Shape.Circle:
a = Math.PI * x * x;
Console.WriteLine("Circle " + a);
break;
case Shape.Square:
a = x * x;
Console.WriteLine("Square " + a);
break;
default:
Console.WriteLine("Invalid");
break;
}
Your switch statement switches on x, which you're always passing in as 15. You should be switching on the ob1 enumeration variable and you won't need the cast.

c# create program using function to generate multiplication table using [Class Library] and test the function with different scenarios [NUnit]

Hi I need a little help creating a simple program that will Generate multiplication table (using for-loop) by using Class Library from VS C#.
I have here below the incomplete code for the for-loop but I got lost coz it's a bit different than application form and console application. If you're using class library you cannot use debug, you can run or check the codes by using Test Explorer/ Test.
(Edited Update 1) For this 2 things are needed.
Class Library (Main program)
Same solution but another class name, now it comes with NUnit that is referenced to the Main Program.
(Edited Update 2)
I'll be back to check for some info
Update 3. Here's the new code
namespace FunctionTest
{
[TestFixture]
public class Class1
{
[Test]
public void Multiplication()
{
int i;
int n = 0;
n = Convert.ToInt32(Console.ReadLine());
for (i = 1; i < 13; i++)
{
Console.WriteLine(i + "x" + n + " = " + i * n);
}
}
}
Here's the idea or what it should be look like. (Below is the program)
using System;
namespace ExerciseFunction
{
public class Equations
{
public int addition(int x, int y)
{
int z = x + y;
return z;
}
public int subtraction(int x, int y)
{
int z = x - y;
return z;
}
public int multiplication(int x, int y)
{
int z = x * y;
return z;
}
public int division(int x, int y)
{
int z = x / y;
return z;
}
static void Main(string[] args)
{
}
}
}
Now this one is the NUnit to check if the input or answer is correct or not of the Program.
using NUnit.Framework;
using ExerciseFunction;
namespace ExerciseNunit
{
[TestFixture]
public class Operations
{
[Test]
public static void addition()
{
Equations result = new Equations ();
float r = result.addition(4, 5);
Assert.AreEqual(9, r);
Assert.AreNotEqual(13, r);
}
[Test]
public static void subraction()
{
Equations result = new Equations();
int t = result.subtraction(5, 3);
Assert.AreEqual(2, t);
Assert.AreNotEqual(5, t);
}
[Test]
public static void multiplication()
{
Equations result = new Equations();
int y = result.multiplication(6, 3);
Assert.AreEqual(18, y);
Assert.AreNotEqual(15, y);
}
[Test]
public static void division()
{
Equations result = new Equations();
int u = result.division(4, 2);
Assert.AreEqual(2, u);
}
}
}
Thanks and looking forwards hearing your response. Your help is appreciated!
If you want to write a program, you probably want to execute it too. So you need and executable, not a library.
So first create a new project "Console Application" or "Windows Forms Application", or maybe a "WPF application" but not a Class Library. Also writing some unit test is useful, but I don't thing that in this case.
Secondly: do not declare loop variable i before the cycle. Do it in the cycle like this
for (int i = 0; i < 15; ++i) //or i++ there is a difference but not relevant right now.
Then... You probably want to get some input from a user to get your n.
In console application you can do that like this
int n;
string input = Console.ReadLine();
if (int.TryParse(input, out n))
{
//do your math here.
}
else
{
Console.WriteLine("That was not a number.");
}
Your for-cycle would work but the formatting of the output will be poor and most importantly, you are not printing or giving the output anywhere. So let's fix it like this (put that to place "//do your math here."):
for (int i = 1; i < 15; ++i)
{
Console.WriteLine(string.Format("{0} x {1} = {2}", i, n, i * n));
}
In the end you might want the application not to exit immediately. If you add Console.ReadLine(); in the end. It will wait for pressing any key before it exits.
If you so much want to have the algebra part in another project (which doesn't really make sense, but OK), you can create another project (Class Library) with this class in it (or put just the class in the existing project):
public static class Algebra
{
public static int Multiply(int a, int b)
{
return a * b;
}
//.... other methods
}
and then call it in the for loop like this:
int product = Algebra.Multiply(i, n);
Console.WriteLine(string.Format("{0} x {1} = {2}", i, n, product));
And of course you can then unit-test the Multiply method as much as you want.

inputs in methods at visual c# 2005

I am facing a problem in creating a console application in Visual Studio c# 2005
I created the following program in which a method (to sum 2 predefined values) is called in the program
here is the code of it
class program
{
static void Main()
{
program a;
a = new program();
Console.WriteLine(a.am1(1,2));
Console.ReadLine();
}
int sum;
public int am1(int num1, int num2)
{
sum = num1 + num2;
return sum;
}
}
Now here is the main problem I am facing, well in this program two integers (num1 and num2) are predefined, I wanted those 2 numbers to be taken from user, means user input the two numbers and then the same program goes on like above. How it should be done?
P.S remember everything should be done in methods
i hope i got your requirements ... if not, please elaborate!
public sealed class Program
{
private readonly int _number1;
private readonly int _number2;
public Program(int number1, int number2)
{
this._number1 = number1;
this._number2 = number2;
}
public int Sum()
{
return this._number1 + this._number2;
}
public static void Main(string[] args)
{
// this one here is really brutal, but you can adapt it
int number1 = int.Parse(args[0]);
int number2 = int.Parse(args[1]);
Program program = new Program(number1, number2);
int sum = program.Sum();
Console.WriteLine(sum);
Console.ReadLine();
}
}
sry, this is not my main coding style ... pfuh ... really ugly!
edit:
don't give blind trust in int.Parse(). the params are coming from the user, you better double check them!
you better triple check them, as you are doing a sum ... thankfully c# compiles with unchecked - this code may fail with an OverflowException if compiled in vb - remember ranges of int
why do you want to do a simple addition in an extra class?
you should elaborate your style (regarding your comment): separate ui-code from business-layer code!
you do not need to create an instance variable for each task - you can do that with scope variables too...!
...
Use console application command line arguments. If it suites you. Below is an example from MSDN.
public class Functions
{
public static long Factorial(int n)
{
// Test for invalid input
if ((n < 0) || (n > 20))
{
return -1;
}
// Calculate the factorial iteratively rather than recursively:
long tempResult = 1;
for (int i = 1; i <= n; i++)
{
tempResult *= i;
}
return tempResult;
}
}
class MainClass
{
static int Main(string[] args)
{
// Test if input arguments were supplied:
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
System.Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Try to convert the input arguments to numbers. This will throw
// an exception if the argument is not a number.
// num = int.Parse(args[0]);
int num;
bool test = int.TryParse(args[0], out num);
if (test == false)
{
System.Console.WriteLine("Please enter a numeric argument.");
System.Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Calculate factorial.
long result = Functions.Factorial(num);
// Print result.
if (result == -1)
System.Console.WriteLine("Input must be >= 0 and <= 20.");
else
System.Console.WriteLine("The Factorial of {0} is {1}.", num, result);
return 0;
}
}
// If 3 is entered on command line, the
// output reads: The factorial of 3 is 6.

Categories

Resources