Why is are the result values are in 0 in C#? - c#

I have this code and I am trying to calculate the area and circumference of the circle. I have tried debugging and I can see that the radius was passed but the area and circumference is not, it's always 0.
using System;
class Circle{
double radius;
double area;
double circumference;
public double Radius{set{radius = value;}}
public double Area{set{area=value;}}
public double Circumference{set{circumference=value;}}
public Circle(double radius){
this.radius = radius;
area=0;
circumference=0;
}
void CalculateArea(){
area=Math.PI*Math.Pow(radius,2);
}
void CalculateCircumference(){
circumference = 2*Math.PI*radius;
}
public void DisplayArea(){
System.Console.WriteLine("Area is {0}",area);
}
public void DisplayCircumference(){
System.Console.WriteLine("Circumference is {0}",circumference);
}
}
class TestCircle{
public static void Main(string[] args)
{
System.Console.WriteLine("Enter radius: ");
double radius=Convert.ToDouble(Console.ReadLine());
Circle theCircle = new Circle(radius);
theCircle.DisplayArea();
theCircle.DisplayCircumference();
}
}
this is the output
Enter radius:
3
Area is 0
Circumference is 0

You have a very strange design: set only Radius (once set I can't read it), editable (both get and set) Area: one
can easily assign -1.0 to it...
Let's redesign it; we have Circle class with three properties only:
class Circle{
// Radius, the man property we can
// - read it (get)
// - assign it, but let it be just once (so set is private)
public double Radius {get; private set;}
// Area, which we can just read (get, no set)
public double Area => Math.PI * Radius * Radius;
// Circumference, which we can just read (get, no set)
public double Circumference => 2 * Math.PI * Radius;
public Circle(double radius) {
Radius = radius;
}
public void DisplayArea(){
System.Console.WriteLine($"Area is {Area}");
}
public void DisplayCircumference(){
System.Console.WriteLine($"Circumference is {Circumference}");
}
}

Related

Calling an overridden function from a base constructor

It makes sense that I should not call an overridden function from a base constructor, since the derived class is not yet constructed.
But I want to use this design pattern, where each derived class provides methods for calculating the properties of the base class since the properties should be immutable and assigned at the constructor.
Shape.cs
public abstract class Shape
{
protected Shape()
{
Area = 0f;
Center = Vector2.Zero;
const int n = 36;
float du = 1/(float)n, dv = 1/(float)n;
for (int i = 0; i < n; i++)
{
float u = (i+0.5f)*du;
for (int j = 0; j < n; j++)
{
float v = (i+0.5f)*dv;
float f = GetAreaElement(u, v);
// Warning: Remove this call from a constructor to the overridable 'GetAreaElement' method.
Area += f*du*dv;
Center += GetPosition(u, v)*f*du*dv;
// Warning: Remove this call from a constructor to the overridable 'GetPosition' method.
}
}
Center /= Area;
}
public abstract Vector2 GetPosition(float u, float v);
protected abstract float GetAreaElement(float u, float v);
public float Area { get; }
public Vector2 Center { get; }
}
public class Circle : Shape
{
public Circle(float radius)
{
Radius=radius;
}
public float Radius { get; }
public override Vector2 GetPosition(float u, float v)
{
float r = u*Radius, θ = (float)(2*Math.PI)*v;
return new Vector2(
r*(float)Math.Cos(θ),
r*(float)Math.Sin(θ));
}
protected override float GetAreaElement(float u, float v)
{
return u*Radius;
}
}
public class Rectangle : Shape
{
public Rectangle(float side1, float side2)
{
Side1=side1;
Side2=side2;
}
public float Side1 { get; }
public float Side2 { get; }
public override Vector2 GetPosition(float u, float v)
{
return new Vector2((u-0.5f)*Side1, (v-0.5f)*Side2);
}
protected override float GetAreaElement(float u, float v)
{
return Side1*Side2;
}
}
So what is the solution here? I want to use the base constructor to define the properties, and the calculation depends on the implementation of the derived class.
Workaround 1 - Future calculator
A workaround would be to provide a protected function that calculates the properties, each to be called from each constructor of the derived class, but there is no enforcement here. If one class forgets to call the calculator function the whole thing falls apart. And the properties are now private set which is not immutable really.
public abstract class Shape
{
protected void Calculate()
{
...
float f = GetAreaElement(u, v);
...
Center += GetPosition(u, v)*f*du*dv;
...
}
public abstract Vector2 GetPosition(float u, float v);
protected abstract float GetAreaElement(float u, float v);
public float Area { get; private set; }
public Vector2 Center { get; private set; }
}
public class Circle : Shape
{
public Circle(float radius)
{
Radius=radius;
base.Calculate();
}
public float Radius { get; }
public override Vector2 GetPosition(float u, float v)
{
...
}
protected override float GetAreaElement(float u, float v)
{
...
}
}
Workaround 2 - Function delegates
Another workaround would be to supply the delegates to the required function implementations as arguments to the base class constructor.
public delegate float AreaFactor(float u, float v);
public delegate Vector2 PositionFunc(float u, float v);
public abstract class Shape
{
protected Shape(AreaFactor a, PositionFunc p)
{
this.GetAreaElement = a;
this.GetPosition = p;
...
float f = a(u, v);
this.Center += p(u, v)*f*du*dv;
...
}
public float Area { get; }
public Vector2 Center { get; }
public AreaFactor GetAreaElement { get; }
public PositionFunc GetPosition { get; }
}
public class Circle : Shape
{
public Circle(float radius)
: base(
(u, v) => u*radius,
(u,v)=>
{
float r = u*radius, θ = (float)(2*Math.PI)*v;
return new Vector2(
r*(float)Math.Cos(θ),
r*(float)Math.Sin(θ));
})
{
Radius=radius;
}
public float Radius { get; }
}
This seems a bit clunky to me, and I am not sure I like the function delegate properties, instead of overridden methods.
Question/Challege
Can [SO] provide some other ways of achieving the above-stated goals
Base properties are immutable
Base properties are calculated at the constructor based on the implementation details of the derived classes.
Each derived class holds its own immutable properties used to describe the derived class.
One option is to, instead of calculating the Area and Center in the constructor, lazily calculate them in the property getter. It will require a backing field to know if the property has been calculated or not, but it will get rid of the warning.
It also seems odd to me that you don't pass the center to the Shape constructor, but I don't fully understand the design you're using.
My preference is to go with Option 2 - passing to the base constructor the methods to generate the derived properties. It does satisfy all your requirements. If aesthetics is a concern, perhaps using a Func might make the code easier to read. The key is that the Func's are static methods, which should not be a problem since they calculate immutable properties of the object.
void Main()
{
var square = new Square(5);
}
public abstract class Shape
{
protected Shape(Func<int> areaFunc)
{
Area = areaFunc();
}
public int Area { get; }
}
public class Square : Shape
{
public Square(int side): base( () => CalcArea(side) )
{
Side = side;
}
static int CalcArea(int side) => side * side;
public int Side { get; }
}

C# difference between member variables and arguments passed to a method

I am working on an assignment with very specific instructions, which, if it is of any intrest, I will post below the code I have created. But, in short, I am to create a BasicShape abstract class, as well as a Circle and Rectangle subclasses. Each subclass has a method for calculating the area of the shape. the area is calculated using member variables. However, in my code below, these member variables are never assigned a value. I am confused as to how to assign it to them, because Circle and Rectangle methods also require arguments to be passed to them. These arguments x, y, r for Circle and w, l for Rectangle are specified in the main program when a new instance of a shape is made, but these values also seem to do nothing, since the output is always 0. What relationship do the arguments passed into the methods have to the member variables? How is it that the member variables should be assigned values when the values are given via arguments set when a Circle or Rectangle instance is called?
Here is my code:
abstract class BasicShape
{
protected double area;
public double getArea()
{
Console.WriteLine("Area: {0}", area);
return area;
}
public virtual void calcArea()
{
}
}
class Circle : BasicShape
{
private int centerX;
private int centerY;
private double radius;
public Circle(int x, int y, double r)
{
calcArea();
}
public int genCenterX()
{
return centerX;
}
public int genCenterY()
{
return centerY;
}
public override void calcArea()
{
area = 3.14159 * radius * radius;
Console.WriteLine("The area of the circle is: {0}", area);
}
}
class Rectangle : BasicShape
{
private int width;
private int length;
public Rectangle(int w, int l)
{
calcArea();
}
public int getWidth()
{
return width;
}
public int getLength()
{
return length;
}
public override void calcArea()
{
area = length * width;
Console.WriteLine("The area of the rectangle is: {0}", area);
}
}
public class TestShapes
{
static void Main(string[] args)
{
Circle circle1 = new Circle(2, 2, 5);
Rectangle rectangle = new Rectangle(6, 7);
Console.ReadLine();
}
}
Here are the instructions for the assignment:
Define a pure abstract base class called BasicShape.
The BasicShape class should have the following members:
Private Member Variable:
area, a double used to hold the shape’s area.
Public Member Methods:
getArea(): This method should return the value in the member variable area.
calcArea(): This method should be a pure virtual method.
Next, define a class named Circle. It should be derived from the BasicShape class. It should have the following members:
Private Member Variable:
centerX, an integer used to hold the x coordinate of the circle’s center.
centerY, an integer used to hold the y coordinate of the circle’s center.
radius, a double used to hold the circle’s radius.
Public Member Methods:
Circle(int x, int y, int r): accepts values for centerX, centerY, and radius. Should call the overridden calcArea
method described below.
genCenterX: returned the value in centerX
genCenterY: returned the value in centerY
calcArea(): calculates the area of the circle (area = 3.14159 * radius * radius) and stored the result in the inherited member area.
Next, define a class named Rectangle. It should be derived from the BasicShape class. It should have the following members:
Private Member Variable:
width, an integer used to hold the width of the rectangle
length, an integer used to hold the length of the rectangle
Public Member Methods:
Rectangle(int w, int l): accepts values for the width and length. Should call the overridden calcArea method described below.
getWidth(): returns the value in width.
getLength(): returns the value in length
calcArea(): calculates the area of the circle (area = length * width) and stored the result in the inherited member area.
After you have created these classes, create a main program that defined a Circle object and a Rectangle object.
Demonstrate that each object properly calculates and reports its area.
You don't assign the values passed from the constructor to your member variables. So when you call calcArea you execute it using the default values for the types int or double (which is zero)
class Circle : BasicShape
{
private int centerX;
private int centerY;
private double radius;
public Circle(int x, int y, double r)
{
radius = r;
// Now you are executing the calcArea using the value passed in
calcArea();
}
....
}
class Rectangle : BasicShape
{
private int width;
private int length;
public Rectangle(int w, int l)
{
width = w;
length = l;
calcArea();
}
....
}
The override of calcArea needs the member variables to be set to something otherwise these member variables are initialized with their default values (zero in both integer and double) and thus the method cannot produce a meaningful result.

My C# program always prints the area as 0

I wrote a C# program to print the area, but when I run the program it always prints "The area is 0". Any idea what seems to be the problem?
class Circle
{
double radius;
// int color;
double area;
public void setCircleInfo()
{
radius = 15;
//color = 225;
}
public void calculateArea()
{
area = 3.142 * radius * radius;
}
public double getRadius()
{
return radius;
}
public void displayArea()
{
Console.WriteLine("The area is " + area.ToString());
Console.ReadLine();
}
}
}
Here's the code to the main method:
{
class Program
{
static void Main(string[] args)
{
Circle obj1 = new Circle();
obj1.displayArea();
}
}
}
Your code runs fine for me. The reason why you are always getting The area is 0 is probably you are missing any one of the following calls. Note that If you miss setCircleInfo or calculateArea, you will get a zero as the result.
Circle c = new Circle();
c.setCircleInfo();
c.calculateArea();
c.displayArea();
Hope this helps :-)
I would adjust the object a little bit to make it easier to use:
class Circle
{
public double Radius
{
get;
set;
}
public double Area
{
get
{
return 3.142 * radius * radius;
}
}
public Circle(double radius)
{
Radius = radius;
}
public void displayArea()
{
Console.WriteLine("The area is " + Area.ToString());
Console.ReadLine();
}
}
You can then use it like this:
static void Main(string[] args)
{
Circle obj1 = new Circle(15);
obj1.displayArea();
}
Change your code
static void Main(string[] args)
{
Circle obj1 = new Circle();
obj1.setCircleInfo();
obj1.calculateArea();
obj1.displayArea();
}
add in your Circle constructor method:
public Circle(double radius){
this.radius=radius;
c.setCircleInfo();
c.calculateArea();
c.displayArea();
}

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

Using methods to make a circumference calculator

So i have made a small console calculator for working out the circumference of a circle. Yet i would like to rewrite it using methods. But i don't know where to start. Can anyone help me
using System;
class Circle
{
static void Main()
// Circumference of a circle: C=2πr
{
Console.WriteLine("What is the radius of your circle: ");
double radius = double.Parse(Console.ReadLine());
double pi = 3.1452;
double area = 2 * pi * radius;
Console.WriteLine("The Circumference of your circle is: "+ area);
Console.ReadKey();
}
}
using System;
class Circle
{
public static double GetCircumference(double radius)
{
return 2 * Math.PI * radius;
}
static void Main()
// Circumference of a circle: C=2πr
{
Console.WriteLine("What is the radius of your circle: ");
Console.WriteLine("The Circumference of your circle is: " + GetCircumference(Double.Parse(Console.ReadLine())).ToString());
Console.ReadKey();
}
}
If you just want to break out the calculation into a method, you just create the following method below your main method:
private static double CalculateCircumference(double radius)
{
return 2 * radius * Math.PI;
}
And then call it from within your main method like so:
double circumference = CalculateCircumference(radius);
All in all
static void Main()
{
Print("What is the radius of your circle: ");
double radius = ParseInputNumber();
double circumference = CalculateCircumference(radius);
Print("The Circumference of your circle is: " + circumference);
WaitForKeystroke();
}
private static void Print(string message)
{
Console.WriteLine(message);
}
private static double ParseInputNumber()
{
return double.Parse(Console.ReadLine());
}
private static void WaitForKeystroke()
{
Console.ReadKey();
}
private static double CalculateCircumference(double radius)
{
return 2 * radius * Math.PI;
}

Categories

Resources