Newer
Older
<?xml version="1.0" encoding="UTF-8"?>
<appendix annotations="slide" version="5.1" xml:id="sd1_appendix"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:ns="http://docbook.org/ns/transclusion"
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 xml:id="sd1Appendix">Appendix</title>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<section xml:id="sd1_sect_exercisingPastExaminations">
<title>Exercising past examinations</title>
<para>Lecture notes exercise solutions are being provided as <xref
linkend="glo_Maven"/> projects below <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/tree/master/P/Sd1">P/Sd1</link>
by the <link xlink:href="https://gitlab.mi.hdm-stuttgart.de">MI
Gitlab</link> repository. Comparing these solutions to your own solution
may be easily accomplished by importing them into your <xref
linkend="glo_IDE"/>.</para>
<para>Moreover the final examination and some exercises require importing
<xref linkend="glo_Maven"/> skeleton projects to start from. The general
procedure during an examination with respect to programming components is
being described subsequently.</para>
<figure xml:id="sd1_fig_examRemoteGuacamole">
<title>Exam training by Guacamole</title>
<mediaobject>
<imageobject>
<imagedata fileref="Fig/guacamoleExam.multi.svg"/>
</imageobject>
</mediaobject>
</figure>
<figure xml:id="sd1_fig_examRemoteGuacamoleHints">
<title>Environment hints:</title>
<para>The following installations allow for exercises with respect to
the final examination:</para>
<itemizedlist>
<listitem>
<para>E-Exam 113105 <foreignphrase
xml:lang="de">Softwareentwicklung</foreignphrase> 1 Test / Network
blocked:</para>
<para>The examination environment with firewall rules restricting
Internet access to a small number of allowed sites.</para>
</listitem>
<listitem>
<para>E-Exam 113105 <foreignphrase
xml:lang="de">Softwareentwicklung</foreignphrase> 1 Test /
<productname>Teamviewer</productname>:</para>
xlink:href="https://www.teamviewer.com/en/products/teamviewer"><productname>Teamviewer</productname></link>
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
</listitem>
</itemizedlist>
</figure>
<section xml:id="sd1_sect_exam_prepare">
<title>Starting an exam</title>
<figure xml:id="sd1_fig_examPrepare">
<title>Preparing an examination</title>
<mediaobject>
<imageobject>
<imagedata fileref="Fig/prepare.multi.svg"/>
</imageobject>
</mediaobject>
</figure>
</section>
<section xml:id="sd1_sect_exam_workUnitTest">
<title>Implementing the project skeleton</title>
<figure xml:id="sd1_fig_examGenJavadoc">
<title>Generating <xref linkend="glo_Javadoc"/>.</title>
<itemizedlist>
<listitem>
<para>HTML is difficult to read:</para>
<programlisting language="java"> * <td><code>a = -3</code>, <code>b = 4</code>, <code>c = 3</code></td>
* <td>4 - (-3) = 7</td>
* </tr>
* </table>
...
*/
static public int getMaxAbsoluteDiff(int a, int b, int c) {
return 42; // TODO: Implement me correctly</programlisting>
</listitem>
<listitem>
<para>⇒ Generate <xref linkend="glo_Javadoc"/> by <acronym
linkend="sd1_fig_mavenJavadoc">CLI</acronym> or <link
linkend="sd1_fig_mavenIdeaExecuteJavadocGoal">Idea</link>.</para>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_fig_examProgrammingHints">
<title>Programming hints</title>
<itemizedlist>
<listitem>
<para>The debugger is your friend ...</para>
</listitem>
<listitem>
<para>... but only if acquiring prior proficiency.</para>
</listitem>
<listitem>
<para>Train <link linkend="sd1_fig_primeDebugError">prime or
related example</link>.</para>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_fig_examImplementTestCycle">
<title>The implement - test - implement cycle</title>
<mediaobject>
<imageobject>
<imagedata fileref="Fig/implement.multi.svg"/>
</imageobject>
</mediaobject>
</figure>
</section>
<section xml:id="sd1_sect_examFinish">
<title>Finish the exam</title>
<figure xml:id="sd1_fig_examFinish">
<title>Finishing the exam</title>
<mediaobject>
<imageobject>
<imagedata fileref="Fig/finish.multi.svg"/>
</imageobject>
</mediaobject>
</figure>
</section>
</section>
<section xml:id="sd1ExaminationHints">
<title>Examination hints</title>
<figure xml:id="sd1_fig_examCheatSheet">
<title>Personal examination cheat sheets</title>
<itemizedlist>
<listitem>
<para>Username based Zip archive of <emphasis role="red">10 MB
<para>Use standard formats e.g. <acronym>png</acronym>,
<acronym>gif</acronym>, <acronym>pdf</acronym>. Proprietary stuff
like <acronym>.doc</acronym>, <acronym>.docx</acronym>,
<acronym>.rtf</acronym> possibly lack tool support by exam
environment.</para>
xlink:href="https://freedocs.mi.hdm-stuttgart.de/uploadCheat">cheat
xlink:href="https://freedocs.mi.hdm-stuttgart.de/cheat/">https://freedocs.mi.hdm-stuttgart.de/cheat/</uri>
<para><emphasis role="red">Check your archive's content in the exam
environment!</emphasis></para>
<figure xml:id="sd1_fig_examByJunit">
<title>Unit tests in examinations</title>
<itemizedlist>
<listitem>
</listitem>
<listitem>
<para>Corresponding Unit tests.</para>
</listitem>
<listitem>
<para>Automated evaluation scoring your achievements.</para>
</listitem>
<listitem>
<para>Individual weights reflecting a test's significance.</para>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_fig_interfaceDefExample">
<title>Example interface definition</title>
<programlisting language="java">/**
* Finde das n-te ungerade Element einer Wertefolge.
*
* <p>Beispiel: Im Array {3, 2, 0, 1, 4} ist der Wert «1» an der Index-
* position «3» das zweite ungerade Element.</p>
* @param n Die gewünschte Position, Start bei 1.
*
* @return Den Index des n-ten ungeraden Wertes falls es mindestens n
* ungerade Werte gibt, ...
*/
static public int getNtesUngeradesElement(final int[] werte, final int n){
return 12345; // TODO: Implementiere mich korrekt!
}</programlisting>
</figure>
<figure xml:id="sd1_fig_testExample">
<title>Corresponding test</title>
<programlisting language="java">@Test
@Marking(points=1) /* 1 point if test passes */
public void test_400() {
Assert.assertEquals(
2, /* Expected result */
Helper.getNtesUngeradesElement(new int[]{-4, 6, 1, -2, 8}, 1));
}</programlisting>
</figure>
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
<figure xml:id="sd1_fig_testDontCheat">
<title>Don't cheat!</title>
<informaltable border="1">
<tr>
<th>Unit Tests</th>
<th>Your solution</th>
</tr>
<tr>
<td valign="top"><programlisting language="none">assertFalse(isPrime(1));
assertTrue (isPrime(<emphasis role="red">2</emphasis>));
assertTrue (isPrime(<emphasis role="red">3</emphasis>));
assertFalse(isPrime(4));
assertTrue (isPrime(<emphasis role="red">5</emphasis>));
assertFalse(isPrime(6));
assertTrue (isPrime(<emphasis role="red">7</emphasis>));
assertFalse(isPrime(8));
assertFalse(isPrime(9));
assertFalse(isPrime(10));</programlisting></td>
<td valign="top"><programlisting language="none">... boolean isPrime(final int p) {
switch (p) {
case <emphasis role="red">2</emphasis>:
case <emphasis role="red">3</emphasis>:
case <emphasis role="red">5</emphasis>:
case <emphasis role="red">7</emphasis>:
return true;
default:
return false; }</programlisting></td>
</tr>
</informaltable>
<para>Will be treated as an <emphasis role="red">attempt at
deception</emphasis> / <foreignphrase xml:lang="de"><emphasis
role="red">Täuschungsversuch</emphasis></foreignphrase>.</para>
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<figure xml:id="sd1_fig_unitTestsStrategy">
<title>Unit tests strategy in examinations</title>
<itemizedlist>
<listitem>
<para>Unit testing is relentless: You are no longer at high school
where a result having <quote>just</quote> a wrong sign used to
matter next to nothing.</para>
</listitem>
<listitem>
<para>Focus on completing units of work rather than
<quote>nearly</quote> finishing a large number of tasks.</para>
</listitem>
<listitem>
<para>Watching a test fail just happens. Learn to
<emphasis>systematically</emphasis> fix bugs:</para>
<orderedlist>
<listitem>
<para>Use your <xref linkend="glo_IDE"/>'s debugger. Practise
debugging <xref linkend="glo_Junit"/> tests individually
addressing failures one by one.</para>
</listitem>
<listitem>
<para>Insert log statements using <productname
xlink:href="https://logging.apache.org/log4j/2.x/">log4j</productname>.</para>
</listitem>
</orderedlist>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_fig_collaborativeEfforts">
<title>Collaborative efforts</title>
<informaltable border="1">
<tr>
<td><mediaobject>
<imageobject>
</imageobject>
</mediaobject></td>
<td><para>Is this your <emphasis
role="red">TEAM</emphasis>?</para><para><emphasis
role="red">T</emphasis>oll</para><para><emphasis
role="red">E</emphasis>in</para><para><emphasis
role="red">A</emphasis>nderer</para><para><emphasis
role="red">M</emphasis>achts</para></td>
</tr>
</informaltable>
<figure xml:id="sd1_fig_projectRules">
<title>Project rules</title>
<orderedlist>
<listitem>
<para>You are expected to work as a <emphasis role="bold">team of
three partners</emphasis>.</para>
</listitem>
<listitem>
<para>Using the <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/">MI Gitlab
SCM</link> is a plus with respect to project evaluation. See table
below.</para>
</listitem>
<listitem>
<para>Your team is expected to supply a Maven project based on the
MI <quote>Maven archetype quickstart</quote> available from <uri
xlink:href="https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven/archetype-catalog.xml">https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven/archetype-catalog.xml</uri>.</para>
<listitem>
<para>You are expected to provide good internal code documentation
with respect both to method signatures (<xref
linkend="glo_Javadoc"/>) and method implementation.</para>
</listitem>
</orderedlist>
</figure>
<figure xml:id="sd1_fig_projectCodeDoc">
<title>Internal code documentation</title>
<para>You are expected to provide good internal code documentation with
respect both to method signatures (<xref linkend="glo_Javadoc"/>) and
method implementation. Possible problems involve:</para>
<imagedata fileref="Fig/bonusJavadocCompileTimeProblems.png"/>
</imageobject>
</mediaobject>
</figure>
<figure xml:id="sd1_fig_projectCodeDocHint">
<title>Internal code documentation hints</title>
<glosslist>
<glossentry>
<glossterm>Compile time warnings</glossterm>
<glossdef>
<para>Activate most compiler warnings at
<guimenuitem>Editor</guimenuitem> -->
<guimenuitem>Inspections</guimenuitem>. This will show potential
compile time problems like dead / unnecessary / unreachable code,
unused variable values, shadowing conflicts and so on.</para>
</glossdef>
</glossentry>
</glosslist>
</figure>
<figure xml:id="sd1_fig_projectJavadoc">
<title><xref linkend="glo_Javadoc"/> mismatches</title>
<para>Your method's formal parameters, their type and a method's return
type must match your documentation.</para>
</imageobject>
</mediaobject>
</figure>
<figure xml:id="sd1_fig_projectUnitTests">
<title>(Automated) tests</title>
<para>You are expected to provide meaningful unit tests:</para>
<itemizedlist>
<listitem>
<para>Try to cover all your implementation code and not just
isolated modules / methods.</para>
</listitem>
<listitem>
<para>If methods allow for null values write suitable tests.</para>
</listitem>
<listitem>
<para>Test special cases: If a method expects <abbrev>i.e.</abbrev>
an array of strings it may be allowed having zero length.</para>
</listitem>
</itemizedlist>
</figure>
<figure xml:id="sd1_fig_projectDeployRun">
<title>Deployment and execution</title>
<para>Your resulting project should be easily installable and
runnable.</para>
<itemizedlist>
<listitem>
<para>Maven is a good starting point with respect both to testing
and cross platform (Unix / Windows / Apple) portability.</para>
</listitem>
<listitem>
<para>Avoid dependencies to local file system resources like
<filename>c:\users\xyz\testdata.txt</filename>.</para>
</listitem>
</itemizedlist>
<tip>
<para>Test your application's deployability by installing it on an
untouched target platform (possibly of a different hard/software
architecture) and execute <command>mvn</command> <option>test</option>
(provided you do have written meaningful unit tests).</para>
</tip>
</figure>
<figure xml:id="sd1_fig_projectEvalCriteria">
<title>Marking criteria</title>
<informaltable border="1">
<colgroup width="62%"/>
<colgroup width="38%"/>
<tr>
<th>Criterion</th>
<th>Percentage</th>
</tr>
<tr>
<td valign="top">Overall code quality</td>
</tr>
<tr>
<td valign="top">Code documentation</td>
</tr>
<tr>
<td valign="top">Unit tests</td>
</tr>
<tr>
<td valign="top">Deployment</td>
<td valign="top">5%</td>
</tr>
<tr>
<td valign="top">SCM usage</td>
</tr>
<tr>
<td valign="top">Software functionality</td>
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
<para>Some of these terms require further explanations:</para>
<glosslist>
<glossentry>
<glossterm>Overall code quality</glossterm>
<glossdef>
<para>Subject to personal preferences unfortunately.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Code documentation</glossterm>
<glossdef>
<para>This involves writing <xref linkend="glo_Javadoc"/> describing
your classes. Furthermore you may want to add a project /
architecture description. A <filename>Readme.md</filename> in your
project's root is a good starting point.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Unit tests</glossterm>
<glossdef>
<para>Ideally your whole code could be covered by sensible unit
tests. Albeit guaranteeing absence of errors it may help minimizing
them.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Deployment</glossterm>
<glossdef>
<para>How difficult is your software's deployment? Sample:</para>
<screen>git clone git@gitlab.mi.hdm-stuttgart.de:.../yourProject.git
cd yourProject
mvn package
# possible configuration according to documentation
java -jar target/yourArchive.jar
</screen>
</glossdef>
</glossentry>
<glossentry>
<glossterm>SCM usage</glossterm>
<glossdef>
<para>Using <abbrev>e.g.</abbrev> git supports team oriented project
development. It also allows for tracing the participants individual
contributions. For this reason your tutor is required to have read
</glossdef>
</glossentry>
<glossentry>
<glossterm>Software functionality</glossterm>
<glossdef>
<itemizedlist>
<listitem>
<para>Project specification met?</para>
</listitem>
<listitem>
<para>(User input) Error handling?</para>
</listitem>
<listitem>
<para>Stability</para>
</listitem>
</itemizedlist>
</glossdef>
</glossentry>
</glosslist>
<para>The following sections contain both current and archived project
<section xml:id="sd1_sect_projectWeatherForecast">
<title>Weather forecast</title>
<warning>
<para>This project aims at using third party software components. It
may not be appropriate if you fancy <quote>bottom up</quote> coding
yourself.</para>
</warning>
<para>In this project you'll implement a terminal based weather forecast
application. Consider the following invocation:</para>
<figure xml:id="sd1_weather_fig_invocationVideo">
<title>Sample forecast session</title>
<mediaobject>
<videoobject>
</videoobject>
</mediaobject>
</figure>
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
<figure xml:id="sd1_weather_fig_invocationExample">
<title>Sample forecast invocation</title>
<screen>goik@goiki target> java -jar weather-1.0.jar <emphasis
role="red">Stuttgart</emphasis> <co
linkends="sd1_weather_fig_invocationExample-1.2"
xml:id="sd1_weather_fig_invocationExample-1.2-co"/>
1 = Stadtkreis Stuttgart <co
linkends="sd1_weather_fig_invocationExample-2.2"
xml:id="sd1_weather_fig_invocationExample-2.2-co"/>
<emphasis role="red">2 = Regierungsbezirk Stuttgart</emphasis>
3 = Stuttgart
4 = Stuttgart Feuerbach
5 = Stuttgart Muehlhausen
Bitte gültige Auswahl 1 bis 5 treffen:<emphasis role="red">2</emphasis> <co
linkends="sd1_weather_fig_invocationExample-3"
xml:id="sd1_weather_fig_invocationExample-3-co"/>
Vorhersage für <emphasis role="red">Regierungsbezirk Stuttgart</emphasis> <co
linkends="sd1_weather_fig_invocationExample-4"
xml:id="sd1_weather_fig_invocationExample-4-co"/>
Dienstag, 15.05
23:00: 11°C, Leichter Regen
Mittwoch, 16.05
02:00: 10°C, Leichter Regen
05:00: 10°C, Leichter Regen
08:00: 11°C, Leichter Regen
...</screen>
</figure>
<calloutlist>
<callout arearefs="sd1_weather_fig_invocationExample-1.2-co"
xml:id="sd1_weather_fig_invocationExample-1.2">
<para>Command line argument <emphasis
role="red">Stuttgart</emphasis> acting as a search filter.</para>
</callout>
<callout arearefs="sd1_weather_fig_invocationExample-2.2-co"
xml:id="sd1_weather_fig_invocationExample-2.2">
<para>The filter <emphasis role="red">Stuttgart</emphasis> yields
five matching towns / regions.</para>
</callout>
<callout arearefs="sd1_weather_fig_invocationExample-3-co"
xml:id="sd1_weather_fig_invocationExample-3">
<para>User choosing second match.</para>
</callout>
<callout arearefs="sd1_weather_fig_invocationExample-4-co"
xml:id="sd1_weather_fig_invocationExample-4">
<para>Forecast corresponding to <emphasis
role="red">Regierungsbezirk Stuttgart</emphasis>.</para>
</callout>
</calloutlist>
<para>The actual weather data is being provided by a web service:</para>
<figure xml:id="sd1_weather_fig_underlyingData">
<title>Underlying data provider</title>
<screen>https://api.openweathermap.org/data/2.5/forecast?lang=de& <co
linkends="sd1_weather_fig_underlyingData-1"
xml:id="sd1_weather_fig_underlyingData-1-co"/>
APPID=7cufdhdcgdhsgdhgfcgsdss67b3&units=metric&<emphasis role="red">id=3214105</emphasis>
{"cod":"200","message":0.0042,"cnt":40,"list":[ <co
linkends="sd1_weather_fig_underlyingData-2"
xml:id="sd1_weather_fig_underlyingData-2-co"/>
{"dt":1526428800,"main":{"temp":10.29,"temp_min":10.29,
"temp_max":12.45,"pressure":985.75,"sea_level":1027.48,
"grnd_level":985.75,"humidity":80,"temp_kf":-2.16},
"weather":[{"id":500,"main":"Rain",
"description":"Leichter Regen","icon":"10n"}],"clouds":
{"all":88},"wind":{"speed":1.59,"deg":313.503},"rain":
{"3h":0.315},"sys":{"pod":"n"},"dt_txt":"2018-05-16 00:00:00"},
{"dt":1526439600,"main": ...</screen>
<calloutlist>
<callout arearefs="sd1_weather_fig_underlyingData-1-co"
xml:id="sd1_weather_fig_underlyingData-1">
<para>An <xref linkend="glo_URL"/> containing an id value
corresponding to a uniquely defined town or region. We identify
the following components:</para>
<glosslist>
<glossentry>
<glossterm><code>lang=de</code></glossterm>
<glossdef>
<para>Provide German localization e.g. «<foreignphrase
xml:lang="de">Leichter Regen</foreignphrase>» in favour of
«light rain».</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm><abbrev>APPID</abbrev>=7cufdhdcgdhsgdhgfcgsdss67b3</glossterm>
<glossdef>
<para>This parameter allows for accessing the service:
«7cufdhdcgdhsgdhgfcgsdss67b3» is actually a fake value. Your
project requires <link
xlink:href="https://openweathermap.org/appid">obtaining an
APPID token</link>.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>units=metric</glossterm>
<glossdef>
<para>Favour metric over imperial units.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>id=3214105</glossterm>
<glossdef>
<para>«3214105» identifies «<foreignphrase
xml:lang="de">Regierungsbezirk Stuttgart</foreignphrase>»,
see line 262703 in <filename
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/resources/cities.list.json">cities.list.json</filename>:</para>
<programlisting language="json">"id": 3214105,
"name": "Regierungsbezirk Stuttgart",
"country": "DE",
"coord": {
"lon": 9.66667,
"lat": 49.083328
}</programlisting>
</glossdef>
</glossentry>
</glosslist>
</callout>
<callout arearefs="sd1_weather_fig_underlyingData-2-co"
xml:id="sd1_weather_fig_underlyingData-2">
<para><uri
xlink:href="https://openweathermap.org/api">https://openweathermap.org/api</uri>'s
reply providing <abbrev>JSON</abbrev> based weather data.</para>
</callout>
</calloutlist>
</figure>
<figure xml:id="sd1_weather_fig_citiesFile">
<title><filename
xlink:href="http://bulk.openweathermap.org/sample/city.list.json.gz">cities.list.json.gz</filename>
providing cities</title>
<programlisting language="json">[
{
"id": 2886241,
"name": "Regierungsbezirk Köln",
"country": "DE",
"coord": {
"lon": 7.16667,
"lat": 50.833328
}
},
{
"id": 3247452,
"name": "Kreis Euskirchen",
...
]</programlisting>
</figure>
<figure xml:id="sd1_weather_fig_urlToFileHelper">
<title>ma/Copy URL result to file</title>
<programlisting language="java">FileUtils.<link
xlink:href="https://commons.apache.org/proper/commons-io/javadocs/api-2.6/org/apache/commons/io/FileUtils.html#copyURLToFile(java.net.URL,java.io.File)">copyURLToFile</link>(
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
"https://api.openweathermap.org/data/2.5/forecast...",
new File("weatherData.json"));</programlisting>
<programlisting language="xml"><dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency></programlisting>
</figure>
<figure xml:id="sd1_weather_fig_parseCityData">
<title>Parse city data</title>
<programlisting language="java"><link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/java/de/hdm_stuttgart/mi/sd1/weather/cities/Cities.java">public class Cities</link> {
static public final City[] cities;
...
}</programlisting>
<programlisting language="java">@Test <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/test/java/de/hdm_stuttgart/mi/sd1/weather/CityParserTest.java">public void testParsedCityCount()</link> {
Assert.assertEquals(209579, Cities.cities.length);
}</programlisting>
</figure>
<figure xml:id="sd1_weather_fig_parseWeatherData">
<title>Parse weather data</title>
<programlisting language="java"><link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/java/de/hdm_stuttgart/mi/sd1/weather/WeatherDataParser.java">public class WeatherDataParser</link> {
static public final <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/java/de/hdm_stuttgart/mi/sd1/weather/model/Weather.java">Weather</link> parse(final String jsonWeatherDataFilename)
throws IOException {
return ...;
}
}</programlisting>
<programlisting language="java">@Test <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/test/java/de/hdm_stuttgart/mi/sd1/weather/WeatherDataParseTest.java">public void testParseWeatherData()</link> {
...
Weather weather = WeatherDataParser.parse(
"src/main/resources/stuttgart.weather.json");
...</programlisting>
</figure>
<figure xml:id="sd1_weather_fig_weatherRequirements">
<title>Requirements</title>
<orderedlist>
<listitem>
<para>The application shall accept a command line parameter like
e.g. «Stuttgart» to filter matching cities from <filename
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/resources/cities.list.json">cities.list.json</filename>.</para>
</listitem>
<listitem>
<para>If a given filter matches multiple locations the user shall
have an option for choosing the desired one.</para>
</listitem>
<listitem>
<para>The most recent city id value shall be cached in a file.
Subsequent invocations without command line parameter shall
provide a current forecast corresponding to this value.</para>
</listitem>
<listitem>
<para>Weather data belonging to a given id value shall be cached
locally for 10 minutes. Subsequent weather queries within this
period shall be read from cache rather than by accessing
<uri>https://api.openweathermap.org/...</uri> .</para>
<para>Provide logging to a file rather than to the console to
avoid cluttering the user interface. Log cache handling.</para>
</listitem>
</orderedlist>
</figure>
<figure xml:id="sd1_weather_fig_weatherLogging">
<title>Logging</title>
<itemizedlist>
<listitem>
<para>Provide logging to a file rather than to the console to
avoid cluttering the user interface.</para>
</listitem>
<listitem>
<para>Log cache handling.</para>
</listitem>
</itemizedlist>
<screen>main INFO weather.Forecast - Re-using cache file
'/ma/goik/Forecast/6930414.json' from 196 seconds ago</screen>
</figure>
<tip>
<para>See the related <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/-/tree/master/Doc/Sd1/Ref/Projects/WeatherSkeleton">skeleton
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<section xml:id="sd1_sect_projectRpnCalculator">
<title>Reverse Polish notation (<abbrev><abbrev
xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev></abbrev>)
calculator</title>
<para>In a nutshell <abbrev
xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
allows for compact arithmetic expressions requiring no parentheses to
express operator priorities. The introductory article <link
xlink:href="http://www.calculator.org/rpn.aspx">What is Reverse Polish
Notation?</link> explains the underlying idea.</para>
<para>This project's comprises two different goals:</para>
<orderedlist>
<listitem>
<para>Parse and evaluate <abbrev
xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
expressions:</para>
<informaltable border="1">
<colgroup width="24%"/>
<colgroup width="28%"/>
<colgroup width="14%"/>
<colgroup width="34%"/>
<tr>
<th><abbrev
xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
expression</th>
<th>Conventional expression</th>
<th>Result</th>
<th>Comment</th>
</tr>
<tr>
<td>1 2 +</td>
<td><inlineequation>
<m:math display="inline">
<m:mrow>
<m:mi>1</m:mi>
<m:mo>+</m:mo>
<m:mi>2</m:mi>
</m:mrow>
</m:math>
</inlineequation></td>
<td>3</td>
<td/>
</tr>
<tr>
<td>1 2 3 4 + - +</td>
<td><inlineequation>
<m:math display="inline">
<m:mrow>
<m:mi>1</m:mi>
<m:mo>+</m:mo>
<m:mrow>
<m:mo>(</m:mo>
<m:mrow>
<m:mi>2</m:mi>
<m:mo>-</m:mo>
<m:mrow>
<m:mo>(</m:mo>
<m:mrow>
<m:mi>3</m:mi>
<m:mo>+</m:mo>
<m:mi>4</m:mi>
</m:mrow>
<m:mo>)</m:mo>
</m:mrow>
</m:mrow>