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