I'm writing a Java Program in which I have to get the Average Area from the given shape. I'm needing to get the average area from the askAreaProblem problem and here is the methods for the askAreaProblem and the getAverageArea method. The askAreaProblem method works fine, but the unit test for the getAverageArea method are failing. Here is my code for the two methods.
public class Assignment9 {
public static void askAreaProblem(IShape s, double acceptableVariance)
{
System.out.println("What is the area of a "+s.forProblemStatement());
double answer=new Scanner(System.in).nextDouble();
double area=s.getArea();
if(Math.abs(answer-area)<=acceptableVariance) {
System.out.println("Yay ! your answer, "+answer+" is correct");
} else {
System.out.println("Sorry :( your answer, "+answer+" is not correct.");
System.out.println("The correct answer is "+area);
}
}
public static double getAverageArea(IShape[] shapes)
{
double sum = 0;
double avg = sum/shapes.length;
for(IShape shape: shapes) {
sum += shape.getArea();
}
return avg;
}
Here is the Unit test. If it passes I get 20 points.
public void testAverageArea()
{
IShape[] shapes={new Rectangle(2,3), new Circle(1)};
Assert.assertEquals(4.57,Assignment9.getAverageArea(shapes),0.01);
IShape[] shapes2={new Rectangle(2,3)};
Assert.assertEquals(6,Assignment9.getAverageArea(shapes2),0.01);
}
#Grade(points=20)
#Test
Here is the rest of my code for the program that I'm writing:
package assignment;
import java.util.Scanner;
import java.util.Random;
interface IShape {
double getArea();
double getPerimeter();
String forProblemStatement();
}
class Rectangle implements IShape {
private double width, height;
public Rectangle(double width, double height) {
this.width=width;
this.height=height;
}
#Override
public double getArea() { return width*height; }
#Override
public double getPerimeter() { return 2*(width+height); }
#Override
public String toString(){ return "Rectangle[width:"+width+" height:"+height+"]"; }
#Override
public String forProblemStatement() {
return "rectangle with width "+ width +" and height "+height+".";
}
}
class Circle implements IShape {
private double radius;
public Circle(double radius) {
this.radius=radius;
}
#Override public double getArea() { return Math.PI*radius*radius;}
#Override public double getPerimeter() {return 2*radius*Math.PI;}
#Override public String toString(){ return "Circle[radius:"+radius+"]"; }
#Override public String forProblemStatement() {
return "circle with radius "+radius;
}
}
class Square implements IShape {
private double side;
public Square(double side) {
this.side=side;
}
double getSide(){return side;}
#Override
public double getArea() { return side * side; }
#Override
public double getPerimeter() { return 4 * side; }
#Override
public String toString(){ return "Square"; }
#Override
public String forProblemStatement() {
return "square.";
}
}
class RegularPolygon implements IShape {
private double sides;
private double size;
private double apothem;
public RegularPolygon(double sides, double size, double apothem) {
this.sides=sides;
this.size=size;
this.apothem=apothem;
}
double getSides(){
return sides;
}
#Override
public double getArea() {
return .5 * apothem * size * sides;
}
#Override
public double getPerimeter() {
return size * sides;
}
#Override
public String toString() {
return "RegularPolygon";
}
#Override
public String forProblemStatement() {
return "RegularPolygon";
}
}
class ShapeFactory {
public static Random randomGenerator=new Random();
public static IShape getShapeInstance(String kindOfShape, double param1, double param2, double param3) {
kindOfShape=kindOfShape.toLowerCase();
if(kindOfShape.equals("circle")) {
return new Circle(param1);
} else if (kindOfShape.equals("rectangle")) {
return new Rectangle(param1, param2);
}
else if (kindOfShape.equals("square")) {
return new Square(param1);
} else if (kindOfShape.equals("RegularPolygon")) {
return new RegularPolygon(param1, param2, param3);
}
return null;
}
public static IShape getRandomShape() {
String[] shapeNames={"circle", "rectangle", "square","RegularPolygon"};
int shape=randomGenerator.nextInt(shapeNames.length);
int param1=randomGenerator.nextInt(10)+1;
int param2=randomGenerator.nextInt(10)+1;
int param3=randomGenerator.nextInt(10)+1;
return getShapeInstance(shapeNames[shape],param1,param2,param3);
}
}
The computation of avg = sum/shapes.length should be after the loop of accumulating sum, not before.
Look at your code line by line.
First line you have declared sum with the value of zero.
Second line you have declared avg with value of sum/shapes.length.
This means avg will equal to zero, your getAverageArea method therefore will always return zero.
I suggest:
public static double getAverageArea(IShape[] shapes)
{
double sum = 0;
for(IShape shape: shapes) {
sum += shape.getArea();
}
return sum/shapes.length;
}
Related
How should I pass the "type" parameter of a constructor in an if/else statement? For eg - cal(2,2,0,rectangle). So if the type=rectangle then calculate area of a rectangle. If type=circle, calculate the area of a circle.
I am using a single constructor. My issue is that I know the logic but I can't write it in syntax. I am using Java or Apex.
I want to use if-else statement. How should I pass the type parameter in the code?
My program is like this -
if "type"=square, the compiler will call calculate area of the square.
if "type"=circle, the compiler will call calculate area of the circle.
public class Area {
private String type;
private Integer length;
private Integer breadth;
private Integer height;
private Integer area;
public void setType(String t){
type=t;
}
public void setLength(Integer l){
length=l;
}
public void setbreadth(Integer b){
breadth=b;
}
public void setheight(Integer h){
height=h;
}
/* public void setArea(Integer a){
area=a;
} */
public Integer getLength(){
return length;
}
public Integer getbreadth(){
return breadth;
}
public Integer getheight(){
return height;
}
public string gettype(){
return type;
}
public Integer AreaRectangle(){
return area=length*breadth;
}
public Integer AreaSquare(){
return area=length*length;
}
public integer AreaTriangle(){
return area=1/2 *(breadth*height);
}
public Area(){ // default constructor
length=9;
breadth=2;
height=7;
}
public Area(String t,Integer l ,Integer b,Integer h ){ // parameterised constructor
type=t;
length=l;
breadth=b;
height=h;
}
}
You don't. You create an abstract class called shape.
public abstract class Shape {
abstract double area();
}
And then two other classes that extend Shape and each provides the proper implementation
public class Square extends Shape {
private int side;
public Square(int side) {
this.side = side;
}
public double area() {
return (double) side * side;
}
}
Now at the place you want to call it:
Shape shape = new Square(5);
double area = shape.area();
Int radius = 4;
shape = new Circle(radius);
double circle area = shape.area();
Define an interface call GeometricForm and which contains methods which return the area and perimeter of the
geometric form. Implement the interface for: squares, rectangles, circles, equilateral triangles and isosceles triangles.
Read from the keyboard N distinct geometric forms specified by their type and specific parameters (for example for a
circle, you would need to read its radius). Compute the total area and perimeter of all the geometric forms, taking into
account the fact that they do not overlap
Okay so I dont understand. Can I read from keyboard N distinct geometric forms like Rectangle, Circle, Square etc? Just declare an interface with n elements but this 5 can circle/square/rectangle?
interface GeometricForm {
double getArea();
double getPerimeter();
String getGeometricForm();
}
class Square implements GeometricForm{
double l;
Square(){
l=1;
}
Square(double l){
this.l=l;
}
double getL() {
return l;
}
public double getArea() {
return (getL()*getL());
}
public double getPerimeter() {
return(getL()*4);
}
public String getGeometricForm() {
return "Square";
}
}
class Rectangle implements GeometricForm{
double L, l;
Rectangle(){
L=1;
l=1;
}
Rectangle(double L, double l){
this.L=L;
this.l=l;
}
double getL() {
return L;
}
double getl() {
return l;
}
public double getArea() {
return (getL())*(getl());
}
public double getPerimeter() {
return 2*(getL()+getl());
}
public String getGeometricForm() {
return "Rectangle";
}
}
class Circle implements GeometricForm{
double radius;
Circle(){
radius=1;
}
Circle(double radius){
this.radius=radius;
}
double getRadius() {
return radius;
}
public double getArea() {
return ((getRadius())*(getRadius())*(Math.PI));
}
public double getPerimeter() {
return 2*Math.PI*getRadius();
}
public String getGeometricForm() {
return "Circle";
}
}
public class P5 {
static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) {
int n=keyboard.nextInt();
}
}
I was told that i should make a JUnit Test to check if all the codes are working. I dont know anything about JUnit that Is why im asking you guys. Anyway, here is my code:
package cst8284.shape;
public abstract class BasicShape {
private double width;
public double getWidth(){return width;}
public void setWidth(double width){this.width = width;}
#Override
public String toString(){
return ("BasicShape Overrides " + super.toString());
}
public abstract double getArea();
public abstract double getPerimeter();
}
Here is where i should make testing,
package cst8284.shape;
public class TestBasicShape {
public static void main(String[] args){
Circle circle = new Circle(2.0);
System.out.println(circle.toString());
System.out.println("The perimeter of the circle is " + circle.getPerimeter());
System.out.println("The area of the circle is: " + circle.getArea() + "\n");
Square square = new Square(2.0);
System.out.println(square.toString());
System.out.println("The perimeter of the square is " + square.getPerimeter());
System.out.println("The area of the square is: " + square.getArea() + "\n");
Rectangle rect1 = new Rectangle(2.0,3);
System.out.println(rect1.toString());
System.out.println("The perimeter of the rectangle is " + rect1.getPerimeter());
System.out.println("The area of the rectangle is: " + rect1.getArea() +"\n");
Rectangle rect2 = new Rectangle(rect1);
Rectangle rect3 = new Rectangle(2.0, 1.0);
System.out.println("The square and the circle are " + (square.equals(circle)?"":"not ") + "equal");
System.out.println("The rectangle and the square are " + (rect1.equals(square)?"":"not ") + "equal");
System.out.println("Rectangles 1 and 2 are " + (rect2.equals(rect1)?"":"not ") + "equal");
System.out.println("Rectangles 2 and 3 are " + (rect2.equals(rect3)?"":"not ") + "equal");
}
}
package cst8284.shape;
public class Circle extends BasicShape {
public Circle(){
}
public Circle(double width){
setWidth(width);
}
public Circle(Circle circle) {
setWidth(circle.getWidth());
}
//Getters
public double getArea() {
return Math.PI * (getWidth()/2) * (getWidth()/2);
}
public double getPerimeter() {
return 2*Math.PI*getWidth()/2;
}
#Override
public String toString(){
return ("Circle Overrides " + super.toString());
}
#Override
public boolean equals(Object obj){
if (!(obj instanceof Circle)) {
return false;
}
Circle c = (Circle)obj;
return (this.getWidth() == c.getWidth());
}
}
package cst8284.shape;
public class Square extends BasicShape{
public Square() {
}
public Square(double width) {
setWidth(width);
}
public Square(Square square) {
setWidth(square.getWidth());
}
//Getters
public double getArea() {
return getWidth()*2;
}
public double getPerimeter() {
return 4*getWidth();
}
#Override
public String toString(){
return ("Square Overrides " + super.toString());
}
#Override
public boolean equals(Object obj){
if (!(obj instanceof Square)) {
return false;
}
Square s = (Square)obj;
return (this.getWidth() == s.getWidth());
}
}
package cst8284.shape;
public class Rectangle extends Square{
private double height;
public Rectangle() {
}
public Rectangle(double width, double height) {
setWidth(width);
setHeight(height);
}
public Rectangle(Rectangle rectangle) {
setWidth(rectangle.getWidth());
setHeight(rectangle.getHeight());
}
public double getHeight(){
return height;
}
public void setHeight(double height){
this.height=height;
}
public double getArea() {
return getWidth()*getHeight();
}
public double getPerimeter() {
return 2*(getHeight()+getWidth());
}
#Override
public String toString(){
return ("Rectangle Overrides " + super.toString());
}
#Override
public boolean equals(Object obj){
if (!(obj instanceof Rectangle)) {
return false;
}
Rectangle r = (Rectangle)obj;
return (this.getWidth() == r.getWidth() && this.getHeight() == r.getHeight());
}
}
In this program, i am trying to calculate the area and perimeter of Circle and Square(subclasses of BasicShape) and Rectangle(subclass of Square) and also trying to compare whether each shape are equal(in shape or in size)
Thank you in advance!
I have found the easiest way to approach testing is to make a test class for each of the classes whose behaviour you would like to test in your system, and place these test classes in a separate package.
Then, say you want to test the methods in the rectangle class.
//imports
public void testRectangle(){
Rectangle rectange;
#Before
public void setup(){
rectangle = new Rectangle();
}
//Say you want to test whether the setHeight method works as it should
#Test
public void testSetHeight(){
rectangle.setHeight(10.0);
assertEquals(10.0, rectangle.getHeight());
}
//The rest of the methods you would like to test
A few things to note :
Methods in the test class never takes in any parameters.
#Before means the method is going to run before each of the test methods. This allows you to setup anything you will need for the tests to run. You must have #Test before each test method. The example I have provided above is very simple and by no means exhaustive, so you should look up the JUnit documentation and learn more.
I have been given an assignment with two given classes, one abstract parent class Lot.java, and test class TestLots.java. I am not supposed to edit either of these. The assignment is to create two subclasses of Lot so that the errors in TestLots are no longer errors.
The purpose of the program is to display the name and area of the lots in order of are like this:
Lot ID L3 has area: 13500.0
Lot ID L2 has area: 27000.0
Lot ID L1 has area: 35000.0
Lot ID L4 has area: 70000.0
However I get the errors:
Incompatible types: LotType1 cannot be converted to Lot, and
LotType2 cannot be converted to Lot. I suspect the issue is in my subclass and the way it is supposed to override or reference the parent class.
Here is TestLots, where I get the error:
public class TestLots {
public static void main(String args[]){
// an array of lots -- some of type1, some of type2
Lot[] lots = {new LotType1("L1",350, 200), // error here
new LotType2("L2",100,270),
new LotType1("L3",100, 270),
new LotType2("L4",350,200)
};
// sort the lots of mixed types by area (note, you'll have to implement
// Comparable interface correctly in LotType1 and LotType2 for this to work:
java.util.Arrays.sort(lots);
// print out sorted results
for (Lot lot: lots) {
System.out.print(lot + " ");
System.out.println();
}
}
}
Here is Lot, the parent class
public abstract class Lot {
public abstract double calculateArea();
public abstract String getID();
#Override
public String toString() {
return "Lot ID "+ getID() +" has area: "+ calculateArea();
}
}
The subclasses are nearly identical:
public class LotType1 extends Lot implements Comparable<LotType1>{
String name;
int height;
int width;
double area;
public LotType1(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = ((width * height)/2);
}
#Override
public int compareTo(LotType1 lot) {
area = ((width * height)/2);
if(area==lot.area)
{
return 0;
}
else if(area>lot.area)
{
return 1;
}
else
{
return -1;
}
}
}
Edit to add LotType2:
public class LotType2 extends Lot implements Comparable<LotType2>{
String name;
int height;
int width;
double area;
public LotType2(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = (width * height);
}
#Override
public int compareTo(LotType2 lot) {
area = (width * height);
if(area==lot.area)
{
return 0;
}
else if(area>lot.area)
{
return 1;
}
else
{
return -1;
}
}
}
Sorry this post is so long. I decided to include all of the relevant files in case that helps.
The problem is that you can't sort objects with different comparable implementations in the same collection. Change the subclass to implement Comparable of Lot :
public class LotType1 extends Lot implements Comparable<Lot> {
and also use calculateArea() in the compareTo method:
#Override
public int compareTo(Lot lot) {
if (calculateArea() == lot.calculateArea()) {
return 0;
} else if (calculateArea() > lot.calculateArea()) {
return 1;
} else {
return -1;
}
}
Your full version of code is given below.
It will give you the expected result.
public class TestLots {
public static void main(String args[]) {
// an array of lots -- some of type1, some of type2
Lot[] lots = {new LotType1("L1", 350, 200), // error here
new LotType2("L2", 100, 270),
new LotType1("L3", 100, 270),
new LotType2("L4", 350, 200)
};
// sort the lots of mixed types by area (note, you'll have to implement
// Comparable interface correctly in LotType1 and LotType2 for this to work:
java.util.Arrays.sort(lots);
// print out sorted results
for (Lot lot : lots) {
System.out.print(lot + " ");
System.out.println();
}
}
}
abstract class Lot {
public abstract double calculateArea();
public abstract String getID();
#Override
public String toString() {
return "Lot ID " + getID() + " has area: " + calculateArea();
}
}
class LotType1 extends Lot implements Comparable<Lot> {
String name;
int height;
int width;
double area;
public LotType1(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = ((width * height) / 2);
}
#Override
public int compareTo(Lot lot) {
if (calculateArea() == lot.calculateArea()) {
return 0;
} else if (calculateArea() > lot.calculateArea()) {
return 1;
} else {
return -1;
}
}
}
class LotType2 extends Lot implements Comparable<Lot> {
String name;
int height;
int width;
double area;
public LotType2(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = ((width * height) / 2);
}
#Override
public int compareTo(Lot lot) {
if (calculateArea() == lot.calculateArea()) {
return 0;
} else if (calculateArea() > lot.calculateArea()) {
return 1;
} else {
return -1;
}
}
}
I am only able to access methods/vars of m1/m2 which are in the interface Measurable how do i access other methods and vars?
How is it possible to use the getLength() AND getBreadth()/getRadius() method of m1/m2 object in the getArea() method? Thanks in Advance!
public class Main {
public static void main(String[] args) {
Circle c = new Circle(10);
Rectangle r = new Rectangle(10,5);
addArea(c, r);
Measurable Rec = new Rectangle(10, 5);
Measurable Cir = new Circle(10);
addArea(Rec, Cir);
}
public static void addArea(Measurable m1, Measurable m2){
String m1s = null,m2s = null;
if(m1 instanceof Rectangle){
m1s="Rectangle";
}
else if(m1 instanceof Circle){
m1s="Circle";
}
if(m2 instanceof Circle){
m2s="Circle";
}
else if(m2 instanceof Rectangle){
m2s="Rectangle";
}
System.out.println("Area of "+m1s+" and "+m2s+" is "+(m1.getArea()+m2.getArea())+"\n");
}
}
interface Measurable{
double PI = 3.14;
public double getPerimeter();
public double getArea();
}
class Rectangle implements Measurable{
public double breadth, length;
public Rectangle(int breadth, int length){
this.breadth = breadth;
this.length = length;
}
#Override
public double getPerimeter() {
return 2*(breadth+length);
}
#Override
public double getArea() {
return length*breadth;
}
public double getLength(){
return length;
}
public double getBreadth(){
return breadth;
}
}
class Circle implements Measurable{
public double radius;
public Circle(int radius){
this.radius = radius;
}
#Override
public double getPerimeter() {
return 2*PI*radius;
}
#Override
public double getArea() {
return PI*radius*radius;
}
public double getRadius(){
return radius;
}
}
You should cast your objects, do that in your if blocs and assign the value to a String object. The reference of the interface can not make a call to a method written in one class that implements it.
Solution
E.g for getLength() and m1
String m1Length = null;
if(m1 instanceof Rectangle){
m1s="Rectangle";
m1Length = ((Rectangle)m1).getLength());
}
else if(m1 instanceof Circle){
m1s="Circle";
m1Length = ((Circle)m1).getLength());
}
Apply this logic to the rest of the code and you'll be fine.