diff --git a/Doc/Sd1/inheritance.xml b/Doc/Sd1/inheritance.xml index c2c1eff167c24b16b9901fdabb8ee1f2977e93bd..6aa8b801f06283ed07c647b4873a15cd2dca7b21 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 0000000000000000000000000000000000000000..cf5fd6bb26d6450c8c63fb34295192784943cf5e --- /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 0000000000000000000000000000000000000000..9d03cbe7fffe885269f489135e5cbbbf35b9bf60 --- /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 0000000000000000000000000000000000000000..d4dab0b975b4d060c1370fce33999d61589e42a4 --- /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 0000000000000000000000000000000000000000..ccfd6e4dfb5691c749db8ca57059c2d1ca279238 --- /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 0000000000000000000000000000000000000000..d6c3ef10e65f29d86d2270a65d38e5d7b21b7f1a --- /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 0000000000000000000000000000000000000000..3b2ca4f1955af24fbf2841c037b65d0822bc5d56 --- /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 0000000000000000000000000000000000000000..7c2fdb71b4e51c15581c8c462a4ef5b572c5d2b7 --- /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 6454f0ae82d9c67db58ae9dbbc22b1484a4a9953..ed8e2754a661c7193330dc752b795be57dd38a58 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>