Initial commit

This commit is contained in:
github-classroom[bot]
2022-05-15 19:55:34 +00:00
commit 37fbbe37ee
54 changed files with 12704 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// enabled plugins
plugins {
id 'java'
}
// Project/Module information
description = 'Lab06 Stepik Solution'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
repositories {
mavenCentral()
}
dependencies {
// Junit 5 dependencies
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.+'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.+'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.+'
// Mockito dependencies
testImplementation 'org.mockito:mockito-core:4.3.+'
}
// Test task configuration
test {
// Use JUnit platform for unit tests
useJUnitPlatform()
// Output results of individual tests
testLogging {
events "PASSED", "SKIPPED", "FAILED"
}
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,87 @@
package ch.zhaw.prog2.functional;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.Scanner;
/**
* Class taken from <a href="https://stepik.org/lesson/46943/step/2?unit=24990">Stepik exercise</a>
*/
class ChainOfResponsibilityDemo {
/**
* Accepts a request and returns new request with data wrapped in the tag <transaction>...</transaction>
*/
static RequestHandler wrapInTransactionTag = req ->
new Request(String.format("<transaction>%s</transaction>", req.getData()));
/**
* Accepts a request and returns a new request with calculated digest inside the tag <digest>...</digest>
*/
static RequestHandler createDigest = req -> {
String digest = "";
try {
final MessageDigest md5 = MessageDigest.getInstance("MD5");
final byte[] digestBytes = md5.digest(req.getData().getBytes("UTF-8"));
digest = new String(Base64.getEncoder().encode(digestBytes));
} catch (Exception ignored) {
System.out.println("An error occurred");
}
return new Request(req.getData() + String.format("<digest>%s</digest>", digest));
};
/**
* Accepts a request and returns a new request with data wrapped in the tag <request>...</request>
*/
static RequestHandler wrapInRequestTag = req ->
new Request(String.format("<request>%s</request>", req.getData()));
/**
* It should represents a chain of responsibility combined from another handlers.
* The format: commonRequestHandler = handler1.setSuccessor(handler2.setSuccessor(...))
* The combining method setSuccessor may has another name
*/
static RequestHandler commonRequestHandler = // !!! write a combination of existing handlers here
wrapInRequestTag.wrapFirst(createDigest.wrapFirst(wrapInTransactionTag));
/**
* It represents a handler and has two methods: one for handling requests and other for combining handlers
*/
@FunctionalInterface
interface RequestHandler {
// !!! write a method handle that accept request and returns new request here
// it allows to use lambda expressions for creating handlers below
Request handle(Request request);
// !!! write a default method for combining this and other handler single one
// the order of execution may be any but you need to consider it when composing handlers
// the method may has any name
default RequestHandler wrapFirst(RequestHandler otherHandler) {
return request -> handle(otherHandler.handle(request));
}
}
/**
* Immutable class for representing requests.
* If you need to change the request data then create new request.
*/
static class Request {
private final String data;
public Request(String requestData) {
this.data = requestData;
}
public String getData() {
return data;
}
}
// Don't change the code below
public static void main(String[] args) throws Exception {
final Scanner scanner = new Scanner(System.in);
final String requestData = scanner.nextLine();
final Request notCompletedRequest = new Request(requestData);
System.out.println(commonRequestHandler.handle(notCompletedRequest).getData());
}
}
@@ -0,0 +1,36 @@
package ch.zhaw.prog2.functional.stepik;
import java.util.List;
import java.util.function.IntPredicate;
public class ComposingPredicate {
/**
* The method represents a disjunct operator for a list of predicates.
* For an empty list it returns the always false predicate.
*/
public static IntPredicate disjunctAll(List<IntPredicate> predicates) {
return predicates.stream().reduce(x -> false, (a, b) -> a.or(b));
}
/**
* Using anyMatch to reduce compute time if possible
*/
public static IntPredicate disjunctAllFaster(List<IntPredicate> predicates) {
return i -> predicates.stream().anyMatch(p -> p.test(i));
}
/**
* Classical implementation provided by lecturer to help you solve this exercise.
* <p>
* This solution works, but you have to search a solution using streams which will lead you
* to a solution with less lines of code.
*/
public static IntPredicate disjunctAllNoStream(List<IntPredicate> predicates) {
IntPredicate disjunct = x -> false;
for (IntPredicate currentPredicate : predicates) {
disjunct = disjunct.or(currentPredicate);
}
return disjunct;
}
}
@@ -0,0 +1,68 @@
package ch.zhaw.prog2.functional.stepik;
import ch.zhaw.prog2.functional.stepik.ComposingPredicate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
import static org.junit.jupiter.api.Assertions.*;
/**
* Do not modify this test class
*/
class ComposingPredicateTest {
private static final IntPredicate isEven = x -> x % 2 == 0;
private static final IntPredicate isDividableBy3 = x -> x % 3 == 0;
private static final List<IntPredicate> predicateList = List.of(isEven, isDividableBy3);
private List<Integer> expected;
private IntStream testIntegers;
/*
* This tests your solution
*/
@Test
void disjunctAll() {
assertDoesNotThrow(
() -> ComposingPredicate.disjunctAll(List.of(x -> true)),
"You have to implement ComposingPredicate.disjunctAll"
);
IntPredicate alwaysTrue = ComposingPredicate.disjunctAll(List.of(x -> true));
assertTrue(alwaysTrue.test(1), "Test with one predicate only");
IntPredicate dividableBy2Or3 = ComposingPredicate.disjunctAll(predicateList);
assertArrayEquals(expected.toArray(), testIntegers.filter(dividableBy2Or3).boxed().toArray());
}
/*
* This tests the alternative solution which tries to reduce compute time
*/
@Test
void disjunctAllFaster() {
IntPredicate alwaysTrue = ComposingPredicate.disjunctAllFaster(List.of(x -> true));
assertTrue(alwaysTrue.test(1), "Test with one predicate only");
IntPredicate dividableBy2Or3 = ComposingPredicate.disjunctAllFaster(predicateList);
assertArrayEquals(expected.toArray(), testIntegers.filter(dividableBy2Or3).boxed().toArray());
}
/*
* This tests the given classical solution without streams
*/
@Test
void disjunctAllNoStream() {
IntPredicate alwaysTrue = ComposingPredicate.disjunctAllNoStream(List.of(x -> true));
assertTrue(alwaysTrue.test(1), "Test with one predicate only");
IntPredicate dividableBy2Or3 = ComposingPredicate.disjunctAllNoStream(predicateList);
assertArrayEquals(expected.toArray(), testIntegers.filter(dividableBy2Or3).boxed().toArray());
}
@BeforeEach
void setUp() {
testIntegers = IntStream.range(1, 10);
expected = List.of(2, 3, 4, 6, 8, 9);
}
}