Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Downloads/HTW Berlin/Sem3/Prog2/ha1-main/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Set up JDK 16
uses: actions/setup-java@v2
with:
java-version: '16'
distribution: 'adopt'

- name: Build with Gradle
run: ./gradlew build
32 changes: 32 additions & 0 deletions Downloads/HTW Berlin/Sem3/Prog2/ha1-main/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build

# Ignore IntelliJ IDEA project files
.idea
18 changes: 18 additions & 0 deletions Downloads/HTW Berlin/Sem3/Prog2/ha1-main/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Hausaufgabe 1

Deadline für Abgabe per Pull Request: 24.10.2021 23:59 Uhr bzw. 27.10.2021 23:59 Uhr je nach dem in welcher Übungsgruppe Sie eingeschrieben sind.

## Aufgabenstellung

- Forken Sie dieses Repository (github.com/prog2-ws21/ha1) in Ihren eigenen GitHub Account.
- Analysieren Sie das Verhalten der Klasse `Calculator` und finden Sie ein paar Abweichungen im Vergleich zu `www.online-calculator.com` und/oder zu dem im JavaDoc beschriebenen Verhalten.
- Teilaufgabe 1: Schreiben Sie einen neuen zusätzlichen Test, der eine bisher nicht getestete Funktionalität abdeckt, die bereits funktioniert und der daher direkt grün wird.
- Teilaufgabe 2: Schreiben Sie zwei weitere zusätzliche Tests, die zwei unterschiedliche Fehlerkategorien aufdecken (d.h. deren Fehlerursachen in unterschiedlichen Methoden liegen) und somit fehlschlagen.
- Teilaufgabe 3: Schreiben Sie zwei Bugfixes (also Änderungen der Implementierungsklasse `Calculator`), so dass die zwei zuvor hinzugefügten Tests erfolgreich durchlaufen. Falls Sie dabei das Verhalten so erweitern, dass es über das im JavaDoc spezifizierte hinausgeht (aber zum Verhalten des Online Calculator passt), dann erweitern Sie bitte auch das JavaDoc entsprechend.
- Pushen Sie Ihre Tests & Änderungen auf Ihr eigenes, geforktes Repository, und zwar strukturiert in mindestens drei Commits: z.B. 1. Commit für neuer grüner Test, 2. Commit für neuer roter Test, 3. Commit für den Fix zu diesem Test, 4. Commit für weiteren neuen roter Test, 5. Commit für Fix zu diesem Test.
- Stellen Sie zum Abschluss einen Pull Request auf das obere Repository, und zwar vor der oben genannten Deadline.

## Hinweise

Sie dürfen mit Ihren Bugfixes die bestehende Implementierung deutlich verändern (z.B. die Verwendung der privaten Variablen), solange Sie dabei nicht die Signaturen (Name, Typ, Parameter) der öffentlichen Methoden ändern.
Sie dürfen auch gerne Hilfsmethoden hinzufügen, die intern von den öffentlichen Methoden aufgerufen werden, und diese internen Hilfsmethoden zum Zwecke der besseren Testbarkeit auch öffentlich (public) machen, um entsprechende Unit-Tests für diese Hilfsmethoden hinzufügen zu können.
68 changes: 68 additions & 0 deletions Downloads/HTW Berlin/Sem3/Prog2/ha1-main/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
}

repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}

dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'

// This dependency is used by the application.
implementation 'com.google.guava:guava:30.1.1-jre'
}

application {
// Define the main class for the application.
mainClass = 'htw.berlin.prog2.ha1.App'
}

tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}

// https://stackoverflow.com/questions/3963708/gradle-how-to-display-test-results-in-the-console-in-real-time#answer-36130467
tasks.withType(Test) {
testLogging {
// set options for log level LIFECYCLE
events TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_OUT
exceptionFormat TestExceptionFormat.FULL
showExceptions true
showCauses true
showStackTraces true

// set options for log level DEBUG and INFO
debug {
events TestLogEvent.STARTED,
TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_ERROR,
TestLogEvent.STANDARD_OUT
exceptionFormat TestExceptionFormat.FULL
}
info.events = debug.events
info.exceptionFormat = debug.exceptionFormat

afterSuite { desc, result ->
if (!desc.parent) { // will match the outermost suite
def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)"
def startItem = '| ', endItem = ' |'
def repeatLength = startItem.length() + output.length() + endItem.length()
println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package htw.berlin.prog2.ha1;

/**
* Eine Klasse, die das Verhalten des Online Taschenrechners imitiert, welcher auf
* https://www.online-calculator.com/ aufgerufen werden kann (ohne die Memory-Funktionen)
* und dessen Bildschirm bis zu zehn Ziffern plus einem Dezimaltrennzeichen darstellen kann.
* Enthält mit Absicht noch diverse Bugs oder unvollständige Funktionen.
*/
public class Calculator {

private String screen = "0";

private double latestValue;

private String latestOperation = "";

/**
* @return den aktuellen Bildschirminhalt als String
*/
public String readScreen() {
return screen;
}

/**
* Empfängt den Wert einer gedrückten Zifferntaste. Da man nur eine Taste auf einmal
* drücken kann muss der Wert positiv und einstellig sein und zwischen 0 und 9 liegen.
* Führt in jedem Fall dazu, dass die gerade gedrückte Ziffer auf dem Bildschirm angezeigt
* oder rechts an die zuvor gedrückte Ziffer angehängt angezeigt wird.
* @param digit Die Ziffer, deren Taste gedrückt wurde
*/
public void pressDigitKey(int digit) {
if(digit > 9 || digit < 0) throw new IllegalArgumentException();

if(screen.equals("0") || latestValue == Double.parseDouble(screen)) screen = "";

screen = screen + digit;
}

/**
* Empfängt den Befehl der C- bzw. CE-Taste (Clear bzw. Clear Entry).
* Einmaliges Drücken der Taste löscht die zuvor eingegebenen Ziffern auf dem Bildschirm
* so dass "0" angezeigt wird, jedoch ohne zuvor zwischengespeicherte Werte zu löschen.
* Wird daraufhin noch einmal die Taste gedrückt, dann werden auch zwischengespeicherte
* Werte sowie der aktuelle Operationsmodus zurückgesetzt, so dass der Rechner wieder
* im Ursprungszustand ist.
*/
public void pressClearKey() {
screen = "0";
latestOperation = "";
latestValue = 0.0;
}

/**
* Empfängt den Wert einer gedrückten binären Operationstaste, also eine der vier Operationen
* Addition, Substraktion, Division, oder Multiplikation, welche zwei Operanden benötigen.
* Beim ersten Drücken der Taste wird der Bildschirminhalt nicht verändert, sondern nur der
* Rechner in den passenden Operationsmodus versetzt.
* Beim zweiten Drücken nach Eingabe einer weiteren Zahl wird direkt des aktuelle Zwischenergebnis
* auf dem Bildschirm angezeigt. Falls hierbei eine Division durch Null auftritt, wird "Error" angezeigt.
* @param operation "+" für Addition, "-" für Substraktion, "x" für Multiplikation, "/" für Division
*/
public void pressBinaryOperationKey(String operation) {
latestValue = Double.parseDouble(screen);
latestOperation = operation;
}

/**
* Empfängt den Wert einer gedrückten unären Operationstaste, also eine der drei Operationen
* Quadratwurzel, Prozent, Inversion, welche nur einen Operanden benötigen.
* Beim Drücken der Taste wird direkt die Operation auf den aktuellen Zahlenwert angewendet und
* der Bildschirminhalt mit dem Ergebnis aktualisiert.
* @param operation "√" für Quadratwurzel, "%" für Prozent, "1/x" für Inversion
*/
public void pressUnaryOperationKey(String operation) {
latestValue = Double.parseDouble(screen);
latestOperation = operation;
var result = switch(operation) {
case "√" -> Math.sqrt(Double.parseDouble(screen));
case "%" -> Double.parseDouble(screen) / 100;
case "1/x" -> 1 / Double.parseDouble(screen);
default -> throw new IllegalArgumentException();
};
screen = Double.toString(result);
if(screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10);

}

/**
* Empfängt den Befehl der gedrückten Dezimaltrennzeichentaste, im Englischen üblicherweise "."
* Fügt beim ersten Mal Drücken dem aktuellen Bildschirminhalt das Trennzeichen auf der rechten
* Seite hinzu und aktualisiert den Bildschirm. Daraufhin eingegebene Zahlen werden rechts vom
* Trennzeichen angegeben und daher als Dezimalziffern interpretiert.
* Beim zweimaligem Drücken, oder wenn bereits ein Trennzeichen angezeigt wird, passiert nichts.
*/
public void pressDotKey() {
if(!screen.endsWith(".")) screen = screen + ".";
}

/**
* Empfängt den Befehl der gedrückten Vorzeichenumkehrstaste ("+/-").
* Zeigt der Bildschirm einen positiven Wert an, so wird ein "-" links angehängt, der Bildschirm
* aktualisiert und die Inhalt fortan als negativ interpretiert.
* Zeigt der Bildschirm bereits einen negativen Wert mit führendem Minus an, dann wird dieses
* entfernt und der Inhalt fortan als positiv interpretiert.
*/
public void pressNegativeKey() {
screen = screen.startsWith("-") ? screen.substring(1) : "-" + screen;
}

/**
* Empfängt den Befehl der gedrückten "="-Taste.
* Wurde zuvor keine Operationstaste gedrückt, passiert nichts.
* Wurde zuvor eine binäre Operationstaste gedrückt und zwei Operanden eingegeben, wird das
* Ergebnis der Operation angezeigt. Falls hierbei eine Division durch Null auftritt, wird "Error" angezeigt.
* Wird die Taste weitere Male gedrückt (ohne andere Tasten dazwischen), so wird die letzte
* Operation (ggf. inklusive letztem Operand) erneut auf den aktuellen Bildschirminhalt angewandt
* und das Ergebnis direkt angezeigt.
*/
public void pressEqualsKey() {
if ((latestOperation.equals("/")) && screen.equals("0")) screen = "Error";
else if (latestOperation.equals("*") && (screen.equals("0") || screen.equals("-0"))) screen = "0";
else {
var result = switch (latestOperation) {
case "+" -> latestValue + Double.parseDouble(screen);
case "-" -> latestValue - Double.parseDouble(screen);
case "x" -> latestValue * Double.parseDouble(screen);
case "/" -> latestValue / Double.parseDouble(screen);
default -> throw new IllegalArgumentException();
};
screen = Double.toString(result);
if (screen.endsWith(".0")) screen = screen.substring(0, screen.length() - 2);
if (screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package htw.berlin.prog2.ha1;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

@DisplayName("Retro calculator")
class CalculatorTest {

@Test
@DisplayName("should display result after adding two positive multi-digit numbers")
void testPositiveAddition() {
Calculator calc = new Calculator();

calc.pressDigitKey(2);
calc.pressDigitKey(0);
calc.pressBinaryOperationKey("+");
calc.pressDigitKey(2);
calc.pressDigitKey(0);
calc.pressEqualsKey();

String expected = "40";
String actual = calc.readScreen();

assertEquals(expected, actual);
}

@Test
@DisplayName("should display result after getting the square root of two")
void testSquareRoot() {
Calculator calc = new Calculator();

calc.pressDigitKey(2);
calc.pressUnaryOperationKey("√");

String expected = "1.41421356";
String actual = calc.readScreen();

assertEquals(expected, actual);
}

@Test
@DisplayName("should display result after subtraction two negative multi-digit numbers")
void testNegativeNumbersSubtraction() {
Calculator calc = new Calculator();

calc.pressDigitKey(5);
calc.pressNegativeKey();
calc.pressBinaryOperationKey("-");
calc.pressDigitKey(3);
calc.pressNegativeKey();
calc.pressEqualsKey();

String expected = "-2";
String actual = calc.readScreen();

assertEquals(expected, actual);
}

@Test
@DisplayName("should display 'Error' when a multi-digit number is divided by 0")
void testDivideByZero() {
Calculator calc = new Calculator();

calc.pressDigitKey(3);
calc.pressBinaryOperationKey("/");
calc.pressDigitKey(0);
calc.pressEqualsKey();

String expected = "Error";
String actual = calc.readScreen();

assertEquals(expected, actual);
}

@Test
@DisplayName("should display 0 when a multi-digit number is multiplied by 0 or -0")
void testMultipleByZero() {
Calculator calc = new Calculator();

calc.pressDigitKey(5);
calc.pressBinaryOperationKey("*");
calc.pressDigitKey(0);
calc.pressNegativeKey();
calc.pressEqualsKey();

String expected = "0";
String actual = calc.readScreen();

assertEquals(expected, actual);
}


}

Loading