From 6f33bfc3279b5de53de25d3c185e9ed9965e8ef0 Mon Sep 17 00:00:00 2001 From: "Dr. Martin Goik" <goik@hdm-stuttgart.de> Date: Thu, 26 Jul 2018 21:16:28 +0200 Subject: [PATCH] Sd1 Exam summer 2018 --- AuswertungKlausur/move.sh | 2 +- Klausuren/Sd1/2018summer/Exam/.gitignore | 5 + Klausuren/Sd1/2018summer/Exam/pom.xml | 99 ++++ .../Exam/src/main/assembly/assembly.xml | 36 ++ .../mi/sd1/aufgabe1/ArrayHelper.java | 49 ++ .../mi/sd1/aufgabe1/MathHelper.java | 46 ++ .../mi/sd1/aufgabe1/StringHelper.java | 53 +++ .../mi/sd1/aufgabe2/Artikel.java | 8 + .../Exam/src/main/resources/log4j2.xml | 21 + .../mi/sd1/test/ShowReachedPoints.java | 26 + .../sd1/test/aufgabe1/Test_ArrayHelper.java | 58 +++ .../mi/sd1/test/aufgabe1/Test_MathHelper.java | 50 ++ .../sd1/test/aufgabe1/Test_StringHelper.java | 82 ++++ .../mi/sd1/test/aufgabe2/Test_Artikel.java | 109 +++++ .../mi/sd1/test/helper/ReflectClass.java | 127 +++++ .../sd1/test/helper/ReflectConstructor.java | 38 ++ .../mi/sd1/test/helper/ReflectMethod.java | 124 +++++ .../mi/sd1/test/helper/ReflectionHelper.java | 26 + Klausuren/Sd1/2018summer/Solve/.gitignore | 5 + .../Sd1/2018summer/Solve/Doc/klausur.xml | 446 ++++++++++++++++++ Klausuren/Sd1/2018summer/Solve/pom.xml | 99 ++++ .../Solve/src/main/assembly/assembly.xml | 36 ++ .../mi/sd1/aufgabe1/ArrayHelper.java | 79 ++++ .../mi/sd1/aufgabe1/MathHelper.java | 62 +++ .../mi/sd1/aufgabe1/StringHelper.java | 89 ++++ .../mi/sd1/aufgabe2/Artikel.java | 84 ++++ .../Solve/src/main/resources/log4j2.xml | 21 + .../mi/sd1/test/ShowReachedPoints.java | 26 + .../sd1/test/aufgabe1/Test_ArrayHelper.java | 58 +++ .../mi/sd1/test/aufgabe1/Test_MathHelper.java | 50 ++ .../sd1/test/aufgabe1/Test_StringHelper.java | 82 ++++ .../mi/sd1/test/aufgabe2/Test_Artikel.java | 109 +++++ .../mi/sd1/test/helper/ReflectClass.java | 127 +++++ .../sd1/test/helper/ReflectConstructor.java | 38 ++ .../mi/sd1/test/helper/ReflectMethod.java | 124 +++++ .../mi/sd1/test/helper/ReflectionHelper.java | 26 + 36 files changed, 2519 insertions(+), 1 deletion(-) create mode 100644 Klausuren/Sd1/2018summer/Exam/.gitignore create mode 100644 Klausuren/Sd1/2018summer/Exam/pom.xml create mode 100644 Klausuren/Sd1/2018summer/Exam/src/main/assembly/assembly.xml create mode 100644 Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/main/resources/log4j2.xml create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java create mode 100644 Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/.gitignore create mode 100644 Klausuren/Sd1/2018summer/Solve/Doc/klausur.xml create mode 100644 Klausuren/Sd1/2018summer/Solve/pom.xml create mode 100644 Klausuren/Sd1/2018summer/Solve/src/main/assembly/assembly.xml create mode 100644 Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/main/resources/log4j2.xml create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java create mode 100644 Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java diff --git a/AuswertungKlausur/move.sh b/AuswertungKlausur/move.sh index 9a237d302..6854ac14f 100755 --- a/AuswertungKlausur/move.sh +++ b/AuswertungKlausur/move.sh @@ -11,7 +11,7 @@ rm -rf ~/newUsers.txt for zip in $( ls *.zip); do userId=${zip%.zip} - destuser=~/C/Hdm/Fh/KlausurBewertung/$userId + destuser=~/C/HdM/Fh/KlausurBewertung/$userId if [ -d "$destuser" ] then diff --git a/Klausuren/Sd1/2018summer/Exam/.gitignore b/Klausuren/Sd1/2018summer/Exam/.gitignore new file mode 100644 index 000000000..a2fa20469 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/.gitignore @@ -0,0 +1,5 @@ +/.classpath +/.project +/.settings +/.idea +/*.iml diff --git a/Klausuren/Sd1/2018summer/Exam/pom.xml b/Klausuren/Sd1/2018summer/Exam/pom.xml new file mode 100644 index 000000000..121ca07aa --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/pom.xml @@ -0,0 +1,99 @@ +<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.mi.sd1</groupId> + <artifactId>sd1_2018summer_exam</artifactId> + <version>0.9</version> + <packaging>jar</packaging> + + <name>sd1_2018summer_exam</name> + + <url>http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.lectures/sd1SectUsingMaven.html</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <repositories> + <repository> + <id>hdm-mi-internal-maven-repo</id> + <url>https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven</url> + </repository> + </repositories> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>2.6</version> + </dependency> + + <dependency> + <groupId>de.hdm_stuttgart.mi.exam</groupId> + <artifactId>unitmarking</artifactId> + <version>0.9</version> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.5.1</version> + <configuration> + <source>1.9</source> + <target>1.9</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>3.0.1</version> + <configuration> + <links> + <link>https://docs.oracle.com/javase/10/docs/api</link> + </links> + <additionalJOptions> + <additionalJOption>-html5</additionalJOption> + </additionalJOptions> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.3</version> + <configuration> + <descriptor>src/main/assembly/assembly.xml</descriptor> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <archive> + <manifest> + <mainClass>de.hdm_stuttgart.mi.sd1.test.ShowReachedPoints</mainClass> + </manifest> + </archive> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/Klausuren/Sd1/2018summer/Exam/src/main/assembly/assembly.xml b/Klausuren/Sd1/2018summer/Exam/src/main/assembly/assembly.xml new file mode 100644 index 000000000..1a2cd6054 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/main/assembly/assembly.xml @@ -0,0 +1,36 @@ +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> + <id>fat-tests</id> + <formats> + <format>jar</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <dependencySets> + <dependencySet> + <outputDirectory>/</outputDirectory> + <useProjectArtifact>true</useProjectArtifact> + <unpack>true</unpack> + <scope>test</scope> + </dependencySet> + </dependencySets> + <fileSets> + <fileSet> + <directory>${project.build.directory}/test-classes</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>**/*.class</include> + </includes> + <useDefaultExcludes>true</useDefaultExcludes> + </fileSet> + <fileSet> + <directory>${project.build.directory}/classes</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>**/*.class</include> + </includes> + <useDefaultExcludes>true</useDefaultExcludes> + </fileSet> + </fileSets> +</assembly> diff --git a/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java new file mode 100644 index 000000000..9b503d828 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java @@ -0,0 +1,49 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe1; + +import java.util.Arrays; + +/** + * Hilfsmethoden für Arrays. + */ +public class ArrayHelper { + + /** + * <p>Enthält ein Array ganzzahliger Werte mindestens einen mehrfach auftretenden Wert? Beispiele:</p> + * + * <ul> + * <li>In <code>{1, -5, 3, 1, 17, 6, 1}</code> ist der Wert 1 dreifach enthalten.</li> + * <li><code>{-5, 5, 4, 9}</code> enthält keinen mehrfach auftretenden Wert.</li> + * </ul> + * + * <p>Praktische Verwendung:</p> + * <pre>final int[] werte = {2, 4, 3, 0, 1, 2}; + * final boolean result = ArrayHelper.enthaeltDuplikate(werte);</pre> + * + * <p>Wegen des doppelten Auftretens des Werts »2« hat <code>result</code> den Wert <code>true</code>.</p> + * + * @param werte null oder ein Array beliebiger Ganzzahlen + * @return <code>true</code>, falls mindestens ein Wert doppelt vorkommt, ansonsten <code>false</code>. + */ + static public boolean enthaeltDuplikate(final int[] werte) { + return false; // TODO: Implementiere mich! + } + + /** + * <p>Analog zu {@link #enthaeltDuplikate(int[])} in Bezug auf Wertgleichheit von Objekten. </p> + * + * <p>Praktische Verwendung:</p> + * + * <pre>final String[] werte = {"One", null, "true", null}; + * final boolean result = ArrayHelper.enthaeltDuplikate(werte);</pre> + * + * <p>Da es keinen doppelt auftretenden String gibt und <code>null</code> Werte ignoriert werden, erhält + * <code>result</code> den Wert <code>false</code>.</p> + * + * @param werte <code>null</code> oder ein Array aus Object Instanzen und/oder <code>null</code> Werten. + * @return <code>true</code>, falls mindestens ein String doppelt vorkommt, ansonsten <code>false</code>, + * wobei enthaltene <code>null</code> Werte in Bezug auf Duplikate ignoriert werden. + */ + static public boolean enthaeltDuplikate(final Object[] werte) { + return false; // TODO: Implementiere mich! + } +} diff --git a/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java new file mode 100644 index 000000000..458b45de9 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java @@ -0,0 +1,46 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe1; + + +/** + * Spezielle Berechnungsmethoden. + */ +public class MathHelper { + + /** + * <p>Die Summe aller ungeraden Werte zweier Argumente. Gerade Werte werden + * bei der Summenbildung ignoriert. Beispiele:</p> + * + * <ul> + * <li>summeUngeraderWerte(3, 4) ergibt 3, weil 4 als gerader Wert ignoriert wird.</li> + * <li>summeUngeraderWerte(1, 5) ergibt 1 + 5 == 6, da beide Werte ungerade sind.</li> + * <li>summeUngeraderWerte(-4, 10) ergibt 0, weil beide Werte gerade sind und somit ignoriert werden.</li> + * + * </ul> + * + * @param a Erster Wert. + * @param b Zweiter Wert + * @return Die Summe aller ungeraden Werte beider Argumente. + */ + static public int summeUngeraderWerte(final int a, final int b) { + /* Tip: Der »%« Operator ist Ihr Freund! */ + return 12345; // TODO: Implementiere mich! + } + /** + * <p>Die harmonische Reihe H(n) zu einer natürlichen Zahl 0 < n ist definiert als:</p> + * + * <p>H(n) = 1/1 + 1/2 + 1/3 + ... + 1/n</p> + * + * <p>Also beispielsweise:</p> + * <ul> + * <li>H(2) = 1 + 1/2 = 1 + 0.5 = 1.5</li> + * <li>H(3) = 1 + 1./2 + 1./3 = 11./6 = 1.8333333...</li> + * </ul> + * + * @param n Anzahl der Terme der harmonischen Reihe, mindestens 1. + * @return Der Wert H(n). + */ + static public double harmonisch(final int n) { + /* Tip: Beachten Sie mögliche Probleme bei der Division zweier int Werte. */ + return 12345; // TODO: Implementiere mich! + } +} diff --git a/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java new file mode 100644 index 000000000..8d92a4c1a --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java @@ -0,0 +1,53 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe1; + +/** + * Hilfsmethode für String Operationen. + */ +public class StringHelper { + + /** + * <p>Berechne den Stundenlohn gemäß den nachfolgenden Regeln in der angegebenen Reihenfolge:</p> + * + * <ol> + * <li>Bei falscher Wochentagsangabe (z.B. "Fr." statt "Freitag" oder null wird der Wert -1 zur + * Fehlererkennung zurückgeliefert.</li> + * <li>An einem Feiertag gilt unabhängig vom Wochentag ein Grundlohn von 25.-€.</li> + * <li>An einem Wochentag ("Montag" bis "Freitag") wird ein Grundlohn von 15.-€ gezahlt.</li> + * <li>Am Wochenende ("Samstag"/"Sonntag") werden 20.-€ Grundlohn gezahlt.</li> + * <li>An Feiertagen werden in einer Nachtschicht 10€ zusätzlich zum Grundlohn gezahlt.</li> + * <li>An nicht-Feiertagen verdoppelt sich der Grundlohn einer Nachtschicht.</li> + * </ol> + * + * @param wochentag Genau ein Wert aus {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", + * "Samstag", "Sonntag"} + * @param nachtschicht true, falls Nachtschicht, sonst false. + * @param feiertag true, falls Feiertag, sonst false. + * @return -1, falls der angegebene Wochentag null oder ungültig ist. Ansonsten der Stundenlohn gemäß Beschreibung. + */ + static public int berechneStundenlohn(final String wochentag, final boolean nachtschicht, boolean feiertag) { + return 123; // TODO: Implementiere mich! + } + + /** + * <p>Hat eine Zeichenkette mindestens eine vorgegebene Länge? Beispiele:</p> + * + * <ul> + * <li>"Kurt" hat mindestens die Länge 2.</li> + * <li>"Eva" hat nicht die Mindestlänge 4.</li> + * </ul> + * + * <p>Praktische Verwendung:</p> + * <pre>boolean result = StringHelper.hatMindestlaenge("Eva", 4);</pre> + * + * <p>Die Zeichenkette "Eva" hat lediglich die Länge 3, daher erhält die Variable + * <code>result</code> den Wert <code>false</code>.</p> + * + * @param s Eine Zeichenkette oder <code>null</code>. + * @param mindestlaenge Eine geforderte, nicht-negative, Mindestlänge. + * @return true, falls die Zeichenkette mindestens die vorgegebene Länge aufweist. Der Wert <code>null</code> + * wird als leere Zeichenkette ("") behandelt. + */ + static public boolean hatMindestlaenge(final String s, final int mindestlaenge) { + return false; // TODO: Implementiere mich! + } +} diff --git a/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java new file mode 100644 index 000000000..5a1684a2d --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java @@ -0,0 +1,8 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe2; + +/** + * Darstellung von Verkaufsartikeln + */ +public class Artikel { + // TODO: Implementiere mich gemäß Aufgabenbeschreibung! +} diff --git a/Klausuren/Sd1/2018summer/Exam/src/main/resources/log4j2.xml b/Klausuren/Sd1/2018summer/Exam/src/main/resources/log4j2.xml new file mode 100644 index 000000000..130f87a14 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/main/resources/log4j2.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration> + <Appenders> + <File name="A1" fileName="A1.log" append="false"> + <PatternLayout pattern="%t %-5p %c{2} - %m%n"/> + </File> + <Console name="STDOUT" target="SYSTEM_OUT"> + <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </Console> + </Appenders> + <Loggers> + + <!-- You my want to define class or package level per-logger rules --> + <Logger name="de.hdm_stuttgart.mi.sd1.App" level="debug"> + <AppenderRef ref="A1"/> + </Logger> + <Root level="info"> + <AppenderRef ref="STDOUT"/> + </Root> + </Loggers> +</Configuration> \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java new file mode 100644 index 000000000..354714e4d --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java @@ -0,0 +1,26 @@ +package de.hdm_stuttgart.mi.sd1.test; + +import de.hdm_stuttgart.mi.exam.unitmarking.RunTests; +import de.hdm_stuttgart.mi.sd1.test.aufgabe1.Test_ArrayHelper; +import de.hdm_stuttgart.mi.sd1.test.aufgabe1.Test_MathHelper; +import de.hdm_stuttgart.mi.sd1.test.aufgabe1.Test_StringHelper; +import de.hdm_stuttgart.mi.sd1.test.aufgabe2.Test_Artikel; + +public class ShowReachedPoints { + + /** + * Execution reveals the number of reached points. + * + * @param args Unused + */ + public static void main(String[] args) { + RunTests.exec( + "Aufgabe 1" + , Test_StringHelper.class + , Test_MathHelper.class + , Test_ArrayHelper.class + ); + + RunTests.exec("Aufgabe 2", Test_Artikel.class); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java new file mode 100644 index 000000000..c8517d639 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java @@ -0,0 +1,58 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe1; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; +import de.hdm_stuttgart.mi.sd1.aufgabe1.ArrayHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_ArrayHelper extends ExaminationTestDefaults { + + // Teste int[] Parameter + @Test public void test_380_testNull() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate((int[]) null)); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 1})); + } + @Test public void test_400_testKeinDuplikat_0() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{0})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 1})); + } + @Test @Marking(points = 3) public void test_410_testKeinDuplikat_1() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{1})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 4, 1})); + } + @Test @Marking(points = 2) public void test_420_testKeinDuplikat_2() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{-1, 2})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 4, 4})); + } + + @Test @Marking(points = 2) public void test_430_testKeinDuplikat_6() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{-1, 2, 5, 9, -30, 0})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{2, 4, 3, 0, 1, 2})); + } + @Test @Marking(points = 2) public void test_440_testNull() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate((int[]) null)); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{0, 0})); + } + + // Teste Object[] parameter + @Test @Marking(points = 2) public void test_500_string_testNull() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate((String[]) null)); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new String[]{ + new String("ab"), "ab"})); + } + + @Test @Marking(points = 2) public void test_520_string_testNullEnthalten() { + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new String[]{ + new String("ab"), null, "ab"})); + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new String[]{null, null, null})); + } + + @Test @Marking(points = 2) public void test_530_string_testHeterogen() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new Object[]{"test", new StringBuffer("test")})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new Object[]{new String("test"), new String("test")})); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java new file mode 100644 index 000000000..ff17c9120 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java @@ -0,0 +1,50 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe1; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; +import de.hdm_stuttgart.mi.sd1.aufgabe1.MathHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_MathHelper extends ExaminationTestDefaults { + /** + * Zwei gerade Werte. + */ + @Test @Marking(points = 4) public void test_100_nullUngeradeWerte() { + Assert.assertEquals(0, MathHelper.summeUngeraderWerte(224, -418)); + Assert.assertEquals(0, MathHelper.summeUngeraderWerte(-418, 224)); + } + /** + * Gerade und ungerade gemischt. + */ + @Test @Marking(points = 4) public void test_110_einUngeraderWert() { + Assert.assertEquals(-419, MathHelper.summeUngeraderWerte(224, -419)); + Assert.assertEquals(-3, MathHelper.summeUngeraderWerte(-3, 224)); + } + /** + * Zwei ungerade Werte. + */ + @Test @Marking(points = 4) public void test_120_zweiUngeradeWerte() { + Assert.assertEquals(-14, MathHelper.summeUngeraderWerte(-17, 3)); + Assert.assertEquals(-4, MathHelper.summeUngeraderWerte(3, -7)); + } + + @Test @Marking(points = 3) public void test_200_testHarmonisch() { + Assert.assertEquals(1., MathHelper.harmonisch(1), 1.E-14); + } + @Test @Marking(points = 3) public void test_210_testHarmonisch() { + Assert.assertEquals(1.5, MathHelper.harmonisch(2), 1.E-14); + Assert.assertEquals(1.8333333333333333, MathHelper.harmonisch(3), 1.E-14); + + Assert.assertEquals(2.9289682539682538, MathHelper.harmonisch(10), 1.E-14); + Assert.assertEquals(3.597739657143682, MathHelper.harmonisch(20), 1.E-14); + Assert.assertEquals(4.499205338329425, MathHelper.harmonisch(50), 1.E-14); + Assert.assertEquals(10.480728217229327, MathHelper.harmonisch(20000),1.E-14); + } + @Test public void test_220_testHarmonisch() { + Assert.assertEquals(10.480728217229327, MathHelper.harmonisch(20000),1.E-14); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java new file mode 100644 index 000000000..82e0c493e --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java @@ -0,0 +1,82 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe1; + +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; +import de.hdm_stuttgart.mi.sd1.aufgabe1.StringHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_StringHelper extends ExaminationTestDefaults { + + @Test @Marking(points = 4) public void test_050_testMindestlaengeNull() { + try { + Assert.assertTrue(StringHelper.hatMindestlaenge(null, 0)); + for (int i = 1; i <= 100; i++) { + Assert.assertFalse(StringHelper.hatMindestlaenge(null, i)); + } + } catch (final NullPointerException e) { + Assert.fail("Ein null String darf nicht zu einer NullPointerException führen"); + } + + } + + @Test @Marking(points = 5) public void test_060_mindestLaenge() { + + final String[] tests = {"", "Eva", "Anton", "Mal sehen!", "Und noch ein wenig länger als alle Anderen!!"}; + + for (final String s: tests) { + for (int i = 0; i <= s.length(); i++) { + Assert.assertTrue(StringHelper.hatMindestlaenge(s, i)); + } + for (int i = 1 + s.length(); i < s.length() + 300; i++) { + Assert.assertFalse(StringHelper.hatMindestlaenge(s, i)); + } + } + } + + @Test public void test_100_stundenlohn_null() { + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, false, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, true, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, false, true)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, true, true)); + } + + @Test public void test_120_stundenlohn_invalid() { + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Do.", false, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Sa", true, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Monday", false, true)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Phantasie", true, true)); + } + + @Test public void test_130_stundenlohn_standard() { + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Montag", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Dienstag", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Mittwoch", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Donnerstag", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Freitag", false, false)); + Assert.assertEquals(20, StringHelper.berechneStundenlohn("Samstag", false, false)); + Assert.assertEquals(20, StringHelper.berechneStundenlohn("Sonntag", false, false)); + } + + @Test public void test_140_stundenlohn_Feiertag_Tagschicht() { + Assert.assertEquals(25, StringHelper.berechneStundenlohn("Montag", false, true)); + Assert.assertEquals(25, StringHelper.berechneStundenlohn("Sonntag", false, true)); + + Assert.assertEquals(25 + 10, StringHelper.berechneStundenlohn("Montag", true, true)); + Assert.assertEquals(25 + 10, StringHelper.berechneStundenlohn("Sonntag", true, true)); + } + + @Test public void test_140_stundenlohn_normal_Nachtschicht() { + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Montag", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Dienstag", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Mittwoch", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Donnerstag", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Freitag", true, false)); + Assert.assertEquals(2 * 20, StringHelper.berechneStundenlohn("Samstag", true, false)); + Assert.assertEquals(2 * 20, StringHelper.berechneStundenlohn("Sonntag", true, false)); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java new file mode 100644 index 000000000..c80a827f0 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java @@ -0,0 +1,109 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe2; + + +import de.hdm_stuttgart.mi.sd1.aufgabe2.Artikel; +import de.hdm_stuttgart.mi.sd1.test.helper.ReflectionHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; + +import java.lang.reflect.InvocationTargetException; + +/** + * . + * + */ + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_Artikel extends ExaminationTestDefaults { + + private final ReflectionHelper rHelper = new ReflectionHelper(); + + private Artikel fussBall, ball, puzzle, flummi; + + private void init() { + fussBall = newArtikel("Fußball", 234, 2250); + ball = newArtikel("Ball", 234, 1030); + puzzle = newArtikel("250 Teile Puzzle", 400, 780); + flummi = newArtikel("Flummi", 420, 89); + + } + + private Artikel newArtikel(final String artikelBezeichnung, final int artikelNummer, final int preis) { + try { + final String msg = rHelper.artikel_new_Bez_id_preis.getRecursiveMsg(); + Assert.assertNull(msg, msg); + + return rHelper.artikel_new_Bez_id_preis.constructor. + newInstance(artikelBezeichnung, artikelNummer, preis); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + Assert.fail("Konnte »new Artikel(\"" + artikelBezeichnung + "\", " + artikelNummer + ", " + + preis + ")« nicht aufrufen."); + } + return null; + } + + @Test @Marking(points = 4) public void test_100_constructorDefined() { + final String msg = rHelper.artikel_new_Bez_id_preis.getRecursiveMsg(); + Assert.assertNull(msg, msg); + } + + @Test @Marking(points = 4) public void test_200_erzeugeArtikel() { + init(); + } + + @Test @Marking(points = 2) public void test_300_equalsAlien() { + init(); + Assert.assertNotEquals(fussBall, "Ball"); // Alien String Objekt + + } + + @Test public void test_305_equals() { + init(); + + Assert.assertFalse(fussBall.equals(null)); + + Assert.assertTrue(fussBall.equals(ball)); // Gleiche Artikelnummer + Assert.assertFalse(fussBall.equals(flummi)); // Ungleiche Artikelnummer + } + + @Test public void test_310_hashCode() { + init(); + Assert.assertEquals(fussBall.hashCode(), ball.hashCode()); + } + + @Test @Marking(points = 3) public void test_320_hashCodeQuality() { + + final int hashcode_1001; + { + final Artikel referenz = newArtikel("Dummy", 1001, 2250); + hashcode_1001 = referenz.hashCode(); + } + + int countEqual1000 = 0; + for (int i = 1; i <= 1000; i++) { + final Artikel a = newArtikel("Dummy", i, 2250); + if (hashcode_1001 == a.hashCode()) { + countEqual1000++; + } + } + Assert.assertTrue( countEqual1000 / 10. + "% identische Hash Werte: Very bad!", + countEqual1000 < 20); // Identische Hash Werte unter 2% + } + + @Test @Marking(points = 2) public void test_400_toString() { + init(); + Assert.assertEquals("Fußball, Artikelnummer 234 zu 22.50€", fussBall.toString()); + Assert.assertEquals("250 Teile Puzzle, Artikelnummer 400 zu 7.80€", puzzle.toString()); + } + + @Test @Marking(points = 3) public void test_500_toString_nurCent() { + init(); + Assert.assertEquals("Flummi, Artikelnummer 420 zu 0.89€", flummi.toString()); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java new file mode 100644 index 000000000..4d0cd1532 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java @@ -0,0 +1,127 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.stream.Collectors; + + +public class ReflectClass<T> { + + public ReflectClass(final String className) { + this.className = className; + Class classTmp = null; + String tmpMsg = null; + try { + classTmp = Class.forName(className); + } catch (final ClassNotFoundException e) { + tmpMsg = "Die Klasse '" + className + "' wurde nicht gefunden:"; + } + classZ = classTmp; + msg = tmpMsg; + } + + ReflectClass(final Class<T> classZ) { + this.className = classZ.getName(); + this.classZ = classZ; + msg = null; + } + + final String className; + final Class<T> classZ; + public final String msg; + + /** + * @param arguments List of classes. + * @return Class names joined by ',', possibly stripped of "java.lang" component + */ + public static String formatArguments(final Class<?>[] arguments) { + + return Arrays.stream(arguments). + map(ReflectClass::normalizeClassname). + collect(Collectors.joining(", ")); + } + + /** + * @param classz Arbitrary class. + * @return The classname possible stripped of "java.lang" component. Fully qualified class names belonging + * to other packages remain untouched. + */ + private static String normalizeClassname(final Class<?> classz) { + final Package + javaDotLang = ReflectClass.class.getClassLoader().getDefinedPackage("java.lang"), + hostingPackage = classz.getPackage(); + + if (null == hostingPackage || !hostingPackage.equals(javaDotLang)) { + return classz.getName(); + } else { + return classz.getSimpleName(); + } + } + + /** + * @param classz Class whose attributes are to be retrieved. + * @return A string containing a comma separated list of all non-private attribute names + */ + public static String getNonPrivateAttributes(final Class<?> classz) { + + final Field[] fields = classz.getDeclaredFields(); + final StringBuilder results = new StringBuilder(); + boolean found = false; + for (final Field f : fields) { + if (0 == (Modifier.PRIVATE & f.getModifiers())) { + if (found) { + results.append(", "); + } + results.append(f.getName()); + found = true; + } + } + if (found) { + return results.toString(); + } + return null; + } + + /** + * Get modifier cleartext name according to + * https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html#field.summary + * + * @param modifier Type declaration modifier e.g. "abstract", "final", ... + * @return Clear text name e.g. "final" + */ + static public String getModifierString(final int modifier) { + + switch (modifier) { + case Modifier.ABSTRACT: + return "abstract"; + case Modifier.FINAL: + return "final"; + case Modifier.INTERFACE: + return "interface"; + case Modifier.NATIVE: + return "native"; + case Modifier.PRIVATE: + return "private"; + case Modifier.PROTECTED: + return "protected"; + case Modifier.PUBLIC: + return "public"; + case Modifier.STATIC: + return "static"; + case Modifier.STRICT: + return "strict"; + case Modifier.SYNCHRONIZED: + return "synchronized"; + case Modifier.TRANSIENT: + return "transient"; + case Modifier.VOLATILE: + return "volatile"; + + default: + return "Unknown modifier value " + modifier; + } + + } + +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java new file mode 100644 index 000000000..cd5e3bdca --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java @@ -0,0 +1,38 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import java.lang.reflect.Constructor; + +public class ReflectConstructor<T> { + + public ReflectConstructor(final ReflectClass<T> reflectClass, final Class<?>[] argumentMeta) { + this.definingClass = reflectClass; + Constructor<?> constructorTmp = null; + String tmpMsg = null; + if (null == reflectClass.classZ) { + tmpMsg = "Folgefehler: Klasse '" + reflectClass.className + "' nicht definiert"; + } else { + try { + constructorTmp = reflectClass.classZ.getConstructor(argumentMeta); + } catch (final NoSuchMethodException | SecurityException e) { + tmpMsg = "Kein Konstruktor '" + + reflectClass.classZ.getSimpleName() + "(" + + ReflectClass.formatArguments(argumentMeta) + + ")' in Klasse '" + + reflectClass.className + "' gefunden"; + } + } + constructor = (Constructor<T>) constructorTmp; + msg = tmpMsg; + } + public String getRecursiveMsg() { + if (null == definingClass.msg) { + return msg; + } else { + return "Folgefehler: " + definingClass.msg; + } + } + + public final ReflectClass<T> definingClass; + public final Constructor<T> constructor; + private final String msg; +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java new file mode 100644 index 000000000..79e7e1e2c --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java @@ -0,0 +1,124 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import java.lang.reflect.Method; + + +/** + * Describing a method to be instantiated by its string name within a given class + */ +public class ReflectMethod<T> { + + /** + * Metainfo about a method being defined in a given class. + * + * @param reflectClass Describing the class in question + * @param reflectMethodName The method's name. + * @param argumentMeta The method's arguments + */ + public ReflectMethod(final ReflectClass<T> reflectClass, final String reflectMethodName, final Class<?>[] argumentMeta) { + this.definingReflectClass = reflectClass; + Method methodTmp = null; + String tmpMsg = null; + if (null == reflectClass.classZ) { + tmpMsg = "Folgefehler: Klasse '" + reflectClass.className + "' nicht definiert"; + } else { + try { + methodTmp = reflectClass.classZ.getMethod(reflectMethodName, argumentMeta); + } catch (NoSuchMethodException | SecurityException e) { + tmpMsg = "Keine Methode '" + reflectMethodName + "(" + ")' in Klasse '" + reflectClass.className + "' gefunden"; + } + } + method = methodTmp; + msg = tmpMsg; + } + + /** + * Ausgangsklasse, in welcher die Methode vorhanden ist. + */ + public final ReflectClass<T> definingReflectClass; + + /** + * + */ + public final Method method; + private final String msg; + + + /** + * Providing error message in case the searched method was not found + * + * @return Explanation if method was not found, null otherwise + */ + public String getRecursiveErrorMsg() { + if (null == definingReflectClass.msg) { + return msg; + } else { + return "Folgefehler: " + definingReflectClass.msg; + } + } + + /** + * Assert whether the method is being defined in a given class. + * + * @param expectedClass Class to be examined for method definition. + * @return null if defined in expected class, error message otherwise + */ + public String assertIsDefinedIn(final String expectedClass) { + final Class<?> definingClass = method.getDeclaringClass(); + + if (expectedClass.equals(definingClass.getName())) { + return null; + } else { + return method.getName() +" ist in '" + definingClass.getName() + "' definiert, aber nicht in '" + + expectedClass + "'"; + } + } + + /** + * Assert whether the method is being defined in a given class. + * + * @param expectedClass Class to be examined for method definition. + * @return null if defined in expected class, error message otherwise + */ + public String assertIsDefinedIn(final Class<?> expectedClass) { + final Class<?> definingClass = method.getDeclaringClass(); + + if (expectedClass.equals(definingClass)) { + return null; + } else { + return method.getName() +" ist in '" + definingClass.getName() + "' definiert, aber nicht in '" + + expectedClass.getName() + "'"; + } + } + + /** + * Check for presence of mandatory modifier. + * + * @param modifier Modifier to be present. + * @return null if desired modifier is present, descriptive message otherwise. + */ + public String assertModifierIsPresent(final int modifier) { + + if (0 == (modifier & method.getModifiers())) { + return "Modifier '" + ReflectClass.getModifierString(modifier) + "' not present"; + } else { + return null; + } + } + + /** + * Check for presence of modifier. + * + * @param modifier Modifier to be present. + * @param msg informative message. + * @return null if desired modifier is present, descriptive message otherwise. + */ + public String assertModifierIsPresent(final int modifier, final String msg) { + + if (0 == (modifier & method.getModifiers())) { + return msg; + } else { + return null; + } + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java new file mode 100644 index 000000000..45a138ea1 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Exam/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java @@ -0,0 +1,26 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import de.hdm_stuttgart.mi.sd1.aufgabe2.Artikel; + +public class ReflectionHelper { + + public ReflectionHelper() { + + // Ersatzteil + // + artikel_Klasse = new ReflectClass(Artikel.class); + artikel_new_Bez_id_preis = new ReflectConstructor( + artikel_Klasse, + new Class[]{String.class, int.class, int.class} + ); + artikel_toString = new ReflectMethod(artikel_Klasse, "toString", new Class[]{}); + artikel_equals = new ReflectMethod(artikel_Klasse, "equals", new Class[]{Object.class}); + } + + // Ersatzteil + // + public final ReflectClass<Artikel> artikel_Klasse; + public final ReflectConstructor<Artikel> artikel_new_Bez_id_preis; + public final ReflectMethod artikel_toString, artikel_equals; + +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/.gitignore b/Klausuren/Sd1/2018summer/Solve/.gitignore new file mode 100644 index 000000000..a2fa20469 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/.gitignore @@ -0,0 +1,5 @@ +/.classpath +/.project +/.settings +/.idea +/*.iml diff --git a/Klausuren/Sd1/2018summer/Solve/Doc/klausur.xml b/Klausuren/Sd1/2018summer/Solve/Doc/klausur.xml new file mode 100644 index 000000000..e3f4572dc --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/Doc/klausur.xml @@ -0,0 +1,446 @@ +<?xml version="1.0" encoding="UTF-8"?> +<book version="5.0" xml:id="klausur_SoSe_2018" xml:lang="de" + xmlns="http://docbook.org/ns/docbook" + 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:trans="http://docbook.org/ns/transclusion" + 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/> + + <author> + <personname/> + </author> + + <pubdate/> + </info> + + <chapter xml:id="task1"> + <title>Klassenmethoden</title> + + <!-- Hier gemeinsames zip Archiv hochladen, auch von anderen Aufgaben. --> + + <section xml:id="aufgabe1_prepare"> + <title>Vorbereitung</title> + + <para>Entpacken Sie das oben sichtbare Archiv + <filename>exam.zip</filename> und importieren Sie den resultierenden + Ordner <filename>Exam</filename> als <productname>Maven</productname> + Projekt in IntelliJ.</para> + </section> + + <section xml:id="aufgabe1_descr"> + <title>Beschreibung</title> + + <para>Implementierung vorbereiteter Methoden gemäß + <productname>Javadoc</productname> Beschreibungen und nachfolgend + beschriebener Funktionalitäten. Sie bekommen bei unvollständiger + Implementierung Teilpunkte.</para> + </section> + + <section xml:id="aufgabe1_task"> + <title>Aufgabe</title> + + <para>Vervollständigen Sie die Implementierung aller Methoden aus + folgenden Klassen im <foreignphrase + xml:lang="en">package</foreignphrase> + <package>de.hdm_stuttgart.mi.sd1.aufgabe1</package>:</para> + + <informaltable border="1"> + <tr> + <th>Zu implementieren</th> + + <th>Zugehörige Testklasse</th> + </tr> + + <tr> + <td><classname>MathHelper</classname></td> + + <td><classname>Test_MathHelper</classname></td> + </tr> + + <tr> + <td><classname>StringHelper</classname></td> + + <td><classname>Test_StringHelper</classname></td> + </tr> + + <tr> + <td><classname>ArrayHelper</classname></td> + + <td><classname>Test_ArrayHelper</classname></td> + </tr> + </informaltable> + </section> + + <section xml:id="aufgabe1_commonHints"> + <title>Allgemeine Hinweise</title> + + <itemizedlist> + <listitem> + <para>Die von Ihnen erreichte Punktzahl richtet sich nach der Anzahl + positiv bestandener Tests. Sie bekommen keine Punkte, wenn Ihre + Implementierung in Bezug auf einen einzelnen Test lediglich + <quote>fast richtig</quote> ist. Implementieren Sie im Zweifelsfall + weniger Methoden, diese dafür aber vollständig.</para> + </listitem> + + <listitem> + <para>Die <productname>Javadoc</productname> Kommentare der + jeweiligen Methoden beschreiben das gewünschte Verhalten. Mittels + <option>Tools</option> --> <option>Generate JavaDoc</option> + können Sie in IntelliJ unter Angabe eines Zielverzeichnisses aus den + Javadoc Beschreibungen eine besser lesbare HTML Ausgabe + erzeugen.</para> + + <para>Lesen Sie die (generierte) Dokumentation <emphasis + role="bold">sehr genau</emphasis>.</para> + </listitem> + + <listitem> + <para>Beachten Sie alle Sonderfälle: Dazu zählen insbesondere + <code>null</code> Werte von Variablen oder enthaltene + <code>null</code> Werte in <foreignphrase + xml:lang="en">Arrays</foreignphrase>.</para> + </listitem> + + <listitem> + <para>Nutzen Sie den <foreignphrase + xml:lang="en">Debugger</foreignphrase> oder logging <foreignphrase + xml:lang="en">Statements</foreignphrase> im Fall fehlgeschlagener + Testfälle.</para> + </listitem> + + <listitem> + <para>Die Ausführung von + <package>de.hdm_stuttgart.mi.sd1.test</package>.<classname>ShowReachedPoints</classname> + im Testzweig Ihres Projekts als <productname>Java</productname> + Anwendung (nicht als Junit Test!) zeigt Ihnen zu jedem Zeitpunkt die + in allen Programmieraufgaben bislang erreichten Punkte.</para> + </listitem> + </itemizedlist> + </section> + + <section version="5.1" xml:id="uploadFirst" xml:lang="de"> + <title>Hochladen Ihrer Lösung in das Klausursystem</title> + + <para>Exportieren Sie Ihr Projekt über den Menüpunkt »File« --> + »Export to Zip File« als <filename>.zip</filename> Archiv. Wählen Sie + einen eindeutigen Namen, z.B. <filename>solution_1.zip</filename>. Laden + Sie danach <filename>solution_1.zip</filename> über die + <quote><foreignphrase xml:lang="en">Upload</foreignphrase> File</quote> + Funktion am unteren Seitenende des <productname>Ilias</productname> + Klausursystems hoch. <emphasis role="red">Wichtig</emphasis>:</para> + + <itemizedlist> + <listitem> + <para>Wählen Sie beim Hochladen nicht die falsche Datei, etwa das + Ausgangsarchiv <filename>exam.zip</filename> oder eine ältere + Version Ihres Projekts.</para> + </listitem> + + <listitem> + <para>Kontrollieren Sie nach dem Hochladen die Sichtbarkeit Ihres + <filename>solution_1.zip</filename> Archivs im Klausursystem.</para> + </listitem> + + <listitem> + <para>Sie können mehrere Versionen + <filename>solution_2.zip</filename> etc. hochladen und bei Bedarf + ältere im <productname>Ilias</productname> System löschen. Nur die + zuletzt hochgeladene Version wird bewertet.</para> + </listitem> + </itemizedlist> + + <caution> + <itemizedlist> + <listitem> + <para>Laden Sie keine Projekte mit <productname>Java</productname> + Syntaxfehlern hoch, diese werden nicht bewertet!</para> + </listitem> + + <listitem> + <para>Reservieren Sie für den Vorgang des Hochladens ausreichend + Zeit vor Klausurende.</para> + </listitem> + + <listitem> + <para>Bearbeitungen, welche sich nach Klausurende lediglich auf + Ihrem Arbeitsplatzrechner befinden, werden nicht gewertet.</para> + </listitem> + + <listitem> + <para>Das Klausursystem akzeptiert nur Archive mit der Endung + <filename>.zip</filename>.</para> + </listitem> + </itemizedlist> + </caution> + </section> + </chapter> + + <chapter xml:id="task2"> + <title>Artikel</title> + + <section xml:id="aufgabe2_prepare"> + <title>Vorbereitung</title> + + <para>Falls Sie die erste Aufgabe bearbeitet haben, arbeiten Sie einfach + an Ihrem Projekt weiter. Ansonsten lesen Sie bitte in der ersten Aufgabe + die Anleitung zum Projektimport sowie die weiteren Hinweise zum + Hochladen in das <productname>Ilias</productname> System.</para> + </section> + + <section xml:id="aufgabe2_descr"> + <title>Beschreibung</title> + + <para>Implementierung einer Klasse zur Darstellung von Artikeln. Das + Projektskelett enthält dazu eine leere Klasse + <package>de.hdm_stuttgart.mi.sd1.aufgabe2</package>.<classname>Artikel</classname> + als Ausgangspunkt für Ihre Implementierung.</para> + </section> + + <section xml:id="aufgabe2_task"> + <title>Aufgaben</title> + + <orderedlist> + <listitem> + <para>Für einen Artikel sollen dessen Bezeichnung, eine + Artikelnummer sowie der Preis in Euro-Cent (25,34€ sind + beispielsweise 2534 Cent) angegeben werden. Erweitern Sie die Klasse + so, dass z.B. der folgende Code das dargestellte Ergebnis + liefert:</para> + + <informaltable border="1"> + <tr> + <th>Code</th> + + <th>Gewünschte Ausgabe</th> + </tr> + + <tr> + <td valign="top"><programlisting language="java">final Artikel a = + new Artikel("Fahrrad", 3321, 23050); + +System.out.println(a);</programlisting></td> + + <td valign="top"><screen>Fahrrad, Artikelnummer 3321 zu 230,50€</screen></td> + </tr> + </informaltable> + </listitem> + + <listitem> + <para>Zwei Instanzen von Artikel sollen genau dann gleich sein, wenn + ihre Artikelnummern übereinstimmen. Bezeichnung und Preis sollen + hingegen in Bezug auf die Wertgleichheit zweier Artikel irrelevant + sein:</para> + + <informaltable border="1"> + <tr> + <th>Code</th> + + <th>Gewünschte Ausgabe</th> + </tr> + + <tr> + <td valign="top"><programlisting language="java">final Artikel + a = new Artikel("Ball", 9132, 4450), + b = new Artikel("Fußball", 9132, 4350), + c = new Artikel("Fahrrad", 3321, 23050); + +System.out.println("Ball / Fußball: " + a.equals(b)); +System.out.println("Ball / Fahrrad: " + a.equals(c));</programlisting></td> + + <td valign="top"><screen>Ball / Fußball: true +Ball / Fahrrad: false</screen></td> + </tr> + </informaltable> + </listitem> + + <listitem> + <para>Implementieren Sie eine kompatible <methodname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode()">hashCode()</methodname> + Methode.</para> + + <para>Hinweis: Die Unit Tests prüfen neben der formalen Korrektheit + auch die Sinnhaftigkeit der Implementierung. Eine Hash Funktion + sollte für verschiedene Objekte »meistens« unterschiedliche Werte + zurückliefern.</para> + </listitem> + </orderedlist> + + <tip> + <para>Beachten Sie die Unit Tests in + <classname>de.hdm_stuttgart.mi.sd1.test.aufgabe2.Test_Artikel</classname>.</para> + </tip> + </section> + + <section version="5.1" xml:id="uploadFollow" xml:lang="de"> + <title>Hochladen Ihrer Lösung in das Klausursystem</title> + + <para>Laden Sie die Lösung dieser Aufgabe als gemeinsamen Projekt Export + mit der ersten Aufgabe <xref linkend="task1"/> gemäß den dortigen + Hinweisen hoch. Falls Sie die erste Aufgabe ebenfalls bearbeitet haben, + enthält Ihr <foreignphrase xml:lang="en">Upload</foreignphrase> die + Lösungen zu beiden Aufgaben.</para> + + <para>Tragen Sie im Freitextfeld weiter unten genau einen der beiden + Texte ein:</para> + + <itemizedlist> + <listitem> + <para>Ich habe die aktuelle Aufgabe bearbeitet und erhoffe dafür + Punkte.</para> + </listitem> + + <listitem> + <para>Ich habe die aktuelle Aufgabe nicht bearbeitet.</para> + </listitem> + </itemizedlist> + </section> + </chapter> + + <chapter xml:id="task3"> + <title>Primitive und Klassentypen</title> + + <para>Wir vergleichen die Werte zweier Instanzen der Klassen <classname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname> + und <classname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Long.html">Long</classname>:</para> + + <informaltable border="1"> + <tr> + <th>Code</th> + + <th>Ergebnis</th> + </tr> + + <tr> + <td valign="top"><programlisting language="java">final Integer x = Integer.valueOf(44); +final long y = Long.valueOf(44); +System.out.println("Wertvergleich Integer mit Long: " + + (x.equals(y)));</programlisting></td> + + <td valign="top"><screen>Wertvergleich <classname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Integer.html">Integer</classname> mit <classname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Long.html">Long</classname>: false</screen></td> + </tr> + </informaltable> + + <para>Der Methode <methodname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#equals(java.lang.Object)">equals()</methodname> + zur Prüfung auf Wertgleichheit bei Instanzen entspricht der Operator + »<code language="java">==</code>« bei primitiven Datentypen:</para> + + <informaltable border="1"> + <tr> + <th>Code</th> + + <th>Ergebnis</th> + </tr> + + <tr> + <td valign="top"><programlisting language="java">final int a = Integer.valueOf(44); +final long b = Long.valueOf(44); +System.out.println("Wertvergleich int mit long: " + + (a == b));</programlisting></td> + + <td valign="top"><screen>Wertvergleich int mit long: true</screen></td> + </tr> + </informaltable> + + <para>Erklären Sie dieses unterschiedliche Ergebnis <code + language="java">true</code> vs. <code language="java">false</code>.</para> + + <para>Hinweis: Wie wird die <methodname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#equals(java.lang.Object)">equals()</methodname> + Methode in Bezug auf Instanzen »fremder« Klassen implementiert? Was + bewirken die Zuweisungen?</para> + </chapter> + + <chapter xml:id="task4"> + <title>Ein Interface Problem</title> + + <para>Wir betrachten:</para> + + <informaltable border="1"> + <tr> + <th>Code</th> + + <th>Compile time Fehler</th> + </tr> + + <tr> + <td valign="top"><programlisting language="java">public interface Konto { + void toString(); +}</programlisting></td> + + <td valign="top">'toString()' in 'de.hdm_stuttgart.mi.sd1.iface.Konto' + clashes with 'toString()' in 'java.lang.Object'; attempting to use + incompatible return type</td> + </tr> + </informaltable> + + <para>Erläutern Sie die Ursache dieser Fehlermeldung. Welche Beziehung + besteht zu <classname + xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html">java.lang.Object</classname>?</para> + </chapter> + + <chapter xml:id="task5"> + <title>Farbwerte, <code language="java">byte</code> und <code + language="java">int</code></title> + + <para>Ein Entwickler möchte Farbwerte nach dem RGB Modell abbilden. Die + drei Farbkomponenten rot, grün und blau stellt er jeweils als <code + language="java">byte</code> dar. Er setzt den byte Wert -128 zu null und + 127 als Maximalwert des jeweiligen Farbanteils fest. Das (rgb) Tripel + (-128, 0, 127) entspricht also null Rotanteil, mittlerem Gelbanteil und + maximalem Blauanteil.</para> + + <para>Der Entwickler möchte den Farbwert in einer fremden, von ihm nicht + veränderbaren, Klasse darstellen. Dort kann er ein nicht mehr genutztes + <code language="java">int</code> Attribut verwenden. Er möchte die drei + Farbanteile in einen int Wert umwandeln und plant dazu eine entsprechende + Methode:</para> + + <programlisting language="java">/** + * Wandele die drei Farbanteile (r, g, b) einer Farbe in einen int + * Wert. Gegenoperation zu {@link #int2rgb(int)}. + * + * @param r Rotanteil + * @param g Gelbanteil + * @param b Blauanteil + * @return Ein der Farbe eindeutig entsprechender int Wert. + */ +static public int rgb2int(final byte r, final byte g, final byte b) { + return ...; +}</programlisting> + + <para>Zudem möchte er diese <code language="java">int</code> Werte auch + wieder eindeutig in die drei Farbanteile zurückwandeln können, um so die + ursprünglichen RGB Anteile zu erhalten:</para> + + <programlisting language="java">/** + * Umwandlung eines int Farbwerts in die drei (r,g,b) Anteile. Gegenoperation + * zu {@link #rgb2int(byte, byte, byte)}. + * + * @param farbwert + * @return Ein Array der Länge drei bestehend aus den RGB Farbanteilen. + */ +static public byte[] int2rgb(final int farbwert) { + return new byte[]{..., ..., ...}; +}</programlisting> + + <para>Frage: Ist dies grundsätzlich möglich? Begründen Sie Ihre + Aussage.</para> + + <tip> + <para>Betrachten Sie die zugrundliegenden Datentypen.</para> + </tip> + </chapter> +</book> diff --git a/Klausuren/Sd1/2018summer/Solve/pom.xml b/Klausuren/Sd1/2018summer/Solve/pom.xml new file mode 100644 index 000000000..4e2caf888 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/pom.xml @@ -0,0 +1,99 @@ +<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.mi.sd1</groupId> + <artifactId>sd1_2018summer_solve</artifactId> + <version>0.9</version> + <packaging>jar</packaging> + + <name>sd1_2018summer_solve</name> + + <url>http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.lectures/sd1SectUsingMaven.html</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <repositories> + <repository> + <id>hdm-mi-internal-maven-repo</id> + <url>https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven</url> + </repository> + </repositories> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>2.6</version> + </dependency> + + <dependency> + <groupId>de.hdm_stuttgart.mi.exam</groupId> + <artifactId>unitmarking</artifactId> + <version>0.9</version> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.5.1</version> + <configuration> + <source>1.9</source> + <target>1.9</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>3.0.1</version> + <configuration> + <links> + <link>https://docs.oracle.com/javase/10/docs/api</link> + </links> + <additionalJOptions> + <additionalJOption>-html5</additionalJOption> + </additionalJOptions> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.3</version> + <configuration> + <descriptor>src/main/assembly/assembly.xml</descriptor> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <archive> + <manifest> + <mainClass>de.hdm_stuttgart.mi.sd1.test.ShowReachedPoints</mainClass> + </manifest> + </archive> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/Klausuren/Sd1/2018summer/Solve/src/main/assembly/assembly.xml b/Klausuren/Sd1/2018summer/Solve/src/main/assembly/assembly.xml new file mode 100644 index 000000000..1a2cd6054 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/main/assembly/assembly.xml @@ -0,0 +1,36 @@ +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> + <id>fat-tests</id> + <formats> + <format>jar</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <dependencySets> + <dependencySet> + <outputDirectory>/</outputDirectory> + <useProjectArtifact>true</useProjectArtifact> + <unpack>true</unpack> + <scope>test</scope> + </dependencySet> + </dependencySets> + <fileSets> + <fileSet> + <directory>${project.build.directory}/test-classes</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>**/*.class</include> + </includes> + <useDefaultExcludes>true</useDefaultExcludes> + </fileSet> + <fileSet> + <directory>${project.build.directory}/classes</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>**/*.class</include> + </includes> + <useDefaultExcludes>true</useDefaultExcludes> + </fileSet> + </fileSets> +</assembly> diff --git a/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java new file mode 100644 index 000000000..0abe68f14 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/ArrayHelper.java @@ -0,0 +1,79 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe1; + +import java.util.Arrays; + +/** + * Hilfsmethoden für Arrays. + */ +public class ArrayHelper { + + /** + * <p>Enthält ein Array ganzzahliger Werte mindestens einen mehrfach auftretenden Wert? Beispiele:</p> + * + * <ul> + * <li>In <code>{1, -5, 3, 1, 17, 6, 1}</code> ist der Wert 1 dreifach enthalten.</li> + * <li><code>{-5, 5, 4, 9}</code> enthält keinen mehrfach auftretenden Wert.</li> + * </ul> + * + * <p>Praktische Verwendung:</p> + * <pre>final int[] werte = {2, 4, 3, 0, 1, 2}; + * final boolean result = ArrayHelper.enthaeltDuplikate(werte);</pre> + * + * <p>Wegen des doppelten Auftretens des Werts »2« hat <code>result</code> den Wert <code>true</code>.</p> + * + * @param werte null oder ein Array beliebiger Ganzzahlen + * @return <code>true</code>, falls mindestens ein Wert doppelt vorkommt, ansonsten <code>false</code>. + */ + static public boolean enthaeltDuplikate(final int[] werte) { + +// // Mit streams: +// if (null == werte) { +// return false; +// } else { +// return enthaeltDuplikate(Arrays.stream(werte).boxed().toArray()); +// } + + if (null != werte) { + for (int i = 0; i < werte.length - 1; i++) { + final int start = werte[i]; + for (int j = i + 1; j < werte.length; j++) { + if (start == werte[j]) { + return true; + } + } + } + } + return false; + } + + /** + * <p>Analog zu {@link #enthaeltDuplikate(int[])}. </p> + * + * <p>Praktische Verwendung:</p> + * + * <pre>final String[] werte = {"One", null, "true", null}; + * final boolean result = ArrayHelper.enthaeltDuplikate(werte);</pre> + * + * <p>Da es keinen doppelt auftretenden String gibt und <code>null</code> Werte ignoriert werden, erhält + * <code>result</code> den Wert <code>false</code>.</p> + * + * @param werte <code>null</code> oder ein Array aus Object und <code>null</code> Werten. + * @return <code>true</code>, falls mindestens ein String doppelt vorkommt, ansonsten <code>false</code>, + * wobei enthaltene <code>null</code> Werte in Bezug auf Duplikate ignoriert werden. + */ + static public boolean enthaeltDuplikate(final Object[] werte) { + if (null != werte) { + for (int i = 0; i < werte.length - 1; i++) { + final Object start = werte[i]; + if (null != start) { + for (int j = i + 1; j < werte.length; j++) { + if (start.equals(werte[j])) { + return true; + } + } + } + } + } + return false; + } +} diff --git a/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java new file mode 100644 index 000000000..80b154808 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/MathHelper.java @@ -0,0 +1,62 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe1; + + +/** + * Spezielle Berechnungsmethoden. + */ +public class MathHelper { + + static private int wertFallsUngerade(int wert) { + if (0 == wert % 2) { + return 0; + } else { + return wert; + } + } + /** + * <p>Die Summe aller ungeraden Werte zweier Argumente. Gerade Werte werden + * bei der Summenbildung ignoriert. Beispiele:</p> + * + * <ul> + * <li>summeUngeraderWerte(3, 4) ergibt 3, weil 4 als gerader Wert ignoriert wird.</li> + * <li>summeUngeraderWerte(1, 5) ergibt 1 + 5 == 6, da beide Werte ungerade sind.</li> + * <li>summeUngeraderWerte(-4, 10) ergibt 0, weil beide Werte gerade sind und somit ignoriert werden.</li> + * + * </ul> + * + * @param a Erster Wert. + * @param b Zweiter Wert + * @return Die Summe aller ungeraden Werte beider Argumente. + */ + static public int summeUngeraderWerte(final int a, final int b) { + /* + Tip: Der »%« Operator ist Ihr Freund! + */ + + return wertFallsUngerade(a) + wertFallsUngerade(b); + } + /** + * <p>Die harmonische Reihe H(n) zu einer natürlichen Zahl 0 < n ist definiert als:</p> + * + * <p>H(n) = 1/1 + 1/2 + 1/3 + ... + 1/n</p> + * + * <p>Also beispielsweise:</p> + * <ul> + * <li>H(2) = 1 + 1/2 = 1 + 0.5 = 1.5</li> + * <li>H(3) = 1 + 1/2 + 1/3 = 11/6 = 1.8333333...</li> + * </ul> + * + * @param n Anzahl der Terme der harmonischen Reihe, mindestens 1. + * @return Der Wert H(n). + */ + static public double harmonisch(final int n) { + /* + Tip: Beachten Sie mögliche Probleme bei der Division zweier int Werte. + */ + double summe = 1; + for (int i = 2; i <= n; i++) { + summe += 1. / i; + } + return summe; + } +} diff --git a/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java new file mode 100644 index 000000000..63a3d09ac --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe1/StringHelper.java @@ -0,0 +1,89 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe1; + +/** + * Hilfsmethode für String Operationen. + */ +public class StringHelper { + + /** + * <p>Berechne den Stundenlohn gemäß den nachfolgenden Regeln in der angegebenen Reihenfolge:</p> + * + * <ol> + * <li>Bei falscher Wochentagsangabe (z.B. "Fr." oder null statt "Freitag" wird der Wert -1 zur + * Fehlererkennung zurückgeliefert.</li> + * <li>An einem Feiertag gilt unabhängig vom Wochentag ein Grundlohn von 25.-€.</li> + * <li>An einem Wochentag ("Montag" bis "Freitag") wird ein Grundlohn von 15.-€ gezahlt.</li> + * <li>Am Wochenende ("Samstag"/"Sonntag") werden 20.-€ Grundlohn gezahlt.</li> + * <li>An Feiertagen werden in einer Nachtschicht 10€ zusätzlich zum Grundlohn gezahlt.</li> + * <li>An nicht-Feiertagen verdoppelt sich der Grundlohn einer Nachtschicht.</li> + * </ol> + * + * @param wochentag Genau ein Wert aus {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", + * "Samstag", "Sonntag"} + * @param nachtschicht true, falls Nachtschicht, sonst false. + * @param feiertag true, falls Feiertag, sonst false. + * @return -1, falls der angegebene Wochentag null oder ungültig ist. Ansonsten der Stundenlohn gemäß Beschreibung. + */ + static public int berechneStundenlohn(final String wochentag, final boolean nachtschicht, boolean feiertag) { + + if (null == wochentag) { + return -1; + } + int stundenLohn; + + switch (wochentag) { + + case "Montag": + case "Dienstag": + case "Mittwoch": + case "Donnerstag": + case "Freitag": + stundenLohn = 15; + break; + + case "Samstag": + case "Sonntag": + stundenLohn = 20; + break; + + default: + return -1; + } + if (feiertag && nachtschicht) { + return 25+10; + } else if (feiertag) { // Keine Nachtschicht + return 25; + } else if (nachtschicht) { // Kein Feiertag + return 2 * stundenLohn; + } else { // Weder Feiertag noch Nachtschicht + return stundenLohn; + } + } + + /** + * <p>Hat eine Zeichenkette mindestens eine vorgegebene Länge? Beispiele:</p> + * + * <ul> + * <li>"Kurt" hat mindestens die Länge 2.</li> + * <li>"Eva" hat nicht die Mindestlänge 4.</li> + * </ul> + * + * <p>Praktische Verwendung:</p> + * <pre>boolean result = StringHelper.hatMindestlaenge("Eva", 4);</pre> + * + * <p>Die Zeichenkette "Eva" hat lediglich die Länge 3, daher erhält die Variable + * <code>result</code> den Wert <code>false</code>.</p> + * + * @param s Eine Zeichenkette oder <code>null</code>. + * @param mindestlaenge Eine geforderte, nicht-negative, Mindestlänge. + * @return true, falls die Zeichenkette mindestens die vorgegebene Länge aufweist. Der Wert <code>null</code> + * wird als leere Zeichenkette ("") behandelt. + */ + static public boolean hatMindestlaenge(final String s, final int mindestlaenge) { + if (null == s) { + return 0 == mindestlaenge; + } else { + return mindestlaenge <= s.length(); + } + } +} diff --git a/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java new file mode 100644 index 000000000..cc907a5c3 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/main/java/de/hdm_stuttgart/mi/sd1/aufgabe2/Artikel.java @@ -0,0 +1,84 @@ +package de.hdm_stuttgart.mi.sd1.aufgabe2; + +/** + * Darstellung von Verkaufsartikeln + */ +public class Artikel { + /** + * Die Bezeichung eines Artikels, z.B. »Fußball« + */ + public final String artikelBezeichnung; + + /** + * Die Artikelnummer. + */ + final int artikelNummer; + + /** + * Preisangabe in Cent + */ + public final int preis; + + /** + * Konstruktor für Artikelinstanzen. + * + * @param artikelBezeichnung Siehe {@link #artikelBezeichnung}. + * @param artikelNummer Siehe {@link #artikelNummer}. + * @param preis Siehe {@link #preis}. + */ + public Artikel(final String artikelBezeichnung, final int artikelNummer, final int preis) { + this.artikelBezeichnung = artikelBezeichnung; + this.artikelNummer = artikelNummer; + this.preis = preis; + } + + /** + * Zwei Artikel sind genau dann gleich, wenn ihre {@link #artikelNummer} identisch ist. + * @param o Das zu vergleichende Objekt. + * @return <code>true</code> falls das zu vergleichende Objekt ein {@link Artikel} mit + * identischem Wert für die {@link #artikelNummer} ist, sonst <code>false</code>. + */ + @Override + public boolean equals(Object o) { + if (o instanceof Artikel) { + final Artikel artikel = (Artikel) o; + return artikelNummer == artikel.artikelNummer; + } else { + return false; + } + } + + /** + * Berechnung im Einklang mit {@link #equals(Object)}. + * + * @return Siehe {@link Object#hashCode()} + */ + @Override + public int hashCode() { + + /* + Hinweis: Achten Sie bei der Implementierung auf die Qualität erzeugter Hash Werte: Beispielsweise ist eine + konstante Hash Funktion zwar formal korrekt, führt aber ggf. zu schlechter Performance. + + Die Qualität Ihrer Implementierung wird getestet. + */ + return artikelNummer; + } + + /** + * @return Objektdarstellung als String + */ + @Override + public String toString() { + return artikelBezeichnung + ", Artikelnummer " + artikelNummer + " zu " + euroDarstellung() + "€"; + } + + private String euroDarstellung() { + if (preis < 100) { + return "0." + preis; + } else { + final StringBuilder ret = new StringBuilder(Integer.toString(preis)); + return ret.insert(ret.length() - 2, ".").toString(); + } + } +} diff --git a/Klausuren/Sd1/2018summer/Solve/src/main/resources/log4j2.xml b/Klausuren/Sd1/2018summer/Solve/src/main/resources/log4j2.xml new file mode 100644 index 000000000..130f87a14 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/main/resources/log4j2.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration> + <Appenders> + <File name="A1" fileName="A1.log" append="false"> + <PatternLayout pattern="%t %-5p %c{2} - %m%n"/> + </File> + <Console name="STDOUT" target="SYSTEM_OUT"> + <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </Console> + </Appenders> + <Loggers> + + <!-- You my want to define class or package level per-logger rules --> + <Logger name="de.hdm_stuttgart.mi.sd1.App" level="debug"> + <AppenderRef ref="A1"/> + </Logger> + <Root level="info"> + <AppenderRef ref="STDOUT"/> + </Root> + </Loggers> +</Configuration> \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java new file mode 100644 index 000000000..354714e4d --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/ShowReachedPoints.java @@ -0,0 +1,26 @@ +package de.hdm_stuttgart.mi.sd1.test; + +import de.hdm_stuttgart.mi.exam.unitmarking.RunTests; +import de.hdm_stuttgart.mi.sd1.test.aufgabe1.Test_ArrayHelper; +import de.hdm_stuttgart.mi.sd1.test.aufgabe1.Test_MathHelper; +import de.hdm_stuttgart.mi.sd1.test.aufgabe1.Test_StringHelper; +import de.hdm_stuttgart.mi.sd1.test.aufgabe2.Test_Artikel; + +public class ShowReachedPoints { + + /** + * Execution reveals the number of reached points. + * + * @param args Unused + */ + public static void main(String[] args) { + RunTests.exec( + "Aufgabe 1" + , Test_StringHelper.class + , Test_MathHelper.class + , Test_ArrayHelper.class + ); + + RunTests.exec("Aufgabe 2", Test_Artikel.class); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java new file mode 100644 index 000000000..c8517d639 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_ArrayHelper.java @@ -0,0 +1,58 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe1; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; +import de.hdm_stuttgart.mi.sd1.aufgabe1.ArrayHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_ArrayHelper extends ExaminationTestDefaults { + + // Teste int[] Parameter + @Test public void test_380_testNull() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate((int[]) null)); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 1})); + } + @Test public void test_400_testKeinDuplikat_0() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{0})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 1})); + } + @Test @Marking(points = 3) public void test_410_testKeinDuplikat_1() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{1})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 4, 1})); + } + @Test @Marking(points = 2) public void test_420_testKeinDuplikat_2() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{-1, 2})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{1, 4, 4})); + } + + @Test @Marking(points = 2) public void test_430_testKeinDuplikat_6() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new int[]{-1, 2, 5, 9, -30, 0})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{2, 4, 3, 0, 1, 2})); + } + @Test @Marking(points = 2) public void test_440_testNull() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate((int[]) null)); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new int[]{0, 0})); + } + + // Teste Object[] parameter + @Test @Marking(points = 2) public void test_500_string_testNull() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate((String[]) null)); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new String[]{ + new String("ab"), "ab"})); + } + + @Test @Marking(points = 2) public void test_520_string_testNullEnthalten() { + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new String[]{ + new String("ab"), null, "ab"})); + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new String[]{null, null, null})); + } + + @Test @Marking(points = 2) public void test_530_string_testHeterogen() { + Assert.assertFalse(ArrayHelper.enthaeltDuplikate(new Object[]{"test", new StringBuffer("test")})); + Assert.assertTrue(ArrayHelper.enthaeltDuplikate(new Object[]{new String("test"), new String("test")})); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java new file mode 100644 index 000000000..ff17c9120 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_MathHelper.java @@ -0,0 +1,50 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe1; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; +import de.hdm_stuttgart.mi.sd1.aufgabe1.MathHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_MathHelper extends ExaminationTestDefaults { + /** + * Zwei gerade Werte. + */ + @Test @Marking(points = 4) public void test_100_nullUngeradeWerte() { + Assert.assertEquals(0, MathHelper.summeUngeraderWerte(224, -418)); + Assert.assertEquals(0, MathHelper.summeUngeraderWerte(-418, 224)); + } + /** + * Gerade und ungerade gemischt. + */ + @Test @Marking(points = 4) public void test_110_einUngeraderWert() { + Assert.assertEquals(-419, MathHelper.summeUngeraderWerte(224, -419)); + Assert.assertEquals(-3, MathHelper.summeUngeraderWerte(-3, 224)); + } + /** + * Zwei ungerade Werte. + */ + @Test @Marking(points = 4) public void test_120_zweiUngeradeWerte() { + Assert.assertEquals(-14, MathHelper.summeUngeraderWerte(-17, 3)); + Assert.assertEquals(-4, MathHelper.summeUngeraderWerte(3, -7)); + } + + @Test @Marking(points = 3) public void test_200_testHarmonisch() { + Assert.assertEquals(1., MathHelper.harmonisch(1), 1.E-14); + } + @Test @Marking(points = 3) public void test_210_testHarmonisch() { + Assert.assertEquals(1.5, MathHelper.harmonisch(2), 1.E-14); + Assert.assertEquals(1.8333333333333333, MathHelper.harmonisch(3), 1.E-14); + + Assert.assertEquals(2.9289682539682538, MathHelper.harmonisch(10), 1.E-14); + Assert.assertEquals(3.597739657143682, MathHelper.harmonisch(20), 1.E-14); + Assert.assertEquals(4.499205338329425, MathHelper.harmonisch(50), 1.E-14); + Assert.assertEquals(10.480728217229327, MathHelper.harmonisch(20000),1.E-14); + } + @Test public void test_220_testHarmonisch() { + Assert.assertEquals(10.480728217229327, MathHelper.harmonisch(20000),1.E-14); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java new file mode 100644 index 000000000..82e0c493e --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe1/Test_StringHelper.java @@ -0,0 +1,82 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe1; + +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; +import de.hdm_stuttgart.mi.sd1.aufgabe1.StringHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_StringHelper extends ExaminationTestDefaults { + + @Test @Marking(points = 4) public void test_050_testMindestlaengeNull() { + try { + Assert.assertTrue(StringHelper.hatMindestlaenge(null, 0)); + for (int i = 1; i <= 100; i++) { + Assert.assertFalse(StringHelper.hatMindestlaenge(null, i)); + } + } catch (final NullPointerException e) { + Assert.fail("Ein null String darf nicht zu einer NullPointerException führen"); + } + + } + + @Test @Marking(points = 5) public void test_060_mindestLaenge() { + + final String[] tests = {"", "Eva", "Anton", "Mal sehen!", "Und noch ein wenig länger als alle Anderen!!"}; + + for (final String s: tests) { + for (int i = 0; i <= s.length(); i++) { + Assert.assertTrue(StringHelper.hatMindestlaenge(s, i)); + } + for (int i = 1 + s.length(); i < s.length() + 300; i++) { + Assert.assertFalse(StringHelper.hatMindestlaenge(s, i)); + } + } + } + + @Test public void test_100_stundenlohn_null() { + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, false, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, true, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, false, true)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn(null, true, true)); + } + + @Test public void test_120_stundenlohn_invalid() { + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Do.", false, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Sa", true, false)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Monday", false, true)); + Assert.assertEquals(-1, StringHelper.berechneStundenlohn("Phantasie", true, true)); + } + + @Test public void test_130_stundenlohn_standard() { + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Montag", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Dienstag", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Mittwoch", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Donnerstag", false, false)); + Assert.assertEquals(15, StringHelper.berechneStundenlohn("Freitag", false, false)); + Assert.assertEquals(20, StringHelper.berechneStundenlohn("Samstag", false, false)); + Assert.assertEquals(20, StringHelper.berechneStundenlohn("Sonntag", false, false)); + } + + @Test public void test_140_stundenlohn_Feiertag_Tagschicht() { + Assert.assertEquals(25, StringHelper.berechneStundenlohn("Montag", false, true)); + Assert.assertEquals(25, StringHelper.berechneStundenlohn("Sonntag", false, true)); + + Assert.assertEquals(25 + 10, StringHelper.berechneStundenlohn("Montag", true, true)); + Assert.assertEquals(25 + 10, StringHelper.berechneStundenlohn("Sonntag", true, true)); + } + + @Test public void test_140_stundenlohn_normal_Nachtschicht() { + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Montag", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Dienstag", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Mittwoch", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Donnerstag", true, false)); + Assert.assertEquals(2 * 15, StringHelper.berechneStundenlohn("Freitag", true, false)); + Assert.assertEquals(2 * 20, StringHelper.berechneStundenlohn("Samstag", true, false)); + Assert.assertEquals(2 * 20, StringHelper.berechneStundenlohn("Sonntag", true, false)); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java new file mode 100644 index 000000000..c80a827f0 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/aufgabe2/Test_Artikel.java @@ -0,0 +1,109 @@ +package de.hdm_stuttgart.mi.sd1.test.aufgabe2; + + +import de.hdm_stuttgart.mi.sd1.aufgabe2.Artikel; +import de.hdm_stuttgart.mi.sd1.test.helper.ReflectionHelper; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import de.hdm_stuttgart.mi.exam.unitmarking.ExaminationTestDefaults; +import de.hdm_stuttgart.mi.exam.unitmarking.Marking; + +import java.lang.reflect.InvocationTargetException; + +/** + * . + * + */ + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class Test_Artikel extends ExaminationTestDefaults { + + private final ReflectionHelper rHelper = new ReflectionHelper(); + + private Artikel fussBall, ball, puzzle, flummi; + + private void init() { + fussBall = newArtikel("Fußball", 234, 2250); + ball = newArtikel("Ball", 234, 1030); + puzzle = newArtikel("250 Teile Puzzle", 400, 780); + flummi = newArtikel("Flummi", 420, 89); + + } + + private Artikel newArtikel(final String artikelBezeichnung, final int artikelNummer, final int preis) { + try { + final String msg = rHelper.artikel_new_Bez_id_preis.getRecursiveMsg(); + Assert.assertNull(msg, msg); + + return rHelper.artikel_new_Bez_id_preis.constructor. + newInstance(artikelBezeichnung, artikelNummer, preis); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + Assert.fail("Konnte »new Artikel(\"" + artikelBezeichnung + "\", " + artikelNummer + ", " + + preis + ")« nicht aufrufen."); + } + return null; + } + + @Test @Marking(points = 4) public void test_100_constructorDefined() { + final String msg = rHelper.artikel_new_Bez_id_preis.getRecursiveMsg(); + Assert.assertNull(msg, msg); + } + + @Test @Marking(points = 4) public void test_200_erzeugeArtikel() { + init(); + } + + @Test @Marking(points = 2) public void test_300_equalsAlien() { + init(); + Assert.assertNotEquals(fussBall, "Ball"); // Alien String Objekt + + } + + @Test public void test_305_equals() { + init(); + + Assert.assertFalse(fussBall.equals(null)); + + Assert.assertTrue(fussBall.equals(ball)); // Gleiche Artikelnummer + Assert.assertFalse(fussBall.equals(flummi)); // Ungleiche Artikelnummer + } + + @Test public void test_310_hashCode() { + init(); + Assert.assertEquals(fussBall.hashCode(), ball.hashCode()); + } + + @Test @Marking(points = 3) public void test_320_hashCodeQuality() { + + final int hashcode_1001; + { + final Artikel referenz = newArtikel("Dummy", 1001, 2250); + hashcode_1001 = referenz.hashCode(); + } + + int countEqual1000 = 0; + for (int i = 1; i <= 1000; i++) { + final Artikel a = newArtikel("Dummy", i, 2250); + if (hashcode_1001 == a.hashCode()) { + countEqual1000++; + } + } + Assert.assertTrue( countEqual1000 / 10. + "% identische Hash Werte: Very bad!", + countEqual1000 < 20); // Identische Hash Werte unter 2% + } + + @Test @Marking(points = 2) public void test_400_toString() { + init(); + Assert.assertEquals("Fußball, Artikelnummer 234 zu 22.50€", fussBall.toString()); + Assert.assertEquals("250 Teile Puzzle, Artikelnummer 400 zu 7.80€", puzzle.toString()); + } + + @Test @Marking(points = 3) public void test_500_toString_nurCent() { + init(); + Assert.assertEquals("Flummi, Artikelnummer 420 zu 0.89€", flummi.toString()); + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java new file mode 100644 index 000000000..4d0cd1532 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectClass.java @@ -0,0 +1,127 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.stream.Collectors; + + +public class ReflectClass<T> { + + public ReflectClass(final String className) { + this.className = className; + Class classTmp = null; + String tmpMsg = null; + try { + classTmp = Class.forName(className); + } catch (final ClassNotFoundException e) { + tmpMsg = "Die Klasse '" + className + "' wurde nicht gefunden:"; + } + classZ = classTmp; + msg = tmpMsg; + } + + ReflectClass(final Class<T> classZ) { + this.className = classZ.getName(); + this.classZ = classZ; + msg = null; + } + + final String className; + final Class<T> classZ; + public final String msg; + + /** + * @param arguments List of classes. + * @return Class names joined by ',', possibly stripped of "java.lang" component + */ + public static String formatArguments(final Class<?>[] arguments) { + + return Arrays.stream(arguments). + map(ReflectClass::normalizeClassname). + collect(Collectors.joining(", ")); + } + + /** + * @param classz Arbitrary class. + * @return The classname possible stripped of "java.lang" component. Fully qualified class names belonging + * to other packages remain untouched. + */ + private static String normalizeClassname(final Class<?> classz) { + final Package + javaDotLang = ReflectClass.class.getClassLoader().getDefinedPackage("java.lang"), + hostingPackage = classz.getPackage(); + + if (null == hostingPackage || !hostingPackage.equals(javaDotLang)) { + return classz.getName(); + } else { + return classz.getSimpleName(); + } + } + + /** + * @param classz Class whose attributes are to be retrieved. + * @return A string containing a comma separated list of all non-private attribute names + */ + public static String getNonPrivateAttributes(final Class<?> classz) { + + final Field[] fields = classz.getDeclaredFields(); + final StringBuilder results = new StringBuilder(); + boolean found = false; + for (final Field f : fields) { + if (0 == (Modifier.PRIVATE & f.getModifiers())) { + if (found) { + results.append(", "); + } + results.append(f.getName()); + found = true; + } + } + if (found) { + return results.toString(); + } + return null; + } + + /** + * Get modifier cleartext name according to + * https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html#field.summary + * + * @param modifier Type declaration modifier e.g. "abstract", "final", ... + * @return Clear text name e.g. "final" + */ + static public String getModifierString(final int modifier) { + + switch (modifier) { + case Modifier.ABSTRACT: + return "abstract"; + case Modifier.FINAL: + return "final"; + case Modifier.INTERFACE: + return "interface"; + case Modifier.NATIVE: + return "native"; + case Modifier.PRIVATE: + return "private"; + case Modifier.PROTECTED: + return "protected"; + case Modifier.PUBLIC: + return "public"; + case Modifier.STATIC: + return "static"; + case Modifier.STRICT: + return "strict"; + case Modifier.SYNCHRONIZED: + return "synchronized"; + case Modifier.TRANSIENT: + return "transient"; + case Modifier.VOLATILE: + return "volatile"; + + default: + return "Unknown modifier value " + modifier; + } + + } + +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java new file mode 100644 index 000000000..cd5e3bdca --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectConstructor.java @@ -0,0 +1,38 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import java.lang.reflect.Constructor; + +public class ReflectConstructor<T> { + + public ReflectConstructor(final ReflectClass<T> reflectClass, final Class<?>[] argumentMeta) { + this.definingClass = reflectClass; + Constructor<?> constructorTmp = null; + String tmpMsg = null; + if (null == reflectClass.classZ) { + tmpMsg = "Folgefehler: Klasse '" + reflectClass.className + "' nicht definiert"; + } else { + try { + constructorTmp = reflectClass.classZ.getConstructor(argumentMeta); + } catch (final NoSuchMethodException | SecurityException e) { + tmpMsg = "Kein Konstruktor '" + + reflectClass.classZ.getSimpleName() + "(" + + ReflectClass.formatArguments(argumentMeta) + + ")' in Klasse '" + + reflectClass.className + "' gefunden"; + } + } + constructor = (Constructor<T>) constructorTmp; + msg = tmpMsg; + } + public String getRecursiveMsg() { + if (null == definingClass.msg) { + return msg; + } else { + return "Folgefehler: " + definingClass.msg; + } + } + + public final ReflectClass<T> definingClass; + public final Constructor<T> constructor; + private final String msg; +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java new file mode 100644 index 000000000..79e7e1e2c --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectMethod.java @@ -0,0 +1,124 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import java.lang.reflect.Method; + + +/** + * Describing a method to be instantiated by its string name within a given class + */ +public class ReflectMethod<T> { + + /** + * Metainfo about a method being defined in a given class. + * + * @param reflectClass Describing the class in question + * @param reflectMethodName The method's name. + * @param argumentMeta The method's arguments + */ + public ReflectMethod(final ReflectClass<T> reflectClass, final String reflectMethodName, final Class<?>[] argumentMeta) { + this.definingReflectClass = reflectClass; + Method methodTmp = null; + String tmpMsg = null; + if (null == reflectClass.classZ) { + tmpMsg = "Folgefehler: Klasse '" + reflectClass.className + "' nicht definiert"; + } else { + try { + methodTmp = reflectClass.classZ.getMethod(reflectMethodName, argumentMeta); + } catch (NoSuchMethodException | SecurityException e) { + tmpMsg = "Keine Methode '" + reflectMethodName + "(" + ")' in Klasse '" + reflectClass.className + "' gefunden"; + } + } + method = methodTmp; + msg = tmpMsg; + } + + /** + * Ausgangsklasse, in welcher die Methode vorhanden ist. + */ + public final ReflectClass<T> definingReflectClass; + + /** + * + */ + public final Method method; + private final String msg; + + + /** + * Providing error message in case the searched method was not found + * + * @return Explanation if method was not found, null otherwise + */ + public String getRecursiveErrorMsg() { + if (null == definingReflectClass.msg) { + return msg; + } else { + return "Folgefehler: " + definingReflectClass.msg; + } + } + + /** + * Assert whether the method is being defined in a given class. + * + * @param expectedClass Class to be examined for method definition. + * @return null if defined in expected class, error message otherwise + */ + public String assertIsDefinedIn(final String expectedClass) { + final Class<?> definingClass = method.getDeclaringClass(); + + if (expectedClass.equals(definingClass.getName())) { + return null; + } else { + return method.getName() +" ist in '" + definingClass.getName() + "' definiert, aber nicht in '" + + expectedClass + "'"; + } + } + + /** + * Assert whether the method is being defined in a given class. + * + * @param expectedClass Class to be examined for method definition. + * @return null if defined in expected class, error message otherwise + */ + public String assertIsDefinedIn(final Class<?> expectedClass) { + final Class<?> definingClass = method.getDeclaringClass(); + + if (expectedClass.equals(definingClass)) { + return null; + } else { + return method.getName() +" ist in '" + definingClass.getName() + "' definiert, aber nicht in '" + + expectedClass.getName() + "'"; + } + } + + /** + * Check for presence of mandatory modifier. + * + * @param modifier Modifier to be present. + * @return null if desired modifier is present, descriptive message otherwise. + */ + public String assertModifierIsPresent(final int modifier) { + + if (0 == (modifier & method.getModifiers())) { + return "Modifier '" + ReflectClass.getModifierString(modifier) + "' not present"; + } else { + return null; + } + } + + /** + * Check for presence of modifier. + * + * @param modifier Modifier to be present. + * @param msg informative message. + * @return null if desired modifier is present, descriptive message otherwise. + */ + public String assertModifierIsPresent(final int modifier, final String msg) { + + if (0 == (modifier & method.getModifiers())) { + return msg; + } else { + return null; + } + } +} \ No newline at end of file diff --git a/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java new file mode 100644 index 000000000..45a138ea1 --- /dev/null +++ b/Klausuren/Sd1/2018summer/Solve/src/test/java/de/hdm_stuttgart/mi/sd1/test/helper/ReflectionHelper.java @@ -0,0 +1,26 @@ +package de.hdm_stuttgart.mi.sd1.test.helper; + +import de.hdm_stuttgart.mi.sd1.aufgabe2.Artikel; + +public class ReflectionHelper { + + public ReflectionHelper() { + + // Ersatzteil + // + artikel_Klasse = new ReflectClass(Artikel.class); + artikel_new_Bez_id_preis = new ReflectConstructor( + artikel_Klasse, + new Class[]{String.class, int.class, int.class} + ); + artikel_toString = new ReflectMethod(artikel_Klasse, "toString", new Class[]{}); + artikel_equals = new ReflectMethod(artikel_Klasse, "equals", new Class[]{Object.class}); + } + + // Ersatzteil + // + public final ReflectClass<Artikel> artikel_Klasse; + public final ReflectConstructor<Artikel> artikel_new_Bez_id_preis; + public final ReflectMethod artikel_toString, artikel_equals; + +} \ No newline at end of file -- GitLab