From ff8bef52497674c7390611937b2f9acc96baf145 Mon Sep 17 00:00:00 2001 From: Martin Goik <goik@hdm-stuttgart.de> Date: Thu, 5 Feb 2015 23:44:47 +0100 Subject: [PATCH] Moving loads of files --- .../Common/bibliography.xml | 0 glossary.xml => Doc/Common/glossary.xml | 0 {Sd1 => Doc/Sd1}/Ref/Fig/Makefile | 0 {Sd1 => Doc/Sd1}/Ref/Fig/account.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/addressHtml.png | Bin {Sd1 => Doc/Sd1}/Ref/Fig/array.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/arrayAssoc.fig | 0 .../Sd1}/Ref/Fig/directionGeometry.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/gameOfLifeWorld.png | Bin {Sd1 => Doc/Sd1}/Ref/Fig/getAverageSpeed.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/person.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/pre.tex | 0 {Sd1 => Doc/Sd1}/Ref/Fig/returnTypeInt.dia | Bin {Sd1 => Doc/Sd1}/Ref/Fig/returnValue.fig | 0 .../Sd1}/Ref/Fig/runconfigDefineArgs.png | Bin .../Ref/Fig/runconfigMavenGoalPackage.png | Bin .../Sd1}/Ref/Fig/runconfigSelectClass.png | Bin {Sd1 => Doc/Sd1}/Ref/Fig/setDirection.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/stayclear.png | Bin {Sd1 => Doc/Sd1}/Ref/Fig/svgGeometry.png | Bin {Sd1 => Doc/Sd1}/Ref/Fig/townsByCountry.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/turnLeft.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/turningStates.fig | 0 {Sd1 => Doc/Sd1}/Ref/Fig/wombatDirection.png | Bin .../Screen/EclipseConfig/windowsCmdJdkJre.png | Bin {Sd1 => Doc/Sd1}/Ref/Screen/sinPlot.png | Bin {Sd1 => Doc/Sd1}/Ref/Svg/exception.svg | 0 {Sd1 => Doc/Sd1}/Ref/Svg/hashing.svg | 0 {Sd1 => Doc/Sd1}/Ref/Svg/mavenPrjRef.svg | 0 Doc/Sd1/array.xml | 1477 +++ Doc/Sd1/class.xml | 925 ++ Doc/Sd1/collections.xml | 1584 ++++ Doc/Sd1/deployment.xml | 418 + Doc/Sd1/identity.xml | 203 + Doc/Sd1/loop.xml | 2362 +++++ Doc/Sd1/preliminaries.xml | 230 + Doc/Sd1/streams.xml | 373 + {Sda1 => Doc/Sda1}/Etest/Doodle/.project | 0 {Sda1 => Doc/Sda1}/Etest/Doodle/data.xml | 0 {Sda1 => Doc/Sda1}/Etest/Doodle/doodle.png | Bin {Sda1 => Doc/Sda1}/Etest/Doodle/doodle.xsd | 0 .../Sda1}/Etest/JdomTable/exercise.xhtml | 0 .../Etest/JdomTable/jdomtable/.gitignore | 0 .../Etest/JdomTable/jdomtable/pom.exam.xml | 0 .../Sda1}/Etest/JdomTable/jdomtable/pom.xml | 0 .../sda1/jdom/background/RowHighlighting.java | 0 .../jdom/background/TableRowColumnSwitch.java | 0 .../jdomtable/src/main/resources/.gitignore | 0 .../jdomtable/src/main/resources/log4j2.xml | 0 .../jdomtable/src/main/resources/persons.xml | 0 .../persons.xml.highlight.expected.html | 0 .../persons.xml.switch.expected.html | 0 .../JdomTable/jdomtable_solution/.gitignore | 0 .../JdomTable/jdomtable_solution/build.sh | 0 .../JdomTable/jdomtable_solution/pom.xml | 0 .../sda1/jdom/background/RowHighlighting.java | 0 .../jdom/background/TableRowColumnSwitch.java | 0 .../src/main/resources/.gitignore | 0 .../src/main/resources/log4j2.xml | 0 .../src/main/resources/persons.xml | 0 .../domhtml/test/TestRowHighlighting.java | 0 .../test/TestTableRowColumnSwitch.java | 0 .../Etest/RdbmsStudents2xml/exercise1.xhtml | 0 .../Etest/RdbmsStudents2xml/exercise2.xhtml | 0 .../rdbmsStudents2xml/.gitignore | 0 .../rdbmsStudents2xml/Schema/schema.sql | 0 .../rdbmsStudents2xml/Schema/testdata.xml | 0 .../rdbmsStudents2xml/Schema/university.xsd | 0 .../rdbmsStudents2xml/pom.xml | 0 .../mi/sda1/sql2catalog/Helper.java | 0 .../mi/sda1/sql2catalog/Rdbms2Xml.java | 0 .../mi/sda1/sql2catalog/RdbmsAccess.java | 0 .../src/main/resources/log4j2.xml | 0 .../rdbmsStudents2xml_solution/.gitignore | 0 .../Schema/schema.sql | 0 .../Schema/testdata.xml | 0 .../Schema/university.xsd | 0 .../rdbmsStudents2xml_solution/pom.xml | 0 .../mi/sda1/sql2catalog/Helper.java | 0 .../mi/sda1/sql2catalog/Messages.java | 0 .../mi/sda1/sql2catalog/Rdbms2Xml.java | 0 .../mi/sda1/sql2catalog/RdbmsAccess.java | 0 .../mi/sda1/sql2catalog/messages.properties | 0 .../src/main/resources/log4j2.xml | 0 .../SaxMemo2Html/SaxMemo2Hhtml/.gitignore | 0 .../SaxMemo2Html/SaxMemo2Hhtml/pom.exam.xml | 0 .../Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.xml | 0 .../mi/sda1/saxhtml/v1/Memo2HtmlHandler.java | 0 .../mi/sda1/saxhtml/v2/Memo2HtmlHandler.java | 0 .../src/main/resources/.gitignore | 0 .../src/main/resources/log4j2.xml | 0 .../SaxMemo2Hhtml/src/main/resources/memo.xml | 0 .../main/resources/memo.xml.1.expected.html | 0 .../main/resources/memo.xml.2.expected.html | 0 .../SaxMemo2Hhtml_solution/.gitignore | 0 .../SaxMemo2Hhtml_solution/build.sh | 0 .../SaxMemo2Hhtml_solution/pom.xml | 0 .../mi/sda1/saxhtml/v1/Memo2HtmlHandler.java | 0 .../mi/sda1/saxhtml/v2/Memo2HtmlHandler.java | 0 .../src/main/resources/.gitignore | 0 .../src/main/resources/log4j2.xml | 0 .../src/main/resources/memo.xml | 0 .../v1/test/TestSimpleSaxTransform.java | 0 .../v2/test/TestComplexSaxTransform.java | 0 .../Sda1}/Etest/SaxMemo2Html/exercise1.xhtml | 0 .../Etest/XmlSchema2RdbmsSchema/.project | 0 .../Etest/XmlSchema2RdbmsSchema/address.xsd | 0 .../XmlSchema2RdbmsSchema/exercise.xhtml | 0 .../XmlSchema2RdbmsSchema/sampleData.xml | 0 .../Etest/XmlSchema2RdbmsSchema/schema.sql | 0 .../Sda1}/Etest/Xslt1/Xml2xml/.project | 0 .../Sda1}/Etest/Xslt1/Xml2xml/person.xsd | 0 .../Sda1}/Etest/Xslt1/Xml2xml/person2user.xsl | 0 .../Etest/Xslt1/Xml2xml/person2userTest.xspec | 0 .../Sda1}/Etest/Xslt1/Xml2xml/personData.xml | 0 .../Sda1}/Etest/Xslt1/Xml2xml/user.xsd | 0 .../Sda1}/Etest/Xslt1/Xml2xml/userData.xml | 0 .../Etest/Xslt1/Xml2xml_Solution/.gitignore | 0 .../Etest/Xslt1/Xml2xml_Solution/.project | 0 .../Etest/Xslt1/Xml2xml_Solution/person.xsd | 0 .../Xslt1/Xml2xml_Solution/person2user.xsl | 0 .../Xml2xml_Solution/person2userTest.xspec | 0 .../Xslt1/Xml2xml_Solution/personData.xml | 0 .../Etest/Xslt1/Xml2xml_Solution/user.xsd | 0 .../Etest/Xslt1/Xml2xml_Solution/userData.xml | 0 {Sda1 => Doc/Sda1}/Etest/Xslt1/user.xhtml | 0 .../Sda1}/Etest/Xslt1/userSolution.xhtml | 0 .../Sda1}/Etest/Xslt2/Book2Html/.project | 0 .../Etest/Xslt2/Book2Html/Book1/.gitignore | 0 .../Etest/Xslt2/Book2Html/Book1/book1.xsd | 0 .../Xslt2/Book2Html/Book1/book1Test.xspec | 0 .../Xslt2/Book2Html/Book1/book1ToHtml.xsl | 0 .../Book2Html/Book1/work1.reference.html | 0 .../Etest/Xslt2/Book2Html/Book1/work1.xml | 0 .../Etest/Xslt2/Book2Html/Book2/.gitignore | 0 .../Etest/Xslt2/Book2Html/Book2/book2.xsd | 0 .../Xslt2/Book2Html/Book2/book2Test.xspec | 0 .../Xslt2/Book2Html/Book2/book2ToHtml.xsl | 0 .../Book2Html/Book2/work2.reference.html | 0 .../Etest/Xslt2/Book2Html/Book2/work2.xml | 0 .../Etest/Xslt2/Book2Html_Solution/.project | 0 .../Xslt2/Book2Html_Solution/Book1/.gitignore | 0 .../Book2Html_Solution/Book1/book1ToHtml.xsl | 0 .../Xslt2/Book2Html_Solution/Book2/.gitignore | 0 .../Book2Html_Solution/Book2/book2ToHtml.xsl | 0 .../Sda1}/Etest/Xslt2/exercise1.xhtml | 0 .../Sda1}/Etest/Xslt2/exercise2.xhtml | 0 {Sda1 => Doc/Sda1}/Etest/solutions.html | 0 {Sda1 => Doc/Sda1}/Ref/Fig/Makefile | 0 .../Sda1}/Ref/Fig/attribInElement.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/attributes.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/blockprop.fo.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/booknavigate.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/clientserv.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/contentmixed.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/cpp.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/crossmedia.fig | 0 .../Sda1}/Ref/Fig/dictionary.1.fo.eps | 0 .../Sda1}/Ref/Fig/dictionary.2.fo.eps | 0 .../Sda1}/Ref/Fig/dictionaryStack.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/domtree.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/entityresolve.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/externalize.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/filtering.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/firefoxrender.png | Bin {Sda1 => Doc/Sda1}/Ref/Fig/hacker.jpg | Bin {Sda1 => Doc/Sda1}/Ref/Fig/headfoot.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/heartland.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/impropernest.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/invoicedata.fig | 0 .../Sda1}/Ref/Fig/invoicedataimplement.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/itemize.fo.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/jdbcFourTier.fig | 0 .../Sda1}/Ref/Fig/jdbcObjectRelation.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/jdbcReadWrite.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/jdbcSniffing.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/jdbcThreeTier.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/jdbcarch.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/jdbcread.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/jdbcurl.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/leader.fo.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/leadermulti.fo.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/memofour.fig | 0 .../Sda1}/Ref/Fig/memorelativexpath.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/memotree.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/memoxpath.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/nodeHierarchy.svg | 0 {Sda1 => Doc/Sda1}/Ref/Fig/overlay.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.1.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.2.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.3.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.4.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/pageStack.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/pageref.1.fo.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/pageref.2.fo.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/pagerefStack.fig | 0 .../Sda1}/Ref/Fig/pagerefhyper.1.fo.eps | 0 .../Sda1}/Ref/Fig/pagerefhyper.2.fo.eps | 0 .../Sda1}/Ref/Fig/pagerefhyperStack.fig | 0 .../Sda1}/Ref/Fig/persistHandlerStates.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/persistence.fig | 0 .../Sda1}/Ref/Fig/persistentStates.fig | 0 .../Sda1}/Ref/Fig/pitr_Syringe_icon.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/pre.tex | 0 {Sda1 => Doc/Sda1}/Ref/Fig/preceding.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/propernest.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/regions.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/saxapparch.odg | Bin {Sda1 => Doc/Sda1}/Ref/Fig/saxapparch.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/saxcharacter.odg | Bin {Sda1 => Doc/Sda1}/Ref/Fig/saxcharacter.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/saxmodel.odg | Bin {Sda1 => Doc/Sda1}/Ref/Fig/saxmodel.pdf | Bin {Sda1 => Doc/Sda1}/Ref/Fig/saxxmlrdbms.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/separate.fo.pdf | Bin .../Sda1}/Ref/Fig/sequenceDomParser.svg | 0 {Sda1 => Doc/Sda1}/Ref/Fig/skull.eps | 0 {Sda1 => Doc/Sda1}/Ref/Fig/sqlTransport.fig | 0 .../Sda1}/Ref/Fig/sqlTransportPrepare.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/sqlinject.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/sqrtree.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/sqrtrender.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/updateinfo.fig | 0 .../Sda1}/Ref/Fig/wellformedandvalid.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xhtml.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xhtmlexample.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xml2fo2pdf.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xml2html.fig | 0 .../Sda1}/Ref/Fig/xmlattribandjava.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xmlbase.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xpath.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xsl_id.fig | 0 {Sda1 => Doc/Sda1}/Ref/Fig/xslconvert.fig | 0 .../Ref/Screen/dom-architecture.screen.png | Bin .../Ref/Screen/eclipseTestngResult.screen.png | Bin {Sda1 => Doc/Sda1}/Ref/Screen/employee.png | Bin .../Sda1}/Ref/Screen/externalize.screen.png | Bin .../Sda1}/Ref/Screen/externalize2.screen.png | Bin .../Sda1}/Ref/Screen/hello.screen.png | Bin .../Ref/Screen/insertValidate.screen.png | Bin .../Sda1}/Ref/Screen/login.screen.png | Bin {Sda1 => Doc/Sda1}/Ref/Screen/mediaFormat.png | Bin .../Ref/Screen/mozparaspancss.screen.png | Bin .../Sda1}/Ref/Screen/pdfbookmarks.screen.png | Bin .../Ref/Screen/runConfigJarAnnot.screen.png | Bin .../Ref/Screen/simpleInsertGui.screen.png | Bin .../Sda1}/Ref/Screen/sqlInject.screen.png | Bin .../Ref/Screen/sqlInjectPrepare.screen.png | Bin {Sda1 => Doc/Sda1}/Ref/Screen/track.png | Bin {Sda1 => Doc/Sda1}/Ref/Video/Makefile | 0 {Sda1 => Doc/Sda1}/Ref/Video/connectauth.mp4 | Bin {Sda1 => Doc/Sda1}/Ref/Video/dataInsert.mp4 | Bin {Sda1 => Doc/Sda1}/Ref/Video/dataInsert.txt | 0 .../Sda1}/Ref/Video/eclipseBasicSql.mp4 | Bin .../Sda1}/Ref/Video/eclipseBasicSql.txt | 0 .../Sda1}/Ref/Video/hibernateConfig.mp4 | Bin .../Sda1}/Ref/Video/hibernateConfig.txt | 0 .../Sda1}/Ref/Video/jdbcConnection.mp4 | Bin .../Sda1}/Ref/Video/jdbcConnection.txt | 0 .../Sda1}/Ref/Video/jdbcDriverConfig.mp4 | Bin .../Sda1}/Ref/Video/jdbcDriverConfig.txt | 0 .../Sda1}/Ref/src/Dom/catalog2fo.final.xsl | 0 .../Sda1}/Ref/src/Dom/catalog2fo.product.xsl | 0 .../Sda1}/Ref/src/Dom/catalog2fo.start.xsl | 0 .../Sda1}/Ref/src/Dom/catalog2fo.toc.xsl | 0 .../Sda1}/Ref/src/Dom/catalog2fo.toclink.xsl | 0 .../Sda1}/Ref/src/Dom/climbenriched.final.pdf | Bin .../Ref/src/Dom/climbenriched.product.pdf | Bin .../Sda1}/Ref/src/Dom/climbenriched.start.pdf | Bin .../Sda1}/Ref/src/Dom/climbenriched.toc.pdf | Bin .../Ref/src/Dom/climbenriched.toclink.pdf | Bin .../Sda1}/Ref/src/Dtd/book/v5/book.xsd | 0 .../Ref/src/Dtd/book/v5/book2chunks.1.xsl | 0 .../Sda1}/Ref/src/Dtd/book/v5/book2html.1.xsl | 0 .../Sda1}/Ref/src/Dtd/book/v5/chap1.xml | 0 .../Sda1}/Ref/src/Dtd/book/v5/chap2.xml | 0 .../Sda1}/Ref/src/Dtd/book/v5/java.xml | 0 .../Sda1}/Ref/src/Dtd/book/v5/master.xml | 0 .../Sda1}/Ref/src/Dtd/book/v5/table.xsd | 0 {Sda1 => Doc/Sda1}/Ref/src/Memo.1/memo.xsd | 0 {Sda1 => Doc/Sda1}/Ref/src/Memo.1/message.xml | 0 {Sda1 => Doc/Sda1}/Ref/src/sorttable.js | 0 {Sda1 => Doc/Sda1}/Ref/src/tablesort.html | 0 {Sda1 => Doc/Sda1}/dom.xml | 0 {Sda1 => Doc/Sda1}/fo.xml | 0 {Sda1 => Doc/Sda1}/jdbc.xml | 0 {Sda1 => Doc/Sda1}/prerequisites.xml | 0 {Sda1 => Doc/Sda1}/sax.xml | 0 {Sda1 => Doc/Sda1}/schema.xml | 0 {Sda1 => Doc/Sda1}/testng.xml | 0 {Sda1 => Doc/Sda1}/try.xml | 0 {Sda1 => Doc/Sda1}/xmlintro.xml | 0 {Sda1 => Doc/Sda1}/xmlschema.xml | 0 {Sda1 => Doc/Sda1}/xslt.xml | 0 {Sda2 => Doc/Sda2}/Ref/Fig/Makefile | 0 {Sda2 => Doc/Sda2}/Ref/Fig/billing.fig | 0 {Sda2 => Doc/Sda2}/Ref/Fig/billingData.fig | 0 .../Sda2}/Ref/Fig/billingMapJoined.fig | 0 {Sda2 => Doc/Sda2}/Ref/Fig/billingSql.fig | 0 {Sda2 => Doc/Sda2}/Ref/Fig/classUser.fig | 0 .../Sda2}/Ref/Fig/concurrentOptimistic.svg | 0 .../Ref/Fig/concurrentOptimisticFail.svg | 0 {Sda2 => Doc/Sda2}/Ref/Fig/figureInherit.fig | 0 {Sda2 => Doc/Sda2}/Ref/Fig/jaxRs.svg | 0 {Sda2 => Doc/Sda2}/Ref/Fig/jpacache.svg | 0 {Sda2 => Doc/Sda2}/Ref/Fig/mapInherit.svg | 0 {Sda2 => Doc/Sda2}/Ref/Fig/mapUser.fig | 0 .../Sda2}/Ref/Fig/mapUserIntegrity.fig | 0 {Sda2 => Doc/Sda2}/Ref/Fig/mavenIntro.fig | 0 .../Sda2}/Ref/Fig/persistProvider.fig | 0 {Sda2 => Doc/Sda2}/Ref/Fig/pre.tex | 0 {Sda2 => Doc/Sda2}/Ref/Fig/transitiveDep.fig | 0 .../Sda2}/Ref/Screen/CreateMaven/1.png | Bin .../Sda2}/Ref/Screen/CreateMaven/2.png | Bin .../Sda2}/Ref/Screen/CreateMaven/3.png | Bin .../Sda2}/Ref/Screen/CreateMaven/4.png | Bin .../Sda2}/Ref/Screen/CreateMaven/5.png | Bin .../Sda2}/Ref/Screen/CreateMaven/6.png | Bin .../Sda2}/Ref/Screen/CreateMaven/mysql1.png | Bin .../Sda2}/Ref/Screen/CreateMaven/mysql2.png | Bin .../Sda2}/Ref/Screen/CreateMaven/mysql3.png | Bin .../Sda2}/Ref/Screen/CreateMaven/mysql4.png | Bin .../Sda2}/Ref/Screen/CreateMaven/mysql5.png | Bin .../Sda2}/Ref/Screen/accountTransferSum.png | Bin .../Sda2}/Ref/Screen/ldapSampleUsers.png | Bin Doc/Sda2/jax-rs.xml | 15 + Sda2/sda2.xml => Doc/Sda2/jpa.xml | 801 +- Doc/Sda2/ldap.xml | 769 ++ Doc/Sda2/sda2.xml | 30 + lectures.xml => Doc/lectures.xml | 31 +- {Sda2/P => P/Sda2}/JaxRs/Intro/.gitignore | 0 {Sda2/P => P/Sda2}/JaxRs/Intro/README.md | 0 {Sda2/P => P/Sda2}/JaxRs/Intro/pom.xml | 0 .../com/restfully/shop/domain/Customer.java | 0 .../restfully/shop/helper/PrettyPrint.java | 0 .../shop/helper/PrettyPrintProcessor.java | 0 .../shop/services/CustomerResource.java | 0 .../shop/services/ShoppingApplication.java | 0 .../hdm_stuttgart/mi/sda2/DeleteCustomer.java | 0 .../de/hdm_stuttgart/mi/sda2/MyClient.java | 0 .../Intro/src/main/webapp/WEB-INF/web.xml | 0 .../src/main/webapp/static/customer2html.xsl | 0 .../shop/test/CustomerResourceTest.java | 0 {Sda2/P => P/Sda2}/Jpa/Cd/.gitignore | 0 {Sda2/P => P/Sda2}/Jpa/Cd/Schema/cd.xsd | 0 {Sda2/P => P/Sda2}/Jpa/Cd/Schema/generate.sh | 0 {Sda2/P => P/Sda2}/Jpa/Cd/cdData.xml | 0 {Sda2/P => P/Sda2}/Jpa/Cd/pom.xml | 0 .../hdm_stuttgart/mi/sda2/jpa/cd/Driver.java | 0 .../mi/sda2/jpa/cd/domain/Catalog.java | 0 .../mi/sda2/jpa/cd/domain/Cd.java | 0 .../mi/sda2/jpa/cd/domain/ObjectFactory.java | 0 .../main/resources/META-INF/persistence.xml | 0 .../Jpa/Cd/src/main/resources/log4j2.xml | 0 .../hdm_stuttgart/mi/sda2/jpa/cd/AppTest.java | 0 .../Sda2}/Jpa/HibernateCacheDemo/.gitignore | 0 .../Sda2}/Jpa/HibernateCacheDemo/pom.xml | 0 .../mi/sda2/ehcache/JpaTest.java | 0 .../mi/sda2/ehcache/domain/Department.java | 0 .../mi/sda2/ehcache/domain/Employee.java | 0 .../main/resources/META-INF/persistence.xml | 0 .../src/main/resources/ehcache.xml | 0 .../src/main/resources/ehcache.xsd | 0 .../src/main/resources/log4j.properties | 0 .../P => P/Sda2}/Jpa/Inherit/Tpch/.gitignore | 0 {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/pom.xml | 0 .../mi/sda2/jpa/billing/CreateData.java | 0 .../mi/sda2/jpa/billing/ReadData.java | 0 .../sda2/jpa/billing/domain/BankAccount.java | 0 .../jpa/billing/domain/BillingDetail.java | 0 .../sda2/jpa/billing/domain/CreditCard.java | 0 .../mi/sda2/jpa/billing/domain/Customer.java | 0 .../main/resources/META-INF/persistence.xml | 0 .../Tpch/src/main/resources/log4j2.xml | 0 {Sda2/P => P/Sda2}/Jpa/University/.gitignore | 0 {Sda2/P => P/Sda2}/Jpa/University/pom.xml | 0 .../mi/sda2/jpa/cd/domain/Lecture.java | 0 .../mi/sda2/jpa/cd/domain/Student.java | 0 .../mi/sda2/jpa/cd/domain/StudentLecture.java | 0 .../mi/sda2/jpa/university/Driver.java | 0 .../main/resources/META-INF/persistence.xml | 0 .../University/src/main/resources/log4j2.xml | 0 .../mi/sda2/jpa/university/AppTest.java | 0 {Sda2/P => P/Sda2}/Register/.gitignore | 0 {Sda2/P => P/Sda2}/Register/Schema/schema.sql | 0 {Sda2/P => P/Sda2}/Register/pom.xml | 0 .../de/hdm_stuttgart/mi/AppWidgetSet.gwt.xml | 0 .../java/de/hdm_stuttgart/mi/MyLogin.java | 0 .../java/de/hdm_stuttgart/mi/MyVaadinUI.java | 0 .../java/de/hdm_stuttgart/mi/NavigatorUI.java | 0 .../java/de/hdm_stuttgart/mi/Register.java | 0 .../de/hdm_stuttgart/mi/entities/User.java | 0 .../mi/tools/MyBeanFieldGroup.java | 0 .../mi/tools/ValidateGlobal.java | 0 .../tools/ValidateSecondIdenticalInput.java | 0 .../src/main/webapp/META-INF/MANIFEST.MF | 0 .../src/main/webapp/META-INF/context.xml | 0 .../webapp/VAADIN/themes/mytheme/addons.scss | 0 .../webapp/VAADIN/themes/mytheme/favicon.ico | Bin .../webapp/VAADIN/themes/mytheme/mytheme.scss | 0 .../webapp/VAADIN/themes/mytheme/styles.scss | 0 .../UnixSqlLdap/Jndi/Rdbms2Ldap/.gitignore | 0 .../Jndi/Rdbms2Ldap/Schema/schema.ldif | 0 .../Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/pom.xml | 0 .../mi/sda2/rdbms2ldap/Config.java | 0 .../mi/sda2/rdbms2ldap/Driver.java | 0 .../mi/sda2/rdbms2ldap/ldap/LdapHandler.java | 0 .../sda2/rdbms2ldap/rdbms/RdbmsHandler.java | 0 .../mi/sda2/rdbms2ldap/ldap.properties | 0 .../Rdbms2Ldap/src/main/resources/log4j2.xml | 0 .../mi/sda2/rdbms2ldap/AppTest.java | 0 .../UnixSqlLdap/Jndi/Unix2Rdbms/.gitignore | 0 .../Jndi/Unix2Rdbms/Schema/divers.sql | 0 .../Jndi/Unix2Rdbms/Schema/schema.sql | 0 .../Jndi/Unix2Rdbms/Testdata/group | 0 .../Jndi/Unix2Rdbms/Testdata/passwd | 0 .../Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/pom.xml | 0 .../hdm_stuttgart/mi/sda2/usermanage/Cfg.java | 0 .../mi/sda2/usermanage/Driver.java | 0 .../mi/sda2/usermanage/parse/Group.java | 0 .../mi/sda2/usermanage/parse/ParseError.java | 0 .../mi/sda2/usermanage/parse/Parser.java | 0 .../mi/sda2/usermanage/parse/User.java | 0 .../sda2/usermanage/rdbms/DatabaseObject.java | 0 .../mi/sda2/usermanage/rdbms/GroupParam.java | 0 .../sda2/usermanage/rdbms/MyNamedQuery.java | 0 .../rdbms/NamedParameterStatement.java | 0 .../mi/sda2/usermanage/rdbms/Param.java | 0 .../sda2/usermanage/rdbms/RdbmsHandler.java | 0 .../sda2/usermanage/rdbms/UserGroupParam.java | 0 .../mi/sda2/usermanage/rdbms/UserParam.java | 0 .../mi/sda2/usermanage/jdbc.properties | 0 .../src/main/resources/log4j.properties | 0 .../mi/sda2/usermanage/UserTest.java | 0 {Sda2/P => P/Sda2}/account/.gitignore | 0 {Sda2/P => P/Sda2}/account/Sql/schema.sql | 0 {Sda2/P => P/Sda2}/account/pom.xml | 0 .../hdm_stuttgart/mi/sda2/account/Conf.java | 0 .../mi/sda2/account/SumDriver.java | 0 .../mi/sda2/account/TransferDriver.java | 0 .../mi/sda2/account/gui/ExceptionDialog.java | 0 .../mi/sda2/account/gui/NumberField.java | 0 .../mi/sda2/account/sql/DbHandler.java | 0 .../mi/sda2/account/jdbc.properties | 0 .../src/main/resources/log4j.properties | 0 .../hdm_stuttgart/mi/sda2/account/DbTest.java | 0 {Sda2/P => P/Sda2}/forum_1/.gitignore | 0 {Sda2/P => P/Sda2}/forum_1/Schema/schema.sql | 0 {Sda2/P => P/Sda2}/forum_1/_Readme.first | 0 {Sda2/P => P/Sda2}/forum_1/pom.xml | 0 .../mi/sda2/forum/AppWidgetSet.gwt.xml | 0 .../de/hdm_stuttgart/mi/sda2/forum/Main.java | 0 .../hdm_stuttgart/mi/sda2/forum/MyLogin.java | 0 .../mi/sda2/forum/NavigatorUI.java | 0 .../hdm_stuttgart/mi/sda2/forum/Register.java | 0 .../mi/sda2/forum/domain/.gitignore | 0 .../mi/sda2/forum/domain/Forum.java | 0 .../mi/sda2/forum/domain/Subscription.java | 0 .../mi/sda2/forum/domain/User.java | 0 .../sda2/forum/domain/UserForumAssocId.java | 0 .../mi/sda2/forum/tools/Credential.java | 0 .../mi/sda2/forum/tools/HashProvider.java | 0 .../mi/sda2/forum/tools/MyBeanFieldGroup.java | 0 .../sda2/forum/tools/PersistenceHelper.java | 0 .../mi/sda2/forum/tools/ValidateGlobal.java | 0 .../tools/ValidateSecondIdenticalInput.java | 0 .../main/resources/META-INF/persistence.xml | 0 .../src/main/webapp/META-INF/MANIFEST.MF | 0 .../src/main/webapp/META-INF/context.xml | 0 .../forum_1/src/main/webapp/VAADIN/.gitignore | 0 .../webapp/VAADIN/themes/mytheme/addons.scss | 0 .../webapp/VAADIN/themes/mytheme/favicon.ico | Bin .../webapp/VAADIN/themes/mytheme/mytheme.scss | 0 .../webapp/VAADIN/themes/mytheme/styles.css | 0 .../webapp/VAADIN/themes/mytheme/styles.scss | 0 .../mi/sda2/forum/TestDomain.java | 0 Sd1/lib/Greenfoot-core-2.5.jar | Bin 284901 -> 0 bytes Sd1/swd1.xml | 8370 +---------------- ws/Docbook/Extensions/Tdata/fig.xml | 2 +- 479 files changed, 8817 insertions(+), 8773 deletions(-) rename bibliography.xml => Doc/Common/bibliography.xml (100%) rename glossary.xml => Doc/Common/glossary.xml (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/Makefile (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/account.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/addressHtml.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/array.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/arrayAssoc.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/directionGeometry.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/gameOfLifeWorld.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/getAverageSpeed.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/person.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/pre.tex (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/returnTypeInt.dia (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/returnValue.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/runconfigDefineArgs.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/runconfigMavenGoalPackage.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/runconfigSelectClass.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/setDirection.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/stayclear.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/svgGeometry.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/townsByCountry.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/turnLeft.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/turningStates.fig (100%) rename {Sd1 => Doc/Sd1}/Ref/Fig/wombatDirection.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Screen/EclipseConfig/windowsCmdJdkJre.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Screen/sinPlot.png (100%) rename {Sd1 => Doc/Sd1}/Ref/Svg/exception.svg (100%) rename {Sd1 => Doc/Sd1}/Ref/Svg/hashing.svg (100%) rename {Sd1 => Doc/Sd1}/Ref/Svg/mavenPrjRef.svg (100%) create mode 100644 Doc/Sd1/array.xml create mode 100644 Doc/Sd1/class.xml create mode 100644 Doc/Sd1/collections.xml create mode 100644 Doc/Sd1/deployment.xml create mode 100644 Doc/Sd1/identity.xml create mode 100644 Doc/Sd1/loop.xml create mode 100644 Doc/Sd1/preliminaries.xml create mode 100644 Doc/Sd1/streams.xml rename {Sda1 => Doc/Sda1}/Etest/Doodle/.project (100%) rename {Sda1 => Doc/Sda1}/Etest/Doodle/data.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Doodle/doodle.png (100%) rename {Sda1 => Doc/Sda1}/Etest/Doodle/doodle.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/exercise.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/pom.exam.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/pom.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/resources/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/resources/log4j2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/resources/persons.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.highlight.expected.html (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable/src/main/resources/persons.xml.switch.expected.html (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/build.sh (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/pom.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/RowHighlighting.java (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/main/java/de/hdm_stuttgart/mi/sda1/jdom/background/TableRowColumnSwitch.java (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/main/resources/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/main/resources/log4j2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/main/resources/persons.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestRowHighlighting.java (100%) rename {Sda1 => Doc/Sda1}/Etest/JdomTable/jdomtable_solution/src/test/java/de/hdm_stuttgart/sda1/domhtml/test/TestTableRowColumnSwitch.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/exercise1.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/exercise2.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/schema.sql (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/testdata.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/Schema/university.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/pom.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml/src/main/resources/log4j2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/schema.sql (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/testdata.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/Schema/university.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/pom.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties (100%) rename {Sda1 => Doc/Sda1}/Etest/RdbmsStudents2xml/rdbmsStudents2xml_solution/src/main/resources/log4j2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.exam.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/pom.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/log4j2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.1.expected.html (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml/src/main/resources/memo.xml.2.expected.html (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/build.sh (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/pom.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/log4j2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/sda1/saxhtml/v2/test/TestComplexSaxTransform.java (100%) rename {Sda1 => Doc/Sda1}/Etest/SaxMemo2Html/exercise1.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/XmlSchema2RdbmsSchema/.project (100%) rename {Sda1 => Doc/Sda1}/Etest/XmlSchema2RdbmsSchema/address.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/XmlSchema2RdbmsSchema/exercise.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/XmlSchema2RdbmsSchema/sampleData.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/XmlSchema2RdbmsSchema/schema.sql (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/.project (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/person.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/person2user.xsl (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/person2userTest.xspec (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/personData.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/user.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml/userData.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/.project (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/person.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/person2user.xsl (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/person2userTest.xspec (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/personData.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/user.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/Xml2xml_Solution/userData.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/user.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt1/userSolution.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/.project (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book1/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book1/book1.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book1/book1Test.xspec (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book1/book1ToHtml.xsl (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book1/work1.reference.html (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book1/work1.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book2/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book2/book2.xsd (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book2/book2Test.xspec (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book2/book2ToHtml.xsl (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book2/work2.reference.html (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html/Book2/work2.xml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html_Solution/.project (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html_Solution/Book1/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html_Solution/Book1/book1ToHtml.xsl (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html_Solution/Book2/.gitignore (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/Book2Html_Solution/Book2/book2ToHtml.xsl (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/exercise1.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/Xslt2/exercise2.xhtml (100%) rename {Sda1 => Doc/Sda1}/Etest/solutions.html (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/Makefile (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/attribInElement.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/attributes.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/blockprop.fo.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/booknavigate.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/clientserv.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/contentmixed.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/cpp.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/crossmedia.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/dictionary.1.fo.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/dictionary.2.fo.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/dictionaryStack.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/domtree.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/entityresolve.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/externalize.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/filtering.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/firefoxrender.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/hacker.jpg (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/headfoot.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/heartland.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/impropernest.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/invoicedata.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/invoicedataimplement.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/itemize.fo.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcFourTier.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcObjectRelation.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcReadWrite.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcSniffing.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcThreeTier.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcarch.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcread.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/jdbcurl.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/leader.fo.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/leadermulti.fo.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/memofour.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/memorelativexpath.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/memotree.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/memoxpath.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/nodeHierarchy.svg (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/overlay.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.1.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.2.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.3.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/page.fo.4.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pageStack.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pageref.1.fo.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pageref.2.fo.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pagerefStack.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pagerefhyper.1.fo.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pagerefhyper.2.fo.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pagerefhyperStack.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/persistHandlerStates.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/persistence.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/persistentStates.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pitr_Syringe_icon.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/pre.tex (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/preceding.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/propernest.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/regions.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxapparch.odg (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxapparch.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxcharacter.odg (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxcharacter.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxmodel.odg (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxmodel.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/saxxmlrdbms.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/separate.fo.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/sequenceDomParser.svg (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/skull.eps (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/sqlTransport.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/sqlTransportPrepare.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/sqlinject.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/sqrtree.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/sqrtrender.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/updateinfo.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/wellformedandvalid.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xhtml.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xhtmlexample.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xml2fo2pdf.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xml2html.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xmlattribandjava.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xmlbase.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xpath.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xsl_id.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Fig/xslconvert.fig (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/dom-architecture.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/eclipseTestngResult.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/employee.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/externalize.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/externalize2.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/hello.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/insertValidate.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/login.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/mediaFormat.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/mozparaspancss.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/pdfbookmarks.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/runConfigJarAnnot.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/simpleInsertGui.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/sqlInject.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/sqlInjectPrepare.screen.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Screen/track.png (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/Makefile (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/connectauth.mp4 (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/dataInsert.mp4 (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/dataInsert.txt (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/eclipseBasicSql.mp4 (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/eclipseBasicSql.txt (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/hibernateConfig.mp4 (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/hibernateConfig.txt (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/jdbcConnection.mp4 (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/jdbcConnection.txt (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/jdbcDriverConfig.mp4 (100%) rename {Sda1 => Doc/Sda1}/Ref/Video/jdbcDriverConfig.txt (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/catalog2fo.final.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/catalog2fo.product.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/catalog2fo.start.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/catalog2fo.toc.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/catalog2fo.toclink.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/climbenriched.final.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/climbenriched.product.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/climbenriched.start.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/climbenriched.toc.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dom/climbenriched.toclink.pdf (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/book.xsd (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/book2chunks.1.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/book2html.1.xsl (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/chap1.xml (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/chap2.xml (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/java.xml (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/master.xml (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Dtd/book/v5/table.xsd (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Memo.1/memo.xsd (100%) rename {Sda1 => Doc/Sda1}/Ref/src/Memo.1/message.xml (100%) rename {Sda1 => Doc/Sda1}/Ref/src/sorttable.js (100%) rename {Sda1 => Doc/Sda1}/Ref/src/tablesort.html (100%) rename {Sda1 => Doc/Sda1}/dom.xml (100%) rename {Sda1 => Doc/Sda1}/fo.xml (100%) rename {Sda1 => Doc/Sda1}/jdbc.xml (100%) rename {Sda1 => Doc/Sda1}/prerequisites.xml (100%) rename {Sda1 => Doc/Sda1}/sax.xml (100%) rename {Sda1 => Doc/Sda1}/schema.xml (100%) rename {Sda1 => Doc/Sda1}/testng.xml (100%) rename {Sda1 => Doc/Sda1}/try.xml (100%) rename {Sda1 => Doc/Sda1}/xmlintro.xml (100%) rename {Sda1 => Doc/Sda1}/xmlschema.xml (100%) rename {Sda1 => Doc/Sda1}/xslt.xml (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/Makefile (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/billing.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/billingData.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/billingMapJoined.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/billingSql.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/classUser.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/concurrentOptimistic.svg (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/concurrentOptimisticFail.svg (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/figureInherit.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/jaxRs.svg (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/jpacache.svg (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/mapInherit.svg (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/mapUser.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/mapUserIntegrity.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/mavenIntro.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/persistProvider.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/pre.tex (100%) rename {Sda2 => Doc/Sda2}/Ref/Fig/transitiveDep.fig (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/1.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/2.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/3.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/4.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/5.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/6.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/mysql1.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/mysql2.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/mysql3.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/mysql4.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/CreateMaven/mysql5.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/accountTransferSum.png (100%) rename {Sda2 => Doc/Sda2}/Ref/Screen/ldapSampleUsers.png (100%) create mode 100644 Doc/Sda2/jax-rs.xml rename Sda2/sda2.xml => Doc/Sda2/jpa.xml (80%) create mode 100644 Doc/Sda2/ldap.xml create mode 100644 Doc/Sda2/sda2.xml rename lectures.xml => Doc/lectures.xml (60%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/.gitignore (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/README.md (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/pom.xml (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/main/webapp/static/customer2html.xsl (100%) rename {Sda2/P => P/Sda2}/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/.gitignore (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/Schema/cd.xsd (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/Schema/generate.sh (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/cdData.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/pom.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/Driver.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Catalog.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Cd.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/ObjectFactory.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/main/resources/META-INF/persistence.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/main/resources/log4j2.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/Cd/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/cd/AppTest.java (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/.gitignore (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/pom.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/JpaTest.java (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Department.java (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/java/de/hdm_stuttgart/mi/sda2/ehcache/domain/Employee.java (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/resources/META-INF/persistence.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/resources/ehcache.xsd (100%) rename {Sda2/P => P/Sda2}/Jpa/HibernateCacheDemo/src/main/resources/log4j.properties (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/.gitignore (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/pom.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/CreateData.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/ReadData.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BankAccount.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/BillingDetail.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/CreditCard.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/billing/domain/Customer.java (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/resources/META-INF/persistence.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/Inherit/Tpch/src/main/resources/log4j2.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/University/.gitignore (100%) rename {Sda2/P => P/Sda2}/Jpa/University/pom.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Lecture.java (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/Student.java (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/cd/domain/StudentLecture.java (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/main/java/de/hdm_stuttgart/mi/sda2/jpa/university/Driver.java (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/main/resources/META-INF/persistence.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/main/resources/log4j2.xml (100%) rename {Sda2/P => P/Sda2}/Jpa/University/src/test/java/de/hdm_stuttgart/mi/sda2/jpa/university/AppTest.java (100%) rename {Sda2/P => P/Sda2}/Register/.gitignore (100%) rename {Sda2/P => P/Sda2}/Register/Schema/schema.sql (100%) rename {Sda2/P => P/Sda2}/Register/pom.xml (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/AppWidgetSet.gwt.xml (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/MyLogin.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/MyVaadinUI.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/NavigatorUI.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/Register.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/entities/User.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/tools/MyBeanFieldGroup.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateGlobal.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/java/de/hdm_stuttgart/mi/tools/ValidateSecondIdenticalInput.java (100%) rename {Sda2/P => P/Sda2}/Register/src/main/webapp/META-INF/MANIFEST.MF (100%) rename {Sda2/P => P/Sda2}/Register/src/main/webapp/META-INF/context.xml (100%) rename {Sda2/P => P/Sda2}/Register/src/main/webapp/VAADIN/themes/mytheme/addons.scss (100%) rename {Sda2/P => P/Sda2}/Register/src/main/webapp/VAADIN/themes/mytheme/favicon.ico (100%) rename {Sda2/P => P/Sda2}/Register/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss (100%) rename {Sda2/P => P/Sda2}/Register/src/main/webapp/VAADIN/themes/mytheme/styles.scss (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/.gitignore (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/Schema/schema.ldif (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/pom.xml (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Config.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/Driver.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap/LdapHandler.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/rdbms/RdbmsHandler.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/de/hdm_stuttgart/mi/sda2/rdbms2ldap/ldap.properties (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/main/resources/log4j2.xml (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Rdbms2Ldap/src/test/java/de/hdm_stuttgart/mi/sda2/rdbms2ldap/AppTest.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/.gitignore (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/divers.sql (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/Schema/schema.sql (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/group (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/Testdata/passwd (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/pom.xml (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Cfg.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/Driver.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Group.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/ParseError.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/Parser.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/parse/User.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/DatabaseObject.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/GroupParam.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/MyNamedQuery.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/NamedParameterStatement.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/Param.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/RdbmsHandler.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserGroupParam.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/java/de/hdm_stuttgart/mi/sda2/usermanage/rdbms/UserParam.java (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/de/hdm_stuttgart/mi/sda2/usermanage/jdbc.properties (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/main/resources/log4j.properties (100%) rename {Sda2/P => P/Sda2}/UnixSqlLdap/Jndi/Unix2Rdbms/src/test/java/de/hdm_stuttgart/mi/sda2/usermanage/UserTest.java (100%) rename {Sda2/P => P/Sda2}/account/.gitignore (100%) rename {Sda2/P => P/Sda2}/account/Sql/schema.sql (100%) rename {Sda2/P => P/Sda2}/account/pom.xml (100%) rename {Sda2/P => P/Sda2}/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/Conf.java (100%) rename {Sda2/P => P/Sda2}/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/SumDriver.java (100%) rename {Sda2/P => P/Sda2}/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/TransferDriver.java (100%) rename {Sda2/P => P/Sda2}/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/ExceptionDialog.java (100%) rename {Sda2/P => P/Sda2}/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/gui/NumberField.java (100%) rename {Sda2/P => P/Sda2}/account/src/main/java/de/hdm_stuttgart/mi/sda2/account/sql/DbHandler.java (100%) rename {Sda2/P => P/Sda2}/account/src/main/resources/de/hdm_stuttgart/mi/sda2/account/jdbc.properties (100%) rename {Sda2/P => P/Sda2}/account/src/main/resources/log4j.properties (100%) rename {Sda2/P => P/Sda2}/account/src/test/java/de/hdm_stuttgart/mi/sda2/account/DbTest.java (100%) rename {Sda2/P => P/Sda2}/forum_1/.gitignore (100%) rename {Sda2/P => P/Sda2}/forum_1/Schema/schema.sql (100%) rename {Sda2/P => P/Sda2}/forum_1/_Readme.first (100%) rename {Sda2/P => P/Sda2}/forum_1/pom.xml (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/AppWidgetSet.gwt.xml (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Main.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/MyLogin.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/NavigatorUI.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/Register.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/.gitignore (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Forum.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/Subscription.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/User.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/domain/UserForumAssocId.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/Credential.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/HashProvider.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/MyBeanFieldGroup.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/PersistenceHelper.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateGlobal.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/java/de/hdm_stuttgart/mi/sda2/forum/tools/ValidateSecondIdenticalInput.java (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/resources/META-INF/persistence.xml (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/META-INF/MANIFEST.MF (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/META-INF/context.xml (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/VAADIN/.gitignore (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/VAADIN/themes/mytheme/addons.scss (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/VAADIN/themes/mytheme/favicon.ico (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.css (100%) rename {Sda2/P => P/Sda2}/forum_1/src/main/webapp/VAADIN/themes/mytheme/styles.scss (100%) rename {Sda2/P => P/Sda2}/forum_1/src/test/java/de/hdm_stuttgart/mi/sda2/forum/TestDomain.java (100%) delete mode 100644 Sd1/lib/Greenfoot-core-2.5.jar 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 000000000..bd449a74e --- /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 000000000..e9330cd6f --- /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 000000000..b0a759c71 --- /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 000000000..25eb2e51d --- /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 000000000..6d01a3b5e --- /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 000000000..6f5c408b9 --- /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 000000000..f4d1008ff --- /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 000000000..fdf58cf65 --- /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 000000000..86d0a6fd7 --- /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 1e265ae56..cb4b1b015 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 000000000..6e579d52a --- /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 000000000..13e6b803e --- /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 a1a5d5b2d..1483f1618 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 GIT binary patch literal 0 HcmV?d00001 literal 284901 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 diff --git a/Sd1/swd1.xml b/Sd1/swd1.xml index 983f47d48..587e988ba 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 ee3d40d6e..996514dc4 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 -- GitLab