CalculateArea using poymorphism and virtual method - not getting proper result. - c#

I have write a code to calculate the area of different shapes using polymorphism (Virtua & Override Method) but not getting correct result. :(
Below is my code:
class Program
{
static void Main(string[] args)
{
double side = 0;
double length = 0;
double width = 0;
double height = 0;
double baseoftriangle = 0;
double radius = 0;
UserChoice:
Console.WriteLine("For what shape you want to calculate the Area:\n1. Sqaure\n2. Rectangle\n3. Triangle\n4. Circle");
Console.Write("Please Select the number from above options: ");
int choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
Console.Write("Please enter the side of square: ");
side = double.Parse(Console.ReadLine());
break;
case 2:
Console.Write("Please enter the length of rectangle: ");
length = double.Parse(Console.ReadLine());
Console.Write("Please enter the width of rectangle: ");
width = double.Parse(Console.ReadLine());
break;
case 3:
Console.Write("Please enter the height of triangle: ");
height = double.Parse(Console.ReadLine());
Console.Write("Please enter the base of triangle: ");
baseoftriangle = double.Parse(Console.ReadLine());
break;
case 4:
Console.Write("Please enter the radius of circle: ");
radius = double.Parse(Console.ReadLine());
break;
default:
Console.WriteLine("Incorrect Choice, please try again!");
goto UserChoice;
}
CalculateArea Sqa = new Square();
Sqa = new Rectangle();
Sqa = new Triangle();
Sqa = new Circle();
if (choice == 1)
{
Sqa.Area(side);
Sqa.ShowResult();
}
else if(choice==2)
{
Sqa.Area(length,width);
Sqa.ShowResult();
}
else if(choice==3)
{
Sqa.Area(height, baseoftriangle);
Sqa.ShowResult();
}
else
{
Sqa.Area(radius);
Sqa.ShowResult();
}
ChoiceOfAnotherCalculation:
Console.Write("\nDo you want to calculate area of any other shape? Give input in Yes or NO: ");
string choice1 = Console.ReadLine();
switch (choice1.ToUpper())
{
case "YES":
goto UserChoice;
case "NO":
break;
default:
Console.WriteLine("Incorrect Choice, please try again!");
goto ChoiceOfAnotherCalculation;
}
}
}
class CalculateArea
{
public double result;
public virtual void Area(double side)
{
}
public virtual void Area(double length, double width)
{
}
public void ShowResult()
{
Console.WriteLine($"Your Result is {result}");
}
}
class Square: CalculateArea
{
public override void Area(double side)
{
result = side * side;
}
}
class Rectangle:CalculateArea
{
public override void Area(double length, double width)
{
result = length * width;
}
}
class Triangle:CalculateArea
{
public override void Area(double height, double baseoftriangle)
{
result = (height * baseoftriangle)/2;
}
}
class Circle:CalculateArea
{
public override void Area(double radius)
{
result = 3.14159 * radius * radius;
}
}
For Rectangle & Triangle, I am always getting 0 as a result and for square I am getting result from circle. I think this issue is causing because of the way I have created objects for class (May be because of lack of understanding in polymorphism).
Can someone please have a look and let me know what is the actual problem here.
Apart from this also I would appreciate your efforts if you can provide me the solution with get & set properties for each class. I have tried to write the code (Where I have tried to define the property in each derive class as well as in base class) but was getting various errors that's why I have jump on above solution.
I will also request please do not downvote the question as system won't allow me ask question for a long time. As this is the only platform where I can understood the things properly.
Many Thanks.

Inside the switch statement, after case 1, your program will exit. This is because you have used return;, you might have intended to use break; instead. Break statement ensures that your switch wont fall through to the next statement, and a return statement would terminate the execution immediately.
Correct case statement should be like this
case 1:
Console.Write("Please enter the side of square: ");
side = int.Parse(Console.ReadLine());
break;
EDIT
Base class will only hold an abstract method to calculate area, which should be implemented by inheriting classes.
public abstract class Shape
{
// must implement by inheriting classes
public abstract double CalculateArea();
}
Each shape would calculate area using different parameters, therefore you should create properties that would be required by that specific shape.
public class Square : Shape
{
// properties differ based on the shape..
// eg: triangle needs height and base
// edit CalculateArea method based on the shape
public double Length { get; set; }
public override double CalculateArea()
{
return Length * Length;
}
}
Implement just like you did before, create an instance of the shape then pass the required parameters and invoke CalculateArea() method, that would return a double value:
double length;
Console.WriteLine("Enter length of one side: ");
if (!double.TryParse(Console.ReadLine(), out length))
Console.WriteLine("Invalid value, must be a number or decimal value.");
Square sq = new Square();
sq.Length = length;
Console.WriteLine(sq.CalculateArea().ToString("F"));

For polymorphism your classes should look like this:
abstract class Shape
{
public abstract double Area {get;}
}
class Square: Shape
{
public double Side {get;}
public override double Area => Side * Side;
public Square (double side)
{
this.Side = side;
}
}
class Rectangle:Shape
{
public double Width {get;}
public double Length {get;}
public override double Area => Width * Length;
public Rectangle (double width, double length)
{
this.Width = width;
this.Length = length;
}
}
etc.
With this in place, you can create the Shape once during the first case statement and can then use the .Area property on it in your output.
You should not have code to do output in your shape class, keep each class focused on one thing (SRP).
Your shapes should track their own properties because you may later want to add, say, a 'Description' property that uses those properties to describe the shape.

Related

How to add a second argument(Number) to a calculator program?

I'm working on a small calculator program in Unity.
I only need the calculator to work with two numbers.
The feature I'm trying to implement:
After inputting the math operator, It should display the second number in the third index.
The issue:
Instead of Adding a second number, the first number is being overwritten if a different number is pressed on the keyboard.
Here's the script I've created:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Functions : MonoBehaviour
{
// Global Variable to display text on top panel
public Text panelText;
// Create a number variable
string num;
string num1;
string num2;
string mOpr;
string calNum;
string cbutton;
string opr;
bool isFirstNum;
// Start is called before the first frame update
void Start()
{
}
// A function with an int argument
public void NumberInputOne(string num)
{
num1 = num;
num2 = num;
if (panelText.text.Length < 1)
{
Debug.Log(num1);
panelText.text = num1;
isFirstNum = false;
}
else if (panelText.text.Length > 1 && panelText.text.Length < 3)
{
num2 = num;
Debug.Log(num2);
panelText.text = num1 + mOpr + num2;
}
}
public void OperatorInput(string opr)
{
mOpr = opr;
if (panelText.text.Length > 0 && panelText.text.Length < 2)
{
panelText.text = num1 + mOpr;
}
}
// public void NumberInputTwo(int num)
//{
// ResNum2 = num;
// Debug.Log(ResNum2);
// if (panelText.text.Length > 1 && panelText.text.Length < 3)
// {
// panelText.text = ResNum1 + opr + ResNum2;
// }
// }
public void RestartCal(string cButton)
{
panelText.text = "";
}
}
I've also added a screen recording to capture the issue:
First number being overwritten
Do you have any suggestions?
Thank you
use the NumberInputOne func like below;
public void NumberInputOne(string num)
{
if (num1 is null)
{
Debug.Log(num1);
panelText.text = num1;
num1 = num
}
else
{
num2 = num;
Debug.Log(num2);
panelText.text = num1 + mOpr + num2;
}
}
btw i recommend that you review the sample calculation application codes. because apart from what you're asking, there are places you need to improve in general.
This feels like a beginner programming exercise. But the right way to build a calculator involves programming concepts that you probably haven't been taught yet. Which makes this a poor choice as an assignment.
Personally I would build a calculator by defining a simple syntax tree to represent the formula being input. Including methods to display the formula and calculate the answer. For example;
public interface IValue
{
int Calculate();
string PrintValue();
}
public class Number : IValue
{
public int? Value;
public void AddDigit(int digit) => Value = (Value ?? 0) * 10 + digit;
public int Calculate() => Value ?? 0;
public string PrintValue() => Value?.ToString();
}
public abstract class BinaryOperator : IValue
{
public IValue Left;
public IValue Right;
public abstract int Operation(int left, int right);
public abstract char Operator { get; }
public int Calculate()
{
var left = Left.Calculate();
var right = Right.Calculate();
return Operation(left, right);
}
public string PrintValue() => $"{Left?.PrintValue()} {Operator} {Right?.PrintValue()}";
}
public class Addition : BinaryOperator
{
public override char Operator => '+';
public override int Operation(int left, int right) => left + right;
}
// TODO define other operators
Then think about how each button should change the syntax tree.
// the entire formula
public IValue Root;
// the number currently being typed
public Number Input;
public void Display() {
panelText.text = Root.PrintValue();
}
// start / clear
public void Start(){
Root = Input = new Number(){
Value = 0
};
Display();
}
public void Plus(){
// left as an exercise for the reader
Display();
}
public void Digit(int digit) {
Input.AddDigit(digit);
Display();
}
public void Calculate() {
// left as an exercise for the reader
Display();
}

Console Calculation [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 1 year ago.
Improve this question
I'm having trouble and I was wondering if there is something wrong with my code.
The code should execute the following
When executed within the terminal the MoveAmount and Move should end up equal to each other.
Side A should follow the equation
(x*a)/(a+b) and execute with the correct value. (x representing the move and A and B representing their perspective ratio).
Move - SideA = Side B
Move = SideA + SideB
Unfortunately it doesn't seem to be working and I am unable to get the code to create the proper output.
If I try to input my values based on this graph the Calculated Movement of Side A and B return incorrectly and the output does not follow the desired perameters above.
If anyone can give me any tips let me know.
using System;
namespace Example
{
class CalculatedMove
{
public double Move = 0.0;
public double SideARatio = 0.0;
public double SideBRatio = 0.0;
public CalculatedMove(double SideARatio, double SideBRatio, double Move)
{
this.Move = Move;
this.SideARatio = SideARatio;
this.SideBRatio = SideBRatio;
}
public virtual void SideA()
{
double SideA = 0.0;
SideA = (Move * SideARatio) /(SideARatio + SideBRatio);
Console.WriteLine("Calculated Side A Movement is {00:00.0000}", SideA);
}
public void SideB()
{
double SideB = 0.0;
SideB = Move - SideARatio;
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
public void MovementAmount()
{
double MovementAmount = 0.0;
MovementAmount = SideARatio + SideBRatio;
Console.WriteLine("The Calculated Move Amount is {0:00.0000}", MovementAmount);
}
}
class Program
{
static void Main(string[] args)
{
double Move, SideARatio, SideBRatio = 0.0;
Console.WriteLine("Enter the Move Amount ");
Move = Double.Parse(Console.ReadLine());
Console.WriteLine("Side A Ratio");
SideARatio = Double.Parse(Console.ReadLine());
Console.WriteLine("Side B Ratio");
SideBRatio = Double.Parse(Console.ReadLine());
CalculatedMove objMove = new CalculatedMove(Move, SideARatio,SideBRatio);
objMove.SideA();
objMove.SideB();
objMove.MovementAmount();
Console.Read();
}
}
}
First of all, as JohnG said, the sequence of parameters is wrong when calling parameters.
Then when calculating SideB, SideARatio should not be subtracted, but SideA should be subtracted.
Finally, Move should be SideA+SideB, not SideARatio+SideBRatio.
using System;
namespace Example {
class CalculatedMove {
private double move =0.0;
public double Move {
get { return move; }
set { move=value; }
}
private double sideARatio=0.0;
public double SideARatio {
get { return sideARatio; }
set { sideARatio=value; }
}
private double sideBRatio = 0.0;
public double SideBRatio {
get { return sideBRatio; }
set { sideBRatio=value; }
}
private double sideA = 0.0;
public double SideA {
get { return sideA; }
set { sideA=value; }
}
private double sideB = 0.0;
public double SideB {
get { return sideB; }
set { sideB=value; }
}
private double movementAmount = 0.0;
public double MovementAmount {
get { return movementAmount; }
set { MovementAmount=value; }
}
public CalculatedMove(double SideARatio, double SideBRatio, double Move) {
this.move=Move;
this.sideARatio=SideARatio;
this.sideBRatio=SideBRatio;
}
public virtual void SideAMove() {
SideA=(Move*SideARatio)/(SideARatio+SideBRatio);
Console.WriteLine("Calculated Side A Movement is {00:00.0000}", SideA);
}
public void SideBMove() {
SideB=(Move*SideBRatio)/(SideARatio+SideBRatio);
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
public void MovementAmountMove() {
MovementAmount=SideA+SideB;
Console.WriteLine("The Calculated Move Amount is {0:00.0000}", MovementAmount);
}
}
class Program {
static void Main(string[] args) {
double Move, SideARatio, SideBRatio = 0.0;
Console.WriteLine("Enter the Move Amount ");
Move=Double.Parse(Console.ReadLine());
Console.WriteLine("Side A Ratio");
SideARatio=Double.Parse(Console.ReadLine());
Console.WriteLine("Side B Ratio");
SideBRatio=Double.Parse(Console.ReadLine());
CalculatedMove objMove = new CalculatedMove( SideARatio, SideBRatio,Move);
objMove.SideAMove();
objMove.SideBMove();
objMove.MovementAmountMove();
Console.Read();
}
}
}
Output:
As 3.Move - SideA = Side B :
public void SideB()
{
double SideB = 0.0;
SideB = Move - SideARatio; // Here is the problem;
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}
Fix public void SideB()
public void SideB()
{
double SideB = 0.0;
SideB = (Move * SideBRatio) /(SideARatio + SideBRatio);
Console.WriteLine("The Calculated Side B Movement is {00:00.0000}", SideB);
}

How do I make another object follow across x - axis when I move an object using Up and Down arrow keys?

I am trying to create a C# console window game where I move an object "M" across the x axis using up and down arrow keys.
I'm unable to figure out how to make another object say "S" to follow me up and down where ever the object "M" is at. "M" will be located at the left of the console window that is X = 0. Whereas "S" should be located at the opposite border that is X = 100.
I have used public int properties X and Y in the abstract class. Moreover, I am using abstract method to do make objects move.
There are two derived classes Martian and SpaceShip. I have got the "M" object arrow key movement working. I just need to code in spaceship class to get the "S" object follow the "M".
//In Martian Class
public override void Draw()
{
int x = 0;
int y = 0;
X = x;
Y = y;
ConsoleKeyInfo keyInfo;
while(true)
{
keyInfo = Console.ReadKey(true);
Console.Clear();
switch (keyInfo.Key)
{
case ConsoleKey.UpArrow:
Y--;
Console.SetCursorPosition(X,Y);
Console.WriteLine("M");
break;
case ConsoleKey.DownArrow:
Y++;
Console.SetCursorPosition(X,Y);
Console.WriteLine("M");
break;
}
}
}
//In SpaceShip Class
public override void Draw()
{
//How do I make the "S" follow "M"?
}
I expect the "S" to follow the "M" across vertically but will be located opposite of the window borders.
Any help is appreciated. Thanks in advance.
I think your Draw methods are doing to much. They should only be responsible for drawing the object on the screen. The moving of the objects and the handling of keyboard must be done somewhere else.
Here is my solution:
using System;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
Martian m = new Martian();
SpaceShip s = new SpaceShip();
const int MaxY = 100;
m.Draw();
s.X = m.X + 100;
s.Y = m.Y;
s.Draw();
ConsoleKeyInfo keyInfo;
while (true)
{
keyInfo = Console.ReadKey(true);
Console.Clear();
switch (keyInfo.Key)
{
case ConsoleKey.UpArrow:
if (m.Y > 0)
{
m.Y--;
}
break;
case ConsoleKey.DownArrow:
if (m.Y < MaxY)
{
m.Y++;
}
break;
}
m.Draw();
s.X = m.X + 100;
s.Y = m.Y;
s.Draw();
}
}
}
public abstract class GameObject
{
public int X { get; set; }
public int Y { get; set; }
public abstract void Draw();
}
public class Martian : GameObject
{
public override void Draw()
{
Console.SetCursorPosition(X, Y);
Console.WriteLine("M");
}
}
public class SpaceShip : GameObject
{
public override void Draw()
{
Console.SetCursorPosition(X, Y);
Console.WriteLine("S");
}
}
}

Calculate Surface Area of 2D shapes

A friend recently had a telephone interview and he was asked a technical question:
Q) If I wanted to calculate the surface area of some 2D shapes then what "Bucket" would I use. He had 20 minutes to write some code and the interviewer called him back. He sent the code via email and the code was not discussed for the remainder of the interview (there were no other technical questions). He sent me the code:
Windows Forms app
namespace ShapesApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += form_load;
}
public void form_load (Object o, EventArgs e)
{
List<Shape> listShape = new List<Shape>();
Shapes.Circle circle = new Shapes.Circle();
Shapes.Rectangle rectangle = new Shapes.Rectangle();
Shapes.Square square = new Shapes.Square();
Shapes.Triangle triangle = new Shapes.Triangle();
listShape.Add(rectangle);
listShape.Add(square);
listShape.Add(triangle);
foreach (Shape shape in listShape)
{
double a = 10;
double b = 10;
double surfaceArea = shape.CalculateSurfaceArea(a,b);
Console.WriteLine("The surface area of a " + shape.GetType() + " is: " + surfaceArea);
}
}
}
}
Shapes - Class Library
namespace Shapes
{
public abstract class Shape
{
abstract public double CalculateSurfaceArea(double Double1, double Double2);
}
public class Circle : Shape
{
public override double CalculateSurfaceArea(double pi, double radius)
{
return (pi * radius) * (pi * radius);
}
}
public class Triangle : Shape
{
public override double CalculateSurfaceArea(double Base, double Height)
{
return (Base*Height)/2;
}
}
public class Rectangle : Shape
{
public override double CalculateSurfaceArea(double Length, double Width)
{
return Length * Width;
}
}
}
The interviewer has said that he "struggled" with the test. What is wrong with the code?
Calculating area is the behavior and every shape has his own formula for calculating it. Because calculating area can involve different amount of variables and constants method will not take any parameter and variables will be concern of class which implement interface .
So I think method of calculating area can be abstracted as interface:
public interface ICalculatingArea
{
double CalculateArea();
}
Then every shape will implement it on its own manner.
public class Rectangle:ICalculatingArea
{
public double Width {get; set;}
public double Length {get; set;}
public double CalculateArea()
{
return Length * Width;
}
}
In the main program it is enough to cast shape classes to the interface type and use CalculateArea method

Getting data from the user via the command line

I want to have someone input a value for length and width in my code, here is what I got so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Rectangle
{
double length;
double width;
double a;
static double Main(string[] args)
{
length = Console.Read();
width = Console.Read();
}
public void Acceptdetails()
{
}
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
class ExecuteRectangle
{
public void Main()
{
Rectangle r = new Rectangle();
r.Display();
Console.ReadLine();
}
}
}
Is trying to use two Main methods the wrong way to approach this? This is code I was copying from http://www.tutorialspoint.com/csharp/csharp_basic_syntax.htm I'm trying to modify it around to just to get more experience with this programming language.
There are some problem with you code, let's analyse them:
a program must have a unique entry point and it must be a declared as static void, here you have two main but they are wrong
you in your static Main the one in the rectangle class you can't reference the variables length e width because they're not declared as static
console.Read() return an int that represent a character so using if the user inputs 1 you may have a different value in your length variable
your static double Main doesn't return a double
I think that what you want is:
declare the static double Main as void Main()
declare your void Main as static void Main(string[] args)
in your new static void Main call (after you create the rectangle) it's Main method (to do that you have to define it as public)
use ReadLine instead of Read()
ReadLine return a string so to transform that in a double you have to use lenght = double.Parse(Console.ReadLine())
finally call your r.display()
This is a working code that do what you want.
Note before copy pasting, since you're trying and lear read the steps and try to fix it without looking at the code
class Rectangle
{
double length;
double width;
double a;
public void GetValues()
{
length = double.Parse(Console.ReadLine());
width = double.Parse(Console.ReadLine());
}
public void Acceptdetails()
{
}
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
class ExecuteRectangle
{
public static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.GetValues();
r.Display();
Console.ReadLine();
}
}
In this cases you'll have to tell the compiles wich is the class with the entry point.
"If your compilation includes more than one type with a Main method, you can specify which type contains the Main method that you want to use as the entry point into the program."
http://msdn.microsoft.com/en-us/library/x3eht538.aspx
And yes, having two main methods is confusing and senseless.

Categories

Resources