diff --git a/bibliography.xml b/Doc/Common/bibliography.xml similarity index 100% rename from bibliography.xml rename to Doc/Common/bibliography.xml diff --git a/glossary.xml b/Doc/Common/glossary.xml similarity index 100% rename from glossary.xml rename to Doc/Common/glossary.xml diff --git a/Sd1/Ref/Fig/Makefile b/Doc/Sd1/Ref/Fig/Makefile similarity index 100% rename from Sd1/Ref/Fig/Makefile rename to Doc/Sd1/Ref/Fig/Makefile diff --git a/Sd1/Ref/Fig/account.fig b/Doc/Sd1/Ref/Fig/account.fig similarity index 100% rename from Sd1/Ref/Fig/account.fig rename to Doc/Sd1/Ref/Fig/account.fig diff --git a/Sd1/Ref/Fig/addressHtml.png b/Doc/Sd1/Ref/Fig/addressHtml.png similarity index 100% rename from Sd1/Ref/Fig/addressHtml.png rename to Doc/Sd1/Ref/Fig/addressHtml.png diff --git a/Sd1/Ref/Fig/array.fig b/Doc/Sd1/Ref/Fig/array.fig similarity index 100% rename from Sd1/Ref/Fig/array.fig rename to Doc/Sd1/Ref/Fig/array.fig diff --git a/Sd1/Ref/Fig/arrayAssoc.fig b/Doc/Sd1/Ref/Fig/arrayAssoc.fig similarity index 100% rename from Sd1/Ref/Fig/arrayAssoc.fig rename to Doc/Sd1/Ref/Fig/arrayAssoc.fig diff --git a/Sd1/Ref/Fig/directionGeometry.fig b/Doc/Sd1/Ref/Fig/directionGeometry.fig similarity index 100% rename from Sd1/Ref/Fig/directionGeometry.fig rename to Doc/Sd1/Ref/Fig/directionGeometry.fig diff --git a/Sd1/Ref/Fig/gameOfLifeWorld.png b/Doc/Sd1/Ref/Fig/gameOfLifeWorld.png similarity index 100% rename from Sd1/Ref/Fig/gameOfLifeWorld.png rename to Doc/Sd1/Ref/Fig/gameOfLifeWorld.png diff --git a/Sd1/Ref/Fig/getAverageSpeed.fig b/Doc/Sd1/Ref/Fig/getAverageSpeed.fig similarity index 100% rename from Sd1/Ref/Fig/getAverageSpeed.fig rename to Doc/Sd1/Ref/Fig/getAverageSpeed.fig diff --git a/Sd1/Ref/Fig/person.fig b/Doc/Sd1/Ref/Fig/person.fig similarity index 100% rename from Sd1/Ref/Fig/person.fig rename to Doc/Sd1/Ref/Fig/person.fig diff --git a/Sd1/Ref/Fig/pre.tex b/Doc/Sd1/Ref/Fig/pre.tex similarity index 100% rename from Sd1/Ref/Fig/pre.tex rename to Doc/Sd1/Ref/Fig/pre.tex diff --git a/Sd1/Ref/Fig/returnTypeInt.dia b/Doc/Sd1/Ref/Fig/returnTypeInt.dia similarity index 100% rename from Sd1/Ref/Fig/returnTypeInt.dia rename to Doc/Sd1/Ref/Fig/returnTypeInt.dia diff --git a/Sd1/Ref/Fig/returnValue.fig b/Doc/Sd1/Ref/Fig/returnValue.fig similarity index 100% rename from Sd1/Ref/Fig/returnValue.fig rename to Doc/Sd1/Ref/Fig/returnValue.fig diff --git a/Sd1/Ref/Fig/runconfigDefineArgs.png b/Doc/Sd1/Ref/Fig/runconfigDefineArgs.png similarity index 100% rename from Sd1/Ref/Fig/runconfigDefineArgs.png rename to Doc/Sd1/Ref/Fig/runconfigDefineArgs.png diff --git a/Sd1/Ref/Fig/runconfigMavenGoalPackage.png b/Doc/Sd1/Ref/Fig/runconfigMavenGoalPackage.png similarity index 100% rename from Sd1/Ref/Fig/runconfigMavenGoalPackage.png rename to Doc/Sd1/Ref/Fig/runconfigMavenGoalPackage.png diff --git a/Sd1/Ref/Fig/runconfigSelectClass.png b/Doc/Sd1/Ref/Fig/runconfigSelectClass.png similarity index 100% rename from Sd1/Ref/Fig/runconfigSelectClass.png rename to Doc/Sd1/Ref/Fig/runconfigSelectClass.png diff --git a/Sd1/Ref/Fig/setDirection.fig b/Doc/Sd1/Ref/Fig/setDirection.fig similarity index 100% rename from Sd1/Ref/Fig/setDirection.fig rename to Doc/Sd1/Ref/Fig/setDirection.fig diff --git a/Sd1/Ref/Fig/stayclear.png b/Doc/Sd1/Ref/Fig/stayclear.png similarity index 100% rename from Sd1/Ref/Fig/stayclear.png rename to Doc/Sd1/Ref/Fig/stayclear.png diff --git a/Sd1/Ref/Fig/svgGeometry.png b/Doc/Sd1/Ref/Fig/svgGeometry.png similarity index 100% rename from Sd1/Ref/Fig/svgGeometry.png rename to Doc/Sd1/Ref/Fig/svgGeometry.png diff --git a/Sd1/Ref/Fig/townsByCountry.fig b/Doc/Sd1/Ref/Fig/townsByCountry.fig similarity index 100% rename from Sd1/Ref/Fig/townsByCountry.fig rename to Doc/Sd1/Ref/Fig/townsByCountry.fig diff --git a/Sd1/Ref/Fig/turnLeft.fig b/Doc/Sd1/Ref/Fig/turnLeft.fig similarity index 100% rename from Sd1/Ref/Fig/turnLeft.fig rename to Doc/Sd1/Ref/Fig/turnLeft.fig diff --git a/Sd1/Ref/Fig/turningStates.fig b/Doc/Sd1/Ref/Fig/turningStates.fig similarity index 100% rename from Sd1/Ref/Fig/turningStates.fig rename to Doc/Sd1/Ref/Fig/turningStates.fig diff --git a/Sd1/Ref/Fig/wombatDirection.png b/Doc/Sd1/Ref/Fig/wombatDirection.png similarity index 100% rename from Sd1/Ref/Fig/wombatDirection.png rename to Doc/Sd1/Ref/Fig/wombatDirection.png diff --git a/Sd1/Ref/Screen/EclipseConfig/windowsCmdJdkJre.png b/Doc/Sd1/Ref/Screen/EclipseConfig/windowsCmdJdkJre.png similarity index 100% rename from Sd1/Ref/Screen/EclipseConfig/windowsCmdJdkJre.png rename to Doc/Sd1/Ref/Screen/EclipseConfig/windowsCmdJdkJre.png diff --git a/Sd1/Ref/Screen/sinPlot.png b/Doc/Sd1/Ref/Screen/sinPlot.png similarity index 100% rename from Sd1/Ref/Screen/sinPlot.png rename to Doc/Sd1/Ref/Screen/sinPlot.png diff --git a/Sd1/Ref/Svg/exception.svg b/Doc/Sd1/Ref/Svg/exception.svg similarity index 100% rename from Sd1/Ref/Svg/exception.svg rename to Doc/Sd1/Ref/Svg/exception.svg diff --git a/Sd1/Ref/Svg/hashing.svg b/Doc/Sd1/Ref/Svg/hashing.svg similarity index 100% rename from Sd1/Ref/Svg/hashing.svg rename to Doc/Sd1/Ref/Svg/hashing.svg diff --git a/Sd1/Ref/Svg/mavenPrjRef.svg b/Doc/Sd1/Ref/Svg/mavenPrjRef.svg similarity index 100% rename from Sd1/Ref/Svg/mavenPrjRef.svg rename to Doc/Sd1/Ref/Svg/mavenPrjRef.svg diff --git a/Doc/Sd1/array.xml b/Doc/Sd1/array.xml new file mode 100644 index 0000000000000000000000000000000000000000..bd449a74e9718a44c42ee9db95fb6f73e430d508 --- /dev/null +++ b/Doc/Sd1/array.xml @@ -0,0 +1,1477 @@ + <chapter xml:id="sd1ArrayI" version="5.0" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Arrays </title> + + <section xml:id="sd1ArrayPrepare"> + <title>Preparations</title> + + <para>Chapter 4 <xref linkend="bib_Horton2011"/> excluding + <quote>Mutable Strings</quote>.</para> + </section> + + <section xml:id="sd1ArrayiExercise"> + <title>Exercises</title> + + <section xml:id="sd1IntStore"> + <title>Storing integer values</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaIntStore"> + <title>A container of fixed capacity holding integer values</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement a class + <classname>BoundedIntegerStore</classname> being able to hold + a fixed number of integer values. Internally these values will + be stored in an array. The design has been chosen to be + extended in later exercises.</para> + + <para>A skeleton project archive is available at:</para> + + <annotation role="make"> + <para role="eclipse">P/Array/integerStoreSkeleton</para> + </annotation> + + <para>The above link contains a skeleton file + <filename>project.zip</filename>. You may import this project + into your <xref linkend="glo_Eclipse"/> workspace by:</para> + + <itemizedlist> + <listitem> + <para>Creating an empty directory e.g. + <quote>myProject</quote>.</para> + </listitem> + + <listitem> + <para>Unzip <filename>project.zip</filename> into + <quote>myProject</quote>.</para> + </listitem> + + <listitem> + <para>Choose File-->Import-->Maven-->Existing + maven projects in <xref linkend="glo_Eclipse"/> and + navigate to the <quote>myProject</quote> folder to import + it.</para> + </listitem> + </itemizedlist> + + <para>This skeleton project contains:</para> + + <itemizedlist> + <listitem> + <para>A class <classname>Driver</classname> which allows + you to execute some output generating tests.</para> + </listitem> + + <listitem> + <para>A <xref linkend="glo_Junit"/> test + <classname>IntStoreTest</classname> which allows you to + test your ongoing implementation of + <classname>BoundedIntegerStore</classname>. This class + contains several <code>// TODO</code> comments indicating + positions to be completed.</para> + </listitem> + + <listitem> + <para>The tests will fail initially. After successful + implementation they should however run + successfully.</para> + </listitem> + </itemizedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Array/integerStore</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1IntStoreUnbounded"> + <title>Let the store grow dynamically</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaIntStoreUnbounded"> + <title>A container of variable capacity holding integer + values</title> + + <qandadiv> + <qandaentry> + <question> + <para>In <xref linkend="sd1QandaIntStore"/> once a store has + been created its capacity is fixed. We'd like to extend our + class to support dynamic growth while adding new values. To + achieve this goal follow the following steps:</para> + + <orderedlist> + <listitem> + <para>Copy the completed project to a new one e.g. named + <quote>UnboundedContainer</quote>. This way you still have + the bounded implementation available.</para> + </listitem> + + <listitem> + <para>Rename your class + <classname>BoundedIntegerStore</classname> to + <classname>IntegerStore</classname> reflecting the + possibility of dynamic growth.</para> + </listitem> + + <listitem> + <para>You have to modify the method <code>void + addValue(int value)</code>: If the array's size gets + exceeded (e.g. adding the fifth value having array size of + just 4) do:</para> + + <itemizedlist> + <listitem> + <para>Create a second array offering twice the current + capacity. This technique is referred to as + <quote>amortized doubling</quote>.</para> + </listitem> + + <listitem> + <para>Copy all existing values from the current array + to the new array</para> + </listitem> + + <listitem> + <para>Assign the new array to <code>int[] + values</code>. You thereby implicitly discard the old + array.</para> + </listitem> + + <listitem> + <para>copy the latest argument to the array as + usual.</para> + </listitem> + </itemizedlist> + + <para>Basically you have to compare the number of already + inserted elements and the current capacity prior to + inserting any new value.</para> + </listitem> + + <listitem> + <para>Add a default constructor providing an initial + default capacity of 4.</para> + </listitem> + </orderedlist> + + <para>Modify and add <xref linkend="glo_Junit"/> tests + accordingly to reflect the new behaviour. Especially test + correct capacity reallocation for larger numbers of values + being added.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Array/integerStoreUnbounded</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1StoreStatistics"> + <title>Providing statistical data</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaIntStoreStat"> + <title>Adding support to retrieve statistical data.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Extend <xref linkend="sd1QandaIntStoreUnbounded"/> by + providing a method <methodname>double + getAverage()</methodname> to provide statistical data on a + given set of integer values. In addition provide a method + <methodname>void clear()</methodname> enabling a user to + support different sets of values.</para> + + <para>Do not forget to extend your <xref linkend="glo_Junit"/> + tests. You may want to import an <link + xlink:href="Ref/api/P/Array/integerStoreStat/eclipse.zip">eclipse + skeleton project</link> to start from.</para> + + <caution> + <para>When testing for equality of double values you may + find the <xref linkend="glo_Junit"/> method <methodname + xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(double,%20double)">assertEquals()</methodname>to + be marked as <link + xlink:href="http://docs.oracle.com/javase/1.5.0/docs/guide/javadoc/deprecation/deprecation.html">deprecated</link>. + Give a reason why this decision has been taken. This may + guide you to find an appropriate test.</para> + </caution> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Array/integerStoreStat</para> + </annotation> + + <para>Testing for equality of two <code>double</code> + variables is generally a bad idea. Consider the double literal + <code>1.25</code> and the expression <code>5. / 4</code>. A + test <code>assertEquals(1.25, 5. / 4)</code> is likely to fail + due to arithmetic representation problems. Thus you have to + use a distance measurement like e.g. + <code>assertTrue(Math.abs(1.25 - 5. / 4) < 1E-50)</code> + instead.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + <section xml:id="sd1ArrayIIprepare"> + <title>Arrays II, Preparations</title> + + <glosslist> + <glossentry> + <glossterm>Java Annotations</glossterm> + + <glossdef> + <para>Unfortunately <xref linkend="bib_Horton2011"/> is somewhat + reluctant regarding Java annotations:</para> + + <remark>A Java source file can contain annotations. An annotation + is not a Java language statement, but a special statement that + changes the way program statements are treated by the compiler or + the libraries. You can define your own annotations but most Java + programmers never need to do so, so I’m not going into the + how.</remark> + + <para>With respect to unit testing using (not defining!) + annotations is very helpful.</para> + + <para>Get a basic understanding of Java annotations by reading + <link + xlink:href="http://docs.oracle.com/javase/tutorial/java/annotations">Lesson: + Annotations</link>. Don't worry if you do not understand the + complete article. The primary intention is about understanding the + <code>@Test</code> annotation in <xref linkend="glo_Junit"/>, see + next topic.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Unit testing using <xref + linkend="glo_Junit"/></glossterm> + + <glossdef> + <para>Read <link + xlink:href="http://www.vogella.com/tutorials/JUnit/article.html">the + introduction</link>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Inheritance</glossterm> + + <glossdef> + <para>Chapter 6 <xref linkend="bib_Horton2011"/> until (including) + <quote>Using the final modifier</quote>. You may skip + <quote>Methods accepting a variable number of + arguments</quote>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><productname>Greenfoot</productname> and + loops</glossterm> + + <glossdef> + <para>Read chapter 5 of <xref + linkend="bib_Koelling2010Ger"/>.</para> + </glossdef> + </glossentry> + </glosslist> + </section> + + <section xml:id="sd1Array2Exercise"> + <title>Exercises</title> + + <section xml:id="sd1PrimeRevisit"> + <title>Prime numbers revisited</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaPrimTest"> + <title>Testing an implementation</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following method aimed to test whether a + given <code>long</code> number is prime or not:</para> + + <programlisting language="java"> /** + * Test, whether a given number is prime. + * @param candidate The number to be assessed + * @return true if candidate is prime, false otherwise + * <dl> + <dt>Precondition:</dt> + <dd>2 &lt;= candidate</dd> + </dl> + */ + public static boolean isPrime(final long candidate) { + for (long i = 2; i * i < candidate; i++) { // Just test up to square + if (0 == candidate % i) { // root of candidate. + return false; + } + } + return true; + } +}</programlisting> + + <orderedlist> + <listitem> + <para>Write a <emphasis role="bold">concise</emphasis> + test which tests the above method for all numbers from [2, + 100]. You need to know all prime numbers from this set in + order to implement a <emphasis + role="bold">complete</emphasis> test for both directions + <quote>is prime</quote> and <quote>is not + prime</quote>.</para> + </listitem> + + <listitem> + <para>In case you find errors correct them.</para> + </listitem> + + <listitem> + <para>Write a method which tests prime number candidates + up to an arbitrary limit (say limit == 10000) and returns + the number of primes within [2, limit]. Measure this + method's execution time. You may want to consult + <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#currentTimeMillis--">System.currentTimeMillis()</methodname> + or <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime--">System.nanoTime()</methodname> + for that purpose.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Prime/V1</para> + </annotation> + + <orderedlist> + <listitem> + <para>We want to test whether our <methodname>boolean + isPrime(final long candidate)</methodname> method + classifies prime numbers as such and whether this message + is able to tell non-primes as well. We achieve this by + defining a boolean array having indexes ranging from 0 to + 100. We then:</para> + + <itemizedlist> + <listitem> + <para>Set all array values to false</para> + </listitem> + + <listitem> + <para>Set all array values to true if their index is a + prime number. This of course requires to know all + prime numbers below 100.</para> + </listitem> + </itemizedlist> + + <para>This array then allows us to test our method for + correctness for values up to 100:</para> + + <programlisting language="java">public class TestPrimes { + + @Test + public void primeTest() { + final int[] primeNumbers = { 2, 3, 5, 7, 11, 13, 17, 19, 23, + 31, 37, 41, 43, 47, 53, 59, 29, + 61, 67, 71, 73, 79, 83, 89, 97}; + + final boolean[] isPrime = new boolean[101]; //Testing 2,3,..,98,99,100 + for (int i = 2; i <= 100; i++) { + isPrime[i] = false; + } + for (final int prime: primeNumbers) { + isPrime[prime] = true; + } + for (int i = 2; i <= 100; i++) { + assertEquals("Index=" + i , isPrime[i], PrimeNumbers.isPrime(i)); + } + }</programlisting> + </listitem> + + <listitem> + <para>Executing this test yields an error at index 49. + This is due to an implementation error. The for- loop had + been defined as:</para> + + <programlisting language="java"> public static boolean isPrime(final long candidate) { + for (long i = 2; i * i < candidate; i++) { + ...</programlisting> + + <para>This is wrong: Having <code>candidate == 49</code> + the last value of i to be considered will be 6. So the + test for the result of <code>49 % 7</code> will never be + executed thus returning true. We actually have to modify + the loop's limit slightly different:</para> + + <programlisting language="java"> public static boolean isPrime(final long candidate) { + for (long i = 2; i * i <emphasis role="bold"><=</emphasis> candidate; i++) { + ...</programlisting> + + <para>This way <code>49 % 7</code> will be evaluated to + zero thus returning <code>false</code> and thereby + categorizing 49 as a non-prime number.</para> + </listitem> + + <listitem> + <para>Our <methodname + xlink:href="Ref/api/P/Prime/V1/de/hdm_stuttgart/mi/sd1/main/PrimeNumbers.html#main-java.lang.String:A-">main()</methodname> + method allows to estimate the prime number computing + performance:</para> + + <programlisting language="none">prime numbers found:664579 +Elapsed time:14997</programlisting> + </listitem> + </orderedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1PrimePerformance"> + <title>Improving performance</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaPrimeFactor"> + <title>Getting better calculating prime numbers</title> + + <qandadiv> + <qandaentry> + <question> + <para>Our current algorithm checking for prime numbers wastes + a lot computing power. Consider testing candidate value 143. + Currently our loop will test:</para> + + <programlisting language="none">143 % 2 == 0 ? No. +143 % 3 == 0 ? No. +143 % 4 == 0 ? No. +143 % 5 == 0 ? No. +143 % 6 == 0 ? No. +143 % 7 == 0 ? No. +143 % 8 == 0 ? No. +143 % 9 == 0 ? No. +143 % 10 == 0 ? No. +143 % 11 == 0 ? Yes ==> 143 is not prime</programlisting> + + <para>Learning from <link + xlink:href="http://en.wikipedia.org/wiki/Prime_factor">prime + factorization</link> it actually suffices just to test all + primes up to the already discussed square root limit:</para> + + <programlisting language="none">143 % 2 == 0 ? No. +143 % 3 == 0 ? No. +143 % 5 == 0 ? No. +143 % 7 == 0 ? No. +143 % 11 == 0 ? Yes ==> 143 is not prime</programlisting> + + <para>The tradeoff is even bigger for higher prime numbers. + Thus if we store all computed prime numbers without gaps they + will save us a lot of operations. You may want to reuse your + unsorted <classname + xlink:href="Ref/api/P/Array/integerStoreUnbounded/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html">IntegerStore</classname> + implementation. Implement the above algorithm and compare the + elapsed execution time.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Prime/V2</para> + </annotation> + + <para>This time we only need ~18% of the previous time:</para> + + <programlisting language="none">prime numbers found:664578 +Elapsed time:2639</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1ConsoleInput"> + <title>Java console input</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaConsoleInput"> + <title>Reading console input</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following code example computing the sum of + an arbitrary number of integer values:</para> + + <programlisting language="java">import java.util.Scanner; + +public class Driver { + public static void main(String[] args) { + + final Scanner scanner = new Scanner(System.in); + + System.out.print("How many values do you want to summ up? "); + final int numValues = scanner.nextInt(); + + int sum = 0; + for (int i = 0; i < numValues; i++) { + System.out.print("Enter value #" + (i + 1) + " of " + numValues + ": "); + sum += scanner.nextInt(); + } + System.out.println("Sum=" + sum); + scanner.close(); + } +}</programlisting> + + <para>This program:</para> + + <orderedlist> + <listitem> + <para>Asks a user how many integer numbers shall be + processed. A user may enter e.g. 4 indicating his wish to + subsequently enter 4 numbers.</para> + </listitem> + + <listitem> + <para>Actually read e.g. 4 input numbers and calculate + their sum.</para> + </listitem> + </orderedlist> + + <para>The result might look like:</para> + + <programlisting language="none">How many values do you want to summ up? 4 +Enter value #1 of 4: 11 +Enter value #2 of 4: 22 +Enter value #3 of 4: -33 +Enter value #4 of 4: 1 +Sum=1</programlisting> + + <para>Modify this program to output not just the desired sum + but the complete input like in the following + representation:</para> + + <programlisting language="none">How many values do you want to summ up? 4 +Enter value #1 of 4: 1 +Enter value #2 of 4: 2 +Enter value #3 of 4: 3 +Enter value #4 of 4: -5 +<emphasis role="bold">1+2+3-5 = 1</emphasis></programlisting> + + <para>Hints:</para> + + <orderedlist> + <listitem> + <para>Use an integer array to store the user's input + values</para> + </listitem> + + <listitem> + <para>Mind the input values' signs: While positive or zero + values are not being represented with a leading + <quote>+</quote> sign negative values do have a preceding + <quote>-</quote> sign. With respect to the above example + you should avoid output representations like + <quote>1+2+3+-5</quote> for negative input values.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <programlisting language="java">import java.util.Scanner; + +public class Driver { + public static void main(String[] args) { + + final Scanner scanner = new Scanner(System.in); + + System.out.print("How many values do you want to summ up? "); + final int numValues = scanner.nextInt(); + + // Allocate an array to store the desired number of integer values + final int[] inputValues = new int[numValues]; + int sum = 0; + for (int i = 0; i < numValues; i++) { + System.out.print("Enter value #" + (i + 1) + " of " + numValues + ": "); + inputValues[i] = scanner.nextInt(); + sum += inputValues[i]; + } + // Write user input to console output + for (int i = 0; i < numValues - 1; i++) {// Omit the last element + System.out.print(inputValues[i]); + if (0 <= inputValues[i + 1]) { // Add a '+' sign if the subsequent number is positive or zero + System.out.print("+"); + } + } + // Write the last element to console output + System.out.println(inputValues[numValues - 1] + " = " + sum); + + scanner.close(); + } +}</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + + + <section xml:id="sd1ArrayIIIExercises"> + <title>Arrays III, Exercises</title> + + <section xml:id="sd1Median"> + <title>The median of a given sample.</title> + + <para>Read the <link + xlink:href="http://en.wikipedia.org/wiki/Median">definition of a given + sample's median</link>.</para> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMedian"> + <title>Calculating the median</title> + + <qandadiv> + <qandaentry> + <question> + <para>We want to extend exercise <xref + linkend="sd1QandaIntStoreStat"/> by adding a method + <methodname>int getMedian()</methodname>. For this purpose our + current implementation lacks ordering of input values. + Consider the following sample of values:</para> + + <programlisting language="none">2, 7, 0, -3, 4</programlisting> + + <para>Obtaining the median requires ordering these + values:</para> + + <programlisting language="none">-3, 0, 2, 4, 7</programlisting> + + <para>Thus the given sample's median is 2. Solve this exercise + in the following order:</para> + + <orderedlist> + <listitem> + <para>For testing and other purposes it is convenient to + provide an additional method returning the array of values + being added so far:</para> + + <programlisting language="java"> /** + * @return The array of values entered so far + */ + public int[] getValues() { + ... + return ...; + }</programlisting> + + <caution> + <para>Do not just return your internal array <code>int[] + values</code>! Due to the amortized doubling + implementation this will in most cases contain unused + positions on top of added values.</para> + + <para>You may either construct a suitable copy + containing the current elements yourself or get + enlightened by reading the <xref linkend="glo_API"/> + documentation of <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#copyOfRange-int:A-int-int-">copyOfRange(...)</link>.</para> + </caution> + </listitem> + + <listitem> + <para>Provide some tests to assure your sorting + implementation works well. You'll implement the actual + sorting in the next step. Right now testing for correct + sorting will fail (unless a given set of values had + already been added in ascending order). A test might look + like:</para> + + <programlisting language="java">final int[] + unsortedValues = {0, -1, 5, 2, 7, 6}, + sortedValues = {-1, 0, 2, 5, 6, 7}; + +IntegerStore store = new IntegerStore(); + +for (final int i: unsortedValues) { + store.addValue(i); +} + +// Now check your store for correctly sorted order of elements +...</programlisting> + + <para>Do not forget to consider value sets which include + duplicates and write tests accordingly!</para> + + <para>Hint: The <xref linkend="glo_Junit"/> <xref + linkend="glo_framework"/> provides a (convenience) method + <methodname + xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertArrayEquals(int[],%20int[])">assertArrayEquals(...)</methodname>.</para> + </listitem> + + <listitem> + <para>Modify your<methodname + xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-"> + addValue(...)</methodname> method's implementation. Though + there are more elaborate sorting methods available in Java + we'll do it the hard way ourselves in this exercise. + Consider the following example:</para> + + <programlisting language="java">store.addValue(1); +store.addValue(2); +store.addValue(7); +store.addValue(9); +store.addValue(3);</programlisting> + + <para>Prior to inserting a new value our <methodname + xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-">addValue(...)</methodname> + method shall find a suitable position inside the array of + already added values to insert the new value. When adding + the last value 3 in the above example the internal array + already contains the values (1, 2, 7, 9). Traversing this + array shows that the new value of 3 should be inserted + between 2 and 7.</para> + + <para>Thus a general strategy inserting a new value + candidate might be:</para> + + <orderedlist> + <listitem> + <para>Find the first index pointing to an existing + value being larger or equal to the given candidate. In + the above example this index value is 2 pointing to + value 7.</para> + + <para>If there is no such existing value just add the + new value at the array's top end like you did before + when not yet bothering about sorting.</para> + </listitem> + + <listitem> + <para>Shift the <quote>right</quote> part of the array + starting at index 2 in our example one position to the + right thus creating a free (denoted by + <quote>F</quote>) insert position:</para> + + <programlisting language="none">Index values | 0| 1| 2| 3| 4| 5| ... +-----------------+--+--+--+--+-----+ ... +values oldArray | 1| 2| 7| 9| | | +-----------------+--+--+--+--+-----+ ... +values newArray | 1| 2| F| 7| 9| | ...</programlisting> + + <para>You may now insert your latest value 3 at the + free index position 2 ending up with a well sorted + array (1, 2, 3, 7, 9).</para> + + <para>This example just illustrates a (very simple!) + sorting algorithm.</para> + + <para>Hint: On implementation be very careful with + respect to <quote>off by one</quote> errors you are + likely to encounter. The tests you have written + beforehand will guide you.</para> + </listitem> + </orderedlist> + </listitem> + + <listitem> + <para>Provide a constructor <code>public + IntegerStore(final int[] values)</code> in a meaningful + way with respect to median calculations.</para> + </listitem> + + <listitem> + <para>Add a dummy implementation <methodname>double + getMedian()</methodname>{return 0;} to your class + <classname>IntegerStore</classname> from exercise <xref + linkend="sd1QandaIntStoreStat"/>.</para> + </listitem> + + <listitem> + <para>Provide some tests both for even and uneven sample + sizes. All of these will probably fail till you complete + your implementation.</para> + </listitem> + + <listitem> + <para>Finally complete the desired <code>double + getMedian()</code> method's implementation and actually + test it. There must be at least one element in order to be + able returning a meaningful result:</para> + + <programlisting language="java"> /** + *<dl> + <dt><b>Precondition:</b></dt> + <dd>There must be at least one element.</dd> + </dl> + * + * @return The sample's median. + */ + public double getMedian() { + ... + return ... ; + }</programlisting> + </listitem> + + <listitem> + <para>With respect to <xref linkend="sd1ConsoleInput"/> + write a main method asking the user for an arbitrary + number of values. Then compute both their average and + median like:</para> + + <programlisting language="none">How big is your sample? 5 + +Enter value #1 of 5: 1 +Enter value #2 of 5: -2 +Enter value #3 of 5: 1 +Enter value #4 of 5: 5 +Enter value #5 of 5: 2 + +Your sample's average is: 1.4 +Your sample's median is: 1.0</programlisting> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Array/integerStoreMedianAnswer</para> + </annotation> + + <orderedlist> + <listitem> + <para>The <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#copyOfRange-int:A-int-int-">copyOfRange(...)</link> + method in <methodname + xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#getValues--">getValues()</methodname> + returns that portion of our <code>int[] values</code> + array which had actually been filled with data.</para> + </listitem> + + <listitem> + <para>Provide some tests to assure your sorting + implementation works well. You'll implement the actual + sorting in the next step. Right now testing for correct + sorting will fail (unless a given set of values had + already been added in ascending order). A test might look + like:</para> + + <programlisting language="java">final int[] + unsortedValues = {0, -1, 5, 2, 7, 6}, + sortedValues = {-1, 0, 2, 5, 6, 7}; + +IntegerStore store = new IntegerStore(); + +for (final int i: unsortedValues) { + store.addValue(i); +} + +// Now check your store for correctly sorted order of elements +...</programlisting> + + <para>Do not forget to consider value sets which include + duplicates and write tests accordingly!</para> + + <para>Hint: The <xref linkend="glo_Junit"/> <xref + linkend="glo_framework"/> provides a (convenient) method + <methodname + xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertArrayEquals(int[],%20int[])">assertArrayEquals(...)</methodname>.</para> + </listitem> + + <listitem> + <para>Modify your<methodname + xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-"> + addValue(...)</methodname> method's implementation. Though + there are more elaborate sorting methods available in Java + we'll do it the hard way ourselves in this exercise. + Consider the following example:</para> + + <programlisting language="java">store.addValue(1); +store.addValue(2); +store.addValue(7); +store.addValue(9); +store.addValue(3);</programlisting> + + <para>Prior to inserting a new value our <methodname + xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-">addValue(...)</methodname> + method shall find a suitable position inside the array of + already added values to insert the new value. When adding + the last value 3 in the above example the internal array + already contains the values (1, 2, 7, 9). Traversing this + array shows that the new value of 3 should be inserted + between 2 and 7.</para> + + <para>Thus a general strategy inserting a new value + candidate might be:</para> + + <orderedlist> + <listitem> + <para>Find the first index pointing to an existing + value being larger or equal to the given candidate. In + the above example this index value is 2 pointing to + value 7.</para> + + <para>If there is no such existing value just add the + new value at the array's top as you did without + bothering about sorting.</para> + </listitem> + + <listitem> + <para>Shift the <quote>right</quote> part of the array + starting at index 2 in our example one position to the + right thus creating a free (denoted by + <quote>F</quote>) insert position:</para> + + <programlisting language="none">Index values | 0| 1| 2| 3| 4| 5| ... +-----------------+--+--+--+--+-----+ ... +values oldArray | 1| 2| 7| 9| | | +-----------------+--+--+--+--+-----+ ... +values newArray | 1| 2| F| 7| 9| | ...</programlisting> + + <para>You may now insert your latest value 3 at the + free index position 2 ending up with a well sorted + array (1, 2, 3, 7, 9).</para> + + <para>This example just illustrates a (very simple!) + sorting algorithm.</para> + + <para>Hint: On implementation be very careful with + respect to <quote>off by one</quote> errors you are + likely to encounter. The tests you have written + beforehand will guide you.</para> + </listitem> + </orderedlist> + </listitem> + + <listitem> + <para>The constructor <methodname + xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#IntegerStore-int:A-">public + IntegerStore(final int[] values)</methodname> internally + uses our <methodname + xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-">addValue(...)</methodname> + method thus adding each array value one by one. Consider + an alternative naive implementation:</para> + + <programlisting language="java"> public IntegerStore(final int[] values) { + this.values = values; + } </programlisting> + + <para>This will fail in most cases since the array + parameter typically contains unsorted values.</para> + + <para>Having this constructor in place also simplifies + writing tests:</para> + + <programlisting language="java">... + @Test + public void testMedian() { + IntegerStore store = new IntegerStore(new int[] {2, 7, 0, -3, 4}); + assertArrayEquals(new int[] {-3, 0, 2, 4, 7}, store.getValues()); + assertTrue(Math.abs(2. - store.getMedian()) < 1.E-10); +...</programlisting> + </listitem> + + <listitem> + <para>-</para> + </listitem> + + <listitem> + <programlisting language="java"> @Test + public void testMedian() { + IntegerStore store = new IntegerStore(new int[] {2, 7, 0, -3, 4}); + assertArrayEquals(new int[] {-3, 0, 2, 4, 7}, store.getValues()); + assertTrue(Math.abs(2. - store.getMedian()) < 1.E-10); + + store.addValue(7); + assertArrayEquals(new int[] {-3, 0, 2, 4, 7, 7}, store.getValues()); + assertTrue(Math.abs(3. - store.getMedian()) < 1.E-10); + + store.addValue(7); + assertArrayEquals(new int[] {-3, 0, 2, 4, 7, 7, 7}, store.getValues()); + assertTrue(Math.abs(4. - store.getMedian()) < 1.E-50); + + store.addValue(6); + assertArrayEquals(new int[] {-3, 0, 2, 4, 6, 7, 7, 7}, store.getValues()); + assertTrue(Math.abs(5. - store.getMedian()) < 1.E-50); + }</programlisting> + </listitem> + + <listitem> + <para><methodname + xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#getMedian--">double + getMedian()</methodname></para> + </listitem> + + <listitem> + <para><methodname + xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/main/Driver.html#main-java.lang.String:A-">main(...)</methodname></para> + </listitem> + </orderedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="plottingFunctions"> + <title>Plotting functions</title> + + <qandaset defaultlabel="qanda" xml:id="qandaPlottingFunctions"> + <title>A simple character based plotting application</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement a class to plot e.g. sin(x) in a terminal like + e.g.:</para> + + <informalfigure> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Screen/sinPlot.png"/> + </imageobject> + </mediaobject> + </informalfigure> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/plot</para> + </annotation> + + <para>The above solution contains a variant using Java 8 + Lambda expressions which allow to supply functions as + arguments to the plotting facility. This second solution will + not be covered in the current lecture but you may catch a + glimpse of upcoming topics in "Softwareentwicklung 2".</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + + + <section xml:id="sd1PrepStrings"> + <title>String instances (1.12.)</title> + + <itemizedlist> + <listitem> + <para>Read the section on <link + xlink:href="http://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html">command + line arguments</link> and execute the given examples.</para> + </listitem> + + <listitem> + <para>Read the <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String + <xref linkend="glo_API"/></link>. Try to understand methods + concerning:</para> + + <itemizedlist> + <listitem> + <para>Comparing strings lexicographically or testing for + equality? How does this relate to the <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> + method you read about in chapter 6 of <xref + linkend="bib_Horton2011"/>.</para> + </listitem> + + <listitem> + <para>Searching for sub strings in a given string i.e. testing, + whether e.g. <quote>keeper</quote> is part of + <quote>goalkeeper</quote>.</para> + </listitem> + </itemizedlist> + </listitem> + </itemizedlist> + </section> + + <section xml:id="sd1StringExercise"> + <title>Exercises</title> + + <section xml:id="greenfootConfigureEclipse"> + <title>Developing <xref linkend="glo_Greenfoot"/> applications using + the <xref linkend="glo_Eclipse"/> <xref linkend="glo_IDE"/>.</title> + + <para>Steps being described in this section are optional and only + required if you like to develop <xref linkend="glo_Greenfoot"/> + applications using <xref linkend="glo_Eclipse"/>.</para> + + <para>When using the <xref linkend="glo_Greenfoot"/> <xref + linkend="glo_IDE"/> your <xref linkend="glo_Java"/> code uses services + from the underlying <productname>Greenfoot</productname> <xref + linkend="glo_framework"/> which in turn uses another framework called + <xref linkend="glo_BlueJ"/>. If you want to use <xref + linkend="glo_Eclipse"/> for <xref linkend="glo_Greenfoot"/> + development based on <xref linkend="glo_Maven"/> you have to define + <xref linkend="glo_Greenfoot"/> within the project's <xref + linkend="glo_pom.xml"/> file's dependency section. You must provide + both dependencies (at least locally on your workstation):</para> + + <glosslist> + <glossentry> + <glossterm>Locally install <xref linkend="glo_BlueJ"/> + dependencies</glossterm> + + <glossdef> + <para>Download <uri + xlink:href="http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/bluej/eclipse.zip">http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/bluej/eclipse.zip</uri> + and unzip it to a subfolder <filename>Bluej</filename>. Import + this Folder as a Maven project into <xref + linkend="glo_Eclipse"/> and right click on pom.xml choosing + <guisubmenu>mvn install</guisubmenu>. This will compile the + sources and install <xref linkend="glo_BlueJ"/> into your local + <xref linkend="glo_Maven"/> repository below + <filename>yourHomeDirPath/.m2</filename>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Locally install <xref linkend="glo_Greenfoot"/> + dependencies</glossterm> + + <glossdef> + <para>Repeat the previous step for <uri + xlink:href="http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/greenfoot/eclipse.zip">http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/greenfoot/eclipse.zip</uri> + using a subfolder <filename>Greenfoot</filename>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Adding <xref linkend="glo_Maven"/> dependency to your + <productname>Greenfoot</productname> game project</glossterm> + + <glossdef> + <para>You may now create your own <xref + linkend="glo_Greenfoot"/> Maven <xref linkend="glo_Eclipse"/> + project by adding the newly created <xref + linkend="glo_Greenfoot"/> Maven artifact as a project + dependency:</para> + + <programlisting language="none">... + <dependencies> + ... + <emphasis role="bold"><dependency> + <groupId>de.hdm-stuttgart.mi</groupId> + <artifactId>greenfoot</artifactId> + <version>2.3.0</version> + </dependency></emphasis> + </dependencies>...</programlisting> + + <para>Due to <xref linkend="glo_Greenfoot"/>'s simplicity and in + contrast to common <xref linkend="glo_Java"/> <quote>best + practice</quote> you'll off course have to create all classes + inside the <quote>default</quote> package ignoring or + suppressing related compiler warnings.</para> + </glossdef> + </glossentry> + </glosslist> + + <caution> + <para>Caveat: Windows and Mac users may require further + configuration described below.</para> + </caution> + + <para>On Windows you'll have to instruct <xref linkend="glo_Eclipse"/> + to use a <xref linkend="glo_JDK"/> and not just a <xref + linkend="glo_JRE"/> (being the default). Whenever you install a <xref + linkend="glo_JDK"/> (like <link + xlink:href="http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html">JDK + 1.8.0</link>) on Windows a so called private <xref linkend="glo_JRE"/> + is being installed as well by default as well:</para> + + <informalfigure> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Screen/EclipseConfig/windowsCmdJdkJre.png"/> + </imageobject> + </mediaobject> + </informalfigure> + + <para>The problem: A library tools.jar being required by <xref + linkend="glo_BlueJ"/> is part of a <xref linkend="glo_JDK"/> but not + of a <xref linkend="glo_JRE"/>. Different resolutions are being + subsequently listed in descending order of ugliness (authors + opinion):</para> + + <glosslist> + <glossentry> + <glossterm>Explicitly defining the <xref linkend="glo_JDK"/> in + <xref linkend="glo_Eclipse"/></glossterm> + + <glossdef> + <para>Modify <filename>eclipse.ini</filename> in your <xref + linkend="glo_Eclipse"/> root installation directory pointing to + a <xref linkend="glo_JDK"/> in favour of the <xref + linkend="glo_JRE"/> default. The highlighted lines must appear + <emphasis role="bold">before</emphasis> any + <option>-vmargs</option> options.</para> + + <programlisting language="none">... +-showsplash +org.eclipse.platform +--launcher.XXMaxPermSize +256m +--launcher.defaultAction +openFile +--launcher.appendVmargs +<emphasis role="bold">-vm +C:\Program Files\Java\jdk1.8.0_25\bin/javaw +</emphasis>-vmargs +-Dosgi.requiredJavaVersion=1.6 +-Xms40m +-Xmx2048m</programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Fix <envar>JAVA_HOME</envar></glossterm> + + <glossdef> + <para>Define the environment variable <envar>JAVA_HOME</envar> + on operating system level pointing to your <xref + linkend="glo_JDK"/> of choice's root directory:</para> + + <programlisting language="none"><emphasis role="bold">set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_25</emphasis></programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Setting a static path in <xref + linkend="glo_pom.xml"/></glossterm> + + <glossdef> + <para>Explicitly set the required dependencies fully qualified + pathname in each <xref linkend="glo_pom.xml"/>:</para> + + <programlisting language="none"><dependency> + <groupId>com.sun</groupId> + <artifactId>tools</artifactId> + <version>1.8.0</version> + <scope>system</scope> + <emphasis role="bold"><systemPath>C:\Program Files\Java\jdk1.8.0_25\lib\tools.jar</systemPath></emphasis> + </dependency></programlisting> + </glossdef> + </glossentry> + </glosslist> + + <para>Needless to mention these path settings have to be revised + accordingly whenever your <xref linkend="glo_JDK"/> receives an update + to e.g. <xref linkend="glo_JDK"/> 1.8.0_31. The author humbly welcomes + any advice towards a better solution.</para> + </section> + + <section xml:id="sd1LifeWorld"> + <title>Creating the Game of life's world</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaLifeWorld"> + <title>Creating the <quote + xlink:href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Game + of Life</quote>'s world</title> + + <glosslist> + <glossentry> + <glossterm>Exporting to your separate + <productname>Greenfoot</productname> environment</glossterm> + + <glossdef> + <para>As soon as you actually want to run your game copy all + Java files from your <xref linkend="glo_Eclipse"/> project to + your <productname>Greenfoot</productname> environment. A + graphical file manager might assist you or you may simply use + shell commands (You'll need to do this next term in + <quote>Operating Systems</quote> anyway) like e.g.:</para> + + <programlisting language="none">goik@goiki:~$ cd ~/workspace/life/src/main/java +goik@goiki:~/workspace/life/src/main/java$ ls +Cell.java CellState.java LifeWorld.java +goik@goiki:~/workspace/life/src/main/java$ cp *.java ~/my-scenarios/Life</programlisting> + + <para>Then hit <quote>compile</quote> inside + <productname>Greenfoot</productname> to refresh and start your + game</para> + </glossdef> + </glossentry> + </glosslist> + + <qandadiv> + <qandaentry> + <question> + <para>Create a <productname>Greenfoot</productname> world + class and a dummy representation for cells representing <link + xlink:href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Conway's + Game of Life</link>:</para> + + <screenshot> + <info> + <title>World and Actor classes representing Conway's Game + of Life</title> + </info> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/gameOfLifeWorld.png"/> + </imageobject> + </mediaobject> + </screenshot> + + <para>The above example shows a grid of 50 * 50 cells each + having a size of 10 pixel. In preparation for subsequent + exercises each cell shall have two possible states namely + <quote>dead</quote> or <quote>alive</quote>. In this exercise + we only deal with the game's initialization. So transitions + <quote>dead</quote> --> <quote>alive</quote> or vice versa + will not occur. But your implementation should already be + prepared to allow such transitions.</para> + + <para>You may follow these steps:</para> + + <orderedlist> + <listitem> + <para>Create a new <productname>Greenfoot</productname> + world class <classname>LifeWorld</classname> of + configurable width and height and an actor class + <classname>Cell</classname>. Choose an arbitrary image + representing cells. The image is actually irrelevant since + our application will replace it by filled white or black + rectangles anyway representing cells being dead or alive. + So the blue dot in the above screenshot left of + <quote>Cell</quote> in the <quote>Actor classes</quote> + pane will never get visualized.</para> + </listitem> + + <listitem> + <para>Create your world's horizontal and vertical red + lines. Hints:</para> + + <itemizedlist> + <listitem> + <para>The method <methodname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/World.html#getBackground()">getBackground()</methodname> + allows you to access your world's background + representation as an instance of class <classname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html">GreenfootImage</classname>.</para> + </listitem> + + <listitem> + <para>You may add lines to <classname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html">GreenfootImage</classname> + instances by calling <methodname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html#drawLine(int,%20int,%20int,%20int)">drawLine(...)</methodname> + after choosing a desired color by calling i.e. + <methodname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html#setColor(java.awt.Color)">setColor(Color.red)</methodname>. + You may experiment a little bit by drawing some + example lines before eventually creating horizontal + and vertical grid lines using loops.</para> + </listitem> + </itemizedlist> + </listitem> + + <listitem> + <para>Use the constructor <classname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html#GreenfootImage(int,%20int)">GreenfootImage(int + width, int height)</classname> to create colored + rectangles representing cells:</para> + + <glosslist> + <glossentry> + <glossterm>black</glossterm> + + <glossdef> + <para>Cell is alive</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>white (=invisible)</glossterm> + + <glossdef> + <para>Cell is dead</para> + </glossdef> + </glossentry> + </glosslist> + + <para>The <methodname + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/Actor.html#setImage(greenfoot.GreenfootImage)">setImage()</methodname> + method allows defining these images to represent your + cells thereby replacing the original + <productname>Greenfoot</productname> definition from class + <classname>Cell</classname> creation time.</para> + + <para>Watch out for appropriate spacing. Your cells should + not interfere with the grid's red lines. They have to be a + little smaller to fit in the <quote>empty</quote> + space.</para> + + <para>When creating cells initialize a configurable + percentage in state alive. In the above screenshot 25% of + all cells are alive when starting the game. You may use a + boolean variable to indicate a cell's two possible states + but a dedicated <classname>Enum CellState</classname> will + improve your code's readability.</para> + </listitem> + + <listitem> + <para>Your world will consist of a two dimensional grid + containing width * height cells. In the above example we + have 50 * 50 == 2500 cells. Arrange your cells in a one + dimensional array of size width * height. Then implement + the following method linking these cells' index values to + x- and y-coordinates:</para> + + <programlisting language="java"> <emphasis role="bold">/** + * Turn (x|y) coordinates into linear cell array index + * values ranging from 0 to (width * height - 1). + * + * Consider a simplified example of an array having width = 4 and + * height = 3: + * + * {(0|0) (1|0) (2|0) (3|0)} --> Linear array Index values {0, 1, 2, 3} + * {(0|1) (1|1) (2|1) (4|1)} --> Linear array Index values {4, 5, 6, 7} + * {(0|2) (1|2) (2|2) (4|2)} --> Linear array Index values {8, 9, 10, 11} + * + * @param x horizontal position in cell coordinates + * @param y vertical position in cell coordinates + * @return The linear array index. + */</emphasis> + private int getCellIndex(int x, int y) { + ... + return ...; + }</programlisting> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/life/V1</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + </chapter> + + diff --git a/Doc/Sd1/class.xml b/Doc/Sd1/class.xml new file mode 100644 index 0000000000000000000000000000000000000000..e9330cd6f48ac8719035e96248ddba344cd25193 --- /dev/null +++ b/Doc/Sd1/class.xml @@ -0,0 +1,925 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter version="5.0" xml:id="sd1ClassesInstancesState" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Lecture 5 - Classes, instances and internal state (20.10)</title> + + <section xml:id="sd1CrabsEnhancePrepare"> + <title>Preparations</title> + + <itemizedlist> + <listitem> + <para>Read Chapter 5 from <xref linkend="bib_Horton2011"/> excluding + the sections <quote>Recursion</quote> and <quote>Nested + classes</quote>. Carefully read the explanations regarding:</para> + + <itemizedlist> + <listitem> + <para>static vs. non-static methods and fields.</para> + </listitem> + + <listitem> + <para>the <code>final</code> keyword's meaning.</para> + </listitem> + + <listitem> + <para>The way a garbage collector works.</para> + </listitem> + </itemizedlist> + </listitem> + </itemizedlist> + </section> + + <section xml:id="sd1GeometryClasses"> + <title>Dealing with geometry classes</title> + + <qandaset defaultlabel="qanda" xml:id="sd1ImplementRectangle"> + <title>Rectangles</title> + + <qandaentry> + <question> + <para>Complete the the following class + <classname>Rectangle</classname>'s dummy implementation:</para> + + <programlisting language="java">/** + * Representing rectangular shapes. + * + */ +public class Rectangle { + + /** + * + * @param width The rectangle's width + * @param heigth The rectangle's height + */ + public Rectangle (double width, double heigth) { + //TODO + } + /** + * @return The rectangle's area. + */ + public double getArea() { + return 0; // TODO + } + + /** + * @return The rectangle's perimeter. + */ + public double getPerimeter() { + return 0; // TODO + } + + /** + * @return The rectangle's width. + */ + public double getWidth() { + return 0; // TODO + } + /** + * @param width The rectangle's new width + */ + public void setWidth(double width) { + // TODO + } + + /** + * @return The rectangle's height. + */ + public double getHeight() { + return 0; // TODO + } + + /** + * @param width The rectangle's new height + */ + public void setHeight(double height) { + // TODO + } +}</programlisting> + </question> + + <answer> + <para>First we define two instance (= non-static) variables + representing a <classname>Rectangle</classname>'s two parameters + <code>width</code> and <code>height</code>:</para> + + <programlisting language="java">public class Rectangle { + + // Instance variables representing a rectangle's parameters + private double width, height; +... +}</programlisting> + + <para>Next we might allow to change these two parameters:</para> + + <programlisting language="java">public class Rectangle { + + // Instance variables representing a rectangle's parameters + private double width, height; + +... + public void setWidth(double w) { + <emphasis role="bold">width = w;</emphasis> + } + + /** + * @return The rectangle's height. + */ + public void setHeight(double height) { + <emphasis role="bold">this.height = height;</emphasis> + } +... +}</programlisting> + + <para>Notice the subtle difference in the implementation of + setWidth(...) and setHeight(...):</para> + + <glosslist> + <glossentry> + <glossterm><methodname>setWidth(double + w)</methodname></glossterm> + + <glossdef> + <para>We use the formal parameter name <quote>w</quote>. Its + name does not conflict with the instance variable name + <quote>width</quote> being defined at class level. We can + simply assign this value to our corresponding instance + variable using <code>width = w;</code>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><methodname>setHeight(double + height)</methodname></glossterm> + + <glossdef> + <para>The method's formal parameter <quote>height</quote> + shadows the instance variable's name being defined at class + level. We need the <quote>this</quote> keyword in + <code>this.height = height;</code> to resolve the + ambiguity.</para> + </glossdef> + </glossentry> + </glosslist> + + <para>Both ways are perfectly legal. We continue our + implementation:</para> + + <programlisting language="java">/** + * Representing rectangular shapes. + * + */ +public class Rectangle { + + // Instance variables representing a rectangle's parameters + private double width, height; + + /** + * + * @param width The rectangle's width + * @param heigth The rectangle's height + */ + public Rectangle (double width, double height) { + 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); + } + + /** + * @return The rectangle's width. + */ + public double getWidth() { + return width; + } + /** + * @param width The rectangle's new width + */ + public void setWidth(double w) { + width = w; + } + + /** + * @return The rectangle's height. + */ + public double getHeight() { + return height; + } + + /** + * @param width The rectangle's new height + */ + public void setHeight(double height) { + this.height = height; + } +}</programlisting> + </answer> + </qandaentry> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="qandasetGeometry"> + <title>Circles</title> + + <qandadiv> + <qandaentry> + <question> + <para>Complete the the following class + <classname>Circle</classname>'s dummy implementation:</para> + + <programlisting language="java">package step1.dummy; + +/** + * A circle of given radius + * + */ +public class Circle { + + /** + * A new circle + * + * @param radius + * The desired radius. + */ + public Circle(double radius) { + // TODO + } + + /** + * @return The circle's area. + */ + public double getArea() { + return 0; // TODO + } + + /** + * @return The circle's perimeter. + */ + public double getPerimeter() { + return 0; // TODO + } + + /** + * @return The circle's radius. + */ + public double getRadius() { + return 0; // TODO + } + + /** + * @param radius + * Setting the circle's radius to a new value. + */ + public void setRadius(double radius) { + // TODO + } +}</programlisting> + + <para>Instances of this class shall be usable in the following + fashion:</para> + + <programlisting language="java">public class Driver { + + public static void main(String[] args) { + Circle c = new Circle(2.3); + System.out.println("Radius:" + c.getRadius()); + System.out.println("Perimeter:" + c.getPerimeter()); + System.out.println("Area:" + c.getArea()); + + // Changing the circle's radius to a different value + c.setRadius(4.7); + System.out.println("Radius:" + c.getRadius()); + System.out.println("Perimeter:" + c.getPerimeter()); + System.out.println("Area:" + c.getArea()); + } +}</programlisting> + + <para>Hint: Obviously you'll have to define an instance variable + within Circle to keep track of its current radius value. All + methods mentioned above simply depend on this single value.</para> + </question> + + <answer> + <para>We define an instance variable radius inside our class + <classname>Circle</classname>:</para> + + <programlisting language="java"> +public class Circle { + + double radius; +... +}</programlisting> + + <para>Next we implement our method to change a circle's + radius:</para> + + <programlisting language="java"> public void setRadius(double r) { + radius = r; + }</programlisting> + + <para>Note that we have chosen a different value for the method's + formal radius parameter to be <quote>r</quote> rather than + <quote>radius</quote>. Many people prefer to use radius here + making it easier for a programmer to recognize the expected name + in the generated javadoc:</para> + + <programlisting language="java"> public void setRadius(double radius) { + <emphasis role="bold">this.</emphasis>radius = radius; + }</programlisting> + + <para>This requires the usage of the <code>this</code> keyword to + distinguish the formal parameter in <methodname>setRadius(double + radius)</methodname> from the instance variable previously being + defined within our class <classname>Circle</classname>. In other + words: We have to resolve a name shadowing conflict.</para> + + <para>The rest of the implementation is (quite) straightforward. A + complete class reads:</para> + + <programlisting language="java">package step1; + +/** + * A circle of given radius + * + */ +public class Circle { + + double radius; + + /** + * A new circle + * @param radius The desired radius. + */ + public Circle(double radius) { + setRadius(radius); + } + + /** + * @return The circle's area. + */ + public double getArea() { + return radius * radius * Math.PI; + } + + /** + * @return The circle's perimeter. + */ + public double getPerimeter() { + return 2 * Math.PI * radius; + } + + /** + * @return The circle's radius. + */ + public double getRadius() { + return radius; + } + + /** + * @param radius Setting the circle's radius to a new value. + */ + public void setRadius(double radius) { + this.radius = radius; + } +}</programlisting> + </answer> + </qandaentry> + + <qandaentry> + <question> + <para>Our current Circle and Rectangle instances are only shapes + yet and do not allow to be moved in a coordinate system:</para> + + <itemizedlist> + <listitem> + <para>Add two more instance variables x and y and + corresponding setter methods to account for a shapes origin + being different from (0,0). The following hint may be + helpful:</para> + + <programlisting language="java"> /** + * @param x The circle's x center coordinate value + */ + public void setX(double x) { + // TODO + } + /** + * @param x The circle's x center coordinate value + */ + public void setY(double y) { + // TODO + }</programlisting> + </listitem> + + <listitem> + <para>We would like Rectangle and Circle instances to be + visualized as <acronym>SVG</acronym> graphics. Add a method + <methodname>void writeSvg()</methodname> to both classes which + allows for <acronym>SVG</acronym> code export to standard + output. You may want to read the w3schools <link + xlink:href="http://www.w3schools.com/svg/svg_rect.asp">rectangle</link> + and <link + xlink:href="http://www.w3schools.com/svg/svg_circle.asp">circle</link> + examples. Use System.out.println(...) calls to create the + desired <acronym>SVG</acronym> output. You may need + <code>\"</code> to represent double quotes as in the + subsequent example:</para> + + <programlisting language="java">System.out.println("<rect width=\"20\"" ...</programlisting> + </listitem> + </itemizedlist> + + <para>The following code snippet may serve to illustrate the + intended use of <methodname>void writeSvg()</methodname>:</para> + + <programlisting language="java">public class Driver { + + public static void main(String[] args) { + + System.out.println("<!DOCTYPE html><html><body>"); + System.out.println(" <svg width='300' height='200' >"); + + // Draw a rectangle as SVG + final Rectangle r = new Rectangle(5, 4); + r.setX(2); + r.setY(1); + r.writeSvg(); + + // Draw a circle as SVG + final Circle c = new Circle(1, 1, 3); + c.setX(3); + c.setY(1); + c.writeSvg(); + System.out.println(" </svg >"); + System.out.println("</body></html>"); + } +}</programlisting> + + <para>Implement the method <methodname>void + writeSvg()</methodname> in both classes + <classname>Rectangle</classname> and + <classname>Circle</classname>. This should produce an output + result like:</para> + + <programlisting language="java"><!DOCTYPE html> +<html> + <body> + <svg width='300' height='200' > + <emphasis role="bold"><rect width='100.0' height='80.0' x='40.0' y='20.0'' style='fill:rgb(0,255,0);stroke-width:3;stroke:rgb(0,0,0)'/></emphasis> + <emphasis role="bold"><circle r='60.0' cx='60.0' cy='20.0' style='fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)'/></emphasis> + </svg > + </body> +</html></programlisting> + + <para>You may enter this output into a file sfg.html. A web + browser should visualize this output as:</para> + + <informalfigure> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/svgGeometry.png"/> + </imageobject> + </mediaobject> + </informalfigure> + </question> + + <answer> + <programlisting language="java"> private double x, y, width, height; + ... + /** + * @param x The rectangle's x center coordinate value + */ + public void setX(double x) { + this.x = x; + } + /** + * @param x The rectangle's x center coordinate value + */ + public void setY(double y) { + this.y = y; + } + +public void writeSvg() { + final int scale = 20; + System.out.println( + "<rect width='" + scale * width +"' height='" + scale * height + + "' x='" + scale * x + "'" + " y='" + scale * y + "'" + + "' style='fill:rgb(0,255,0);stroke-width:3;stroke:rgb(0,0,0)'/>"); + } +}</programlisting> + + <programlisting language="java">public class Circle { + + double x, y, radius; +... + + /** + * @param x The circle's x center coordinate value + */ + public void setX(double x) { + this.x = x; + } + /** + * @param x The circle's x center coordinate value + */ + public void setY(double y) { + this.y = y; + } + +public void writeSvg() { + final int scale = 20; + + System.out.println( + "<circle r='" + scale * radius + + "' cx='" + scale * x + "'" + " cy='" + scale * y + + "' style='fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)'/>"); + + } +}</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section version="5.0" xml:id="sd1InterestCalculator"> + <title>Lecture 5 - A simple interest calculator (22.10.)</title> + + <!-- + <para>See compressed eclipse project account.zip in <link + xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud/public.php?service=files&t=df9f296af3298f96361a15a679390e59">subfolder + 06</link>. This example illustrates the following concepts:</para> +--> + + <para>Consider the following implementation of an interest + calculator:</para> + + <annotation role="make"> + <para role="eclipse">P/interest/V1</para> + </annotation> + + <glosslist> + <glossentry> + <glossterm>Instance versus class variables and methods</glossterm> + + <glossdef> + <para>Examples:</para> + + <glosslist> + <glossentry> + <glossterm>Instance variables and methods, non-static + declaration</glossterm> + + <glossdef> + <para><code>private double balance</code>, <code>public void + setBalance(double balance)</code></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Class variables and methods, static + declaration</glossterm> + + <glossdef> + <para><code>private static double </code>interestRate, + <code>public static void setInterestRate(double + z)</code></para> + </glossdef> + </glossentry> + </glosslist> + + <para>For both categories see <xref linkend="bib_Horton2011"/>, + chapter 5, <quote>Fields in a Class Definition</quote> and + <quote>Methods in a Class Definition</quote>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Formal parameter names and variable scopes</glossterm> + + <glossdef> + <programlisting language="java"> /** + * Setting the interest rate common to all accounts. + * + * @param z + * the desired (global) interest rate. + */ + public static void setInterestRate(double z) { // Scope of variable "z" limited is just the next block {...}, + interestRate = z; // in contrast interestRate has class scope. + }</programlisting> + + <para>The formal variable's name <quote><code>z</code></quote> may + be <emphasis>consistently</emphasis> renamed to any other legal, + non-conflicting value like + <quote><code>myFunnyVariableName</code></quote>:</para> + + <programlisting language="java"> public static void setInterestRate(double myFunnyVariableName) { + interestRate = myFunnyVariableName; + }</programlisting> + + <para>Name shadowing conflicts can be resolved by using the keyword + <emphasis><code>this</code></emphasis> <coref + linkend="sd1ListingThis"/>:</para> + + <programlisting language="java">public class Konto { +... + private double balance; <emphasis role="bold">// variable "stand" being shadowed inside body of setStand(...)</emphasis> +... + public void setStand(double stand) { + if (balance <= 10000) { + <emphasis role="bold">this</emphasis>.balance <co + xml:id="sd1ListingThis"/> = balance; // "this" required to resolve name shadowing conflict + // by formal parameter name "double balance". + } else { + System.out.println("Balance" + balance + " exceeds " + 10000); + } + } +... +}</programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Access restrictions public / private / protected to + attributes and methods</glossterm> + + <glossdef> + <programlisting language="java">public class Account { + + <emphasis role="bold">private</emphasis> static double // Visible for class methods only + interestRate = 1.5; +... + <emphasis role="bold">public</emphasis> void applyInterest() { // Externally visible + balance = balance * (1 + interestRate / 100); + } +...</programlisting> + + <para>See <xref linkend="bib_Horton2011"/>, chapter 5, + <quote>CONTROLLING ACCESS TO CLASS MEMBERS</quote>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Method overloading</glossterm> + + <glossdef> + <para>Example:</para> + + <programlisting language="java">public class Account { + + public Account() { // Default Constructor without any parameter + setBalance(0); + } +... + public Account(double balance) { // <emphasis role="bold">Overloaded</emphasis> non-default constructor creating an account + setBalance(balance); // with (possibly) non-zero balance. + } +... + public void applyInterest() { // Just one year + balance = balance * + (1 + interestRate / 100); + } +... + public void applyInterest(int years) { // <emphasis role="bold">Overloaded</emphasis> method allowing for different time periods. + balance = balance * + Math.pow((1 + interestRate / 100), years); + } +... +}</programlisting> + + <para>See <xref linkend="bib_Horton2011"/>, chapter 5, <quote>METHOD + OVERLOADING</quote>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Use of standard mathematical functions</glossterm> + + <glossdef> + <programlisting language="java">Math.pow((1 + interestRate / 100), years)</programlisting> + + <para>See <xref linkend="bib_Horton2011"/>, chapter 2, + <quote>MATHEMATICAL FUNCTIONS AND CONSTANTS</quote>.</para> + </glossdef> + </glossentry> + </glosslist> + </section> + + <section xml:id="sd1VariableExercises"> + <title>Extending our interest calculator</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaExtendInterest"> + <qandadiv> + <qandaentry> + <question> + <para>Our current <code>Account</code> class does not handle + negative balances accordingly. Typically banks will charge a + different interest rate whenever an account is in debt i.e. having + a negative balance. In this case a second so called default + interest rate (being significantly higher) will be applied.</para> + + <para>Extend the current project by adding a new instance variable + <varname>defaultInterestRate</varname> along with getter and + setter methods. Then change the implementation of + <code>applyInterest()</code> and <code>applyInterest(int + years)</code> by using the correct interest value according to the + account's balance being positive or negative.</para> + + <caution> + <para>Do not forget to change the <command>Javadoc</command> + comments accordingly!</para> + </caution> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/interest/V2</para> + </annotation> + + <para>We introduce a new variable <code>defaultInterestRate</code> + to cover negative balance values:</para> + + <programlisting language="java"> private static double + interestRate = 1.5, // applied to positive balances + <emphasis role="bold">defaultInterestRate = 15.; // applied to negative balances</emphasis></programlisting> + + <para>We need the appropriate getter and setter methods in + <classname + xlink:href="Ref/api/P/interest/V2/de/hdm_stuttgart/mi/sd1/interest/Account.html">Account</classname>:</para> + + <programlisting language="java"> /** + * @return + * the current default interest rate value. + */ + public static double <link + xlink:href="Ref/api/P/interest/V2/de/hdm_stuttgart/mi/sd1/interest/Account.html#getDefaultInterestRate--">getDefaultInterestRate()</link> { + return defaultInterestRate; + } + + /** + * This interest rate will be applied to negative balances. In contrast + * {{@link #setInterestRate(double)} will handle positive balance values. + * + * @param defaultInterestRate + * the desired default interest rate value. + */ + public static void <link + xlink:href="Ref/api/P/interest/V2/de/hdm_stuttgart/mi/sd1/interest/Account.html#setDefaultInterestRate-double-">setDefaultInterestRate(double defaultInterestRate)</link> { + Account.defaultInterestRate = defaultInterestRate; + }</programlisting> + + <para>The computed interest depends on positive or negative + balance values:</para> + + <programlisting language="java"> public void applyInterest(int years) { + if (0 < balance) { + balance = balance * Math.pow((1 + interestRate / 100), years) ; + } else if (balance < 0){ + balance = balance * Math.pow((1 + defaultInterestRate / 100), years) ; + } + }</programlisting> + + <para>A complete solution including updated + <productname>Javadoc</productname> comments can be downloaded + <link + xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud/public.php?service=files&t=577bc9091391524692b6d812a6d2737a">from + here</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sd1VariableComplexExpression"> + <title>Programmers favourite expression</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following code fragment:</para> + + <programlisting language="java"> int a = 6, + b = 7, + c = -3, + result = 0; + + result += ++a - b++ + --c;</programlisting> + + <para>Rewrite this code by decomposing the last line into several + lines to make the code easier to understand.</para> + + <para>Hint: After execution of your modified code all variable + must have identical values with respect to the original code. In + other words: Your modifications shall not alter the code's + behaviour in any way.</para> + </question> + + <answer> + <para>Incrementing <code>++a</code> and decrementing + <code>--c</code> happens prior to adding / subtracting their + values to the variable <code>result</code> (prefix notation). The + increment operation <code>b--</code> in contrast happens after + being being subtracted from variable <code>result</code> (postfix + notation). The following code snippet is thus equivalent:</para> + + <programlisting language="java"> int a = 6, + b = 7, + c = -3, + result = 0; + ++a; + --c; + result += a - b + c; // or even: result = result + a - b + c; + b++;</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaIntOverflow"> + <title>Integer value considerations.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following piece of code:</para> + + <programlisting language="java">int a = ..., b = ...; +...// statements being omitted +int sum = a + b;</programlisting> + + <para>Which representation related problem may arise here? May you + supply a solution?</para> + </question> + + <answer> + <para>The sum of a and b may either exceed + <code>java.lang.Integer.MAX_VALUE</code> or in turn may be less + than <code>java.lang.Integer.MIN_VALUE</code>. To avoid this type + of overflow error our variable <code>sum</code> may be declared of + type long:</para> + + <programlisting language="java">int a = ..., b = ...; +...// statements being omitted +long sum = a + b;</programlisting> + + <para>Unfortunately this does not (yet) help at all: Since both + operands <code>a</code> and <code>b</code> are of type + <code>int</code> the expression <code>a + b</code> is also of type + int and will be evaluated as such. To circumvent this problem we + have to cast at least one operand to type <code>long</code> prior + to computing the sum. This works since the cast operator + <code>(long)</code> does have higher priority than the + <quote>+</quote> operator</para> + + <programlisting language="java">int a = ..., b = ...; +...// statements being omitted +long sum = (long)a + b;</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sde1QandaFraction"> + <title>A class representing fractions</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement a class representing fractions. You may find a + dummy implementation containing some (not yet working) sample + usage code being contained in a <code>main()</code> method. This + Maven archive also includes a <xref linkend="glo_Junit"/> + test.</para> + + <annotation role="make"> + <para role="eclipse">P/fraction/V05</para> + </annotation> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/fraction/V1</para> + </annotation> + + <para>See implementation at <link + xlink:href="Ref/api/P/fraction/V1/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html">Fraction</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> +</chapter> diff --git a/Doc/Sd1/collections.xml b/Doc/Sd1/collections.xml new file mode 100644 index 0000000000000000000000000000000000000000..b0a759c716eab014c7e8f3f405ccb202c3d06429 --- /dev/null +++ b/Doc/Sd1/collections.xml @@ -0,0 +1,1584 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter version="5.0" xml:id="sd1Collection1" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Collections</title> + + <section xml:id="sd1CollectionsPrep"> + <title>Preparations</title> + + <para>Chapter 14 of <xref linkend="bib_Horton2011"/> provides an in depth + discussion of Java collections. Regarding the upcoming exercises you may + however prefer to study the following track:</para> + + <glosslist> + <glossentry> + <glossterm>Introduction</glossterm> + + <glossdef> + <para + xlink:href="http://tutorials.jenkov.com/java-collections/collection.html"><link + xlink:href="http://tutorials.jenkov.com/java-collections/collection.html">Java + Collections - Collection</link></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname>List</classname></glossterm> + + <glossdef> + <para + xlink:href="http://tutorials.jenkov.com/java-collections/list.html"><link + xlink:href="http://tutorials.jenkov.com/java-collections/list.html">Java + Collections - List</link></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname>Set</classname></glossterm> + + <glossdef> + <para + xlink:href="http://tutorials.jenkov.com/java-collections/set.html"><link + xlink:href="http://tutorials.jenkov.com/java-collections/set.html">Java + Collections - Set</link></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><methodname>hashCode()</methodname> and + <methodname>equals()</methodname></glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para + xlink:href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html"><link + xlink:href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html">Java + Collections - hashCode() and equals()</link></para> + </listitem> + + <listitem> + <para><link xlink:href="Ref/Svg/hashing.svg">Hashing overview + slides</link>.</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + </glosslist> + </section> + + <section xml:id="sd1Collection1exercise"> + <title>Collections I,Exercises</title> + + <section xml:id="sd1Collection2exerciseSetString"> + <title>A <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> + of Strings</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSetString"> + <title>Inserting strings into a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname>.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Create a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> + of String instances including duplicates. Iterate over this set + and write each value to <code>System.out</code>:</para> + + <programlisting language="java"> public static void main(String[] args) { + + final Set<String> names = new HashSet<String>(); + names.add(... + ... + // Iterate over all inserted coordinates + for (... + }</programlisting> + </question> + + <answer> + <para>Inserting some string literals is a trivial task. A + for-each loop allows iterating over the set to write its content + to standard output:</para> + + <programlisting language="java"> public static void main(String[] args) { + + final Set<String> names = new HashSet<String>(); + + names.add("Eve"); + names.add("Jim"); + names.add("Tom"); + names.add("Jim"); + + // Iterate over all inserted coordinates + System.out.println("The set contains " + names.size() + " elements:"); + for (final String s : names) { + System.out.println(s); + } + }</programlisting> + + <para>Notice the duplicate name <code>"Jim"</code>: Since our + collection does have set semantics it only contains three + elements {"Eve", "Jim", "Tom"}:</para> + + <programlisting language="none">The set contains 3 elements: +Tom +Jim +Eve</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1CollectionExerciseListString"> + <title>A <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname> + of Strings</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaListString"> + <title>Inserting strings into a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname>.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Create a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname> + of String instances including duplicates. Iterate over this list + and write each value to <code>System.out</code>:</para> + + <programlisting language="java"> public static void main(String[] args) { + + final List<String> names = ...; + + names.add(... + ... + + // Iterate over all inserted strings + System.out.println("The list contains " + names.size() + " elements:"); + for (final String s : names) { + System.out.println(s); + } + }</programlisting> + </question> + + <answer> + <para>Our code closely resembles <xref + linkend="sd1QandaSetString"/>:</para> + + <programlisting language="java"> public static void main(String[] args) { + + final List<String> names = new Vector<String>(); + + names.add("Eve"); + names.add("Jim"); + names.add("Tom"); + names.add("Jim"); + + // Iterate over all inserted strings + System.out.println("The list contains " + names.size() + " elements:"); + for (final String s : names) { + System.out.println(s); + } + }</programlisting> + + <para>This time the duplicate actually shows up:</para> + + <programlisting language="none">The list contains 4 elements: +Eve +Jim +Tom +Jim</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1CollectionDefCoordinate"> + <title>Defining a <classname>Coordinate</classname> class</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaCoordinate"> + <title>Representing integer coordinate values</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement a class <classname>Coordinate</classname> to + represent integer Cartesian coordinate values:</para> + + <programlisting language="java">public class Coordinate { + + private int x, y; + ... +}</programlisting> + + <para>Provide an appropriate constructor and override both + <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--">toString()</methodname> + and <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> + to allow execution of:</para> + + <programlisting language="java"> // Defining and testing integer coordinates + final Coordinate + c12 = new Coordinate(1, 2), + c52 = new Coordinate(5, 0), + c12Duplicate = new Coordinate(1, 2); + + + System.out.println("c12:"+ c12); + System.out.println("c12.equals(c52):"+ c12.equals(c52)); + System.out.println("c12.equals(c12Duplicate):"+ c12.equals(c12Duplicate)); + System.out.println("c12.equals(\"dummy\"):"+ c12.equals("dummy")); + + System.out.println(c12);</programlisting> + + <para>This should yield the expected output:</para> + + <programlisting language="none">c12:(1|2) +c12.equals(c52):false +c12.equals(c12Duplicate):true +c12.equals("dummy"):false +(1|2)</programlisting> + </question> + + <answer> + <para>Overriding <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--">toString()</methodname> + and <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> + and adding a non-default constructor is a straightforward + exercise:</para> + + <programlisting language="java">public class Coordinate { + + private int x, y; + + /** + * Create a Cartesian coordinate / point. + * @param x + * @param y + */ + public Coordinate(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Coordinate) { + return x == ((Coordinate)obj).x && + y == ((Coordinate)obj).y; + } else { + return false; + } + } + + @Override + public String toString() { + return "(" + x + "|" + y + ")"; + } +}</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1SetCoordinate"> + <title>A <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> + of Coordinate instances</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSetCoordinate"> + <title>Inserting <link + linkend="sd1CollectionDefCoordinate"><classname>Coordinate</classname></link> + instances into a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname>.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Create a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> + of <link + linkend="sd1CollectionDefCoordinate"><classname>Coordinate</classname></link> + instances including duplicates. Iterate over this set and write + each value to <code>System.out</code> in a similar fashion to + <xref linkend="sd1QandaSetString"/>. Compare your output to the + corresponding example <xref + linkend="sd1QandaSetString"/>.</para> + + <para>Did you expect this behaviour? Explain this result and a + solution.</para> + </question> + + <answer> + <para>Our code is very similar to <xref + linkend="sd1QandaSetString"/>:</para> + + <programlisting language="java"> final Set<Coordinate> points = new HashSet<Coordinate>(); + + points.add(new Coordinate(1, 2)); + points.add(new Coordinate(4, 1)); + points.add(new Coordinate(1, 2)); // Equal to first Object + + // Iterate over all inserted coordinates + System.out.println("The set contains " + points.size() + " elements:"); + for (final Coordinate c : points) { + System.out.println(c.toString()); + }</programlisting> + + <para>Since we do have set semantics we expect the duplicate + coordinate value <code>(1|2)</code> to be dropped and thus to + appear only once. So our set should contain <code>{(4|1), + (1|2)}</code>. We however see the duplicate object appearing on + standard output:</para> + + <programlisting language="none">The set contains 3 elements: +(4|1) +(1|2) +(1|2)</programlisting> + + <para>This is due to our own fault not providing a <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashCode()</methodname> + implementation being compatible to our overridden <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> + method. Consider:</para> + + <programlisting language="java"> final Coordinate + c12 = new Coordinate(1, 2), + c12Duplicate = new Coordinate(1, 2); + + System.out.println("c12.hashCode() and c12Duplicate.hashCode():"+ c12.hashCode() + "," + c12Duplicate.hashCode());</programlisting> + + <para>This yields the following output:</para> + + <programlisting language="none">c12.hashCode() and c12Duplicate.hashCode():1334574952,1882008996</programlisting> + + <para>Apparently the two instances c12 and c12Duplicate are + equal to each other. Their hash codes however are different + clearly violating the contract being described in <link + xlink:href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html">Java + Collections - hashCode() and equals()</link>. The values + actually stem from <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashCode()</methodname> + being defined in our superclass <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html">Object</classname>.</para> + + <para>The former exercise <xref linkend="sd1QandaSetString"/> + involved instances of class String having well defined + <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#equals-java.lang.Object-">equals()</methodname> + and <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode--">hashCode()</methodname> + implementations. To resolve this issue we thus have to override + not just <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> + but <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashCode()</methodname> + as well:</para> + + <programlisting language="java">public class Coordinate { + + private int x, y; + ... + + @Override + public int hashCode() { + // See last answer (06/16/2014) in + // http://stackoverflow.com/questions/16629893/good-hashcode-implementation + return Long.valueOf(x * 31 + y).hashCode(); + } +}</programlisting> + + <para>This yields:</para> + + <programlisting language="none">c12.hashCode() and c12Duplicate.hashCode():33,33</programlisting> + + <para>And finally:</para> + + <programlisting language="none">The set contains 2 elements: +(1|2) +(4|1)</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + + <section xml:id="sd1Collection2exercise"> + <title>Collections I, Exercises</title> + + <section xml:id="sd1CollectionExerciseWordSearch"> + <title>Getting a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> + of strings from a text file</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaWordSearch"> + <title>Getting a text's set of words.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider a text file <filename>foo.txt</filename> + containing:</para> + + <programlisting language="none">A simple collection of words. + Some words may appear multiple times.</programlisting> + + <para>We would like to retrieve a comma separated list of all + words being contained within excluding duplicates.</para> + + <programlisting language="none">of, multiple, collection, simple, words, may, Some, times, A, appear</programlisting> + + <para>The subsequent rules shall apply:</para> + + <itemizedlist> + <listitem> + <para>Arbitrary combinations of white space and the + characters <emphasis + role="bold"><code>.,:;?!"</code></emphasis> shall be treated + as word delimiters and are otherwise to be ignored.</para> + </listitem> + + <listitem> + <para>The order of appearance in the generated result does + not matter.</para> + </listitem> + + <listitem> + <para>Duplicates like <quote>words</quote> in the current + example shall show up only once on output.</para> + </listitem> + </itemizedlist> + + <para>Hints:</para> + + <orderedlist> + <listitem> + <para>Your application shall read its input from a given + file name provided as a command line argument. Provide + appropriate error messages if:</para> + + <itemizedlist> + <listitem> + <para>The users enters either no arguments at all or + more than one command line argument.</para> + </listitem> + + <listitem> + <para>The file in question cannot be read.</para> + </listitem> + </itemizedlist> + + <para>You may reconsider <xref linkend="sd1GnuWc"/> + regarding file read access.</para> + </listitem> + + <listitem> + <para>Splitting input text lines at word delimiters + <emphasis role="bold"><code>.,:;?!"</code></emphasis> or + white space characters may be achieved by means of + <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-">split(...)</methodname> + and the regular expression <code>String regex = "[ + \t\"!?.,'´`:;]+"</code>;. This <quote>+</quote> sign + indicates the appearance of a succession of one ore more + character element from the set <emphasis role="bold"><code> + \t\"!?.,'´`:;</code></emphasis>.</para> + + <para>Thus a text <emphasis role="bold"><code>That's it. + Next try</code></emphasis> will be split into a string array + <code>{"That", "s", "it", "Next", "try"}</code>.</para> + </listitem> + + <listitem> + <para>Write a <xref linkend="glo_Junit"/> test which reads + from a given input file and compares its result with a hard + coded set of expected strings.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Wordlist/Solution</para> + </annotation> + + <para>The input file smalltest.txt may be used to define a <xref + linkend="glo_Junit"/> test:</para> + + <programlisting language="java"> @Test + public void testWordSet() throws FileNotFoundException, IOException { + + final Set<String> expectedStrings = + new HashSet <String>(Arrays.asList(new String[]{ + "A", "simple", "collection", "of", "words", + "Some", "may", "appear", "multiple", "times" + })); + + final TextFileHandler tfh = new TextFileHandler("smalltest.txt"); + Assert.assertTrue(tfh.getWords().equals(expectedStrings)); + }</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1CollectionExerciseWordSearchOrder"> + <title>Result string ordering</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaWordSearchOrdered"> + <title>A text's set of words in alphabetic order</title> + + <qandadiv> + <qandaentry> + <question> + <para>Copy the previous project to a second one and modify your + code to get the same set of words but in alphabetic order with + respect to capital and small letters:</para> + + <programlisting language="none">A, Some, appear, collection, may, multiple, of, simple, times, words </programlisting> + </question> + + <answer> + <para>The desired result is easy to achieve by exchanging our + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> + by a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html">SortedSet</classname>:</para> + + <programlisting language="java"> /** + * The set of words found so far. + */ + final SortedSet<String> words = new TreeSet<String>();</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1StringLengthSort"> + <title>Sorting strings in an unusual way</title> + + <para>This exercise intends to provide some knowledge on sorting being + needed in subsequent exercises.</para> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaStringLengthSort"> + <title>Implementing unusual string sorting.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Strings will often be sorted alphabetically:</para> + + <programlisting language="none">ant +apple +by +eye +it +printer +van +x-ray</programlisting> + + <para>In this exercise we want to sort strings by length and + then alphabetically:</para> + + <programlisting language="none">by +it +ant +eye +van +apple +x-ray +printer</programlisting> + + <para>Hints:</para> + + <orderedlist> + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-java.util.Comparator-">Collections.sort(</link>List<String>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator</classname> + c) is your friend.</para> + </listitem> + + <listitem> + <para>Defining a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator</classname> + class acting on strings works like:</para> + + <programlisting language="java">/** + * Compare strings first by their length. If two strings do have + * common length, sort them alphabetically. + * + */ +public class LengthCompare implements Comparator<String> { + @Override + public int compare(String s1, String s2) { + ... + return ...; +}</programlisting> + </listitem> + + <listitem> + <para>Write a <xref linkend="glo_Junit"/> test to assure + correct sorting of strings.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/StringLengthSort/Solution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1CollectionWordFrequencies"> + <title>Result string ordering</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaWordFrequencies"> + <title>Words and corresponding frequencies</title> + + <qandadiv> + <qandaentry> + <question> + <para>So far we've extracted the set of words a given text + consists of. In addition we'd like to see their corresponding + frequencies of appearance as well. This frequency value shall be + used as primary sorting criterion with respect to report output. + Consider the following example text:</para> + + <programlisting language="none">One day, Einstein, Newton, and Pascal meet up +and decide to play a game of hide and seek. +Einstein volunteered to be "It". As Einstein +counted, eyes closed, to 100, Pascal ran away +and hid, but Newton stood right in front of +Einstein and drew a one meter by one meter +square on the floor around himself. When +Einstein opened his eyes, he immediately saw +Newton and said "I found you Newton", but Newton +replied, "No, you found one Newton per square meter. +You found Pascal!"</programlisting> + + <para>Ignoring special characters the following result shall be + created:</para> + + <programlisting language="none"> 6: Newton + 6: and + 5: Einstein + 3: Pascal + 3: found + 3: meter + 3: one + 3: to + 2: a +...</programlisting> + + <para>The first line tells us that the word + <quote>Newton</quote> appears six times in the analyzed + document.</para> + + <para>Hints:<orderedlist> + <listitem> + <para>Define a class <classname>WordFrequency</classname> + containing a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname> + attribute among with an integer number representing its + frequency of appearance:</para> + + <programlisting language="java">/** + * A helper class to account for frequencies of words found in textual input. + * + */ +public class WordFrequency { + /** + * The frequency of this word will be counted. + */ + public final String word; + private int frequency; + ... +}</programlisting> + + <para>Two instances of + <classname>WordFrequency</classname> shall be equal if and + only if their <quote>word</quote> attribute values are + equal regardless of their frequency values. In slightly + other words: With respect to equality instances of + <classname>WordFrequency</classname> inherit equality + solely from their contained word values irrespective of + any frequency value.</para> + + <para>Override <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals(...)</methodname> + and <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashValue()</methodname> + accordingly.</para> + </listitem> + + <listitem> + <para>Create a List<WordFrequency> (Not a + Set<WordFrequency>!) holding words being found in + your input texts among with their frequencies of + appearance.</para> + + <para>Whenever the next input word is being processed + follow the subsequent procedure:</para> + + <orderedlist> + <listitem> + <para>Create a corresponding instance of + <classname>WordFrequency</classname> from it having + initial frequency 1.</para> + </listitem> + + <listitem> + <para>Test whether an instance being equal has already + been added to your + <code>List<WordFrequency></code> instance + leaving you with two choices:</para> + + <glosslist> + <glossentry> + <glossterm>The current word already + exists:</glossterm> + + <glossdef> + <para>Lookup the entry and increment its frequency + by one.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>The current word is new:</glossterm> + + <glossdef> + <para>Add the previously created + <classname>WordFrequency</classname> instance to + your <code>List<WordFrequency></code>.</para> + </glossdef> + </glossentry> + </glosslist> + </listitem> + + <listitem> + <para>After processing the input text file sort your + <code>List<WordFrequency></code> by a suitable + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator<WordFrequency></classname> + instance by means of <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-java.util.Comparator-">Collections.sort(...)</methodname>.</para> + </listitem> + </orderedlist> + </listitem> + </orderedlist></para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/WordFrequency1/Solution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + + <section xml:id="sd1Collection3Exercise"> + <title>Collections III, Exercises</title> + + <figure xml:id="sd1FigureAccoutInheritHierarchy"> + <title>Account hierarchy</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/account.fig"/> + </imageobject> + </mediaobject> + </figure> + + <figure xml:id="sda1FigurePersonInheritHierarchy"> + <title>Students and lecturers</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/person.fig"/> + </imageobject> + </mediaobject> + </figure> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaAddressHtmlFormat"> + <title>Formatting an address list</title> + + <qandadiv> + <qandaentry> + <question> + <para>We want to transform address data to different destination + formats. Consider the following text file data source:</para> + + <programlisting language="none">"firstName","lastName","companyName","address","city", ... +"Aleshia","Tomkiewicz","Alan D Rosenburg Cpa Pc","14 Tay ... +...</programlisting> + + <para>This excerpt exists as file named + <filename>addresses.txt</filename> in the following Maven + project:</para> + + <annotation role="make"> + <para role="eclipse">P/HtmlFormatting/Simple/Exercise</para> + </annotation> + + <para>Import the above project into <xref linkend="glo_Eclipse"/>. + Executing + <classname>de.hdm_stuttgart.mi.sd1.htmlformat.Address2text</classname> + yields the following output:</para> + + <programlisting language="none">"firstName","lastName","companyName","address","city", ... +List of addresses: +++++++++++++++++++++++ +Name:Tim Dummy +Company:Dummy Company +Address:Dummy street, DummyCity, DummyPostal +Phone:1234567, 7654321 +E-Mail:@dummy@dummy.com +-------------------- + +... + +-------------------- +End of records</programlisting> + + <para>This result neither uses the input data supplied by + <filename>addresses.txt</filename> nor does it produce HTML output + yet. You have to complete the implementation by following the + subsequent steps:</para> + + <orderedlist> + <listitem> + <para>Try to understand the current project. Its classes have + the following general purposes:</para> + + <glosslist> + <glossentry> + <glossterm><classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address.html">Address</classname></glossterm> + + <glossdef> + <para>Holding components like first name, last name, + telephone numbers, email and so on of an individual + address.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2text.html">Address2text</classname></glossterm> + + <glossdef> + <para>The main application. This class assembles other + classes, opens the address data source and starts the + formatting process.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2textFormatter.html">Address2textFormatter</classname></glossterm> + + <glossdef> + <para>This class formats individual address + records.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressDataHandler.html">AddressDataHandler</classname></glossterm> + + <glossdef> + <para>Opening the data source and creating a Java in + memory representation of the whole set. This is + necessary since the output sorting order may be + altered.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressFormatter.html">AddressFormatter</classname></glossterm> + + <glossdef> + <para>This interface specifies three methods being + called during output formatting.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressParseError.html">AddressParseError</classname></glossterm> + + <glossdef> + <para>Instances of this exception will be thrown + whenever the input file contains errors. Consider the + following example:</para> + + <programlisting language="none">"Laquita","Hisaw,"In Communications Inc","20 Gloucester Pl #96",</programlisting> + + <para>In this example we have no quote after + <code>Hisaw</code>. This should yield a parsing + error.</para> + </glossdef> + </glossentry> + </glosslist> + </listitem> + + <listitem> + <para>The constructor <link + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address.html#Address(java.lang.String,%20int)">Address(...)</link> + does not yet parse address records but creates constant dummy + data instead. Use the parameter <code>csvRecord</code> to + actually initialize the desired address fields + <code>firstName</code>, <code>lastName</code>, ..., + <code>web</code>. Hint: You may use the <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-">split(...)</link> + method:</para> + + <programlisting language="java">... = s.split("\",\"");</programlisting> + + <para>This splits an input record into its address components. + The first component will however start with a quotation mark + like <code>"Aleshia</code> and the last component will have a + trailing <code>"</code> like in + <code>http://www.lbt.co.uk"</code>. You may use the + substring(...) method to get rid of them.</para> + </listitem> + + <listitem> + <para>You must exclude the header line (= first line of + addresses.txt) of your data source from result + generation:</para> + + <programlisting language="none">"firstName","lastName","companyName","address","city","county","postal","phone1","phone2","email","web"</programlisting> + </listitem> + + <listitem> + <para>Think of all syntax rules of your input data source + addresses.txt and throw <classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressParseError.html">AddressParseError</classname> + appropriate exceptions. Write test cases checking for correct + parsing error detection in input files.</para> + </listitem> + + <listitem> + <para>The current project produces text output. In order to + generate HTML you have to replace <classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2textFormatter.html">Address2textFormatter</classname> + by a new class <classname>Address2htmlFormatter</classname> + which implements the interface <classname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressFormatter.html">AddressFormatter</classname> + as well.</para> + + <para>You may then exchange your formatter in + <classname>Address2text</classname>.<methodname + xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2text.html#main(java.lang.String[])">main()</methodname>:</para> + + <programlisting language="java">final AddressFormatter htmlFormatter = new Address2htmlFormatter();</programlisting> + </listitem> + + <listitem> + <para>Address fields may contain the characters + <code><</code>, <code>></code> and <code>&</code>. + These will interfere with generated HTML markup. There are two + possible solutions:</para> + + <glosslist> + <glossentry> + <glossterm><acronym>CDATA</acronym> sections + (preferred):</glossterm> + + <glossdef> + <para>Wrap your output in <code><![CDATA[ ... + ]]></code> sections if required. Strictly speaking + this is only specified for XHTML variants but most + browsers will accept it anyway.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Using HTML replacement entities</glossterm> + + <glossdef> + <informaltable border="1" width="10%"> + <tr> + <td><code>&</code></td> + + <td><code>&amp;</code></td> + </tr> + + <tr> + <td><code><</code></td> + + <td><code>&lt;</code></td> + </tr> + + <tr> + <td><code>></code></td> + + <td><code>&gt;</code></td> + </tr> + </informaltable> + + <para>This requires textually replacing special + characters by the above entities e.g. by means of + <classname>String</classname>.<methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#replace-java.lang.CharSequence-java.lang.CharSequence-">replace(...)</methodname>.</para> + </glossdef> + </glossentry> + </glosslist> + </listitem> + + <listitem> + <para>Since you do generate HTML output renaming your class + <classname>Address2text</classname> to + <classname>Address2html</classname> is a good idea. Your + output might look like:</para> + + <programlisting language="none"><html xmlns='http://www.w3.org/1999/xhtml'> + <head> + <title>Address list:</title> + </head> + <body> + <h1>Address list:</h1> + <table border='1'> + <colgroup style='width: 20%'/> + <colgroup style='width: 30%'/> + <colgroup style='width: 25%'/> + <colgroup style='width: 25%'/> + <tr> + <th>Name</th> + <th>Address</th> + <th>Phone</th> + <th>E-Mail</th> + </tr> + ... + <tr> + <td>Graham <b>Stanwick</b></td> + <td><emphasis role="bold"><![CDATA[73 Hawkstone St, Renfrew South & Gallowhill War]]></emphasis>, <b>G52 4YG</b></td> + <td>01860-191930</td> + <td>gstanwick@gmail.com</td> + </tr> + <tr> + ... + + </tr> + </table> + </body> +</html></programlisting> + + <para>As you can see <acronym>CDATA</acronym> sections are + only used if embedded data does contain <, > or & + characters.</para> + </listitem> + + <listitem> + <para>You may direct your generated HTML output to a file + rather than to the standard output <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#out">System.out</link>. + This can be achieved by opening an output <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html">PrintStream</classname> + related to a file by means of the <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html#PrintStream-java.lang.String-">PrintStream</methodname> + output filename constructor. Your resulting output may + transform the file <filename>addresses.txt</filename> into + <filename>addresses.txt.xhtml</filename>. The latter should be + rendered like:</para> + + <informalfigure> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/addressHtml.png"/> + </imageobject> + </mediaobject> + </informalfigure> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/HtmlFormatting/Simple/Solution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1Collection4Exercise"> + <title>Collections IV, Exercises</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaImplementStringSet"> + <title>Implementing a set of strings</title> + + <qandadiv> + <qandaentry> + <question> + <para>We want to partly implement a simplified version of + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname>:</para> + + <programlisting language="java">package de.hdm_stuttgart.mi.sd1.stringset; + + +/** + * A collection of Strings that contains no duplicate elements. + * More formally, sets contain no pair of Strings s1 and s2 such that + * s1.equals(s2), and no null elements. As implied by its name, + * this class models the mathematical set abstraction. + * + * The StringSet class places stipulations on the contracts of the add, + * equals and hashCode methods. + * + * The stipulation on constructors is, not surprisingly, that all constructors + * must create a set that contains no duplicate elements (as defined above). + * + */ +public interface Set_String { + + /** + * Returns the number of strings in this set (its cardinality). + * + * @return the number of elements in this set (its cardinality) + */ + public int size() ; + + /** + * Returns true if this set contains no elements. + * + * @return true if this set contains no elements + */ + public boolean isEmpty(); + + /** + * Returns true if this set contains the specified element. More + * formally, returns true if and only if this set contains an + * element e such that (o==null ? e==null : o.equals(e)). + * + * @param o element whose presence in this set is to be tested + * @return true if this set contains the specified element. + * A null value will be treated as "not in set". + * + */ + public boolean contains(Object o); + + /** + * Returns an array containing all strings in this set. + * + * The returned array will be "safe" in that no references to it are + * maintained by this set. (In other words, this method allocates + * a new array). The caller is thus free to modify the returned array. + * + * @return an array containing all strings in this set. + */ + public String[] toArray(); + + /** + * Adds the specified element to this set if it is not already present. + * More formally, adds the specified element e to this set if the set + * contains no element e2 such that (e==null ? e2==null : e.equals(e2)). + * If this set already contains the element, the call leaves the set + * unchanged and returns false. In combination with the restriction on + * constructors, this ensures that sets never contain duplicate elements. + * + * null values will be discarded + * + * @param s string to be added to this set + * + * @return true if this set did not already contain the specified element. + * The attempted insert of a null value will return false. + */ + public boolean add(String s); + + /** + * Removes the specified string from this set if it is present + * (optional operation). More formally, removes a string s + * such that (o==null ? s==null : o.equals(s)), if this set + * contains such a string. Returns true if this set contained + * the string (or equivalently, if this set changed as a result + * of the call). (This set will not contain the string once the + * call returns.) + * + * @param s String to be removed from this set, if present. + * @return true if this set contained the specified string. + */ + public boolean remove(Object s); + + /** + * Removes all of the strings from this set (optional operation). + * The set will be empty after this call returns. + */ + public void clear(); +}</programlisting> + + <para>Implement this interface:</para> + + <programlisting language="java">public class MySet_String implements Set_String { + + /** + * Constructs a new, empty set; + */ + public MySet_String() { + ... + } + + /** + * Copy array values into this set excluding duplicates. + * + * @param source The array to copy values from + */ + public MySet_String(final String[] source) { + ... + } + + @Override + public int size() { + ... + } + ... +}</programlisting> + + <para>Hints:</para> + + <orderedlist> + <listitem> + <para>Store strings among with corresponding hash code values + in two separate arrays. You may use the <quote>amortized + doubling</quote> strategy from <xref + linkend="sd1IntStoreUnbounded"/> to accommodate arbitrary + numbers of instances.</para> + </listitem> + + <listitem> + <para>On lookup use hash code values prior to comparing via + <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#equals-java.lang.Object-">equals()</methodname> + in order to gain performance.</para> + </listitem> + </orderedlist> + + <para>Write appropriate tests to assure a sound + implementation.</para> + </question> + + <answer> + <annotation role="make"> + <para + role="eclipse">P/CollectionImplement/StringSet/Solution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + <section xml:id="sd1MapPrepare"> + <title>Maps 1, Preparations</title> + + <para>Read the introduction on <link + xlink:href="http://tutorials.jenkov.com/java-collections/map.html">Java + Collections - Map</link> and <link xlink:href="???">Java Collections - + SortedMap</link>.</para> + + <para>Consider the following array of person names:</para> + + <figure xml:id="sd1ArrayPersons"> + <title>An array of strings</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/array.fig"/> + </imageobject> + </mediaobject> + </figure> + + <para>Consider the following array describing (non leap year) month + lengths:</para> + + <figure xml:id="sd1MonthLength"> + <title>An associative array describing month lengths</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/arrayAssoc.fig"/> + </imageobject> + </mediaobject> + </figure> + </section> + + <section xml:id="sd1MapExercise"> + <title>Exercises</title> + + <para>In <xref linkend="sd1CollectionWordFrequencies"/> we created a + sorted set of words appearing in a text among with their respective + frequencies:</para> + + <programlisting language="none"> 6: Newton + 6: and + 5: Einstein + 3: Pascal + 3: found + 3: meter + 3: one + 3: to + 2: a +...</programlisting> + + <para>Achieving this result relied on implementing a helper class + <classname + xlink:href="Ref/api/P/WordFrequency1/Solution/de/hdm_stuttgart/mi/sd1/textstat/WordFrequency.html">WordFrequency</classname> + grouping words and frequencies:</para> + + <programlisting language="java">public class WordFrequency { + /** + * The frequency of this word will be counted. + */ + public final String word; + private int frequency; +...</programlisting> + + <para>A cleaner solution might conceive the above result output as a + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>>. + The set of words appearing in a text will be regarded as keys. The + frequencies of appearance are corresponding values:</para> + + <informaltable border="1" width="40%"> + <tr> + <th colspan="2"><classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>></th> + </tr> + + <tr> + <th>Word (<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>)</th> + + <th>Frequency (<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>)</th> + </tr> + + <tr> + <td>Newton</td> + + <td>6</td> + </tr> + + <tr> + <td>and</td> + + <td>6</td> + </tr> + + <tr> + <td>Einstein</td> + + <td>5</td> + </tr> + + <tr> + <td>Pascal</td> + + <td>3</td> + </tr> + + <tr> + <td>...</td> + + <td>...</td> + </tr> + </informaltable> + + <qandaset defaultlabel="qanda" xml:id="sde1QandaWordFreqMap"> + <title>Implementing word frequencies by <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>> + instances.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Re-implement <xref + linkend="sd1CollectionWordFrequencies"/> replacing your + <classname + xlink:href="Ref/api/P/WordFrequency1/Solution/de/hdm_stuttgart/mi/sd1/textstat/WordFrequency.html">WordFrequency</classname> + object by an instance of <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>>. + For the time being consider the output sorting order yet as + irrelevant.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/WordFrequency1/Solution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <para>The subsequent exercise is considered to be optional with respect + to the final course's examination. It does however provide some deeper + insight into the subject of <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname> + instances.</para> + + <qandaset defaultlabel="qanda" xml:id="sde1QandaWordFreqMapSortOrder"> + <title>Regain sorting capabilities.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Refine <xref linkend="sde1QandaWordFreqMap"/> to sort your + output by word frequencies in the first place as you already did + in <xref linkend="sd1CollectionWordFrequencies"/>.</para> + + <para>Hint: Following the discussion in <quote + xlink:href="http://stackoverflow.com/questions/11647889/sorting-the-mapkey-value-in-descending-order-based-on-the-value">Sorting + the Map<Key,Value> in descending order based on the + value</quote> you may create a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname><<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html">Entry</classname>(<<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>>> + from your <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>> + instance on demand (i.e. when sorting). Then define an + appropriate <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator</classname> + class to get this list sorted.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/WordFrequency2/Solution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + <section xml:id="sd1TownsByCountry"> + <title>Towns and country names</title> + + <figure xml:id="sd1FigTownsByCountry"> + <title>Grouping towns by country names</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/townsByCountry.fig"/> + </imageobject> + </mediaobject> + </figure> + </section> + <section xml:id="sd1MapMarks"> + <title>Creating an overview of grades</title> + + <para>Consider a text file representing a list of students among with + examination grades ranging from level <quote>A</quote> to + <quote>D</quote>:</para> + + <programlisting language="none">Tim Bone, D +Eve Thunder, A +Aaron King, B +Joan White, B +Mark Singer, C +Jane Simmonds, D +Ethan Clarke, C +Paula Beam, C</programlisting> + + <para>Duplicate names may appear.</para> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMarkFrequency"> + <title>Creating an overview of grades showing frequencies</title> + + <qandadiv> + <qandaentry> + <question> + <para>Transform the preceding text file into an overview of + grades by aggregating the occurrences of marks. The current + example should lead to:</para> + + <programlisting language="none">Overview of marks: +A: 1 +B: 2 +C: 3 +D: 2</programlisting> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Marks/Solution1</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMarkNames"> + <title>Creating an overview of grades showing individual names</title> + + <qandadiv> + <qandaentry> + <question> + <para>Replace the mark frequencies by the actual list of + alphabetically sorted names. The current example should lead + to:</para> + + <programlisting language="none">Overview of marks: +A: Eve Thunder +B: Aaron King, Joan White +C: Ethan Clarke, Mark Singer, Paula Beam +D: Jane Simmonds, Tim Bone</programlisting> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Marks/Solution2</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> +</chapter> diff --git a/Doc/Sd1/deployment.xml b/Doc/Sd1/deployment.xml new file mode 100644 index 0000000000000000000000000000000000000000..25eb2e51d2037e5affe82f0f502578e9c09142be --- /dev/null +++ b/Doc/Sd1/deployment.xml @@ -0,0 +1,418 @@ + <chapter xml:id="sd1Deploy" version="5.0" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Application deployment I (8.12.)</title> + + <section xml:id="sd1DeployPrepare"> + <title>Preparations</title> + + <para>Read <link + xlink:href="http://www.cs.swarthmore.edu/~newhall/unixhelp/debuggingtips_Java.html">http://www.cs.swarthmore.edu/~newhall/unixhelp/debuggingtips_Java.html</link> + up to including the <quote>The <code>CLASSPATH</code> environment + variable and JAR files</quote> section.</para> + </section> + + <section xml:id="sda1DeployExercise"> + <title>Exercises</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaArrayVarious"> + <title>Various integer array algorithms</title> + + <qandadiv> + <qandaentry> + <question> + <para>The Maven Java project archive <link + xlink:href="Ref/api/P/Array/arraycalcExercise/eclipse.zip">eclipse.zip</link> + contains a series of yet unimplemented methods and corresponding + tests. The following hints may help you completing the + implementation</para> + + <glosslist> + <glossentry> + <glossterm><link + xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#swap(int[],%20int[])">swap</link></glossterm> + + <glossdef> + <para>This effectively requires extending the concept of + swapping just two integer values within a block</para> + + <programlisting language="java"> int a = 3, b = 5; + + // Other code ... + + {// Swap values of a and b + final int tmp = a; + a = b; + b = tmp; + } </programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><link + xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#isPalindrome(java.lang.String)">isPalindrome</link></glossterm> + + <glossdef> + <para>Consider a two step implementation:</para> + + <orderedlist> + <listitem> + <para>Normalize a given palindrome candidate by + transforming to lower case and erasing + non-letters:</para> + + <para><code>Hey, Roy! Am I mayor? Yeh!</code> --> + <code>heyroyamimayoryeh</code></para> + + <para>You may search the <xref linkend="glo_API"/> of + class <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Character.html">Character</classname> + assisting you to distinguish letters from + non-letters.</para> + </listitem> + + <listitem> + <para>Check the remaining string for being a + palindrome.</para> + </listitem> + </orderedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><link + xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#containsSameElements(int[],%20int[])">containsSameElements</link></glossterm> + + <glossdef> + <para>You may copy <code>int[] b</code> array to a + <quote>shadow</quote> array and then subsequently erase + all elements of <code>int[] a</code> from this copy. The + method <link + xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#findIndex(int[],%20int)">findIndex</link> + is quite helpful.</para> + + <para>Consider for example <code>int[] bCopy = {1, 3, 4, + 3, 7}</code> containing 5 elements. Suppose our array + <code>a</code> contains the value 3 which exists at index + position 1 in <code>bCopy</code>. We may override the + value index position 1 by the last array value 7 and + thereby keeping track of reducing the number of array + elements to 4 like {1, 7, 4, 3}.</para> + + <para>Off course the array <code>bCopy</code> cannot + shrink. But we may introduce an integer variable to + account for the effective number of array elements still + to be considered. If and only if all elements from + <code>a</code> are subsequently found within + <code>bCopy</code> the two arrays <code>a</code> and + <code>b</code> are equal.</para> + </glossdef> + </glossentry> + </glosslist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Array/arraycalcSolution</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + <section xml:id="sd1AppDeploy2Exercise"> + <title>Part II, Exercises</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMedianCmdline"> + <title>A command line version computing a sample's average and + median</title> + + <qandadiv> + <qandaentry> + <question> + <para>This exercise extends <xref linkend="sd1StoreStatistics"/> + by adding a command line interface. Consider the following + console execution:</para> + + <programlisting language="none">goik >java -jar statistics-1.0.jar 2 6 7 +Your sample's average is: 5.0 +Your sample's median is: 6.0</programlisting> + + <para>The above example executes our Java program in a shell and + supplies three command line parameters 2, 6 and 7. The program + then executes and creates the desired statistical data.</para> + + <para>The subsequent remarks may assist you creating an + implementation:</para> + + <orderedlist> + <listitem xml:id="sd1OlMedianCmdLineStep1"> + <para>Using command line values means entering strings + rather then e.g. integer values: In the current example the + Java runtime will pass an array of strings <code>{"2", "6", + "7"}</code> on behalf of the user's input <quote><code>2 6 + 7</code></quote> to your <code>main(String [] args)</code> + method. These strings must be converted to integer values. + This may be achieved by means of <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#parseInt-java.lang.String-">parseInt(String)</methodname>.</para> + + <para>Depending on inconsistent user input like + <quote><code>three</code></quote> instead of + <quote><code>3</code></quote> you may decide to terminate + your application thereby providing a meaningful error + message:</para> + + <programlisting language="none">goik >java -jar statistics-1.0.jar 1 2 three +Input string 'three' does not represent an integer value</programlisting> + </listitem> + + <listitem> + <para>If the user does not provide any input at all our + program shall terminate as well:</para> + + <programlisting language="none">goik >java -jar statistics-1.0.jar +No values provided</programlisting> + </listitem> + + <listitem> + <para>Provide an <classname>public enum + ErrorState</classname> definition representing all three + possible error states:</para> + + <glosslist> + <glossentry> + <glossterm><code>OK</code>:</glossterm> + + <glossdef> + <para>No error, all user input strings represent + integer values.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><code>NO_VALUE</code>:</glossterm> + + <glossdef> + <para>Error: No user input at all.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><code>NO_INTEGER</code>:</glossterm> + + <glossdef> + <para>Error: At least one input value does not + represent an integer value.</para> + </glossdef> + </glossentry> + </glosslist> + </listitem> + + <listitem> + <para>Implement a class + <classname>InputValidator</classname> to validate user input + and thereby converting string values to an integer array of + equal size:</para> + + <programlisting language="java">/** + * Validate sample input strings and convert + * them to integer values. + */ +public class InputValidator { + + /** + * Integer values being calculated upon + * constructor call. + */ + public final int[] values; + + /** + * Transform a series of strings into integer values. In case + * of invalid input, a corresponding error messsage will be written + * to System.err and the current application will terminate by calling + * {@link System#exit(int)}. Example: The array ["-1", "20", "three"] + * contains two valid elements and the invalid element "three" which + * cannot be converted to an integer value by virtue of + * {@link Integer#parseInt(String)}. + * + * @param userInput A set of strings possibly representing integer values. + */ + public InputValidator(final String[] userInput) {...} +}</programlisting> + + <para>You may then create an instance by supplying your + <code>main(String[] args)</code> command line values:</para> + + <programlisting language="java"> public static void main(String[] args) { + + final InputValidator userInput = new InputValidator(args); +...</programlisting> + + <para>Choose your implementation with testing in + mind.</para> + </listitem> + + <listitem> + <para>Write at least one test case for all three possible + error categories and check for correct behaviour of your + <classname>InputValidator</classname> class.</para> + </listitem> + + <listitem> + <para>Use your class <classname + xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html">IntegerStore</classname> + from exercise <xref linkend="sd1StoreStatistics"/> to + compute the desired output.</para> + </listitem> + + <listitem> + <para>Simulating command line arguments in <xref + linkend="glo_Eclipse"/> requires a run time configuration. + Click <guimenu>Run</guimenu> <guimenuitem>Run + Configurations...</guimenuitem>. Choose <quote>Java + Applications</quote> and "new launch configuration" from the + panel's left side, choose your project and main class (if + not already selected).</para> + + <screenshot> + <info> + <title>Defining an Eclipse runtime configuration</title> + </info> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/runconfigSelectClass.png"/> + </imageobject> + </mediaobject> + </screenshot> + + <para>Select the <guimenu>Arguments</guimenu> tab. Enter + your desired command line values, hit + <guibutton>Apply</guibutton> and subsequently + <guibutton>Run</guibutton> to launch your + application.</para> + + <screenshot> + <info> + <title>Defining an Eclipse runtime configuration</title> + </info> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/runconfigDefineArgs.png"/> + </imageobject> + </mediaobject> + </screenshot> + </listitem> + + <listitem> + <para>Maven projects allow for creation of executable jar + archives. This leverages the process being described in + <link + xlink:href="http://www.skylit.com/javamethods/faqs/createjar.html">Creating + an Executable jar File</link>. It avoids messing with + manifest files and zipping up archives manually.</para> + + <para>Among several configuration possibilities you may use + the <link + xlink:href="http://maven.apache.org/plugins/maven-jar-plugin">Maven + JAR Plugin</link> and its <option + xlink:href="http://maven.apache.org/plugins/maven-jar-plugin/usage.html#How_to_build_a_JAR_file">package</option> + goal. You have to add this plugin to the <tag + class="starttag">plugins</tag> section of your + <filename>pom.xml</filename> file. The plugin in turn + requires defining the fully qualified name of your entry + class <coref linkend="sd1CaPomFqnMainEntryClass"/> + containing the desired <methodname>main(String[] + args)</methodname> method:</para> + + <programlisting language="xml">... +<properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <javadocDestdir>~/tmp</javadocDestdir> +</properties> + +<build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>2.4</version> + <configuration> + <archive> + <manifest> + <addClasspath>true</addClasspath> +<emphasis role="bold"> <mainClass>de.hdm_stuttgart.mi.sd1.statistics.main.Statistics</mainClass></emphasis> <co + xml:id="sd1CaPomFqnMainEntryClass"/> + </manifest> + </archive> + </configuration> + </plugin> + </plugins> +</build> +...</programlisting> + + <para>Creating the actual jar archive may be triggered by + either of:</para> + + <glosslist> + <glossentry> + <glossterm>From the command line:</glossterm> + + <glossdef> + <para>Change to your project root containing your + <filename>pom.xml</filename> file and execute + <command>mvn</command> + <option>package</option>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>From inside <xref + linkend="glo_Eclipse"/>:</glossterm> + + <glossdef> + <para>Create a maven run time configuration (see + above) containing your <option>package</option> + goal:</para> + + <screenshot> + <info> + <title>Creating a Maven runtime configuration + corresponding to the <option>package</option> + goal</title> + </info> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/runconfigMavenGoalPackage.png"/> + </imageobject> + </mediaobject> + </screenshot> + </glossdef> + </glossentry> + </glosslist> + + <para>After creating the jar archive you may now run your + program in a shell as being described in <xref + linkend="sd1OlMedianCmdLineStep1"/> of this section.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Array/medianCmdLine</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </chapter> + diff --git a/Doc/Sd1/identity.xml b/Doc/Sd1/identity.xml new file mode 100644 index 0000000000000000000000000000000000000000..6d01a3b5ecffc82044f72434ef3af1f1f869ac45 --- /dev/null +++ b/Doc/Sd1/identity.xml @@ -0,0 +1,203 @@ + <chapter xml:id="sd1IdentEqual" version="5.0" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Object identity and equality (3.12.)</title> + + <section xml:id="sec_PrepareOidEquality"> + <title>Preparations</title> + + <para>Read all sections of chapter 6 in <xref linkend="bib_Horton2011"/> + till and including <quote>THE UNIVERSAL SUPERCLASS</quote>.</para> + </section> + + <section xml:id="sd1String2Exercises"> + <title>Exercises</title> + + <section xml:id="pitfallsUsingOperatorEquals"> + <title>Pitfalls using operator <quote>==</quote></title> + + <qandaset defaultlabel="qanda" xml:id="qandaStringOperatorEquals"> + <title>String instances and equality</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following fragment:</para> + + <programlisting language="java">public static void main(String[] args) { + + final String a1 = "TestA", a2 = "TestA"; + System.out.println(" a1 == a2: " + (a1 == a2)); + + final String b1 = new String("TestB"), b2 = new String("TestB"); + System.out.println("b1 == b2: " + (b1 == b2)); +}</programlisting> + + <para>Execute this code and explain the resulting + output.</para> + + <para>Hints: Read the documentation of <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#identityHashCode-java.lang.Object-">System.identityHashCode(Object + o)</link> and <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">Object.hashCode()</link>.</para> + </question> + + <answer> + <para>Execution yields:</para> + + <programlisting language="none">a1 == a2: true <co + linkends="answerCoStringOperatorEquality-1" + xml:id="answerCoStringOperatorEquality-1-co"/> +b1 == b2: false <co linkends="answerCoStringOperatorEquality-2" + xml:id="answerCoStringOperatorEquality-2-co"/></programlisting> + + <calloutlist> + <callout arearefs="answerCoStringOperatorEquality-1-co" + xml:id="answerCoStringOperatorEquality-1"> + <para>This effectively compares two string literals + <code>"TestA"</code> and <code>"TestA"</code>. The <xref + linkend="glo_JDK"/> compiler implementation allocates only + one instance of class String for all string literals + having identical content. So all string literals "TestA" + (even if existing in different classes or packages) + represent the same object. Thus the two distinct variables + <code>a1</code> and <code>a2</code> are being assigned an + identical reference pointing to this unique instance. + Comparing identical references by the operator == always + yields true. You might as well write:</para> + + <programlisting language="java">System.out.println(<emphasis + role="bold">"TestA".equals("TestA")</emphasis>);</programlisting> + + <para>The method <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#identityHashCode-java.lang.Object-">System.identityHashCode(Object + o)</link> returns <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">Object.hashCode()</link> + rather then <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode--">String.hashCode()</link>. + This hash code from <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html">java.lang.Object</link> + has a one to one correspondence to an object's reference + and thus helps to understand the underlying object + references of our current example:</para> + + <programlisting language="java">System.out.println("Hashcode a1 == " + System.identityHashCode(a1) + + ", Hashcode a2 == " + System.identityHashCode(a2));</programlisting> + + <para>This yields identical values showing that + <code>a1</code> and <code>a2</code> point to the same + instance:</para> + + <programlisting language="none">Hashcode a1 == 366712642, Hashcode a2 == 366712642</programlisting> + </callout> + + <callout arearefs="answerCoStringOperatorEquality-2-co" + xml:id="answerCoStringOperatorEquality-2"> + <para>Every call to a constructor will create a new object + regardless of internal state. Thus <code>b1</code> and + <code>b2</code> will hold two distinct references pointing + to different String instances albeit these two instances + contain identical values. Following the above reasoning we + may execute:</para> + + <programlisting language="java">System.out.println("Hashcode b1 == " + System.identityHashCode(b1) + + ", Hashcode b2 == " + System.identityHashCode(b2));</programlisting> + + <para>This yields values corresponding to two different + object references:</para> + + <programlisting language="none">Hashcode b1 == 1829164700, Hashcode b2 == 2018699554</programlisting> + + <para>Comparing these two values for equality via the + <quote>==</quote> operator thus returns the boolean value + <code>false</code>.</para> + </callout> + </calloutlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1GomeOfLifeLogic"> + <title>Implementing <quote>Game of Life</quote> logic</title> + + <para>We complete our previous exercise by implementing the rules + governing cells being born, dying or just continue existing.</para> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaGameOfLifeLogic"> + <title>Implementing <quote>Game of Life</quote> logic.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implementing cells being born and dying requires several + steps. The following sketch outlines one of different ways to + achieve this goal.</para> + + <orderedlist> + <listitem> + <para>Each cell is in exactly one of two distinct states + <quote>dead</quote> or <quote>alive</quote>. Though it is + possible to use a boolean for this purpose a dedicated + <classname>enum CellState {...}</classname> definition is + in order here to improve your code's readability.</para> + </listitem> + + <listitem> + <para>Read the documentation of the two different + <methodname>act()</methodname> methods being defined in + <link + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/World.html#act()">World</link> + and <link + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/Actor.html#act()">Actor</link>. + You'll learn about the temporal order in which these are + being invoked by the <productname>Greenfoot</productname> + <xref linkend="glo_framework"/>.</para> + </listitem> + + <listitem> + <para>The rules governing life or death in the next step + have to be applied to each individual cell. Consider two + isolated neighboring cells A and B both being in live + state: Both cells do have exactly one living neighbor. + When A dies in the next step B does no longer have any + living neighbor.</para> + + <para>But it would be wrong to calculate B's following + state based on this assumption. Thus we need to keep a + record of A's current state as long as the computation for + <emphasis role="bold">all</emphasis> cells has been + finished. This effectively requires keeping track of each + cell's <quote>current</quote> and <quote>next</quote> + state. The two different act() methods mentioned earlier + provide a clue setting these two states + accordingly.</para> + </listitem> + + <listitem> + <para>Each cell needs to have a reference to its neighbors + for calculation its subsequent state. Since our world is + limited (in contrast to Conway's assumption) we have to + deal with cells existing at our world's edges having fewer + neighbors as well.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/life/V3</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + </chapter> diff --git a/Doc/Sd1/loop.xml b/Doc/Sd1/loop.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f5c408b9a433fa2207331f2186186593865075d --- /dev/null +++ b/Doc/Sd1/loop.xml @@ -0,0 +1,2362 @@ + <chapter xml:id="sd1Loop" version="5.0" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Loops</title> + + <section xml:id="sd1LoopPrepare"> + <title>Preparations</title> + + <para>Chapter <quote>Loops and logic</quote> <xref + linkend="bib_Horton2011"/> till <quote>Loops</quote> (inclusive).</para> + </section> + + <section xml:id="sd1LoopExercises"> + <title>Exercises</title> + + <section xml:id="sd1LeapYera"> + <title>Leap years</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaLeapYear"> + <title>Distinguishing leap- and non-leap years</title> + + <qandadiv> + <qandaentry> + <question> + <para>Look up the Gregorian calendar rule for leap years. Then + implement the following method to decide whether a given year + is a leap year:</para> + + <programlisting language="java"> /** + * Characterizing a given year either as leap year or + * non- leap year + * + * @param year The year in question. + * @return true if the year parameter is a leap year, false otherwise. + */ + public static boolean isLeapYear(int year) { + ... + }</programlisting> + + <para>You should be able to test your implementation the + following way:</para> + + <programlisting language="java"> public static void main(String[] args) { + System.out.println("Is 1800 a leap year? " + isLeapYear(1800)); + System.out.println("Is 2000 a leap year? " + isLeapYear(2000)); + System.out.println("Is 2016 a leap year? " + isLeapYear(2016)); + }</programlisting> + + <para>This should produce the following output:</para> + + <programlisting language="ignore">Is 1800 a leap year? false +Is 2000 a leap year? true +Is 2016 a leap year? true</programlisting> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/rounding</para> + </annotation> + + <para>A first solution may be:</para> + + <programlisting language="java"> <link + xlink:href="Ref/api/P/rounding//de/hdm_stuttgart/de/sd1/leap/LeapYear.html#isLeapYear-int-">public static boolean isLeapYear(int year)</link> { + if (year % 400 == 0) { // Every 400 years we do have a leap year. + return true; + } else if (year % 4 == 0 && 0 != year % 100) { // Every 4 years we do have a leap year unless the year + return true; // in question is a multiple of 100. + } else { + return false; + } + }</programlisting> + + <para>This one is easy to read. Experienced programmers + however prefer compact code:</para> + + <programlisting language="java"> <link + xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/leap/LeapYearCompact.html#isLeapYear-int-">public static boolean isLeapYear(int year)</link> { + return + year % 400 == 0 || // Every 400 years we do have a leap year. + year % 4 == 0 && 0 != year % 100; // Every 4 years we do have a leap year unless the year + // in question is a multiple of 100. + } </programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1SummingUpIntegers"> + <title>Summing up integer values</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSumInteger"> + <title>Summing up integers to a given limit</title> + + <qandadiv> + <qandaentry> + <question> + <para>Suppose an arbitrary number n is given e.g n=5. We want + to compute the sum of all integers ranging from 1 to 5:</para> + + <para>1 + 2 + 3 + 4 + 5 = 15</para> + + <para>Implement the following method by using a loop:</para> + + <programlisting language="java"> /** + * Summing up all integers up to and including a given limit + * Example: Let the limit be 5, then the result is 1 + 2 + 3 + 4 + 5 + * + * @param limit The last number to include into the computed sum + * @return The sum of 1 + 2 + ... + limit + */ + public static long getSum (int limit) { + ... + }</programlisting> + + <para>You may test your implementation by:<programlisting + language="java"> public static void main(String[] args) { + System.out.println("1 + 2 + ... + 150" + "=" + getSum(150)); + }</programlisting><parameter>Actually a loop is not needed + since:</parameter></para> + + <informalequation> + <m:math display="block"> + <m:mrow> + <m:mrow> + <m:munderover> + <m:mo>∑</m:mo> + + <m:mrow> + <m:mi>i</m:mi> + + <m:mo>=</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + + <m:mi>n</m:mi> + </m:munderover> + + <m:mi>i</m:mi> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mfrac> + <m:mrow> + <m:mi>n</m:mi> + + <m:mo>â¢</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>n</m:mi> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </informalequation> + + <para>You may use this formula to verify your + implementation.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/rounding</para> + </annotation> + + <para>We just need a single loop in <link + xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/sum/Summing.html#getSum-int-">getSum(...)</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1RewriteLoop"> + <title>Rewriting a loop</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaRewriteLoop"> + <title><code>for</code>, <code>while</code> and <code>do</code> ... + <code>while</code></title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following example:</para> + + <programlisting language="java">public class LoopExample { + + public static void main(String [] args) { + squareNumbers(14); + } + + /** + * Compute all square numbers starting from 4 in steps of 3 + * being smaller than a given limit. The results are being written to standard output. + * Implemented by a for -loop. + * + * @param limit An upper exclusive bound for the highest number to be squared.. + */ + public static void squareNumbers(final int limit) { + System.out.println("Computing square numbers"); + for (int i = 4; i < limit; i += 3) { + System.out.println("i = " + i + ", i * i = " + i * i); + } + System.out.println("Finished computing square numbers"); + } +}</programlisting> + + <para>Re-implement the above code two times as:</para> + + <orderedlist> + <listitem> + <para>while loop:</para> + + <programlisting language="java"> ... + public static void while_squareNumbers(final int limit) { + System.out.println("Computing square numbers"); +... + while (...) { +... + } + System.out.println("Finished computing square numbers"); + } ...</programlisting> + </listitem> + + <listitem> + <para>do ... while loop:</para> + + <programlisting language="java"> ... + public static void while_squareNumbers(final int limit) { + System.out.println("Computing square numbers"); +... + do { +... + } while(...); + + System.out.println("Finished computing square numbers"); + } ...</programlisting> + </listitem> + </orderedlist> + + <para>Caveat: The do ... while part is a little bit tricky. + Read the method's documentation <emphasis><emphasis + role="bold">precisely</emphasis></emphasis> to avoid a common + pitfall.</para> + + <para>Do you have a comment choosing the right type of + loop?</para> + </question> + + <answer> + <para>The while loop is actually quite straightforward to + implement:</para> + + <programlisting language="java">public class <link + xlink:href="Ref/api/P/loop/answer/de/hdm_stuttgart/de/sd1/loop/LoopExample.html">LoopExample</link> { + ... + public static void <link + xlink:href="Ref/api/P/loop/answer/de/hdm_stuttgart/de/sd1/loop/LoopExample.html#doWhile_squareNumbers-int-">while_squareNumbers(final int limit)</link> { + System.out.println("Computing square numbers"); + int i = 4; + while (i < limit) { + System.out.println("i = " + i + ", i * i = " + i * i); + i += 3; + } + System.out.println("Finished computing square numbers"); + } ...</programlisting> + + <para>Its tempting to implement a <code>do ... while</code> in + a similar fashion:</para> + + <programlisting language="java">public class LoopExample { + ... + public static void doWhile_squareNumbers(final int limit) { + System.out.println("Computing square numbers"); + int i = 4; + do { + System.out.println("i = " + i + ", i * i = " + i * i); + i += 3; + } while (i < limit); + System.out.println("Finished computing square numbers"); + } ...</programlisting> + + <para>This implementation however is flawed: If we call + doWhile_squareNumbers(3) we still receive one line of output. + But according to the documentation no output is to be + expected. Whatever the argument is, at least one output line + gets printed. To avoid this error the loop has to be enclosed + by an if- statement:</para> + + <programlisting language="java"> public static void <link + xlink:href="Ref/api/P/loop/answer/de/hdm_stuttgart/de/sd1/loop/LoopExample.html#doWhile_squareNumbers-int-">doWhile_squareNumbers</link>(final int limit) { + System.out.println("Computing square numbers"); + int i = 4; + if (i < limit) { // Needed !!! + do { + System.out.println("i = " + i + ", i * i = " + i * i); + i += 3; + } while (i < limit); + } + System.out.println("Finished computing square numbers"); + }</programlisting> + + <para>This required if-clause reminds us that a <code>do {...} + while (...)</code> is an ill-suited choice here in comparison + to a <code>while(...){...}</code> or a + <code>for(...){...}</code> loop.</para> + + <para>Actually a <code>for(...){...} loop is the best choice + here since the number of iterations is known in advance, the + increment is constant and it allows for + initialization</code>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1MathTable"> + <title>A mathematical table.</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSinTable"> + <title>Nicely formatting sine values.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We are interested in the following output presenting the + sine function rounded to three decimal places:</para> + + <programlisting language="ignore"> x | sin(x) +----+------ + 0 | 0.000 + 5 | 0.087 + 10 | 0.174 + 15 | 0.259 + 20 | 0.342 +----+------- + 25 | 0.423 + 30 | 0.500 + 35 | 0.574 + 40 | 0.643 +----+------- +... (left out for brevity's sake) +----+------- +325 |-0.574 +330 |-0.500 +335 |-0.423 +340 |-0.342 +----+------- +345 |-0.259 +350 |-0.174 +355 |-0.870</programlisting> + + <para>You may also generate HTML output.</para> + + <para>Write a corresponding Java application producing this + output. You will have to deal with alignment problems, leading + spaces, padding zeros and so on. Though more sophisticated + support exists the following hints will fully suffice:</para> + + <orderedlist> + <listitem> + <para>Consider the <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sin-double-">sin(...)</link> + function. The documentation will tell you that the + argument to sin(...) is expected to be in radians rather + than common degree values from [0,360[ being expected on + output. So you will have to transform degree values to + radians.</para> + </listitem> + + <listitem> + <para>Depending on the angle's value you may want to add + one or two leading spaces to keep the first column right + aligned.</para> + </listitem> + + <listitem> + <para>Depending on the sign you may want to add leading + spaces to the second column.</para> + </listitem> + + <listitem> + <para>Rounding the sine's value is the crucial part here. + The function <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-">round()</link> + is quite helpful. Consider the following example rounding + 23.22365 to four decimal places:</para> + + <orderedlist> + <listitem> + <para>Multiplication by 10000 results in + 232236.5</para> + </listitem> + + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-">round(232236.5)</link> + results in 232237 (long).</para> + </listitem> + + <listitem> + <para>Integer division by 10000 yields 23</para> + </listitem> + + <listitem> + <para>The remainder (by 10000) is 2237</para> + </listitem> + + <listitem> + <para>So you may print 23.2237 this way</para> + </listitem> + </orderedlist> + </listitem> + + <listitem> + <para>You'll need padding zero values to transform e.g. + <quote>0.4</quote> to <quote>0.400</quote>.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/rounding</para> + </annotation> + + <para>See <link + xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/rounding/MathTable.html">MathTable</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + <section xml:id="sd1Gcd"> + <title>Loops II, The greatest common divisor and the common multiple</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaGcd"> + <title>Finding the greatest common divisor of two integer + values</title> + + <qandadiv> + <qandaentry> + <question> + <para>We recall <xref linkend="sde1QandaFraction"/>. So far no + one demands fractions to be kept in maximally reduced state. The + call new Fraction(4,8) will create an instance internally being + represented by <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>4</m:mi> + + <m:mi>8</m:mi> + </m:mfrac> + </m:math> + </inlineequation> rather than by <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>1</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:math> + </inlineequation>.</para> + + <para>Reducing fractions requires a loop implementing e.g. the + <link + xlink:href="http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html">Euclidean + algorithm</link> in order to find the greatest common divisor + (<acronym>GCD</acronym>) of two non-zero integer values.</para> + + <para>Read the above link and implement a private class method + getGcd(long, long) inside a class + <classname>Math</classname>:</para> + + <programlisting language="java"> public static long getGcd(long a, long b) <co + xml:id="sd1ListEuclidNeg"/> { + // Following http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html + return ??; + }</programlisting> + + <para>With respect to fractions one or both parameters + <code>a</code> and <code>b</code> <coref + linkend="sd1ListEuclidNeg"/> may zero or negative. So we do have + several special cases to handle:</para> + + <glosslist> + <glossentry> + <glossterm>a == 0 and b == 0</glossterm> + + <glossdef> + <para>Return 1.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>a == 0 and b != 0</glossterm> + + <glossdef> + <para>Return absolute value of b.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>a != 0 and b != 0</glossterm> + + <glossdef> + <para>Return the <acronym>gcd</acronym> of the absolute + values of a and b</para> + </glossdef> + </glossentry> + </glosslist> + + <para>Based on <methodname>getGcd(...)</methodname> implement + the common multiple of two long values:</para> + + <programlisting language="java">public static long getCommonMultiple(long a, long b) {...}</programlisting> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Gcd/V1</para> + </annotation> + + <para>Implementing <methodname + xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getGcd-long-long-">getGcd(</methodname>...):</para> + + <programlisting language="java"> public static long <link + xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getCommonMultiple-long-long-">getGcd(long a, long b)</link> { + + // Following http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html + if (a < b) { // Swap the values of a and b + long tmp = a; + a = b; + b = tmp; + } + while (0 != b) { + long r = a % b; + a = b; + b = r; + } + return a; + }</programlisting> + + <para>Knowing the the <acronym>gcd</acronym> of two values a and + b the common multiple may be obtained by <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mfrac> + <m:mi>a</m:mi> + + <m:mi>gcd</m:mi> + </m:mfrac> + + <m:mo>â¢</m:mo> + + <m:mfrac> + <m:mi>b</m:mi> + + <m:mi>gcd</m:mi> + </m:mfrac> + + <m:mo>â¢</m:mo> + + <m:mi>gcd</m:mi> + + <m:mo>=</m:mo> + + <m:mfrac> + <m:mrow> + <m:mi>a</m:mi> + + <m:mo>â¢</m:mo> + + <m:mi>b</m:mi> + </m:mrow> + + <m:mi>gcd</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </inlineequation>. Thus we have:</para> + + <programlisting language="java"> public static long <link + xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getGcd-long-long-">getCommonMultiple(long a, long b)</link> { + final long gcd = getGcd(a, b); + if (1 == gcd) { + return a * b; + } else { + return (a / gcd) * b; + } + }</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="ed1FractionCancel"> + <title>Reducing fractions</title> + + <para>The following exercise requires the import of the previous Maven + based exercise <xref linkend="sd1QandaGcd"/>. The import may be effected + by:</para> + + <orderedlist> + <listitem> + <para>Creating a local Maven jar archive export by executing + <quote><command>mvn</command> <option>install</option></quote> in + project <xref linkend="sd1QandaGcd"/> at the command line. + Alternatively you may right click on your <xref + linkend="glo_pom.xml"/> file in <xref linkend="glo_Eclipse"/> + hitting <quote>Run as Maven build</quote> using + <parameter>install</parameter> as goal.</para> + </listitem> + + <listitem> + <para>Defining <xref linkend="sd1QandaGcd"/> as a dependency <coref + linkend="mvnGcdDep"/> in your current project:</para> + + <programlisting language="none"><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> + + <groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>fraction</artifactId> + <version>1.0</version> + <packaging>jar</packaging> + + <name>fraction</name> + ... + <dependencies> + <emphasis role="bold"><dependency></emphasis> <co xml:id="mvnGcdDep"/> + <emphasis role="bold"><groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>gcd</artifactId> + <version>1.0</version> + <scope>compile</scope> + </dependency></emphasis> + <dependency> + <groupId>junit</groupId> + ... + </dependency> + </dependencies> +</project></programlisting> + </listitem> + </orderedlist> + + <figure xml:id="figMavenProjectDependency"> + <title>Defining a dependency to another Maven artifact.</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Svg/mavenPrjRef.svg"/> + </imageobject> + </mediaobject> + </figure> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaFractionCancel"> + <title>Implementing reducing of fractions</title> + + <qandadiv> + <qandaentry> + <question> + <para>We have implemented <acronym>GCD</acronym> computation in + <xref linkend="sd1QandaGcd"/>. The current exercises idea is to + implement reducing of fractions by using the method + <methodname>long getGcd(long a, long b)</methodname>. Change the + following implementation items:</para> + + <itemizedlist> + <listitem> + <para>The constructor should reduce a fraction if required, + see introductory remark.</para> + </listitem> + + <listitem> + <para>The Methods <methodname>mult(...)</methodname> and + <methodname>add(...)</methodname> should reduce any + resulting Fraction instance. It might be worth to consider a + defensive strategy to avoid unnecessary overflow + errors.</para> + </listitem> + </itemizedlist> + + <para>Test your results.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/fraction/V2</para> + </annotation> + + <para>Modifying the constructor is straightforward: On creating + a fraction we simply divide both numerator and denominator by + the <acronym>GCD</acronym> value:</para> + + <programlisting language="java"> <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#Fraction-long-long-">public Fraction(long numerator, long denominator)</link> { + final long gcd = Math.getGcd(numerator, denominator); + + setNumerator(numerator / gcd); + setDenominator(denominator / gcd); + }</programlisting> + + <para>Its tempting to implement + <methodname>mult(...)</methodname> in a simple fashion:</para> + + <programlisting language="java"> public Fraction mult2(Fraction f) { + return new Fraction(numerator * f.numerator, + denominator * f.denominator); + }</programlisting> + + <para>This is however too shortsighted. Consider the example + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mfrac> + <m:mi>4</m:mi> + + <m:mi>7</m:mi> + </m:mfrac> + + <m:mo>â¢</m:mo> + + <m:mfrac> + <m:mi>3</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </inlineequation>. Our simple implementation proposal would + call <code>new Fraction(12, 14)</code> only to discover a + <acronym>GCD</acronym> value of 4. Having larger argument values + this might cause an unnecessary overflow. Moreover the + <acronym>GCD</acronym> calculation will take longer than + needed.</para> + + <para>We may instead transform the term in question by + exchanging the numerators like <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mfrac> + <m:mi>3</m:mi> + + <m:mi>7</m:mi> + </m:mfrac> + + <m:mo>â¢</m:mo> + + <m:mfrac> + <m:mi>4</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </inlineequation> to enable reducing <emphasis + role="bold">prior</emphasis> to multiplying. Now the call + <code>new Fraction(4,2)</code> will construct the representation + <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>2</m:mi> + + <m:mi>1</m:mi> + </m:mfrac> + </m:math> + </inlineequation> and finishing the computation will yield the + correct result <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>6</m:mi> + + <m:mi>7</m:mi> + </m:mfrac> + </m:math> + </inlineequation>. We should thus implement:</para> + + <programlisting language="java"> public Fraction <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#mult-de.hdm_stuttgart.mi.sd1.fraction.Fraction-">mult(Fraction f)</link> { + final Fraction f1 = new Fraction(f.numerator, denominator), + f2 = new Fraction(numerator, f.denominator); + + return new Fraction(f1.numerator * f2.numerator, + f1.denominator * f2.denominator); + }</programlisting> + + <para>Similar reflections lead to the clue decomposing the + denominators when implementing + <methodname>add(...)</methodname>. This is what you'd do as well + if your task was adding two fractions by hand trying to avoid + large numbers:</para> + + <programlisting language="java"> public Fraction <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#add-de.hdm_stuttgart.mi.sd1.fraction.Fraction-">add(Fraction f)</link> { + + final long gcd = Math.getGcd(denominator, f.denominator); + + return new Fraction( numerator * (f.denominator / gcd) + (denominator / gcd) * f.numerator, + (denominator / gcd) * f.denominator); + }</programlisting> + + <para>See complete <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html">implementation + here</link>. We may re-use out test:</para> + + <programlisting language="java"> public static void <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Driver.html#main-java.lang.String:A-">main(String[] args)</link> { + + // Input + final Fraction + twoThird = new Fraction(2, 3), // Construct a fraction object (2/3) + threeSeven = new Fraction(3, 7); // Construct a fraction object (3/7) + + // Computed results + final Fraction + sum = twoThird.add(threeSeven), // (2/3) + (3/7) + product = twoThird.mult(threeSeven); // (2/3) * (3/7) + + System.out.println("(2/3) + (3/7) = (23/21) = " + sum.getValue()); + System.out.println("(2/3) * (3/7) = (2/7) = " + product.getValue()); + }</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1MathMaxAbs"> + <title>Building a private library of mathematical functions.</title> + + <para>The following sections provide exercises on implementing + mathematical functions. We start with an easy one.</para> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMaxAbs"> + <title>Maximum and absolute value</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement two class methods double abs(double) and double + max(double, double, double) in a class math living in a package + of your choice:</para> + + <programlisting language="java">package de.hdm_stuttgart.de.sd1.math; + +/** + * Some class methods. + */ +public class Math { + + /** + * Return the absolute value of a given argument + * @param value The argument to be considered + * @return the argument's absolute (positive) value. + */ + public static double abs(double value) { + ... return ??; + } + + /** + * The maximum of two arguments + * @param a First argument + * @param b Second argument + * @return The maximum of a and b + */ + public static double max(double a, double b) { + ... return ??; + } + + /** + * The maximum of three arguments + * + * @param a First argument + * @param b Second argument + * @param c Third argument + * @return The maximum of a, b and c + */ + public static double max(double a, double b, double c) { + ... return ??; + } +}</programlisting> + + <para>Test these functions using appropriate data.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/math/V0_5</para> + </annotation> + + <para>See <link + xlink:href="Ref/api/P/math/V0_5/de/hdm_stuttgart/de/sd1/math/Math.html">implementation + here.</link></para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1SecExp"> + <title>Implementing the exponential function.</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMath"> + <title>The exponential <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo>â¡</m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:mrow> + </m:math> + </inlineequation></title> + + <qandadiv> + <qandaentry> + <question> + <para>The exponential <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo>â¡</m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:mrow> + </m:math> + </inlineequation> is being defined by a power series:</para> + + <equation xml:id="sd1EqnDefExp"> + <title>Power series definition of <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo>â¡</m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:mrow> + </m:math> + </inlineequation></title> + + <m:math display="block"> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mrow> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>1</m:mi> + </m:msup> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>2</m:mi> + </m:msup> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mi>...</m:mi> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mo>=</m:mo> + + <m:mrow> + <m:munderover> + <m:mo>∑</m:mo> + + <m:mrow> + <m:mi>i</m:mi> + + <m:mo>=</m:mo> + + <m:mi>0</m:mi> + </m:mrow> + + <m:mi mathvariant="normal">∞</m:mi> + </m:munderover> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>i</m:mi> + </m:msup> + + <m:mrow> + <m:mi>i</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:math> + </equation> + + <para>Implement a class method <methodname>double + exp(double)</methodname> inside a class <package>Math</package> + choosing a package of your choice. The name clash with the Java + standard class <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html">java.lang.Math</link> + is intended: You'll learn how to resolve naming + conflicts.</para> + + <para>Regarding practical calculations we replace the above + infinite series by a limited one. So the number of terms to be + considered will become a parameter which shall be configurable. + Continue the implementation of the following skeleton:</para> + + <figure xml:id="sd1FigExpSketch"> + <title>An implementation sketch for the exponential</title> + + <programlisting language="java">public class Math { + ... + + /** + * @param seriesLimit The last term's index of a power series to be included, + */ + public static void setSeriesLimit(int seriesLimit) {...} + + /** + * Approximating the natural exponential function by a finite + * number of terms from the corresponding power series. + * + * A power series implementation has to be finite since an + * infinite number of terms requires infinite execution time. + * + * The number of terms to be considered can be set by {@link #setSeriesLimit(int)}} + * + * @param x + * @return + */ + public static double exp(double x) {...} +}</programlisting> + </figure> + + <para>Compare your results using <code>seriesLimit=8</code> + terms and the corresponding values from the professional + implementation <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#exp-double">java.lang.Math.exp</link> + by calculating <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>1</m:mi> + </m:msup> + </m:math> + </inlineequation>, <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>2</m:mi> + </m:msup> + </m:math> + </inlineequation> and <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>3</m:mi> + </m:msup> + </m:math> + </inlineequation>. What do you observe? Can you explain this + result?</para> + + <para>Do not forget to provide suitable + <command>Javadoc</command> comments and watch the generated + documentation.</para> + + <para>Hints:</para> + + <itemizedlist> + <listitem> + <para>You should only use basic arithmetic operations like + +, - * and /. Do not use <link + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#pow-double-double-">Math.pow(double + a, double b)</link> and friends! Their implementations use + power series expansions as well and are designed for a + different purpose like having fractional exponent + values.</para> + </listitem> + + <listitem> + <para>The power series' elements may be obtained in a + recursive fashion like e.g.:</para> + + <informalequation> + <m:math display="block"> + <m:mrow> + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mfrac> + <m:mi>x</m:mi> + + <m:mn>3</m:mn> + </m:mfrac> + + <m:mo>â¢</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>2</m:mi> + </m:msup> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + </listitem> + </itemizedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/math/V1</para> + </annotation> + + <para>Regarding the finite number of terms we implement the last + index to be considered as a class variable <coref + linkend="sd1ListingSeriesLimit"/> having default value 1. We + also provide a corresponding setter method <coref + linkend="sd1ListingSeriesLimitSetter"/> enabling users of our + class to choose an appropriate value:</para> + + <programlisting language="java">public class Math { + + static int <emphasis role="bold">seriesLimit = 1</emphasis>; <co + xml:id="sd1ListingSeriesLimit"/> + + /** + * + * @param seriesLimit The last term's index of a power series to be included, + * {@link }}. + */ + public static void setSeriesLimit(int seriesLimit) { <co + xml:id="sd1ListingSeriesLimitSetter"/> + Math.seriesLimit = seriesLimit; + } ...</programlisting> + + <para>Calculating values by a finite series requires a + loop:</para> + + <programlisting language="java"> public static double exp(double x) { + double currentTerm = 1., // the first (i == 0) term x^0/0! + sum = currentTerm; // initialize to the power series' first term + + for (int i = 1; i <= seriesLimit; i++) { // i = 0 has already been completed. + currentTerm *= x / i; + sum += currentTerm; + } + return sum; + }</programlisting> + + <para>You may also view the <productname>Javadoc</productname> + and the implementation of <link + xlink:href="Ref/api/P/math/V1/de/hdm_stuttgart/de/sd1/math/Math.html#exp-double-">double + Math.exp(double)</link>. We may use the subsequent code snippet + for testing and comparing our implementation:</para> + + <programlisting language="java"> Math.setSeriesLimit(6); + + double byPowerSeries = Math.exp(1.); + System.out.println("e^1=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(1.))); + + byPowerSeries = Math.exp(2.); + System.out.println("e^2=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(2.))); + + byPowerSeries = Math.exp(3.); + System.out.println("e^3=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(3.)));</programlisting> + + <para>In comparison with a professional implementation we have + the following results:</para> + + <programlisting language="unknown">e^1=2.7180555555555554, difference=-2.262729034896438E-4 +e^2=7.355555555555555, difference=-0.033500543375095226 +e^3=19.412499999999998, difference=-0.67303692318767</programlisting> + + <para>Our implementation based on just 6 terms is quite good for + small values of x. Larger values however exhibit growing + differences.</para> + + <para>This is due to the fact that our approximation is in fact + just a polynomial of degree 6.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1MathSin"> + <title>Adding sine</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSin"> + <title>Implementing <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We may implement <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> in a similar fashion to <xref + linkend="sd1EqnDefExp"/>:</para> + + <equation xml:id="sd1EqnDefSin"> + <title>Power series definition of <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo>â¡</m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation></title> + + <m:math display="block"> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>5</m:mi> + </m:msup> + + <m:mrow> + <m:mi>5</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>7</m:mi> + </m:msup> + + <m:mrow> + <m:mi>7</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mi>...</m:mi> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mo>=</m:mo> + + <m:mrow> + <m:munderover> + <m:mo>∑</m:mo> + + <m:mrow> + <m:mi>i</m:mi> + + <m:mo>=</m:mo> + + <m:mi>0</m:mi> + </m:mrow> + + <m:mi mathvariant="normal">∞</m:mi> + </m:munderover> + + <m:mrow> + <m:msup> + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>-1</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mi>i</m:mi> + </m:msup> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>i</m:mo> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:msup> + + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>2</m:mi> + + <m:mi>i</m:mi> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:math> + </equation> + + <para>Extend <xref linkend="sd1FigExpSketch"/> by adding a + second method <methodname>double sin(double)</methodname>. Do + not forget to add suitable <command>Javadoc</command> comments + and watch the generated documentation.</para> + + <para>Test your implementation by calculating the known values + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>, <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>Ï€</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> and <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>4</m:mi> + + <m:mi>Ï€</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> using <varname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#PI">java.lang.Math.PI</varname>. + Explain your results</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/math/V2</para> + </annotation> + + <para>Taking seven terms into account we have the following + results:</para> + + <programlisting language="unknown">sin(pi/2)=0.9999999999939768, difference=-6.023181953196399E-12 +sin(pi)=-7.727858895155385E-7, difference=-7.727858895155385E-7 +sin(4 * PI)=-9143.306026012957, <emphasis role="bold">difference=-9143.306026012957</emphasis></programlisting> + + <para>As with the implementation of <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:math> + </inlineequation> larger (positive or negative) argument + values show growing differences. On the other hand the + approximation is remarkably precise for smaller arguments. The + reason again is the fact that our power series is just a + polynomial approximation.</para> + + <para>You may also view the <link + xlink:href="Ref/api/P/math/V2/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">Javadoc</link> + and the implementation of <link + xlink:href="Ref/api/P/math/V2/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">double + Math.sin(double)</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sdnSecSinRoundingErrors"> + <title>Strange things happen</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaReorderSin"> + <title>Summing up in a different order.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We may reorder summing up within our power series + defining<inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>:</para> + + <equation xml:id="sde1MathReorderSumming"> + <title>Reordering of terms with respect to an + implementation.</title> + + <m:math display="block"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>+</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>5</m:mi> + </m:msup> + + <m:mrow> + <m:mi>5</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mo>+</m:mo> + + <m:mo>(</m:mo> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>7</m:mi> + </m:msup> + + <m:mrow> + <m:mi>7</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>9</m:mi> + </m:msup> + + <m:mrow> + <m:mi>9</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>)</m:mo> + + <m:mo>+</m:mo> + + <m:mo>...</m:mo> + </m:mrow> + </m:math> + </equation> + + <para>From a mathematical point of view there is no difference + to <xref linkend="sd1EqnDefSin"/>. Nevertheless:</para> + + <itemizedlist> + <listitem> + <para>Rename your current sine implementation to + <methodname>double sinOld(double)</methodname>.</para> + </listitem> + + <listitem> + <para>Implement a new method <methodname>double + sin(double)</methodname> using the above summing + reordering.</para> + </listitem> + </itemizedlist> + + <para>Compare the results of <methodname>double + sinOld(double)</methodname> and <methodname>double + sin(double)</methodname> for seven terms. What do you observe? + Do you have an explanation?</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/math/V3</para> + </annotation> + + <para>The following results result from <link + xlink:href="Ref/api/P/math/V3/de/hdm_stuttgart/de/sd1/math/Driver.html">this + test</link>:</para> + + <programlisting language="unknown">Old Implementation:+++++++++++++++++++++++++++++++++++++++ + +sinOld(pi/2)=0.9999999999939768, difference=-6.023181953196399E-12 +sinOld(pi)=-7.727858895155385E-7, difference=-7.727858895155385E-7 +sinOld(4 * PI)=-9143.306026012957, difference=-9143.306026012957 + +New reorder Implementation:+++++++++++++++++++++++++++++++++++++ + +sin(pi/2)=1.0000000000000435, difference=4.3520742565306136E-14 +sin(pi)=2.2419510618081458E-8, difference=2.2419510618081458E-8 +sin(4 * PI)=4518.2187229323445, difference=4518.2187229323445</programlisting> + + <para>Comparing corresponding values our reordered + implementation is more than 100 times more precise. For larger + values we still have a factor of two.</para> + + <para>This is due to limited arithmetic precision: Each double + value can only be approximated by an in memory representation of + eight bytes. Consider the following example:</para> + + <programlisting language="java"> double one = 1., + a = 0.000000000000200, + b = 0.000000000000201; + + System.out.println("(1 + (a - b)) - 1:" + ((one + (a - b)) - one)); + System.out.println("((1 + a) - b) - 1:" + (((one + a) - b) - one));</programlisting> + + <para>This produces the following output:</para> + + <programlisting language="unknown">(1 + (a - b)) - 1:-9.992007221626409E-16 +((1 + a) - b) - 1:-8.881784197001252E-16</programlisting> + + <para>Errors like this one sum up in a power series to + reasonable values especially if higher powers are + involved.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1SinComplete"> + <title>Completing sine implementation</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSinMapArguments"> + <title>Transforming arguments.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We've reached an implementation offering good results for + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> if <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>]</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>. The following rules may be used to retain + precision for arbitrary argument values:</para> + + <orderedlist> + <listitem> + <informalequation> + <m:math display="block"> + <m:mrow> + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">â„</m:mi> + </m:mrow> + </m:msub> + + <m:mo>,</m:mo> + + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>n</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">ℤ</m:mi> + </m:mrow> + </m:msub> + + <m:mo>:</m:mo> + + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>n</m:mi> + + <m:mo>â¢</m:mo> + + <m:mi>2</m:mi> + + <m:mo>â¢</m:mo> + + <m:mi>Ï€</m:mi> + + <m:mo>+</m:mo> + + <m:mi>x</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>This rule of periodicity allows us to consider only + the interval <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mo>-</m:mo> + + <m:mi>Ï€</m:mi> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mi>Ï€</m:mi> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> like e.g. <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>20</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>20</m:mi> + + <m:mo>-</m:mo> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>â¢</m:mo> + + <m:mi>2</m:mi> + + <m:mo>â¢</m:mo> + + <m:mi>Ï€</m:mi> + </m:mrow> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>≈</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>1.15</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</para> + </listitem> + + <listitem> + <informalequation> + <m:math display="block"> + <m:mrow> + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">â„</m:mi> + </m:mrow> + </m:msub> + + <m:mo>:</m:mo> + + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>Ï€</m:mi> + + <m:mo>-</m:mo> + + <m:mi>x</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>This rule allows us to map values from <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mo>-</m:mo> + + <m:mi>Ï€</m:mi> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mi>Ï€</m:mi> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> to <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> like e.g. <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(2</m:mo> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>Ï€</m:mi> + + <m:mo>-</m:mo> + + <m:mi>2</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>≈</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo>â¡</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>1.14</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</para> + </listitem> + </orderedlist> + + <para>These two rules allow us to consider only the interval + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>Ï€</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>]</m:mo> + </m:mrow> + </m:math> + </inlineequation> with respect to our power series. Extend + your current implementation by mapping arbitrary arguments to + this interval appropriately.</para> + + <para>Hint: The standard function <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-">Math.rint(double)</methodname> + could be helpful: It may turn e.g. 4.47 (<code>double</code>) to + 4 (<code>long</code>).</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/math/V4</para> + </annotation> + + <para>For convenience reasons we start defining PI within our + class:</para> + + <programlisting language="java">public class Math { + + private static final double PI = java.lang.Math.PI; + ...</programlisting> + + <para>No we need two steps mapping our argument:</para> + + <programlisting language="java"> public static double sin(double x) { + // Step 1: Normalize x to [-PI, +PI[ + final long countTimes2PI = (long) java.lang.Math.rint(x / 2 / PI); + if (countTimes2PI != 0) { + x -= 2 * PI * countTimes2PI; + } + + // Step 2: Normalize x to [-PI/2, +PI/2] + // Since sin(x) = sin (PI - x) we continue to normalize + // having x in [-PI/2, +PI/2] + if (PI/2 < x) { + x = PI - x; + } else if (x < -PI/2) { + x = -x - PI; + } + + // Step 3: Continue with business as usual + ...</programlisting> + + <para>You may also view the <productname>Javadoc</productname> + and the implementation of <link + xlink:href="Ref/api/P/math/V4/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">double + Math.sin(double)</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + + </chapter> + + diff --git a/Doc/Sd1/preliminaries.xml b/Doc/Sd1/preliminaries.xml new file mode 100644 index 0000000000000000000000000000000000000000..f4d1008ff373de99e902d881e08e9bc9af6be20f --- /dev/null +++ b/Doc/Sd1/preliminaries.xml @@ -0,0 +1,230 @@ +<?xml version="1.0" encoding="UTF-8"?> +<chapter xml:id="sw1Lect1" version="5.0" xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Lecture 1</title> + + <section xml:id="sd1CommonRessources"> + <title>Common software development related resources</title> + + <glosslist> + <glossentry> + <glossterm><xref linkend="glo_HdM"/> mail server</glossterm> + + <glossdef> + <para>Either</para> + + <itemizedlist> + <listitem> + <para>read your mails regularly</para> + </listitem> + + <listitem> + <para>activate mail forwarding to your <quote>real</quote> + account at <link + xlink:href="https://mail.hdm-stuttgart.de/webmail">https://mail.hdm-stuttgart.de/webmail</link> + (<quote>Filter</quote> tab).</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><acronym>MI <xref linkend="glo_VPN"/></acronym> + Installation</glossterm> + + <glossdef> + <para>OpenVPN <acronym>wiki</acronym> <link + xlink:href="https://wiki.mi.hdm-stuttgart.de/wiki/VPN">installation + page</link> (Login required). Look for HdM_MI_stud.ovpn allowing to + use a maximum of MI specific services.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>MI Cloud</glossterm> + + <glossdef> + <para>25 GB free space. Base address <link + xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud">https://cloud.mi.hdm-stuttgart.de/owncloud</link>. + Client software for Linux, Android, <productname>IOS</productname>, + Windows, MacOS available at <link + xlink:href="http://owncloud.org/sync-clients">http://owncloud.org/sync-clients</link>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>MI <xref linkend="glo_Git"/> / <xref linkend="glo_Svn"/> + repository</glossterm> + + <glossdef> + <para><link + xlink:href="https://version.mi.hdm-stuttgart.de">https://version.mi.hdm-stuttgart.de</link></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>MI file server</glossterm> + + <glossdef> + <para><filename>Prototype user xy05 may acces his home directory via + \\srv2.srv.mi.hdm-stuttgart.de\xy05</filename> or + \\192.168.111.9\xy05 respectively.</para> + + <caution> + <para>External access requires <acronym>VPN</acronym></para> + </caution> + </glossdef> + </glossentry> + </glosslist> + </section> + + <section xml:id="sw1Resources"> + <title>Lecture related resources</title> + + <glosslist> + <glossentry> + <glossterm>Books / Literature</glossterm> + + <glossdef> + <glosslist> + <glossentry> + <glossterm>Primary</glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para><xref linkend="bib_Koelling2010"/> or <xref + linkend="bib_Koelling2010Ger"/>.</para> + </listitem> + + <listitem> + <para><xref linkend="bib_Horton2011"/></para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Secondary</glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para><xref linkend="bib_Jobst2014"/>.</para> + </listitem> + + <listitem> + <para>Older free online copy <xref + linkend="bib_Ullenboom2011"/> or current book <xref + linkend="bib_Ullenboom2014"/> including <xref + linkend="glo_Java"/> 8.</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>UNIX shell introduction</glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para><link + xlink:href="http://software-carpentry.org/v4/shell">The + Unix Shell</link> / Software-carpentry, nice video + collection. Each section is also available in PDF and + <trademark>PowerPoint</trademark> format.</para> + </listitem> + + <listitem> + <para><link + xlink:href="http://www.ee.surrey.ac.uk/Teaching/Unix">UNIX + Tutorial for Beginners</link>, text oriented.</para> + </listitem> + + <listitem> + <para><link + xlink:href="http://vic.gedris.org/Manual-ShellIntro/1.2/ShellIntro.pdf">An + Introduction to ...</link>, small reference of important + command names, filename conventions etc.</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + </glosslist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Live lecture additions</glossterm> + + <glossdef> + <para><link + xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud/public.php?service=files&t=df9f296af3298f96361a15a679390e59">MI + cloud folder</link></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><xref linkend="glo_Eclipse"/> <xref + linkend="glo_IDE"/></glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para><link + xlink:href="http://wiki.eclipse.org/Eclipse/Installation">Installation</link>, + choose <quote>Eclipse IDE for Java Developers</quote> from <link + xlink:href="http://eclipse.org/downloads">http://eclipse.org/downloads</link>.</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Maven artifact + <quote>mi-maven-archetype-quickstart</quote></glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para>Configure <filename + xlink:href="http://maven.mi.hdm-stuttgart.de/Archetypes/catalog.xml">catalog.xml</filename> + in your <xref linkend="glo_Eclipse"/> <xref linkend="glo_IDE"/> + at + <guimenu>Window-->Preferences-->Maven-->Archetypes-->Add + Remote Catalog</guimenu>. Click <guibutton>verify</guibutton> to + assure correct configuration.</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><productname>Virtualbox</productname> + <productname>Lubuntu</productname> VM</glossterm> + + <glossdef> + <para><link + xlink:href="ftp://mirror.mi.hdm-stuttgart.de/ubuntu/VirtualBox">ftp://mirror.mi.hdm-stuttgart.de/ubuntu/VirtualBox</link>.</para> + + <caution> + <para>External access requires <acronym>VPN</acronym></para> + </caution> + + <para>If you experience bad <productname>Virtualbox</productname> + performance on your system please consider <link + xlink:href="http://blog.jdpfu.com/2012/09/14/solution-for-slow-ubuntu-in-virtualbox">solution-for-slow-ubuntu-in-virtualbox</link> + and the <link + xlink:href="http://blog.jdpfu.com/ALE/ALE-NW/Ubuntu-12.04-x32-install.pdf">referenced + collection of screenshots</link>.</para> + </glossdef> + </glossentry> + </glosslist> + </section> +</chapter> diff --git a/Doc/Sd1/streams.xml b/Doc/Sd1/streams.xml new file mode 100644 index 0000000000000000000000000000000000000000..fdf58cf65304efcfaf9ddfbb9b47857b98940457 --- /dev/null +++ b/Doc/Sd1/streams.xml @@ -0,0 +1,373 @@ + <chapter xml:id="sd1ReadCharStreams" version="5.0" + xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>Reading character streams (15.12.)</title> + + <section xml:id="sd1ReadCharStreamsPrepare"> + <title>Preparations</title> + + <itemizedlist> + <listitem> + <para>Section <quote>Interfaces</quote> of chapter 6 in <xref + linkend="bib_Horton2011"/>.</para> + </listitem> + + <listitem> + <para>Chapter 8 of <xref linkend="bib_Horton2011"/> excluding the + last chapter <quote>The Standard Streams</quote>.</para> + </listitem> + + <listitem> + <para><link xlink:href="Ref/Svg/exception.svg">Exception + basics</link>.</para> + </listitem> + </itemizedlist> + </section> + + <section xml:id="sd1GnuWc"> + <title>Exercises</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaLinenumbers"> + <title>Adding line numbers to text files</title> + + <qandadiv> + <qandaentry> + <question> + <para>We want to add line numbers to arbitrary text files not + necessarily being related to programming. Consider the following + HTML example input:</para> + + <programlisting language="java"><html> + <head> + <title>A simple HTML example</title> + </head> + <body> + <p>Some text ... </p> + </body> +</html></programlisting> + + <para>Your application shall add line numbers:</para> + + <programlisting language="none">1: <html> +2: <head> +3: <title>A simple HTML example</title> +4: </head> +5: <body> +6: <p>Some text ... </p> +7: </body> +8: </html></programlisting> + + <para>Hints:</para> + + <orderedlist> + <listitem> + <para>Given the name of an existing file you may create an + instance of <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname>:</para> + + <programlisting language="java">final FileReader fileReader = new FileReader(inputFileName); +final BufferedReader inputBufferedReader = new BufferedReader(fileReader);</programlisting> + </listitem> + + <listitem> + <para>You will have to deal with possible <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/FileNotFoundException.html">FileNotFoundException</classname> + problems providing meaningful error messages.</para> + </listitem> + + <listitem> + <para>The <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname> + class provides a method <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#readLine--">readLine()</methodname> + allowing to access a given file's content line by + line.</para> + + <caution> + <para>Even if a file exists you have my encounter + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/IOException.html">IOException</classname> + problems being related to <acronym>i.e.</acronym> missing + permissions.</para> + </caution> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Wc/readFile</para> + </annotation> + + <para>This solutions reacts both to inexistent files and general + IO problems:</para> + + <programlisting language="none">File not found: Testdata/input.java</programlisting> + + <para>Two test cases deal both with readable and non-existing + files: and expected exceptions:</para> + + <programlisting language="java"> @Test + public void testReadFileOk() throws FileNotFoundException, IOException { + ReadFile.openStream("Testdata/input.txt"); // Existing file + } + @Test (expected=FileNotFoundException.class) // We expect this exception to be thrown + public void testReadMissingFile() throws FileNotFoundException, IOException { + ReadFile.openStream("Testdata/input.java"); // Does not exist + }</programlisting> + + <para>Notice the second test which will only succeed if a + <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/FileNotFoundException.html">FileNotFoundException</classname> + is being thrown.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaWc"> + <title>A partial implementation of GNU UNIX + <command>wc</command></title> + + <qandadiv> + <qandaentry> + <question> + <para>In this exercise we will partly implement the (Gnu) UNIX + command line tool <command + xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/wc-invocation.html">wc</command> + (word count). Prior to starting this exercise you may want + to:</para> + + <itemizedlist> + <listitem> + <para>Execute <command + xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/wc-invocation.html">wc</command> + for sample text files like e.g. a Java source file of + similar:</para> + + <programlisting language="bourne">goik >wc BoundedIntegerStore.java + 58 198 1341 BoundedIntegerStore.java +</programlisting> + + <para>What do these three numbers 58, 198 and 1341 mean? + Execute <command>wc</command> <option>--help</option> or + <command>man</command> <option>wc</option> or read the <link + xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/wc-invocation.html">HTML + documentation</link>.</para> + </listitem> + + <listitem> + <para><command>wc</command> may process several file in + parallel thereby producing an extra line <coref + linkend="sd1PlWcExtraLine"/> summing up all values:</para> + + <programlisting language="bourne">goik >wc bibliography.xml swd1.xml + 69 83 2087 bibliography.xml + 6809 18252 248894 swd1.xml + <emphasis role="bold">6878 18335 250981 total</emphasis> <co + xml:id="sd1PlWcExtraLine"/> +</programlisting> + </listitem> + + <listitem> + <para><command>wc</command> can be used in <link + xlink:href="http://en.wikipedia.org/wiki/Pipeline_(Unix)">pipes</link> + () like:</para> + + <programlisting language="bourne">goik >grep int BoundedIntegerStore.java | wc + 12 76 516</programlisting> + + <para>The above output <quote>12 76 516</quote> tells us + that our file <filename>BoundedIntegerStore.java</filename> + does have 12 lines containing the string + <quote>int</quote>.</para> + </listitem> + </itemizedlist> + + <para>A partial implementation shall offer all features being + mentioned in the introduction. The following steps are a + proposal for your implementation:</para> + + <orderedlist> + <listitem> + <para>Write a method counting the number of words within a + given string. We assume words to be separated by at least + one white space character (<code>space</code> or + <code>\t</code>). Write some tests to assure correct + behaviour.</para> + </listitem> + + <listitem> + <para>Read input either from a list of files or from + standard input depending on the number of arguments to + main(String[] args):</para> + + <itemizedlist> + <listitem> + <para>If <code>args.length == 0</code> assume to read + from standard input.</para> + </listitem> + + <listitem> + <para>if <code>0 < args.length</code> try to + interpret the arguments as filenames.</para> + </listitem> + </itemizedlist> + </listitem> + + <listitem> + <para>Write a class <code>TextFileStatistics</code> being + able to and count characters, words and lines of a single + input file. Instances of this class may be initialized from + a <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname>.</para> + + <para>Write corresponding tests.</para> + </listitem> + + <listitem> + <para>You may create an instance of <classname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname> + from <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#in">System.in</link> + via:</para> + + <programlisting language="java">new BufferedReader(new InputStreamReader(System.in))</programlisting> + </listitem> + + <listitem> + <para>Create an executable Jar archive and execute some + examples. The UNIX command <command + xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html#cat-invocation">cat</command> + writes a file's content to standard output. This output may + be piped as input to your application as in <code>cat + filename.txt | java -jar .../wc-1.0.jar</code>.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/Wc/wc</para> + </annotation> + + <para>Executing <command>mvn</command> <option>package</option> + creates an executable Jar file + <filename>../target/wc-1.0.jar</filename>. We test both ways of + operation:</para> + + <glosslist> + <glossentry> + <glossterm>Reading from standard input</glossterm> + + <glossdef> + <programlisting language="bourne">goik >cat Testdata/input.html | java -jar target/wc-1.0.jar + 9 14 137</programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Passing file names as parameters</glossterm> + + <glossdef> + <programlisting language="bourne">goik >java -jar target/wc-1.0.jar Testdata/* + 9 14 137 Testdata/input.html + 4 5 41 Testdata/model.css + 13 19 178 total</programlisting> + </glossdef> + </glossentry> + </glosslist> + + <para><xref linkend="glo_Junit"/> tests of internal + functionality:</para> + + <glosslist> + <glossentry> + <glossterm>Counting words in a given string:</glossterm> + + <glossdef> + <programlisting language="java"> @Test + public void testNoWord() { + Assert.assertEquals("Just white space", 0, TextFileStatistics.findNoOfWords(" \t")); + } + + @Test + public void testSingleWord() { + final String s = "We're"; + Assert.assertEquals("text='" + s + "'", 1, TextFileStatistics.findNoOfWords(s)); + } + + @Test + public void testTwoWords() { + final String s = "We are"; + Assert.assertEquals("text='" + s + "'", 2, TextFileStatistics.findNoOfWords(s)); + } + + @Test + public void testWordsWhiteHead() { + final String s = "\t \tBegin_space"; + Assert.assertEquals("text='" + s + "'", 1, TextFileStatistics.findNoOfWords(s)); + } + + @Test + public void testWordsWhiteTail() { + final String s = "End_space \t "; + Assert.assertEquals("text='" + s + "'", 1, TextFileStatistics.findNoOfWords(s)); + } + + @Test + public void testWhiteMulti() { + final String s = " some\t\tinterspersed \t spaces \t\t "; + Assert.assertEquals("text='" + s + "'", 3, TextFileStatistics.findNoOfWords(s)); + }</programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Analyzing test file data:</glossterm> + + <glossdef> + <programlisting language="java"> @Test + public void testTwoInputFiles() throws FileNotFoundException, IOException { + + final String model_css_filename = "Testdata/model.css", // 4 lines 5 words 41 character + input_html_filename = "Testdata/input.html"; // 9 lines 14 words 137 character + //_________________________________________ + // total 13 lines 19 words 178 character + + final TextFileStatistics + model_css = new TextFileStatistics( + new BufferedReader(new FileReader(model_css_filename)), model_css_filename), + + input_html = new TextFileStatistics(new BufferedReader( + new FileReader(input_html_filename)), input_html_filename); + + // File Testdata/model.css + Assert.assertEquals( 4, model_css.numLines); + Assert.assertEquals( 5, model_css.numWords); + Assert.assertEquals(41, model_css.numCharacters); + + // File Testdata/input.html + Assert.assertEquals( 9, input_html.numLines); + Assert.assertEquals( 14, input_html.numWords); + Assert.assertEquals(137, input_html.numCharacters); + + // Grand total + Assert.assertEquals( 13, TextFileStatistics.getTotalNumLines()); + Assert.assertEquals( 19, TextFileStatistics.getTotalNumWords()); + Assert.assertEquals(178, TextFileStatistics.getTotalNumCharacters()); + }</programlisting> + </glossdef> + </glossentry> + </glosslist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </chapter> diff --git a/Sda1/Etest/Doodle/.project b/Doc/Sda1/Etest/Doodle/.project similarity index 100% rename from Sda1/Etest/Doodle/.project rename to Doc/Sda1/Etest/Doodle/.project diff --git a/Sda1/Etest/Doodle/data.xml b/Doc/Sda1/Etest/Doodle/data.xml similarity index 100% rename from Sda1/Etest/Doodle/data.xml rename to Doc/Sda1/Etest/Doodle/data.xml diff --git a/Sda1/Etest/Doodle/doodle.png b/Doc/Sda1/Etest/Doodle/doodle.png similarity index 100% rename from Sda1/Etest/Doodle/doodle.png rename to Doc/Sda1/Etest/Doodle/doodle.png diff --git a/Sda1/Etest/Doodle/doodle.xsd b/Doc/Sda1/Etest/Doodle/doodle.xsd similarity index 100% rename from Sda1/Etest/Doodle/doodle.xsd rename to Doc/Sda1/Etest/Doodle/doodle.xsd diff --git a/Sda1/Etest/JdomTable/exercise.xhtml b/Doc/Sda1/Etest/JdomTable/exercise.xhtml similarity index 100% rename from Sda1/Etest/JdomTable/exercise.xhtml rename to Doc/Sda1/Etest/JdomTable/exercise.xhtml diff --git a/Sda1/Etest/JdomTable/jdomtable/.gitignore b/Doc/Sda1/Etest/JdomTable/jdomtable/.gitignore similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/.gitignore rename to Doc/Sda1/Etest/JdomTable/jdomtable/.gitignore diff --git a/Sda1/Etest/JdomTable/jdomtable/pom.exam.xml b/Doc/Sda1/Etest/JdomTable/jdomtable/pom.exam.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/pom.exam.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable/pom.exam.xml diff --git a/Sda1/Etest/JdomTable/jdomtable/pom.xml b/Doc/Sda1/Etest/JdomTable/jdomtable/pom.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/pom.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable/pom.xml diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/resources/.gitignore b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/.gitignore similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/resources/.gitignore rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/.gitignore diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/resources/log4j2.xml b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/log4j2.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/resources/log4j2.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/log4j2.xml diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.highlight.expected.html b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.highlight.expected.html similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.highlight.expected.html rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.highlight.expected.html diff --git a/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.switch.expected.html b/Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.switch.expected.html similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.switch.expected.html rename to Doc/Sda1/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.switch.expected.html diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/.gitignore b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/.gitignore similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/.gitignore rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/.gitignore diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/build.sh b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/build.sh similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/build.sh rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/build.sh diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/pom.xml b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/pom.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/pom.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/pom.xml diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/.gitignore b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/.gitignore similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/.gitignore rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/.gitignore diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/log4j2.xml b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/log4j2.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/log4j2.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/log4j2.xml diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/persons.xml b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/persons.xml similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/persons.xml rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/main/resources/persons.xml diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestRowHighlighting.java b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestRowHighlighting.java similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestRowHighlighting.java rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestRowHighlighting.java diff --git a/Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestTableRowColumnSwitch.java b/Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestTableRowColumnSwitch.java similarity index 100% rename from Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestTableRowColumnSwitch.java rename to Doc/Sda1/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestTableRowColumnSwitch.java diff --git a/Sda1/Etest/RdbmsStudents2xml/exercise1.xhtml b/Doc/Sda1/Etest/RdbmsStudents2xml/exercise1.xhtml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/exercise1.xhtml rename to Doc/Sda1/Etest/RdbmsStudents2xml/exercise1.xhtml diff --git a/Sda1/Etest/RdbmsStudents2xml/exercise2.xhtml b/Doc/Sda1/Etest/RdbmsStudents2xml/exercise2.xhtml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/exercise2.xhtml rename to Doc/Sda1/Etest/RdbmsStudents2xml/exercise2.xhtml diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/.gitignore b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/.gitignore similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/.gitignore rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/.gitignore diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/schema.sql b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/schema.sql similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/schema.sql rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/schema.sql diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/testdata.xml b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/testdata.xml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/testdata.xml rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/testdata.xml diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/university.xsd b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/university.xsd similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/university.xsd rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/university.xsd diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/pom.xml b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/pom.xml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/pom.xml rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/pom.xml diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/resources/log4j2.xml b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/resources/log4j2.xml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/resources/log4j2.xml rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/resources/log4j2.xml diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/.gitignore b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/.gitignore similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/.gitignore rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/.gitignore diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/schema.sql b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/schema.sql similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/schema.sql rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/schema.sql diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/testdata.xml b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/testdata.xml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/testdata.xml rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/testdata.xml diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/university.xsd b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/university.xsd similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/university.xsd rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/university.xsd diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/pom.xml b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/pom.xml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/pom.xml rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/pom.xml diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties diff --git a/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/resources/log4j2.xml b/Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/resources/log4j2.xml similarity index 100% rename from Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/resources/log4j2.xml rename to Doc/Sda1/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/resources/log4j2.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/.gitignore b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/.gitignore similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/.gitignore rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/.gitignore diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.exam.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.exam.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.exam.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.exam.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/.gitignore b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/.gitignore similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/.gitignore rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/.gitignore diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/log4j2.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/log4j2.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/log4j2.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/log4j2.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.1.expected.html b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.1.expected.html similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.1.expected.html rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.1.expected.html diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.2.expected.html b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.2.expected.html similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.2.expected.html rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.2.expected.html diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/.gitignore b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/.gitignore similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/.gitignore rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/.gitignore diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/build.sh b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/build.sh similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/build.sh rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/build.sh diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/pom.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/pom.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/pom.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/pom.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/.gitignore b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/.gitignore similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/.gitignore rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/.gitignore diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/log4j2.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/log4j2.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/log4j2.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/log4j2.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v2/test/TestComplexSaxTransform.java b/Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v2/test/TestComplexSaxTransform.java similarity index 100% rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v2/test/TestComplexSaxTransform.java rename to Doc/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v2/test/TestComplexSaxTransform.java diff --git a/Sda1/Etest/SaxMemo2Html/exercise1.xhtml b/Doc/Sda1/Etest/SaxMemo2Html/exercise1.xhtml similarity index 100% rename from Sda1/Etest/SaxMemo2Html/exercise1.xhtml rename to Doc/Sda1/Etest/SaxMemo2Html/exercise1.xhtml diff --git a/Sda1/Etest/XmlSchema2RdbmsSchema/.project b/Doc/Sda1/Etest/XmlSchema2RdbmsSchema/.project similarity index 100% rename from Sda1/Etest/XmlSchema2RdbmsSchema/.project rename to Doc/Sda1/Etest/XmlSchema2RdbmsSchema/.project diff --git a/Sda1/Etest/XmlSchema2RdbmsSchema/address.xsd b/Doc/Sda1/Etest/XmlSchema2RdbmsSchema/address.xsd similarity index 100% rename from Sda1/Etest/XmlSchema2RdbmsSchema/address.xsd rename to Doc/Sda1/Etest/XmlSchema2RdbmsSchema/address.xsd diff --git a/Sda1/Etest/XmlSchema2RdbmsSchema/exercise.xhtml b/Doc/Sda1/Etest/XmlSchema2RdbmsSchema/exercise.xhtml similarity index 100% rename from Sda1/Etest/XmlSchema2RdbmsSchema/exercise.xhtml rename to Doc/Sda1/Etest/XmlSchema2RdbmsSchema/exercise.xhtml diff --git a/Sda1/Etest/XmlSchema2RdbmsSchema/sampleData.xml b/Doc/Sda1/Etest/XmlSchema2RdbmsSchema/sampleData.xml similarity index 100% rename from Sda1/Etest/XmlSchema2RdbmsSchema/sampleData.xml rename to Doc/Sda1/Etest/XmlSchema2RdbmsSchema/sampleData.xml diff --git a/Sda1/Etest/XmlSchema2RdbmsSchema/schema.sql b/Doc/Sda1/Etest/XmlSchema2RdbmsSchema/schema.sql similarity index 100% rename from Sda1/Etest/XmlSchema2RdbmsSchema/schema.sql rename to Doc/Sda1/Etest/XmlSchema2RdbmsSchema/schema.sql diff --git a/Sda1/Etest/Xslt1/Xml2xml/.project b/Doc/Sda1/Etest/Xslt1/Xml2xml/.project similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/.project rename to Doc/Sda1/Etest/Xslt1/Xml2xml/.project diff --git a/Sda1/Etest/Xslt1/Xml2xml/person.xsd b/Doc/Sda1/Etest/Xslt1/Xml2xml/person.xsd similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/person.xsd rename to Doc/Sda1/Etest/Xslt1/Xml2xml/person.xsd diff --git a/Sda1/Etest/Xslt1/Xml2xml/person2user.xsl b/Doc/Sda1/Etest/Xslt1/Xml2xml/person2user.xsl similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/person2user.xsl rename to Doc/Sda1/Etest/Xslt1/Xml2xml/person2user.xsl diff --git a/Sda1/Etest/Xslt1/Xml2xml/person2userTest.xspec b/Doc/Sda1/Etest/Xslt1/Xml2xml/person2userTest.xspec similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/person2userTest.xspec rename to Doc/Sda1/Etest/Xslt1/Xml2xml/person2userTest.xspec diff --git a/Sda1/Etest/Xslt1/Xml2xml/personData.xml b/Doc/Sda1/Etest/Xslt1/Xml2xml/personData.xml similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/personData.xml rename to Doc/Sda1/Etest/Xslt1/Xml2xml/personData.xml diff --git a/Sda1/Etest/Xslt1/Xml2xml/user.xsd b/Doc/Sda1/Etest/Xslt1/Xml2xml/user.xsd similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/user.xsd rename to Doc/Sda1/Etest/Xslt1/Xml2xml/user.xsd diff --git a/Sda1/Etest/Xslt1/Xml2xml/userData.xml b/Doc/Sda1/Etest/Xslt1/Xml2xml/userData.xml similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml/userData.xml rename to Doc/Sda1/Etest/Xslt1/Xml2xml/userData.xml diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/.gitignore b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/.gitignore similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/.gitignore rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/.gitignore diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/.project b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/.project similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/.project rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/.project diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/person.xsd b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/person.xsd similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/person.xsd rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/person.xsd diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/person2user.xsl b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/person2user.xsl similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/person2user.xsl rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/person2user.xsl diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/person2userTest.xspec b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/person2userTest.xspec similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/person2userTest.xspec rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/person2userTest.xspec diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/personData.xml b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/personData.xml similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/personData.xml rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/personData.xml diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/user.xsd b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/user.xsd similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/user.xsd rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/user.xsd diff --git a/Sda1/Etest/Xslt1/Xml2xml_Solution/userData.xml b/Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/userData.xml similarity index 100% rename from Sda1/Etest/Xslt1/Xml2xml_Solution/userData.xml rename to Doc/Sda1/Etest/Xslt1/Xml2xml_Solution/userData.xml diff --git a/Sda1/Etest/Xslt1/user.xhtml b/Doc/Sda1/Etest/Xslt1/user.xhtml similarity index 100% rename from Sda1/Etest/Xslt1/user.xhtml rename to Doc/Sda1/Etest/Xslt1/user.xhtml diff --git a/Sda1/Etest/Xslt1/userSolution.xhtml b/Doc/Sda1/Etest/Xslt1/userSolution.xhtml similarity index 100% rename from Sda1/Etest/Xslt1/userSolution.xhtml rename to Doc/Sda1/Etest/Xslt1/userSolution.xhtml diff --git a/Sda1/Etest/Xslt2/Book2Html/.project b/Doc/Sda1/Etest/Xslt2/Book2Html/.project similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/.project rename to Doc/Sda1/Etest/Xslt2/Book2Html/.project diff --git a/Sda1/Etest/Xslt2/Book2Html/Book1/.gitignore b/Doc/Sda1/Etest/Xslt2/Book2Html/Book1/.gitignore similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book1/.gitignore rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book1/.gitignore diff --git a/Sda1/Etest/Xslt2/Book2Html/Book1/book1.xsd b/Doc/Sda1/Etest/Xslt2/Book2Html/Book1/book1.xsd similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book1/book1.xsd rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book1/book1.xsd diff --git a/Sda1/Etest/Xslt2/Book2Html/Book1/book1Test.xspec b/Doc/Sda1/Etest/Xslt2/Book2Html/Book1/book1Test.xspec similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book1/book1Test.xspec rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book1/book1Test.xspec diff --git a/Sda1/Etest/Xslt2/Book2Html/Book1/book1ToHtml.xsl b/Doc/Sda1/Etest/Xslt2/Book2Html/Book1/book1ToHtml.xsl similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book1/book1ToHtml.xsl rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book1/book1ToHtml.xsl diff --git a/Sda1/Etest/Xslt2/Book2Html/Book1/work1.reference.html b/Doc/Sda1/Etest/Xslt2/Book2Html/Book1/work1.reference.html similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book1/work1.reference.html rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book1/work1.reference.html diff --git a/Sda1/Etest/Xslt2/Book2Html/Book1/work1.xml b/Doc/Sda1/Etest/Xslt2/Book2Html/Book1/work1.xml similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book1/work1.xml rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book1/work1.xml diff --git a/Sda1/Etest/Xslt2/Book2Html/Book2/.gitignore b/Doc/Sda1/Etest/Xslt2/Book2Html/Book2/.gitignore similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book2/.gitignore rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book2/.gitignore diff --git a/Sda1/Etest/Xslt2/Book2Html/Book2/book2.xsd b/Doc/Sda1/Etest/Xslt2/Book2Html/Book2/book2.xsd similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book2/book2.xsd rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book2/book2.xsd diff --git a/Sda1/Etest/Xslt2/Book2Html/Book2/book2Test.xspec b/Doc/Sda1/Etest/Xslt2/Book2Html/Book2/book2Test.xspec similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book2/book2Test.xspec rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book2/book2Test.xspec diff --git a/Sda1/Etest/Xslt2/Book2Html/Book2/book2ToHtml.xsl b/Doc/Sda1/Etest/Xslt2/Book2Html/Book2/book2ToHtml.xsl similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book2/book2ToHtml.xsl rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book2/book2ToHtml.xsl diff --git a/Sda1/Etest/Xslt2/Book2Html/Book2/work2.reference.html b/Doc/Sda1/Etest/Xslt2/Book2Html/Book2/work2.reference.html similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book2/work2.reference.html rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book2/work2.reference.html diff --git a/Sda1/Etest/Xslt2/Book2Html/Book2/work2.xml b/Doc/Sda1/Etest/Xslt2/Book2Html/Book2/work2.xml similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html/Book2/work2.xml rename to Doc/Sda1/Etest/Xslt2/Book2Html/Book2/work2.xml diff --git a/Sda1/Etest/Xslt2/Book2Html_Solution/.project b/Doc/Sda1/Etest/Xslt2/Book2Html_Solution/.project similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html_Solution/.project rename to Doc/Sda1/Etest/Xslt2/Book2Html_Solution/.project diff --git a/Sda1/Etest/Xslt2/Book2Html_Solution/Book1/.gitignore b/Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book1/.gitignore similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html_Solution/Book1/.gitignore rename to Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book1/.gitignore diff --git a/Sda1/Etest/Xslt2/Book2Html_Solution/Book1/book1ToHtml.xsl b/Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book1/book1ToHtml.xsl similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html_Solution/Book1/book1ToHtml.xsl rename to Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book1/book1ToHtml.xsl diff --git a/Sda1/Etest/Xslt2/Book2Html_Solution/Book2/.gitignore b/Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book2/.gitignore similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html_Solution/Book2/.gitignore rename to Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book2/.gitignore diff --git a/Sda1/Etest/Xslt2/Book2Html_Solution/Book2/book2ToHtml.xsl b/Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book2/book2ToHtml.xsl similarity index 100% rename from Sda1/Etest/Xslt2/Book2Html_Solution/Book2/book2ToHtml.xsl rename to Doc/Sda1/Etest/Xslt2/Book2Html_Solution/Book2/book2ToHtml.xsl diff --git a/Sda1/Etest/Xslt2/exercise1.xhtml b/Doc/Sda1/Etest/Xslt2/exercise1.xhtml similarity index 100% rename from Sda1/Etest/Xslt2/exercise1.xhtml rename to Doc/Sda1/Etest/Xslt2/exercise1.xhtml diff --git a/Sda1/Etest/Xslt2/exercise2.xhtml b/Doc/Sda1/Etest/Xslt2/exercise2.xhtml similarity index 100% rename from Sda1/Etest/Xslt2/exercise2.xhtml rename to Doc/Sda1/Etest/Xslt2/exercise2.xhtml diff --git a/Sda1/Etest/solutions.html b/Doc/Sda1/Etest/solutions.html similarity index 100% rename from Sda1/Etest/solutions.html rename to Doc/Sda1/Etest/solutions.html diff --git a/Sda1/Ref/Fig/Makefile b/Doc/Sda1/Ref/Fig/Makefile similarity index 100% rename from Sda1/Ref/Fig/Makefile rename to Doc/Sda1/Ref/Fig/Makefile diff --git a/Sda1/Ref/Fig/attribInElement.fig b/Doc/Sda1/Ref/Fig/attribInElement.fig similarity index 100% rename from Sda1/Ref/Fig/attribInElement.fig rename to Doc/Sda1/Ref/Fig/attribInElement.fig diff --git a/Sda1/Ref/Fig/attributes.fig b/Doc/Sda1/Ref/Fig/attributes.fig similarity index 100% rename from Sda1/Ref/Fig/attributes.fig rename to Doc/Sda1/Ref/Fig/attributes.fig diff --git a/Sda1/Ref/Fig/blockprop.fo.pdf b/Doc/Sda1/Ref/Fig/blockprop.fo.pdf similarity index 100% rename from Sda1/Ref/Fig/blockprop.fo.pdf rename to Doc/Sda1/Ref/Fig/blockprop.fo.pdf diff --git a/Sda1/Ref/Fig/booknavigate.fig b/Doc/Sda1/Ref/Fig/booknavigate.fig similarity index 100% rename from Sda1/Ref/Fig/booknavigate.fig rename to Doc/Sda1/Ref/Fig/booknavigate.fig diff --git a/Sda1/Ref/Fig/clientserv.fig b/Doc/Sda1/Ref/Fig/clientserv.fig similarity index 100% rename from Sda1/Ref/Fig/clientserv.fig rename to Doc/Sda1/Ref/Fig/clientserv.fig diff --git a/Sda1/Ref/Fig/contentmixed.fig b/Doc/Sda1/Ref/Fig/contentmixed.fig similarity index 100% rename from Sda1/Ref/Fig/contentmixed.fig rename to Doc/Sda1/Ref/Fig/contentmixed.fig diff --git a/Sda1/Ref/Fig/cpp.fig b/Doc/Sda1/Ref/Fig/cpp.fig similarity index 100% rename from Sda1/Ref/Fig/cpp.fig rename to Doc/Sda1/Ref/Fig/cpp.fig diff --git a/Sda1/Ref/Fig/crossmedia.fig b/Doc/Sda1/Ref/Fig/crossmedia.fig similarity index 100% rename from Sda1/Ref/Fig/crossmedia.fig rename to Doc/Sda1/Ref/Fig/crossmedia.fig diff --git a/Sda1/Ref/Fig/dictionary.1.fo.eps b/Doc/Sda1/Ref/Fig/dictionary.1.fo.eps similarity index 100% rename from Sda1/Ref/Fig/dictionary.1.fo.eps rename to Doc/Sda1/Ref/Fig/dictionary.1.fo.eps diff --git a/Sda1/Ref/Fig/dictionary.2.fo.eps b/Doc/Sda1/Ref/Fig/dictionary.2.fo.eps similarity index 100% rename from Sda1/Ref/Fig/dictionary.2.fo.eps rename to Doc/Sda1/Ref/Fig/dictionary.2.fo.eps diff --git a/Sda1/Ref/Fig/dictionaryStack.fig b/Doc/Sda1/Ref/Fig/dictionaryStack.fig similarity index 100% rename from Sda1/Ref/Fig/dictionaryStack.fig rename to Doc/Sda1/Ref/Fig/dictionaryStack.fig diff --git a/Sda1/Ref/Fig/domtree.fig b/Doc/Sda1/Ref/Fig/domtree.fig similarity index 100% rename from Sda1/Ref/Fig/domtree.fig rename to Doc/Sda1/Ref/Fig/domtree.fig diff --git a/Sda1/Ref/Fig/entityresolve.fig b/Doc/Sda1/Ref/Fig/entityresolve.fig similarity index 100% rename from Sda1/Ref/Fig/entityresolve.fig rename to Doc/Sda1/Ref/Fig/entityresolve.fig diff --git a/Sda1/Ref/Fig/externalize.fig b/Doc/Sda1/Ref/Fig/externalize.fig similarity index 100% rename from Sda1/Ref/Fig/externalize.fig rename to Doc/Sda1/Ref/Fig/externalize.fig diff --git a/Sda1/Ref/Fig/filtering.fig b/Doc/Sda1/Ref/Fig/filtering.fig similarity index 100% rename from Sda1/Ref/Fig/filtering.fig rename to Doc/Sda1/Ref/Fig/filtering.fig diff --git a/Sda1/Ref/Fig/firefoxrender.png b/Doc/Sda1/Ref/Fig/firefoxrender.png similarity index 100% rename from Sda1/Ref/Fig/firefoxrender.png rename to Doc/Sda1/Ref/Fig/firefoxrender.png diff --git a/Sda1/Ref/Fig/hacker.jpg b/Doc/Sda1/Ref/Fig/hacker.jpg similarity index 100% rename from Sda1/Ref/Fig/hacker.jpg rename to Doc/Sda1/Ref/Fig/hacker.jpg diff --git a/Sda1/Ref/Fig/headfoot.fig b/Doc/Sda1/Ref/Fig/headfoot.fig similarity index 100% rename from Sda1/Ref/Fig/headfoot.fig rename to Doc/Sda1/Ref/Fig/headfoot.fig diff --git a/Sda1/Ref/Fig/heartland.fig b/Doc/Sda1/Ref/Fig/heartland.fig similarity index 100% rename from Sda1/Ref/Fig/heartland.fig rename to Doc/Sda1/Ref/Fig/heartland.fig diff --git a/Sda1/Ref/Fig/impropernest.fig b/Doc/Sda1/Ref/Fig/impropernest.fig similarity index 100% rename from Sda1/Ref/Fig/impropernest.fig rename to Doc/Sda1/Ref/Fig/impropernest.fig diff --git a/Sda1/Ref/Fig/invoicedata.fig b/Doc/Sda1/Ref/Fig/invoicedata.fig similarity index 100% rename from Sda1/Ref/Fig/invoicedata.fig rename to Doc/Sda1/Ref/Fig/invoicedata.fig diff --git a/Sda1/Ref/Fig/invoicedataimplement.fig b/Doc/Sda1/Ref/Fig/invoicedataimplement.fig similarity index 100% rename from Sda1/Ref/Fig/invoicedataimplement.fig rename to Doc/Sda1/Ref/Fig/invoicedataimplement.fig diff --git a/Sda1/Ref/Fig/itemize.fo.pdf b/Doc/Sda1/Ref/Fig/itemize.fo.pdf similarity index 100% rename from Sda1/Ref/Fig/itemize.fo.pdf rename to Doc/Sda1/Ref/Fig/itemize.fo.pdf diff --git a/Sda1/Ref/Fig/jdbcFourTier.fig b/Doc/Sda1/Ref/Fig/jdbcFourTier.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcFourTier.fig rename to Doc/Sda1/Ref/Fig/jdbcFourTier.fig diff --git a/Sda1/Ref/Fig/jdbcObjectRelation.fig b/Doc/Sda1/Ref/Fig/jdbcObjectRelation.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcObjectRelation.fig rename to Doc/Sda1/Ref/Fig/jdbcObjectRelation.fig diff --git a/Sda1/Ref/Fig/jdbcReadWrite.fig b/Doc/Sda1/Ref/Fig/jdbcReadWrite.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcReadWrite.fig rename to Doc/Sda1/Ref/Fig/jdbcReadWrite.fig diff --git a/Sda1/Ref/Fig/jdbcSniffing.fig b/Doc/Sda1/Ref/Fig/jdbcSniffing.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcSniffing.fig rename to Doc/Sda1/Ref/Fig/jdbcSniffing.fig diff --git a/Sda1/Ref/Fig/jdbcThreeTier.fig b/Doc/Sda1/Ref/Fig/jdbcThreeTier.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcThreeTier.fig rename to Doc/Sda1/Ref/Fig/jdbcThreeTier.fig diff --git a/Sda1/Ref/Fig/jdbcarch.fig b/Doc/Sda1/Ref/Fig/jdbcarch.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcarch.fig rename to Doc/Sda1/Ref/Fig/jdbcarch.fig diff --git a/Sda1/Ref/Fig/jdbcread.fig b/Doc/Sda1/Ref/Fig/jdbcread.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcread.fig rename to Doc/Sda1/Ref/Fig/jdbcread.fig diff --git a/Sda1/Ref/Fig/jdbcurl.fig b/Doc/Sda1/Ref/Fig/jdbcurl.fig similarity index 100% rename from Sda1/Ref/Fig/jdbcurl.fig rename to Doc/Sda1/Ref/Fig/jdbcurl.fig diff --git a/Sda1/Ref/Fig/leader.fo.pdf b/Doc/Sda1/Ref/Fig/leader.fo.pdf similarity index 100% rename from Sda1/Ref/Fig/leader.fo.pdf rename to Doc/Sda1/Ref/Fig/leader.fo.pdf diff --git a/Sda1/Ref/Fig/leadermulti.fo.pdf b/Doc/Sda1/Ref/Fig/leadermulti.fo.pdf similarity index 100% rename from Sda1/Ref/Fig/leadermulti.fo.pdf rename to Doc/Sda1/Ref/Fig/leadermulti.fo.pdf diff --git a/Sda1/Ref/Fig/memofour.fig b/Doc/Sda1/Ref/Fig/memofour.fig similarity index 100% rename from Sda1/Ref/Fig/memofour.fig rename to Doc/Sda1/Ref/Fig/memofour.fig diff --git a/Sda1/Ref/Fig/memorelativexpath.fig b/Doc/Sda1/Ref/Fig/memorelativexpath.fig similarity index 100% rename from Sda1/Ref/Fig/memorelativexpath.fig rename to Doc/Sda1/Ref/Fig/memorelativexpath.fig diff --git a/Sda1/Ref/Fig/memotree.fig b/Doc/Sda1/Ref/Fig/memotree.fig similarity index 100% rename from Sda1/Ref/Fig/memotree.fig rename to Doc/Sda1/Ref/Fig/memotree.fig diff --git a/Sda1/Ref/Fig/memoxpath.fig b/Doc/Sda1/Ref/Fig/memoxpath.fig similarity index 100% rename from Sda1/Ref/Fig/memoxpath.fig rename to Doc/Sda1/Ref/Fig/memoxpath.fig diff --git a/Sda1/Ref/Fig/nodeHierarchy.svg b/Doc/Sda1/Ref/Fig/nodeHierarchy.svg similarity index 100% rename from Sda1/Ref/Fig/nodeHierarchy.svg rename to Doc/Sda1/Ref/Fig/nodeHierarchy.svg diff --git a/Sda1/Ref/Fig/overlay.fig b/Doc/Sda1/Ref/Fig/overlay.fig similarity index 100% rename from Sda1/Ref/Fig/overlay.fig rename to Doc/Sda1/Ref/Fig/overlay.fig diff --git a/Sda1/Ref/Fig/page.fo.1.eps b/Doc/Sda1/Ref/Fig/page.fo.1.eps similarity index 100% rename from Sda1/Ref/Fig/page.fo.1.eps rename to Doc/Sda1/Ref/Fig/page.fo.1.eps diff --git a/Sda1/Ref/Fig/page.fo.2.eps b/Doc/Sda1/Ref/Fig/page.fo.2.eps similarity index 100% rename from Sda1/Ref/Fig/page.fo.2.eps rename to Doc/Sda1/Ref/Fig/page.fo.2.eps diff --git a/Sda1/Ref/Fig/page.fo.3.eps b/Doc/Sda1/Ref/Fig/page.fo.3.eps similarity index 100% rename from Sda1/Ref/Fig/page.fo.3.eps rename to Doc/Sda1/Ref/Fig/page.fo.3.eps diff --git a/Sda1/Ref/Fig/page.fo.4.eps b/Doc/Sda1/Ref/Fig/page.fo.4.eps similarity index 100% rename from Sda1/Ref/Fig/page.fo.4.eps rename to Doc/Sda1/Ref/Fig/page.fo.4.eps diff --git a/Sda1/Ref/Fig/pageStack.fig b/Doc/Sda1/Ref/Fig/pageStack.fig similarity index 100% rename from Sda1/Ref/Fig/pageStack.fig rename to Doc/Sda1/Ref/Fig/pageStack.fig diff --git a/Sda1/Ref/Fig/pageref.1.fo.eps b/Doc/Sda1/Ref/Fig/pageref.1.fo.eps similarity index 100% rename from Sda1/Ref/Fig/pageref.1.fo.eps rename to Doc/Sda1/Ref/Fig/pageref.1.fo.eps diff --git a/Sda1/Ref/Fig/pageref.2.fo.eps b/Doc/Sda1/Ref/Fig/pageref.2.fo.eps similarity index 100% rename from Sda1/Ref/Fig/pageref.2.fo.eps rename to Doc/Sda1/Ref/Fig/pageref.2.fo.eps diff --git a/Sda1/Ref/Fig/pagerefStack.fig b/Doc/Sda1/Ref/Fig/pagerefStack.fig similarity index 100% rename from Sda1/Ref/Fig/pagerefStack.fig rename to Doc/Sda1/Ref/Fig/pagerefStack.fig diff --git a/Sda1/Ref/Fig/pagerefhyper.1.fo.eps b/Doc/Sda1/Ref/Fig/pagerefhyper.1.fo.eps similarity index 100% rename from Sda1/Ref/Fig/pagerefhyper.1.fo.eps rename to Doc/Sda1/Ref/Fig/pagerefhyper.1.fo.eps diff --git a/Sda1/Ref/Fig/pagerefhyper.2.fo.eps b/Doc/Sda1/Ref/Fig/pagerefhyper.2.fo.eps similarity index 100% rename from Sda1/Ref/Fig/pagerefhyper.2.fo.eps rename to Doc/Sda1/Ref/Fig/pagerefhyper.2.fo.eps diff --git a/Sda1/Ref/Fig/pagerefhyperStack.fig b/Doc/Sda1/Ref/Fig/pagerefhyperStack.fig similarity index 100% rename from Sda1/Ref/Fig/pagerefhyperStack.fig rename to Doc/Sda1/Ref/Fig/pagerefhyperStack.fig diff --git a/Sda1/Ref/Fig/persistHandlerStates.fig b/Doc/Sda1/Ref/Fig/persistHandlerStates.fig similarity index 100% rename from Sda1/Ref/Fig/persistHandlerStates.fig rename to Doc/Sda1/Ref/Fig/persistHandlerStates.fig diff --git a/Sda1/Ref/Fig/persistence.fig b/Doc/Sda1/Ref/Fig/persistence.fig similarity index 100% rename from Sda1/Ref/Fig/persistence.fig rename to Doc/Sda1/Ref/Fig/persistence.fig diff --git a/Sda1/Ref/Fig/persistentStates.fig b/Doc/Sda1/Ref/Fig/persistentStates.fig similarity index 100% rename from Sda1/Ref/Fig/persistentStates.fig rename to Doc/Sda1/Ref/Fig/persistentStates.fig diff --git a/Sda1/Ref/Fig/pitr_Syringe_icon.eps b/Doc/Sda1/Ref/Fig/pitr_Syringe_icon.eps similarity index 100% rename from Sda1/Ref/Fig/pitr_Syringe_icon.eps rename to Doc/Sda1/Ref/Fig/pitr_Syringe_icon.eps diff --git a/Sda1/Ref/Fig/pre.tex b/Doc/Sda1/Ref/Fig/pre.tex similarity index 100% rename from Sda1/Ref/Fig/pre.tex rename to Doc/Sda1/Ref/Fig/pre.tex diff --git a/Sda1/Ref/Fig/preceding.fig b/Doc/Sda1/Ref/Fig/preceding.fig similarity index 100% rename from Sda1/Ref/Fig/preceding.fig rename to Doc/Sda1/Ref/Fig/preceding.fig diff --git a/Sda1/Ref/Fig/propernest.fig b/Doc/Sda1/Ref/Fig/propernest.fig similarity index 100% rename from Sda1/Ref/Fig/propernest.fig rename to Doc/Sda1/Ref/Fig/propernest.fig diff --git a/Sda1/Ref/Fig/regions.fig b/Doc/Sda1/Ref/Fig/regions.fig similarity index 100% rename from Sda1/Ref/Fig/regions.fig rename to Doc/Sda1/Ref/Fig/regions.fig diff --git a/Sda1/Ref/Fig/saxapparch.odg b/Doc/Sda1/Ref/Fig/saxapparch.odg similarity index 100% rename from Sda1/Ref/Fig/saxapparch.odg rename to Doc/Sda1/Ref/Fig/saxapparch.odg diff --git a/Sda1/Ref/Fig/saxapparch.pdf b/Doc/Sda1/Ref/Fig/saxapparch.pdf similarity index 100% rename from Sda1/Ref/Fig/saxapparch.pdf rename to Doc/Sda1/Ref/Fig/saxapparch.pdf diff --git a/Sda1/Ref/Fig/saxcharacter.odg b/Doc/Sda1/Ref/Fig/saxcharacter.odg similarity index 100% rename from Sda1/Ref/Fig/saxcharacter.odg rename to Doc/Sda1/Ref/Fig/saxcharacter.odg diff --git a/Sda1/Ref/Fig/saxcharacter.pdf b/Doc/Sda1/Ref/Fig/saxcharacter.pdf similarity index 100% rename from Sda1/Ref/Fig/saxcharacter.pdf rename to Doc/Sda1/Ref/Fig/saxcharacter.pdf diff --git a/Sda1/Ref/Fig/saxmodel.odg b/Doc/Sda1/Ref/Fig/saxmodel.odg similarity index 100% rename from Sda1/Ref/Fig/saxmodel.odg rename to Doc/Sda1/Ref/Fig/saxmodel.odg diff --git a/Sda1/Ref/Fig/saxmodel.pdf b/Doc/Sda1/Ref/Fig/saxmodel.pdf similarity index 100% rename from Sda1/Ref/Fig/saxmodel.pdf rename to Doc/Sda1/Ref/Fig/saxmodel.pdf diff --git a/Sda1/Ref/Fig/saxxmlrdbms.fig b/Doc/Sda1/Ref/Fig/saxxmlrdbms.fig similarity index 100% rename from Sda1/Ref/Fig/saxxmlrdbms.fig rename to Doc/Sda1/Ref/Fig/saxxmlrdbms.fig diff --git a/Sda1/Ref/Fig/separate.fo.pdf b/Doc/Sda1/Ref/Fig/separate.fo.pdf similarity index 100% rename from Sda1/Ref/Fig/separate.fo.pdf rename to Doc/Sda1/Ref/Fig/separate.fo.pdf diff --git a/Sda1/Ref/Fig/sequenceDomParser.svg b/Doc/Sda1/Ref/Fig/sequenceDomParser.svg similarity index 100% rename from Sda1/Ref/Fig/sequenceDomParser.svg rename to Doc/Sda1/Ref/Fig/sequenceDomParser.svg diff --git a/Sda1/Ref/Fig/skull.eps b/Doc/Sda1/Ref/Fig/skull.eps similarity index 100% rename from Sda1/Ref/Fig/skull.eps rename to Doc/Sda1/Ref/Fig/skull.eps diff --git a/Sda1/Ref/Fig/sqlTransport.fig b/Doc/Sda1/Ref/Fig/sqlTransport.fig similarity index 100% rename from Sda1/Ref/Fig/sqlTransport.fig rename to Doc/Sda1/Ref/Fig/sqlTransport.fig diff --git a/Sda1/Ref/Fig/sqlTransportPrepare.fig b/Doc/Sda1/Ref/Fig/sqlTransportPrepare.fig similarity index 100% rename from Sda1/Ref/Fig/sqlTransportPrepare.fig rename to Doc/Sda1/Ref/Fig/sqlTransportPrepare.fig diff --git a/Sda1/Ref/Fig/sqlinject.fig b/Doc/Sda1/Ref/Fig/sqlinject.fig similarity index 100% rename from Sda1/Ref/Fig/sqlinject.fig rename to Doc/Sda1/Ref/Fig/sqlinject.fig diff --git a/Sda1/Ref/Fig/sqrtree.fig b/Doc/Sda1/Ref/Fig/sqrtree.fig similarity index 100% rename from Sda1/Ref/Fig/sqrtree.fig rename to Doc/Sda1/Ref/Fig/sqrtree.fig diff --git a/Sda1/Ref/Fig/sqrtrender.fig b/Doc/Sda1/Ref/Fig/sqrtrender.fig similarity index 100% rename from Sda1/Ref/Fig/sqrtrender.fig rename to Doc/Sda1/Ref/Fig/sqrtrender.fig diff --git a/Sda1/Ref/Fig/updateinfo.fig b/Doc/Sda1/Ref/Fig/updateinfo.fig similarity index 100% rename from Sda1/Ref/Fig/updateinfo.fig rename to Doc/Sda1/Ref/Fig/updateinfo.fig diff --git a/Sda1/Ref/Fig/wellformedandvalid.fig b/Doc/Sda1/Ref/Fig/wellformedandvalid.fig similarity index 100% rename from Sda1/Ref/Fig/wellformedandvalid.fig rename to Doc/Sda1/Ref/Fig/wellformedandvalid.fig diff --git a/Sda1/Ref/Fig/xhtml.fig b/Doc/Sda1/Ref/Fig/xhtml.fig similarity index 100% rename from Sda1/Ref/Fig/xhtml.fig rename to Doc/Sda1/Ref/Fig/xhtml.fig diff --git a/Sda1/Ref/Fig/xhtmlexample.fig b/Doc/Sda1/Ref/Fig/xhtmlexample.fig similarity index 100% rename from Sda1/Ref/Fig/xhtmlexample.fig rename to Doc/Sda1/Ref/Fig/xhtmlexample.fig diff --git a/Sda1/Ref/Fig/xml2fo2pdf.fig b/Doc/Sda1/Ref/Fig/xml2fo2pdf.fig similarity index 100% rename from Sda1/Ref/Fig/xml2fo2pdf.fig rename to Doc/Sda1/Ref/Fig/xml2fo2pdf.fig diff --git a/Sda1/Ref/Fig/xml2html.fig b/Doc/Sda1/Ref/Fig/xml2html.fig similarity index 100% rename from Sda1/Ref/Fig/xml2html.fig rename to Doc/Sda1/Ref/Fig/xml2html.fig diff --git a/Sda1/Ref/Fig/xmlattribandjava.fig b/Doc/Sda1/Ref/Fig/xmlattribandjava.fig similarity index 100% rename from Sda1/Ref/Fig/xmlattribandjava.fig rename to Doc/Sda1/Ref/Fig/xmlattribandjava.fig diff --git a/Sda1/Ref/Fig/xmlbase.fig b/Doc/Sda1/Ref/Fig/xmlbase.fig similarity index 100% rename from Sda1/Ref/Fig/xmlbase.fig rename to Doc/Sda1/Ref/Fig/xmlbase.fig diff --git a/Sda1/Ref/Fig/xpath.fig b/Doc/Sda1/Ref/Fig/xpath.fig similarity index 100% rename from Sda1/Ref/Fig/xpath.fig rename to Doc/Sda1/Ref/Fig/xpath.fig diff --git a/Sda1/Ref/Fig/xsl_id.fig b/Doc/Sda1/Ref/Fig/xsl_id.fig similarity index 100% rename from Sda1/Ref/Fig/xsl_id.fig rename to Doc/Sda1/Ref/Fig/xsl_id.fig diff --git a/Sda1/Ref/Fig/xslconvert.fig b/Doc/Sda1/Ref/Fig/xslconvert.fig similarity index 100% rename from Sda1/Ref/Fig/xslconvert.fig rename to Doc/Sda1/Ref/Fig/xslconvert.fig diff --git a/Sda1/Ref/Screen/dom-architecture.screen.png b/Doc/Sda1/Ref/Screen/dom-architecture.screen.png similarity index 100% rename from Sda1/Ref/Screen/dom-architecture.screen.png rename to Doc/Sda1/Ref/Screen/dom-architecture.screen.png diff --git a/Sda1/Ref/Screen/eclipseTestngResult.screen.png b/Doc/Sda1/Ref/Screen/eclipseTestngResult.screen.png similarity index 100% rename from Sda1/Ref/Screen/eclipseTestngResult.screen.png rename to Doc/Sda1/Ref/Screen/eclipseTestngResult.screen.png diff --git a/Sda1/Ref/Screen/employee.png b/Doc/Sda1/Ref/Screen/employee.png similarity index 100% rename from Sda1/Ref/Screen/employee.png rename to Doc/Sda1/Ref/Screen/employee.png diff --git a/Sda1/Ref/Screen/externalize.screen.png b/Doc/Sda1/Ref/Screen/externalize.screen.png similarity index 100% rename from Sda1/Ref/Screen/externalize.screen.png rename to Doc/Sda1/Ref/Screen/externalize.screen.png diff --git a/Sda1/Ref/Screen/externalize2.screen.png b/Doc/Sda1/Ref/Screen/externalize2.screen.png similarity index 100% rename from Sda1/Ref/Screen/externalize2.screen.png rename to Doc/Sda1/Ref/Screen/externalize2.screen.png diff --git a/Sda1/Ref/Screen/hello.screen.png b/Doc/Sda1/Ref/Screen/hello.screen.png similarity index 100% rename from Sda1/Ref/Screen/hello.screen.png rename to Doc/Sda1/Ref/Screen/hello.screen.png diff --git a/Sda1/Ref/Screen/insertValidate.screen.png b/Doc/Sda1/Ref/Screen/insertValidate.screen.png similarity index 100% rename from Sda1/Ref/Screen/insertValidate.screen.png rename to Doc/Sda1/Ref/Screen/insertValidate.screen.png diff --git a/Sda1/Ref/Screen/login.screen.png b/Doc/Sda1/Ref/Screen/login.screen.png similarity index 100% rename from Sda1/Ref/Screen/login.screen.png rename to Doc/Sda1/Ref/Screen/login.screen.png diff --git a/Sda1/Ref/Screen/mediaFormat.png b/Doc/Sda1/Ref/Screen/mediaFormat.png similarity index 100% rename from Sda1/Ref/Screen/mediaFormat.png rename to Doc/Sda1/Ref/Screen/mediaFormat.png diff --git a/Sda1/Ref/Screen/mozparaspancss.screen.png b/Doc/Sda1/Ref/Screen/mozparaspancss.screen.png similarity index 100% rename from Sda1/Ref/Screen/mozparaspancss.screen.png rename to Doc/Sda1/Ref/Screen/mozparaspancss.screen.png diff --git a/Sda1/Ref/Screen/pdfbookmarks.screen.png b/Doc/Sda1/Ref/Screen/pdfbookmarks.screen.png similarity index 100% rename from Sda1/Ref/Screen/pdfbookmarks.screen.png rename to Doc/Sda1/Ref/Screen/pdfbookmarks.screen.png diff --git a/Sda1/Ref/Screen/runConfigJarAnnot.screen.png b/Doc/Sda1/Ref/Screen/runConfigJarAnnot.screen.png similarity index 100% rename from Sda1/Ref/Screen/runConfigJarAnnot.screen.png rename to Doc/Sda1/Ref/Screen/runConfigJarAnnot.screen.png diff --git a/Sda1/Ref/Screen/simpleInsertGui.screen.png b/Doc/Sda1/Ref/Screen/simpleInsertGui.screen.png similarity index 100% rename from Sda1/Ref/Screen/simpleInsertGui.screen.png rename to Doc/Sda1/Ref/Screen/simpleInsertGui.screen.png diff --git a/Sda1/Ref/Screen/sqlInject.screen.png b/Doc/Sda1/Ref/Screen/sqlInject.screen.png similarity index 100% rename from Sda1/Ref/Screen/sqlInject.screen.png rename to Doc/Sda1/Ref/Screen/sqlInject.screen.png diff --git a/Sda1/Ref/Screen/sqlInjectPrepare.screen.png b/Doc/Sda1/Ref/Screen/sqlInjectPrepare.screen.png similarity index 100% rename from Sda1/Ref/Screen/sqlInjectPrepare.screen.png rename to Doc/Sda1/Ref/Screen/sqlInjectPrepare.screen.png diff --git a/Sda1/Ref/Screen/track.png b/Doc/Sda1/Ref/Screen/track.png similarity index 100% rename from Sda1/Ref/Screen/track.png rename to Doc/Sda1/Ref/Screen/track.png diff --git a/Sda1/Ref/Video/Makefile b/Doc/Sda1/Ref/Video/Makefile similarity index 100% rename from Sda1/Ref/Video/Makefile rename to Doc/Sda1/Ref/Video/Makefile diff --git a/Sda1/Ref/Video/connectauth.mp4 b/Doc/Sda1/Ref/Video/connectauth.mp4 similarity index 100% rename from Sda1/Ref/Video/connectauth.mp4 rename to Doc/Sda1/Ref/Video/connectauth.mp4 diff --git a/Sda1/Ref/Video/dataInsert.mp4 b/Doc/Sda1/Ref/Video/dataInsert.mp4 similarity index 100% rename from Sda1/Ref/Video/dataInsert.mp4 rename to Doc/Sda1/Ref/Video/dataInsert.mp4 diff --git a/Sda1/Ref/Video/dataInsert.txt b/Doc/Sda1/Ref/Video/dataInsert.txt similarity index 100% rename from Sda1/Ref/Video/dataInsert.txt rename to Doc/Sda1/Ref/Video/dataInsert.txt diff --git a/Sda1/Ref/Video/eclipseBasicSql.mp4 b/Doc/Sda1/Ref/Video/eclipseBasicSql.mp4 similarity index 100% rename from Sda1/Ref/Video/eclipseBasicSql.mp4 rename to Doc/Sda1/Ref/Video/eclipseBasicSql.mp4 diff --git a/Sda1/Ref/Video/eclipseBasicSql.txt b/Doc/Sda1/Ref/Video/eclipseBasicSql.txt similarity index 100% rename from Sda1/Ref/Video/eclipseBasicSql.txt rename to Doc/Sda1/Ref/Video/eclipseBasicSql.txt diff --git a/Sda1/Ref/Video/hibernateConfig.mp4 b/Doc/Sda1/Ref/Video/hibernateConfig.mp4 similarity index 100% rename from Sda1/Ref/Video/hibernateConfig.mp4 rename to Doc/Sda1/Ref/Video/hibernateConfig.mp4 diff --git a/Sda1/Ref/Video/hibernateConfig.txt b/Doc/Sda1/Ref/Video/hibernateConfig.txt similarity index 100% rename from Sda1/Ref/Video/hibernateConfig.txt rename to Doc/Sda1/Ref/Video/hibernateConfig.txt diff --git a/Sda1/Ref/Video/jdbcConnection.mp4 b/Doc/Sda1/Ref/Video/jdbcConnection.mp4 similarity index 100% rename from Sda1/Ref/Video/jdbcConnection.mp4 rename to Doc/Sda1/Ref/Video/jdbcConnection.mp4 diff --git a/Sda1/Ref/Video/jdbcConnection.txt b/Doc/Sda1/Ref/Video/jdbcConnection.txt similarity index 100% rename from Sda1/Ref/Video/jdbcConnection.txt rename to Doc/Sda1/Ref/Video/jdbcConnection.txt diff --git a/Sda1/Ref/Video/jdbcDriverConfig.mp4 b/Doc/Sda1/Ref/Video/jdbcDriverConfig.mp4 similarity index 100% rename from Sda1/Ref/Video/jdbcDriverConfig.mp4 rename to Doc/Sda1/Ref/Video/jdbcDriverConfig.mp4 diff --git a/Sda1/Ref/Video/jdbcDriverConfig.txt b/Doc/Sda1/Ref/Video/jdbcDriverConfig.txt similarity index 100% rename from Sda1/Ref/Video/jdbcDriverConfig.txt rename to Doc/Sda1/Ref/Video/jdbcDriverConfig.txt diff --git a/Sda1/Ref/src/Dom/catalog2fo.final.xsl b/Doc/Sda1/Ref/src/Dom/catalog2fo.final.xsl similarity index 100% rename from Sda1/Ref/src/Dom/catalog2fo.final.xsl rename to Doc/Sda1/Ref/src/Dom/catalog2fo.final.xsl diff --git a/Sda1/Ref/src/Dom/catalog2fo.product.xsl b/Doc/Sda1/Ref/src/Dom/catalog2fo.product.xsl similarity index 100% rename from Sda1/Ref/src/Dom/catalog2fo.product.xsl rename to Doc/Sda1/Ref/src/Dom/catalog2fo.product.xsl diff --git a/Sda1/Ref/src/Dom/catalog2fo.start.xsl b/Doc/Sda1/Ref/src/Dom/catalog2fo.start.xsl similarity index 100% rename from Sda1/Ref/src/Dom/catalog2fo.start.xsl rename to Doc/Sda1/Ref/src/Dom/catalog2fo.start.xsl diff --git a/Sda1/Ref/src/Dom/catalog2fo.toc.xsl b/Doc/Sda1/Ref/src/Dom/catalog2fo.toc.xsl similarity index 100% rename from Sda1/Ref/src/Dom/catalog2fo.toc.xsl rename to Doc/Sda1/Ref/src/Dom/catalog2fo.toc.xsl diff --git a/Sda1/Ref/src/Dom/catalog2fo.toclink.xsl b/Doc/Sda1/Ref/src/Dom/catalog2fo.toclink.xsl similarity index 100% rename from Sda1/Ref/src/Dom/catalog2fo.toclink.xsl rename to Doc/Sda1/Ref/src/Dom/catalog2fo.toclink.xsl diff --git a/Sda1/Ref/src/Dom/climbenriched.final.pdf b/Doc/Sda1/Ref/src/Dom/climbenriched.final.pdf similarity index 100% rename from Sda1/Ref/src/Dom/climbenriched.final.pdf rename to Doc/Sda1/Ref/src/Dom/climbenriched.final.pdf diff --git a/Sda1/Ref/src/Dom/climbenriched.product.pdf b/Doc/Sda1/Ref/src/Dom/climbenriched.product.pdf similarity index 100% rename from Sda1/Ref/src/Dom/climbenriched.product.pdf rename to Doc/Sda1/Ref/src/Dom/climbenriched.product.pdf diff --git a/Sda1/Ref/src/Dom/climbenriched.start.pdf b/Doc/Sda1/Ref/src/Dom/climbenriched.start.pdf similarity index 100% rename from Sda1/Ref/src/Dom/climbenriched.start.pdf rename to Doc/Sda1/Ref/src/Dom/climbenriched.start.pdf diff --git a/Sda1/Ref/src/Dom/climbenriched.toc.pdf b/Doc/Sda1/Ref/src/Dom/climbenriched.toc.pdf similarity index 100% rename from Sda1/Ref/src/Dom/climbenriched.toc.pdf rename to Doc/Sda1/Ref/src/Dom/climbenriched.toc.pdf diff --git a/Sda1/Ref/src/Dom/climbenriched.toclink.pdf b/Doc/Sda1/Ref/src/Dom/climbenriched.toclink.pdf similarity index 100% rename from Sda1/Ref/src/Dom/climbenriched.toclink.pdf rename to Doc/Sda1/Ref/src/Dom/climbenriched.toclink.pdf diff --git a/Sda1/Ref/src/Dtd/book/v5/book.xsd b/Doc/Sda1/Ref/src/Dtd/book/v5/book.xsd similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/book.xsd rename to Doc/Sda1/Ref/src/Dtd/book/v5/book.xsd diff --git a/Sda1/Ref/src/Dtd/book/v5/book2chunks.1.xsl b/Doc/Sda1/Ref/src/Dtd/book/v5/book2chunks.1.xsl similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/book2chunks.1.xsl rename to Doc/Sda1/Ref/src/Dtd/book/v5/book2chunks.1.xsl diff --git a/Sda1/Ref/src/Dtd/book/v5/book2html.1.xsl b/Doc/Sda1/Ref/src/Dtd/book/v5/book2html.1.xsl similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/book2html.1.xsl rename to Doc/Sda1/Ref/src/Dtd/book/v5/book2html.1.xsl diff --git a/Sda1/Ref/src/Dtd/book/v5/chap1.xml b/Doc/Sda1/Ref/src/Dtd/book/v5/chap1.xml similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/chap1.xml rename to Doc/Sda1/Ref/src/Dtd/book/v5/chap1.xml diff --git a/Sda1/Ref/src/Dtd/book/v5/chap2.xml b/Doc/Sda1/Ref/src/Dtd/book/v5/chap2.xml similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/chap2.xml rename to Doc/Sda1/Ref/src/Dtd/book/v5/chap2.xml diff --git a/Sda1/Ref/src/Dtd/book/v5/java.xml b/Doc/Sda1/Ref/src/Dtd/book/v5/java.xml similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/java.xml rename to Doc/Sda1/Ref/src/Dtd/book/v5/java.xml diff --git a/Sda1/Ref/src/Dtd/book/v5/master.xml b/Doc/Sda1/Ref/src/Dtd/book/v5/master.xml similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/master.xml rename to Doc/Sda1/Ref/src/Dtd/book/v5/master.xml diff --git a/Sda1/Ref/src/Dtd/book/v5/table.xsd b/Doc/Sda1/Ref/src/Dtd/book/v5/table.xsd similarity index 100% rename from Sda1/Ref/src/Dtd/book/v5/table.xsd rename to Doc/Sda1/Ref/src/Dtd/book/v5/table.xsd diff --git a/Sda1/Ref/src/Memo.1/memo.xsd b/Doc/Sda1/Ref/src/Memo.1/memo.xsd similarity index 100% rename from Sda1/Ref/src/Memo.1/memo.xsd rename to Doc/Sda1/Ref/src/Memo.1/memo.xsd diff --git a/Sda1/Ref/src/Memo.1/message.xml b/Doc/Sda1/Ref/src/Memo.1/message.xml similarity index 100% rename from Sda1/Ref/src/Memo.1/message.xml rename to Doc/Sda1/Ref/src/Memo.1/message.xml diff --git a/Sda1/Ref/src/sorttable.js b/Doc/Sda1/Ref/src/sorttable.js similarity index 100% rename from Sda1/Ref/src/sorttable.js rename to Doc/Sda1/Ref/src/sorttable.js diff --git a/Sda1/Ref/src/tablesort.html b/Doc/Sda1/Ref/src/tablesort.html similarity index 100% rename from Sda1/Ref/src/tablesort.html rename to Doc/Sda1/Ref/src/tablesort.html diff --git a/Sda1/dom.xml b/Doc/Sda1/dom.xml similarity index 100% rename from Sda1/dom.xml rename to Doc/Sda1/dom.xml diff --git a/Sda1/fo.xml b/Doc/Sda1/fo.xml similarity index 100% rename from Sda1/fo.xml rename to Doc/Sda1/fo.xml diff --git a/Sda1/jdbc.xml b/Doc/Sda1/jdbc.xml similarity index 100% rename from Sda1/jdbc.xml rename to Doc/Sda1/jdbc.xml diff --git a/Sda1/prerequisites.xml b/Doc/Sda1/prerequisites.xml similarity index 100% rename from Sda1/prerequisites.xml rename to Doc/Sda1/prerequisites.xml diff --git a/Sda1/sax.xml b/Doc/Sda1/sax.xml similarity index 100% rename from Sda1/sax.xml rename to Doc/Sda1/sax.xml diff --git a/Sda1/schema.xml b/Doc/Sda1/schema.xml similarity index 100% rename from Sda1/schema.xml rename to Doc/Sda1/schema.xml diff --git a/Sda1/testng.xml b/Doc/Sda1/testng.xml similarity index 100% rename from Sda1/testng.xml rename to Doc/Sda1/testng.xml diff --git a/Sda1/try.xml b/Doc/Sda1/try.xml similarity index 100% rename from Sda1/try.xml rename to Doc/Sda1/try.xml diff --git a/Sda1/xmlintro.xml b/Doc/Sda1/xmlintro.xml similarity index 100% rename from Sda1/xmlintro.xml rename to Doc/Sda1/xmlintro.xml diff --git a/Sda1/xmlschema.xml b/Doc/Sda1/xmlschema.xml similarity index 100% rename from Sda1/xmlschema.xml rename to Doc/Sda1/xmlschema.xml diff --git a/Sda1/xslt.xml b/Doc/Sda1/xslt.xml similarity index 100% rename from Sda1/xslt.xml rename to Doc/Sda1/xslt.xml diff --git a/Sda2/Ref/Fig/Makefile b/Doc/Sda2/Ref/Fig/Makefile similarity index 100% rename from Sda2/Ref/Fig/Makefile rename to Doc/Sda2/Ref/Fig/Makefile diff --git a/Sda2/Ref/Fig/billing.fig b/Doc/Sda2/Ref/Fig/billing.fig similarity index 100% rename from Sda2/Ref/Fig/billing.fig rename to Doc/Sda2/Ref/Fig/billing.fig diff --git a/Sda2/Ref/Fig/billingData.fig b/Doc/Sda2/Ref/Fig/billingData.fig similarity index 100% rename from Sda2/Ref/Fig/billingData.fig rename to Doc/Sda2/Ref/Fig/billingData.fig diff --git a/Sda2/Ref/Fig/billingMapJoined.fig b/Doc/Sda2/Ref/Fig/billingMapJoined.fig similarity index 100% rename from Sda2/Ref/Fig/billingMapJoined.fig rename to Doc/Sda2/Ref/Fig/billingMapJoined.fig diff --git a/Sda2/Ref/Fig/billingSql.fig b/Doc/Sda2/Ref/Fig/billingSql.fig similarity index 100% rename from Sda2/Ref/Fig/billingSql.fig rename to Doc/Sda2/Ref/Fig/billingSql.fig diff --git a/Sda2/Ref/Fig/classUser.fig b/Doc/Sda2/Ref/Fig/classUser.fig similarity index 100% rename from Sda2/Ref/Fig/classUser.fig rename to Doc/Sda2/Ref/Fig/classUser.fig diff --git a/Sda2/Ref/Fig/concurrentOptimistic.svg b/Doc/Sda2/Ref/Fig/concurrentOptimistic.svg similarity index 100% rename from Sda2/Ref/Fig/concurrentOptimistic.svg rename to Doc/Sda2/Ref/Fig/concurrentOptimistic.svg diff --git a/Sda2/Ref/Fig/concurrentOptimisticFail.svg b/Doc/Sda2/Ref/Fig/concurrentOptimisticFail.svg similarity index 100% rename from Sda2/Ref/Fig/concurrentOptimisticFail.svg rename to Doc/Sda2/Ref/Fig/concurrentOptimisticFail.svg diff --git a/Sda2/Ref/Fig/figureInherit.fig b/Doc/Sda2/Ref/Fig/figureInherit.fig similarity index 100% rename from Sda2/Ref/Fig/figureInherit.fig rename to Doc/Sda2/Ref/Fig/figureInherit.fig diff --git a/Sda2/Ref/Fig/jaxRs.svg b/Doc/Sda2/Ref/Fig/jaxRs.svg similarity index 100% rename from Sda2/Ref/Fig/jaxRs.svg rename to Doc/Sda2/Ref/Fig/jaxRs.svg diff --git a/Sda2/Ref/Fig/jpacache.svg b/Doc/Sda2/Ref/Fig/jpacache.svg similarity index 100% rename from Sda2/Ref/Fig/jpacache.svg rename to Doc/Sda2/Ref/Fig/jpacache.svg diff --git a/Sda2/Ref/Fig/mapInherit.svg b/Doc/Sda2/Ref/Fig/mapInherit.svg similarity index 100% rename from Sda2/Ref/Fig/mapInherit.svg rename to Doc/Sda2/Ref/Fig/mapInherit.svg diff --git a/Sda2/Ref/Fig/mapUser.fig b/Doc/Sda2/Ref/Fig/mapUser.fig similarity index 100% rename from Sda2/Ref/Fig/mapUser.fig rename to Doc/Sda2/Ref/Fig/mapUser.fig diff --git a/Sda2/Ref/Fig/mapUserIntegrity.fig b/Doc/Sda2/Ref/Fig/mapUserIntegrity.fig similarity index 100% rename from Sda2/Ref/Fig/mapUserIntegrity.fig rename to Doc/Sda2/Ref/Fig/mapUserIntegrity.fig diff --git a/Sda2/Ref/Fig/mavenIntro.fig b/Doc/Sda2/Ref/Fig/mavenIntro.fig similarity index 100% rename from Sda2/Ref/Fig/mavenIntro.fig rename to Doc/Sda2/Ref/Fig/mavenIntro.fig diff --git a/Sda2/Ref/Fig/persistProvider.fig b/Doc/Sda2/Ref/Fig/persistProvider.fig similarity index 100% rename from Sda2/Ref/Fig/persistProvider.fig rename to Doc/Sda2/Ref/Fig/persistProvider.fig diff --git a/Sda2/Ref/Fig/pre.tex b/Doc/Sda2/Ref/Fig/pre.tex similarity index 100% rename from Sda2/Ref/Fig/pre.tex rename to Doc/Sda2/Ref/Fig/pre.tex diff --git a/Sda2/Ref/Fig/transitiveDep.fig b/Doc/Sda2/Ref/Fig/transitiveDep.fig similarity index 100% rename from Sda2/Ref/Fig/transitiveDep.fig rename to Doc/Sda2/Ref/Fig/transitiveDep.fig diff --git a/Sda2/Ref/Screen/CreateMaven/1.png b/Doc/Sda2/Ref/Screen/CreateMaven/1.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/1.png rename to Doc/Sda2/Ref/Screen/CreateMaven/1.png diff --git a/Sda2/Ref/Screen/CreateMaven/2.png b/Doc/Sda2/Ref/Screen/CreateMaven/2.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/2.png rename to Doc/Sda2/Ref/Screen/CreateMaven/2.png diff --git a/Sda2/Ref/Screen/CreateMaven/3.png b/Doc/Sda2/Ref/Screen/CreateMaven/3.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/3.png rename to Doc/Sda2/Ref/Screen/CreateMaven/3.png diff --git a/Sda2/Ref/Screen/CreateMaven/4.png b/Doc/Sda2/Ref/Screen/CreateMaven/4.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/4.png rename to Doc/Sda2/Ref/Screen/CreateMaven/4.png diff --git a/Sda2/Ref/Screen/CreateMaven/5.png b/Doc/Sda2/Ref/Screen/CreateMaven/5.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/5.png rename to Doc/Sda2/Ref/Screen/CreateMaven/5.png diff --git a/Sda2/Ref/Screen/CreateMaven/6.png b/Doc/Sda2/Ref/Screen/CreateMaven/6.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/6.png rename to Doc/Sda2/Ref/Screen/CreateMaven/6.png diff --git a/Sda2/Ref/Screen/CreateMaven/mysql1.png b/Doc/Sda2/Ref/Screen/CreateMaven/mysql1.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/mysql1.png rename to Doc/Sda2/Ref/Screen/CreateMaven/mysql1.png diff --git a/Sda2/Ref/Screen/CreateMaven/mysql2.png b/Doc/Sda2/Ref/Screen/CreateMaven/mysql2.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/mysql2.png rename to Doc/Sda2/Ref/Screen/CreateMaven/mysql2.png diff --git a/Sda2/Ref/Screen/CreateMaven/mysql3.png b/Doc/Sda2/Ref/Screen/CreateMaven/mysql3.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/mysql3.png rename to Doc/Sda2/Ref/Screen/CreateMaven/mysql3.png diff --git a/Sda2/Ref/Screen/CreateMaven/mysql4.png b/Doc/Sda2/Ref/Screen/CreateMaven/mysql4.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/mysql4.png rename to Doc/Sda2/Ref/Screen/CreateMaven/mysql4.png diff --git a/Sda2/Ref/Screen/CreateMaven/mysql5.png b/Doc/Sda2/Ref/Screen/CreateMaven/mysql5.png similarity index 100% rename from Sda2/Ref/Screen/CreateMaven/mysql5.png rename to Doc/Sda2/Ref/Screen/CreateMaven/mysql5.png diff --git a/Sda2/Ref/Screen/accountTransferSum.png b/Doc/Sda2/Ref/Screen/accountTransferSum.png similarity index 100% rename from Sda2/Ref/Screen/accountTransferSum.png rename to Doc/Sda2/Ref/Screen/accountTransferSum.png diff --git a/Sda2/Ref/Screen/ldapSampleUsers.png b/Doc/Sda2/Ref/Screen/ldapSampleUsers.png similarity index 100% rename from Sda2/Ref/Screen/ldapSampleUsers.png rename to Doc/Sda2/Ref/Screen/ldapSampleUsers.png diff --git a/Doc/Sda2/jax-rs.xml b/Doc/Sda2/jax-rs.xml new file mode 100644 index 0000000000000000000000000000000000000000..86d0a6fd7be3ec9df8c357e9d1c53691d707579b --- /dev/null +++ b/Doc/Sda2/jax-rs.xml @@ -0,0 +1,15 @@ + <chapter xml:id="jax-rs" version="5.0" xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title>REST applications based on <xref linkend="glo_Java"/>-rs</title> + + <para><link xlink:href="Ref/Fig/jaxRs.svg">Introductory + slides</link>.</para> + + <para>Sample chapters from <xref linkend="bib_Burke13"/> available at <uri + xlink:href="https://github.com/oreillymedia/restful_java_jax-rs_2_0">https://github.com/oreillymedia/restful_java_jax-rs_2_0</uri>.</para> + </chapter> diff --git a/Sda2/sda2.xml b/Doc/Sda2/jpa.xml similarity index 80% rename from Sda2/sda2.xml rename to Doc/Sda2/jpa.xml index 1e265ae5634bb2cedc688bfa83e2606260e708a9..cb4b1b0151ac2a3d78668341ec707fdd01dcd628 100644 --- a/Sda2/sda2.xml +++ b/Doc/Sda2/jpa.xml @@ -1,794 +1,10 @@ -<?xml version="1.0" encoding="UTF-8"?> -<book version="5.0" xmlns="http://docbook.org/ns/docbook" + <chapter xml:id="jpa" version="5.0" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:svg="http://www.w3.org/2000/svg" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:db="http://docbook.org/ns/docbook"> - <info> - <title>Structured data and applications 2</title> - - <author> - <personname><firstname>Martin</firstname> - <surname>Goik</surname></personname> - - <affiliation> - <orgname>http://medieninformatik.hdm-stuttgart.de</orgname> - </affiliation> - </author> - - <legalnotice> - <para>Source code available at <uri - xlink:href="https://version.mi.hdm-stuttgart.de/git/GoikLectures">https://version.mi.hdm-stuttgart.de/git/GoikLectures</uri></para> - </legalnotice> - </info> - - <chapter xml:id="ldap"> - <title><link linkend="glo_LDAP">ldap</link> and <link - linkend="glo_JDBC">JDBC</link></title> - - <section xml:id="ldapIntro"> - <title>Getting started with <xref linkend="glo_LDAP"/></title> - - <para>Resources:</para> - - <itemizedlist> - <listitem> - <para><link - xlink:href="http://www.zytrax.com/books/ldap/ch3">Schema, - objectclasses and attributes</link></para> - </listitem> - - <listitem> - <para><link xlink:href="http://www.zytrax.com/books/ldap/apd">LDAP - Glossary</link></para> - </listitem> - </itemizedlist> - </section> - - <section xml:id="ldapSetup"> - <title>Setting up an <productname - xlink:href="http://www.openldap.org">Openldap</productname> - server</title> - - <para>The MI department provides an <productname - xlink:href="http://www.openldap.org">Openldap</productname> server at - each workstation (<productname - xlink:href="http://www.ubuntu.com/desktop">Ubuntu</productname> / Linux - only). The <xref linkend="glo_LDAP"/> manager credentials are:</para> - - <glosslist> - <glossentry> - <glossterm>Bind <xref linkend="glo_DN"/>:</glossterm> - - <glossdef> - <para><code>cn=admin,dc=hdm-stuttgart,dc=de</code></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Bind password:</glossterm> - - <glossdef> - <para><code>XYZ</code></para> - </glossdef> - </glossentry> - </glosslist> - - <para>In addition <xref linkend="glo_ApacheDirectoryStudio"/> is in - place and may serve as a means to conveniently establish <xref - linkend="glo_LDAP"/> communications. Console geeks may use <command - xlink:href="http://tldp.org/HOWTO/LDAP-HOWTO/utilities.html">ldapmodify</command> - and friends.</para> - - <task> - <title>Set up a connection to your local <xref linkend="glo_LDAP"/> - server</title> - - <procedure> - <step> - <para>Open <xref linkend="glo_ApacheDirectoryStudio"/>.</para> - </step> - - <step> - <para>Activate the <xref linkend="glo_LDAP"/> perspective.</para> - </step> - - <step> - <para>In the <quote>Connections</quote> window right click - <quote>New Connection ...</quote> like in <uri - xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_create_connection.html">http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_create_connection.html</uri>.</para> - </step> - - <step> - <para>Configure a connection to <parameter - xlink:href="http://www.techterms.com/definition/localhost">localhost</parameter> - using the above bind parameters.</para> - </step> - </procedure> - </task> - </section> - - <section xml:id="ldapSimpleInserts"> - <title>Adding some sample data using <xref - linkend="glo_ApacheDirectoryStudio"/></title> - - <qandaset defaultlabel="qanda" xml:id="qandaPopulateLdap"> - <title>Populating the <xref linkend="glo_DIT"/></title> - - <qandadiv> - <qandaentry> - <question> - <para>Add two departments <code>billing</code> and - <code>research</code>. Then supply corresponding user entries to - both departments by using the <link - xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_browse.html">LDAP - browser view</link>. (As being mentioned previously hardcore - hackers take <link - xlink:href="http://tldp.org/HOWTO/LDAP-HOWTO/utilities.html">this - track</link> neglecting time consuming <xref linkend="glo_GUI"/> - stuff).</para> - - <para>Hint: If you do have limited understanding of <xref - linkend="glo_LDAP"/> classes an schemata you may want to create - entries containing the following <parameter - xlink:href="http://www.zytrax.com/books/ldap/apd/index.html#objectclass">objectClass</parameter> - values:</para> - - <glosslist> - <glossentry> - <glossterm>Departments <code>billing</code> and - <code>research</code>:</glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para><code - xlink:href="http://www.zytrax.com/books/ldap/ape/#organizationalunit">organizationalUnit</code> - (structural)</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Child user entries below <code>billing</code> and - <code>research</code>:</glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para><code - xlink:href="http://www.zytrax.com/books/ldap/ape/#organizationalperson">organizationalPerson</code> - (structural) and <code - xlink:href="http://www.zytrax.com/books/ldap/ape/#posixaccount">posixAccount</code> - (auxiliary)</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - </glosslist> - - <para>Note that required parent <parameter - xlink:href="http://www.zytrax.com/books/ldap/apd/index.html#objectclass">objectClass</parameter> - definitions like <code>top</code> and <code - xlink:href="http://www.zytrax.com/books/ldap/ape/#person">person</code> - are being omitted here. <xref - linkend="glo_ApacheDirectoryStudio"/> will gracefully add - missing objectClasses on behalf of you automatically. The - subsequent <xref linkend="glo_LDIF"/> dump may serve as a - hint:</para> - - <programlisting language="none">... - <emphasis role="bold">dn: ou=billing,dc=hdm-stuttgart,dc=de</emphasis> - objectClass: top - objectClass: organizationalUnit - ou: billing - - <emphasis role="bold">dn: ou=research,dc=hdm-stuttgart,dc=de</emphasis> - objectClass: top - objectClass: organizationalUnit - ou: research - - <emphasis role="bold">dn: uid=lapinski,ou=billing,dc=hdm-stuttgart,dc=de</emphasis> - objectClass: posixAccount - objectClass: top - objectClass: person - objectClass: organizationalPerson - cn: Mee Lapinski - gidNumber: 100 - homeDirectory: /home/lapinski - sn: Lapinski - uid: lapinski - uidNumber: 1023 - ...</programlisting> - - <para>Question: What is the ratio behind adding the - <code>objectClass</code> value <code>posixAccount</code>? Hint: - Try to create a corresponding dataset having two persons with - identical names within the same department.</para> - </question> - - <answer> - <para>Your result may look like:</para> - - <figure xml:id="figureLdapTwoDepartments"> - <title>Two departments billing and research populated with - sample user entries</title> - - <screenshot> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Screen/ldapSampleUsers.png"/> - </imageobject> - </mediaobject> - </screenshot> - </figure> - - <para>Without having the <code>objectClass</code> value - <code>posixAccount</code> the attribute <code>uid</code> would - be disallowed and could thus not be part of our <xref - linkend="glo_DN"/> values. This would leave us with solutions - like:</para> - - <programlisting language="none"><emphasis role="bold">dn: cn=Mee Lapinski,ou=billing,dc=hdm-stuttgart,dc=de</emphasis></programlisting> - - <para>This in turn disallows identical common names (e.g. a - second <personname>Mee Lapinski</personname>) within the same - department. Thus the auxiliary objectClass posixAccount enables - us to introduce additional mandatory <code>uid</code> attribute - being the unique identifier within a given parent scope.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="ldifImportExport"> - <title><xref linkend="glo_LDIF"/> export and import</title> - - <para>This section is intended to get acquainted with <xref - linkend="glo_LDIF"/> representation of <xref linkend="glo_LDAP"/> data - and requires successful completion of <xref - linkend="qandaPopulateLdap"/> as a prerequisite. You may want to read - <uri - xlink:href="http://www.zytrax.com/books/ldap/ch8">http://www.zytrax.com/books/ldap/ch8</uri>.</para> - - <qandaset defaultlabel="qanda" xml:id="qanda_ldifExportImport"> - <title>Exporting, modifying and importing <xref linkend="glo_LDAP"/> - data using the <xref linkend="glo_LDIF"/> interchange - representation.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Export your current database state being left from <xref - linkend="qandaPopulateLdap"/> to an <xref linkend="glo_LDIF"/> - text file.</para> - - <para>Subsequently use this database dump file as a starting - point to create a <xref linkend="glo_LDIF"/> import file adding - a department <quote>pr</quote> (public relations) containing a - user <quote>Paul Simon</quote> with suitable attribute values to - the dataset.</para> - </question> - - <answer> - <para>Adding the new entries in question requires:</para> - - <programlisting language="none">version: 1 - - dn: ou=pr,dc=hdm-stuttgart,dc=de - objectClass: top - objectClass: organizationalUnit - ou: pr - - dn: uid=simon,ou=pr,dc=hdm-stuttgart,dc=de - objectClass: posixAccount - objectClass: top - objectClass: person - objectClass: organizationalPerson - cn: Paul Simon - gidNumber: 130 - homeDirectory: /home/tauras - sn: Svetlana - uid: tauras - uidNumber: 1028</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="ditSearch"> - <title>Searching the <xref linkend="glo_DIT"/></title> - - <para>Like relational and other database types <xref - linkend="glo_LDAP"/> provides a <link - xlink:href="http://www.zytrax.com/books/ldap/apa/search.html">query - language</link> to filter result entries.</para> - - <qandaset defaultlabel="qanda" xml:id="qanda_firstLdapQuery"> - <title>Filtering child elements</title> - - <qandadiv> - <qandaentry> - <question> - <para>Create <xref linkend="glo_LDAP"/> queries corresponding to - the following descriptions:</para> - - <orderedlist> - <listitem> - <para>All users entries within the whole <xref - linkend="glo_DIT"/> having a gidNumber value of 100.</para> - </listitem> - - <listitem> - <para>All user entries belonging to the billing department - having a <code>uid</code> value greater than 1023.</para> - </listitem> - - <listitem> - <para>All user entries within the whole <xref - linkend="glo_DIT"/> having a common name containing the - substring <quote>ei</quote>.</para> - </listitem> - - <listitem> - <para>All user entries within the whole <xref - linkend="glo_DIT"/> belonging to gidNumber == 100 or having - a <code>uid</code> value starting with letter - <quote>t</quote>.</para> - </listitem> - </orderedlist> - - <para>Hint: <xref linkend="glo_ApacheDirectoryStudio"/> allows - both for <link - xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/tools_filter_editor_dialog.html">filtering</link> - and <link - xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_search.html">searching</link> - providing nifty features like attribute name completion and - syntax highlighting. For regular searches you may define:</para> - - <itemizedlist> - <listitem> - <para>The <xref linkend="glo_DIT"/> entry to start from - being identified by its <xref linkend="glo_DN"/>.</para> - </listitem> - - <listitem> - <para>The search scope being either of object, one level or - subtree.</para> - </listitem> - - <listitem> - <para>Boolean expressions based on attribute values.</para> - </listitem> - </itemizedlist> - - <para>But yes, I forgot to mention <link - xlink:href="http://tldp.org/HOWTO/LDAP-HOWTO/utilities.html">something</link>.</para> - </question> - - <answer> - <orderedlist> - <listitem> - <para><emphasis role="bold">All users entries within the - whole </emphasis><xref linkend="glo_DIT"/><emphasis - role="bold"> having a gidNumber value of - 100.</emphasis></para> - - <para>Solution: <code>(gidNumber=100)</code>, starting from - top of <xref linkend="glo_DIT"/> having subtree - scope.</para> - </listitem> - - <listitem> - <para><emphasis role="bold">All user entries belonging to - the billing department having a <code>uid</code> value - greater than 1023.</emphasis></para> - - <para>Solution: <code>(uidNumber>=1024)</code> starting - from <xref linkend="glo_DN"/> - <code>ou=billing,dc=hdm-stuttgart,dc=de</code> and scope - <code>one level</code>.</para> - - <para>Notice the expression - <code>(uidNumber>=1024)</code> in favour of the seemingly - equivalent but syntactically illegal counterpart - <code>(uidNumber>1023)</code>.</para> - </listitem> - - <listitem> - <para><emphasis role="bold">All user entries within the - whole </emphasis><xref linkend="glo_DIT"/><emphasis - role="bold"> having a common name containing the substring - <quote>ei</quote>.</emphasis></para> - - <para>Solution: <code>(cn=*ei*)</code>, starting from top of - <xref linkend="glo_DIT"/> having subtree scope.</para> - </listitem> - - <listitem> - <para><emphasis role="bold">All user entries within the - whole </emphasis><xref linkend="glo_DIT"/><emphasis - role="bold"> belonging to gidNumber == 100 or having a - <code>uid</code> value starting with letter - <quote>t</quote>.</emphasis></para> - - <para>Solution: <code>(|(gidNumber=100)(uid=t*))</code>, - starting from top of <xref linkend="glo_DIT"/> having - subtree scope.</para> - </listitem> - </orderedlist> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="unix2sql2ldap"> - <title><xref linkend="glo_UNIX"/> to <xref linkend="glo_SQL"/> to <xref - linkend="glo_LDAP"/></title> - - <para><xref linkend="glo_UNIX"/> type operating systems manage users, - groups and their respective relationships in three different text - files:</para> - - <glosslist> - <glossentry> - <glossterm><filename>/etc/passwd</filename></glossterm> - - <glossdef> - <para>Users being defined on the system:</para> - - <programlisting language="none">root:x:0:0:root:/root:/bin/bash - daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin - bin:x:2:2:bin:/bin:/usr/sbin/nologin - sys:x:3:3:sys:/dev:/usr/sbin/nologin - sync:x:4:65534:sync:/bin:/bin/sync - ...</programlisting> - - <para>We illustrate the meaning of this <xref linkend="glo_CSV"/> - (actually **character** separated) by examining the first - row:</para> - - <glosslist> - <glossentry> - <glossterm>Column 1, <code>root</code>:</glossterm> - - <glossdef> - <para>The user's unique system name as being entered at - login.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 2, x<code>:</code></glossterm> - - <glossdef> - <para>This field is not being used on current <xref - linkend="glo_UNIX"/> implementations. Historically either - the user's clear text password or its hash value was present - here. For security reasons this attribute has been moved to - a third file <filename>/etc/shadow</filename> being read - access protected to non-administrator users.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 3, <code>0</code>:</glossterm> - - <glossdef> - <para>The user's unique integer numerical - <parameter>uid</parameter> number value.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 4, <code>0</code>:</glossterm> - - <glossdef> - <para>The user's unique primary group integer numerical - <parameter>gid</parameter> number value. The value - <quote>0</quote> here refers to a group root of identical - name being defined in <filename>/etc/group</filename>, see - next section.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 5, <code>root</code>:</glossterm> - - <glossdef> - <para>The user's common name. For a regular user account - this might be <quote>Jim Beam</quote> for example.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 6, <filename>/root</filename>:</glossterm> - - <glossdef> - <para>The user's home directory. Might be /home/beam for a - user <quote>Jim Beam</quote>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 7, <command>/bin/bash</command>:</glossterm> - - <glossdef> - <para>The user's login shell (command interpreter. This - attribute contains a reference to a command interpreter like - <command>/bin/(t)csh</command>, <command>/bin/ksh</command> - and so on.</para> - </glossdef> - </glossentry> - </glosslist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><filename>/etc/group</filename></glossterm> - - <glossdef> - <para>This file contains all groups being defined on the - system:</para> - - <programlisting language="none">root:x:0: - daemon:x:1: - bin:x:2: - sys:x:3: - adm:x:4:syslog,mi <co xml:id="secondaryGroupmembership"/> - tty:x:5: - ...</programlisting> - - <glosslist> - <glossentry> - <glossterm>Column1,root:</glossterm> - - <glossdef> - <para>The group's name</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 2, x:</glossterm> - - <glossdef> - <para>Not used</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 3, 4:</glossterm> - - <glossdef> - <para>The group's unique <parameter>gid</parameter> - number</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Column 4, <code>syslog,mi</code>:</glossterm> - - <glossdef> - <para>The set <code>{syslog,mi}</code> <coref - linkend="secondaryGroupmembership"/> defines secondary group - memberships: These two users will belong to the group - <code>adm</code> in addition to their respective primary - group definition.</para> - </glossdef> - </glossentry> - </glosslist> - </glossdef> - </glossentry> - </glosslist> - - <qandaset defaultlabel="qanda" xml:id="qandUnixToSqlToLdap"> - <title>Exporting and importing data</title> - - <qandadiv> - <qandaentry> - <question> - <para>Write two applications being able to perform the following - tasks:</para> - - <orderedlist> - <listitem> - <para>Import the previously described UNIX user and group - data ton an RDBMS using <xref linkend="glo_JDBC"/>. You will - have to define a suitable SQL schema first.</para> - </listitem> - - <listitem> - <para>Transfer RDBMS data to your local <xref - linkend="glo_LDAP"/> server using <link - xlink:href="http://docs.oracle.com/javase/jndi/tutorial/ldap/misc/url.html">JNDI</link>.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/UnixSqlLdap/Jndi/Unix2Rdbms</para> - </annotation> - - <annotation role="make"> - <para role="eclipse">P/UnixSqlLdap/Jndi/Rdbms2Ldap</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="transactionsInJdbc"> - <title>Transactions in <xref linkend="glo_JDBC"/></title> - - <para>You may review some remarks on SQL standard isolation level - definitions:</para> - - <itemizedlist> - <listitem> - <para><xref linkend="glo_Javadoc"/>:</para> - - <itemizedlist> - <listitem> - <para><link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_READ_UNCOMMITTED">TRANSACTION_READ_UNCOMMITTED</link></para> - </listitem> - - <listitem> - <para><link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_READ_COMMITTED">TRANSACTION_READ_COMMITTED</link></para> - </listitem> - - <listitem> - <para><link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_REPEATABLE_READ">TRANSACTION_READ_REPEATABLE_READ</link></para> - </listitem> - - <listitem> - <para><link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_SERIALIZABLE">TRANSACTION_READ_SERIALIZABLE</link></para> - </listitem> - </itemizedlist> - </listitem> - - <listitem> - <para><link - xlink:href="http://www.oracle.com/technetwork/issue-archive/2005/05-nov/o65asktom-082389.html">On - Transaction Isolation Levels (Oracle)</link></para> - </listitem> - - <listitem> - <para><link - xlink:href="http://technet.microsoft.com/en-us/library/ms378149(v=sql.110).aspx">Understanding - Isolation Levels (Microsoft)</link></para> - </listitem> - </itemizedlist> - - <section xml:id="accountTransferPessimistic"> - <title>Account Transfer using pessimistic concurrency control</title> - - <qandaset defaultlabel="qanda" xml:id="qandaJdbcIsolation"> - <title>Accounts and balances</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following simple schema of accounts keeping - customer balances:</para> - - <programlisting language="none">CREATE TABLE Account ( - number INT NOT NULL PRIMARY KEY - ,balance INT NOT NULL - )</programlisting> - - <para>Write two GUI applications to:</para> - - <itemizedlist> - <listitem> - <para>Transfer amounts from one account to another</para> - </listitem> - - <listitem> - <para>Get the sum of all balances</para> - </listitem> - </itemizedlist> - - <informalfigure> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Screen/accountTransferSum.png"/> - </imageobject> - </mediaobject> - </informalfigure> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/account</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="accountTransferOptimistic"> - <title>Account Transfer using optimistic concurrency control</title> - - <figure xml:id="fig_optimisticConcurrencyControl"> - <title>Optimistic concurrency control</title> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/concurrentOptimistic.svg"/> - </imageobject> - </mediaobject> - </figure> - - <para>An interfering transaction obeying the protocol causes a - transaction failure:</para> - - <figure xml:id="concurrentObtimisticFail"> - <title>Failure with optimistic transactions</title> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/concurrentOptimisticFail.svg"/> - </imageobject> - </mediaobject> - </figure> - - <para>Considerations:</para> - - <itemizedlist> - <listitem> - <para>Race conditions, time of check to time of use</para> - </listitem> - </itemizedlist> - - <qandaset defaultlabel="qanda" xml:id="qandaTransferOptimistic"> - <title>Optimistic account transfer</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implement your (pessimistic) account transfer - application <xref linkend="qandaJdbcIsolation"/> in an - optimistic manner:</para> - - <itemizedlist> - <listitem> - <para>Make sure both source and destination accounts get - protected against interfering transactions.</para> - </listitem> - - <listitem> - <para>Provide a means to definitely avoid deadlocks during - the second transaction section of a balance transfer - operation.</para> - </listitem> - - <listitem> - <para>Supply a suitable message in case of an interfering - second balance transfer</para> - </listitem> - </itemizedlist> - </question> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="jpa"> <title><xref linkend="glo_JPA"/></title> <remark>Mapping tools should be used only by someone familiar with @@ -3830,18 +3046,3 @@ <para>Describe the difference and construct an example.</para> </section> </chapter> - - <chapter xml:id="jax-rs"> - <title>REST applications based on <xref linkend="glo_Java"/>-rs</title> - - <para><link xlink:href="Ref/Fig/jaxRs.svg">Introductory - slides</link>.</para> - - <para>Sample chapters from <xref linkend="bib_Burke13"/> available at <uri - xlink:href="https://github.com/oreillymedia/restful_java_jax-rs_2_0">https://github.com/oreillymedia/restful_java_jax-rs_2_0</uri>.</para> - </chapter> - - <xi:include href="../glossary.xml" xpointer="element(/1)"/> - - <xi:include href="../bibliography.xml" xpointer="element(/1)"/> -</book> diff --git a/Doc/Sda2/ldap.xml b/Doc/Sda2/ldap.xml new file mode 100644 index 0000000000000000000000000000000000000000..6e579d52a62a0ae6bd15aee0f7979817d05c5310 --- /dev/null +++ b/Doc/Sda2/ldap.xml @@ -0,0 +1,769 @@ + <chapter xml:id="ldap" version="5.0" xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <title><link linkend="glo_LDAP">ldap</link> and <link + linkend="glo_JDBC">JDBC</link></title> + + <section xml:id="ldapIntro"> + <title>Getting started with <xref linkend="glo_LDAP"/></title> + + <para>Resources:</para> + + <itemizedlist> + <listitem> + <para><link + xlink:href="http://www.zytrax.com/books/ldap/ch3">Schema, + objectclasses and attributes</link></para> + </listitem> + + <listitem> + <para><link xlink:href="http://www.zytrax.com/books/ldap/apd">LDAP + Glossary</link></para> + </listitem> + </itemizedlist> + </section> + + <section xml:id="ldapSetup"> + <title>Setting up an <productname + xlink:href="http://www.openldap.org">Openldap</productname> + server</title> + + <para>The MI department provides an <productname + xlink:href="http://www.openldap.org">Openldap</productname> server at + each workstation (<productname + xlink:href="http://www.ubuntu.com/desktop">Ubuntu</productname> / Linux + only). The <xref linkend="glo_LDAP"/> manager credentials are:</para> + + <glosslist> + <glossentry> + <glossterm>Bind <xref linkend="glo_DN"/>:</glossterm> + + <glossdef> + <para><code>cn=admin,dc=hdm-stuttgart,dc=de</code></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Bind password:</glossterm> + + <glossdef> + <para><code>XYZ</code></para> + </glossdef> + </glossentry> + </glosslist> + + <para>In addition <xref linkend="glo_ApacheDirectoryStudio"/> is in + place and may serve as a means to conveniently establish <xref + linkend="glo_LDAP"/> communications. Console geeks may use <command + xlink:href="http://tldp.org/HOWTO/LDAP-HOWTO/utilities.html">ldapmodify</command> + and friends.</para> + + <task> + <title>Set up a connection to your local <xref linkend="glo_LDAP"/> + server</title> + + <procedure> + <step> + <para>Open <xref linkend="glo_ApacheDirectoryStudio"/>.</para> + </step> + + <step> + <para>Activate the <xref linkend="glo_LDAP"/> perspective.</para> + </step> + + <step> + <para>In the <quote>Connections</quote> window right click + <quote>New Connection ...</quote> like in <uri + xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_create_connection.html">http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_create_connection.html</uri>.</para> + </step> + + <step> + <para>Configure a connection to <parameter + xlink:href="http://www.techterms.com/definition/localhost">localhost</parameter> + using the above bind parameters.</para> + </step> + </procedure> + </task> + </section> + + <section xml:id="ldapSimpleInserts"> + <title>Adding some sample data using <xref + linkend="glo_ApacheDirectoryStudio"/></title> + + <qandaset defaultlabel="qanda" xml:id="qandaPopulateLdap"> + <title>Populating the <xref linkend="glo_DIT"/></title> + + <qandadiv> + <qandaentry> + <question> + <para>Add two departments <code>billing</code> and + <code>research</code>. Then supply corresponding user entries to + both departments by using the <link + xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_browse.html">LDAP + browser view</link>. (As being mentioned previously hardcore + hackers take <link + xlink:href="http://tldp.org/HOWTO/LDAP-HOWTO/utilities.html">this + track</link> neglecting time consuming <xref linkend="glo_GUI"/> + stuff).</para> + + <para>Hint: If you do have limited understanding of <xref + linkend="glo_LDAP"/> classes an schemata you may want to create + entries containing the following <parameter + xlink:href="http://www.zytrax.com/books/ldap/apd/index.html#objectclass">objectClass</parameter> + values:</para> + + <glosslist> + <glossentry> + <glossterm>Departments <code>billing</code> and + <code>research</code>:</glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para><code + xlink:href="http://www.zytrax.com/books/ldap/ape/#organizationalunit">organizationalUnit</code> + (structural)</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Child user entries below <code>billing</code> and + <code>research</code>:</glossterm> + + <glossdef> + <itemizedlist> + <listitem> + <para><code + xlink:href="http://www.zytrax.com/books/ldap/ape/#organizationalperson">organizationalPerson</code> + (structural) and <code + xlink:href="http://www.zytrax.com/books/ldap/ape/#posixaccount">posixAccount</code> + (auxiliary)</para> + </listitem> + </itemizedlist> + </glossdef> + </glossentry> + </glosslist> + + <para>Note that required parent <parameter + xlink:href="http://www.zytrax.com/books/ldap/apd/index.html#objectclass">objectClass</parameter> + definitions like <code>top</code> and <code + xlink:href="http://www.zytrax.com/books/ldap/ape/#person">person</code> + are being omitted here. <xref + linkend="glo_ApacheDirectoryStudio"/> will gracefully add + missing objectClasses on behalf of you automatically. The + subsequent <xref linkend="glo_LDIF"/> dump may serve as a + hint:</para> + + <programlisting language="none">... + <emphasis role="bold">dn: ou=billing,dc=hdm-stuttgart,dc=de</emphasis> + objectClass: top + objectClass: organizationalUnit + ou: billing + + <emphasis role="bold">dn: ou=research,dc=hdm-stuttgart,dc=de</emphasis> + objectClass: top + objectClass: organizationalUnit + ou: research + + <emphasis role="bold">dn: uid=lapinski,ou=billing,dc=hdm-stuttgart,dc=de</emphasis> + objectClass: posixAccount + objectClass: top + objectClass: person + objectClass: organizationalPerson + cn: Mee Lapinski + gidNumber: 100 + homeDirectory: /home/lapinski + sn: Lapinski + uid: lapinski + uidNumber: 1023 + ...</programlisting> + + <para>Question: What is the ratio behind adding the + <code>objectClass</code> value <code>posixAccount</code>? Hint: + Try to create a corresponding dataset having two persons with + identical names within the same department.</para> + </question> + + <answer> + <para>Your result may look like:</para> + + <figure xml:id="figureLdapTwoDepartments"> + <title>Two departments billing and research populated with + sample user entries</title> + + <screenshot> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Screen/ldapSampleUsers.png"/> + </imageobject> + </mediaobject> + </screenshot> + </figure> + + <para>Without having the <code>objectClass</code> value + <code>posixAccount</code> the attribute <code>uid</code> would + be disallowed and could thus not be part of our <xref + linkend="glo_DN"/> values. This would leave us with solutions + like:</para> + + <programlisting language="none"><emphasis role="bold">dn: cn=Mee Lapinski,ou=billing,dc=hdm-stuttgart,dc=de</emphasis></programlisting> + + <para>This in turn disallows identical common names (e.g. a + second <personname>Mee Lapinski</personname>) within the same + department. Thus the auxiliary objectClass posixAccount enables + us to introduce additional mandatory <code>uid</code> attribute + being the unique identifier within a given parent scope.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="ldifImportExport"> + <title><xref linkend="glo_LDIF"/> export and import</title> + + <para>This section is intended to get acquainted with <xref + linkend="glo_LDIF"/> representation of <xref linkend="glo_LDAP"/> data + and requires successful completion of <xref + linkend="qandaPopulateLdap"/> as a prerequisite. You may want to read + <uri + xlink:href="http://www.zytrax.com/books/ldap/ch8">http://www.zytrax.com/books/ldap/ch8</uri>.</para> + + <qandaset defaultlabel="qanda" xml:id="qanda_ldifExportImport"> + <title>Exporting, modifying and importing <xref linkend="glo_LDAP"/> + data using the <xref linkend="glo_LDIF"/> interchange + representation.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Export your current database state being left from <xref + linkend="qandaPopulateLdap"/> to an <xref linkend="glo_LDIF"/> + text file.</para> + + <para>Subsequently use this database dump file as a starting + point to create a <xref linkend="glo_LDIF"/> import file adding + a department <quote>pr</quote> (public relations) containing a + user <quote>Paul Simon</quote> with suitable attribute values to + the dataset.</para> + </question> + + <answer> + <para>Adding the new entries in question requires:</para> + + <programlisting language="none">version: 1 + + dn: ou=pr,dc=hdm-stuttgart,dc=de + objectClass: top + objectClass: organizationalUnit + ou: pr + + dn: uid=simon,ou=pr,dc=hdm-stuttgart,dc=de + objectClass: posixAccount + objectClass: top + objectClass: person + objectClass: organizationalPerson + cn: Paul Simon + gidNumber: 130 + homeDirectory: /home/tauras + sn: Svetlana + uid: tauras + uidNumber: 1028</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="ditSearch"> + <title>Searching the <xref linkend="glo_DIT"/></title> + + <para>Like relational and other database types <xref + linkend="glo_LDAP"/> provides a <link + xlink:href="http://www.zytrax.com/books/ldap/apa/search.html">query + language</link> to filter result entries.</para> + + <qandaset defaultlabel="qanda" xml:id="qanda_firstLdapQuery"> + <title>Filtering child elements</title> + + <qandadiv> + <qandaentry> + <question> + <para>Create <xref linkend="glo_LDAP"/> queries corresponding to + the following descriptions:</para> + + <orderedlist> + <listitem> + <para>All users entries within the whole <xref + linkend="glo_DIT"/> having a gidNumber value of 100.</para> + </listitem> + + <listitem> + <para>All user entries belonging to the billing department + having a <code>uid</code> value greater than 1023.</para> + </listitem> + + <listitem> + <para>All user entries within the whole <xref + linkend="glo_DIT"/> having a common name containing the + substring <quote>ei</quote>.</para> + </listitem> + + <listitem> + <para>All user entries within the whole <xref + linkend="glo_DIT"/> belonging to gidNumber == 100 or having + a <code>uid</code> value starting with letter + <quote>t</quote>.</para> + </listitem> + </orderedlist> + + <para>Hint: <xref linkend="glo_ApacheDirectoryStudio"/> allows + both for <link + xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/tools_filter_editor_dialog.html">filtering</link> + and <link + xlink:href="http://directory.apache.org/studio/users-guide/ldap_browser/gettingstarted_search.html">searching</link> + providing nifty features like attribute name completion and + syntax highlighting. For regular searches you may define:</para> + + <itemizedlist> + <listitem> + <para>The <xref linkend="glo_DIT"/> entry to start from + being identified by its <xref linkend="glo_DN"/>.</para> + </listitem> + + <listitem> + <para>The search scope being either of object, one level or + subtree.</para> + </listitem> + + <listitem> + <para>Boolean expressions based on attribute values.</para> + </listitem> + </itemizedlist> + + <para>But yes, I forgot to mention <link + xlink:href="http://tldp.org/HOWTO/LDAP-HOWTO/utilities.html">something</link>.</para> + </question> + + <answer> + <orderedlist> + <listitem> + <para><emphasis role="bold">All users entries within the + whole </emphasis><xref linkend="glo_DIT"/><emphasis + role="bold"> having a gidNumber value of + 100.</emphasis></para> + + <para>Solution: <code>(gidNumber=100)</code>, starting from + top of <xref linkend="glo_DIT"/> having subtree + scope.</para> + </listitem> + + <listitem> + <para><emphasis role="bold">All user entries belonging to + the billing department having a <code>uid</code> value + greater than 1023.</emphasis></para> + + <para>Solution: <code>(uidNumber>=1024)</code> starting + from <xref linkend="glo_DN"/> + <code>ou=billing,dc=hdm-stuttgart,dc=de</code> and scope + <code>one level</code>.</para> + + <para>Notice the expression + <code>(uidNumber>=1024)</code> in favour of the seemingly + equivalent but syntactically illegal counterpart + <code>(uidNumber>1023)</code>.</para> + </listitem> + + <listitem> + <para><emphasis role="bold">All user entries within the + whole </emphasis><xref linkend="glo_DIT"/><emphasis + role="bold"> having a common name containing the substring + <quote>ei</quote>.</emphasis></para> + + <para>Solution: <code>(cn=*ei*)</code>, starting from top of + <xref linkend="glo_DIT"/> having subtree scope.</para> + </listitem> + + <listitem> + <para><emphasis role="bold">All user entries within the + whole </emphasis><xref linkend="glo_DIT"/><emphasis + role="bold"> belonging to gidNumber == 100 or having a + <code>uid</code> value starting with letter + <quote>t</quote>.</emphasis></para> + + <para>Solution: <code>(|(gidNumber=100)(uid=t*))</code>, + starting from top of <xref linkend="glo_DIT"/> having + subtree scope.</para> + </listitem> + </orderedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="unix2sql2ldap"> + <title><xref linkend="glo_UNIX"/> to <xref linkend="glo_SQL"/> to <xref + linkend="glo_LDAP"/></title> + + <para><xref linkend="glo_UNIX"/> type operating systems manage users, + groups and their respective relationships in three different text + files:</para> + + <glosslist> + <glossentry> + <glossterm><filename>/etc/passwd</filename></glossterm> + + <glossdef> + <para>Users being defined on the system:</para> + + <programlisting language="none">root:x:0:0:root:/root:/bin/bash + daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin + bin:x:2:2:bin:/bin:/usr/sbin/nologin + sys:x:3:3:sys:/dev:/usr/sbin/nologin + sync:x:4:65534:sync:/bin:/bin/sync + ...</programlisting> + + <para>We illustrate the meaning of this <xref linkend="glo_CSV"/> + (actually **character** separated) by examining the first + row:</para> + + <glosslist> + <glossentry> + <glossterm>Column 1, <code>root</code>:</glossterm> + + <glossdef> + <para>The user's unique system name as being entered at + login.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 2, x<code>:</code></glossterm> + + <glossdef> + <para>This field is not being used on current <xref + linkend="glo_UNIX"/> implementations. Historically either + the user's clear text password or its hash value was present + here. For security reasons this attribute has been moved to + a third file <filename>/etc/shadow</filename> being read + access protected to non-administrator users.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 3, <code>0</code>:</glossterm> + + <glossdef> + <para>The user's unique integer numerical + <parameter>uid</parameter> number value.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 4, <code>0</code>:</glossterm> + + <glossdef> + <para>The user's unique primary group integer numerical + <parameter>gid</parameter> number value. The value + <quote>0</quote> here refers to a group root of identical + name being defined in <filename>/etc/group</filename>, see + next section.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 5, <code>root</code>:</glossterm> + + <glossdef> + <para>The user's common name. For a regular user account + this might be <quote>Jim Beam</quote> for example.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 6, <filename>/root</filename>:</glossterm> + + <glossdef> + <para>The user's home directory. Might be /home/beam for a + user <quote>Jim Beam</quote>.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 7, <command>/bin/bash</command>:</glossterm> + + <glossdef> + <para>The user's login shell (command interpreter. This + attribute contains a reference to a command interpreter like + <command>/bin/(t)csh</command>, <command>/bin/ksh</command> + and so on.</para> + </glossdef> + </glossentry> + </glosslist> + </glossdef> + </glossentry> + + <glossentry> + <glossterm><filename>/etc/group</filename></glossterm> + + <glossdef> + <para>This file contains all groups being defined on the + system:</para> + + <programlisting language="none">root:x:0: + daemon:x:1: + bin:x:2: + sys:x:3: + adm:x:4:syslog,mi <co xml:id="secondaryGroupmembership"/> + tty:x:5: + ...</programlisting> + + <glosslist> + <glossentry> + <glossterm>Column1,root:</glossterm> + + <glossdef> + <para>The group's name</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 2, x:</glossterm> + + <glossdef> + <para>Not used</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 3, 4:</glossterm> + + <glossdef> + <para>The group's unique <parameter>gid</parameter> + number</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Column 4, <code>syslog,mi</code>:</glossterm> + + <glossdef> + <para>The set <code>{syslog,mi}</code> <coref + linkend="secondaryGroupmembership"/> defines secondary group + memberships: These two users will belong to the group + <code>adm</code> in addition to their respective primary + group definition.</para> + </glossdef> + </glossentry> + </glosslist> + </glossdef> + </glossentry> + </glosslist> + + <qandaset defaultlabel="qanda" xml:id="qandUnixToSqlToLdap"> + <title>Exporting and importing data</title> + + <qandadiv> + <qandaentry> + <question> + <para>Write two applications being able to perform the following + tasks:</para> + + <orderedlist> + <listitem> + <para>Import the previously described UNIX user and group + data ton an RDBMS using <xref linkend="glo_JDBC"/>. You will + have to define a suitable SQL schema first.</para> + </listitem> + + <listitem> + <para>Transfer RDBMS data to your local <xref + linkend="glo_LDAP"/> server using <link + xlink:href="http://docs.oracle.com/javase/jndi/tutorial/ldap/misc/url.html">JNDI</link>.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/UnixSqlLdap/Jndi/Unix2Rdbms</para> + </annotation> + + <annotation role="make"> + <para role="eclipse">P/UnixSqlLdap/Jndi/Rdbms2Ldap</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="transactionsInJdbc"> + <title>Transactions in <xref linkend="glo_JDBC"/></title> + + <para>You may review some remarks on SQL standard isolation level + definitions:</para> + + <itemizedlist> + <listitem> + <para><xref linkend="glo_Javadoc"/>:</para> + + <itemizedlist> + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_READ_UNCOMMITTED">TRANSACTION_READ_UNCOMMITTED</link></para> + </listitem> + + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_READ_COMMITTED">TRANSACTION_READ_COMMITTED</link></para> + </listitem> + + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_REPEATABLE_READ">TRANSACTION_READ_REPEATABLE_READ</link></para> + </listitem> + + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#TRANSACTION_SERIALIZABLE">TRANSACTION_READ_SERIALIZABLE</link></para> + </listitem> + </itemizedlist> + </listitem> + + <listitem> + <para><link + xlink:href="http://www.oracle.com/technetwork/issue-archive/2005/05-nov/o65asktom-082389.html">On + Transaction Isolation Levels (Oracle)</link></para> + </listitem> + + <listitem> + <para><link + xlink:href="http://technet.microsoft.com/en-us/library/ms378149(v=sql.110).aspx">Understanding + Isolation Levels (Microsoft)</link></para> + </listitem> + </itemizedlist> + + <section xml:id="accountTransferPessimistic"> + <title>Account Transfer using pessimistic concurrency control</title> + + <qandaset defaultlabel="qanda" xml:id="qandaJdbcIsolation"> + <title>Accounts and balances</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following simple schema of accounts keeping + customer balances:</para> + + <programlisting language="none">CREATE TABLE Account ( + number INT NOT NULL PRIMARY KEY + ,balance INT NOT NULL + )</programlisting> + + <para>Write two GUI applications to:</para> + + <itemizedlist> + <listitem> + <para>Transfer amounts from one account to another</para> + </listitem> + + <listitem> + <para>Get the sum of all balances</para> + </listitem> + </itemizedlist> + + <informalfigure> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Screen/accountTransferSum.png"/> + </imageobject> + </mediaobject> + </informalfigure> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">P/account</para> + </annotation> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="accountTransferOptimistic"> + <title>Account Transfer using optimistic concurrency control</title> + + <figure xml:id="fig_optimisticConcurrencyControl"> + <title>Optimistic concurrency control</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/concurrentOptimistic.svg"/> + </imageobject> + </mediaobject> + </figure> + + <para>An interfering transaction obeying the protocol causes a + transaction failure:</para> + + <figure xml:id="concurrentObtimisticFail"> + <title>Failure with optimistic transactions</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/concurrentOptimisticFail.svg"/> + </imageobject> + </mediaobject> + </figure> + + <para>Considerations:</para> + + <itemizedlist> + <listitem> + <para>Race conditions, time of check to time of use</para> + </listitem> + </itemizedlist> + + <qandaset defaultlabel="qanda" xml:id="qandaTransferOptimistic"> + <title>Optimistic account transfer</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement your (pessimistic) account transfer + application <xref linkend="qandaJdbcIsolation"/> in an + optimistic manner:</para> + + <itemizedlist> + <listitem> + <para>Make sure both source and destination accounts get + protected against interfering transactions.</para> + </listitem> + + <listitem> + <para>Provide a means to definitely avoid deadlocks during + the second transaction section of a balance transfer + operation.</para> + </listitem> + + <listitem> + <para>Supply a suitable message in case of an interfering + second balance transfer</para> + </listitem> + </itemizedlist> + </question> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> + </chapter> diff --git a/Doc/Sda2/sda2.xml b/Doc/Sda2/sda2.xml new file mode 100644 index 0000000000000000000000000000000000000000..13e6b803e057c1f0ea0e56e883272f9f1e35263a --- /dev/null +++ b/Doc/Sda2/sda2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<book version="5.0" xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:m="http://www.w3.org/1998/Math/MathML" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:db="http://docbook.org/ns/docbook"> + <info> + <title>Structured data and applications 2</title> + + <author> + <personname><firstname>Martin</firstname> + <surname>Goik</surname></personname> + + <affiliation> + <orgname>http://medieninformatik.hdm-stuttgart.de</orgname> + </affiliation> + </author> + + <legalnotice> + <para>Source code available at <uri + xlink:href="https://version.mi.hdm-stuttgart.de/git/GoikLectures">https://version.mi.hdm-stuttgart.de/git/GoikLectures</uri></para> + </legalnotice> + </info> + + + + +</book> diff --git a/lectures.xml b/Doc/lectures.xml similarity index 60% rename from lectures.xml rename to Doc/lectures.xml index a1a5d5b2dea9149c74129c8a023caee9ab06e754..1483f161837d793d6351e4b0a08bf5fb8cc3e1b2 100644 --- a/lectures.xml +++ b/Doc/lectures.xml @@ -24,6 +24,22 @@ </legalnotice> </info> + <part xml:id="sd1"> + <info> + <title>Software development 1</title> + </info> + + <xi:include href="Sd1/preliminaries.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/class.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/loop.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/array.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/identity.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/deployment.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/streams.xml" xpointer="element(/1)"/> + <xi:include href="Sd1/collections.xml" xpointer="element(/1)"/> + + </part> + <part xml:id="sda1"> <info> <title>Structured Data and Applications 1</title> @@ -47,8 +63,19 @@ <xi:include href="Sda1/fo.xml" xpointer="element(/1)"/> - <xi:include href="bibliography.xml" xpointer="element(/1)"/> + </part> + + <part xml:id="sda2"> + <info> + <title>Structured Data and Applications 2</title> + </info> - <xi:include href="glossary.xml" xpointer="element(/1)"/> + <xi:include href="Sda2/ldap.xml" xpointer="element(/1)"/> + <xi:include href="Sda2/jpa.xml" xpointer="element(/1)"/> + <xi:include href="Sda2/jax-rs.xml" xpointer="element(/1)"/> </part> + + <xi:include href="Common/bibliography.xml" xpointer="element(/1)"/> + <xi:include href="Common/glossary.xml" xpointer="element(/1)"/> + </book> diff --git a/Sda2/P/JaxRs/Intro/.gitignore b/P/Sda2/JaxRs/Intro/.gitignore similarity index 100% rename from Sda2/P/JaxRs/Intro/.gitignore rename to P/Sda2/JaxRs/Intro/.gitignore diff --git a/Sda2/P/JaxRs/Intro/README.md b/P/Sda2/JaxRs/Intro/README.md similarity index 100% rename from Sda2/P/JaxRs/Intro/README.md rename to P/Sda2/JaxRs/Intro/README.md diff --git a/Sda2/P/JaxRs/Intro/pom.xml b/P/Sda2/JaxRs/Intro/pom.xml similarity index 100% rename from Sda2/P/JaxRs/Intro/pom.xml rename to P/Sda2/JaxRs/Intro/pom.xml diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java b/P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java rename to P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java b/P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java rename to P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java b/P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java rename to P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java b/P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java rename to P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java b/P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java rename to P/Sda2/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java diff --git a/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java b/P/Sda2/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java rename to P/Sda2/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java diff --git a/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java b/P/Sda2/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java rename to P/Sda2/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java diff --git a/Sda2/P/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml b/P/Sda2/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml rename to P/Sda2/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml diff --git a/Sda2/P/JaxRs/Intro/src/main/webapp/static/customer2html.xsl b/P/Sda2/JaxRs/Intro/src/main/webapp/static/customer2html.xsl similarity index 100% rename from Sda2/P/JaxRs/Intro/src/main/webapp/static/customer2html.xsl rename to P/Sda2/JaxRs/Intro/src/main/webapp/static/customer2html.xsl diff --git a/Sda2/P/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java b/P/Sda2/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java similarity index 100% rename from Sda2/P/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java rename to P/Sda2/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java diff --git a/Sda2/P/Jpa/Cd/.gitignore b/P/Sda2/Jpa/Cd/.gitignore similarity index 100% rename from Sda2/P/Jpa/Cd/.gitignore rename to P/Sda2/Jpa/Cd/.gitignore diff --git a/Sda2/P/Jpa/Cd/Schema/cd.xsd b/P/Sda2/Jpa/Cd/Schema/cd.xsd similarity index 100% rename from Sda2/P/Jpa/Cd/Schema/cd.xsd rename to P/Sda2/Jpa/Cd/Schema/cd.xsd diff --git a/Sda2/P/Jpa/Cd/Schema/generate.sh b/P/Sda2/Jpa/Cd/Schema/generate.sh similarity index 100% rename from Sda2/P/Jpa/Cd/Schema/generate.sh rename to P/Sda2/Jpa/Cd/Schema/generate.sh diff --git a/Sda2/P/Jpa/Cd/cdData.xml b/P/Sda2/Jpa/Cd/cdData.xml similarity index 100% rename from Sda2/P/Jpa/Cd/cdData.xml rename to P/Sda2/Jpa/Cd/cdData.xml diff --git a/Sda2/P/Jpa/Cd/pom.xml b/P/Sda2/Jpa/Cd/pom.xml similarity index 100% rename from Sda2/P/Jpa/Cd/pom.xml rename to P/Sda2/Jpa/Cd/pom.xml diff --git a/Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/Driver.java b/P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/Driver.java similarity index 100% rename from Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/Driver.java rename to P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/Driver.java diff --git a/Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Catalog.java b/P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Catalog.java similarity index 100% rename from Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Catalog.java rename to P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Catalog.java diff --git a/Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Cd.java b/P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Cd.java similarity index 100% rename from Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Cd.java rename to P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Cd.java diff --git a/Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/ObjectFactory.java b/P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/ObjectFactory.java similarity index 100% rename from Sda2/P/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/ObjectFactory.java rename to P/Sda2/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/ObjectFactory.java diff --git a/Sda2/P/Jpa/Cd/src/main/resources/META-INF/persistence.xml b/P/Sda2/Jpa/Cd/src/main/resources/META-INF/persistence.xml similarity index 100% rename from Sda2/P/Jpa/Cd/src/main/resources/META-INF/persistence.xml rename to P/Sda2/Jpa/Cd/src/main/resources/META-INF/persistence.xml diff --git a/Sda2/P/Jpa/Cd/src/main/resources/log4j2.xml b/P/Sda2/Jpa/Cd/src/main/resources/log4j2.xml similarity index 100% rename from Sda2/P/Jpa/Cd/src/main/resources/log4j2.xml rename to P/Sda2/Jpa/Cd/src/main/resources/log4j2.xml diff --git a/Sda2/P/Jpa/Cd/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/cd/AppTest.java b/P/Sda2/Jpa/Cd/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/cd/AppTest.java similarity index 100% rename from Sda2/P/Jpa/Cd/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/cd/AppTest.java rename to P/Sda2/Jpa/Cd/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/cd/AppTest.java diff --git a/Sda2/P/Jpa/HibernateCacheDemo/.gitignore b/P/Sda2/Jpa/HibernateCacheDemo/.gitignore similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/.gitignore rename to P/Sda2/Jpa/HibernateCacheDemo/.gitignore diff --git a/Sda2/P/Jpa/HibernateCacheDemo/pom.xml b/P/Sda2/Jpa/HibernateCacheDemo/pom.xml similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/pom.xml rename to P/Sda2/Jpa/HibernateCacheDemo/pom.xml diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/JpaTest.java b/P/Sda2/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/JpaTest.java similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/JpaTest.java rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/JpaTest.java diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Department.java b/P/Sda2/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Department.java similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Department.java rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Department.java diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Employee.java b/P/Sda2/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Employee.java similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Employee.java rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Employee.java diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/META-INF/persistence.xml b/P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/META-INF/persistence.xml similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/META-INF/persistence.xml rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/META-INF/persistence.xml diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xml b/P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xml similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xml rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xml diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xsd b/P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xsd similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xsd rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xsd diff --git a/Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/log4j.properties b/P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/log4j.properties similarity index 100% rename from Sda2/P/Jpa/HibernateCacheDemo/src/main/resources/log4j.properties rename to P/Sda2/Jpa/HibernateCacheDemo/src/main/resources/log4j.properties diff --git a/Sda2/P/Jpa/Inherit/Tpch/.gitignore b/P/Sda2/Jpa/Inherit/Tpch/.gitignore similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/.gitignore rename to P/Sda2/Jpa/Inherit/Tpch/.gitignore diff --git a/Sda2/P/Jpa/Inherit/Tpch/pom.xml b/P/Sda2/Jpa/Inherit/Tpch/pom.xml similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/pom.xml rename to P/Sda2/Jpa/Inherit/Tpch/pom.xml diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/CreateData.java b/P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/CreateData.java similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/CreateData.java rename to P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/CreateData.java diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/ReadData.java b/P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/ReadData.java similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/ReadData.java rename to P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/ReadData.java diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BankAccount.java b/P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BankAccount.java similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BankAccount.java rename to P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BankAccount.java diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BillingDetail.java b/P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BillingDetail.java similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BillingDetail.java rename to P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BillingDetail.java diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/CreditCard.java b/P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/CreditCard.java similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/CreditCard.java rename to P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/CreditCard.java diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/Customer.java b/P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/Customer.java similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/Customer.java rename to P/Sda2/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/Customer.java diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/resources/META-INF/persistence.xml b/P/Sda2/Jpa/Inherit/Tpch/src/main/resources/META-INF/persistence.xml similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/resources/META-INF/persistence.xml rename to P/Sda2/Jpa/Inherit/Tpch/src/main/resources/META-INF/persistence.xml diff --git a/Sda2/P/Jpa/Inherit/Tpch/src/main/resources/log4j2.xml b/P/Sda2/Jpa/Inherit/Tpch/src/main/resources/log4j2.xml similarity index 100% rename from Sda2/P/Jpa/Inherit/Tpch/src/main/resources/log4j2.xml rename to P/Sda2/Jpa/Inherit/Tpch/src/main/resources/log4j2.xml diff --git a/Sda2/P/Jpa/University/.gitignore b/P/Sda2/Jpa/University/.gitignore similarity index 100% rename from Sda2/P/Jpa/University/.gitignore rename to P/Sda2/Jpa/University/.gitignore diff --git a/Sda2/P/Jpa/University/pom.xml b/P/Sda2/Jpa/University/pom.xml similarity index 100% rename from Sda2/P/Jpa/University/pom.xml rename to P/Sda2/Jpa/University/pom.xml diff --git a/Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Lecture.java b/P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Lecture.java similarity index 100% rename from Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Lecture.java rename to P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Lecture.java diff --git a/Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Student.java b/P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Student.java similarity index 100% rename from Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Student.java rename to P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Student.java diff --git a/Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/StudentLecture.java b/P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/StudentLecture.java similarity index 100% rename from Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/StudentLecture.java rename to P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/StudentLecture.java diff --git a/Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/university/Driver.java b/P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/university/Driver.java similarity index 100% rename from Sda2/P/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/university/Driver.java rename to P/Sda2/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/university/Driver.java diff --git a/Sda2/P/Jpa/University/src/main/resources/META-INF/persistence.xml b/P/Sda2/Jpa/University/src/main/resources/META-INF/persistence.xml similarity index 100% rename from Sda2/P/Jpa/University/src/main/resources/META-INF/persistence.xml rename to P/Sda2/Jpa/University/src/main/resources/META-INF/persistence.xml diff --git a/Sda2/P/Jpa/University/src/main/resources/log4j2.xml b/P/Sda2/Jpa/University/src/main/resources/log4j2.xml similarity index 100% rename from Sda2/P/Jpa/University/src/main/resources/log4j2.xml rename to P/Sda2/Jpa/University/src/main/resources/log4j2.xml diff --git a/Sda2/P/Jpa/University/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/university/AppTest.java b/P/Sda2/Jpa/University/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/university/AppTest.java similarity index 100% rename from Sda2/P/Jpa/University/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/university/AppTest.java rename to P/Sda2/Jpa/University/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/university/AppTest.java diff --git a/Sda2/P/Register/.gitignore b/P/Sda2/Register/.gitignore similarity index 100% rename from Sda2/P/Register/.gitignore rename to P/Sda2/Register/.gitignore diff --git a/Sda2/P/Register/Schema/schema.sql b/P/Sda2/Register/Schema/schema.sql similarity index 100% rename from Sda2/P/Register/Schema/schema.sql rename to P/Sda2/Register/Schema/schema.sql diff --git a/Sda2/P/Register/pom.xml b/P/Sda2/Register/pom.xml similarity index 100% rename from Sda2/P/Register/pom.xml rename to P/Sda2/Register/pom.xml diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/AppWidgetSet.gwt.xml b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/AppWidgetSet.gwt.xml similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/AppWidgetSet.gwt.xml rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/AppWidgetSet.gwt.xml diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/MyLogin.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/MyLogin.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/MyLogin.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/MyLogin.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/MyVaadinUI.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/MyVaadinUI.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/MyVaadinUI.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/MyVaadinUI.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/NavigatorUI.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/NavigatorUI.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/NavigatorUI.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/NavigatorUI.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/Register.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/Register.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/Register.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/Register.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/entities/User.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/entities/User.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/entities/User.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/entities/User.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/tools/MyBeanFieldGroup.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/tools/MyBeanFieldGroup.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/tools/MyBeanFieldGroup.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/tools/MyBeanFieldGroup.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateGlobal.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateGlobal.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateGlobal.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateGlobal.java diff --git a/Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateSecondIdenticalInput.java b/P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateSecondIdenticalInput.java similarity index 100% rename from Sda2/P/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateSecondIdenticalInput.java rename to P/Sda2/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateSecondIdenticalInput.java diff --git a/Sda2/P/Register/src/main/webapp/META-INF/MANIFEST.MF b/P/Sda2/Register/src/main/webapp/META-INF/MANIFEST.MF similarity index 100% rename from Sda2/P/Register/src/main/webapp/META-INF/MANIFEST.MF rename to P/Sda2/Register/src/main/webapp/META-INF/MANIFEST.MF diff --git a/Sda2/P/Register/src/main/webapp/META-INF/context.xml b/P/Sda2/Register/src/main/webapp/META-INF/context.xml similarity index 100% rename from Sda2/P/Register/src/main/webapp/META-INF/context.xml rename to P/Sda2/Register/src/main/webapp/META-INF/context.xml diff --git a/Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/addons.scss similarity index 100% rename from Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/addons.scss rename to P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/addons.scss diff --git a/Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/favicon.ico similarity index 100% rename from Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/favicon.ico rename to P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/favicon.ico diff --git a/Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss similarity index 100% rename from Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss rename to P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss diff --git a/Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/styles.scss similarity index 100% rename from Sda2/P/Register/src/main/webapp/VAADIN/themes/mytheme/styles.scss rename to P/Sda2/Register/src/main/webapp/VAADIN/themes/mytheme/styles.scss diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/.gitignore b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/.gitignore similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/.gitignore rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/.gitignore diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/Schema/schema.ldif b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/Schema/schema.ldif similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/Schema/schema.ldif rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/Schema/schema.ldif diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/pom.xml b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/pom.xml similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/pom.xml rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/pom.xml diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Config.java b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Config.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Config.java rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Config.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Driver.java b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Driver.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Driver.java rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Driver.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap/LdapHandler.java b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap/LdapHandler.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap/LdapHandler.java rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap/LdapHandler.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/rdbms/RdbmsHandler.java b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/rdbms/RdbmsHandler.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/rdbms/RdbmsHandler.java rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/rdbms/RdbmsHandler.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap.properties b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap.properties similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap.properties rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap.properties diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/log4j2.xml b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/log4j2.xml similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/log4j2.xml rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/log4j2.xml diff --git a/Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/test/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/AppTest.java b/P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/test/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/AppTest.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Rdbms2Ldap/src/test/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/AppTest.java rename to P/Sda2/UnixSqlLdap/Jndi/Rdbms2Ldap/src/test/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/AppTest.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/.gitignore b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/.gitignore similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/.gitignore rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/.gitignore diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/divers.sql b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/divers.sql similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/divers.sql rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/divers.sql diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/schema.sql b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/schema.sql similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/schema.sql rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/schema.sql diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/group b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/group similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/group rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/group diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/passwd b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/passwd similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/passwd rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/passwd diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/pom.xml b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/pom.xml similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/pom.xml rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/pom.xml diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Cfg.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Cfg.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Cfg.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Cfg.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Driver.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Driver.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Driver.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Driver.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Group.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Group.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Group.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Group.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/ParseError.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/ParseError.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/ParseError.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/ParseError.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Parser.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Parser.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Parser.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Parser.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/User.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/User.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/User.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/User.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/DatabaseObject.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/DatabaseObject.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/DatabaseObject.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/DatabaseObject.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/GroupParam.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/GroupParam.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/GroupParam.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/GroupParam.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/MyNamedQuery.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/MyNamedQuery.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/MyNamedQuery.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/MyNamedQuery.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/NamedParameterStatement.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/NamedParameterStatement.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/NamedParameterStatement.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/NamedParameterStatement.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/Param.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/Param.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/Param.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/Param.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/RdbmsHandler.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/RdbmsHandler.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/RdbmsHandler.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/RdbmsHandler.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserGroupParam.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserGroupParam.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserGroupParam.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserGroupParam.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserParam.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserParam.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserParam.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserParam.java diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/de/hdm_stuttgart/mi/sda2/usermanage/jdbc.properties b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/de/hdm_stuttgart/mi/sda2/usermanage/jdbc.properties similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/de/hdm_stuttgart/mi/sda2/usermanage/jdbc.properties rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/de/hdm_stuttgart/mi/sda2/usermanage/jdbc.properties diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/log4j.properties b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/log4j.properties similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/log4j.properties rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/log4j.properties diff --git a/Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/test/java/de/hdm_stuttgart/mi/sda2/usermanage/UserTest.java b/P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/test/java/de/hdm_stuttgart/mi/sda2/usermanage/UserTest.java similarity index 100% rename from Sda2/P/UnixSqlLdap/Jndi/Unix2Rdbms/src/test/java/de/hdm_stuttgart/mi/sda2/usermanage/UserTest.java rename to P/Sda2/UnixSqlLdap/Jndi/Unix2Rdbms/src/test/java/de/hdm_stuttgart/mi/sda2/usermanage/UserTest.java diff --git a/Sda2/P/account/.gitignore b/P/Sda2/account/.gitignore similarity index 100% rename from Sda2/P/account/.gitignore rename to P/Sda2/account/.gitignore diff --git a/Sda2/P/account/Sql/schema.sql b/P/Sda2/account/Sql/schema.sql similarity index 100% rename from Sda2/P/account/Sql/schema.sql rename to P/Sda2/account/Sql/schema.sql diff --git a/Sda2/P/account/pom.xml b/P/Sda2/account/pom.xml similarity index 100% rename from Sda2/P/account/pom.xml rename to P/Sda2/account/pom.xml diff --git a/Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/Conf.java b/P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/Conf.java similarity index 100% rename from Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/Conf.java rename to P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/Conf.java diff --git a/Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/SumDriver.java b/P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/SumDriver.java similarity index 100% rename from Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/SumDriver.java rename to P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/SumDriver.java diff --git a/Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/TransferDriver.java b/P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/TransferDriver.java similarity index 100% rename from Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/TransferDriver.java rename to P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/TransferDriver.java diff --git a/Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/ExceptionDialog.java b/P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/ExceptionDialog.java similarity index 100% rename from Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/ExceptionDialog.java rename to P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/ExceptionDialog.java diff --git a/Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/NumberField.java b/P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/NumberField.java similarity index 100% rename from Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/NumberField.java rename to P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/NumberField.java diff --git a/Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/sql/DbHandler.java b/P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/sql/DbHandler.java similarity index 100% rename from Sda2/P/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/sql/DbHandler.java rename to P/Sda2/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/sql/DbHandler.java diff --git a/Sda2/P/account/src/main/resources/de/hdm_stuttgart/mi/sda2/account/jdbc.properties b/P/Sda2/account/src/main/resources/de/hdm_stuttgart/mi/sda2/account/jdbc.properties similarity index 100% rename from Sda2/P/account/src/main/resources/de/hdm_stuttgart/mi/sda2/account/jdbc.properties rename to P/Sda2/account/src/main/resources/de/hdm_stuttgart/mi/sda2/account/jdbc.properties diff --git a/Sda2/P/account/src/main/resources/log4j.properties b/P/Sda2/account/src/main/resources/log4j.properties similarity index 100% rename from Sda2/P/account/src/main/resources/log4j.properties rename to P/Sda2/account/src/main/resources/log4j.properties diff --git a/Sda2/P/account/src/test/java/de/hdm_stuttgart/mi/sda2/account/DbTest.java b/P/Sda2/account/src/test/java/de/hdm_stuttgart/mi/sda2/account/DbTest.java similarity index 100% rename from Sda2/P/account/src/test/java/de/hdm_stuttgart/mi/sda2/account/DbTest.java rename to P/Sda2/account/src/test/java/de/hdm_stuttgart/mi/sda2/account/DbTest.java diff --git a/Sda2/P/forum_1/.gitignore b/P/Sda2/forum_1/.gitignore similarity index 100% rename from Sda2/P/forum_1/.gitignore rename to P/Sda2/forum_1/.gitignore diff --git a/Sda2/P/forum_1/Schema/schema.sql b/P/Sda2/forum_1/Schema/schema.sql similarity index 100% rename from Sda2/P/forum_1/Schema/schema.sql rename to P/Sda2/forum_1/Schema/schema.sql diff --git a/Sda2/P/forum_1/_Readme.first b/P/Sda2/forum_1/_Readme.first similarity index 100% rename from Sda2/P/forum_1/_Readme.first rename to P/Sda2/forum_1/_Readme.first diff --git a/Sda2/P/forum_1/pom.xml b/P/Sda2/forum_1/pom.xml similarity index 100% rename from Sda2/P/forum_1/pom.xml rename to P/Sda2/forum_1/pom.xml diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/AppWidgetSet.gwt.xml b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/AppWidgetSet.gwt.xml similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/AppWidgetSet.gwt.xml rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/AppWidgetSet.gwt.xml diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Main.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Main.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Main.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Main.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/MyLogin.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/MyLogin.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/MyLogin.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/MyLogin.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/NavigatorUI.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/NavigatorUI.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/NavigatorUI.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/NavigatorUI.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Register.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Register.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Register.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Register.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/.gitignore b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/.gitignore similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/.gitignore rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/.gitignore diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Forum.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Forum.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Forum.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Forum.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Subscription.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Subscription.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Subscription.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Subscription.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/User.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/User.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/User.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/User.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/UserForumAssocId.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/UserForumAssocId.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/UserForumAssocId.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/UserForumAssocId.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/Credential.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/Credential.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/Credential.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/Credential.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/HashProvider.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/HashProvider.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/HashProvider.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/HashProvider.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/MyBeanFieldGroup.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/MyBeanFieldGroup.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/MyBeanFieldGroup.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/MyBeanFieldGroup.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/PersistenceHelper.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/PersistenceHelper.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/PersistenceHelper.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/PersistenceHelper.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateGlobal.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateGlobal.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateGlobal.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateGlobal.java diff --git a/Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateSecondIdenticalInput.java b/P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateSecondIdenticalInput.java similarity index 100% rename from Sda2/P/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateSecondIdenticalInput.java rename to P/Sda2/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateSecondIdenticalInput.java diff --git a/Sda2/P/forum_1/src/main/resources/META-INF/persistence.xml b/P/Sda2/forum_1/src/main/resources/META-INF/persistence.xml similarity index 100% rename from Sda2/P/forum_1/src/main/resources/META-INF/persistence.xml rename to P/Sda2/forum_1/src/main/resources/META-INF/persistence.xml diff --git a/Sda2/P/forum_1/src/main/webapp/META-INF/MANIFEST.MF b/P/Sda2/forum_1/src/main/webapp/META-INF/MANIFEST.MF similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/META-INF/MANIFEST.MF rename to P/Sda2/forum_1/src/main/webapp/META-INF/MANIFEST.MF diff --git a/Sda2/P/forum_1/src/main/webapp/META-INF/context.xml b/P/Sda2/forum_1/src/main/webapp/META-INF/context.xml similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/META-INF/context.xml rename to P/Sda2/forum_1/src/main/webapp/META-INF/context.xml diff --git a/Sda2/P/forum_1/src/main/webapp/VAADIN/.gitignore b/P/Sda2/forum_1/src/main/webapp/VAADIN/.gitignore similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/VAADIN/.gitignore rename to P/Sda2/forum_1/src/main/webapp/VAADIN/.gitignore diff --git a/Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/addons.scss similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/addons.scss rename to P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/addons.scss diff --git a/Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/favicon.ico similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/favicon.ico rename to P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/favicon.ico diff --git a/Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss rename to P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss diff --git a/Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.css b/P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.css similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.css rename to P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.css diff --git a/Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.scss similarity index 100% rename from Sda2/P/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.scss rename to P/Sda2/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.scss diff --git a/Sda2/P/forum_1/src/test/java/de/hdm_stuttgart/mi/sda2/forum/TestDomain.java b/P/Sda2/forum_1/src/test/java/de/hdm_stuttgart/mi/sda2/forum/TestDomain.java similarity index 100% rename from Sda2/P/forum_1/src/test/java/de/hdm_stuttgart/mi/sda2/forum/TestDomain.java rename to P/Sda2/forum_1/src/test/java/de/hdm_stuttgart/mi/sda2/forum/TestDomain.java diff --git a/Sd1/lib/Greenfoot-core-2.5.jar b/Sd1/lib/Greenfoot-core-2.5.jar deleted file mode 100644 index ea7d806702a6c0cb53cd8ce87e682df89da0a4b2..0000000000000000000000000000000000000000 Binary files a/Sd1/lib/Greenfoot-core-2.5.jar and /dev/null differ diff --git a/Sd1/swd1.xml b/Sd1/swd1.xml index 983f47d484f467d16d635c3a74ea083e29f5fdc2..587e988baf73dadd49b1b10368b6feeda5205625 100644 --- a/Sd1/swd1.xml +++ b/Sd1/swd1.xml @@ -8,231 +8,6 @@ xmlns:db="http://docbook.org/ns/docbook"> <title>Software development 1</title> - <chapter xml:id="sw1Lect1"> - <title>Lecture 1 (6.10.)</title> - - <section xml:id="sd1CommonRessources"> - <title>Common software development related resources</title> - - <glosslist> - <glossentry> - <glossterm><xref linkend="glo_HdM"/> mail server</glossterm> - - <glossdef> - <para>Either</para> - - <itemizedlist> - <listitem> - <para>read your mails regularly</para> - </listitem> - - <listitem> - <para>activate mail forwarding to your <quote>real</quote> - account at <link - xlink:href="https://mail.hdm-stuttgart.de/webmail">https://mail.hdm-stuttgart.de/webmail</link> - (<quote>Filter</quote> tab).</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><acronym>MI <xref linkend="glo_VPN"/></acronym> - Installation</glossterm> - - <glossdef> - <para>OpenVPN <acronym>wiki</acronym> <link - xlink:href="https://wiki.mi.hdm-stuttgart.de/wiki/VPN">installation - page</link> (Login required). Look for HdM_MI_stud.ovpn allowing - to use a maximum of MI specific services.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>MI Cloud</glossterm> - - <glossdef> - <para>25 GB free space. Base address <link - xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud">https://cloud.mi.hdm-stuttgart.de/owncloud</link>. - Client software for Linux, Android, - <productname>IOS</productname>, Windows, MacOS available at <link - xlink:href="http://owncloud.org/sync-clients">http://owncloud.org/sync-clients</link>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>MI <xref linkend="glo_Git"/> / <xref linkend="glo_Svn"/> - repository</glossterm> - - <glossdef> - <para><link - xlink:href="https://version.mi.hdm-stuttgart.de">https://version.mi.hdm-stuttgart.de</link></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>MI file server</glossterm> - - <glossdef> - <para><filename>Prototype user xy05 may acces his home directory - via \\srv2.srv.mi.hdm-stuttgart.de\xy05</filename> or - \\192.168.111.9\xy05 respectively.</para> - - <caution> - <para>External access requires <acronym>VPN</acronym></para> - </caution> - </glossdef> - </glossentry> - </glosslist> - </section> - - <section xml:id="sw1Resources"> - <title>Lecture related resources</title> - - <glosslist> - <glossentry> - <glossterm>Books / Literature</glossterm> - - <glossdef> - <glosslist> - <glossentry> - <glossterm>Primary</glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para><xref linkend="bib_Koelling2010"/> or <xref - linkend="bib_Koelling2010Ger"/>.</para> - </listitem> - - <listitem> - <para><xref linkend="bib_Horton2011"/></para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Secondary</glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para><xref linkend="bib_Jobst2014"/>.</para> - </listitem> - - <listitem> - <para>Older free online copy <xref - linkend="bib_Ullenboom2011"/> or current book <xref - linkend="bib_Ullenboom2014"/> including <xref - linkend="glo_Java"/> 8.</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>UNIX shell introduction</glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para><link - xlink:href="http://software-carpentry.org/v4/shell">The - Unix Shell</link> / Software-carpentry, nice video - collection. Each section is also available in PDF and - <trademark>PowerPoint</trademark> format.</para> - </listitem> - - <listitem> - <para><link - xlink:href="http://www.ee.surrey.ac.uk/Teaching/Unix">UNIX - Tutorial for Beginners</link>, text oriented.</para> - </listitem> - - <listitem> - <para><link - xlink:href="http://vic.gedris.org/Manual-ShellIntro/1.2/ShellIntro.pdf">An - Introduction to ...</link>, small reference of important - command names, filename conventions etc.</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - </glosslist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Live lecture additions</glossterm> - - <glossdef> - <para><link - xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud/public.php?service=files&t=df9f296af3298f96361a15a679390e59">MI - cloud folder</link></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><xref linkend="glo_Eclipse"/> <xref - linkend="glo_IDE"/></glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para><link - xlink:href="http://wiki.eclipse.org/Eclipse/Installation">Installation</link>, - choose <quote>Eclipse IDE for Java Developers</quote> from - <link - xlink:href="http://eclipse.org/downloads">http://eclipse.org/downloads</link>.</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Maven artifact - <quote>mi-maven-archetype-quickstart</quote></glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para>Configure <filename - xlink:href="http://maven.mi.hdm-stuttgart.de/Archetypes/catalog.xml">catalog.xml</filename> - in your <xref linkend="glo_Eclipse"/> <xref - linkend="glo_IDE"/> at - <guimenu>Window-->Preferences-->Maven-->Archetypes-->Add - Remote Catalog</guimenu>. Click <guibutton>verify</guibutton> - to assure correct configuration.</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><productname>Virtualbox</productname> - <productname>Lubuntu</productname> VM</glossterm> - - <glossdef> - <para><link - xlink:href="ftp://mirror.mi.hdm-stuttgart.de/ubuntu/VirtualBox">ftp://mirror.mi.hdm-stuttgart.de/ubuntu/VirtualBox</link>.</para> - - <caution> - <para>External access requires <acronym>VPN</acronym></para> - </caution> - - <para>If you experience bad <productname>Virtualbox</productname> - performance on your system please consider <link - xlink:href="http://blog.jdpfu.com/2012/09/14/solution-for-slow-ubuntu-in-virtualbox">solution-for-slow-ubuntu-in-virtualbox</link> - and the <link - xlink:href="http://blog.jdpfu.com/ALE/ALE-NW/Ubuntu-12.04-x32-install.pdf">referenced - collection of screenshots</link>.</para> - </glossdef> - </glossentry> - </glosslist> - </section> - </chapter> - <chapter xml:id="sd1IntroGreenfoot"> <title>Lecture 2 - Introduction to <link xlink:href="http://www.greenfoot.org">Greenfoot (8.10.)</link></title> @@ -1252,7866 +1027,521 @@ </section> </chapter> - <chapter xml:id="sd1ClassesInstancesState"> - <title>Lecture 5 - Classes, instances and internal state (20.10)</title> - - <section xml:id="sd1CrabsEnhancePrepare"> - <title>Preparations</title> + <chapter xml:id="sd1Variables"> + <title>Lecture 6 - Variables (27.10.)</title> - <itemizedlist> - <listitem> - <para>Read Chapter 5 from <xref linkend="bib_Horton2011"/> excluding - the sections <quote>Recursion</quote> and <quote>Nested - classes</quote>. Carefully read the explanations regarding:</para> + <itemizedlist> + <listitem> + <para>Read Chapter 2 from <xref linkend="bib_Horton2011"/> till + <quote>Mathematical Functions and constants</quote>.</para> + </listitem> - <itemizedlist> - <listitem> - <para>static vs. non-static methods and fields.</para> - </listitem> + <listitem> + <para>Read chapter 3 of <xref linkend="bib_Koelling2010Ger"/>.</para> + </listitem> + </itemizedlist> - <listitem> - <para>the <code>final</code> keyword's meaning.</para> - </listitem> + <section xml:id="sd1ExerciseGreenCh3"> + <title><productname>Greenfoot</productname></title> - <listitem> - <para>The way a garbage collector works.</para> - </listitem> - </itemizedlist> - </listitem> - </itemizedlist> + <para>Finish all exercises being presented in chapter 3 of <xref + linkend="bib_Koelling2010Ger"/>.</para> </section> + </chapter> - <section xml:id="sd1GeometryClasses"> - <title>Dealing with geometry classes</title> + <chapter xml:id="sd1L7"> + <title>Lecture 7 (29.10.)</title> - <qandaset defaultlabel="qanda" xml:id="sd1ImplementRectangle"> - <title>Rectangles</title> + <section xml:id="sd1CrabsFinish"> + <title>Preparations</title> - <qandaentry> - <question> - <para>Complete the the following class - <classname>Rectangle</classname>'s dummy implementation:</para> + <itemizedlist> + <listitem> + <para>Read the remaining chapter 2 from <xref + linkend="bib_Horton2011"/> excluding the <quote>Bitwise + Operations</quote> section.</para> + </listitem> - <programlisting language="java">/** - * Representing rectangular shapes. - * - */ -public class Rectangle { - - /** - * - * @param width The rectangle's width - * @param heigth The rectangle's height - */ - public Rectangle (double width, double heigth) { - //TODO - } - /** - * @return The rectangle's area. - */ - public double getArea() { - return 0; // TODO - } + <listitem> + <para>Read chapter 4 of <xref + linkend="bib_Koelling2010Ger"/>.</para> + </listitem> + </itemizedlist> + </section> - /** - * @return The rectangle's perimeter. - */ - public double getPerimeter() { - return 0; // TODO - } - - /** - * @return The rectangle's width. - */ - public double getWidth() { - return 0; // TODO - } - /** - * @param width The rectangle's new width - */ - public void setWidth(double width) { - // TODO - } + <section xml:id="sd1FirstLoops"> + <title>Exercises</title> - /** - * @return The rectangle's height. - */ - public double getHeight() { - return 0; // TODO - } - - /** - * @param width The rectangle's new height - */ - public void setHeight(double height) { - // TODO - } -}</programlisting> - </question> + <qandaset defaultlabel="qanda" xml:id="sd1WormEatWorm"> + <title>Eating multiple worms</title> - <answer> - <para>First we define two instance (= non-static) variables - representing a <classname>Rectangle</classname>'s two parameters - <code>width</code> and <code>height</code>:</para> + <qandadiv> + <qandaentry> + <question> + <para>We want to count the number of worms a crab has eaten so + long. This may later be used to finish the game (like you won!) + when a certain number has been exceeded.</para> - <programlisting language="java">public class Rectangle { - - // Instance variables representing a rectangle's parameters - private double width, height; -... -}</programlisting> + <para>For this purpose define a class variable + <code>noOfWormsEaten</code> in your class Crab and add an + increment rule to your <methodname>lookForWorm()</methodname> + method accordingly. Place two worms at exactly the same + position. Then activate <quote>inspect</quote> for a crab and + let the beast approach the two worms' position by clicking the + <quote>Act</quote> button in succession. When the crab eats the + two worms your variable <code>noOfWormsEaten</code> should have + a value of 2.</para> - <para>Next we might allow to change these two parameters:</para> + <para>Does the increment happen in one or two steps with respect + to clicking on <quote>Act</quote> ? Explain your result,</para> + </question> - <programlisting language="java">public class Rectangle { + <answer> + <para>A simple implementation to count worms being eaten + reads:</para> - // Instance variables representing a rectangle's parameters - private double width, height; + <programlisting language="java">public class Crab extends Animal { -... - public void setWidth(double w) { - <emphasis role="bold">width = w;</emphasis> - } + <emphasis role="bold">int noOfWormsEaten = 0; // initially no worm has been eaten</emphasis> + // other methods ... - /** - * @return The rectangle's height. - */ - public void setHeight(double height) { - <emphasis role="bold">this.height = height;</emphasis> - } -... + public void lookForWorm() { + if (canSee(Worm.class)) { + eat(Worm.class); + <emphasis role="bold">noOfWormsEaten++;</emphasis> + } + } }</programlisting> - <para>Notice the subtle difference in the implementation of - setWidth(...) and setHeight(...):</para> - - <glosslist> - <glossentry> - <glossterm><methodname>setWidth(double - w)</methodname></glossterm> - - <glossdef> - <para>We use the formal parameter name <quote>w</quote>. Its - name does not conflict with the instance variable name - <quote>width</quote> being defined at class level. We can - simply assign this value to our corresponding instance - variable using <code>width = w;</code>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><methodname>setHeight(double - height)</methodname></glossterm> - - <glossdef> - <para>The method's formal parameter <quote>height</quote> - shadows the instance variable's name being defined at class - level. We need the <quote>this</quote> keyword in - <code>this.height = height;</code> to resolve the - ambiguity.</para> - </glossdef> - </glossentry> - </glosslist> - - <para>Both ways are perfectly legal. We continue our - implementation:</para> - - <programlisting language="java">/** - * Representing rectangular shapes. - * - */ -public class Rectangle { - - // Instance variables representing a rectangle's parameters - private double width, height; - - /** - * - * @param width The rectangle's width - * @param heigth The rectangle's height - */ - public Rectangle (double width, double height) { - 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); - } - - /** - * @return The rectangle's width. - */ - public double getWidth() { - return width; - } - /** - * @param width The rectangle's new width - */ - public void setWidth(double w) { - width = w; - } - - /** - * @return The rectangle's height. - */ - public double getHeight() { - return height; - } - - /** - * @param width The rectangle's new height - */ - public void setHeight(double height) { - this.height = height; - } -}</programlisting> - </answer> - </qandaentry> + <para>When approaching two worms at an identical position the + instance variable <code>noOfWormsEaten</code> is being + incremented in two steps.</para> + </answer> + </qandaentry> + </qandadiv> </qandaset> - <qandaset defaultlabel="qanda" xml:id="qandasetGeometry"> - <title>Circles</title> + <qandaset defaultlabel="qanda" xml:id="sd1QandaGreedyCrab"> + <title>The greedy crab</title> <qandadiv> <qandaentry> <question> - <para>Complete the the following class - <classname>Circle</classname>'s dummy implementation:</para> + <para>Modify the behaviour of <xref linkend="sd1WormEatWorm"/>. + Whenever a crab can see worms all of them should be eaten at + once i.e on a single execution of your + <methodname>act()</methodname> method.</para> + </question> - <programlisting language="java">package step1.dummy; + <answer> + <para>Whenever <methodname>canSee()</methodname> returns true + only one worm will be eaten. Then + <methodname>canSee()</methodname> has to be called again till no + worm is being left. With respect to the solution of <xref + linkend="sd1WormEatWorm"/> we need to replace the + <code>if</code> clause by a <code>while</code> loop:</para> -/** - * A circle of given radius - * - */ -public class Circle { + <programlisting language="java"> public void lookForWorm() { + <emphasis role="bold">while</emphasis> (canSee(Worm.class)) { + eat(Worm.class); + noOfWormsEaten++; + }</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> - /** - * A new circle - * - * @param radius - * The desired radius. - */ - public Circle(double radius) { - // TODO - } - - /** - * @return The circle's area. - */ - public double getArea() { - return 0; // TODO - } - - /** - * @return The circle's perimeter. - */ - public double getPerimeter() { - return 0; // TODO - } - - /** - * @return The circle's radius. - */ - public double getRadius() { - return 0; // TODO - } - - /** - * @param radius - * Setting the circle's radius to a new value. - */ - public void setRadius(double radius) { - // TODO - } -}</programlisting> - - <para>Instances of this class shall be usable in the following - fashion:</para> - - <programlisting language="java">public class Driver { - - public static void main(String[] args) { - Circle c = new Circle(2.3); - System.out.println("Radius:" + c.getRadius()); - System.out.println("Perimeter:" + c.getPerimeter()); - System.out.println("Area:" + c.getArea()); - - // Changing the circle's radius to a different value - c.setRadius(4.7); - System.out.println("Radius:" + c.getRadius()); - System.out.println("Perimeter:" + c.getPerimeter()); - System.out.println("Area:" + c.getArea()); - } -}</programlisting> - - <para>Hint: Obviously you'll have to define an instance variable - within Circle to keep track of its current radius value. All - methods mentioned above simply depend on this single - value.</para> - </question> - - <answer> - <para>We define an instance variable radius inside our class - <classname>Circle</classname>:</para> - - <programlisting language="java"> -public class Circle { - - double radius; -... -}</programlisting> - - <para>Next we implement our method to change a circle's - radius:</para> - - <programlisting language="java"> public void setRadius(double r) { - radius = r; - }</programlisting> - - <para>Note that we have chosen a different value for the - method's formal radius parameter to be <quote>r</quote> rather - than <quote>radius</quote>. Many people prefer to use radius - here making it easier for a programmer to recognize the expected - name in the generated javadoc:</para> - - <programlisting language="java"> public void setRadius(double radius) { - <emphasis role="bold">this.</emphasis>radius = radius; - }</programlisting> - - <para>This requires the usage of the <code>this</code> keyword - to distinguish the formal parameter in - <methodname>setRadius(double radius)</methodname> from the - instance variable previously being defined within our class - <classname>Circle</classname>. In other words: We have to - resolve a name shadowing conflict.</para> - - <para>The rest of the implementation is (quite) straightforward. - A complete class reads:</para> - - <programlisting language="java">package step1; - -/** - * A circle of given radius - * - */ -public class Circle { - - double radius; - - /** - * A new circle - * @param radius The desired radius. - */ - public Circle(double radius) { - setRadius(radius); - } - - /** - * @return The circle's area. - */ - public double getArea() { - return radius * radius * Math.PI; - } - - /** - * @return The circle's perimeter. - */ - public double getPerimeter() { - return 2 * Math.PI * radius; - } - - /** - * @return The circle's radius. - */ - public double getRadius() { - return radius; - } - - /** - * @param radius Setting the circle's radius to a new value. - */ - public void setRadius(double radius) { - this.radius = radius; - } -}</programlisting> - </answer> - </qandaentry> - - <qandaentry> - <question> - <para>Our current Circle and Rectangle instances are only shapes - yet and do not allow to be moved in a coordinate system:</para> - - <itemizedlist> - <listitem> - <para>Add two more instance variables x and y and - corresponding setter methods to account for a shapes origin - being different from (0,0). The following hint may be - helpful:</para> - - <programlisting language="java"> /** - * @param x The circle's x center coordinate value - */ - public void setX(double x) { - // TODO - } - /** - * @param x The circle's x center coordinate value - */ - public void setY(double y) { - // TODO - }</programlisting> - </listitem> - - <listitem> - <para>We would like Rectangle and Circle instances to be - visualized as <acronym>SVG</acronym> graphics. Add a method - <methodname>void writeSvg()</methodname> to both classes - which allows for <acronym>SVG</acronym> code export to - standard output. You may want to read the w3schools <link - xlink:href="http://www.w3schools.com/svg/svg_rect.asp">rectangle</link> - and <link - xlink:href="http://www.w3schools.com/svg/svg_circle.asp">circle</link> - examples. Use System.out.println(...) calls to create the - desired <acronym>SVG</acronym> output. You may need - <code>\"</code> to represent double quotes as in the - subsequent example:</para> - - <programlisting language="java">System.out.println("<rect width=\"20\"" ...</programlisting> - </listitem> - </itemizedlist> - - <para>The following code snippet may serve to illustrate the - intended use of <methodname>void writeSvg()</methodname>:</para> - - <programlisting language="java">public class Driver { - - public static void main(String[] args) { - - System.out.println("<!DOCTYPE html><html><body>"); - System.out.println(" <svg width='300' height='200' >"); - - // Draw a rectangle as SVG - final Rectangle r = new Rectangle(5, 4); - r.setX(2); - r.setY(1); - r.writeSvg(); - - // Draw a circle as SVG - final Circle c = new Circle(1, 1, 3); - c.setX(3); - c.setY(1); - c.writeSvg(); - System.out.println(" </svg >"); - System.out.println("</body></html>"); - } -}</programlisting> - - <para>Implement the method <methodname>void - writeSvg()</methodname> in both classes - <classname>Rectangle</classname> and - <classname>Circle</classname>. This should produce an output - result like:</para> - - <programlisting language="java"><!DOCTYPE html> -<html> - <body> - <svg width='300' height='200' > - <emphasis role="bold"><rect width='100.0' height='80.0' x='40.0' y='20.0'' style='fill:rgb(0,255,0);stroke-width:3;stroke:rgb(0,0,0)'/></emphasis> - <emphasis role="bold"><circle r='60.0' cx='60.0' cy='20.0' style='fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)'/></emphasis> - </svg > - </body> -</html></programlisting> - - <para>You may enter this output into a file sfg.html. A web - browser should visualize this output as:</para> - - <informalfigure> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/svgGeometry.png"/> - </imageobject> - </mediaobject> - </informalfigure> - </question> - - <answer> - <programlisting language="java"> private double x, y, width, height; - ... - /** - * @param x The rectangle's x center coordinate value - */ - public void setX(double x) { - this.x = x; - } - /** - * @param x The rectangle's x center coordinate value - */ - public void setY(double y) { - this.y = y; - } - -public void writeSvg() { - final int scale = 20; - System.out.println( - "<rect width='" + scale * width +"' height='" + scale * height + - "' x='" + scale * x + "'" + " y='" + scale * y + "'" + - "' style='fill:rgb(0,255,0);stroke-width:3;stroke:rgb(0,0,0)'/>"); - } -}</programlisting> - - <programlisting language="java">public class Circle { - - double x, y, radius; -... - - /** - * @param x The circle's x center coordinate value - */ - public void setX(double x) { - this.x = x; - } - /** - * @param x The circle's x center coordinate value - */ - public void setY(double y) { - this.y = y; - } - -public void writeSvg() { - final int scale = 20; - - System.out.println( - "<circle r='" + scale * radius + - "' cx='" + scale * x + "'" + " cy='" + scale * y + - "' style='fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)'/>"); - - } -}</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1CrabsEnhance2"> - <title>Lecture 5 - A simple interest calculator (22.10.)</title> - - <!-- - <para>See compressed eclipse project account.zip in <link - xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud/public.php?service=files&t=df9f296af3298f96361a15a679390e59">subfolder - 06</link>. This example illustrates the following concepts:</para> ---> - - <para>Consider the following implementation of an interest - calculator:</para> - - <annotation role="make"> - <para role="eclipse">P/interest/V1</para> - </annotation> - - <glosslist> - <glossentry> - <glossterm>Instance versus class variables and methods</glossterm> - - <glossdef> - <para>Examples:</para> - - <glosslist> - <glossentry> - <glossterm>Instance variables and methods, non-static - declaration</glossterm> - - <glossdef> - <para><code>private double balance</code>, <code>public void - setBalance(double balance)</code></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Class variables and methods, static - declaration</glossterm> - - <glossdef> - <para><code>private static double </code>interestRate, - <code>public static void setInterestRate(double - z)</code></para> - </glossdef> - </glossentry> - </glosslist> - - <para>For both categories see <xref linkend="bib_Horton2011"/>, - chapter 5, <quote>Fields in a Class Definition</quote> and - <quote>Methods in a Class Definition</quote>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Formal parameter names and variable scopes</glossterm> - - <glossdef> - <programlisting language="java"> /** - * Setting the interest rate common to all accounts. - * - * @param z - * the desired (global) interest rate. - */ - public static void setInterestRate(double z) { // Scope of variable "z" limited is just the next block {...}, - interestRate = z; // in contrast interestRate has class scope. - }</programlisting> - - <para>The formal variable's name <quote><code>z</code></quote> may - be <emphasis>consistently</emphasis> renamed to any other legal, - non-conflicting value like - <quote><code>myFunnyVariableName</code></quote>:</para> - - <programlisting language="java"> public static void setInterestRate(double myFunnyVariableName) { - interestRate = myFunnyVariableName; - }</programlisting> - - <para>Name shadowing conflicts can be resolved by using the keyword - <emphasis><code>this</code></emphasis> <coref - linkend="sd1ListingThis"/>:</para> - - <programlisting language="java">public class Konto { -... - private double balance; <emphasis role="bold">// variable "stand" being shadowed inside body of setStand(...)</emphasis> -... - public void setStand(double stand) { - if (balance <= 10000) { - <emphasis role="bold">this</emphasis>.balance <co - xml:id="sd1ListingThis"/> = balance; // "this" required to resolve name shadowing conflict - // by formal parameter name "double balance". - } else { - System.out.println("Balance" + balance + " exceeds " + 10000); - } - } -... -}</programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Access restrictions public / private / protected to - attributes and methods</glossterm> - - <glossdef> - <programlisting language="java">public class Account { - - <emphasis role="bold">private</emphasis> static double // Visible for class methods only - interestRate = 1.5; -... - <emphasis role="bold">public</emphasis> void applyInterest() { // Externally visible - balance = balance * (1 + interestRate / 100); - } -...</programlisting> - - <para>See <xref linkend="bib_Horton2011"/>, chapter 5, - <quote>CONTROLLING ACCESS TO CLASS MEMBERS</quote>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Method overloading</glossterm> - - <glossdef> - <para>Example:</para> - - <programlisting language="java">public class Account { - - public Account() { // Default Constructor without any parameter - setBalance(0); - } -... - public Account(double balance) { // <emphasis role="bold">Overloaded</emphasis> non-default constructor creating an account - setBalance(balance); // with (possibly) non-zero balance. - } -... - public void applyInterest() { // Just one year - balance = balance * - (1 + interestRate / 100); - } -... - public void applyInterest(int years) { // <emphasis role="bold">Overloaded</emphasis> method allowing for different time periods. - balance = balance * - Math.pow((1 + interestRate / 100), years); - } -... -}</programlisting> - - <para>See <xref linkend="bib_Horton2011"/>, chapter 5, <quote>METHOD - OVERLOADING</quote>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Use of standard mathematical functions</glossterm> - - <glossdef> - <programlisting language="java">Math.pow((1 + interestRate / 100), years)</programlisting> - - <para>See <xref linkend="bib_Horton2011"/>, chapter 2, - <quote>MATHEMATICAL FUNCTIONS AND CONSTANTS</quote>.</para> - </glossdef> - </glossentry> - </glosslist> - </chapter> - - <chapter xml:id="sd1Variables"> - <title>Lecture 6 - Variables (27.10.)</title> - - <itemizedlist> - <listitem> - <para>Read Chapter 2 from <xref linkend="bib_Horton2011"/> till - <quote>Mathematical Functions and constants</quote>.</para> - </listitem> - - <listitem> - <para>Read chapter 3 of <xref linkend="bib_Koelling2010Ger"/>.</para> - </listitem> - </itemizedlist> - - <section xml:id="sd1VariableExercises"> - <title>Exercises</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaExtendInterest"> - <title>Extending interest calculations.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Our current <code>Account</code> class does not handle - negative balances accordingly. Typically banks will charge a - different interest rate whenever an account is in debt i.e. - having a negative balance. In this case a second so called - default interest rate (being significantly higher) will be - applied.</para> - - <para>Extend the current project by adding a new instance - variable <varname>defaultInterestRate</varname> along with - getter and setter methods. Then change the implementation of - <code>applyInterest()</code> and <code>applyInterest(int - years)</code> by using the correct interest value according to - the account's balance being positive or negative.</para> - - <caution> - <para>Do not forget to change the <command>Javadoc</command> - comments accordingly!</para> - </caution> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/interest/V2</para> - </annotation> - - <para>We introduce a new variable - <code>defaultInterestRate</code> to cover negative balance - values:</para> - - <programlisting language="java"> private static double - interestRate = 1.5, // applied to positive balances - <emphasis role="bold">defaultInterestRate = 15.; // applied to negative balances</emphasis></programlisting> - - <para>We need the appropriate getter and setter methods in - <classname - xlink:href="Ref/api/P/interest/V2/de/hdm_stuttgart/mi/sd1/interest/Account.html">Account</classname>:</para> - - <programlisting language="java"> /** - * @return - * the current default interest rate value. - */ - public static double <link - xlink:href="Ref/api/P/interest/V2/de/hdm_stuttgart/mi/sd1/interest/Account.html#getDefaultInterestRate--">getDefaultInterestRate()</link> { - return defaultInterestRate; - } - - /** - * This interest rate will be applied to negative balances. In contrast - * {{@link #setInterestRate(double)} will handle positive balance values. - * - * @param defaultInterestRate - * the desired default interest rate value. - */ - public static void <link - xlink:href="Ref/api/P/interest/V2/de/hdm_stuttgart/mi/sd1/interest/Account.html#setDefaultInterestRate-double-">setDefaultInterestRate(double defaultInterestRate)</link> { - Account.defaultInterestRate = defaultInterestRate; - }</programlisting> - - <para>The computed interest depends on positive or negative - balance values:</para> - - <programlisting language="java"> public void applyInterest(int years) { - if (0 < balance) { - balance = balance * Math.pow((1 + interestRate / 100), years) ; - } else if (balance < 0){ - balance = balance * Math.pow((1 + defaultInterestRate / 100), years) ; - } - }</programlisting> - - <para>A complete solution including updated - <productname>Javadoc</productname> comments can be downloaded - <link - xlink:href="https://cloud.mi.hdm-stuttgart.de/owncloud/public.php?service=files&t=577bc9091391524692b6d812a6d2737a">from - here</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1VariableComplexExpression"> - <title>Programmers favourite expression</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following code fragment:</para> - - <programlisting language="java"> int a = 6, - b = 7, - c = -3, - result = 0; - - result += ++a - b++ + --c;</programlisting> - - <para>Rewrite this code by decomposing the last line into - several lines to make the code easier to understand.</para> - - <para>Hint: After execution of your modified code all variable - must have identical values with respect to the original code. In - other words: Your modifications shall not alter the code's - behaviour in any way.</para> - </question> - - <answer> - <para>Incrementing <code>++a</code> and decrementing - <code>--c</code> happens prior to adding / subtracting their - values to the variable <code>result</code> (prefix notation). - The increment operation <code>b--</code> in contrast happens - after being being subtracted from variable <code>result</code> - (postfix notation). The following code snippet is thus - equivalent:</para> - - <programlisting language="java"> int a = 6, - b = 7, - c = -3, - result = 0; - ++a; - --c; - result += a - b + c; // or even: result = result + a - b + c; - b++;</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaIntOverflow"> - <title>Integer value considerations.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following piece of code:</para> - - <programlisting language="java">int a = ..., b = ...; -...// statements being omitted -int sum = a + b;</programlisting> - - <para>Which representation related problem may arise here? May - you supply a solution?</para> - </question> - - <answer> - <para>The sum of a and b may either exceed - <code>java.lang.Integer.MAX_VALUE</code> or in turn may be less - than <code>java.lang.Integer.MIN_VALUE</code>. To avoid this - type of overflow error our variable <code>sum</code> may be - declared of type long:</para> - - <programlisting language="java">int a = ..., b = ...; -...// statements being omitted -long sum = a + b;</programlisting> - - <para>Unfortunately this does not (yet) help at all: Since both - operands <code>a</code> and <code>b</code> are of type - <code>int</code> the expression <code>a + b</code> is also of - type int and will be evaluated as such. To circumvent this - problem we have to cast at least one operand to type - <code>long</code> prior to computing the sum. This works since - the cast operator <code>(long)</code> does have higher priority - than the <quote>+</quote> operator</para> - - <programlisting language="java">int a = ..., b = ...; -...// statements being omitted -long sum = (long)a + b;</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sde1QandaFraction"> - <title>A class representing fractions</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implement a class representing fractions. You may find a - dummy implementation containing some (not yet working) sample - usage code being contained in a <code>main()</code> method. This - Maven archive also includes a <xref linkend="glo_Junit"/> - test.</para> - - <annotation role="make"> - <para role="eclipse">P/fraction/V05</para> - </annotation> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/fraction/V1</para> - </annotation> - - <para>See implementation at <link - xlink:href="Ref/api/P/fraction/V1/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html">Fraction</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1ExerciseGreenCh3"> - <title><productname>Greenfoot</productname></title> - - <para>Finish all exercises being presented in chapter 3 of <xref - linkend="bib_Koelling2010Ger"/>.</para> - </section> - </chapter> - - <chapter xml:id="sd1L7"> - <title>Lecture 7 (29.10.)</title> - - <section xml:id="sd1CrabsFinish"> - <title>Preparations</title> - - <itemizedlist> - <listitem> - <para>Read the remaining chapter 2 from <xref - linkend="bib_Horton2011"/> excluding the <quote>Bitwise - Operations</quote> section.</para> - </listitem> - - <listitem> - <para>Read chapter 4 of <xref - linkend="bib_Koelling2010Ger"/>.</para> - </listitem> - </itemizedlist> - </section> - - <section xml:id="sd1FirstLoops"> - <title>Exercises</title> - - <qandaset defaultlabel="qanda" xml:id="sd1WormEatWorm"> - <title>Eating multiple worms</title> - - <qandadiv> - <qandaentry> - <question> - <para>We want to count the number of worms a crab has eaten so - long. This may later be used to finish the game (like you won!) - when a certain number has been exceeded.</para> - - <para>For this purpose define a class variable - <code>noOfWormsEaten</code> in your class Crab and add an - increment rule to your <methodname>lookForWorm()</methodname> - method accordingly. Place two worms at exactly the same - position. Then activate <quote>inspect</quote> for a crab and - let the beast approach the two worms' position by clicking the - <quote>Act</quote> button in succession. When the crab eats the - two worms your variable <code>noOfWormsEaten</code> should have - a value of 2.</para> - - <para>Does the increment happen in one or two steps with respect - to clicking on <quote>Act</quote> ? Explain your result,</para> - </question> - - <answer> - <para>A simple implementation to count worms being eaten - reads:</para> - - <programlisting language="java">public class Crab extends Animal { - - <emphasis role="bold">int noOfWormsEaten = 0; // initially no worm has been eaten</emphasis> - // other methods ... - - public void lookForWorm() { - if (canSee(Worm.class)) { - eat(Worm.class); - <emphasis role="bold">noOfWormsEaten++;</emphasis> - } - } -}</programlisting> - - <para>When approaching two worms at an identical position the - instance variable <code>noOfWormsEaten</code> is being - incremented in two steps.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaGreedyCrab"> - <title>The greedy crab</title> - - <qandadiv> - <qandaentry> - <question> - <para>Modify the behaviour of <xref linkend="sd1WormEatWorm"/>. - Whenever a crab can see worms all of them should be eaten at - once i.e on a single execution of your - <methodname>act()</methodname> method.</para> - </question> - - <answer> - <para>Whenever <methodname>canSee()</methodname> returns true - only one worm will be eaten. Then - <methodname>canSee()</methodname> has to be called again till no - worm is being left. With respect to the solution of <xref - linkend="sd1WormEatWorm"/> we need to replace the - <code>if</code> clause by a <code>while</code> loop:</para> - - <programlisting language="java"> public void lookForWorm() { - <emphasis role="bold">while</emphasis> (canSee(Worm.class)) { - eat(Worm.class); - noOfWormsEaten++; - }</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1TidyCrabImages"> - <title>Tidy up image handling</title> - - <qandadiv> - <qandaentry> - <question> - <para>The source ode of our little crab version 5 scenario - (<filename>book-scenarios/chapter02-04/little-crab-5)</filename> - contains:</para> - - <programlisting language="java">public class Crab extends Animal { - - private GreenfootImage <emphasis role="bold">image1</emphasis>; - private GreenfootImage <emphasis role="bold">image2</emphasis>; - ... - public Crab() { - <emphasis role="bold">image1</emphasis> = new GreenfootImage("crab.png"); - <emphasis role="bold">image2</emphasis> = new GreenfootImage("crab2.png"); - setImage(image1); - wormsEaten = 0; - }</programlisting> - - <para>Imagine we'd like to extend the crab game doing a - simulation requiring thousands of crabs. Why is the above code - badly written with respect to performance? Do you have an idea - how to correct this issue?</para> - - <para>Hint: Think whether each crab really needs two <emphasis - role="bold">individual</emphasis> images.</para> - </question> - - <answer> - <para>If we had 1000 crabs the code in question would allocate - 2000 images in memory. But actually only two of these 2000 - images are mutually different from each other. So allocating the - remaining 1998 is a wast of memory.</para> - - <para>It is sufficient to create only these two images since - each crab will just toggle between them. This should happen on - class level rater than on instance level:</para> - - <programlisting language="java">public class Crab extends Animal { - - private final static GreenfootImage image1 = new GreenfootImage("crab.png"); - private GreenfootImage image2 = new GreenfootImage("crab2.png"); - public Crab() { - setImage(image1); - wormsEaten = 0; - } ...</programlisting> - - <para>The remaining code may remain unchanged</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaInitCrabWorld"> - <title>Initializing our crab's world.</title> - - <qandadiv> - <qandaentry> - <question> - <para>We take a closer look at the little crab version 5 - scenario in - <filename>book-scenarios/chapter02-04/little-crab-5</filename>. - The subsequently copied code is meant to initialize our crab's - world. Albeit being technically achieving its purpose this code - lacks flexibility and suffers from various flaws to be corrected - by <emphasis role="bold">YOU</emphasis>:</para> - - <programlisting language="java">public class CrabWorld extends World { - /** - * Create the crab world (the beach). Our world has a size - * of 560x560 cells, where every cell is just 1 pixel. - */ - public CrabWorld() { - super(560, 560, 1); <co linkends="sd1CrabworldInitDeficiencies-1" - xml:id="sd1CrabworldInitDeficiencies-1-co"/> - populateWorld(); - } - - /** - * Create the objects for the start of the game. - */ - public void populateWorld() { - addObject(new Crab(), 300, 300); <co - linkends="sd1CrabworldInitDeficiencies-2" - xml:id="sd1CrabworldInitDeficiencies-2-co"/> <co - linkends="sd1CrabworldInitDeficiencies-3" - xml:id="sd1CrabworldInitDeficiencies-3-co"/> - - addObject(new Lobster(), 90, 70); <co - linkends="sd1CrabworldInitDeficiencies-4" - xml:id="sd1CrabworldInitDeficiencies-4-co"/> <coref - linkend="sd1CrabworldInitDeficiencies-2-co"/> <coref - linkend="sd1CrabworldInitDeficiencies-3-co"/> - addObject(new Lobster(), 390, 200); - addObject(new Lobster(), 360, 500); - - addObject(new Worm(), 20, 500); <coref - linkend="sd1CrabworldInitDeficiencies-4-co"/> <coref - linkend="sd1CrabworldInitDeficiencies-2-co"/> <coref - linkend="sd1CrabworldInitDeficiencies-3-co"/> - addObject(new Worm(), 30, 200); - addObject(new Worm(), 60, 90); - addObject(new Worm(), 80, 310); - addObject(new Worm(), 150, 50); - addObject(new Worm(), 210, 410); - addObject(new Worm(), 220, 520); - addObject(new Worm(), 380, 330); - addObject(new Worm(), 410, 270); - addObject(new Worm(), 530, 30); - } -}</programlisting> - - <calloutlist> - <callout arearefs="sd1CrabworldInitDeficiencies-1-co" - xml:id="sd1CrabworldInitDeficiencies-1"> - <para>We might want our world to become parametrized in a - more flexible way. Different values for width and height - should be easily adjustable. With respect to random - placement of characters these values should be accessible by - other methods as well. Thus having just integer literals in - a constructor call is not appropriate.</para> - - <para>Action: Define these parameters as class level - variables.</para> - </callout> - - <callout arearefs="sd1CrabworldInitDeficiencies-2-co" - xml:id="sd1CrabworldInitDeficiencies-2"> - <para>Our animals will always start at the same initial - position (300, 300). Playing this game frequently should - allow for random placement.</para> - - <para>Action: Use <productname>Greenfoot</productname>.<link - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/Greenfoot.html#getRandomNumber(int)">getRandomNumber(int)</link> - to place the crab at random positions.</para> - </callout> - - <callout arearefs="sd1CrabworldInitDeficiencies-3-co" - xml:id="sd1CrabworldInitDeficiencies-3"> - <para>All animals initially move into the same direction. - This is due to their rotation angle being initialized to - zero. Thus each animal will move exactly to the right when - starting the game.</para> - - <para>Action: Randomly initialize all moving animals' - initial walking directions.</para> - </callout> - - <callout arearefs="sd1CrabworldInitDeficiencies-4-co" - xml:id="sd1CrabworldInitDeficiencies-4"> - <para>All animals are being positioned at fixed positions - making our game a little boring.</para> - - <para>Action: Rather then positioning lobsters and worms one - by one use two different for-loops instead. Inside each loop - randomly position each animal:</para> - - <programlisting language="java">for (...) { - <emphasis role="bold">// Create all desired worms</emphasis> -} - -for (...) { - <emphasis role="bold">// Create all desired lobsters</emphasis> -}</programlisting> - - <para>Use class variables to define the number of animals to - be created.</para> - </callout> - </calloutlist> - </question> - - <answer> - <orderedlist> - <listitem> - <para>We define two variables <emphasis - role="bold">worldWidth</emphasis> , <emphasis - role="bold">worldHeight</emphasis> and make them replace the - integer literal values inside our default - constructor:</para> - - <programlisting language="java">public class CrabWorld extends World { - - private final static int // Width and height of our - <emphasis role="bold">worldWidth</emphasis> = 700, // crab's world. - <emphasis role="bold">worldHeight</emphasis> = 560; -... - - public CrabWorld() { - super(<emphasis role="bold">worldWidth</emphasis>, <emphasis role="bold">worldHeight</emphasis>, 1); - populateWorld(); - } ...</programlisting> - </listitem> - - <listitem> - <para>There are different ways to implement choosing - coordinates randomly. We take an intermediate step by - implementing two helper methods which create random x- and - y-coordinate values being valid with respect to our world's - boundaries:</para> - - <programlisting language="java">public class CrabWorld extends World { - - private final static int // Width and height of our - worldWidth = 700, // crab's world. - worldHeight = 560; - - /** - * @return A random c ranging from 0 to the worlds's width in pixel units - * - 1. A width of e.g. 100 sets the range to {0, 1,..., 99}. - */ - public static int getRandomX() { - return Greenfoot.getRandomNumber(worldWidth); - } - - /** - * @return A random number ranging from 0 to the worlds's height in pixel - * units - 1. A height of e.g. 70 sets the range to {0, 1,..., 69}. - */ - public static int getRandomY() { - return Greenfoot.getRandomNumber(worldHeight); - } ...</programlisting> - - <para>Creating animals at random positions becomes fairly - easy:</para> - - <programlisting language="java"> public void populateWorld() { - addObject(new Crab(), <emphasis role="bold">getRandomX()</emphasis>, <emphasis - role="bold">getRandomY()</emphasis>);...</programlisting> - </listitem> - - <listitem> - <para>In complete analogy we implement a random rotation - value generating method:</para> - - <programlisting language="java"> /** - * @return A random rotation within the range [0, 1, ..., 360[. - */ - public static int getRandomRotation() { - return Greenfoot.getRandomNumber(360); - }</programlisting> - - <para>We might create animals and set their rotation value - subsequently. Adding a non-default constructor appears to be - a cleaner approach:</para> - - <programlisting language="java">public class Crab extends Animal { - - // Common constructor code: Initialize a crab's two images, rotation ... - private void commonConstructor(int rotation) { - setRotation(rotation); - setImage(image1); - wormsEaten = 0; - } - - /** - * Create a crab. - */ - public Crab() { - commonConstructor(0); - } - - public Crab(int rotation) { - commonConstructor(rotation); - }</programlisting> - - <para>We may now complete a crab's random placement with - random rotation value:</para> - - <programlisting language="java"> public void populateWorld() { - addObject(new Crab(getRandomRotation()), getRandomX(), getRandomY());...</programlisting> - </listitem> - - <listitem> - <para>Creating and placing lobsters and worms randomly is - now a straightforward exercise:</para> - - <programlisting language="java">public class CrabWorld extends World { - - private final static int - <emphasis role="bold">initialLobsterCount</emphasis> = 3, - <emphasis role="bold">initialWormCount</emphasis> = 10; -... - - public void populateWorld() { - addObject(new Crab(getRandomRotation()), getRandomX(), getRandomY()); - - // Creating lobsters. - for (int i = 0; i < i<emphasis role="bold">nitialLobsterCount</emphasis>; i++) { - addObject(new Lobster(getRandomRotation()), getRandomX(), getRandomY()); - } - // Creating worms. - for (int i = 0; i < <emphasis role="bold">initialWormCount</emphasis>; i++) { - addObject(new Worm(), getRandomX(), getRandomY()); - } - } ...</programlisting> - </listitem> - </orderedlist> - - <annotation role="make"> - <para role="eclipse">P/crab/V1</para> - </annotation> - </answer> - </qandaentry> - - <qandaentry> - <question> - <para>The current initialization code may produce the following - scenario:</para> - - <informalfigure> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/stayclear.png"/> - </imageobject> - </mediaobject> - </informalfigure> - - <para>This will leave a player with hardly any chance to escape. - So we'd like our lobsters to initially keep some distance from - our crab. Modify your code accordingly.</para> - - <para>Hint: Calculate the distance between a potential lobster's - position and the already existing crab. Exclude placements - whenever a lobster gets too close.</para> - </question> - - <answer> - <para>We may define a constant reflecting the minimal initial - distance between a lobster and a crab:</para> - - <programlisting language="java">public class CrabWorld extends World { - - private final static int ... - - minimalLobsterCrabDistance = 100; // The minimal distance when starting the game. ...</programlisting> - - <para>We may then modify our loop to exclude lobster coordinate - positions <coref linkend="sd1ListingExcludeLobsterCircle"/> - falling inside a circle of radius <emphasis - role="bold">minimalLobsterCrabDistance</emphasis> surrounding - our crab:</para> - - <programlisting language="java"> public void populateWorld() { - - final int crabX = getRandomX(), // Our crab's initial (x|y) coordinates are - crabY = getRandomY(); // needed for later calculations, see below. - - <emphasis role="bold">// Create our crab.</emphasis> - addObject(new Crab(getRandomRotation()), crabX, crabY); - - <emphasis role="bold">// Creating lobsters.</emphasis> - int numLobsters = 0; - while (numLobsters < initialLobsterCount) { // We use a while loop instead of for since - // numLobsters gets incremented condionally. - - final int lobsterX = getRandomX(), // <emphasis role="bold">Potential</emphasis> lobster's position - lobsterY = getRandomY(), // at (lobsterX|lobsterY). - deltaX = lobsterX - crabX, - deltaY = lobsterY - crabY; - - // Pythagoras is talking to us. Do you listen? If you can't hear him, take a pencil - // and a sheet of paper to sketch the problem's geometry. - // - // We only add a lobster at coordinate position (lobsterX|lobsterY) if - // its distance to our crab is sufficiently large. - // - if (<emphasis role="bold">minimalLobsterCrabDistance * minimalLobsterCrabDistance <</emphasis> <co - xml:id="sd1ListingExcludeLobsterCircle"/> // Distance between lobster and crab is - <emphasis role="bold">deltaX * deltaX + deltaY * deltaY</emphasis>) { // larger than minimalLobsterCrabDistance. - addObject(new Lobster(getRandomRotation()), lobsterX, lobsterY); - numLobsters++; - } - } - - <emphasis role="bold">// Creating worms. Easy: No conditions apply.</emphasis> - for (int i = 0; i < initialWormCount; i++) { - addObject(new Worm(), getRandomX(), getRandomY()); - } - }</programlisting> - - <para>Full <command>Javadoc</command> including source code is - <link - xlink:href="Ref/api/P/crab/V2/package-summary.html">available - here</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1XXX"> - <title>Lecture 8, Loops I (3.11.)</title> - - <section xml:id="sd1LoopPrepare"> - <title>Preparations</title> - - <para>Chapter <quote>Loops and logic</quote> <xref - linkend="bib_Horton2011"/> till <quote>Loops</quote> (inclusive).</para> - </section> - - <section xml:id="sd1LoopExercises"> - <title>Exercises</title> - - <section xml:id="sd1LeapYera"> - <title>Leap years</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaLeapYear"> - <title>Distinguishing leap- and non-leap years</title> - - <qandadiv> - <qandaentry> - <question> - <para>Look up the Gregorian calendar rule for leap years. Then - implement the following method to decide whether a given year - is a leap year:</para> - - <programlisting language="java"> /** - * Characterizing a given year either as leap year or - * non- leap year - * - * @param year The year in question. - * @return true if the year parameter is a leap year, false otherwise. - */ - public static boolean isLeapYear(int year) { - ... - }</programlisting> - - <para>You should be able to test your implementation the - following way:</para> - - <programlisting language="java"> public static void main(String[] args) { - System.out.println("Is 1800 a leap year? " + isLeapYear(1800)); - System.out.println("Is 2000 a leap year? " + isLeapYear(2000)); - System.out.println("Is 2016 a leap year? " + isLeapYear(2016)); - }</programlisting> - - <para>This should produce the following output:</para> - - <programlisting language="ignore">Is 1800 a leap year? false -Is 2000 a leap year? true -Is 2016 a leap year? true</programlisting> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/rounding</para> - </annotation> - - <para>A first solution may be:</para> - - <programlisting language="java"> <link - xlink:href="Ref/api/P/rounding//de/hdm_stuttgart/de/sd1/leap/LeapYear.html#isLeapYear-int-">public static boolean isLeapYear(int year)</link> { - if (year % 400 == 0) { // Every 400 years we do have a leap year. - return true; - } else if (year % 4 == 0 && 0 != year % 100) { // Every 4 years we do have a leap year unless the year - return true; // in question is a multiple of 100. - } else { - return false; - } - }</programlisting> - - <para>This one is easy to read. Experienced programmers - however prefer compact code:</para> - - <programlisting language="java"> <link - xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/leap/LeapYearCompact.html#isLeapYear-int-">public static boolean isLeapYear(int year)</link> { - return - year % 400 == 0 || // Every 400 years we do have a leap year. - year % 4 == 0 && 0 != year % 100; // Every 4 years we do have a leap year unless the year - // in question is a multiple of 100. - } </programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1SummingUpIntegers"> - <title>Summing up integer values</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaSumInteger"> - <title>Summing up integers to a given limit</title> - - <qandadiv> - <qandaentry> - <question> - <para>Suppose an arbitrary number n is given e.g n=5. We want - to compute the sum of all integers ranging from 1 to 5:</para> - - <para>1 + 2 + 3 + 4 + 5 = 15</para> - - <para>Implement the following method by using a loop:</para> - - <programlisting language="java"> /** - * Summing up all integers up to and including a given limit - * Example: Let the limit be 5, then the result is 1 + 2 + 3 + 4 + 5 - * - * @param limit The last number to include into the computed sum - * @return The sum of 1 + 2 + ... + limit - */ - public static long getSum (int limit) { - ... - }</programlisting> - - <para>You may test your implementation by:<programlisting - language="java"> public static void main(String[] args) { - System.out.println("1 + 2 + ... + 150" + "=" + getSum(150)); - }</programlisting><parameter>Actually a loop is not needed - since:</parameter></para> - - <informalequation> - <m:math display="block"> - <m:mrow> - <m:mrow> - <m:munderover> - <m:mo>∑</m:mo> - - <m:mrow> - <m:mi>i</m:mi> - - <m:mo>=</m:mo> - - <m:mi>1</m:mi> - </m:mrow> - - <m:mi>n</m:mi> - </m:munderover> - - <m:mi>i</m:mi> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mfrac> - <m:mrow> - <m:mi>n</m:mi> - - <m:mo>â¢</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mrow> - <m:mi>n</m:mi> - - <m:mo>+</m:mo> - - <m:mi>1</m:mi> - </m:mrow> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - </m:math> - </informalequation> - - <para>You may use this formula to verify your - implementation.</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/rounding</para> - </annotation> - - <para>We just need a single loop in <link - xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/sum/Summing.html#getSum-int-">getSum(...)</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1RewriteLoop"> - <title>Rewriting a loop</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaRewriteLoop"> - <title><code>for</code>, <code>while</code> and <code>do</code> ... - <code>while</code></title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following example:</para> - - <programlisting language="java">public class LoopExample { - - public static void main(String [] args) { - squareNumbers(14); - } - - /** - * Compute all square numbers starting from 4 in steps of 3 - * being smaller than a given limit. The results are being written to standard output. - * Implemented by a for -loop. - * - * @param limit An upper exclusive bound for the highest number to be squared.. - */ - public static void squareNumbers(final int limit) { - System.out.println("Computing square numbers"); - for (int i = 4; i < limit; i += 3) { - System.out.println("i = " + i + ", i * i = " + i * i); - } - System.out.println("Finished computing square numbers"); - } -}</programlisting> - - <para>Re-implement the above code two times as:</para> - - <orderedlist> - <listitem> - <para>while loop:</para> - - <programlisting language="java"> ... - public static void while_squareNumbers(final int limit) { - System.out.println("Computing square numbers"); -... - while (...) { -... - } - System.out.println("Finished computing square numbers"); - } ...</programlisting> - </listitem> - - <listitem> - <para>do ... while loop:</para> - - <programlisting language="java"> ... - public static void while_squareNumbers(final int limit) { - System.out.println("Computing square numbers"); -... - do { -... - } while(...); - - System.out.println("Finished computing square numbers"); - } ...</programlisting> - </listitem> - </orderedlist> - - <para>Caveat: The do ... while part is a little bit tricky. - Read the method's documentation <emphasis><emphasis - role="bold">precisely</emphasis></emphasis> to avoid a common - pitfall.</para> - - <para>Do you have a comment choosing the right type of - loop?</para> - </question> - - <answer> - <para>The while loop is actually quite straightforward to - implement:</para> - - <programlisting language="java">public class <link - xlink:href="Ref/api/P/loop/answer/de/hdm_stuttgart/de/sd1/loop/LoopExample.html">LoopExample</link> { - ... - public static void <link - xlink:href="Ref/api/P/loop/answer/de/hdm_stuttgart/de/sd1/loop/LoopExample.html#doWhile_squareNumbers-int-">while_squareNumbers(final int limit)</link> { - System.out.println("Computing square numbers"); - int i = 4; - while (i < limit) { - System.out.println("i = " + i + ", i * i = " + i * i); - i += 3; - } - System.out.println("Finished computing square numbers"); - } ...</programlisting> - - <para>Its tempting to implement a <code>do ... while</code> in - a similar fashion:</para> - - <programlisting language="java">public class LoopExample { - ... - public static void doWhile_squareNumbers(final int limit) { - System.out.println("Computing square numbers"); - int i = 4; - do { - System.out.println("i = " + i + ", i * i = " + i * i); - i += 3; - } while (i < limit); - System.out.println("Finished computing square numbers"); - } ...</programlisting> - - <para>This implementation however is flawed: If we call - doWhile_squareNumbers(3) we still receive one line of output. - But according to the documentation no output is to be - expected. Whatever the argument is, at least one output line - gets printed. To avoid this error the loop has to be enclosed - by an if- statement:</para> - - <programlisting language="java"> public static void <link - xlink:href="Ref/api/P/loop/answer/de/hdm_stuttgart/de/sd1/loop/LoopExample.html#doWhile_squareNumbers-int-">doWhile_squareNumbers</link>(final int limit) { - System.out.println("Computing square numbers"); - int i = 4; - if (i < limit) { // Needed !!! - do { - System.out.println("i = " + i + ", i * i = " + i * i); - i += 3; - } while (i < limit); - } - System.out.println("Finished computing square numbers"); - }</programlisting> - - <para>This required if-clause reminds us that a <code>do {...} - while (...)</code> is an ill-suited choice here in comparison - to a <code>while(...){...}</code> or a - <code>for(...){...}</code> loop.</para> - - <para>Actually a <code>for(...){...} loop is the best choice - here since the number of iterations is known in advance, the - increment is constant and it allows for - initialization</code>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1MathTable"> - <title>A mathematical table.</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaSinTable"> - <title>Nicely formatting sine values.</title> - - <qandadiv> - <qandaentry> - <question> - <para>We are interested in the following output presenting the - sine function rounded to three decimal places:</para> - - <programlisting language="ignore"> x | sin(x) -----+------ - 0 | 0.000 - 5 | 0.087 - 10 | 0.174 - 15 | 0.259 - 20 | 0.342 -----+------- - 25 | 0.423 - 30 | 0.500 - 35 | 0.574 - 40 | 0.643 -----+------- -... (left out for brevity's sake) -----+------- -325 |-0.574 -330 |-0.500 -335 |-0.423 -340 |-0.342 -----+------- -345 |-0.259 -350 |-0.174 -355 |-0.870</programlisting> - - <para>You may also generate HTML output.</para> - - <para>Write a corresponding Java application producing this - output. You will have to deal with alignment problems, leading - spaces, padding zeros and so on. Though more sophisticated - support exists the following hints will fully suffice:</para> - - <orderedlist> - <listitem> - <para>Consider the <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sin-double-">sin(...)</link> - function. The documentation will tell you that the - argument to sin(...) is expected to be in radians rather - than common degree values from [0,360[ being expected on - output. So you will have to transform degree values to - radians.</para> - </listitem> - - <listitem> - <para>Depending on the angle's value you may want to add - one or two leading spaces to keep the first column right - aligned.</para> - </listitem> - - <listitem> - <para>Depending on the sign you may want to add leading - spaces to the second column.</para> - </listitem> - - <listitem> - <para>Rounding the sine's value is the crucial part here. - The function <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-">round()</link> - is quite helpful. Consider the following example rounding - 23.22365 to four decimal places:</para> - - <orderedlist> - <listitem> - <para>Multiplication by 10000 results in - 232236.5</para> - </listitem> - - <listitem> - <para><link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-">round(232236.5)</link> - results in 232237 (long).</para> - </listitem> - - <listitem> - <para>Integer division by 10000 yields 23</para> - </listitem> - - <listitem> - <para>The remainder (by 10000) is 2237</para> - </listitem> - - <listitem> - <para>So you may print 23.2237 this way</para> - </listitem> - </orderedlist> - </listitem> - - <listitem> - <para>You'll need padding zero values to transform e.g. - <quote>0.4</quote> to <quote>0.400</quote>.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/rounding</para> - </annotation> - - <para>See <link - xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/rounding/MathTable.html">MathTable</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1Loop2"> - <title>Lecture 9, Loops II (5.11.)</title> - - <section xml:id="sd1Gcd"> - <title>The greatest common divisor and the common multiple</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaGcd"> - <title>Finding the greatest common divisor of two integer - values</title> - - <qandadiv> - <qandaentry> - <question> - <para>We recall <xref linkend="sde1QandaFraction"/>. So far no - one demands fractions to be kept in maximally reduced state. The - call new Fraction(4,8) will create an instance internally being - represented by <inlineequation> - <m:math display="inline"> - <m:mfrac> - <m:mi>4</m:mi> - - <m:mi>8</m:mi> - </m:mfrac> - </m:math> - </inlineequation> rather than by <inlineequation> - <m:math display="inline"> - <m:mfrac> - <m:mi>1</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:math> - </inlineequation>.</para> - - <para>Reducing fractions requires a loop implementing e.g. the - <link - xlink:href="http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html">Euclidean - algorithm</link> in order to find the greatest common divisor - (<acronym>GCD</acronym>) of two non-zero integer values.</para> - - <para>Read the above link and implement a private class method - getGcd(long, long) inside a class - <classname>Math</classname>:</para> - - <programlisting language="java"> public static long getGcd(long a, long b) <co - xml:id="sd1ListEuclidNeg"/> { - // Following http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html - return ??; - }</programlisting> - - <para>With respect to fractions one or both parameters - <code>a</code> and <code>b</code> <coref - linkend="sd1ListEuclidNeg"/> may zero or negative. So we do have - several special cases to handle:</para> - - <glosslist> - <glossentry> - <glossterm>a == 0 and b == 0</glossterm> - - <glossdef> - <para>Return 1.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>a == 0 and b != 0</glossterm> - - <glossdef> - <para>Return absolute value of b.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>a != 0 and b != 0</glossterm> - - <glossdef> - <para>Return the <acronym>gcd</acronym> of the absolute - values of a and b</para> - </glossdef> - </glossentry> - </glosslist> - - <para>Based on <methodname>getGcd(...)</methodname> implement - the common multiple of two long values:</para> - - <programlisting language="java">public static long getCommonMultiple(long a, long b) {...}</programlisting> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Gcd/V1</para> - </annotation> - - <para>Implementing <methodname - xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getGcd-long-long-">getGcd(</methodname>...):</para> - - <programlisting language="java"> public static long <link - xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getCommonMultiple-long-long-">getGcd(long a, long b)</link> { - - // Following http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html - if (a < b) { // Swap the values of a and b - long tmp = a; - a = b; - b = tmp; - } - while (0 != b) { - long r = a % b; - a = b; - b = r; - } - return a; - }</programlisting> - - <para>Knowing the the <acronym>gcd</acronym> of two values a and - b the common multiple may be obtained by <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mfrac> - <m:mi>a</m:mi> - - <m:mi>gcd</m:mi> - </m:mfrac> - - <m:mo>â¢</m:mo> - - <m:mfrac> - <m:mi>b</m:mi> - - <m:mi>gcd</m:mi> - </m:mfrac> - - <m:mo>â¢</m:mo> - - <m:mi>gcd</m:mi> - - <m:mo>=</m:mo> - - <m:mfrac> - <m:mrow> - <m:mi>a</m:mi> - - <m:mo>â¢</m:mo> - - <m:mi>b</m:mi> - </m:mrow> - - <m:mi>gcd</m:mi> - </m:mfrac> - </m:mrow> - </m:math> - </inlineequation>. Thus we have:</para> - - <programlisting language="java"> public static long <link - xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getGcd-long-long-">getCommonMultiple(long a, long b)</link> { - final long gcd = getGcd(a, b); - if (1 == gcd) { - return a * b; - } else { - return (a / gcd) * b; - } - }</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="ed1FractionCancel"> - <title>Reducing fractions</title> - - <para>The following exercise requires the import of the previous Maven - based exercise <xref linkend="sd1QandaGcd"/>. The import may be effected - by:</para> - - <orderedlist> - <listitem> - <para>Creating a local Maven jar archive export by executing - <quote><command>mvn</command> <option>install</option></quote> in - project <xref linkend="sd1QandaGcd"/> at the command line. - Alternatively you may right click on your <xref - linkend="glo_pom.xml"/> file in <xref linkend="glo_Eclipse"/> - hitting <quote>Run as Maven build</quote> using - <parameter>install</parameter> as goal.</para> - </listitem> - - <listitem> - <para>Defining <xref linkend="sd1QandaGcd"/> as a dependency <coref - linkend="mvnGcdDep"/> in your current project:</para> - - <programlisting language="none"><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> - - <groupId>de.hdm-stuttgart.de.sd1</groupId> - <artifactId>fraction</artifactId> - <version>1.0</version> - <packaging>jar</packaging> - - <name>fraction</name> - ... - <dependencies> - <emphasis role="bold"><dependency></emphasis> <co xml:id="mvnGcdDep"/> - <emphasis role="bold"><groupId>de.hdm-stuttgart.de.sd1</groupId> - <artifactId>gcd</artifactId> - <version>1.0</version> - <scope>compile</scope> - </dependency></emphasis> - <dependency> - <groupId>junit</groupId> - ... - </dependency> - </dependencies> -</project></programlisting> - </listitem> - </orderedlist> - - <figure xml:id="figMavenProjectDependency"> - <title>Defining a dependency to another Maven artifact.</title> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Svg/mavenPrjRef.svg"/> - </imageobject> - </mediaobject> - </figure> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaFractionCancel"> - <title>Implementing reducing of fractions</title> - - <qandadiv> - <qandaentry> - <question> - <para>We have implemented <acronym>GCD</acronym> computation in - <xref linkend="sd1QandaGcd"/>. The current exercises idea is to - implement reducing of fractions by using the method - <methodname>long getGcd(long a, long b)</methodname>. Change the - following implementation items:</para> - - <itemizedlist> - <listitem> - <para>The constructor should reduce a fraction if required, - see introductory remark.</para> - </listitem> - - <listitem> - <para>The Methods <methodname>mult(...)</methodname> and - <methodname>add(...)</methodname> should reduce any - resulting Fraction instance. It might be worth to consider a - defensive strategy to avoid unnecessary overflow - errors.</para> - </listitem> - </itemizedlist> - - <para>Test your results.</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/fraction/V2</para> - </annotation> - - <para>Modifying the constructor is straightforward: On creating - a fraction we simply divide both numerator and denominator by - the <acronym>GCD</acronym> value:</para> - - <programlisting language="java"> <link - xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#Fraction-long-long-">public Fraction(long numerator, long denominator)</link> { - final long gcd = Math.getGcd(numerator, denominator); - - setNumerator(numerator / gcd); - setDenominator(denominator / gcd); - }</programlisting> - - <para>Its tempting to implement - <methodname>mult(...)</methodname> in a simple fashion:</para> - - <programlisting language="java"> public Fraction mult2(Fraction f) { - return new Fraction(numerator * f.numerator, - denominator * f.denominator); - }</programlisting> - - <para>This is however too shortsighted. Consider the example - <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mfrac> - <m:mi>4</m:mi> - - <m:mi>7</m:mi> - </m:mfrac> - - <m:mo>â¢</m:mo> - - <m:mfrac> - <m:mi>3</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - </m:math> - </inlineequation>. Our simple implementation proposal would - call <code>new Fraction(12, 14)</code> only to discover a - <acronym>GCD</acronym> value of 4. Having larger argument values - this might cause an unnecessary overflow. Moreover the - <acronym>GCD</acronym> calculation will take longer than - needed.</para> - - <para>We may instead transform the term in question by - exchanging the numerators like <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mfrac> - <m:mi>3</m:mi> - - <m:mi>7</m:mi> - </m:mfrac> - - <m:mo>â¢</m:mo> - - <m:mfrac> - <m:mi>4</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - </m:math> - </inlineequation> to enable reducing <emphasis - role="bold">prior</emphasis> to multiplying. Now the call - <code>new Fraction(4,2)</code> will construct the representation - <inlineequation> - <m:math display="inline"> - <m:mfrac> - <m:mi>2</m:mi> - - <m:mi>1</m:mi> - </m:mfrac> - </m:math> - </inlineequation> and finishing the computation will yield the - correct result <inlineequation> - <m:math display="inline"> - <m:mfrac> - <m:mi>6</m:mi> - - <m:mi>7</m:mi> - </m:mfrac> - </m:math> - </inlineequation>. We should thus implement:</para> - - <programlisting language="java"> public Fraction <link - xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#mult-de.hdm_stuttgart.mi.sd1.fraction.Fraction-">mult(Fraction f)</link> { - final Fraction f1 = new Fraction(f.numerator, denominator), - f2 = new Fraction(numerator, f.denominator); - - return new Fraction(f1.numerator * f2.numerator, - f1.denominator * f2.denominator); - }</programlisting> - - <para>Similar reflections lead to the clue decomposing the - denominators when implementing - <methodname>add(...)</methodname>. This is what you'd do as well - if your task was adding two fractions by hand trying to avoid - large numbers:</para> - - <programlisting language="java"> public Fraction <link - xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#add-de.hdm_stuttgart.mi.sd1.fraction.Fraction-">add(Fraction f)</link> { - - final long gcd = Math.getGcd(denominator, f.denominator); - - return new Fraction( numerator * (f.denominator / gcd) + (denominator / gcd) * f.numerator, - (denominator / gcd) * f.denominator); - }</programlisting> - - <para>See complete <link - xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html">implementation - here</link>. We may re-use out test:</para> - - <programlisting language="java"> public static void <link - xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Driver.html#main-java.lang.String:A-">main(String[] args)</link> { - - // Input - final Fraction - twoThird = new Fraction(2, 3), // Construct a fraction object (2/3) - threeSeven = new Fraction(3, 7); // Construct a fraction object (3/7) - - // Computed results - final Fraction - sum = twoThird.add(threeSeven), // (2/3) + (3/7) - product = twoThird.mult(threeSeven); // (2/3) * (3/7) - - System.out.println("(2/3) + (3/7) = (23/21) = " + sum.getValue()); - System.out.println("(2/3) * (3/7) = (2/7) = " + product.getValue()); - }</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1MathMaxAbs"> - <title>Building a private library of mathematical functions.</title> - - <para>The following sections provide exercises on implementing - mathematical functions. We start with an easy one.</para> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaMaxAbs"> - <title>Maximum and absolute value</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implement two class methods double abs(double) and double - max(double, double, double) in a class math living in a package - of your choice:</para> - - <programlisting language="java">package de.hdm_stuttgart.de.sd1.math; - -/** - * Some class methods. - */ -public class Math { - - /** - * Return the absolute value of a given argument - * @param value The argument to be considered - * @return the argument's absolute (positive) value. - */ - public static double abs(double value) { - ... return ??; - } - - /** - * The maximum of two arguments - * @param a First argument - * @param b Second argument - * @return The maximum of a and b - */ - public static double max(double a, double b) { - ... return ??; - } - - /** - * The maximum of three arguments - * - * @param a First argument - * @param b Second argument - * @param c Third argument - * @return The maximum of a, b and c - */ - public static double max(double a, double b, double c) { - ... return ??; - } -}</programlisting> - - <para>Test these functions using appropriate data.</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/math/V0_5</para> - </annotation> - - <para>See <link - xlink:href="Ref/api/P/math/V0_5/de/hdm_stuttgart/de/sd1/math/Math.html">implementation - here.</link></para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1SecExp"> - <title>Implementing the exponential function.</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaMath"> - <title>The exponential <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mi>f</m:mi> - - <m:mo>â¡</m:mo> - - <m:mfenced> - <m:mi>x</m:mi> - </m:mfenced> - </m:mrow> - - <m:mo>=</m:mo> - - <m:msup> - <m:mi>e</m:mi> - - <m:mi>x</m:mi> - </m:msup> - </m:mrow> - </m:math> - </inlineequation></title> - - <qandadiv> - <qandaentry> - <question> - <para>The exponential <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mi>f</m:mi> - - <m:mo>â¡</m:mo> - - <m:mfenced> - <m:mi>x</m:mi> - </m:mfenced> - </m:mrow> - - <m:mo>=</m:mo> - - <m:msup> - <m:mi>e</m:mi> - - <m:mi>x</m:mi> - </m:msup> - </m:mrow> - </m:math> - </inlineequation> is being defined by a power series:</para> - - <equation xml:id="sd1EqnDefExp"> - <title>Power series definition of <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mi>f</m:mi> - - <m:mo>â¡</m:mo> - - <m:mfenced> - <m:mi>x</m:mi> - </m:mfenced> - </m:mrow> - - <m:mo>=</m:mo> - - <m:msup> - <m:mi>e</m:mi> - - <m:mi>x</m:mi> - </m:msup> - </m:mrow> - </m:math> - </inlineequation></title> - - <m:math display="block"> - <m:mtable> - <m:mtr> - <m:mtd> - <m:mrow> - <m:msup> - <m:mi>e</m:mi> - - <m:mi>x</m:mi> - </m:msup> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>1</m:mi> - - <m:mo>+</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>1</m:mi> - </m:msup> - - <m:mrow> - <m:mi>1</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>2</m:mi> - </m:msup> - - <m:mrow> - <m:mi>2</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>3</m:mi> - </m:msup> - - <m:mrow> - <m:mi>3</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mi>...</m:mi> - </m:mrow> - </m:mrow> - </m:mtd> - </m:mtr> - - <m:mtr> - <m:mtd> - <m:mrow> - <m:mo>=</m:mo> - - <m:mrow> - <m:munderover> - <m:mo>∑</m:mo> - - <m:mrow> - <m:mi>i</m:mi> - - <m:mo>=</m:mo> - - <m:mi>0</m:mi> - </m:mrow> - - <m:mi mathvariant="normal">∞</m:mi> - </m:munderover> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>i</m:mi> - </m:msup> - - <m:mrow> - <m:mi>i</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - </m:mrow> - </m:mrow> - </m:mtd> - </m:mtr> - </m:mtable> - </m:math> - </equation> - - <para>Implement a class method <methodname>double - exp(double)</methodname> inside a class <package>Math</package> - choosing a package of your choice. The name clash with the Java - standard class <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html">java.lang.Math</link> - is intended: You'll learn how to resolve naming - conflicts.</para> - - <para>Regarding practical calculations we replace the above - infinite series by a limited one. So the number of terms to be - considered will become a parameter which shall be configurable. - Continue the implementation of the following skeleton:</para> - - <figure xml:id="sd1FigExpSketch"> - <title>An implementation sketch for the exponential</title> - - <programlisting language="java">public class Math { - ... - - /** - * @param seriesLimit The last term's index of a power series to be included, - */ - public static void setSeriesLimit(int seriesLimit) {...} - - /** - * Approximating the natural exponential function by a finite - * number of terms from the corresponding power series. - * - * A power series implementation has to be finite since an - * infinite number of terms requires infinite execution time. - * - * The number of terms to be considered can be set by {@link #setSeriesLimit(int)}} - * - * @param x - * @return - */ - public static double exp(double x) {...} -}</programlisting> - </figure> - - <para>Compare your results using <code>seriesLimit=8</code> - terms and the corresponding values from the professional - implementation <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#exp-double">java.lang.Math.exp</link> - by calculating <inlineequation> - <m:math display="inline"> - <m:msup> - <m:mi>e</m:mi> - - <m:mi>1</m:mi> - </m:msup> - </m:math> - </inlineequation>, <inlineequation> - <m:math display="inline"> - <m:msup> - <m:mi>e</m:mi> - - <m:mi>2</m:mi> - </m:msup> - </m:math> - </inlineequation> and <inlineequation> - <m:math display="inline"> - <m:msup> - <m:mi>e</m:mi> - - <m:mi>3</m:mi> - </m:msup> - </m:math> - </inlineequation>. What do you observe? Can you explain this - result?</para> - - <para>Do not forget to provide suitable - <command>Javadoc</command> comments and watch the generated - documentation.</para> - - <para>Hints:</para> - - <itemizedlist> - <listitem> - <para>You should only use basic arithmetic operations like - +, - * and /. Do not use <link - xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#pow-double-double-">Math.pow(double - a, double b)</link> and friends! Their implementations use - power series expansions as well and are designed for a - different purpose like having fractional exponent - values.</para> - </listitem> - - <listitem> - <para>The power series' elements may be obtained in a - recursive fashion like e.g.:</para> - - <informalequation> - <m:math display="block"> - <m:mrow> - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>3</m:mi> - </m:msup> - - <m:mrow> - <m:mi>3</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mfrac> - <m:mi>x</m:mi> - - <m:mn>3</m:mn> - </m:mfrac> - - <m:mo>â¢</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>2</m:mi> - </m:msup> - - <m:mrow> - <m:mi>2</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - </m:mrow> - </m:mrow> - </m:math> - </informalequation> - </listitem> - </itemizedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/math/V1</para> - </annotation> - - <para>Regarding the finite number of terms we implement the last - index to be considered as a class variable <coref - linkend="sd1ListingSeriesLimit"/> having default value 1. We - also provide a corresponding setter method <coref - linkend="sd1ListingSeriesLimitSetter"/> enabling users of our - class to choose an appropriate value:</para> - - <programlisting language="java">public class Math { - - static int <emphasis role="bold">seriesLimit = 1</emphasis>; <co - xml:id="sd1ListingSeriesLimit"/> - - /** - * - * @param seriesLimit The last term's index of a power series to be included, - * {@link }}. - */ - public static void setSeriesLimit(int seriesLimit) { <co - xml:id="sd1ListingSeriesLimitSetter"/> - Math.seriesLimit = seriesLimit; - } ...</programlisting> - - <para>Calculating values by a finite series requires a - loop:</para> - - <programlisting language="java"> public static double exp(double x) { - double currentTerm = 1., // the first (i == 0) term x^0/0! - sum = currentTerm; // initialize to the power series' first term - - for (int i = 1; i <= seriesLimit; i++) { // i = 0 has already been completed. - currentTerm *= x / i; - sum += currentTerm; - } - return sum; - }</programlisting> - - <para>You may also view the <productname>Javadoc</productname> - and the implementation of <link - xlink:href="Ref/api/P/math/V1/de/hdm_stuttgart/de/sd1/math/Math.html#exp-double-">double - Math.exp(double)</link>. We may use the subsequent code snippet - for testing and comparing our implementation:</para> - - <programlisting language="java"> Math.setSeriesLimit(6); - - double byPowerSeries = Math.exp(1.); - System.out.println("e^1=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(1.))); - - byPowerSeries = Math.exp(2.); - System.out.println("e^2=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(2.))); - - byPowerSeries = Math.exp(3.); - System.out.println("e^3=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(3.)));</programlisting> - - <para>In comparison with a professional implementation we have - the following results:</para> - - <programlisting language="unknown">e^1=2.7180555555555554, difference=-2.262729034896438E-4 -e^2=7.355555555555555, difference=-0.033500543375095226 -e^3=19.412499999999998, difference=-0.67303692318767</programlisting> - - <para>Our implementation based on just 6 terms is quite good for - small values of x. Larger values however exhibit growing - differences.</para> - - <para>This is due to the fact that our approximation is in fact - just a polynomial of degree 6.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1MathSin"> - <title>Adding sine</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaSin"> - <title>Implementing <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation>.</title> - - <qandadiv> - <qandaentry> - <question> - <para>We may implement <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation> in a similar fashion to <xref - linkend="sd1EqnDefExp"/>:</para> - - <equation xml:id="sd1EqnDefSin"> - <title>Power series definition of <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mi>f</m:mi> - - <m:mo>â¡</m:mo> - - <m:mfenced> - <m:mi>x</m:mi> - </m:mfenced> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation></title> - - <m:math display="block"> - <m:mtable> - <m:mtr> - <m:mtd> - <m:mrow> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>x</m:mi> - - <m:mo>-</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>3</m:mi> - </m:msup> - - <m:mrow> - <m:mi>3</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>5</m:mi> - </m:msup> - - <m:mrow> - <m:mi>5</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>-</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>7</m:mi> - </m:msup> - - <m:mrow> - <m:mi>7</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mi>...</m:mi> - </m:mrow> - </m:mrow> - </m:mtd> - </m:mtr> - - <m:mtr> - <m:mtd> - <m:mrow> - <m:mo>=</m:mo> - - <m:mrow> - <m:munderover> - <m:mo>∑</m:mo> - - <m:mrow> - <m:mi>i</m:mi> - - <m:mo>=</m:mo> - - <m:mi>0</m:mi> - </m:mrow> - - <m:mi mathvariant="normal">∞</m:mi> - </m:munderover> - - <m:mrow> - <m:msup> - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>-1</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - - <m:mi>i</m:mi> - </m:msup> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mrow> - <m:mi>2</m:mi> - - <m:mo>i</m:mo> - - <m:mo>+</m:mo> - - <m:mi>1</m:mi> - </m:mrow> - </m:msup> - - <m:mrow> - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>2</m:mi> - - <m:mi>i</m:mi> - - <m:mo>+</m:mo> - - <m:mi>1</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - </m:mrow> - </m:mrow> - </m:mrow> - </m:mtd> - </m:mtr> - </m:mtable> - </m:math> - </equation> - - <para>Extend <xref linkend="sd1FigExpSketch"/> by adding a - second method <methodname>double sin(double)</methodname>. Do - not forget to add suitable <command>Javadoc</command> comments - and watch the generated documentation.</para> - - <para>Test your implementation by calculating the known values - <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation>, <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>Ï€</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation> and <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mrow> - <m:mi>4</m:mi> - - <m:mi>Ï€</m:mi> - </m:mrow> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation> using <varname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#PI">java.lang.Math.PI</varname>. - Explain your results</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/math/V2</para> - </annotation> - - <para>Taking seven terms into account we have the following - results:</para> - - <programlisting language="unknown">sin(pi/2)=0.9999999999939768, difference=-6.023181953196399E-12 -sin(pi)=-7.727858895155385E-7, difference=-7.727858895155385E-7 -sin(4 * PI)=-9143.306026012957, <emphasis role="bold">difference=-9143.306026012957</emphasis></programlisting> - - <para>As with the implementation of <inlineequation> - <m:math display="inline"> - <m:msup> - <m:mi>e</m:mi> - - <m:mi>x</m:mi> - </m:msup> - </m:math> - </inlineequation> larger (positive or negative) argument - values show growing differences. On the other hand the - approximation is remarkably precise for smaller arguments. The - reason again is the fact that our power series is just a - polynomial approximation.</para> - - <para>You may also view the <link - xlink:href="Ref/api/P/math/V2/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">Javadoc</link> - and the implementation of <link - xlink:href="Ref/api/P/math/V2/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">double - Math.sin(double)</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sdnSecSinRoundingErrors"> - <title>Strange things happen</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaReorderSin"> - <title>Summing up in a different order.</title> - - <qandadiv> - <qandaentry> - <question> - <para>We may reorder summing up within our power series - defining<inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation>:</para> - - <equation xml:id="sde1MathReorderSumming"> - <title>Reordering of terms with respect to an - implementation.</title> - - <m:math display="block"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>x</m:mi> - - <m:mo>+</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mo>-</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>3</m:mi> - </m:msup> - - <m:mrow> - <m:mi>3</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>5</m:mi> - </m:msup> - - <m:mrow> - <m:mi>5</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>)</m:mo> - </m:mrow> - - <m:mo>+</m:mo> - - <m:mo>(</m:mo> - - <m:mo>-</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>7</m:mi> - </m:msup> - - <m:mrow> - <m:mi>7</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>+</m:mo> - - <m:mfrac> - <m:msup> - <m:mi>x</m:mi> - - <m:mi>9</m:mi> - </m:msup> - - <m:mrow> - <m:mi>9</m:mi> - - <m:mo>!</m:mo> - </m:mrow> - </m:mfrac> - - <m:mo>)</m:mo> - - <m:mo>+</m:mo> - - <m:mo>...</m:mo> - </m:mrow> - </m:math> - </equation> - - <para>From a mathematical point of view there is no difference - to <xref linkend="sd1EqnDefSin"/>. Nevertheless:</para> - - <itemizedlist> - <listitem> - <para>Rename your current sine implementation to - <methodname>double sinOld(double)</methodname>.</para> - </listitem> - - <listitem> - <para>Implement a new method <methodname>double - sin(double)</methodname> using the above summing - reordering.</para> - </listitem> - </itemizedlist> - - <para>Compare the results of <methodname>double - sinOld(double)</methodname> and <methodname>double - sin(double)</methodname> for seven terms. What do you observe? - Do you have an explanation?</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/math/V3</para> - </annotation> - - <para>The following results result from <link - xlink:href="Ref/api/P/math/V3/de/hdm_stuttgart/de/sd1/math/Driver.html">this - test</link>:</para> - - <programlisting language="unknown">Old Implementation:+++++++++++++++++++++++++++++++++++++++ - -sinOld(pi/2)=0.9999999999939768, difference=-6.023181953196399E-12 -sinOld(pi)=-7.727858895155385E-7, difference=-7.727858895155385E-7 -sinOld(4 * PI)=-9143.306026012957, difference=-9143.306026012957 - -New reorder Implementation:+++++++++++++++++++++++++++++++++++++ - -sin(pi/2)=1.0000000000000435, difference=4.3520742565306136E-14 -sin(pi)=2.2419510618081458E-8, difference=2.2419510618081458E-8 -sin(4 * PI)=4518.2187229323445, difference=4518.2187229323445</programlisting> - - <para>Comparing corresponding values our reordered - implementation is more than 100 times more precise. For larger - values we still have a factor of two.</para> - - <para>This is due to limited arithmetic precision: Each double - value can only be approximated by an in memory representation of - eight bytes. Consider the following example:</para> - - <programlisting language="java"> double one = 1., - a = 0.000000000000200, - b = 0.000000000000201; - - System.out.println("(1 + (a - b)) - 1:" + ((one + (a - b)) - one)); - System.out.println("((1 + a) - b) - 1:" + (((one + a) - b) - one));</programlisting> - - <para>This produces the following output:</para> - - <programlisting language="unknown">(1 + (a - b)) - 1:-9.992007221626409E-16 -((1 + a) - b) - 1:-8.881784197001252E-16</programlisting> - - <para>Errors like this one sum up in a power series to - reasonable values especially if higher powers are - involved.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1SinComplete"> - <title>Completing sine implementation</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaSinMapArguments"> - <title>Transforming arguments.</title> - - <qandadiv> - <qandaentry> - <question> - <para>We've reached an implementation offering good results for - <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation> if <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mi>x</m:mi> - - <m:mo>∈</m:mo> - - <m:mrow> - <m:mo>[</m:mo> - - <m:mrow> - <m:mrow> - <m:mo>-</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - - <m:mo>,</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - - <m:mo>]</m:mo> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation>. The following rules may be used to retain - precision for arbitrary argument values:</para> - - <orderedlist> - <listitem> - <informalequation> - <m:math display="block"> - <m:mrow> - <m:msub> - <m:mo>∀</m:mo> - - <m:mrow> - <m:mi>x</m:mi> - - <m:mo>∈</m:mo> - - <m:mi mathvariant="normal">â„</m:mi> - </m:mrow> - </m:msub> - - <m:mo>,</m:mo> - - <m:msub> - <m:mo>∀</m:mo> - - <m:mrow> - <m:mi>n</m:mi> - - <m:mo>∈</m:mo> - - <m:mi mathvariant="normal">ℤ</m:mi> - </m:mrow> - </m:msub> - - <m:mo>:</m:mo> - - <m:mrow> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mrow> - <m:mi>n</m:mi> - - <m:mo>â¢</m:mo> - - <m:mi>2</m:mi> - - <m:mo>â¢</m:mo> - - <m:mi>Ï€</m:mi> - - <m:mo>+</m:mo> - - <m:mi>x</m:mi> - </m:mrow> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:mrow> - </m:mrow> - </m:math> - </informalequation> - - <para>This rule of periodicity allows us to consider only - the interval <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mo>[</m:mo> - - <m:mrow> - <m:mo>-</m:mo> - - <m:mi>Ï€</m:mi> - </m:mrow> - - <m:mo>,</m:mo> - - <m:mi>Ï€</m:mi> - - <m:mo>[</m:mo> - </m:mrow> - </m:math> - </inlineequation> like e.g. <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>20</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mrow> - <m:mi>20</m:mi> - - <m:mo>-</m:mo> - - <m:mrow> - <m:mi>3</m:mi> - - <m:mo>â¢</m:mo> - - <m:mi>2</m:mi> - - <m:mo>â¢</m:mo> - - <m:mi>Ï€</m:mi> - </m:mrow> - </m:mrow> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>≈</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>1.15</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation>.</para> - </listitem> - - <listitem> - <informalequation> - <m:math display="block"> - <m:mrow> - <m:msub> - <m:mo>∀</m:mo> - - <m:mrow> - <m:mi>x</m:mi> - - <m:mo>∈</m:mo> - - <m:mi mathvariant="normal">â„</m:mi> - </m:mrow> - </m:msub> - - <m:mo>:</m:mo> - - <m:mrow> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>x</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mrow> - <m:mi>Ï€</m:mi> - - <m:mo>-</m:mo> - - <m:mi>x</m:mi> - </m:mrow> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:mrow> - </m:mrow> - </m:math> - </informalequation> - - <para>This rule allows us to map values from <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mo>[</m:mo> - - <m:mrow> - <m:mo>-</m:mo> - - <m:mi>Ï€</m:mi> - </m:mrow> - - <m:mo>,</m:mo> - - <m:mi>Ï€</m:mi> - - <m:mo>[</m:mo> - </m:mrow> - </m:math> - </inlineequation> to <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mo>[</m:mo> - - <m:mrow> - <m:mrow> - <m:mo>-</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - - <m:mo>,</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - - <m:mo>[</m:mo> - </m:mrow> - </m:math> - </inlineequation> like e.g. <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(2</m:mo> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>=</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mrow> - <m:mi>Ï€</m:mi> - - <m:mo>-</m:mo> - - <m:mi>2</m:mi> - </m:mrow> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - - <m:mo>≈</m:mo> - - <m:mrow> - <m:mi>sin</m:mi> - - <m:mo>â¡</m:mo> - - <m:mrow> - <m:mo>(</m:mo> - - <m:mi>1.14</m:mi> - - <m:mo>)</m:mo> - </m:mrow> - </m:mrow> - </m:mrow> - </m:math> - </inlineequation>.</para> - </listitem> - </orderedlist> - - <para>These two rules allow us to consider only the interval - <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mo>[</m:mo> - - <m:mrow> - <m:mrow> - <m:mo>-</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - - <m:mo>,</m:mo> - - <m:mfrac> - <m:mi>Ï€</m:mi> - - <m:mi>2</m:mi> - </m:mfrac> - </m:mrow> - - <m:mo>]</m:mo> - </m:mrow> - </m:math> - </inlineequation> with respect to our power series. Extend - your current implementation by mapping arbitrary arguments to - this interval appropriately.</para> - - <para>Hint: The standard function <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-">Math.rint(double)</methodname> - could be helpful: It may turn e.g. 4.47 (<code>double</code>) to - 4 (<code>long</code>).</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/math/V4</para> - </annotation> - - <para>For convenience reasons we start defining PI within our - class:</para> - - <programlisting language="java">public class Math { - - private static final double PI = java.lang.Math.PI; - ...</programlisting> - - <para>No we need two steps mapping our argument:</para> - - <programlisting language="java"> public static double sin(double x) { - // Step 1: Normalize x to [-PI, +PI[ - final long countTimes2PI = (long) java.lang.Math.rint(x / 2 / PI); - if (countTimes2PI != 0) { - x -= 2 * PI * countTimes2PI; - } - - // Step 2: Normalize x to [-PI/2, +PI/2] - // Since sin(x) = sin (PI - x) we continue to normalize - // having x in [-PI/2, +PI/2] - if (PI/2 < x) { - x = PI - x; - } else if (x < -PI/2) { - x = -x - PI; - } - - // Step 3: Continue with business as usual - ...</programlisting> - - <para>You may also view the <productname>Javadoc</productname> - and the implementation of <link - xlink:href="Ref/api/P/math/V4/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">double - Math.sin(double)</link>.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1ArrayI"> - <title>Arrays I (17.11.)</title> - - <section xml:id="sd1ArrayPrepare"> - <title>Preparations</title> - - <para>Chapter 4 <xref linkend="bib_Horton2011"/> excluding - <quote>Mutable Strings</quote>.</para> - </section> - - <section xml:id="sd1ArrayiExercise"> - <title>Exercises</title> - - <section xml:id="sd1IntStore"> - <title>Storing integer values</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaIntStore"> - <title>A container of fixed capacity holding integer values</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implement a class - <classname>BoundedIntegerStore</classname> being able to hold - a fixed number of integer values. Internally these values will - be stored in an array. The design has been chosen to be - extended in later exercises.</para> - - <para>A skeleton project archive is available at:</para> - - <annotation role="make"> - <para role="eclipse">P/Array/integerStoreSkeleton</para> - </annotation> - - <para>The above link contains a skeleton file - <filename>project.zip</filename>. You may import this project - into your <xref linkend="glo_Eclipse"/> workspace by:</para> - - <itemizedlist> - <listitem> - <para>Creating an empty directory e.g. - <quote>myProject</quote>.</para> - </listitem> - - <listitem> - <para>Unzip <filename>project.zip</filename> into - <quote>myProject</quote>.</para> - </listitem> - - <listitem> - <para>Choose File-->Import-->Maven-->Existing - maven projects in <xref linkend="glo_Eclipse"/> and - navigate to the <quote>myProject</quote> folder to import - it.</para> - </listitem> - </itemizedlist> - - <para>This skeleton project contains:</para> - - <itemizedlist> - <listitem> - <para>A class <classname>Driver</classname> which allows - you to execute some output generating tests.</para> - </listitem> - - <listitem> - <para>A <xref linkend="glo_Junit"/> test - <classname>IntStoreTest</classname> which allows you to - test your ongoing implementation of - <classname>BoundedIntegerStore</classname>. This class - contains several <code>// TODO</code> comments indicating - positions to be completed.</para> - </listitem> - - <listitem> - <para>The tests will fail initially. After successful - implementation they should however run - successfully.</para> - </listitem> - </itemizedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Array/integerStore</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1IntStoreUnbounded"> - <title>Let the store grow dynamically</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaIntStoreUnbounded"> - <title>A container of variable capacity holding integer - values</title> - - <qandadiv> - <qandaentry> - <question> - <para>In <xref linkend="sd1QandaIntStore"/> once a store has - been created its capacity is fixed. We'd like to extend our - class to support dynamic growth while adding new values. To - achieve this goal follow the following steps:</para> - - <orderedlist> - <listitem> - <para>Copy the completed project to a new one e.g. named - <quote>UnboundedContainer</quote>. This way you still have - the bounded implementation available.</para> - </listitem> - - <listitem> - <para>Rename your class - <classname>BoundedIntegerStore</classname> to - <classname>IntegerStore</classname> reflecting the - possibility of dynamic growth.</para> - </listitem> - - <listitem> - <para>You have to modify the method <code>void - addValue(int value)</code>: If the array's size gets - exceeded (e.g. adding the fifth value having array size of - just 4) do:</para> - - <itemizedlist> - <listitem> - <para>Create a second array offering twice the current - capacity. This technique is referred to as - <quote>amortized doubling</quote>.</para> - </listitem> - - <listitem> - <para>Copy all existing values from the current array - to the new array</para> - </listitem> - - <listitem> - <para>Assign the new array to <code>int[] - values</code>. You thereby implicitly discard the old - array.</para> - </listitem> - - <listitem> - <para>copy the latest argument to the array as - usual.</para> - </listitem> - </itemizedlist> - - <para>Basically you have to compare the number of already - inserted elements and the current capacity prior to - inserting any new value.</para> - </listitem> - - <listitem> - <para>Add a default constructor providing an initial - default capacity of 4.</para> - </listitem> - </orderedlist> - - <para>Modify and add <xref linkend="glo_Junit"/> tests - accordingly to reflect the new behaviour. Especially test - correct capacity reallocation for larger numbers of values - being added.</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Array/integerStoreUnbounded</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1StoreStatistics"> - <title>Providing statistical data</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaIntStoreStat"> - <title>Adding support to retrieve statistical data.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Extend <xref linkend="sd1QandaIntStoreUnbounded"/> by - providing a method <methodname>double - getAverage()</methodname> to provide statistical data on a - given set of integer values. In addition provide a method - <methodname>void clear()</methodname> enabling a user to - support different sets of values.</para> - - <para>Do not forget to extend your <xref linkend="glo_Junit"/> - tests. You may want to import an <link - xlink:href="Ref/api/P/Array/integerStoreStat/eclipse.zip">eclipse - skeleton project</link> to start from.</para> - - <caution> - <para>When testing for equality of double values you may - find the <xref linkend="glo_Junit"/> method <methodname - xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(double,%20double)">assertEquals()</methodname>to - be marked as <link - xlink:href="http://docs.oracle.com/javase/1.5.0/docs/guide/javadoc/deprecation/deprecation.html">deprecated</link>. - Give a reason why this decision has been taken. This may - guide you to find an appropriate test.</para> - </caution> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Array/integerStoreStat</para> - </annotation> - - <para>Testing for equality of two <code>double</code> - variables is generally a bad idea. Consider the double literal - <code>1.25</code> and the expression <code>5. / 4</code>. A - test <code>assertEquals(1.25, 5. / 4)</code> is likely to fail - due to arithmetic representation problems. Thus you have to - use a distance measurement like e.g. - <code>assertTrue(Math.abs(1.25 - 5. / 4) < 1E-50)</code> - instead.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1ArrayII"> - <title>Arrays II (19.11.)</title> - - <section xml:id="sd1ArrayIprepare"> - <title>Preparations</title> - - <glosslist> - <glossentry> - <glossterm>Java Annotations</glossterm> - - <glossdef> - <para>Unfortunately <xref linkend="bib_Horton2011"/> is somewhat - reluctant regarding Java annotations:</para> - - <remark>A Java source file can contain annotations. An annotation - is not a Java language statement, but a special statement that - changes the way program statements are treated by the compiler or - the libraries. You can define your own annotations but most Java - programmers never need to do so, so I’m not going into the - how.</remark> - - <para>With respect to unit testing using (not defining!) - annotations is very helpful.</para> - - <para>Get a basic understanding of Java annotations by reading - <link - xlink:href="http://docs.oracle.com/javase/tutorial/java/annotations">Lesson: - Annotations</link>. Don't worry if you do not understand the - complete article. The primary intention is about understanding the - <code>@Test</code> annotation in <xref linkend="glo_Junit"/>, see - next topic.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Unit testing using <xref - linkend="glo_Junit"/></glossterm> - - <glossdef> - <para>Read <link - xlink:href="http://www.vogella.com/tutorials/JUnit/article.html">the - introduction</link>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Inheritance</glossterm> - - <glossdef> - <para>Chapter 6 <xref linkend="bib_Horton2011"/> until (including) - <quote>Using the final modifier</quote>. You may skip - <quote>Methods accepting a variable number of - arguments</quote>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><productname>Greenfoot</productname> and - loops</glossterm> - - <glossdef> - <para>Read chapter 5 of <xref - linkend="bib_Koelling2010Ger"/>.</para> - </glossdef> - </glossentry> - </glosslist> - </section> - - <section xml:id="sd1Array2Exercise"> - <title>Exercises</title> - - <section xml:id="sd1PrimeRevisit"> - <title>Prime numbers revisited</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaPrimTest"> - <title>Testing an implementation</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following method aimed to test whether a - given <code>long</code> number is prime or not:</para> - - <programlisting language="java"> /** - * Test, whether a given number is prime. - * @param candidate The number to be assessed - * @return true if candidate is prime, false otherwise - * <dl> - <dt>Precondition:</dt> - <dd>2 &lt;= candidate</dd> - </dl> - */ - public static boolean isPrime(final long candidate) { - for (long i = 2; i * i < candidate; i++) { // Just test up to square - if (0 == candidate % i) { // root of candidate. - return false; - } - } - return true; - } -}</programlisting> - - <orderedlist> - <listitem> - <para>Write a <emphasis role="bold">concise</emphasis> - test which tests the above method for all numbers from [2, - 100]. You need to know all prime numbers from this set in - order to implement a <emphasis - role="bold">complete</emphasis> test for both directions - <quote>is prime</quote> and <quote>is not - prime</quote>.</para> - </listitem> - - <listitem> - <para>In case you find errors correct them.</para> - </listitem> - - <listitem> - <para>Write a method which tests prime number candidates - up to an arbitrary limit (say limit == 10000) and returns - the number of primes within [2, limit]. Measure this - method's execution time. You may want to consult - <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#currentTimeMillis--">System.currentTimeMillis()</methodname> - or <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime--">System.nanoTime()</methodname> - for that purpose.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Prime/V1</para> - </annotation> - - <orderedlist> - <listitem> - <para>We want to test whether our <methodname>boolean - isPrime(final long candidate)</methodname> method - classifies prime numbers as such and whether this message - is able to tell non-primes as well. We achieve this by - defining a boolean array having indexes ranging from 0 to - 100. We then:</para> - - <itemizedlist> - <listitem> - <para>Set all array values to false</para> - </listitem> - - <listitem> - <para>Set all array values to true if their index is a - prime number. This of course requires to know all - prime numbers below 100.</para> - </listitem> - </itemizedlist> - - <para>This array then allows us to test our method for - correctness for values up to 100:</para> - - <programlisting language="java">public class TestPrimes { - - @Test - public void primeTest() { - final int[] primeNumbers = { 2, 3, 5, 7, 11, 13, 17, 19, 23, - 31, 37, 41, 43, 47, 53, 59, 29, - 61, 67, 71, 73, 79, 83, 89, 97}; - - final boolean[] isPrime = new boolean[101]; //Testing 2,3,..,98,99,100 - for (int i = 2; i <= 100; i++) { - isPrime[i] = false; - } - for (final int prime: primeNumbers) { - isPrime[prime] = true; - } - for (int i = 2; i <= 100; i++) { - assertEquals("Index=" + i , isPrime[i], PrimeNumbers.isPrime(i)); - } - }</programlisting> - </listitem> - - <listitem> - <para>Executing this test yields an error at index 49. - This is due to an implementation error. The for- loop had - been defined as:</para> - - <programlisting language="java"> public static boolean isPrime(final long candidate) { - for (long i = 2; i * i < candidate; i++) { - ...</programlisting> - - <para>This is wrong: Having <code>candidate == 49</code> - the last value of i to be considered will be 6. So the - test for the result of <code>49 % 7</code> will never be - executed thus returning true. We actually have to modify - the loop's limit slightly different:</para> - - <programlisting language="java"> public static boolean isPrime(final long candidate) { - for (long i = 2; i * i <emphasis role="bold"><=</emphasis> candidate; i++) { - ...</programlisting> - - <para>This way <code>49 % 7</code> will be evaluated to - zero thus returning <code>false</code> and thereby - categorizing 49 as a non-prime number.</para> - </listitem> - - <listitem> - <para>Our <methodname - xlink:href="Ref/api/P/Prime/V1/de/hdm_stuttgart/mi/sd1/main/PrimeNumbers.html#main-java.lang.String:A-">main()</methodname> - method allows to estimate the prime number computing - performance:</para> - - <programlisting language="none">prime numbers found:664579 -Elapsed time:14997</programlisting> - </listitem> - </orderedlist> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1PrimePerformance"> - <title>Improving performance</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaPrimeFactor"> - <title>Getting better calculating prime numbers</title> - - <qandadiv> - <qandaentry> - <question> - <para>Our current algorithm checking for prime numbers wastes - a lot computing power. Consider testing candidate value 143. - Currently our loop will test:</para> - - <programlisting language="none">143 % 2 == 0 ? No. -143 % 3 == 0 ? No. -143 % 4 == 0 ? No. -143 % 5 == 0 ? No. -143 % 6 == 0 ? No. -143 % 7 == 0 ? No. -143 % 8 == 0 ? No. -143 % 9 == 0 ? No. -143 % 10 == 0 ? No. -143 % 11 == 0 ? Yes ==> 143 is not prime</programlisting> - - <para>Learning from <link - xlink:href="http://en.wikipedia.org/wiki/Prime_factor">prime - factorization</link> it actually suffices just to test all - primes up to the already discussed square root limit:</para> - - <programlisting language="none">143 % 2 == 0 ? No. -143 % 3 == 0 ? No. -143 % 5 == 0 ? No. -143 % 7 == 0 ? No. -143 % 11 == 0 ? Yes ==> 143 is not prime</programlisting> - - <para>The tradeoff is even bigger for higher prime numbers. - Thus if we store all computed prime numbers without gaps they - will save us a lot of operations. You may want to reuse your - unsorted <classname - xlink:href="Ref/api/P/Array/integerStoreUnbounded/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html">IntegerStore</classname> - implementation. Implement the above algorithm and compare the - elapsed execution time.</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Prime/V2</para> - </annotation> - - <para>This time we only need ~18% of the previous time:</para> - - <programlisting language="none">prime numbers found:664578 -Elapsed time:2639</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1ConsoleInput"> - <title>Java console input</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaConsoleInput"> - <title>Reading console input</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following code example computing the sum of - an arbitrary number of integer values:</para> - - <programlisting language="java">import java.util.Scanner; - -public class Driver { - public static void main(String[] args) { - - final Scanner scanner = new Scanner(System.in); - - System.out.print("How many values do you want to summ up? "); - final int numValues = scanner.nextInt(); - - int sum = 0; - for (int i = 0; i < numValues; i++) { - System.out.print("Enter value #" + (i + 1) + " of " + numValues + ": "); - sum += scanner.nextInt(); - } - System.out.println("Sum=" + sum); - scanner.close(); - } -}</programlisting> - - <para>This program:</para> - - <orderedlist> - <listitem> - <para>Asks a user how many integer numbers shall be - processed. A user may enter e.g. 4 indicating his wish to - subsequently enter 4 numbers.</para> - </listitem> - - <listitem> - <para>Actually read e.g. 4 input numbers and calculate - their sum.</para> - </listitem> - </orderedlist> - - <para>The result might look like:</para> - - <programlisting language="none">How many values do you want to summ up? 4 -Enter value #1 of 4: 11 -Enter value #2 of 4: 22 -Enter value #3 of 4: -33 -Enter value #4 of 4: 1 -Sum=1</programlisting> - - <para>Modify this program to output not just the desired sum - but the complete input like in the following - representation:</para> - - <programlisting language="none">How many values do you want to summ up? 4 -Enter value #1 of 4: 1 -Enter value #2 of 4: 2 -Enter value #3 of 4: 3 -Enter value #4 of 4: -5 -<emphasis role="bold">1+2+3-5 = 1</emphasis></programlisting> - - <para>Hints:</para> - - <orderedlist> - <listitem> - <para>Use an integer array to store the user's input - values</para> - </listitem> - - <listitem> - <para>Mind the input values' signs: While positive or zero - values are not being represented with a leading - <quote>+</quote> sign negative values do have a preceding - <quote>-</quote> sign. With respect to the above example - you should avoid output representations like - <quote>1+2+3+-5</quote> for negative input values.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <programlisting language="java">import java.util.Scanner; - -public class Driver { - public static void main(String[] args) { - - final Scanner scanner = new Scanner(System.in); - - System.out.print("How many values do you want to summ up? "); - final int numValues = scanner.nextInt(); - - // Allocate an array to store the desired number of integer values - final int[] inputValues = new int[numValues]; - int sum = 0; - for (int i = 0; i < numValues; i++) { - System.out.print("Enter value #" + (i + 1) + " of " + numValues + ": "); - inputValues[i] = scanner.nextInt(); - sum += inputValues[i]; - } - // Write user input to console output - for (int i = 0; i < numValues - 1; i++) {// Omit the last element - System.out.print(inputValues[i]); - if (0 <= inputValues[i + 1]) { // Add a '+' sign if the subsequent number is positive or zero - System.out.print("+"); - } - } - // Write the last element to console output - System.out.println(inputValues[numValues - 1] + " = " + sum); - - scanner.close(); - } -}</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1Array3"> - <title>Arrays III (24.11.)</title> - - <section xml:id="sd1Array3Exercises"> - <title>Exercises</title> - - <section xml:id="sd1Median"> - <title>The median of a given sample.</title> - - <para>Read the <link - xlink:href="http://en.wikipedia.org/wiki/Median">definition of a given - sample's median</link>.</para> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaMedian"> - <title>Calculating the median</title> - - <qandadiv> - <qandaentry> - <question> - <para>We want to extend exercise <xref - linkend="sd1QandaIntStoreStat"/> by adding a method - <methodname>int getMedian()</methodname>. For this purpose our - current implementation lacks ordering of input values. - Consider the following sample of values:</para> - - <programlisting language="none">2, 7, 0, -3, 4</programlisting> - - <para>Obtaining the median requires ordering these - values:</para> - - <programlisting language="none">-3, 0, 2, 4, 7</programlisting> - - <para>Thus the given sample's median is 2. Solve this exercise - in the following order:</para> - - <orderedlist> - <listitem> - <para>For testing and other purposes it is convenient to - provide an additional method returning the array of values - being added so far:</para> - - <programlisting language="java"> /** - * @return The array of values entered so far - */ - public int[] getValues() { - ... - return ...; - }</programlisting> - - <caution> - <para>Do not just return your internal array <code>int[] - values</code>! Due to the amortized doubling - implementation this will in most cases contain unused - positions on top of added values.</para> - - <para>You may either construct a suitable copy - containing the current elements yourself or get - enlightened by reading the <xref linkend="glo_API"/> - documentation of <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#copyOfRange-int:A-int-int-">copyOfRange(...)</link>.</para> - </caution> - </listitem> - - <listitem> - <para>Provide some tests to assure your sorting - implementation works well. You'll implement the actual - sorting in the next step. Right now testing for correct - sorting will fail (unless a given set of values had - already been added in ascending order). A test might look - like:</para> - - <programlisting language="java">final int[] - unsortedValues = {0, -1, 5, 2, 7, 6}, - sortedValues = {-1, 0, 2, 5, 6, 7}; - -IntegerStore store = new IntegerStore(); - -for (final int i: unsortedValues) { - store.addValue(i); -} - -// Now check your store for correctly sorted order of elements -...</programlisting> - - <para>Do not forget to consider value sets which include - duplicates and write tests accordingly!</para> - - <para>Hint: The <xref linkend="glo_Junit"/> <xref - linkend="glo_framework"/> provides a (convenience) method - <methodname - xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertArrayEquals(int[],%20int[])">assertArrayEquals(...)</methodname>.</para> - </listitem> - - <listitem> - <para>Modify your<methodname - xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-"> - addValue(...)</methodname> method's implementation. Though - there are more elaborate sorting methods available in Java - we'll do it the hard way ourselves in this exercise. - Consider the following example:</para> - - <programlisting language="java">store.addValue(1); -store.addValue(2); -store.addValue(7); -store.addValue(9); -store.addValue(3);</programlisting> - - <para>Prior to inserting a new value our <methodname - xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-">addValue(...)</methodname> - method shall find a suitable position inside the array of - already added values to insert the new value. When adding - the last value 3 in the above example the internal array - already contains the values (1, 2, 7, 9). Traversing this - array shows that the new value of 3 should be inserted - between 2 and 7.</para> - - <para>Thus a general strategy inserting a new value - candidate might be:</para> - - <orderedlist> - <listitem> - <para>Find the first index pointing to an existing - value being larger or equal to the given candidate. In - the above example this index value is 2 pointing to - value 7.</para> - - <para>If there is no such existing value just add the - new value at the array's top end like you did before - when not yet bothering about sorting.</para> - </listitem> - - <listitem> - <para>Shift the <quote>right</quote> part of the array - starting at index 2 in our example one position to the - right thus creating a free (denoted by - <quote>F</quote>) insert position:</para> - - <programlisting language="none">Index values | 0| 1| 2| 3| 4| 5| ... ------------------+--+--+--+--+-----+ ... -values oldArray | 1| 2| 7| 9| | | ------------------+--+--+--+--+-----+ ... -values newArray | 1| 2| F| 7| 9| | ...</programlisting> - - <para>You may now insert your latest value 3 at the - free index position 2 ending up with a well sorted - array (1, 2, 3, 7, 9).</para> - - <para>This example just illustrates a (very simple!) - sorting algorithm.</para> - - <para>Hint: On implementation be very careful with - respect to <quote>off by one</quote> errors you are - likely to encounter. The tests you have written - beforehand will guide you.</para> - </listitem> - </orderedlist> - </listitem> - - <listitem> - <para>Provide a constructor <code>public - IntegerStore(final int[] values)</code> in a meaningful - way with respect to median calculations.</para> - </listitem> - - <listitem> - <para>Add a dummy implementation <methodname>double - getMedian()</methodname>{return 0;} to your class - <classname>IntegerStore</classname> from exercise <xref - linkend="sd1QandaIntStoreStat"/>.</para> - </listitem> - - <listitem> - <para>Provide some tests both for even and uneven sample - sizes. All of these will probably fail till you complete - your implementation.</para> - </listitem> - - <listitem> - <para>Finally complete the desired <code>double - getMedian()</code> method's implementation and actually - test it. There must be at least one element in order to be - able returning a meaningful result:</para> - - <programlisting language="java"> /** - *<dl> - <dt><b>Precondition:</b></dt> - <dd>There must be at least one element.</dd> - </dl> - * - * @return The sample's median. - */ - public double getMedian() { - ... - return ... ; - }</programlisting> - </listitem> - - <listitem> - <para>With respect to <xref linkend="sd1ConsoleInput"/> - write a main method asking the user for an arbitrary - number of values. Then compute both their average and - median like:</para> - - <programlisting language="none">How big is your sample? 5 - -Enter value #1 of 5: 1 -Enter value #2 of 5: -2 -Enter value #3 of 5: 1 -Enter value #4 of 5: 5 -Enter value #5 of 5: 2 - -Your sample's average is: 1.4 -Your sample's median is: 1.0</programlisting> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Array/integerStoreMedianAnswer</para> - </annotation> - - <orderedlist> - <listitem> - <para>The <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#copyOfRange-int:A-int-int-">copyOfRange(...)</link> - method in <methodname - xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#getValues--">getValues()</methodname> - returns that portion of our <code>int[] values</code> - array which had actually been filled with data.</para> - </listitem> - - <listitem> - <para>Provide some tests to assure your sorting - implementation works well. You'll implement the actual - sorting in the next step. Right now testing for correct - sorting will fail (unless a given set of values had - already been added in ascending order). A test might look - like:</para> - - <programlisting language="java">final int[] - unsortedValues = {0, -1, 5, 2, 7, 6}, - sortedValues = {-1, 0, 2, 5, 6, 7}; - -IntegerStore store = new IntegerStore(); - -for (final int i: unsortedValues) { - store.addValue(i); -} - -// Now check your store for correctly sorted order of elements -...</programlisting> - - <para>Do not forget to consider value sets which include - duplicates and write tests accordingly!</para> - - <para>Hint: The <xref linkend="glo_Junit"/> <xref - linkend="glo_framework"/> provides a (convenient) method - <methodname - xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertArrayEquals(int[],%20int[])">assertArrayEquals(...)</methodname>.</para> - </listitem> - - <listitem> - <para>Modify your<methodname - xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-"> - addValue(...)</methodname> method's implementation. Though - there are more elaborate sorting methods available in Java - we'll do it the hard way ourselves in this exercise. - Consider the following example:</para> - - <programlisting language="java">store.addValue(1); -store.addValue(2); -store.addValue(7); -store.addValue(9); -store.addValue(3);</programlisting> - - <para>Prior to inserting a new value our <methodname - xlink:href="Ref/api/P/Array/integerStoreStat/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-">addValue(...)</methodname> - method shall find a suitable position inside the array of - already added values to insert the new value. When adding - the last value 3 in the above example the internal array - already contains the values (1, 2, 7, 9). Traversing this - array shows that the new value of 3 should be inserted - between 2 and 7.</para> - - <para>Thus a general strategy inserting a new value - candidate might be:</para> - - <orderedlist> - <listitem> - <para>Find the first index pointing to an existing - value being larger or equal to the given candidate. In - the above example this index value is 2 pointing to - value 7.</para> - - <para>If there is no such existing value just add the - new value at the array's top as you did without - bothering about sorting.</para> - </listitem> - - <listitem> - <para>Shift the <quote>right</quote> part of the array - starting at index 2 in our example one position to the - right thus creating a free (denoted by - <quote>F</quote>) insert position:</para> - - <programlisting language="none">Index values | 0| 1| 2| 3| 4| 5| ... ------------------+--+--+--+--+-----+ ... -values oldArray | 1| 2| 7| 9| | | ------------------+--+--+--+--+-----+ ... -values newArray | 1| 2| F| 7| 9| | ...</programlisting> - - <para>You may now insert your latest value 3 at the - free index position 2 ending up with a well sorted - array (1, 2, 3, 7, 9).</para> - - <para>This example just illustrates a (very simple!) - sorting algorithm.</para> - - <para>Hint: On implementation be very careful with - respect to <quote>off by one</quote> errors you are - likely to encounter. The tests you have written - beforehand will guide you.</para> - </listitem> - </orderedlist> - </listitem> - - <listitem> - <para>The constructor <methodname - xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#IntegerStore-int:A-">public - IntegerStore(final int[] values)</methodname> internally - uses our <methodname - xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#addValue-int-">addValue(...)</methodname> - method thus adding each array value one by one. Consider - an alternative naive implementation:</para> - - <programlisting language="java"> public IntegerStore(final int[] values) { - this.values = values; - } </programlisting> - - <para>This will fail in most cases since the array - parameter typically contains unsorted values.</para> - - <para>Having this constructor in place also simplifies - writing tests:</para> - - <programlisting language="java">... - @Test - public void testMedian() { - IntegerStore store = new IntegerStore(new int[] {2, 7, 0, -3, 4}); - assertArrayEquals(new int[] {-3, 0, 2, 4, 7}, store.getValues()); - assertTrue(Math.abs(2. - store.getMedian()) < 1.E-10); -...</programlisting> - </listitem> - - <listitem> - <para>-</para> - </listitem> - - <listitem> - <programlisting language="java"> @Test - public void testMedian() { - IntegerStore store = new IntegerStore(new int[] {2, 7, 0, -3, 4}); - assertArrayEquals(new int[] {-3, 0, 2, 4, 7}, store.getValues()); - assertTrue(Math.abs(2. - store.getMedian()) < 1.E-10); - - store.addValue(7); - assertArrayEquals(new int[] {-3, 0, 2, 4, 7, 7}, store.getValues()); - assertTrue(Math.abs(3. - store.getMedian()) < 1.E-10); - - store.addValue(7); - assertArrayEquals(new int[] {-3, 0, 2, 4, 7, 7, 7}, store.getValues()); - assertTrue(Math.abs(4. - store.getMedian()) < 1.E-50); - - store.addValue(6); - assertArrayEquals(new int[] {-3, 0, 2, 4, 6, 7, 7, 7}, store.getValues()); - assertTrue(Math.abs(5. - store.getMedian()) < 1.E-50); - }</programlisting> - </listitem> - - <listitem> - <para><methodname - xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html#getMedian--">double - getMedian()</methodname></para> - </listitem> - - <listitem> - <para><methodname - xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/main/Driver.html#main-java.lang.String:A-">main(...)</methodname></para> - </listitem> - </orderedlist> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="plottingFunctions"> - <title>Plotting functions</title> - - <qandaset defaultlabel="qanda" xml:id="qandaPlottingFunctions"> - <title>A simple character based plotting application</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implement a class to plot e.g. sin(x) in a terminal like - e.g.:</para> - - <informalfigure> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Screen/sinPlot.png"/> - </imageobject> - </mediaobject> - </informalfigure> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/plot</para> - </annotation> - - <para>The above solution contains a variant using Java 8 - Lambda expressions which allow to supply functions as - arguments to the plotting facility. This second solution will - not be covered in the current lecture but you may catch a - glimpse of upcoming topics in "Softwareentwicklung 2".</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1String1"> - <title>String instances (1.12.)</title> - - <section xml:id="sd1PrepStrings"> - <title>Preparations</title> - - <itemizedlist> - <listitem> - <para>Read the section on <link - xlink:href="http://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html">command - line arguments</link> and execute the given examples.</para> - </listitem> - - <listitem> - <para>Read the <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String - <xref linkend="glo_API"/></link>. Try to understand methods - concerning:</para> - - <itemizedlist> - <listitem> - <para>Comparing strings lexicographically or testing for - equality? How does this relate to the <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> - method you read about in chapter 6 of <xref - linkend="bib_Horton2011"/>.</para> - </listitem> - - <listitem> - <para>Searching for sub strings in a given string i.e. testing, - whether e.g. <quote>keeper</quote> is part of - <quote>goalkeeper</quote>.</para> - </listitem> - </itemizedlist> - </listitem> - </itemizedlist> - </section> - - <section xml:id="sd1StringExercise"> - <title>Exercises</title> - - <section xml:id="greenfootConfigureEclipse"> - <title>Developing <xref linkend="glo_Greenfoot"/> applications using - the <xref linkend="glo_Eclipse"/> <xref linkend="glo_IDE"/>.</title> - - <para>Steps being described in this section are optional and only - required if you like to develop <xref linkend="glo_Greenfoot"/> - applications using <xref linkend="glo_Eclipse"/>.</para> - - <para>When using the <xref linkend="glo_Greenfoot"/> <xref - linkend="glo_IDE"/> your <xref linkend="glo_Java"/> code uses services - from the underlying <productname>Greenfoot</productname> <xref - linkend="glo_framework"/> which in turn uses another framework called - <xref linkend="glo_BlueJ"/>. If you want to use <xref - linkend="glo_Eclipse"/> for <xref linkend="glo_Greenfoot"/> - development based on <xref linkend="glo_Maven"/> you have to define - <xref linkend="glo_Greenfoot"/> within the project's <xref - linkend="glo_pom.xml"/> file's dependency section. You must provide - both dependencies (at least locally on your workstation):</para> - - <glosslist> - <glossentry> - <glossterm>Locally install <xref linkend="glo_BlueJ"/> - dependencies</glossterm> - - <glossdef> - <para>Download <uri - xlink:href="http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/bluej/eclipse.zip">http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/bluej/eclipse.zip</uri> - and unzip it to a subfolder <filename>Bluej</filename>. Import - this Folder as a Maven project into <xref - linkend="glo_Eclipse"/> and right click on pom.xml choosing - <guisubmenu>mvn install</guisubmenu>. This will compile the - sources and install <xref linkend="glo_BlueJ"/> into your local - <xref linkend="glo_Maven"/> repository below - <filename>yourHomeDirPath/.m2</filename>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Locally install <xref linkend="glo_Greenfoot"/> - dependencies</glossterm> - - <glossdef> - <para>Repeat the previous step for <uri - xlink:href="http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/greenfoot/eclipse.zip">http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.swd1/Ref/api/P/Maven/greenfoot/eclipse.zip</uri> - using a subfolder <filename>Greenfoot</filename>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Adding <xref linkend="glo_Maven"/> dependency to your - <productname>Greenfoot</productname> game project</glossterm> - - <glossdef> - <para>You may now create your own <xref - linkend="glo_Greenfoot"/> Maven <xref linkend="glo_Eclipse"/> - project by adding the newly created <xref - linkend="glo_Greenfoot"/> Maven artifact as a project - dependency:</para> - - <programlisting language="none">... - <dependencies> - ... - <emphasis role="bold"><dependency> - <groupId>de.hdm-stuttgart.mi</groupId> - <artifactId>greenfoot</artifactId> - <version>2.3.0</version> - </dependency></emphasis> - </dependencies>...</programlisting> - - <para>Due to <xref linkend="glo_Greenfoot"/>'s simplicity and in - contrast to common <xref linkend="glo_Java"/> <quote>best - practice</quote> you'll off course have to create all classes - inside the <quote>default</quote> package ignoring or - suppressing related compiler warnings.</para> - </glossdef> - </glossentry> - </glosslist> - - <caution> - <para>Caveat: Windows and Mac users may require further - configuration described below.</para> - </caution> - - <para>On Windows you'll have to instruct <xref linkend="glo_Eclipse"/> - to use a <xref linkend="glo_JDK"/> and not just a <xref - linkend="glo_JRE"/> (being the default). Whenever you install a <xref - linkend="glo_JDK"/> (like <link - xlink:href="http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html">JDK - 1.8.0</link>) on Windows a so called private <xref linkend="glo_JRE"/> - is being installed as well by default as well:</para> - - <informalfigure> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Screen/EclipseConfig/windowsCmdJdkJre.png"/> - </imageobject> - </mediaobject> - </informalfigure> - - <para>The problem: A library tools.jar being required by <xref - linkend="glo_BlueJ"/> is part of a <xref linkend="glo_JDK"/> but not - of a <xref linkend="glo_JRE"/>. Different resolutions are being - subsequently listed in descending order of ugliness (authors - opinion):</para> - - <glosslist> - <glossentry> - <glossterm>Explicitly defining the <xref linkend="glo_JDK"/> in - <xref linkend="glo_Eclipse"/></glossterm> - - <glossdef> - <para>Modify <filename>eclipse.ini</filename> in your <xref - linkend="glo_Eclipse"/> root installation directory pointing to - a <xref linkend="glo_JDK"/> in favour of the <xref - linkend="glo_JRE"/> default. The highlighted lines must appear - <emphasis role="bold">before</emphasis> any - <option>-vmargs</option> options.</para> - - <programlisting language="none">... --showsplash -org.eclipse.platform ---launcher.XXMaxPermSize -256m ---launcher.defaultAction -openFile ---launcher.appendVmargs -<emphasis role="bold">-vm -C:\Program Files\Java\jdk1.8.0_25\bin/javaw -</emphasis>-vmargs --Dosgi.requiredJavaVersion=1.6 --Xms40m --Xmx2048m</programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Fix <envar>JAVA_HOME</envar></glossterm> - - <glossdef> - <para>Define the environment variable <envar>JAVA_HOME</envar> - on operating system level pointing to your <xref - linkend="glo_JDK"/> of choice's root directory:</para> - - <programlisting language="none"><emphasis role="bold">set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_25</emphasis></programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Setting a static path in <xref - linkend="glo_pom.xml"/></glossterm> - - <glossdef> - <para>Explicitly set the required dependencies fully qualified - pathname in each <xref linkend="glo_pom.xml"/>:</para> - - <programlisting language="none"><dependency> - <groupId>com.sun</groupId> - <artifactId>tools</artifactId> - <version>1.8.0</version> - <scope>system</scope> - <emphasis role="bold"><systemPath>C:\Program Files\Java\jdk1.8.0_25\lib\tools.jar</systemPath></emphasis> - </dependency></programlisting> - </glossdef> - </glossentry> - </glosslist> - - <para>Needless to mention these path settings have to be revised - accordingly whenever your <xref linkend="glo_JDK"/> receives an update - to e.g. <xref linkend="glo_JDK"/> 1.8.0_31. The author humbly welcomes - any advice towards a better solution.</para> - </section> - - <section xml:id="sd1LifeWorld"> - <title>Creating the Game of life's world</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaLifeWorld"> - <title>Creating the <quote - xlink:href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Game - of Life</quote>'s world</title> - - <glosslist> - <glossentry> - <glossterm>Exporting to your separate - <productname>Greenfoot</productname> environment</glossterm> - - <glossdef> - <para>As soon as you actually want to run your game copy all - Java files from your <xref linkend="glo_Eclipse"/> project to - your <productname>Greenfoot</productname> environment. A - graphical file manager might assist you or you may simply use - shell commands (You'll need to do this next term in - <quote>Operating Systems</quote> anyway) like e.g.:</para> - - <programlisting language="none">goik@goiki:~$ cd ~/workspace/life/src/main/java -goik@goiki:~/workspace/life/src/main/java$ ls -Cell.java CellState.java LifeWorld.java -goik@goiki:~/workspace/life/src/main/java$ cp *.java ~/my-scenarios/Life</programlisting> - - <para>Then hit <quote>compile</quote> inside - <productname>Greenfoot</productname> to refresh and start your - game</para> - </glossdef> - </glossentry> - </glosslist> - - <qandadiv> - <qandaentry> - <question> - <para>Create a <productname>Greenfoot</productname> world - class and a dummy representation for cells representing <link - xlink:href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Conway's - Game of Life</link>:</para> - - <screenshot> - <info> - <title>World and Actor classes representing Conway's Game - of Life</title> - </info> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/gameOfLifeWorld.png"/> - </imageobject> - </mediaobject> - </screenshot> - - <para>The above example shows a grid of 50 * 50 cells each - having a size of 10 pixel. In preparation for subsequent - exercises each cell shall have two possible states namely - <quote>dead</quote> or <quote>alive</quote>. In this exercise - we only deal with the game's initialization. So transitions - <quote>dead</quote> --> <quote>alive</quote> or vice versa - will not occur. But your implementation should already be - prepared to allow such transitions.</para> - - <para>You may follow these steps:</para> - - <orderedlist> - <listitem> - <para>Create a new <productname>Greenfoot</productname> - world class <classname>LifeWorld</classname> of - configurable width and height and an actor class - <classname>Cell</classname>. Choose an arbitrary image - representing cells. The image is actually irrelevant since - our application will replace it by filled white or black - rectangles anyway representing cells being dead or alive. - So the blue dot in the above screenshot left of - <quote>Cell</quote> in the <quote>Actor classes</quote> - pane will never get visualized.</para> - </listitem> - - <listitem> - <para>Create your world's horizontal and vertical red - lines. Hints:</para> - - <itemizedlist> - <listitem> - <para>The method <methodname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/World.html#getBackground()">getBackground()</methodname> - allows you to access your world's background - representation as an instance of class <classname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html">GreenfootImage</classname>.</para> - </listitem> - - <listitem> - <para>You may add lines to <classname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html">GreenfootImage</classname> - instances by calling <methodname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html#drawLine(int,%20int,%20int,%20int)">drawLine(...)</methodname> - after choosing a desired color by calling i.e. - <methodname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html#setColor(java.awt.Color)">setColor(Color.red)</methodname>. - You may experiment a little bit by drawing some - example lines before eventually creating horizontal - and vertical grid lines using loops.</para> - </listitem> - </itemizedlist> - </listitem> - - <listitem> - <para>Use the constructor <classname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/GreenfootImage.html#GreenfootImage(int,%20int)">GreenfootImage(int - width, int height)</classname> to create colored - rectangles representing cells:</para> - - <glosslist> - <glossentry> - <glossterm>black</glossterm> - - <glossdef> - <para>Cell is alive</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>white (=invisible)</glossterm> - - <glossdef> - <para>Cell is dead</para> - </glossdef> - </glossentry> - </glosslist> - - <para>The <methodname - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/Actor.html#setImage(greenfoot.GreenfootImage)">setImage()</methodname> - method allows defining these images to represent your - cells thereby replacing the original - <productname>Greenfoot</productname> definition from class - <classname>Cell</classname> creation time.</para> - - <para>Watch out for appropriate spacing. Your cells should - not interfere with the grid's red lines. They have to be a - little smaller to fit in the <quote>empty</quote> - space.</para> - - <para>When creating cells initialize a configurable - percentage in state alive. In the above screenshot 25% of - all cells are alive when starting the game. You may use a - boolean variable to indicate a cell's two possible states - but a dedicated <classname>Enum CellState</classname> will - improve your code's readability.</para> - </listitem> - - <listitem> - <para>Your world will consist of a two dimensional grid - containing width * height cells. In the above example we - have 50 * 50 == 2500 cells. Arrange your cells in a one - dimensional array of size width * height. Then implement - the following method linking these cells' index values to - x- and y-coordinates:</para> - - <programlisting language="java"> <emphasis role="bold">/** - * Turn (x|y) coordinates into linear cell array index - * values ranging from 0 to (width * height - 1). - * - * Consider a simplified example of an array having width = 4 and - * height = 3: - * - * {(0|0) (1|0) (2|0) (3|0)} --> Linear array Index values {0, 1, 2, 3} - * {(0|1) (1|1) (2|1) (4|1)} --> Linear array Index values {4, 5, 6, 7} - * {(0|2) (1|2) (2|2) (4|2)} --> Linear array Index values {8, 9, 10, 11} - * - * @param x horizontal position in cell coordinates - * @param y vertical position in cell coordinates - * @return The linear array index. - */</emphasis> - private int getCellIndex(int x, int y) { - ... - return ...; - }</programlisting> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/life/V1</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1IdentEqual"> - <title>Object identity and equality (3.12.)</title> - - <section xml:id="sec_PrepareOidEquality"> - <title>Preparations</title> - - <para>Read all sections of chapter 6 in <xref linkend="bib_Horton2011"/> - till and including <quote>THE UNIVERSAL SUPERCLASS</quote>.</para> - </section> - - <section xml:id="sd1String2Exercises"> - <title>Exercises</title> - - <section xml:id="pitfallsUsingOperatorEquals"> - <title>Pitfalls using operator <quote>==</quote></title> - - <qandaset defaultlabel="qanda" xml:id="qandaStringOperatorEquals"> - <title>String instances and equality</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following fragment:</para> - - <programlisting language="java">public static void main(String[] args) { - - final String a1 = "TestA", a2 = "TestA"; - System.out.println(" a1 == a2: " + (a1 == a2)); - - final String b1 = new String("TestB"), b2 = new String("TestB"); - System.out.println("b1 == b2: " + (b1 == b2)); -}</programlisting> - - <para>Execute this code and explain the resulting - output.</para> - - <para>Hints: Read the documentation of <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#identityHashCode-java.lang.Object-">System.identityHashCode(Object - o)</link> and <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">Object.hashCode()</link>.</para> - </question> - - <answer> - <para>Execution yields:</para> - - <programlisting language="none">a1 == a2: true <co - linkends="answerCoStringOperatorEquality-1" - xml:id="answerCoStringOperatorEquality-1-co"/> -b1 == b2: false <co linkends="answerCoStringOperatorEquality-2" - xml:id="answerCoStringOperatorEquality-2-co"/></programlisting> - - <calloutlist> - <callout arearefs="answerCoStringOperatorEquality-1-co" - xml:id="answerCoStringOperatorEquality-1"> - <para>This effectively compares two string literals - <code>"TestA"</code> and <code>"TestA"</code>. The <xref - linkend="glo_JDK"/> compiler implementation allocates only - one instance of class String for all string literals - having identical content. So all string literals "TestA" - (even if existing in different classes or packages) - represent the same object. Thus the two distinct variables - <code>a1</code> and <code>a2</code> are being assigned an - identical reference pointing to this unique instance. - Comparing identical references by the operator == always - yields true. You might as well write:</para> - - <programlisting language="java">System.out.println(<emphasis - role="bold">"TestA".equals("TestA")</emphasis>);</programlisting> - - <para>The method <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#identityHashCode-java.lang.Object-">System.identityHashCode(Object - o)</link> returns <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">Object.hashCode()</link> - rather then <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode--">String.hashCode()</link>. - This hash code from <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html">java.lang.Object</link> - has a one to one correspondence to an object's reference - and thus helps to understand the underlying object - references of our current example:</para> - - <programlisting language="java">System.out.println("Hashcode a1 == " + System.identityHashCode(a1) + - ", Hashcode a2 == " + System.identityHashCode(a2));</programlisting> - - <para>This yields identical values showing that - <code>a1</code> and <code>a2</code> point to the same - instance:</para> - - <programlisting language="none">Hashcode a1 == 366712642, Hashcode a2 == 366712642</programlisting> - </callout> - - <callout arearefs="answerCoStringOperatorEquality-2-co" - xml:id="answerCoStringOperatorEquality-2"> - <para>Every call to a constructor will create a new object - regardless of internal state. Thus <code>b1</code> and - <code>b2</code> will hold two distinct references pointing - to different String instances albeit these two instances - contain identical values. Following the above reasoning we - may execute:</para> - - <programlisting language="java">System.out.println("Hashcode b1 == " + System.identityHashCode(b1) + - ", Hashcode b2 == " + System.identityHashCode(b2));</programlisting> - - <para>This yields values corresponding to two different - object references:</para> - - <programlisting language="none">Hashcode b1 == 1829164700, Hashcode b2 == 2018699554</programlisting> - - <para>Comparing these two values for equality via the - <quote>==</quote> operator thus returns the boolean value - <code>false</code>.</para> - </callout> - </calloutlist> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1GomeOfLifeLogic"> - <title>Implementing <quote>Game of Life</quote> logic</title> - - <para>We complete our previous exercise by implementing the rules - governing cells being born, dying or just continue existing.</para> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaGameOfLifeLogic"> - <title>Implementing <quote>Game of Life</quote> logic.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implementing cells being born and dying requires several - steps. The following sketch outlines one of different ways to - achieve this goal.</para> - - <orderedlist> - <listitem> - <para>Each cell is in exactly one of two distinct states - <quote>dead</quote> or <quote>alive</quote>. Though it is - possible to use a boolean for this purpose a dedicated - <classname>enum CellState {...}</classname> definition is - in order here to improve your code's readability.</para> - </listitem> - - <listitem> - <para>Read the documentation of the two different - <methodname>act()</methodname> methods being defined in - <link - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/World.html#act()">World</link> - and <link - xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/Actor.html#act()">Actor</link>. - You'll learn about the temporal order in which these are - being invoked by the <productname>Greenfoot</productname> - <xref linkend="glo_framework"/>.</para> - </listitem> - - <listitem> - <para>The rules governing life or death in the next step - have to be applied to each individual cell. Consider two - isolated neighboring cells A and B both being in live - state: Both cells do have exactly one living neighbor. - When A dies in the next step B does no longer have any - living neighbor.</para> - - <para>But it would be wrong to calculate B's following - state based on this assumption. Thus we need to keep a - record of A's current state as long as the computation for - <emphasis role="bold">all</emphasis> cells has been - finished. This effectively requires keeping track of each - cell's <quote>current</quote> and <quote>next</quote> - state. The two different act() methods mentioned earlier - provide a clue setting these two states - accordingly.</para> - </listitem> - - <listitem> - <para>Each cell needs to have a reference to its neighbors - for calculation its subsequent state. Since our world is - limited (in contrast to Conway's assumption) we have to - deal with cells existing at our world's edges having fewer - neighbors as well.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/life/V3</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1Deploy"> - <title>Application deployment I (8.12.)</title> - - <section xml:id="sd1DeployPrepare"> - <title>Preparations</title> - - <para>Read <link - xlink:href="http://www.cs.swarthmore.edu/~newhall/unixhelp/debuggingtips_Java.html">http://www.cs.swarthmore.edu/~newhall/unixhelp/debuggingtips_Java.html</link> - up to including the <quote>The <code>CLASSPATH</code> environment - variable and JAR files</quote> section.</para> - </section> - - <section xml:id="sda1DeployExercise"> - <title>Exercises</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaArrayVarious"> - <title>Various integer array algorithms</title> - - <qandadiv> - <qandaentry> - <question> - <para>The Maven Java project archive <link - xlink:href="Ref/api/P/Array/arraycalcExercise/eclipse.zip">eclipse.zip</link> - contains a series of yet unimplemented methods and corresponding - tests. The following hints may help you completing the - implementation</para> - - <glosslist> - <glossentry> - <glossterm><link - xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#swap(int[],%20int[])">swap</link></glossterm> - - <glossdef> - <para>This effectively requires extending the concept of - swapping just two integer values within a block</para> - - <programlisting language="java"> int a = 3, b = 5; - - // Other code ... - - {// Swap values of a and b - final int tmp = a; - a = b; - b = tmp; - } </programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><link - xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#isPalindrome(java.lang.String)">isPalindrome</link></glossterm> - - <glossdef> - <para>Consider a two step implementation:</para> - - <orderedlist> - <listitem> - <para>Normalize a given palindrome candidate by - transforming to lower case and erasing - non-letters:</para> - - <para><code>Hey, Roy! Am I mayor? Yeh!</code> --> - <code>heyroyamimayoryeh</code></para> - - <para>You may search the <xref linkend="glo_API"/> of - class <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Character.html">Character</classname> - assisting you to distinguish letters from - non-letters.</para> - </listitem> - - <listitem> - <para>Check the remaining string for being a - palindrome.</para> - </listitem> - </orderedlist> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><link - xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#containsSameElements(int[],%20int[])">containsSameElements</link></glossterm> - - <glossdef> - <para>You may copy <code>int[] b</code> array to a - <quote>shadow</quote> array and then subsequently erase - all elements of <code>int[] a</code> from this copy. The - method <link - xlink:href="Ref/api/P/Array/arraycalcExercise/de/hdm_stuttgart/mi/sd1/store/Arraymethods.html#findIndex(int[],%20int)">findIndex</link> - is quite helpful.</para> - - <para>Consider for example <code>int[] bCopy = {1, 3, 4, - 3, 7}</code> containing 5 elements. Suppose our array - <code>a</code> contains the value 3 which exists at index - position 1 in <code>bCopy</code>. We may override the - value index position 1 by the last array value 7 and - thereby keeping track of reducing the number of array - elements to 4 like {1, 7, 4, 3}.</para> - - <para>Off course the array <code>bCopy</code> cannot - shrink. But we may introduce an integer variable to - account for the effective number of array elements still - to be considered. If and only if all elements from - <code>a</code> are subsequently found within - <code>bCopy</code> the two arrays <code>a</code> and - <code>b</code> are equal.</para> - </glossdef> - </glossentry> - </glosslist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Array/arraycalcSolution</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1AppDeploy2"> - <title>Application deployment II (10.12.)</title> - - <section xml:id="sd1AppDeploy2Exercise"> - <title>Exercises</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaMedianCmdline"> - <title>A command line version computing a sample's average and - median</title> - - <qandadiv> - <qandaentry> - <question> - <para>This exercise extends <xref linkend="sd1StoreStatistics"/> - by adding a command line interface. Consider the following - console execution:</para> - - <programlisting language="none">goik >java -jar statistics-1.0.jar 2 6 7 -Your sample's average is: 5.0 -Your sample's median is: 6.0</programlisting> - - <para>The above example executes our Java program in a shell and - supplies three command line parameters 2, 6 and 7. The program - then executes and creates the desired statistical data.</para> - - <para>The subsequent remarks may assist you creating an - implementation:</para> - - <orderedlist> - <listitem xml:id="sd1OlMedianCmdLineStep1"> - <para>Using command line values means entering strings - rather then e.g. integer values: In the current example the - Java runtime will pass an array of strings <code>{"2", "6", - "7"}</code> on behalf of the user's input <quote><code>2 6 - 7</code></quote> to your <code>main(String [] args)</code> - method. These strings must be converted to integer values. - This may be achieved by means of <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#parseInt-java.lang.String-">parseInt(String)</methodname>.</para> - - <para>Depending on inconsistent user input like - <quote><code>three</code></quote> instead of - <quote><code>3</code></quote> you may decide to terminate - your application thereby providing a meaningful error - message:</para> - - <programlisting language="none">goik >java -jar statistics-1.0.jar 1 2 three -Input string 'three' does not represent an integer value</programlisting> - </listitem> - - <listitem> - <para>If the user does not provide any input at all our - program shall terminate as well:</para> - - <programlisting language="none">goik >java -jar statistics-1.0.jar -No values provided</programlisting> - </listitem> - - <listitem> - <para>Provide an <classname>public enum - ErrorState</classname> definition representing all three - possible error states:</para> - - <glosslist> - <glossentry> - <glossterm><code>OK</code>:</glossterm> - - <glossdef> - <para>No error, all user input strings represent - integer values.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><code>NO_VALUE</code>:</glossterm> - - <glossdef> - <para>Error: No user input at all.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><code>NO_INTEGER</code>:</glossterm> - - <glossdef> - <para>Error: At least one input value does not - represent an integer value.</para> - </glossdef> - </glossentry> - </glosslist> - </listitem> - - <listitem> - <para>Implement a class - <classname>InputValidator</classname> to validate user input - and thereby converting string values to an integer array of - equal size:</para> - - <programlisting language="java">/** - * Validate sample input strings and convert - * them to integer values. - */ -public class InputValidator { - - /** - * Integer values being calculated upon - * constructor call. - */ - public final int[] values; - - /** - * Transform a series of strings into integer values. In case - * of invalid input, a corresponding error messsage will be written - * to System.err and the current application will terminate by calling - * {@link System#exit(int)}. Example: The array ["-1", "20", "three"] - * contains two valid elements and the invalid element "three" which - * cannot be converted to an integer value by virtue of - * {@link Integer#parseInt(String)}. - * - * @param userInput A set of strings possibly representing integer values. - */ - public InputValidator(final String[] userInput) {...} -}</programlisting> - - <para>You may then create an instance by supplying your - <code>main(String[] args)</code> command line values:</para> - - <programlisting language="java"> public static void main(String[] args) { - - final InputValidator userInput = new InputValidator(args); -...</programlisting> - - <para>Choose your implementation with testing in - mind.</para> - </listitem> - - <listitem> - <para>Write at least one test case for all three possible - error categories and check for correct behaviour of your - <classname>InputValidator</classname> class.</para> - </listitem> - - <listitem> - <para>Use your class <classname - xlink:href="Ref/api/P/Array/integerStoreMedianAnswer/de/hdm_stuttgart/mi/sd1/store/IntegerStore.html">IntegerStore</classname> - from exercise <xref linkend="sd1StoreStatistics"/> to - compute the desired output.</para> - </listitem> - - <listitem> - <para>Simulating command line arguments in <xref - linkend="glo_Eclipse"/> requires a run time configuration. - Click <guimenu>Run</guimenu> <guimenuitem>Run - Configurations...</guimenuitem>. Choose <quote>Java - Applications</quote> and "new launch configuration" from the - panel's left side, choose your project and main class (if - not already selected).</para> - - <screenshot> - <info> - <title>Defining an Eclipse runtime configuration</title> - </info> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/runconfigSelectClass.png"/> - </imageobject> - </mediaobject> - </screenshot> - - <para>Select the <guimenu>Arguments</guimenu> tab. Enter - your desired command line values, hit - <guibutton>Apply</guibutton> and subsequently - <guibutton>Run</guibutton> to launch your - application.</para> - - <screenshot> - <info> - <title>Defining an Eclipse runtime configuration</title> - </info> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/runconfigDefineArgs.png"/> - </imageobject> - </mediaobject> - </screenshot> - </listitem> - - <listitem> - <para>Maven projects allow for creation of executable jar - archives. This leverages the process being described in - <link - xlink:href="http://www.skylit.com/javamethods/faqs/createjar.html">Creating - an Executable jar File</link>. It avoids messing with - manifest files and zipping up archives manually.</para> - - <para>Among several configuration possibilities you may use - the <link - xlink:href="http://maven.apache.org/plugins/maven-jar-plugin">Maven - JAR Plugin</link> and its <option - xlink:href="http://maven.apache.org/plugins/maven-jar-plugin/usage.html#How_to_build_a_JAR_file">package</option> - goal. You have to add this plugin to the <tag - class="starttag">plugins</tag> section of your - <filename>pom.xml</filename> file. The plugin in turn - requires defining the fully qualified name of your entry - class <coref linkend="sd1CaPomFqnMainEntryClass"/> - containing the desired <methodname>main(String[] - args)</methodname> method:</para> - - <programlisting language="xml">... -<properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <javadocDestdir>~/tmp</javadocDestdir> -</properties> - -<build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <version>2.4</version> - <configuration> - <archive> - <manifest> - <addClasspath>true</addClasspath> -<emphasis role="bold"> <mainClass>de.hdm_stuttgart.mi.sd1.statistics.main.Statistics</mainClass></emphasis> <co - xml:id="sd1CaPomFqnMainEntryClass"/> - </manifest> - </archive> - </configuration> - </plugin> - </plugins> -</build> -...</programlisting> - - <para>Creating the actual jar archive may be triggered by - either of:</para> - - <glosslist> - <glossentry> - <glossterm>From the command line:</glossterm> - - <glossdef> - <para>Change to your project root containing your - <filename>pom.xml</filename> file and execute - <command>mvn</command> - <option>package</option>.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>From inside <xref - linkend="glo_Eclipse"/>:</glossterm> - - <glossdef> - <para>Create a maven run time configuration (see - above) containing your <option>package</option> - goal:</para> - - <screenshot> - <info> - <title>Creating a Maven runtime configuration - corresponding to the <option>package</option> - goal</title> - </info> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/runconfigMavenGoalPackage.png"/> - </imageobject> - </mediaobject> - </screenshot> - </glossdef> - </glossentry> - </glosslist> - - <para>After creating the jar archive you may now run your - program in a shell as being described in <xref - linkend="sd1OlMedianCmdLineStep1"/> of this section.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Array/medianCmdLine</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1ReadCharStreams"> - <title>Reading character streams (15.12.)</title> - - <section xml:id="sd1ReadCharStreamsPrepare"> - <title>Preparations</title> - - <itemizedlist> - <listitem> - <para>Section <quote>Interfaces</quote> of chapter 6 in <xref - linkend="bib_Horton2011"/>.</para> - </listitem> - - <listitem> - <para>Chapter 8 of <xref linkend="bib_Horton2011"/> excluding the - last chapter <quote>The Standard Streams</quote>.</para> - </listitem> - - <listitem> - <para><link xlink:href="Ref/Svg/exception.svg">Exception - basics</link>.</para> - </listitem> - </itemizedlist> - </section> - - <section xml:id="sd1GnuWc"> - <title>Exercises</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaLinenumbers"> - <title>Adding line numbers to text files</title> - - <qandadiv> - <qandaentry> - <question> - <para>We want to add line numbers to arbitrary text files not - necessarily being related to programming. Consider the following - HTML example input:</para> - - <programlisting language="java"><html> - <head> - <title>A simple HTML example</title> - </head> - <body> - <p>Some text ... </p> - </body> -</html></programlisting> - - <para>Your application shall add line numbers:</para> - - <programlisting language="none">1: <html> -2: <head> -3: <title>A simple HTML example</title> -4: </head> -5: <body> -6: <p>Some text ... </p> -7: </body> -8: </html></programlisting> - - <para>Hints:</para> - - <orderedlist> - <listitem> - <para>Given the name of an existing file you may create an - instance of <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname>:</para> - - <programlisting language="java">final FileReader fileReader = new FileReader(inputFileName); -final BufferedReader inputBufferedReader = new BufferedReader(fileReader);</programlisting> - </listitem> - - <listitem> - <para>You will have to deal with possible <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/FileNotFoundException.html">FileNotFoundException</classname> - problems providing meaningful error messages.</para> - </listitem> - - <listitem> - <para>The <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname> - class provides a method <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#readLine--">readLine()</methodname> - allowing to access a given file's content line by - line.</para> - - <caution> - <para>Even if a file exists you have my encounter - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/IOException.html">IOException</classname> - problems being related to <acronym>i.e.</acronym> missing - permissions.</para> - </caution> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Wc/readFile</para> - </annotation> - - <para>This solutions reacts both to inexistent files and general - IO problems:</para> - - <programlisting language="none">File not found: Testdata/input.java</programlisting> - - <para>Two test cases deal both with readable and non-existing - files: and expected exceptions:</para> - - <programlisting language="java"> @Test - public void testReadFileOk() throws FileNotFoundException, IOException { - ReadFile.openStream("Testdata/input.txt"); // Existing file - } - @Test (expected=FileNotFoundException.class) // We expect this exception to be thrown - public void testReadMissingFile() throws FileNotFoundException, IOException { - ReadFile.openStream("Testdata/input.java"); // Does not exist - }</programlisting> - - <para>Notice the second test which will only succeed if a - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/FileNotFoundException.html">FileNotFoundException</classname> - is being thrown.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaWc"> - <title>A partial implementation of GNU UNIX - <command>wc</command></title> - - <qandadiv> - <qandaentry> - <question> - <para>In this exercise we will partly implement the (Gnu) UNIX - command line tool <command - xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/wc-invocation.html">wc</command> - (word count). Prior to starting this exercise you may want - to:</para> - - <itemizedlist> - <listitem> - <para>Execute <command - xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/wc-invocation.html">wc</command> - for sample text files like e.g. a Java source file of - similar:</para> - - <programlisting language="bourne">goik >wc BoundedIntegerStore.java - 58 198 1341 BoundedIntegerStore.java -</programlisting> - - <para>What do these three numbers 58, 198 and 1341 mean? - Execute <command>wc</command> <option>--help</option> or - <command>man</command> <option>wc</option> or read the <link - xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/wc-invocation.html">HTML - documentation</link>.</para> - </listitem> - - <listitem> - <para><command>wc</command> may process several file in - parallel thereby producing an extra line <coref - linkend="sd1PlWcExtraLine"/> summing up all values:</para> - - <programlisting language="bourne">goik >wc bibliography.xml swd1.xml - 69 83 2087 bibliography.xml - 6809 18252 248894 swd1.xml - <emphasis role="bold">6878 18335 250981 total</emphasis> <co - xml:id="sd1PlWcExtraLine"/> -</programlisting> - </listitem> - - <listitem> - <para><command>wc</command> can be used in <link - xlink:href="http://en.wikipedia.org/wiki/Pipeline_(Unix)">pipes</link> - () like:</para> - - <programlisting language="bourne">goik >grep int BoundedIntegerStore.java | wc - 12 76 516</programlisting> - - <para>The above output <quote>12 76 516</quote> tells us - that our file <filename>BoundedIntegerStore.java</filename> - does have 12 lines containing the string - <quote>int</quote>.</para> - </listitem> - </itemizedlist> - - <para>A partial implementation shall offer all features being - mentioned in the introduction. The following steps are a - proposal for your implementation:</para> - - <orderedlist> - <listitem> - <para>Write a method counting the number of words within a - given string. We assume words to be separated by at least - one white space character (<code>space</code> or - <code>\t</code>). Write some tests to assure correct - behaviour.</para> - </listitem> - - <listitem> - <para>Read input either from a list of files or from - standard input depending on the number of arguments to - main(String[] args):</para> - - <itemizedlist> - <listitem> - <para>If <code>args.length == 0</code> assume to read - from standard input.</para> - </listitem> - - <listitem> - <para>if <code>0 < args.length</code> try to - interpret the arguments as filenames.</para> - </listitem> - </itemizedlist> - </listitem> - - <listitem> - <para>Write a class <code>TextFileStatistics</code> being - able to and count characters, words and lines of a single - input file. Instances of this class may be initialized from - a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname>.</para> - - <para>Write corresponding tests.</para> - </listitem> - - <listitem> - <para>You may create an instance of <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html">BufferedReader</classname> - from <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#in">System.in</link> - via:</para> - - <programlisting language="java">new BufferedReader(new InputStreamReader(System.in))</programlisting> - </listitem> - - <listitem> - <para>Create an executable Jar archive and execute some - examples. The UNIX command <command - xlink:href="http://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html#cat-invocation">cat</command> - writes a file's content to standard output. This output may - be piped as input to your application as in <code>cat - filename.txt | java -jar .../wc-1.0.jar</code>.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Wc/wc</para> - </annotation> - - <para>Executing <command>mvn</command> <option>package</option> - creates an executable Jar file - <filename>../target/wc-1.0.jar</filename>. We test both ways of - operation:</para> - - <glosslist> - <glossentry> - <glossterm>Reading from standard input</glossterm> - - <glossdef> - <programlisting language="bourne">goik >cat Testdata/input.html | java -jar target/wc-1.0.jar - 9 14 137</programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Passing file names as parameters</glossterm> - - <glossdef> - <programlisting language="bourne">goik >java -jar target/wc-1.0.jar Testdata/* - 9 14 137 Testdata/input.html - 4 5 41 Testdata/model.css - 13 19 178 total</programlisting> - </glossdef> - </glossentry> - </glosslist> - - <para><xref linkend="glo_Junit"/> tests of internal - functionality:</para> - - <glosslist> - <glossentry> - <glossterm>Counting words in a given string:</glossterm> - - <glossdef> - <programlisting language="java"> @Test - public void testNoWord() { - Assert.assertEquals("Just white space", 0, TextFileStatistics.findNoOfWords(" \t")); - } - - @Test - public void testSingleWord() { - final String s = "We're"; - Assert.assertEquals("text='" + s + "'", 1, TextFileStatistics.findNoOfWords(s)); - } - - @Test - public void testTwoWords() { - final String s = "We are"; - Assert.assertEquals("text='" + s + "'", 2, TextFileStatistics.findNoOfWords(s)); - } - - @Test - public void testWordsWhiteHead() { - final String s = "\t \tBegin_space"; - Assert.assertEquals("text='" + s + "'", 1, TextFileStatistics.findNoOfWords(s)); - } - - @Test - public void testWordsWhiteTail() { - final String s = "End_space \t "; - Assert.assertEquals("text='" + s + "'", 1, TextFileStatistics.findNoOfWords(s)); - } - - @Test - public void testWhiteMulti() { - final String s = " some\t\tinterspersed \t spaces \t\t "; - Assert.assertEquals("text='" + s + "'", 3, TextFileStatistics.findNoOfWords(s)); - }</programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Analyzing test file data:</glossterm> - - <glossdef> - <programlisting language="java"> @Test - public void testTwoInputFiles() throws FileNotFoundException, IOException { - - final String model_css_filename = "Testdata/model.css", // 4 lines 5 words 41 character - input_html_filename = "Testdata/input.html"; // 9 lines 14 words 137 character - //_________________________________________ - // total 13 lines 19 words 178 character - - final TextFileStatistics - model_css = new TextFileStatistics( - new BufferedReader(new FileReader(model_css_filename)), model_css_filename), - - input_html = new TextFileStatistics(new BufferedReader( - new FileReader(input_html_filename)), input_html_filename); - - // File Testdata/model.css - Assert.assertEquals( 4, model_css.numLines); - Assert.assertEquals( 5, model_css.numWords); - Assert.assertEquals(41, model_css.numCharacters); - - // File Testdata/input.html - Assert.assertEquals( 9, input_html.numLines); - Assert.assertEquals( 14, input_html.numWords); - Assert.assertEquals(137, input_html.numCharacters); - - // Grand total - Assert.assertEquals( 13, TextFileStatistics.getTotalNumLines()); - Assert.assertEquals( 19, TextFileStatistics.getTotalNumWords()); - Assert.assertEquals(178, TextFileStatistics.getTotalNumCharacters()); - }</programlisting> - </glossdef> - </glossentry> - </glosslist> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1Collection1"> - <title>Collections I</title> - - <section xml:id="sd1CollectionsPrep"> - <title>Preparations</title> - - <para>Chapter 14 of <xref linkend="bib_Horton2011"/> provides an in - depth discussion of Java collections. Regarding the upcoming exercises - you may however prefer to study the following track:</para> - - <glosslist> - <glossentry> - <glossterm>Introduction</glossterm> - - <glossdef> - <para - xlink:href="http://tutorials.jenkov.com/java-collections/collection.html"><link - xlink:href="http://tutorials.jenkov.com/java-collections/collection.html">Java - Collections - Collection</link></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname>List</classname></glossterm> - - <glossdef> - <para - xlink:href="http://tutorials.jenkov.com/java-collections/list.html"><link - xlink:href="http://tutorials.jenkov.com/java-collections/list.html">Java - Collections - List</link></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname>Set</classname></glossterm> - - <glossdef> - <para - xlink:href="http://tutorials.jenkov.com/java-collections/set.html"><link - xlink:href="http://tutorials.jenkov.com/java-collections/set.html">Java - Collections - Set</link></para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><methodname>hashCode()</methodname> and - <methodname>equals()</methodname></glossterm> - - <glossdef> - <itemizedlist> - <listitem> - <para - xlink:href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html"><link - xlink:href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html">Java - Collections - hashCode() and equals()</link></para> - </listitem> - - <listitem> - <para><link xlink:href="Ref/Svg/hashing.svg">Hashing overview - slides</link>.</para> - </listitem> - </itemizedlist> - </glossdef> - </glossentry> - </glosslist> - </section> - - <section xml:id="sd1Collection1exercise"> - <title>Exercises</title> - - <section xml:id="sd1Collection2exerciseSetString"> - <title>A <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> - of Strings</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaSetString"> - <title>Inserting strings into a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname>.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Create a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> - of String instances including duplicates. Iterate over this - set and write each value to <code>System.out</code>:</para> - - <programlisting language="java"> public static void main(String[] args) { - - final Set<String> names = new HashSet<String>(); - names.add(... - ... - // Iterate over all inserted coordinates - for (... - }</programlisting> - </question> - - <answer> - <para>Inserting some string literals is a trivial task. A - for-each loop allows iterating over the set to write its - content to standard output:</para> - - <programlisting language="java"> public static void main(String[] args) { - - final Set<String> names = new HashSet<String>(); - - names.add("Eve"); - names.add("Jim"); - names.add("Tom"); - names.add("Jim"); - - // Iterate over all inserted coordinates - System.out.println("The set contains " + names.size() + " elements:"); - for (final String s : names) { - System.out.println(s); - } - }</programlisting> - - <para>Notice the duplicate name <code>"Jim"</code>: Since our - collection does have set semantics it only contains three - elements {"Eve", "Jim", "Tom"}:</para> - - <programlisting language="none">The set contains 3 elements: -Tom -Jim -Eve</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1CollectionExerciseListString"> - <title>A <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname> - of Strings</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaListString"> - <title>Inserting strings into a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname>.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Create a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname> - of String instances including duplicates. Iterate over this - list and write each value to <code>System.out</code>:</para> - - <programlisting language="java"> public static void main(String[] args) { - - final List<String> names = ...; - - names.add(... - ... - - // Iterate over all inserted strings - System.out.println("The list contains " + names.size() + " elements:"); - for (final String s : names) { - System.out.println(s); - } - }</programlisting> - </question> - - <answer> - <para>Our code closely resembles <xref - linkend="sd1QandaSetString"/>:</para> - - <programlisting language="java"> public static void main(String[] args) { - - final List<String> names = new Vector<String>(); - - names.add("Eve"); - names.add("Jim"); - names.add("Tom"); - names.add("Jim"); - - // Iterate over all inserted strings - System.out.println("The list contains " + names.size() + " elements:"); - for (final String s : names) { - System.out.println(s); - } - }</programlisting> - - <para>This time the duplicate actually shows up:</para> - - <programlisting language="none">The list contains 4 elements: -Eve -Jim -Tom -Jim</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1CollectionDefCoordinate"> - <title>Defining a <classname>Coordinate</classname> class</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaCoordinate"> - <title>Representing integer coordinate values</title> - - <qandadiv> - <qandaentry> - <question> - <para>Implement a class <classname>Coordinate</classname> to - represent integer Cartesian coordinate values:</para> - - <programlisting language="java">public class Coordinate { - - private int x, y; - ... -}</programlisting> - - <para>Provide an appropriate constructor and override both - <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--">toString()</methodname> - and <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> - to allow execution of:</para> - - <programlisting language="java"> // Defining and testing integer coordinates - final Coordinate - c12 = new Coordinate(1, 2), - c52 = new Coordinate(5, 0), - c12Duplicate = new Coordinate(1, 2); - - - System.out.println("c12:"+ c12); - System.out.println("c12.equals(c52):"+ c12.equals(c52)); - System.out.println("c12.equals(c12Duplicate):"+ c12.equals(c12Duplicate)); - System.out.println("c12.equals(\"dummy\"):"+ c12.equals("dummy")); - - System.out.println(c12);</programlisting> - - <para>This should yield the expected output:</para> - - <programlisting language="none">c12:(1|2) -c12.equals(c52):false -c12.equals(c12Duplicate):true -c12.equals("dummy"):false -(1|2)</programlisting> - </question> - - <answer> - <para>Overriding <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString--">toString()</methodname> - and <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> - and adding a non-default constructor is a straightforward - exercise:</para> - - <programlisting language="java">public class Coordinate { - - private int x, y; - - /** - * Create a Cartesian coordinate / point. - * @param x - * @param y - */ - public Coordinate(int x, int y) { - this.x = x; - this.y = y; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Coordinate) { - return x == ((Coordinate)obj).x && - y == ((Coordinate)obj).y; - } else { - return false; - } - } - - @Override - public String toString() { - return "(" + x + "|" + y + ")"; - } -}</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1SetCoordinate"> - <title>A <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> - of Coordinate instances</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaSetCoordinate"> - <title>Inserting <link - linkend="sd1CollectionDefCoordinate"><classname>Coordinate</classname></link> - instances into a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname>.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Create a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> - of <link - linkend="sd1CollectionDefCoordinate"><classname>Coordinate</classname></link> - instances including duplicates. Iterate over this set and - write each value to <code>System.out</code> in a similar - fashion to <xref linkend="sd1QandaSetString"/>. Compare your - output to the corresponding example <xref - linkend="sd1QandaSetString"/>.</para> - - <para>Did you expect this behaviour? Explain this result and a - solution.</para> - </question> - - <answer> - <para>Our code is very similar to <xref - linkend="sd1QandaSetString"/>:</para> - - <programlisting language="java"> final Set<Coordinate> points = new HashSet<Coordinate>(); - - points.add(new Coordinate(1, 2)); - points.add(new Coordinate(4, 1)); - points.add(new Coordinate(1, 2)); // Equal to first Object - - // Iterate over all inserted coordinates - System.out.println("The set contains " + points.size() + " elements:"); - for (final Coordinate c : points) { - System.out.println(c.toString()); - }</programlisting> - - <para>Since we do have set semantics we expect the duplicate - coordinate value <code>(1|2)</code> to be dropped and thus to - appear only once. So our set should contain <code>{(4|1), - (1|2)}</code>. We however see the duplicate object appearing - on standard output:</para> - - <programlisting language="none">The set contains 3 elements: -(4|1) -(1|2) -(1|2)</programlisting> - - <para>This is due to our own fault not providing a <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashCode()</methodname> - implementation being compatible to our overridden <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> - method. Consider:</para> - - <programlisting language="java"> final Coordinate - c12 = new Coordinate(1, 2), - c12Duplicate = new Coordinate(1, 2); - - System.out.println("c12.hashCode() and c12Duplicate.hashCode():"+ c12.hashCode() + "," + c12Duplicate.hashCode());</programlisting> - - <para>This yields the following output:</para> - - <programlisting language="none">c12.hashCode() and c12Duplicate.hashCode():1334574952,1882008996</programlisting> - - <para>Apparently the two instances c12 and c12Duplicate are - equal to each other. Their hash codes however are different - clearly violating the contract being described in <link - xlink:href="http://tutorials.jenkov.com/java-collections/hashcode-equals.html">Java - Collections - hashCode() and equals()</link>. The values - actually stem from <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashCode()</methodname> - being defined in our superclass <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html">Object</classname>.</para> - - <para>The former exercise <xref linkend="sd1QandaSetString"/> - involved instances of class String having well defined - <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#equals-java.lang.Object-">equals()</methodname> - and <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#hashCode--">hashCode()</methodname> - implementations. To resolve this issue we thus have to - override not just <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals()</methodname> - but <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashCode()</methodname> - as well:</para> - - <programlisting language="java">public class Coordinate { - - private int x, y; - ... - - @Override - public int hashCode() { - // See last answer (06/16/2014) in - // http://stackoverflow.com/questions/16629893/good-hashcode-implementation - return Long.valueOf(x * 31 + y).hashCode(); - } -}</programlisting> - - <para>This yields:</para> - - <programlisting language="none">c12.hashCode() and c12Duplicate.hashCode():33,33</programlisting> - - <para>And finally:</para> - - <programlisting language="none">The set contains 2 elements: -(1|2) -(4|1)</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1Collect2"> - <title>Collections II</title> - - <section xml:id="sd1Collection2exercise"> - <title>Exercises</title> - - <section xml:id="sd1CollectionExerciseWordSearch"> - <title>Getting a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> - of strings from a text file</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaWordSearch"> - <title>Getting a text's set of words.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider a text file <filename>foo.txt</filename> - containing:</para> - - <programlisting language="none">A simple collection of words. - Some words may appear multiple times.</programlisting> - - <para>We would like to retrieve a comma separated list of all - words being contained within excluding duplicates.</para> - - <programlisting language="none">of, multiple, collection, simple, words, may, Some, times, A, appear</programlisting> - - <para>The subsequent rules shall apply:</para> - - <itemizedlist> - <listitem> - <para>Arbitrary combinations of white space and the - characters <emphasis - role="bold"><code>.,:;?!"</code></emphasis> shall be - treated as word delimiters and are otherwise to be - ignored.</para> - </listitem> - - <listitem> - <para>The order of appearance in the generated result does - not matter.</para> - </listitem> - - <listitem> - <para>Duplicates like <quote>words</quote> in the current - example shall show up only once on output.</para> - </listitem> - </itemizedlist> - - <para>Hints:</para> - - <orderedlist> - <listitem> - <para>Your application shall read its input from a given - file name provided as a command line argument. Provide - appropriate error messages if:</para> - - <itemizedlist> - <listitem> - <para>The users enters either no arguments at all or - more than one command line argument.</para> - </listitem> - - <listitem> - <para>The file in question cannot be read.</para> - </listitem> - </itemizedlist> - - <para>You may reconsider <xref linkend="sd1GnuWc"/> - regarding file read access.</para> - </listitem> - - <listitem> - <para>Splitting input text lines at word delimiters - <emphasis role="bold"><code>.,:;?!"</code></emphasis> or - white space characters may be achieved by means of - <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-">split(...)</methodname> - and the regular expression <code>String regex = "[ - \t\"!?.,'´`:;]+"</code>;. This <quote>+</quote> sign - indicates the appearance of a succession of one ore more - character element from the set <emphasis - role="bold"><code> \t\"!?.,'´`:;</code></emphasis>.</para> - - <para>Thus a text <emphasis role="bold"><code>That's it. - Next try</code></emphasis> will be split into a string - array <code>{"That", "s", "it", "Next", - "try"}</code>.</para> - </listitem> - - <listitem> - <para>Write a <xref linkend="glo_Junit"/> test which reads - from a given input file and compares its result with a - hard coded set of expected strings.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/Wordlist/Solution</para> - </annotation> - - <para>The input file smalltest.txt may be used to define a - <xref linkend="glo_Junit"/> test:</para> - - <programlisting language="java"> @Test - public void testWordSet() throws FileNotFoundException, IOException { - - final Set<String> expectedStrings = - new HashSet <String>(Arrays.asList(new String[]{ - "A", "simple", "collection", "of", "words", - "Some", "may", "appear", "multiple", "times" - })); - - final TextFileHandler tfh = new TextFileHandler("smalltest.txt"); - Assert.assertTrue(tfh.getWords().equals(expectedStrings)); - }</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1CollectionExerciseWordSearchOrder"> - <title>Result string ordering</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaWordSearchOrdered"> - <title>A text's set of words in alphabetic order</title> - - <qandadiv> - <qandaentry> - <question> - <para>Copy the previous project to a second one and modify - your code to get the same set of words but in alphabetic order - with respect to capital and small letters:</para> - - <programlisting language="none">A, Some, appear, collection, may, multiple, of, simple, times, words </programlisting> - </question> - - <answer> - <para>The desired result is easy to achieve by exchanging our - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname> - by a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html">SortedSet</classname>:</para> - - <programlisting language="java"> /** - * The set of words found so far. - */ - final SortedSet<String> words = new TreeSet<String>();</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1StringLengthSort"> - <title>Sorting strings in an unusual way</title> - - <para>This exercise intends to provide some knowledge on sorting being - needed in subsequent exercises.</para> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaStringLengthSort"> - <title>Implementing unusual string sorting.</title> - - <qandadiv> - <qandaentry> - <question> - <para>Strings will often be sorted alphabetically:</para> - - <programlisting language="none">ant -apple -by -eye -it -printer -van -x-ray</programlisting> - - <para>In this exercise we want to sort strings by length and - then alphabetically:</para> - - <programlisting language="none">by -it -ant -eye -van -apple -x-ray -printer</programlisting> - - <para>Hints:</para> - - <orderedlist> - <listitem> - <para><link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-java.util.Comparator-">Collections.sort(</link>List<String>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator</classname> - c) is your friend.</para> - </listitem> - - <listitem> - <para>Defining a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator</classname> - class acting on strings works like:</para> - - <programlisting language="java">/** - * Compare strings first by their length. If two strings do have - * common length, sort them alphabetically. - * - */ -public class LengthCompare implements Comparator<String> { - @Override - public int compare(String s1, String s2) { - ... - return ...; -}</programlisting> - </listitem> - - <listitem> - <para>Write a <xref linkend="glo_Junit"/> test to assure - correct sorting of strings.</para> - </listitem> - </orderedlist> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/StringLengthSort/Solution</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1CollectionWordFrequencies"> - <title>Result string ordering</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaWordFrequencies"> - <title>Words and corresponding frequencies</title> - - <qandadiv> - <qandaentry> - <question> - <para>So far we've extracted the set of words a given text - consists of. In addition we'd like to see their corresponding - frequencies of appearance as well. This frequency value shall - be used as primary sorting criterion with respect to report - output. Consider the following example text:</para> - - <programlisting language="none">One day, Einstein, Newton, and Pascal meet up -and decide to play a game of hide and seek. -Einstein volunteered to be "It". As Einstein -counted, eyes closed, to 100, Pascal ran away -and hid, but Newton stood right in front of -Einstein and drew a one meter by one meter -square on the floor around himself. When -Einstein opened his eyes, he immediately saw -Newton and said "I found you Newton", but Newton -replied, "No, you found one Newton per square meter. -You found Pascal!"</programlisting> - - <para>Ignoring special characters the following result shall - be created:</para> - - <programlisting language="none"> 6: Newton - 6: and - 5: Einstein - 3: Pascal - 3: found - 3: meter - 3: one - 3: to - 2: a -...</programlisting> - - <para>The first line tells us that the word - <quote>Newton</quote> appears six times in the analyzed - document.</para> - - <para>Hints:<orderedlist> - <listitem> - <para>Define a class - <classname>WordFrequency</classname> containing a - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname> - attribute among with an integer number representing its - frequency of appearance:</para> - - <programlisting language="java">/** - * A helper class to account for frequencies of words found in textual input. - * - */ -public class WordFrequency { - /** - * The frequency of this word will be counted. - */ - public final String word; - private int frequency; - ... -}</programlisting> - - <para>Two instances of - <classname>WordFrequency</classname> shall be equal if - and only if their <quote>word</quote> attribute values - are equal regardless of their frequency values. In - slightly other words: With respect to equality instances - of <classname>WordFrequency</classname> inherit equality - solely from their contained word values irrespective of - any frequency value.</para> - - <para>Override <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-">equals(...)</methodname> - and <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--">hashValue()</methodname> - accordingly.</para> - </listitem> - - <listitem> - <para>Create a List<WordFrequency> (Not a - Set<WordFrequency>!) holding words being found in - your input texts among with their frequencies of - appearance.</para> - - <para>Whenever the next input word is being processed - follow the subsequent procedure:</para> - - <orderedlist> - <listitem> - <para>Create a corresponding instance of - <classname>WordFrequency</classname> from it having - initial frequency 1.</para> - </listitem> - - <listitem> - <para>Test whether an instance being equal has - already been added to your - <code>List<WordFrequency></code> instance - leaving you with two choices:</para> - - <glosslist> - <glossentry> - <glossterm>The current word already - exists:</glossterm> - - <glossdef> - <para>Lookup the entry and increment its frequency - by one.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>The current word is new:</glossterm> - - <glossdef> - <para>Add the previously created - <classname>WordFrequency</classname> instance to - your <code>List<WordFrequency></code>.</para> - </glossdef> - </glossentry> - </glosslist> - </listitem> - - <listitem> - <para>After processing the input text file sort your - <code>List<WordFrequency></code> by a suitable - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator<WordFrequency></classname> - instance by means of <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-java.util.Comparator-">Collections.sort(...)</methodname>.</para> - </listitem> - </orderedlist> - </listitem> - </orderedlist></para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/WordFrequency1/Solution</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> - </chapter> - - <chapter xml:id="sd1Collection3"> - <title>Collections III</title> - - <section xml:id="sd1Collection3Exercise"> - <title>Exercises</title> - - <figure xml:id="sd1FigureAccoutInheritHierarchy"> - <title>Account hierarchy</title> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/account.fig"/> - </imageobject> - </mediaobject> - </figure> - - <figure xml:id="sda1FigurePersonInheritHierarchy"> - <title>Students and lecturers</title> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/person.fig"/> - </imageobject> - </mediaobject> - </figure> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaAddressHtmlFormat"> - <title>Formatting an address list</title> + <qandaset defaultlabel="qanda" xml:id="sd1TidyCrabImages"> + <title>Tidy up image handling</title> <qandadiv> <qandaentry> <question> - <para>We want to transform address data to different destination - formats. Consider the following text file data source:</para> - - <programlisting language="none">"firstName","lastName","companyName","address","city", ... -"Aleshia","Tomkiewicz","Alan D Rosenburg Cpa Pc","14 Tay ... -...</programlisting> - - <para>This excerpt exists as file named - <filename>addresses.txt</filename> in the following Maven - project:</para> - - <annotation role="make"> - <para role="eclipse">P/HtmlFormatting/Simple/Exercise</para> - </annotation> - - <para>Import the above project into <xref - linkend="glo_Eclipse"/>. Executing - <classname>de.hdm_stuttgart.mi.sd1.htmlformat.Address2text</classname> - yields the following output:</para> - - <programlisting language="none">"firstName","lastName","companyName","address","city", ... -List of addresses: -++++++++++++++++++++++ -Name:Tim Dummy -Company:Dummy Company -Address:Dummy street, DummyCity, DummyPostal -Phone:1234567, 7654321 -E-Mail:@dummy@dummy.com --------------------- - -... - --------------------- -End of records</programlisting> - - <para>This result neither uses the input data supplied by - <filename>addresses.txt</filename> nor does it produce HTML - output yet. You have to complete the implementation by following - the subsequent steps:</para> - - <orderedlist> - <listitem> - <para>Try to understand the current project. Its classes - have the following general purposes:</para> - - <glosslist> - <glossentry> - <glossterm><classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address.html">Address</classname></glossterm> - - <glossdef> - <para>Holding components like first name, last name, - telephone numbers, email and so on of an individual - address.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2text.html">Address2text</classname></glossterm> - - <glossdef> - <para>The main application. This class assembles other - classes, opens the address data source and starts the - formatting process.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2textFormatter.html">Address2textFormatter</classname></glossterm> - - <glossdef> - <para>This class formats individual address - records.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressDataHandler.html">AddressDataHandler</classname></glossterm> - - <glossdef> - <para>Opening the data source and creating a Java in - memory representation of the whole set. This is - necessary since the output sorting order may be - altered.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressFormatter.html">AddressFormatter</classname></glossterm> - - <glossdef> - <para>This interface specifies three methods being - called during output formatting.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm><classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressParseError.html">AddressParseError</classname></glossterm> - - <glossdef> - <para>Instances of this exception will be thrown - whenever the input file contains errors. Consider the - following example:</para> - - <programlisting language="none">"Laquita","Hisaw,"In Communications Inc","20 Gloucester Pl #96",</programlisting> - - <para>In this example we have no quote after - <code>Hisaw</code>. This should yield a parsing - error.</para> - </glossdef> - </glossentry> - </glosslist> - </listitem> + <para>The source ode of our little crab version 5 scenario + (<filename>book-scenarios/chapter02-04/little-crab-5)</filename> + contains:</para> - <listitem> - <para>The constructor <link - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address.html#Address(java.lang.String,%20int)">Address(...)</link> - does not yet parse address records but creates constant - dummy data instead. Use the parameter <code>csvRecord</code> - to actually initialize the desired address fields - <code>firstName</code>, <code>lastName</code>, ..., - <code>web</code>. Hint: You may use the <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-">split(...)</link> - method:</para> - - <programlisting language="java">... = s.split("\",\"");</programlisting> - - <para>This splits an input record into its address - components. The first component will however start with a - quotation mark like <code>"Aleshia</code> and the last - component will have a trailing <code>"</code> like in - <code>http://www.lbt.co.uk"</code>. You may use the - substring(...) method to get rid of them.</para> - </listitem> + <programlisting language="java">public class Crab extends Animal { - <listitem> - <para>You must exclude the header line (= first line of - addresses.txt) of your data source from result - generation:</para> + private GreenfootImage <emphasis role="bold">image1</emphasis>; + private GreenfootImage <emphasis role="bold">image2</emphasis>; + ... + public Crab() { + <emphasis role="bold">image1</emphasis> = new GreenfootImage("crab.png"); + <emphasis role="bold">image2</emphasis> = new GreenfootImage("crab2.png"); + setImage(image1); + wormsEaten = 0; + }</programlisting> - <programlisting language="none">"firstName","lastName","companyName","address","city","county","postal","phone1","phone2","email","web"</programlisting> - </listitem> + <para>Imagine we'd like to extend the crab game doing a + simulation requiring thousands of crabs. Why is the above code + badly written with respect to performance? Do you have an idea + how to correct this issue?</para> - <listitem> - <para>Think of all syntax rules of your input data source - addresses.txt and throw <classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressParseError.html">AddressParseError</classname> - appropriate exceptions. Write test cases checking for - correct parsing error detection in input files.</para> - </listitem> + <para>Hint: Think whether each crab really needs two <emphasis + role="bold">individual</emphasis> images.</para> + </question> - <listitem> - <para>The current project produces text output. In order to - generate HTML you have to replace <classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2textFormatter.html">Address2textFormatter</classname> - by a new class <classname>Address2htmlFormatter</classname> - which implements the interface <classname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/AddressFormatter.html">AddressFormatter</classname> - as well.</para> - - <para>You may then exchange your formatter in - <classname>Address2text</classname>.<methodname - xlink:href="Ref/api/P/HtmlFormatting/Simple/Exercise/de/hdm_stuttgart/mi/sd1/htmlformat/Address2text.html#main(java.lang.String[])">main()</methodname>:</para> - - <programlisting language="java">final AddressFormatter htmlFormatter = new Address2htmlFormatter();</programlisting> - </listitem> + <answer> + <para>If we had 1000 crabs the code in question would allocate + 2000 images in memory. But actually only two of these 2000 + images are mutually different from each other. So allocating the + remaining 1998 is a wast of memory.</para> - <listitem> - <para>Address fields may contain the characters - <code><</code>, <code>></code> and <code>&</code>. - These will interfere with generated HTML markup. There are - two possible solutions:</para> - - <glosslist> - <glossentry> - <glossterm><acronym>CDATA</acronym> sections - (preferred):</glossterm> - - <glossdef> - <para>Wrap your output in <code><![CDATA[ ... - ]]></code> sections if required. Strictly speaking - this is only specified for XHTML variants but most - browsers will accept it anyway.</para> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Using HTML replacement entities</glossterm> - - <glossdef> - <informaltable border="1" width="10%"> - <tr> - <td><code>&</code></td> - - <td><code>&amp;</code></td> - </tr> - - <tr> - <td><code><</code></td> - - <td><code>&lt;</code></td> - </tr> - - <tr> - <td><code>></code></td> - - <td><code>&gt;</code></td> - </tr> - </informaltable> - - <para>This requires textually replacing special - characters by the above entities e.g. by means of - <classname>String</classname>.<methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#replace-java.lang.CharSequence-java.lang.CharSequence-">replace(...)</methodname>.</para> - </glossdef> - </glossentry> - </glosslist> - </listitem> + <para>It is sufficient to create only these two images since + each crab will just toggle between them. This should happen on + class level rater than on instance level:</para> - <listitem> - <para>Since you do generate HTML output renaming your class - <classname>Address2text</classname> to - <classname>Address2html</classname> is a good idea. Your - output might look like:</para> - - <programlisting language="none"><html xmlns='http://www.w3.org/1999/xhtml'> - <head> - <title>Address list:</title> - </head> - <body> - <h1>Address list:</h1> - <table border='1'> - <colgroup style='width: 20%'/> - <colgroup style='width: 30%'/> - <colgroup style='width: 25%'/> - <colgroup style='width: 25%'/> - <tr> - <th>Name</th> - <th>Address</th> - <th>Phone</th> - <th>E-Mail</th> - </tr> - ... - <tr> - <td>Graham <b>Stanwick</b></td> - <td><emphasis role="bold"><![CDATA[73 Hawkstone St, Renfrew South & Gallowhill War]]></emphasis>, <b>G52 4YG</b></td> - <td>01860-191930</td> - <td>gstanwick@gmail.com</td> - </tr> - <tr> - ... - - </tr> - </table> - </body> -</html></programlisting> - - <para>As you can see <acronym>CDATA</acronym> sections are - only used if embedded data does contain <, > or & - characters.</para> - </listitem> + <programlisting language="java">public class Crab extends Animal { - <listitem> - <para>You may direct your generated HTML output to a file - rather than to the standard output <link - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#out">System.out</link>. - This can be achieved by opening an output <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html">PrintStream</classname> - related to a file by means of the <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html#PrintStream-java.lang.String-">PrintStream</methodname> - output filename constructor. Your resulting output may - transform the file <filename>addresses.txt</filename> into - <filename>addresses.txt.xhtml</filename>. The latter should - be rendered like:</para> - - <informalfigure> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/addressHtml.png"/> - </imageobject> - </mediaobject> - </informalfigure> - </listitem> - </orderedlist> - </question> + private final static GreenfootImage image1 = new GreenfootImage("crab.png"); + private GreenfootImage image2 = new GreenfootImage("crab2.png"); + public Crab() { + setImage(image1); + wormsEaten = 0; + } ...</programlisting> - <answer> - <annotation role="make"> - <para role="eclipse">P/HtmlFormatting/Simple/Solution</para> - </annotation> + <para>The remaining code may remain unchanged</para> </answer> </qandaentry> </qandadiv> </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1Collection4"> - <title>Collections IV</title> - - <section xml:id="sd1Collection4Exercise"> - <title>Exercises</title> - <qandaset defaultlabel="qanda" xml:id="sd1QandaImplementStringSet"> - <title>Implementing a set of strings</title> + <qandaset defaultlabel="qanda" xml:id="sd1QandaInitCrabWorld"> + <title>Initializing our crab's world.</title> <qandadiv> <qandaentry> <question> - <para>We want to partly implement a simplified version of - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Set.html">Set</classname>:</para> - - <programlisting language="java">package de.hdm_stuttgart.mi.sd1.stringset; - - -/** - * A collection of Strings that contains no duplicate elements. - * More formally, sets contain no pair of Strings s1 and s2 such that - * s1.equals(s2), and no null elements. As implied by its name, - * this class models the mathematical set abstraction. - * - * The StringSet class places stipulations on the contracts of the add, - * equals and hashCode methods. - * - * The stipulation on constructors is, not surprisingly, that all constructors - * must create a set that contains no duplicate elements (as defined above). - * - */ -public interface Set_String { - - /** - * Returns the number of strings in this set (its cardinality). - * - * @return the number of elements in this set (its cardinality) - */ - public int size() ; - - /** - * Returns true if this set contains no elements. - * - * @return true if this set contains no elements - */ - public boolean isEmpty(); + <para>We take a closer look at the little crab version 5 + scenario in + <filename>book-scenarios/chapter02-04/little-crab-5</filename>. + The subsequently copied code is meant to initialize our crab's + world. Albeit being technically achieving its purpose this code + lacks flexibility and suffers from various flaws to be corrected + by <emphasis role="bold">YOU</emphasis>:</para> - /** - * Returns true if this set contains the specified element. More - * formally, returns true if and only if this set contains an - * element e such that (o==null ? e==null : o.equals(e)). - * - * @param o element whose presence in this set is to be tested - * @return true if this set contains the specified element. - * A null value will be treated as "not in set". - * - */ - public boolean contains(Object o); + <programlisting language="java">public class CrabWorld extends World { + /** + * Create the crab world (the beach). Our world has a size + * of 560x560 cells, where every cell is just 1 pixel. + */ + public CrabWorld() { + super(560, 560, 1); <co linkends="sd1CrabworldInitDeficiencies-1" + xml:id="sd1CrabworldInitDeficiencies-1-co"/> + populateWorld(); + } - /** - * Returns an array containing all strings in this set. - * - * The returned array will be "safe" in that no references to it are - * maintained by this set. (In other words, this method allocates - * a new array). The caller is thus free to modify the returned array. - * - * @return an array containing all strings in this set. - */ - public String[] toArray(); + /** + * Create the objects for the start of the game. + */ + public void populateWorld() { + addObject(new Crab(), 300, 300); <co + linkends="sd1CrabworldInitDeficiencies-2" + xml:id="sd1CrabworldInitDeficiencies-2-co"/> <co + linkends="sd1CrabworldInitDeficiencies-3" + xml:id="sd1CrabworldInitDeficiencies-3-co"/> - /** - * Adds the specified element to this set if it is not already present. - * More formally, adds the specified element e to this set if the set - * contains no element e2 such that (e==null ? e2==null : e.equals(e2)). - * If this set already contains the element, the call leaves the set - * unchanged and returns false. In combination with the restriction on - * constructors, this ensures that sets never contain duplicate elements. - * - * null values will be discarded - * - * @param s string to be added to this set - * - * @return true if this set did not already contain the specified element. - * The attempted insert of a null value will return false. - */ - public boolean add(String s); - - /** - * Removes the specified string from this set if it is present - * (optional operation). More formally, removes a string s - * such that (o==null ? s==null : o.equals(s)), if this set - * contains such a string. Returns true if this set contained - * the string (or equivalently, if this set changed as a result - * of the call). (This set will not contain the string once the - * call returns.) - * - * @param s String to be removed from this set, if present. - * @return true if this set contained the specified string. - */ - public boolean remove(Object s); + addObject(new Lobster(), 90, 70); <co + linkends="sd1CrabworldInitDeficiencies-4" + xml:id="sd1CrabworldInitDeficiencies-4-co"/> <coref + linkend="sd1CrabworldInitDeficiencies-2-co"/> <coref + linkend="sd1CrabworldInitDeficiencies-3-co"/> + addObject(new Lobster(), 390, 200); + addObject(new Lobster(), 360, 500); - /** - * Removes all of the strings from this set (optional operation). - * The set will be empty after this call returns. - */ - public void clear(); + addObject(new Worm(), 20, 500); <coref + linkend="sd1CrabworldInitDeficiencies-4-co"/> <coref + linkend="sd1CrabworldInitDeficiencies-2-co"/> <coref + linkend="sd1CrabworldInitDeficiencies-3-co"/> + addObject(new Worm(), 30, 200); + addObject(new Worm(), 60, 90); + addObject(new Worm(), 80, 310); + addObject(new Worm(), 150, 50); + addObject(new Worm(), 210, 410); + addObject(new Worm(), 220, 520); + addObject(new Worm(), 380, 330); + addObject(new Worm(), 410, 270); + addObject(new Worm(), 530, 30); + } }</programlisting> - <para>Implement this interface:</para> - - <programlisting language="java">public class MySet_String implements Set_String { - - /** - * Constructs a new, empty set; - */ - public MySet_String() { - ... - } - - /** - * Copy array values into this set excluding duplicates. - * - * @param source The array to copy values from - */ - public MySet_String(final String[] source) { - ... - } - - @Override - public int size() { - ... - } - ... -}</programlisting> + <calloutlist> + <callout arearefs="sd1CrabworldInitDeficiencies-1-co" + xml:id="sd1CrabworldInitDeficiencies-1"> + <para>We might want our world to become parametrized in a + more flexible way. Different values for width and height + should be easily adjustable. With respect to random + placement of characters these values should be accessible by + other methods as well. Thus having just integer literals in + a constructor call is not appropriate.</para> - <para>Hints:</para> + <para>Action: Define these parameters as class level + variables.</para> + </callout> - <orderedlist> - <listitem> - <para>Store strings among with corresponding hash code - values in two separate arrays. You may use the - <quote>amortized doubling</quote> strategy from <xref - linkend="sd1IntStoreUnbounded"/> to accommodate arbitrary - numbers of instances.</para> - </listitem> + <callout arearefs="sd1CrabworldInitDeficiencies-2-co" + xml:id="sd1CrabworldInitDeficiencies-2"> + <para>Our animals will always start at the same initial + position (300, 300). Playing this game frequently should + allow for random placement.</para> - <listitem> - <para>On lookup use hash code values prior to comparing via - <methodname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#equals-java.lang.Object-">equals()</methodname> - in order to gain performance.</para> - </listitem> - </orderedlist> + <para>Action: Use <productname>Greenfoot</productname>.<link + xlink:href="http://www.greenfoot.org/files/javadoc/greenfoot/Greenfoot.html#getRandomNumber(int)">getRandomNumber(int)</link> + to place the crab at random positions.</para> + </callout> - <para>Write appropriate tests to assure a sound - implementation.</para> - </question> + <callout arearefs="sd1CrabworldInitDeficiencies-3-co" + xml:id="sd1CrabworldInitDeficiencies-3"> + <para>All animals initially move into the same direction. + This is due to their rotation angle being initialized to + zero. Thus each animal will move exactly to the right when + starting the game.</para> - <answer> - <annotation role="make"> - <para - role="eclipse">P/CollectionImplement/StringSet/Solution</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> + <para>Action: Randomly initialize all moving animals' + initial walking directions.</para> + </callout> - <chapter xml:id="sd1Map1"> - <title>Collections: Maps I</title> + <callout arearefs="sd1CrabworldInitDeficiencies-4-co" + xml:id="sd1CrabworldInitDeficiencies-4"> + <para>All animals are being positioned at fixed positions + making our game a little boring.</para> - <section xml:id="sd1MapPrepare"> - <title>Preparations</title> + <para>Action: Rather then positioning lobsters and worms one + by one use two different for-loops instead. Inside each loop + randomly position each animal:</para> - <para>Read the introduction on <link - xlink:href="http://tutorials.jenkov.com/java-collections/map.html">Java - Collections - Map</link> and <link xlink:href="???">Java Collections - - SortedMap</link>.</para> + <programlisting language="java">for (...) { + <emphasis role="bold">// Create all desired worms</emphasis> +} - <para>Consider the following array of person names:</para> +for (...) { + <emphasis role="bold">// Create all desired lobsters</emphasis> +}</programlisting> - <figure xml:id="sd1ArrayPersons"> - <title>An array of strings</title> + <para>Use class variables to define the number of animals to + be created.</para> + </callout> + </calloutlist> + </question> - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/array.fig"/> - </imageobject> - </mediaobject> - </figure> + <answer> + <orderedlist> + <listitem> + <para>We define two variables <emphasis + role="bold">worldWidth</emphasis> , <emphasis + role="bold">worldHeight</emphasis> and make them replace the + integer literal values inside our default + constructor:</para> - <para>Consider the following array describing (non leap year) month - lengths:</para> + <programlisting language="java">public class CrabWorld extends World { - <figure xml:id="sd1MonthLength"> - <title>An associative array describing month lengths</title> + private final static int // Width and height of our + <emphasis role="bold">worldWidth</emphasis> = 700, // crab's world. + <emphasis role="bold">worldHeight</emphasis> = 560; +... - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/arrayAssoc.fig"/> - </imageobject> - </mediaobject> - </figure> - </section> + public CrabWorld() { + super(<emphasis role="bold">worldWidth</emphasis>, <emphasis role="bold">worldHeight</emphasis>, 1); + populateWorld(); + } ...</programlisting> + </listitem> - <section xml:id="sd1MapExercise"> - <title>Exercises</title> + <listitem> + <para>There are different ways to implement choosing + coordinates randomly. We take an intermediate step by + implementing two helper methods which create random x- and + y-coordinate values being valid with respect to our world's + boundaries:</para> - <para>In <xref linkend="sd1CollectionWordFrequencies"/> we created a - sorted set of words appearing in a text among with their respective - frequencies:</para> - - <programlisting language="none"> 6: Newton - 6: and - 5: Einstein - 3: Pascal - 3: found - 3: meter - 3: one - 3: to - 2: a -...</programlisting> + <programlisting language="java">public class CrabWorld extends World { - <para>Achieving this result relied on implementing a helper class - <classname - xlink:href="Ref/api/P/WordFrequency1/Solution/de/hdm_stuttgart/mi/sd1/textstat/WordFrequency.html">WordFrequency</classname> - grouping words and frequencies:</para> + private final static int // Width and height of our + worldWidth = 700, // crab's world. + worldHeight = 560; - <programlisting language="java">public class WordFrequency { /** - * The frequency of this word will be counted. + * @return A random c ranging from 0 to the worlds's width in pixel units + * - 1. A width of e.g. 100 sets the range to {0, 1,..., 99}. */ - public final String word; - private int frequency; -...</programlisting> + public static int getRandomX() { + return Greenfoot.getRandomNumber(worldWidth); + } + + /** + * @return A random number ranging from 0 to the worlds's height in pixel + * units - 1. A height of e.g. 70 sets the range to {0, 1,..., 69}. + */ + public static int getRandomY() { + return Greenfoot.getRandomNumber(worldHeight); + } ...</programlisting> - <para>A cleaner solution might conceive the above result output as a - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>>. - The set of words appearing in a text will be regarded as keys. The - frequencies of appearance are corresponding values:</para> + <para>Creating animals at random positions becomes fairly + easy:</para> - <informaltable border="1" width="40%"> - <tr> - <th colspan="2"><classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>></th> - </tr> + <programlisting language="java"> public void populateWorld() { + addObject(new Crab(), <emphasis role="bold">getRandomX()</emphasis>, <emphasis + role="bold">getRandomY()</emphasis>);...</programlisting> + </listitem> - <tr> - <th>Word (<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>)</th> + <listitem> + <para>In complete analogy we implement a random rotation + value generating method:</para> - <th>Frequency (<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>)</th> - </tr> + <programlisting language="java"> /** + * @return A random rotation within the range [0, 1, ..., 360[. + */ + public static int getRandomRotation() { + return Greenfoot.getRandomNumber(360); + }</programlisting> - <tr> - <td>Newton</td> + <para>We might create animals and set their rotation value + subsequently. Adding a non-default constructor appears to be + a cleaner approach:</para> - <td>6</td> - </tr> + <programlisting language="java">public class Crab extends Animal { - <tr> - <td>and</td> + // Common constructor code: Initialize a crab's two images, rotation ... + private void commonConstructor(int rotation) { + setRotation(rotation); + setImage(image1); + wormsEaten = 0; + } - <td>6</td> - </tr> + /** + * Create a crab. + */ + public Crab() { + commonConstructor(0); + } - <tr> - <td>Einstein</td> + public Crab(int rotation) { + commonConstructor(rotation); + }</programlisting> - <td>5</td> - </tr> + <para>We may now complete a crab's random placement with + random rotation value:</para> - <tr> - <td>Pascal</td> + <programlisting language="java"> public void populateWorld() { + addObject(new Crab(getRandomRotation()), getRandomX(), getRandomY());...</programlisting> + </listitem> - <td>3</td> - </tr> + <listitem> + <para>Creating and placing lobsters and worms randomly is + now a straightforward exercise:</para> - <tr> - <td>...</td> + <programlisting language="java">public class CrabWorld extends World { - <td>...</td> - </tr> - </informaltable> + private final static int + <emphasis role="bold">initialLobsterCount</emphasis> = 3, + <emphasis role="bold">initialWormCount</emphasis> = 10; +... - <qandaset defaultlabel="qanda" xml:id="sde1QandaWordFreqMap"> - <title>Implementing word frequencies by <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>> - instances.</title> + public void populateWorld() { + addObject(new Crab(getRandomRotation()), getRandomX(), getRandomY()); - <qandadiv> - <qandaentry> - <question> - <para>Re-implement <xref - linkend="sd1CollectionWordFrequencies"/> replacing your - <classname - xlink:href="Ref/api/P/WordFrequency1/Solution/de/hdm_stuttgart/mi/sd1/textstat/WordFrequency.html">WordFrequency</classname> - object by an instance of <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>>. - For the time being consider the output sorting order yet as - irrelevant.</para> - </question> + // Creating lobsters. + for (int i = 0; i < i<emphasis role="bold">nitialLobsterCount</emphasis>; i++) { + addObject(new Lobster(getRandomRotation()), getRandomX(), getRandomY()); + } + // Creating worms. + for (int i = 0; i < <emphasis role="bold">initialWormCount</emphasis>; i++) { + addObject(new Worm(), getRandomX(), getRandomY()); + } + } ...</programlisting> + </listitem> + </orderedlist> - <answer> <annotation role="make"> - <para role="eclipse">P/WordFrequency1/Solution</para> + <para role="eclipse">P/crab/V1</para> </annotation> </answer> </qandaentry> - </qandadiv> - </qandaset> - - <para>The subsequent exercise is considered to be optional with respect - to the final course's examination. It does however provide some deeper - insight into the subject of <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname> - instances.</para> - <qandaset defaultlabel="qanda" xml:id="sde1QandaWordFreqMapSortOrder"> - <title>Regain sorting capabilities.</title> - - <qandadiv> <qandaentry> <question> - <para>Refine <xref linkend="sde1QandaWordFreqMap"/> to sort your - output by word frequencies in the first place as you already did - in <xref linkend="sd1CollectionWordFrequencies"/>.</para> - - <para>Hint: Following the discussion in <quote - xlink:href="http://stackoverflow.com/questions/11647889/sorting-the-mapkey-value-in-descending-order-based-on-the-value">Sorting - the Map<Key,Value> in descending order based on the - value</quote> you may create a <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/List.html">List</classname><<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html">Entry</classname>(<<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>>> - from your <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Map.html">Map</classname><<classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/String.html">String</classname>, - <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname>> - instance on demand (i.e. when sorting). Then define an - appropriate <classname - xlink:href="http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Comparator</classname> - class to get this list sorted.</para> - </question> - - <answer> - <annotation role="make"> - <para role="eclipse">P/WordFrequency2/Solution</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </chapter> - - <chapter xml:id="sd1Map2"> - <title>Collections: Maps II</title> - - <figure xml:id="sd1FigTownsByCountry"> - <title>Grouping towns by country names</title> - - <mediaobject> - <imageobject> - <imagedata fileref="Ref/Fig/townsByCountry.fig"/> - </imageobject> - </mediaobject> - </figure> + <para>The current initialization code may produce the following + scenario:</para> - <section xml:id="sd1MapMarks"> - <title>Creating an overview of grades</title> + <informalfigure> + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Fig/stayclear.png"/> + </imageobject> + </mediaobject> + </informalfigure> - <para>Consider a text file representing a list of students among with - examination grades ranging from level <quote>A</quote> to - <quote>D</quote>:</para> + <para>This will leave a player with hardly any chance to escape. + So we'd like our lobsters to initially keep some distance from + our crab. Modify your code accordingly.</para> - <programlisting language="none">Tim Bone, D -Eve Thunder, A -Aaron King, B -Joan White, B -Mark Singer, C -Jane Simmonds, D -Ethan Clarke, C -Paula Beam, C</programlisting> + <para>Hint: Calculate the distance between a potential lobster's + position and the already existing crab. Exclude placements + whenever a lobster gets too close.</para> + </question> - <para>Duplicate names may appear.</para> + <answer> + <para>We may define a constant reflecting the minimal initial + distance between a lobster and a crab:</para> - <qandaset defaultlabel="qanda" xml:id="sd1QandaMarkFrequency"> - <title>Creating an overview of grades showing frequencies</title> + <programlisting language="java">public class CrabWorld extends World { - <qandadiv> - <qandaentry> - <question> - <para>Transform the preceding text file into an overview of - grades by aggregating the occurrences of marks. The current - example should lead to:</para> - - <programlisting language="none">Overview of marks: -A: 1 -B: 2 -C: 3 -D: 2</programlisting> - </question> + private final static int ... + + minimalLobsterCrabDistance = 100; // The minimal distance when starting the game. ...</programlisting> - <answer> - <annotation role="make"> - <para role="eclipse">P/Marks/Solution1</para> - </annotation> - </answer> - </qandaentry> - </qandadiv> - </qandaset> + <para>We may then modify our loop to exclude lobster coordinate + positions <coref linkend="sd1ListingExcludeLobsterCircle"/> + falling inside a circle of radius <emphasis + role="bold">minimalLobsterCrabDistance</emphasis> surrounding + our crab:</para> - <qandaset defaultlabel="qanda" xml:id="sd1QandaMarkNames"> - <title>Creating an overview of grades showing individual names</title> + <programlisting language="java"> public void populateWorld() { + + final int crabX = getRandomX(), // Our crab's initial (x|y) coordinates are + crabY = getRandomY(); // needed for later calculations, see below. + + <emphasis role="bold">// Create our crab.</emphasis> + addObject(new Crab(getRandomRotation()), crabX, crabY); - <qandadiv> - <qandaentry> - <question> - <para>Replace the mark frequencies by the actual list of - alphabetically sorted names. The current example should lead - to:</para> - - <programlisting language="none">Overview of marks: -A: Eve Thunder -B: Aaron King, Joan White -C: Ethan Clarke, Mark Singer, Paula Beam -D: Jane Simmonds, Tim Bone</programlisting> - </question> + <emphasis role="bold">// Creating lobsters.</emphasis> + int numLobsters = 0; + while (numLobsters < initialLobsterCount) { // We use a while loop instead of for since + // numLobsters gets incremented condionally. + + final int lobsterX = getRandomX(), // <emphasis role="bold">Potential</emphasis> lobster's position + lobsterY = getRandomY(), // at (lobsterX|lobsterY). + deltaX = lobsterX - crabX, + deltaY = lobsterY - crabY; + + // Pythagoras is talking to us. Do you listen? If you can't hear him, take a pencil + // and a sheet of paper to sketch the problem's geometry. + // + // We only add a lobster at coordinate position (lobsterX|lobsterY) if + // its distance to our crab is sufficiently large. + // + if (<emphasis role="bold">minimalLobsterCrabDistance * minimalLobsterCrabDistance <</emphasis> <co + xml:id="sd1ListingExcludeLobsterCircle"/> // Distance between lobster and crab is + <emphasis role="bold">deltaX * deltaX + deltaY * deltaY</emphasis>) { // larger than minimalLobsterCrabDistance. + addObject(new Lobster(getRandomRotation()), lobsterX, lobsterY); + numLobsters++; + } + } + + <emphasis role="bold">// Creating worms. Easy: No conditions apply.</emphasis> + for (int i = 0; i < initialWormCount; i++) { + addObject(new Worm(), getRandomX(), getRandomY()); + } + }</programlisting> - <answer> - <annotation role="make"> - <para role="eclipse">P/Marks/Solution2</para> - </annotation> + <para>Full <command>Javadoc</command> including source code is + <link + xlink:href="Ref/api/P/crab/V2/package-summary.html">available + here</link>.</para> </answer> </qandaentry> </qandadiv> </qandaset> </section> </chapter> - - <xi:include href="../glossary.xml" xpointer="element(/1)"/> - - <xi:include href="../bibliography.xml" xpointer="element(/1)"/> </part> diff --git a/ws/Docbook/Extensions/Tdata/fig.xml b/ws/Docbook/Extensions/Tdata/fig.xml index ee3d40d6eb59114a12256ae0c912fc4ace1ad20e..996514dc4086ebda512d988ba86a620af2dc0717 100644 --- a/ws/Docbook/Extensions/Tdata/fig.xml +++ b/ws/Docbook/Extensions/Tdata/fig.xml @@ -25,7 +25,7 @@ <para>Some sql code:</para> - <programlisting>SELECT * FROM Table + <programlisting language="none">SELECT * FROM Table