From b3152a27fb1b7e738d6de22bd077431abfef6c36 Mon Sep 17 00:00:00 2001 From: Martin Goik <goik@hdm-stuttgart.de> Date: Wed, 3 Jun 2015 09:30:07 +0200 Subject: [PATCH] Implementing toString() for figures --- Doc/Sd1/inheritance.xml | 73 ++++++++++- P/Sd1/Figure/ToString/.gitignore | 5 + P/Sd1/Figure/ToString/pom.xml | 45 +++++++ .../de/hdm_stuttgart/mi/sd1/figure/App.java | 18 +++ .../mi/sd1/figure/model/Circle.java | 45 +++++++ .../mi/sd1/figure/model/Figure.java | 64 ++++++++++ .../mi/sd1/figure/model/Rectangle.java | 54 ++++++++ .../mi/sd1/figuretest/FigureTest.java | 119 ++++++++++++++++++ P/pom.xml | 1 + 9 files changed, 422 insertions(+), 2 deletions(-) create mode 100644 P/Sd1/Figure/ToString/.gitignore create mode 100644 P/Sd1/Figure/ToString/pom.xml create mode 100644 P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/App.java create mode 100644 P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Circle.java create mode 100644 P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Figure.java create mode 100644 P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Rectangle.java create mode 100644 P/Sd1/Figure/ToString/src/test/java/de/hdm_stuttgart/mi/sd1/figuretest/FigureTest.java diff --git a/Doc/Sd1/inheritance.xml b/Doc/Sd1/inheritance.xml index c2c1eff16..6aa8b801f 100644 --- a/Doc/Sd1/inheritance.xml +++ b/Doc/Sd1/inheritance.xml @@ -115,6 +115,8 @@ c.move(1, 5).move(-3, 7);</programlisting> half its original size. Add a corresponding scale(...) method to the Figure inheritance hierarchy which allows for operation chaining as well.</para> + + <para>Provide appropriate unit tests.</para> </question> <answer> @@ -138,8 +140,75 @@ c.move(1, 5).move(-3, 7);</programlisting> <para>This method has to be implemented in our two concrete classes <classname>Circle</classname> and - <classname>Rectangle</classname>. Provide appropriate unit - tests.</para> + <classname>Rectangle</classname>.</para> + + <para>Sensible unit tests may be based on the observation + that:</para> + + <itemizedlist> + <listitem> + <para>A figure's perimeter grows linear with the scaling + factor.</para> + </listitem> + + <listitem> + <para>A figure's area grows linear with the scaling factor's + square.</para> + </listitem> + </itemizedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1SectFigureToString"> + <title>Providing <methodname + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--">toString()</methodname> + methods</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaFigureToString"> + <qandadiv> + <qandaentry> + <question> + <para>Consider:</para> + + <programlisting language="none"> final Circle c = new Circle(-2, -1, 3.5); + final Rectangle r = new Rectangle(3, 1, 1.5, 4.4); + + System.out.println(c); + System.out.println(r);</programlisting> + + <para>This creates the following output:</para> + + <programlisting language="none">de.hdm_stuttgart.mi.sd1.figure.model.Circle@659e0bfd +de.hdm_stuttgart.mi.sd1.figure.model.Rectangle@2a139a55</programlisting> + + <para>This result is due to the invocation of the <methodname + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--">toString()</methodname> + method being defined in the <classname + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html">Object</classname> + superclass. Provide appropriate definitions in + <classname>Figure</classname>, <classname>Circle</classname> and + <classname>Rectangle</classname> to replace this output + by:</para> + + <programlisting language="none">Circle (-2.0,-1.0), radius=3.5 +Rectangle (3.0,1.0), width=1.5, height=4.4</programlisting> + + <para>Provide appropriate unit tests.</para> + + <tip> + <para>You may access + <methodname>Figure.toString()</methodname> from derived + classes by using <code>super()</code>.</para> + </tip> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/Figure/ToString</para> + </annotation> </answer> </qandaentry> </qandadiv> diff --git a/P/Sd1/Figure/ToString/.gitignore b/P/Sd1/Figure/ToString/.gitignore new file mode 100644 index 000000000..cf5fd6bb2 --- /dev/null +++ b/P/Sd1/Figure/ToString/.gitignore @@ -0,0 +1,5 @@ +/.settings +/target +/.classpath +/.project +/A1.log diff --git a/P/Sd1/Figure/ToString/pom.xml b/P/Sd1/Figure/ToString/pom.xml new file mode 100644 index 000000000..9d03cbe7f --- /dev/null +++ b/P/Sd1/Figure/ToString/pom.xml @@ -0,0 +1,45 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.hdm-stuttgart.mi</groupId> + <artifactId>lecturenotes-pom</artifactId> + <version>1.0</version> + <relativePath>../../../pom.xml</relativePath> + </parent> + + <groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>figure</artifactId> + <version>1.3</version> + <packaging>jar</packaging> + + <name>figure</name> + <url>http://www.mi.hdm-stuttgart.de/freedocs</url> + + <build> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10.1</version> + <configuration> + <linksource>true</linksource> + <taglets> + <taglet> + <tagletClass>de.hdm_stuttgart.de.sd1.taglet.HtmlExtensionTaglet</tagletClass> + <tagletArtifact> + <groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>taglet</artifactId> + <version>1.0</version> + </tagletArtifact> + </taglet> + </taglets> + </configuration> + </plugin> + + </plugins> + </build> + +</project> diff --git a/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/App.java b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/App.java new file mode 100644 index 000000000..d4dab0b97 --- /dev/null +++ b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/App.java @@ -0,0 +1,18 @@ +package de.hdm_stuttgart.mi.sd1.figure; + +import de.hdm_stuttgart.mi.sd1.figure.model.Circle; +import de.hdm_stuttgart.mi.sd1.figure.model.Rectangle; + +public class App { + + public static void main(String[] args) { + + final Circle c = new Circle(-2, -1, 3.5); + final Rectangle r = new Rectangle(3, 1, 1.5, 4.4); + + System.out.println(c); + System.out.println(r); + + } + +} diff --git a/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Circle.java b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Circle.java new file mode 100644 index 000000000..ccfd6e4df --- /dev/null +++ b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Circle.java @@ -0,0 +1,45 @@ +package de.hdm_stuttgart.mi.sd1.figure.model; + +/** + * + */ +public class Circle extends Figure { + + private double radius; + + @Override + public String toString() { + return "Circle " + super.toString() + ", radius=" + radius; + } + + /** + * Extending {@link Figure#Figure(double, double)} by adding parameter radius + * on top of center coordinates. + * + * @param x + * @param y + * @param radius + */ + public Circle(final double x, final double y, final double radius) { + super(x, y); + setRadius(radius); + } + + public double getArea() { + return radius * radius * Math.PI; + } + + public double getPerimeter() { + return 2 * Math.PI * radius; + } + + // Getter and setter methods for private attribute + public double getRadius() { return radius;} + public void setRadius(final double radius) { this.radius = radius;} + + @Override + public Figure scale(final double factor) { + radius *= factor; + return this; + } +} diff --git a/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Figure.java b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Figure.java new file mode 100644 index 000000000..d6c3ef10e --- /dev/null +++ b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Figure.java @@ -0,0 +1,64 @@ +package de.hdm_stuttgart.mi.sd1.figure.model; + +/** + * + */ +public abstract class Figure { + + private double x,y; + + + + @Override + public String toString() { + return "(" + x + ',' + y + ')'; + } + + /** + * Creating a figure with given center coordinates + * + * @param x + * @param y + */ + public Figure(final double x, final double y) { + setX(x); + setY(y); + } + + // To be implemented in derived classes Rectangle and Circle + /** + * + * @param factor Scale the current figure by this value. + * @return The current object. + */ + public abstract Figure scale(double factor); + + /** + * + * @return The current figure's area e.g. with times height in case of a rectangle + */ + public abstract double getArea(); + + /** + * @return The current figure's perimeter e.g. with 2 * (height + width) in case of a rectangle + */ + public abstract double getPerimeter(); + + public double getX() { return x;} + public void setX(final double x) { this.x = x;} + public double getY() { return y;} + public void setY(final double y) { this.y = y;} + + /** + * Translating a figure by a given vector (x,y). + * + * @param x + * @param y + * @return The current object. + */ + public final Figure move(final double x, final double y) { + setX(getX() + x); + setY(getY() + y); + return this; + } +} \ No newline at end of file diff --git a/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Rectangle.java b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Rectangle.java new file mode 100644 index 000000000..3b2ca4f19 --- /dev/null +++ b/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/figure/model/Rectangle.java @@ -0,0 +1,54 @@ +package de.hdm_stuttgart.mi.sd1.figure.model; + +public class Rectangle extends Figure { + +// Instance variables representing a rectangle's additional parameters + private double width, height; + + @Override + public String toString() { + return "Rectangle " + super.toString() + ", width=" + width + ", height=" + height; + } + + /** + * Extending {@link Figure#Figure(double, double)} by adding parameters + * width and height on top of center coordinates. + * + * @param x + * @param y + * @param width + * @param height + */ + public Rectangle(final double x, final double y, final double width, final double height) { + super(x, y); + setWidth(width); + setHeight(height); + } + + /** + * @return The rectangle's area. + */ + public double getArea() { + return width * height; + } + + /** + * @return The rectangle's perimeter. + */ + public double getPerimeter() { + return 2 * (width + height); + } + + // Getter and setter methods for private attributes + public double getWidth() { return width;} + public void setWidth(final double width) { this.width = width;} + public double getHeight() { return height;} + public void setHeight(final double height) { this.height = height;} + + @Override + public Figure scale(final double factor) { + width *= factor; + height *= factor; + return this; + } +} \ No newline at end of file diff --git a/P/Sd1/Figure/ToString/src/test/java/de/hdm_stuttgart/mi/sd1/figuretest/FigureTest.java b/P/Sd1/Figure/ToString/src/test/java/de/hdm_stuttgart/mi/sd1/figuretest/FigureTest.java new file mode 100644 index 000000000..7c2fdb71b --- /dev/null +++ b/P/Sd1/Figure/ToString/src/test/java/de/hdm_stuttgart/mi/sd1/figuretest/FigureTest.java @@ -0,0 +1,119 @@ +package de.hdm_stuttgart.mi.sd1.figuretest; + +import org.junit.Assert; +import org.junit.Test; + +import de.hdm_stuttgart.mi.sd1.figure.model.Circle; +import de.hdm_stuttgart.mi.sd1.figure.model.Rectangle; + +public class FigureTest { + static final double accuracyLimit = 1.E-15; // Rounding accuracy limit with respect to arithmetic operations + + @Test + public void circleTranslation() { + + final double + x = 3., y = 4., // circle's center coordinates (3, 4) + transX = 3., transY = -2., // translation vector (3, -2) + expectX = x + transX, expectY = y + transY; // translated circle's coordinates (6, 2) + + final Circle c = new Circle(x, y, 3.0); + c.move(transX, transY); + + Assert.assertEquals(expectX, c.getX(), accuracyLimit); + Assert.assertEquals(expectY, c.getY(), accuracyLimit); + } + + @Test + public void rectangleTranslation() { + + final double + x = 2., y = 6.5, // rectangle's center coordinates (2, 6.5) + transX = 4., transY = 1., // translation vector (3, -2) + expectX = x + transX, expectY = y + transY; // translated circle's coordinates (6, 2) + + final Rectangle r = new Rectangle(x, y, 2., 1.); + r.move(transX, transY); + Assert.assertEquals(expectX, r.getX(), accuracyLimit); + Assert.assertEquals(expectY, r.getY(), accuracyLimit); + } + + @Test + public void circlePerimeterAndArea() { + final double + radius = 1., + expectedPerimeter = 2 * Math.PI * radius, + expectedArea = Math.PI * radius * radius; + + final Circle c = new Circle(3, 4, radius); + + Assert.assertEquals(expectedPerimeter, c.getPerimeter(), accuracyLimit); + Assert.assertEquals(expectedArea, c.getArea(), accuracyLimit); + } + + @Test + public void rectanglePerimeterAndArea() { + final double + width = 2., + height = 1., + expectedPerimeter = 2 * (width + height), + expectedArea = width * height; + + final Rectangle r = new Rectangle(1, 3, width, height); + + Assert.assertEquals(expectedPerimeter, r.getPerimeter(), accuracyLimit); + Assert.assertEquals(expectedArea, r.getArea(), accuracyLimit); + } + + @Test + public void rectangleScale() { + final double + width = 2., + height = 1., + factor = 3; + + final Rectangle r = new Rectangle(1, 3, width, height); + + final double + originalPerimeter = r.getPerimeter(), + originalArea = r.getArea(), + expectedPerimeter = originalPerimeter * factor, // Perimeter is linear with respect to scale factor + expectedArea = originalArea * factor * factor; // Area is quadratic with respect to scale factor + + r.scale(factor); + + Assert.assertEquals(expectedPerimeter, r.getPerimeter(), accuracyLimit); + Assert.assertEquals(expectedArea, r.getArea(), accuracyLimit); + } + + @Test + public void circleScale() { + final double + radius = 2., + factor = 0.7; + + final Circle c = new Circle(-2, 5, radius); + + final double + originalPerimeter = c.getPerimeter(), + originalArea = c.getArea(), + expectedPerimeter = originalPerimeter * factor, // Perimeter is linear with respect to scale factor + expectedArea = originalArea * factor * factor; // Area is quadratic with respect to scale factor + + c.scale(factor); + + Assert.assertEquals(expectedPerimeter, c.getPerimeter(), accuracyLimit); + Assert.assertEquals(expectedArea, c.getArea(), accuracyLimit); + } + + @Test + public void circleToString() { + final Circle c = new Circle(-2, -1, 3.5); + Assert.assertEquals("Circle (-2.0,-1.0), radius=3.5", c.toString()); + } + @Test + public void rectangleToString() { + final Rectangle r = new Rectangle(3, 1, 1.5, 4.4); + Assert.assertEquals("Rectangle (3.0,1.0), width=1.5, height=4.4", r.toString()); + } +} diff --git a/P/pom.xml b/P/pom.xml index 6454f0ae8..ed8e2754a 100644 --- a/P/pom.xml +++ b/P/pom.xml @@ -47,6 +47,7 @@ <module>Sd1/Figure/BaseClass</module> <module>Sd1/Figure/Scale</module> + <module>Sd1/Figure/ToString</module> <module>Sd1/Gcd/V1</module> -- GitLab