From 3917c05d961cbd807bf8d9fddddc6a6ea8100a16 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Wed, 7 Jul 2021 21:32:52 +0300 Subject: [PATCH 01/22] add homework_1 --- src/main/java/homework_1/Main.java | 39 +++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java index 07c029a2..258fa682 100644 --- a/src/main/java/homework_1/Main.java +++ b/src/main/java/homework_1/Main.java @@ -1,9 +1,42 @@ package homework_1; -public class Main { +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +public class Main { public static void main(String[] args) { - System.out.println("Hello homework!"); + System.out.println("Current codepage: " + Charset.defaultCharset()); + if (Charset.defaultCharset() != StandardCharsets.UTF_8) { + System.out.println("For correct display cyrillic args need to run with \"-Dfile.encoding=\"UTF-8\"\""); + } + try { + if (args.length == 0) { + System.out.println("No arguments provided!"); + } else printOutput(args); + } catch (IOException e) { + System.err.println("Error!"); + e.printStackTrace(); + } } -} + private static void printOutput(String[] inputArgs) throws IOException { + for (String arg : inputArgs) { + if (arg.matches("error")) { + throw new IOException("Alarm!"); + } + + StringBuilder charBuffer = new StringBuilder(); + charBuffer.append("Argument: "); +// charBuffer.append(arg.length()); +// charBuffer.append(" letters"); + + String[] lettersInArg = arg.split(""); + int outputLength = Math.min(lettersInArg.length, 8); //cut off symbols more then 8 elements + for (int i = 0; i < outputLength; i++) { + charBuffer.append(lettersInArg[i]); + } + System.out.println(charBuffer); + } + } +} \ No newline at end of file From e21617692e6069677fc2316a2c2bca4e540a8f2f Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Thu, 8 Jul 2021 16:58:02 +0300 Subject: [PATCH 02/22] add readme for homework_1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d686e9f..a699ab05 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Java Core June 2021 -## *Nikolaev Artem* +## *Belyaevskov Alexander* | Number | Solution | Short description | --- | --- | --- | -| HW1 | [Console printer](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/master/src/main/java/homework_1) | The app that reads input arguments and prints them, until "error" argument | +| HW1 | [Console printer](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/AlexanderBelyaevskov/src/main/java/homework_1) | The app that reads input arguments and prints them, until "error" argument | [Link to markdown giude](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) From 6e9d1df74de5d0e2b7728833fd16b42b31f080f9 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Sat, 10 Jul 2021 11:43:44 +0300 Subject: [PATCH 03/22] simplifying solution --- src/main/java/homework_1/Main.java | 50 ++++++++++-------------------- 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java index 258fa682..51671f21 100644 --- a/src/main/java/homework_1/Main.java +++ b/src/main/java/homework_1/Main.java @@ -5,38 +5,22 @@ import java.nio.charset.StandardCharsets; public class Main { - public static void main(String[] args) { - System.out.println("Current codepage: " + Charset.defaultCharset()); - if (Charset.defaultCharset() != StandardCharsets.UTF_8) { - System.out.println("For correct display cyrillic args need to run with \"-Dfile.encoding=\"UTF-8\"\""); + public static void main(String[] args) { + if (Charset.defaultCharset() != StandardCharsets.UTF_8) { + System.out.println("For correct display cyrillic args need to run with \"-Dfile.encoding=\"UTF-8\"\""); + } + try { + if (args.length == 0) { + System.out.println("No arguments provided!"); + } else for (String arg : args) { + if (arg.matches("error")) { + throw new IOException("Alarm!"); + } + System.out.printf("%s : %s letter(s)!\n", arg, arg.length()); + } + } catch (IOException e) { + System.err.println("Error!"); + e.printStackTrace(); + } } - try { - if (args.length == 0) { - System.out.println("No arguments provided!"); - } else printOutput(args); - } catch (IOException e) { - System.err.println("Error!"); - e.printStackTrace(); - } - } - - private static void printOutput(String[] inputArgs) throws IOException { - for (String arg : inputArgs) { - if (arg.matches("error")) { - throw new IOException("Alarm!"); - } - - StringBuilder charBuffer = new StringBuilder(); - charBuffer.append("Argument: "); -// charBuffer.append(arg.length()); -// charBuffer.append(" letters"); - - String[] lettersInArg = arg.split(""); - int outputLength = Math.min(lettersInArg.length, 8); //cut off symbols more then 8 elements - for (int i = 0; i < outputLength; i++) { - charBuffer.append(lettersInArg[i]); - } - System.out.println(charBuffer); - } - } } \ No newline at end of file From f0affa53fd4af03471ee6b8db3b18425ca040aa0 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Sat, 10 Jul 2021 11:49:43 +0300 Subject: [PATCH 04/22] 1 --- src/main/java/homework_1/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java index 51671f21..f29737fc 100644 --- a/src/main/java/homework_1/Main.java +++ b/src/main/java/homework_1/Main.java @@ -16,7 +16,7 @@ public static void main(String[] args) { if (arg.matches("error")) { throw new IOException("Alarm!"); } - System.out.printf("%s : %s letter(s)!\n", arg, arg.length()); + System.out.printf("%s : %s letter(s)\n", arg, arg.length()); } } catch (IOException e) { System.err.println("Error!"); From 1a26679040dbf911888fdeb6809f4257d1b76640 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Mon, 12 Jul 2021 12:03:26 +0300 Subject: [PATCH 05/22] removed raising exeption, fixed output --- src/main/java/homework_1/Main.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java index f29737fc..eaeb4d48 100644 --- a/src/main/java/homework_1/Main.java +++ b/src/main/java/homework_1/Main.java @@ -9,18 +9,14 @@ public static void main(String[] args) { if (Charset.defaultCharset() != StandardCharsets.UTF_8) { System.out.println("For correct display cyrillic args need to run with \"-Dfile.encoding=\"UTF-8\"\""); } - try { - if (args.length == 0) { - System.out.println("No arguments provided!"); - } else for (String arg : args) { - if (arg.matches("error")) { - throw new IOException("Alarm!"); - } - System.out.printf("%s : %s letter(s)\n", arg, arg.length()); + if (args.length == 0) { + System.out.println("No arguments provided!"); + } else for (String arg : args) { + if (arg.matches("error")) { + System.err.println("Alarm!"); + break; } - } catch (IOException e) { - System.err.println("Error!"); - e.printStackTrace(); + System.out.printf("%s: %s letter(s)\n", arg, arg.length()); } } } \ No newline at end of file From 90e0b849c980b772617c1c9fbcae9728b08eaccd Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Wed, 14 Jul 2021 17:12:12 +0300 Subject: [PATCH 06/22] homework 1 fixes --- src/main/java/homework_1/Main.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java index eaeb4d48..af3f7243 100644 --- a/src/main/java/homework_1/Main.java +++ b/src/main/java/homework_1/Main.java @@ -1,6 +1,5 @@ package homework_1; -import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -11,12 +10,14 @@ public static void main(String[] args) { } if (args.length == 0) { System.out.println("No arguments provided!"); - } else for (String arg : args) { - if (arg.matches("error")) { - System.err.println("Alarm!"); - break; + } else { + for (String arg : args) { + if (arg.matches("error")) { + System.out.println("\u001B[31m" + "Alarm!" + "\u001B[0m"); + break; + } + System.out.printf("%s: %s letter(s)\n", arg, arg.length()); } - System.out.printf("%s: %s letter(s)\n", arg, arg.length()); } } } \ No newline at end of file From bc9ee77c84653d3212d573d96fd8fc6574e5382b Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Thu, 15 Jul 2021 10:19:34 +0300 Subject: [PATCH 07/22] homework 2 traffic light --- src/main/java/homework_2/TrafficLight.java | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/homework_2/TrafficLight.java diff --git a/src/main/java/homework_2/TrafficLight.java b/src/main/java/homework_2/TrafficLight.java new file mode 100644 index 00000000..b395b146 --- /dev/null +++ b/src/main/java/homework_2/TrafficLight.java @@ -0,0 +1,64 @@ +package homework_2; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class TrafficLight { + + public static final String ANSI_RED = "\u001B[31m"; + public static final String ANSI_GREEN = "\u001B[32m"; + public static final String ANSI_YELLOW = "\u001B[33m"; + + public static void main(String[] args) { + try { + int secondsValue = readIntFromConsole(); + if (secondsValue < 0) { + printError("Only positive int numbers are allowed!"); + } + else if (secondsValue > 86399) { + printError("Day is over!"); + } + else { + printTrafficLight(secondsValue); + } + } catch (Exception e) { + printError("Only int numbers are allowed!"); + } + } + + private static void printTrafficLight(int secondsValue) { + int SecondsInLastMinute = getSecondsInLastMinute(secondsValue); + String currentColor, currentColorText; + if (SecondsInLastMinute < 35) { + currentColorText = "green"; + currentColor = ANSI_GREEN; + } else if (SecondsInLastMinute < 40) { + currentColorText = "yellow"; + currentColor = ANSI_YELLOW; + } else if (SecondsInLastMinute < 55) { + currentColorText = "red"; + currentColor = ANSI_RED; + } else { + currentColorText = "yellow"; + currentColor = ANSI_YELLOW; + } + System.out.println(currentColor + "Current traffic light is " + currentColorText + "\u001B[0m"); + } + + public static void printError (String Message){ + System.out.println(ANSI_RED + "Error! " + Message + "\u001B[0m"); + } + + private static int getSecondsInLastMinute(int secNumber) { + int minutes = secNumber / 60; + return secNumber - minutes * 60; + } + + private static int readIntFromConsole() throws Exception { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.print("Enter seconds value from 0 - 86399: "); + return Integer.parseInt(reader.readLine()); + } + } + +} \ No newline at end of file From dac6415585558b490c07bec110f38fc05ecb2071 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Thu, 15 Jul 2021 10:43:43 +0300 Subject: [PATCH 08/22] homework 2 pyramid printer --- src/main/java/homework_2/PyramidPrinter.java | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/homework_2/PyramidPrinter.java diff --git a/src/main/java/homework_2/PyramidPrinter.java b/src/main/java/homework_2/PyramidPrinter.java new file mode 100644 index 00000000..20d20cc6 --- /dev/null +++ b/src/main/java/homework_2/PyramidPrinter.java @@ -0,0 +1,41 @@ +package homework_2; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class PyramidPrinter { + + public static void main(String[] args) { + try { + int pyramidValue = readIntFromConsole(); + if (pyramidValue < 0) { + printError("Only positive int numbers are allowed!"); + } + else { + printPyramid(pyramidValue); + } + } catch (Exception e) { + printError("Only int numbers are allowed!"); + } + } + + private static void printPyramid(int pyramidValue) { + String outputString = "x"; + for (int i = 0; i < pyramidValue; i++) { + System.out.println(outputString); + outputString = outputString + "x"; + } + } + + public static void printError (String Message){ + System.out.println("\u001B[31m" + "Error! " + Message + "\u001B[0m"); + } + + private static int readIntFromConsole() throws Exception { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.printf("Enter value from 0 - %s: ", Integer.MAX_VALUE); + return Integer.parseInt(reader.readLine()); + } + } + +} \ No newline at end of file From 422d07d48ed9d81581e0fb75659886f770252965 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Thu, 15 Jul 2021 19:45:36 +0300 Subject: [PATCH 09/22] homework 2 RandomCharsTable --- .../java/homework_2/RandomCharsTable.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/main/java/homework_2/RandomCharsTable.java diff --git a/src/main/java/homework_2/RandomCharsTable.java b/src/main/java/homework_2/RandomCharsTable.java new file mode 100644 index 00000000..e49f989a --- /dev/null +++ b/src/main/java/homework_2/RandomCharsTable.java @@ -0,0 +1,91 @@ +package homework_2; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Random; +import java.util.StringJoiner; + +public class RandomCharsTable { + + public static void main(String[] args) { + try { + String inputString = readInputFromConsole(); + + if (inputString.matches("[1-9]\\s+[1-9]\\s+even|\\s*[1-9]\\s*[1-9]\\s*odd")) { + + String[] paramArray = inputString.split("\\s+"); + int length = Integer.parseInt(paramArray[0]); + int width = Integer.parseInt(paramArray[1]); + int strategy = getStrategyIndex(paramArray[2]); + + char[][] charArray = getNewCharArray(length, width); + printArray(charArray, strategy); + + } + else { + System.out.println("\u001B[31m" + "Error! Input doesn't match pattern!" + "\u001B[0m"); + } + + } catch (Exception e) { + System.out.println("\u001B[31m" + "Unknown error!" + "\u001B[0m"); + } + } + + private static char[] getAlphabetLetters() { + return "abcdefghijklmnopqrstuvwxyz".toUpperCase().toCharArray(); + } + + private static int getStrategyIndex(String strategyKeyword) { + return strategyKeyword.equals("even") ? 0 : 1; //even = 0, odd = 1 + } + + private static char[][] getNewCharArray(int length, int width) { + char[][] array = new char[length][width]; + + Random rand = new Random(); + char[] alphabetLetters = getAlphabetLetters(); + + for (int i = 0; i < length; i++) { + for (int j = 0; j < width; j++) { + int randomIndex = rand.nextInt(alphabetLetters.length); + array[i][j] = alphabetLetters[randomIndex]; + } + } + return array; + } + + private static boolean strategyMatch(int strategy, char charItem) { + return (strategy == 0 && charItem % 2 == 0) || (strategy == 1 && charItem % 2 != 0); + } + + private static void printArray(char[][] charArray, int strategy) { + String modeLetters = ""; + if (strategy == 0) { + modeLetters = "Even letters - "; + } else if (strategy == 1) { + modeLetters = "Odd letters - "; + } + + StringJoiner joiner = new StringJoiner(","); + + for (int i = 0; i < charArray.length; i++) { + for (int j = 0; j < charArray[i].length; j++) { + char arrayItem = charArray[i][j]; + if (strategyMatch(strategy, arrayItem)) { + joiner.add("" + arrayItem); + } + System.out.print("|" + arrayItem); + } + System.out.println("|"); + } + System.out.println(modeLetters + joiner); + } + + private static String readInputFromConsole() throws Exception { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.print("Enter value: "); + return String.valueOf(reader.readLine()); + } + } + +} From b818068f653fb0f0fd771e9827f5974432da7b20 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Thu, 15 Jul 2021 21:05:02 +0300 Subject: [PATCH 10/22] fix readme for homework 2 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a699ab05..0ed99650 100644 --- a/README.md +++ b/README.md @@ -5,5 +5,8 @@ | Number | Solution | Short description | --- | --- | --- | | HW1 | [Console printer](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/AlexanderBelyaevskov/src/main/java/homework_1) | The app that reads input arguments and prints them, until "error" argument | +| HW2 | [Traffic light](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/TrafficLight.java) | App reads current time in seconds from the console and prints the traffic light | +| HW2 | [Pyramid printer](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/PyramidPrinter.java) | App reads positive integer numbers from the console and prints pyramid of "x" characters | +| HW2 | [Random chars table](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/RandomCharsTable.java) | App reads from the console width and length of the chart, strategy keyword (even or odd). Prints to the console the chart of random chars from A to Z, and in separate line all the chars (from the chart) that match strategy | [Link to markdown giude](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) From 5e8a0f80fb97b61f7a1eb157c5d19747e5d76a65 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Tue, 20 Jul 2021 22:22:57 +0300 Subject: [PATCH 11/22] homework 3 + test --- build.gradle | 1 + src/main/java/homework_3/ImmutableTask.java | 96 +++++++++++++++++++ .../java/homework_3/ImmutableTaskTest.java | 42 ++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/main/java/homework_3/ImmutableTask.java create mode 100644 src/test/java/homework_3/ImmutableTaskTest.java diff --git a/build.gradle b/build.gradle index b91dc843..2b34ac84 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ repositories { } dependencies { + implementation 'org.junit.jupiter:junit-jupiter:5.7.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' } diff --git a/src/main/java/homework_3/ImmutableTask.java b/src/main/java/homework_3/ImmutableTask.java new file mode 100644 index 00000000..19d8f1a7 --- /dev/null +++ b/src/main/java/homework_3/ImmutableTask.java @@ -0,0 +1,96 @@ +package homework_3; + +import java.util.Arrays; + +public final class ImmutableTask { + +// Requirements for immutable class: +// The class must be declared as final (So that child classes can’t be created) +// Data members in the class must be declared as private (So that direct access is not allowed) +// Data members in the class must be declared as final (So that we can’t change the value of it after object creation) +// A parameterized constructor should initialize all the fields performing a deep copy (So that data members can’t be modified with object reference) +// Deep Copy of objects should be performed in the getter methods (To return a copy rather than returning the actual object reference) +// No setters (To not have the option to change the value of the instance variable) +// To change class properties, class should have methods which return a new instance of a class with new properties + + private final String name; + private final String description; + private final int estimation; + private final String[] additionalInfo; + + public ImmutableTask(String name) { + this.name = name; + this.description = ""; + this.estimation = 0; + this.additionalInfo = new String[]{}; + } + + public ImmutableTask(String name, String description) { + this.name = name; + this.description = description; + this.estimation = 0; + this.additionalInfo = new String[]{}; + } + + public ImmutableTask(String name, String description, int estimation) { + this.name = name; + this.description = description; + this.estimation = estimation; + this.additionalInfo = new String[]{}; + } + + public ImmutableTask(String name, String description, int estimation, String[] additionalInfo) { + this.name = name; + this.description = description; + this.estimation = estimation; + //since array contains immutable values, shallow copy is OK + this.additionalInfo = additionalInfo.clone(); + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public int getEstimation() { + return estimation; + } + + public String[] getAdditionalInfo() { + //since array contains immutable values, shallow copy is OK + return additionalInfo.clone(); + } + + public ImmutableTask changeName (String newName){ + //since class is immutable return a new instance with changed property + return new ImmutableTask(newName, getDescription(), getEstimation(), getAdditionalInfo()); + } + + public ImmutableTask changeDescription (String newDescription){ + //since class is immutable return a new instance with changed property + return new ImmutableTask(getName(), newDescription, getEstimation(), getAdditionalInfo()); + } + + public ImmutableTask changeAdditionalInfo(int index, String value){ + if (index + 1 > additionalInfo.length){ + throw new RuntimeException("Index of AdditionalInfo is out of bounds"); + } + String[] newArray = getAdditionalInfo(); + newArray[index] = value; + //since class is immutable return a new instance with changed property + return new ImmutableTask(getName(), getDescription(), getEstimation(), newArray); + } + + @Override + public String toString() { + return String.format("name: %s\ndescription: %s\nestimation: %s\nadditionalInfo: %s", + getName(), + getDescription(), + getEstimation(), + Arrays.deepToString(getAdditionalInfo())); + } +} + diff --git a/src/test/java/homework_3/ImmutableTaskTest.java b/src/test/java/homework_3/ImmutableTaskTest.java new file mode 100644 index 00000000..6e610d12 --- /dev/null +++ b/src/test/java/homework_3/ImmutableTaskTest.java @@ -0,0 +1,42 @@ +package homework_3; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class ImmutableTaskTest { + + @Test + void test_NameIsChanged() { + + ImmutableTask task = new ImmutableTask("Immutable class"); + + ImmutableTask taskAfterChangeName = task.changeName("new name here!!!"); + assertEquals(taskAfterChangeName.getName(), "new name here!!!"); + + } + + @Test + void test_ReturnsNewObjectAfterChangeName() { + + ImmutableTask task = new ImmutableTask("Immutable class"); + + ImmutableTask taskAfterChangeName = task.changeName("new name here!!!"); + assertNotEquals(task, taskAfterChangeName); + + } + + @Test + void test_changeAdditionalInfoField() { + + String[] info = {"homework_3", "EPAM june 2021"}; + ImmutableTask task = new ImmutableTask("Immutable class", + "Implement immutable class", + 50, + info); + + String[] newArray = task.getAdditionalInfo(); + newArray[1] = "EPAM Java core 06/2021"; + assertEquals(task.getAdditionalInfo()[1], info[1]); + + } +} \ No newline at end of file From 4e00348596c0c1bb71214d59ec144ba9942f0a3f Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Tue, 20 Jul 2021 22:31:04 +0300 Subject: [PATCH 12/22] readme fix for hw3 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0ed99650..fd695ff9 100644 --- a/README.md +++ b/README.md @@ -8,5 +8,6 @@ | HW2 | [Traffic light](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/TrafficLight.java) | App reads current time in seconds from the console and prints the traffic light | | HW2 | [Pyramid printer](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/PyramidPrinter.java) | App reads positive integer numbers from the console and prints pyramid of "x" characters | | HW2 | [Random chars table](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/RandomCharsTable.java) | App reads from the console width and length of the chart, strategy keyword (even or odd). Prints to the console the chart of random chars from A to Z, and in separate line all the chars (from the chart) that match strategy | +| HW3 | [Immutable class example](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_3/ImmutableTask.java) | Example of an immutable class | [Link to markdown giude](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) From e58d14cd7541625708e1d721ba333ed8fabd0c7d Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Tue, 20 Jul 2021 22:40:01 +0300 Subject: [PATCH 13/22] add CodingBat progress reference --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fd695ff9..debb2e2a 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,6 @@ | HW2 | [Random chars table](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/RandomCharsTable.java) | App reads from the console width and length of the chart, strategy keyword (even or odd). Prints to the console the chart of random chars from A to Z, and in separate line all the chars (from the chart) that match strategy | | HW3 | [Immutable class example](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_3/ImmutableTask.java) | Example of an immutable class | +[CodingBat done page](https://codingbat.com/done?user=abelyaevskov@gmail.com&tag=6930560875) + [Link to markdown giude](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) From 1649783aff484fdfafa31b50b666d52576e64b0f Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Fri, 23 Jul 2021 10:58:04 +0300 Subject: [PATCH 14/22] HM2 refactored and tests added --- README.md | 6 +- src/main/java/homework_2/PyramidPrinter.java | 41 ----- .../java/homework_2/PyramidPrinter/Main.java | 8 + .../PyramidPrinter/PyramidPrinter.java | 49 ++++++ .../java/homework_2/RandomCharsTable.java | 91 ----------- .../homework_2/RandomCharsTable/Main.java | 8 + .../RandomCharsTable/RandomCharsTable.java | 76 +++++++++ src/main/java/homework_2/TrafficLight.java | 64 -------- .../java/homework_2/TrafficLight/Main.java | 8 + .../homework_2/TrafficLight/TrafficLight.java | 70 +++++++++ .../PyramidPrinter/PyramidPrinterTest.java | 78 ++++++++++ .../RandomCharsTableTest.java | 145 ++++++++++++++++++ .../TrafficLight/TrafficLightTest.java | 80 ++++++++++ 13 files changed, 525 insertions(+), 199 deletions(-) delete mode 100644 src/main/java/homework_2/PyramidPrinter.java create mode 100644 src/main/java/homework_2/PyramidPrinter/Main.java create mode 100644 src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java delete mode 100644 src/main/java/homework_2/RandomCharsTable.java create mode 100644 src/main/java/homework_2/RandomCharsTable/Main.java create mode 100644 src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java delete mode 100644 src/main/java/homework_2/TrafficLight.java create mode 100644 src/main/java/homework_2/TrafficLight/Main.java create mode 100644 src/main/java/homework_2/TrafficLight/TrafficLight.java create mode 100644 src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java create mode 100644 src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java create mode 100644 src/test/java/homework_2/TrafficLight/TrafficLightTest.java diff --git a/README.md b/README.md index debb2e2a..2185d111 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ | Number | Solution | Short description | --- | --- | --- | | HW1 | [Console printer](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/AlexanderBelyaevskov/src/main/java/homework_1) | The app that reads input arguments and prints them, until "error" argument | -| HW2 | [Traffic light](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/TrafficLight.java) | App reads current time in seconds from the console and prints the traffic light | -| HW2 | [Pyramid printer](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/PyramidPrinter.java) | App reads positive integer numbers from the console and prints pyramid of "x" characters | -| HW2 | [Random chars table](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/RandomCharsTable.java) | App reads from the console width and length of the chart, strategy keyword (even or odd). Prints to the console the chart of random chars from A to Z, and in separate line all the chars (from the chart) that match strategy | +| HW2 | [Traffic light](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/TrafficLight/TrafficLight.java) | App reads current time in seconds from the console and prints the traffic light | +| HW2 | [Pyramid printer](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java) | App reads positive integer numbers from the console and prints pyramid of "x" characters | +| HW2 | [Random chars table](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java) | App reads from the console width and length of the chart, strategy keyword (even or odd). Prints to the console the chart of random chars from A to Z, and in separate line all the chars (from the chart) that match strategy | | HW3 | [Immutable class example](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_3/ImmutableTask.java) | Example of an immutable class | [CodingBat done page](https://codingbat.com/done?user=abelyaevskov@gmail.com&tag=6930560875) diff --git a/src/main/java/homework_2/PyramidPrinter.java b/src/main/java/homework_2/PyramidPrinter.java deleted file mode 100644 index 20d20cc6..00000000 --- a/src/main/java/homework_2/PyramidPrinter.java +++ /dev/null @@ -1,41 +0,0 @@ -package homework_2; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -public class PyramidPrinter { - - public static void main(String[] args) { - try { - int pyramidValue = readIntFromConsole(); - if (pyramidValue < 0) { - printError("Only positive int numbers are allowed!"); - } - else { - printPyramid(pyramidValue); - } - } catch (Exception e) { - printError("Only int numbers are allowed!"); - } - } - - private static void printPyramid(int pyramidValue) { - String outputString = "x"; - for (int i = 0; i < pyramidValue; i++) { - System.out.println(outputString); - outputString = outputString + "x"; - } - } - - public static void printError (String Message){ - System.out.println("\u001B[31m" + "Error! " + Message + "\u001B[0m"); - } - - private static int readIntFromConsole() throws Exception { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { - System.out.printf("Enter value from 0 - %s: ", Integer.MAX_VALUE); - return Integer.parseInt(reader.readLine()); - } - } - -} \ No newline at end of file diff --git a/src/main/java/homework_2/PyramidPrinter/Main.java b/src/main/java/homework_2/PyramidPrinter/Main.java new file mode 100644 index 00000000..008efbde --- /dev/null +++ b/src/main/java/homework_2/PyramidPrinter/Main.java @@ -0,0 +1,8 @@ +package homework_2.PyramidPrinter; + +public class Main { + + public static void main(String[] args) { + new PyramidPrinter().run(); + } +} diff --git a/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java b/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java new file mode 100644 index 00000000..1c834f39 --- /dev/null +++ b/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java @@ -0,0 +1,49 @@ +package homework_2.PyramidPrinter; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.StringJoiner; + +public final class PyramidPrinter { + + private int inputInt; + + public void run() { + try { + readFromConsole(); + printPyramid(); + } catch (Exception e) { + System.out.println(getErrorMessage("Only 1 non-negative integer is allowed as passed parameter")); + } + } + + private void readFromConsole() throws Exception { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.printf("Enter int value from 0 - %s: ", Integer.MAX_VALUE); + String inputString = reader.readLine(); + inputInt = validateInput(inputString); + } + } + + private int validateInput(String inputString) throws IllegalArgumentException { + if (!inputString.matches("^\\d+$") || inputString.matches("0")) { + throw new IllegalArgumentException(); + } + return Integer.parseInt(inputString); + } + + private static String getErrorMessage(String message){ + return "\u001B[31m" + message + "\u001B[0m"; + } + + private void printPyramid() { + StringJoiner joiner = new StringJoiner("\r\n"); + String outputString = "x"; + for (int i = 0; i < inputInt; i++) { + joiner.add(outputString); + outputString = outputString + "x"; + } + System.out.println(joiner); + } + +} \ No newline at end of file diff --git a/src/main/java/homework_2/RandomCharsTable.java b/src/main/java/homework_2/RandomCharsTable.java deleted file mode 100644 index e49f989a..00000000 --- a/src/main/java/homework_2/RandomCharsTable.java +++ /dev/null @@ -1,91 +0,0 @@ -package homework_2; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.Random; -import java.util.StringJoiner; - -public class RandomCharsTable { - - public static void main(String[] args) { - try { - String inputString = readInputFromConsole(); - - if (inputString.matches("[1-9]\\s+[1-9]\\s+even|\\s*[1-9]\\s*[1-9]\\s*odd")) { - - String[] paramArray = inputString.split("\\s+"); - int length = Integer.parseInt(paramArray[0]); - int width = Integer.parseInt(paramArray[1]); - int strategy = getStrategyIndex(paramArray[2]); - - char[][] charArray = getNewCharArray(length, width); - printArray(charArray, strategy); - - } - else { - System.out.println("\u001B[31m" + "Error! Input doesn't match pattern!" + "\u001B[0m"); - } - - } catch (Exception e) { - System.out.println("\u001B[31m" + "Unknown error!" + "\u001B[0m"); - } - } - - private static char[] getAlphabetLetters() { - return "abcdefghijklmnopqrstuvwxyz".toUpperCase().toCharArray(); - } - - private static int getStrategyIndex(String strategyKeyword) { - return strategyKeyword.equals("even") ? 0 : 1; //even = 0, odd = 1 - } - - private static char[][] getNewCharArray(int length, int width) { - char[][] array = new char[length][width]; - - Random rand = new Random(); - char[] alphabetLetters = getAlphabetLetters(); - - for (int i = 0; i < length; i++) { - for (int j = 0; j < width; j++) { - int randomIndex = rand.nextInt(alphabetLetters.length); - array[i][j] = alphabetLetters[randomIndex]; - } - } - return array; - } - - private static boolean strategyMatch(int strategy, char charItem) { - return (strategy == 0 && charItem % 2 == 0) || (strategy == 1 && charItem % 2 != 0); - } - - private static void printArray(char[][] charArray, int strategy) { - String modeLetters = ""; - if (strategy == 0) { - modeLetters = "Even letters - "; - } else if (strategy == 1) { - modeLetters = "Odd letters - "; - } - - StringJoiner joiner = new StringJoiner(","); - - for (int i = 0; i < charArray.length; i++) { - for (int j = 0; j < charArray[i].length; j++) { - char arrayItem = charArray[i][j]; - if (strategyMatch(strategy, arrayItem)) { - joiner.add("" + arrayItem); - } - System.out.print("|" + arrayItem); - } - System.out.println("|"); - } - System.out.println(modeLetters + joiner); - } - - private static String readInputFromConsole() throws Exception { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { - System.out.print("Enter value: "); - return String.valueOf(reader.readLine()); - } - } - -} diff --git a/src/main/java/homework_2/RandomCharsTable/Main.java b/src/main/java/homework_2/RandomCharsTable/Main.java new file mode 100644 index 00000000..3741a385 --- /dev/null +++ b/src/main/java/homework_2/RandomCharsTable/Main.java @@ -0,0 +1,8 @@ +package homework_2.RandomCharsTable; + +public class Main { + + public static void main(String[] args) { + new RandomCharsTable().run(); + } +} diff --git a/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java b/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java new file mode 100644 index 00000000..7cb6ddc6 --- /dev/null +++ b/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java @@ -0,0 +1,76 @@ +package homework_2.RandomCharsTable; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Random; +import java.util.StringJoiner; + +public final class RandomCharsTable { + + private int length; + private int width; + private String strategy; + + public void run() { + try { + if (readFromConsole()) { + printArray(); + } + } catch (Exception e) { + printErrorMessage("Passed parameters should match the format [positive integer] [positive integer] [even|odd]"); + } + } + + private boolean readFromConsole() throws Exception { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.print("Enter value in format [positive integer] [positive integer] [even|odd]: "); + return validateInput(reader.readLine()); + } + } + + private boolean validateInput(String inputString) throws IllegalArgumentException { + + if (inputString.matches("\\s*[1-9]\\s+[1-9]\\s+(even|odd){1}$")) { + String[] paramArray = inputString.split("\\s+"); + length = Integer.parseInt(paramArray[0]); + width = Integer.parseInt(paramArray[1]); + strategy = paramArray[2]; + return true; + } else { + printErrorMessage("Passed parameters should match the format [positive integer] [positive integer] [even|odd]"); + return false; + } + } + + private void printErrorMessage(String message) { + System.out.println("\u001B[31m" + message + "\u001B[0m"); + } + + private void printArray() { + + StringJoiner joiner = new StringJoiner(","); + StringBuilder tableOutput = new StringBuilder(); + + Random rand = new Random(); + char[] alphabetLetters = "abcdefghijklmnopqrstuvwxyz".toUpperCase().toCharArray(); + + for (int i = 0; i < length; i++) { + for (int j = 0; j < width; j++) { + int randomIndex = rand.nextInt(alphabetLetters.length); + char letter = alphabetLetters[randomIndex]; + if (strategyMatch(letter)) { + joiner.add("" + letter); + } + tableOutput.append("|").append(letter); + } + tableOutput.append("|").append("\n\r"); + } + String lastRow = String.format("%s%s letters - %s", strategy.substring(0,1).toUpperCase(), strategy.substring(1), joiner); + System.out.println(tableOutput + lastRow); + } + + private boolean strategyMatch(char charItem) { + return (strategy.equals("even") && charItem % 2 == 0) || (strategy.equals("odd") && charItem % 2 != 0); + } + +} diff --git a/src/main/java/homework_2/TrafficLight.java b/src/main/java/homework_2/TrafficLight.java deleted file mode 100644 index b395b146..00000000 --- a/src/main/java/homework_2/TrafficLight.java +++ /dev/null @@ -1,64 +0,0 @@ -package homework_2; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -public class TrafficLight { - - public static final String ANSI_RED = "\u001B[31m"; - public static final String ANSI_GREEN = "\u001B[32m"; - public static final String ANSI_YELLOW = "\u001B[33m"; - - public static void main(String[] args) { - try { - int secondsValue = readIntFromConsole(); - if (secondsValue < 0) { - printError("Only positive int numbers are allowed!"); - } - else if (secondsValue > 86399) { - printError("Day is over!"); - } - else { - printTrafficLight(secondsValue); - } - } catch (Exception e) { - printError("Only int numbers are allowed!"); - } - } - - private static void printTrafficLight(int secondsValue) { - int SecondsInLastMinute = getSecondsInLastMinute(secondsValue); - String currentColor, currentColorText; - if (SecondsInLastMinute < 35) { - currentColorText = "green"; - currentColor = ANSI_GREEN; - } else if (SecondsInLastMinute < 40) { - currentColorText = "yellow"; - currentColor = ANSI_YELLOW; - } else if (SecondsInLastMinute < 55) { - currentColorText = "red"; - currentColor = ANSI_RED; - } else { - currentColorText = "yellow"; - currentColor = ANSI_YELLOW; - } - System.out.println(currentColor + "Current traffic light is " + currentColorText + "\u001B[0m"); - } - - public static void printError (String Message){ - System.out.println(ANSI_RED + "Error! " + Message + "\u001B[0m"); - } - - private static int getSecondsInLastMinute(int secNumber) { - int minutes = secNumber / 60; - return secNumber - minutes * 60; - } - - private static int readIntFromConsole() throws Exception { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { - System.out.print("Enter seconds value from 0 - 86399: "); - return Integer.parseInt(reader.readLine()); - } - } - -} \ No newline at end of file diff --git a/src/main/java/homework_2/TrafficLight/Main.java b/src/main/java/homework_2/TrafficLight/Main.java new file mode 100644 index 00000000..f304b17f --- /dev/null +++ b/src/main/java/homework_2/TrafficLight/Main.java @@ -0,0 +1,8 @@ +package homework_2.TrafficLight; + +public class Main { + + public static void main(String[] args) { + new TrafficLight().run(); + } +} diff --git a/src/main/java/homework_2/TrafficLight/TrafficLight.java b/src/main/java/homework_2/TrafficLight/TrafficLight.java new file mode 100644 index 00000000..f05e4169 --- /dev/null +++ b/src/main/java/homework_2/TrafficLight/TrafficLight.java @@ -0,0 +1,70 @@ +package homework_2.TrafficLight; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public final class TrafficLight { + + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_YELLOW = "\u001B[33m"; + private static final String ANSI_BLACK = "\u001B[0m"; + + private int inputInt; + + public void run() { + try { + if (readFromConsole()) { + printTrafficLight(); + } + } catch (Exception e) { + printError("Only 1 non-negative integer is allowed as passed parameter"); + } + } + + private void printTrafficLight() { + int SecondsInLastMinute = inputInt % 60; + String currentColor, currentColorText; + if (SecondsInLastMinute < 35) { + currentColorText = "green"; + currentColor = ANSI_GREEN; + } else if (SecondsInLastMinute < 40) { + currentColorText = "yellow"; + currentColor = ANSI_YELLOW; + } else if (SecondsInLastMinute < 55) { + currentColorText = "red"; + currentColor = ANSI_RED; + } else { + currentColorText = "yellow"; + currentColor = ANSI_YELLOW; + } + System.out.println(currentColor + currentColorText.toUpperCase() + ANSI_BLACK); + } + + public static void printError(String Message) { + System.out.println(ANSI_RED + "Error! " + Message + ANSI_BLACK); + } + + boolean readFromConsole() throws Exception { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.print("Enter seconds value (int) from 0 - 86399: "); + String inputString = reader.readLine(); + return validateInput(inputString); + } + } + + private boolean validateInput(String inputString) throws NumberFormatException { + boolean result = false; + int newInt = Integer.parseInt(inputString); + if (newInt < 0) { + printError("Only 1 non-negative integer is allowed as passed parameter"); + } else if (newInt > 86399) { + printError("Day is over!"); + } else { + inputInt = newInt; + result = true; + } + return result; + } + +} \ No newline at end of file diff --git a/src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java b/src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java new file mode 100644 index 00000000..6d491fd8 --- /dev/null +++ b/src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java @@ -0,0 +1,78 @@ +package homework_2.PyramidPrinter; + +import base.UnitBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.StringJoiner; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PyramidPrinterTest extends UnitBase { + + private static String welcomeMessage = String.format("Enter int value from 0 - %s: ", Integer.MAX_VALUE); + private static String errorMessage = "Only 1 non-negative integer is allowed as passed parameter"; + + @ParameterizedTest + @MethodSource("testCases") + void test_MainCases(final String input, final String expected) { + setInput(input); + new PyramidPrinter().run(); + printOut(); + removeFromOutput(welcomeMessage); + String actual = getOutput(); + assertEquals(expected, actual); + } + + static Stream testCases() { + return Stream.of( + Arguments.of("1", getOutput(1)), + //Arguments.of("2147483647", getOutput(2147483647)), //OutOfMemoryError, Java heap space + Arguments.of("3", getOutput(3)), + Arguments.of("5", getOutput(5)), + Arguments.of("133", getOutput(133)), + Arguments.of("255", getOutput(255)), + Arguments.of("0005", getOutput(5)), + Arguments.of("50", getOutput(50)) + ); + } + + @ParameterizedTest + @MethodSource("zero_Negative_NonDigit_Values") + void test_Zero_Negative_NonDigit_Values(final String input, final String expected) { + setInput(input); + new PyramidPrinter().run(); + printOut(); + removeFromOutput(welcomeMessage); + String actual = getOutput(); + assertTrue(actual.contains(expected)); + } + + static Stream zero_Negative_NonDigit_Values() { + return Stream.of( + Arguments.of("test", errorMessage), + Arguments.of("5878 545454 464", errorMessage), + Arguments.of("hello", errorMessage), + Arguments.of("0", errorMessage), + Arguments.of("-5", errorMessage), + Arguments.of("-100000000", errorMessage), + Arguments.of("", errorMessage), + Arguments.of(" ", errorMessage), + Arguments.of("2147483648", errorMessage) + ); + } + + private static String getOutput(int inputInt) { + StringJoiner joiner = new StringJoiner("\r\n"); + String outputString = "x"; + for (int i = 0; i < inputInt; i++) { + joiner.add(outputString); + outputString = outputString + "x"; + } + return joiner.toString(); + } + +} \ No newline at end of file diff --git a/src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java b/src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java new file mode 100644 index 00000000..a8896a07 --- /dev/null +++ b/src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java @@ -0,0 +1,145 @@ +package homework_2.RandomCharsTable; + +import base.UnitBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.StringJoiner; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RandomCharsTableTest extends UnitBase { + + private static final String welcomeMessage = "Enter value in format [positive integer] [positive integer] [even|odd]: "; + private static final String errorMessage = "Passed parameters should match the format [positive integer] [positive integer] [even|odd]"; + + @ParameterizedTest + @MethodSource("testCases") + void test_MainCases(final String input, final int length, final int width, final String strategy) { + + setInput(input); + new RandomCharsTable().run(); + printOut(); + removeFromOutput(welcomeMessage); + String actual = getOutput(); + + //check width + String widthCheckResult = checkWidth(actual, width); + assertTrue(widthCheckResult.isEmpty(), widthCheckResult); + + String[][] outputTable = parseOutput(actual, length, width); + + //check chars + String charsCheckResult = checkCharsInTable(outputTable); + assertTrue(charsCheckResult.isEmpty(), charsCheckResult); + + //check strategy + String strategyCheckResult = checkStrategy(actual, outputTable, strategy); + assertTrue(strategyCheckResult.isEmpty(), strategyCheckResult); + + //check length + String lengthNotCheckedMessage = String.format("Length of the table is not correct, expected %s.", length); + assertEquals(length, actual.split("\n\r").length - 1, lengthNotCheckedMessage); + + } + + static Stream testCases() { + return Stream.of( + Arguments.of("2 5 odd", 2, 5, "odd"), + Arguments.of("3 5 even", 3, 5, "even") + ); + } + + @ParameterizedTest + @MethodSource("garbageInput") + void test_garbageInput(final String input, final String expected) { + setInput(input); + new RandomCharsTable().run(); + printOut(); + removeFromOutput(welcomeMessage); + String actual = getOutput(); + assertTrue(actual.contains(expected)); + } + + static Stream garbageInput() { + return Stream.of( + Arguments.of("test", errorMessage), + Arguments.of("5 6 odd ", errorMessage), + Arguments.of("0 0 odd", errorMessage), + Arguments.of("0 0 even", errorMessage), + Arguments.of("5 6 Even", errorMessage), + Arguments.of("2 2 oddeven", errorMessage), + Arguments.of("0", errorMessage), + Arguments.of("-5", errorMessage), + Arguments.of("-100000000", errorMessage), + Arguments.of("", errorMessage), + Arguments.of(" ", errorMessage) + ); + } + + private String checkStrategy(String actual, String[][] outputTable, String strategy) { + String result = ""; + StringJoiner joiner = new StringJoiner(","); + for (String[] strings : outputTable) { + for (String string : strings) { + char letter = string.charAt(0); + if (strategyMatch(letter, strategy)) { + joiner.add("" + letter); + } + } + } + String strategyString = String.format("%s%s letters - %s", strategy.substring(0, 1).toUpperCase(), strategy.substring(1), joiner); + String[] rows = actual.split("\n\r"); + String lastRow = rows[rows.length - 1]; + if (!lastRow.matches(strategyString)) { + result = result + String.format("The last row in output is incorrect. Expected: %s.", strategyString); + } + return result; + } + + private String[][] parseOutput(String actual, int length, int width) { + String[][] result = new String[length][width]; + String[] rows = actual.split("\n\r"); + for (int i = 0; i < length; i++) { + String[] charSeqInRow = rows[i].replace("|", "").split(""); + for (int j = 0; j < width; j++) { + result[i][j] = charSeqInRow[j]; + } + } + return result; + } + + private String checkCharsInTable(String[][] outputTable) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < outputTable.length; i++) { + for (int j = 0; j < outputTable[i].length; j++) { + if (!outputTable[i][j].matches("[A-Z]")) { + result.append(String.format("In row %s char is not in [A-Z] sequence\n\r", i + 1)); + } + } + } + return result.toString(); + } + + private String checkWidth(String actual, int width) { + StringBuilder result = new StringBuilder(); + String[] rows = actual.split("\n\r"); + for (int i = 0; i < rows.length - 1; i++) { + int actualWidth = rows[i].replace("|", "").split("").length; + if (actualWidth != width) { + result.append(String.format("In row %s width is %s, but %s is expected\n\r", + i + 1, + actualWidth, + width)); + } + } + return result.toString(); + } + + private static boolean strategyMatch(char charItem, String strategy) { + return (strategy.equals("even") && charItem % 2 == 0) || (strategy.equals("odd") && charItem % 2 != 0); + } +} \ No newline at end of file diff --git a/src/test/java/homework_2/TrafficLight/TrafficLightTest.java b/src/test/java/homework_2/TrafficLight/TrafficLightTest.java new file mode 100644 index 00000000..717ecece --- /dev/null +++ b/src/test/java/homework_2/TrafficLight/TrafficLightTest.java @@ -0,0 +1,80 @@ +package homework_2.TrafficLight; + +import base.UnitBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TrafficLightTest extends UnitBase{ + + private static String welcomeMessage = "Enter seconds value (int) from 0 - 86399: "; + private static String errorMessage1 = "Only 1 non-negative integer is allowed as passed parameter"; + private static String errorMessage2 = "Day is over!"; + + @ParameterizedTest + @MethodSource("testCases") + void test_MainCases(final String input, final String expected) { + setInput(input); + new TrafficLight().run(); + printOut(); + removeFromOutput(welcomeMessage); + String actual = getOutput(); + assertTrue(actual.contains(expected)); + } + + static Stream testCases() { + return Stream.of( + Arguments.of("22", getTrafficLightOutput(22)), + Arguments.of("40", getTrafficLightOutput(40)), + Arguments.of("0", getTrafficLightOutput(0)), + Arguments.of("60", getTrafficLightOutput(60)), + Arguments.of("41", getTrafficLightOutput(41)), + Arguments.of("86399", getTrafficLightOutput(86399)), + Arguments.of("005", getTrafficLightOutput(5)) + ); + } + + @ParameterizedTest + @MethodSource("Negative_NonDigit_Values") + void test_Negative_NonDigit_Values(final String input, final String expected) { + setInput(input); + new TrafficLight().run(); + printOut(); + removeFromOutput(welcomeMessage); + String actual = getOutput(); + assertTrue(actual.contains(expected)); + } + + static Stream Negative_NonDigit_Values() { + return Stream.of( + Arguments.of("test", errorMessage1), + Arguments.of("5878 545454 464", errorMessage1), + Arguments.of("hello", errorMessage1), + Arguments.of("-5", errorMessage1), + Arguments.of("-100000000", errorMessage1), + Arguments.of("", errorMessage1), + Arguments.of(" ", errorMessage1), + Arguments.of("2147483648", errorMessage1), + Arguments.of("87399", errorMessage2) + ); + } + + private static String getTrafficLightOutput(int inputInt) { + int SecondsInLastMinute = inputInt % 60; + String currentColorText; + if (SecondsInLastMinute < 35) { + currentColorText = "green"; + } else if (SecondsInLastMinute < 40) { + currentColorText = "yellow"; + } else if (SecondsInLastMinute < 55) { + currentColorText = "red"; + } else { + currentColorText = "yellow"; + } + return currentColorText.toUpperCase(); + } +} \ No newline at end of file From 00ddf384fe1adfc576087a831f9bc0c009406c84 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Fri, 23 Jul 2021 11:07:10 +0300 Subject: [PATCH 15/22] RandomCharsTable and PyramidPrinter refactored --- .../java/homework_2/PyramidPrinter/PyramidPrinter.java | 6 +----- .../homework_2/RandomCharsTable/RandomCharsTable.java | 9 +++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java b/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java index 1c834f39..c87d44bc 100644 --- a/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java +++ b/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java @@ -13,7 +13,7 @@ public void run() { readFromConsole(); printPyramid(); } catch (Exception e) { - System.out.println(getErrorMessage("Only 1 non-negative integer is allowed as passed parameter")); + System.out.println("\u001B[31m" + "Only 1 non-negative integer is allowed as passed parameter" + "\u001B[0m"); } } @@ -32,10 +32,6 @@ private int validateInput(String inputString) throws IllegalArgumentException { return Integer.parseInt(inputString); } - private static String getErrorMessage(String message){ - return "\u001B[31m" + message + "\u001B[0m"; - } - private void printPyramid() { StringJoiner joiner = new StringJoiner("\r\n"); String outputString = "x"; diff --git a/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java b/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java index 7cb6ddc6..f904b3cf 100644 --- a/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java +++ b/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java @@ -10,6 +10,7 @@ public final class RandomCharsTable { private int length; private int width; private String strategy; + private static final String ERROR_MESSAGE = "\u001B[31m" + "Passed parameters should match the format [positive integer] [positive integer] [even|odd]" + "\u001B[0m"; public void run() { try { @@ -17,7 +18,7 @@ public void run() { printArray(); } } catch (Exception e) { - printErrorMessage("Passed parameters should match the format [positive integer] [positive integer] [even|odd]"); + System.out.println(ERROR_MESSAGE); } } @@ -37,15 +38,11 @@ private boolean validateInput(String inputString) throws IllegalArgumentExceptio strategy = paramArray[2]; return true; } else { - printErrorMessage("Passed parameters should match the format [positive integer] [positive integer] [even|odd]"); + System.out.println(ERROR_MESSAGE); return false; } } - private void printErrorMessage(String message) { - System.out.println("\u001B[31m" + message + "\u001B[0m"); - } - private void printArray() { StringJoiner joiner = new StringJoiner(","); From 1deca0fd81b76af3b58bc9026063dda647c6b460 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Sun, 1 Aug 2021 15:12:05 +0300 Subject: [PATCH 16/22] changed package names --- .../homework_2/{PyramidPrinter => pyramid_printer}/Main.java | 2 +- .../{PyramidPrinter => pyramid_printer}/PyramidPrinter.java | 2 +- .../{RandomCharsTable => random_chars_table}/Main.java | 2 +- .../RandomCharsTable.java | 2 +- .../java/homework_2/{TrafficLight => traffic_light}/Main.java | 2 +- .../{TrafficLight => traffic_light}/TrafficLight.java | 2 +- .../{PyramidPrinter => pyramid_printer}/PyramidPrinterTest.java | 2 +- .../RandomCharsTableTest.java | 2 +- .../{TrafficLight => traffic_light}/TrafficLightTest.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) rename src/main/java/homework_2/{PyramidPrinter => pyramid_printer}/Main.java (75%) rename src/main/java/homework_2/{PyramidPrinter => pyramid_printer}/PyramidPrinter.java (97%) rename src/main/java/homework_2/{RandomCharsTable => random_chars_table}/Main.java (74%) rename src/main/java/homework_2/{RandomCharsTable => random_chars_table}/RandomCharsTable.java (98%) rename src/main/java/homework_2/{TrafficLight => traffic_light}/Main.java (76%) rename src/main/java/homework_2/{TrafficLight => traffic_light}/TrafficLight.java (98%) rename src/test/java/homework_2/{PyramidPrinter => pyramid_printer}/PyramidPrinterTest.java (98%) rename src/test/java/homework_2/{RandomCharsTable => random_chars_table}/RandomCharsTableTest.java (99%) rename src/test/java/homework_2/{TrafficLight => traffic_light}/TrafficLightTest.java (98%) diff --git a/src/main/java/homework_2/PyramidPrinter/Main.java b/src/main/java/homework_2/pyramid_printer/Main.java similarity index 75% rename from src/main/java/homework_2/PyramidPrinter/Main.java rename to src/main/java/homework_2/pyramid_printer/Main.java index 008efbde..71e33035 100644 --- a/src/main/java/homework_2/PyramidPrinter/Main.java +++ b/src/main/java/homework_2/pyramid_printer/Main.java @@ -1,4 +1,4 @@ -package homework_2.PyramidPrinter; +package homework_2.pyramid_printer; public class Main { diff --git a/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java b/src/main/java/homework_2/pyramid_printer/PyramidPrinter.java similarity index 97% rename from src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java rename to src/main/java/homework_2/pyramid_printer/PyramidPrinter.java index c87d44bc..7998f254 100644 --- a/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java +++ b/src/main/java/homework_2/pyramid_printer/PyramidPrinter.java @@ -1,4 +1,4 @@ -package homework_2.PyramidPrinter; +package homework_2.pyramid_printer; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/src/main/java/homework_2/RandomCharsTable/Main.java b/src/main/java/homework_2/random_chars_table/Main.java similarity index 74% rename from src/main/java/homework_2/RandomCharsTable/Main.java rename to src/main/java/homework_2/random_chars_table/Main.java index 3741a385..be586c4b 100644 --- a/src/main/java/homework_2/RandomCharsTable/Main.java +++ b/src/main/java/homework_2/random_chars_table/Main.java @@ -1,4 +1,4 @@ -package homework_2.RandomCharsTable; +package homework_2.random_chars_table; public class Main { diff --git a/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java b/src/main/java/homework_2/random_chars_table/RandomCharsTable.java similarity index 98% rename from src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java rename to src/main/java/homework_2/random_chars_table/RandomCharsTable.java index f904b3cf..d7be4196 100644 --- a/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java +++ b/src/main/java/homework_2/random_chars_table/RandomCharsTable.java @@ -1,4 +1,4 @@ -package homework_2.RandomCharsTable; +package homework_2.random_chars_table; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/src/main/java/homework_2/TrafficLight/Main.java b/src/main/java/homework_2/traffic_light/Main.java similarity index 76% rename from src/main/java/homework_2/TrafficLight/Main.java rename to src/main/java/homework_2/traffic_light/Main.java index f304b17f..3ff7f428 100644 --- a/src/main/java/homework_2/TrafficLight/Main.java +++ b/src/main/java/homework_2/traffic_light/Main.java @@ -1,4 +1,4 @@ -package homework_2.TrafficLight; +package homework_2.traffic_light; public class Main { diff --git a/src/main/java/homework_2/TrafficLight/TrafficLight.java b/src/main/java/homework_2/traffic_light/TrafficLight.java similarity index 98% rename from src/main/java/homework_2/TrafficLight/TrafficLight.java rename to src/main/java/homework_2/traffic_light/TrafficLight.java index f05e4169..9ecd9979 100644 --- a/src/main/java/homework_2/TrafficLight/TrafficLight.java +++ b/src/main/java/homework_2/traffic_light/TrafficLight.java @@ -1,4 +1,4 @@ -package homework_2.TrafficLight; +package homework_2.traffic_light; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java b/src/test/java/homework_2/pyramid_printer/PyramidPrinterTest.java similarity index 98% rename from src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java rename to src/test/java/homework_2/pyramid_printer/PyramidPrinterTest.java index 6d491fd8..0e8b72e5 100644 --- a/src/test/java/homework_2/PyramidPrinter/PyramidPrinterTest.java +++ b/src/test/java/homework_2/pyramid_printer/PyramidPrinterTest.java @@ -1,4 +1,4 @@ -package homework_2.PyramidPrinter; +package homework_2.pyramid_printer; import base.UnitBase; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java b/src/test/java/homework_2/random_chars_table/RandomCharsTableTest.java similarity index 99% rename from src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java rename to src/test/java/homework_2/random_chars_table/RandomCharsTableTest.java index a8896a07..bde6b13e 100644 --- a/src/test/java/homework_2/RandomCharsTable/RandomCharsTableTest.java +++ b/src/test/java/homework_2/random_chars_table/RandomCharsTableTest.java @@ -1,4 +1,4 @@ -package homework_2.RandomCharsTable; +package homework_2.random_chars_table; import base.UnitBase; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/homework_2/TrafficLight/TrafficLightTest.java b/src/test/java/homework_2/traffic_light/TrafficLightTest.java similarity index 98% rename from src/test/java/homework_2/TrafficLight/TrafficLightTest.java rename to src/test/java/homework_2/traffic_light/TrafficLightTest.java index 717ecece..03e74d3e 100644 --- a/src/test/java/homework_2/TrafficLight/TrafficLightTest.java +++ b/src/test/java/homework_2/traffic_light/TrafficLightTest.java @@ -1,4 +1,4 @@ -package homework_2.TrafficLight; +package homework_2.traffic_light; import base.UnitBase; import org.junit.jupiter.params.ParameterizedTest; From 3e1aafadae5e97185608a5f569006e1c6ee034bf Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Mon, 16 Aug 2021 16:25:40 +0300 Subject: [PATCH 17/22] homework 4 --- .../custom_annotation/ChangeOutputName.java | 12 ++++ .../custom_annotation/Customer.java | 65 +++++++++++++++++++ .../homework_4/custom_annotation/Main.java | 14 ++++ .../custom_file_reader/CustomFileReader.java | 61 +++++++++++++++++ .../homework_4/custom_file_reader/Main.java | 11 ++++ .../singleton/DatabaseConnection.java | 32 +++++++++ .../singleton/EnumDatabaseConnection.java | 25 +++++++ src/main/java/homework_4/singleton/Main.java | 30 +++++++++ src/main/resources/custom_file_reader | 14 ++++ .../CustomAnnotationTest.java | 31 +++++++++ .../CustomFileReaderTest.java | 55 ++++++++++++++++ .../homework_4/singleton/SingletonTest.java | 17 +++++ 12 files changed, 367 insertions(+) create mode 100644 src/main/java/homework_4/custom_annotation/ChangeOutputName.java create mode 100644 src/main/java/homework_4/custom_annotation/Customer.java create mode 100644 src/main/java/homework_4/custom_annotation/Main.java create mode 100644 src/main/java/homework_4/custom_file_reader/CustomFileReader.java create mode 100644 src/main/java/homework_4/custom_file_reader/Main.java create mode 100644 src/main/java/homework_4/singleton/DatabaseConnection.java create mode 100644 src/main/java/homework_4/singleton/EnumDatabaseConnection.java create mode 100644 src/main/java/homework_4/singleton/Main.java create mode 100644 src/main/resources/custom_file_reader create mode 100644 src/test/java/homework_4/custom_annotation/CustomAnnotationTest.java create mode 100644 src/test/java/homework_4/custom_file_reader/CustomFileReaderTest.java create mode 100644 src/test/java/homework_4/singleton/SingletonTest.java diff --git a/src/main/java/homework_4/custom_annotation/ChangeOutputName.java b/src/main/java/homework_4/custom_annotation/ChangeOutputName.java new file mode 100644 index 00000000..d1599243 --- /dev/null +++ b/src/main/java/homework_4/custom_annotation/ChangeOutputName.java @@ -0,0 +1,12 @@ +package homework_4.custom_annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ChangeOutputName { + String value(); +} diff --git a/src/main/java/homework_4/custom_annotation/Customer.java b/src/main/java/homework_4/custom_annotation/Customer.java new file mode 100644 index 00000000..43748ba6 --- /dev/null +++ b/src/main/java/homework_4/custom_annotation/Customer.java @@ -0,0 +1,65 @@ +package homework_4.custom_annotation; + +import java.lang.reflect.Field; + +public class Customer { + + @ChangeOutputName("Наименование") + private String name; + @ChangeOutputName("Полное имя") + private String fullName; + private String address; + @ChangeOutputName("Номер телефона") + private String phoneNumber; + + public Customer() { + } + + public Customer(String name, String fullName) { + this.name = name; + this.fullName = fullName; + } + + public void setName(String name) { + this.name = name; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + @Override + public String toString() { + + String result = "Customer{" + + "%s='" + name + '\'' + + ", %s='" + fullName + '\'' + + ", %s='" + address + '\'' + + ", %s='" + phoneNumber + '\'' + + '}'; + + return getMappedString(result); + } + + private String getMappedString(String s) { + + Class customAnnotationClass = ChangeOutputName.class; + + Field[] declaredFields = this.getClass().getDeclaredFields(); + + String[] fieldNames = new String[declaredFields.length]; + + for (int i = 0; i < declaredFields.length; i++) { + Field field = declaredFields[i]; + field.setAccessible(true); + if (field.isAnnotationPresent(customAnnotationClass)) { + fieldNames[i] = field.getAnnotation(customAnnotationClass).value(); + } else { + fieldNames[i] = field.getName(); + } + } + + return String.format(s, (Object[]) fieldNames); + + } +} diff --git a/src/main/java/homework_4/custom_annotation/Main.java b/src/main/java/homework_4/custom_annotation/Main.java new file mode 100644 index 00000000..a4a8c3cd --- /dev/null +++ b/src/main/java/homework_4/custom_annotation/Main.java @@ -0,0 +1,14 @@ +package homework_4.custom_annotation; + +public class Main { + + public static void main(String[] args) { + + Customer customer = new Customer("ООО \"Ромашка\"", + "Общество с ограниченной ответственностью \"Ромашка\""); + + System.out.println(customer); + + } + +} diff --git a/src/main/java/homework_4/custom_file_reader/CustomFileReader.java b/src/main/java/homework_4/custom_file_reader/CustomFileReader.java new file mode 100644 index 00000000..a0672287 --- /dev/null +++ b/src/main/java/homework_4/custom_file_reader/CustomFileReader.java @@ -0,0 +1,61 @@ +package homework_4.custom_file_reader; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class CustomFileReader { + + private final Path path = Paths.get("src/main/resources/custom_file_reader"); + private final String lineSeparator = System.lineSeparator(); + private String resultString = ""; + + public final void run1() { + try { + //using nio's File class wrapper + resultString = String.join(lineSeparator, Files.readAllLines(path)); + } catch (IOException e) { + e.printStackTrace(); + } + EditAndPrintResult(); + } + + public final void run2() { + //using core IO + streams + try (BufferedReader reader = new BufferedReader(new FileReader(path.toAbsolutePath().toString()))) { + resultString = reader.lines().collect(Collectors.joining(lineSeparator)); + EditAndPrintResult(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public final void run3() { + //using core IO + Scanner + try (FileReader reader = new FileReader(path.toAbsolutePath().toString())) { + Scanner scanner = new Scanner(reader); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (line.isEmpty()) { + break; + } + resultString += line + lineSeparator; + } + EditAndPrintResult(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void EditAndPrintResult() { + resultString = resultString.replaceAll("[.,]", ""); //not the fastest way but readable + System.out.println(resultString); + } + +} diff --git a/src/main/java/homework_4/custom_file_reader/Main.java b/src/main/java/homework_4/custom_file_reader/Main.java new file mode 100644 index 00000000..264dc882 --- /dev/null +++ b/src/main/java/homework_4/custom_file_reader/Main.java @@ -0,0 +1,11 @@ +package homework_4.custom_file_reader; + +public class Main { + + public static void main(String[] args) { + + new CustomFileReader().run1(); + new CustomFileReader().run2(); + new CustomFileReader().run3(); + } +} diff --git a/src/main/java/homework_4/singleton/DatabaseConnection.java b/src/main/java/homework_4/singleton/DatabaseConnection.java new file mode 100644 index 00000000..4f77f711 --- /dev/null +++ b/src/main/java/homework_4/singleton/DatabaseConnection.java @@ -0,0 +1,32 @@ +package homework_4.singleton; + +import java.util.UUID; + +public class DatabaseConnection { + + private String userName; + private UUID sessionID; + + private static DatabaseConnection instance; + + //Private constructor to avoid instantiation + private DatabaseConnection(String userName) { + this.userName = userName; + this.sessionID = UUID.randomUUID(); //should be received from db + String message = String.format("Database connection instantiated for user %s with uuid %s", userName, sessionID); + System.out.println(message); + } + + //Double-checked locking design pattern to avoid several instantiations in multithreading + public static DatabaseConnection getInstance(String userName) { + if (instance == null) { + synchronized (DatabaseConnection.class) { + if (instance == null) { + instance = new DatabaseConnection(userName); + } + } + } + return instance; + } + +} diff --git a/src/main/java/homework_4/singleton/EnumDatabaseConnection.java b/src/main/java/homework_4/singleton/EnumDatabaseConnection.java new file mode 100644 index 00000000..2fa19593 --- /dev/null +++ b/src/main/java/homework_4/singleton/EnumDatabaseConnection.java @@ -0,0 +1,25 @@ +package homework_4.singleton; + +import java.util.UUID; + +//has serialization and thread-safety guaranteed by the enum implementation itself +public enum EnumDatabaseConnection { + + INSTANCE; + + private UUID sessionID; + + EnumDatabaseConnection() { + this.sessionID = UUID.randomUUID(); //should be received from db + String message = String.format("Database connection instantiated with uuid %s", sessionID); + System.out.println(message); + } + + //Double-checked locking design pattern to avoid several instantiations in multithreading + public EnumDatabaseConnection getInstance() { + return INSTANCE; + } + + + +} diff --git a/src/main/java/homework_4/singleton/Main.java b/src/main/java/homework_4/singleton/Main.java new file mode 100644 index 00000000..0ebe3a42 --- /dev/null +++ b/src/main/java/homework_4/singleton/Main.java @@ -0,0 +1,30 @@ +package homework_4.singleton; + +public class Main { + + public static void main(String[] args) { + + //Class singleton + + String userName1 = "admin"; + DatabaseConnection classSingleton1 = DatabaseConnection.getInstance(userName1); +// DatabaseConnection object1 = new DatabaseConnection(); // The constructor DatabaseConnection() is not visible + + String userName2 = "superAdmin"; + DatabaseConnection classSingleton2 = DatabaseConnection.getInstance(userName2); + + System.out.println(classSingleton1); + System.out.println(classSingleton2); + + //Enum singleton + + EnumDatabaseConnection enumSingleton1 = EnumDatabaseConnection.INSTANCE.getInstance(); + + EnumDatabaseConnection enumSingleton2 = EnumDatabaseConnection.INSTANCE.getInstance(); + + System.out.println(enumSingleton1); + System.out.println(enumSingleton2); + + + } +} diff --git a/src/main/resources/custom_file_reader b/src/main/resources/custom_file_reader new file mode 100644 index 00000000..e5212bfb --- /dev/null +++ b/src/main/resources/custom_file_reader @@ -0,0 +1,14 @@ +test; 564564; +0.0 +-0.0 +-0.3333333333333333 +0.3333333333333333 +-0.9166666666666665 +0.4166666666666667 +-0.7037037037037036 +0.962962962962963 +-0.3333333333333333 +-0.3333333333333333 +-0.6666666666666666 +0.0 +-1.25 diff --git a/src/test/java/homework_4/custom_annotation/CustomAnnotationTest.java b/src/test/java/homework_4/custom_annotation/CustomAnnotationTest.java new file mode 100644 index 00000000..aad2ec33 --- /dev/null +++ b/src/test/java/homework_4/custom_annotation/CustomAnnotationTest.java @@ -0,0 +1,31 @@ +package homework_4.custom_annotation; + +import base.UnitBase; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CustomAnnotationTest extends UnitBase { + + private final Customer customer = new Customer(); + + @Test + void test_ToStringReturnsNewFieldsName() { + + String name = "ООО \"Ромашка\""; + String fullName = "Общество с ограниченной ответственностью \"Ромашка\""; + + customer.setName(name); + customer.setFullName(fullName); + + System.out.println(customer); + + String expected = String.format("Customer{Наименование='%s', Полное имя='%s', address='null', Номер телефона='null'}", + name, + fullName); + + String actual = getOutput(); + + assertEquals(actual, expected); + } +} diff --git a/src/test/java/homework_4/custom_file_reader/CustomFileReaderTest.java b/src/test/java/homework_4/custom_file_reader/CustomFileReaderTest.java new file mode 100644 index 00000000..875651e4 --- /dev/null +++ b/src/test/java/homework_4/custom_file_reader/CustomFileReaderTest.java @@ -0,0 +1,55 @@ +package homework_4.custom_file_reader; + +import base.UnitBase; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class CustomFileReaderTest extends UnitBase { + + private final CustomFileReader reader = new CustomFileReader(); + + @Test + void test_method1() { + new MethodTestTemplate() { + @Override + protected void run() { + reader.run1(); + } + }.process(); + } + + @Test + void test_method2() { + new MethodTestTemplate() { + @Override + protected void run() { + reader.run2(); + } + }.process(); + } + + @Test + void test_method3() { + new MethodTestTemplate() { + @Override + protected void run() { + reader.run3(); + } + }.process(); + } + + public abstract class MethodTestTemplate { + + protected abstract void run(); + + protected void process() { + run(); + String resultString = getOutput(); + assertTrue(!resultString.contains(".") && !resultString.contains(","), + "Result contains \".\" or \",\" or both:" + System.lineSeparator() + resultString); + } + + } + +} diff --git a/src/test/java/homework_4/singleton/SingletonTest.java b/src/test/java/homework_4/singleton/SingletonTest.java new file mode 100644 index 00000000..84d299ae --- /dev/null +++ b/src/test/java/homework_4/singleton/SingletonTest.java @@ -0,0 +1,17 @@ +package homework_4.singleton; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +public class SingletonTest{ + + @Test + void test_OnlyOneInstance() { + //Class singleton + assertEquals(DatabaseConnection.getInstance("superAdmin"), DatabaseConnection.getInstance("admin")); + //Enum singleton + assertEquals(EnumDatabaseConnection.INSTANCE.getInstance(), EnumDatabaseConnection.INSTANCE.getInstance()); + } +} From a227ba0b85f89119b127c221716115d6117e3147 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Mon, 16 Aug 2021 16:30:28 +0300 Subject: [PATCH 18/22] renamed source file --- .../java/homework_4/custom_file_reader/CustomFileReader.java | 2 +- src/main/resources/{custom_file_reader => file.txt} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/main/resources/{custom_file_reader => file.txt} (100%) diff --git a/src/main/java/homework_4/custom_file_reader/CustomFileReader.java b/src/main/java/homework_4/custom_file_reader/CustomFileReader.java index a0672287..941aa540 100644 --- a/src/main/java/homework_4/custom_file_reader/CustomFileReader.java +++ b/src/main/java/homework_4/custom_file_reader/CustomFileReader.java @@ -12,7 +12,7 @@ public class CustomFileReader { - private final Path path = Paths.get("src/main/resources/custom_file_reader"); + private final Path path = Paths.get("src/main/resources/file.txt"); private final String lineSeparator = System.lineSeparator(); private String resultString = ""; diff --git a/src/main/resources/custom_file_reader b/src/main/resources/file.txt similarity index 100% rename from src/main/resources/custom_file_reader rename to src/main/resources/file.txt From 26a2d3ba80bae139e0db7597dffdc6eec3edf4bc Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Tue, 31 Aug 2021 08:49:11 +0300 Subject: [PATCH 19/22] homework 5 + tests --- .../CustomRegexMatcher.java | 25 ++++++ .../homework_5/custom_regex_matcher/Main.java | 8 ++ .../java/homework_5/power_of_number/Main.java | 8 ++ .../power_of_number/PowerOfNumber.java | 54 ++++++++++++ .../CustomRegexMatcherTest.java | 41 ++++++++++ .../power_of_number/PowerOfNumberTest.java | 82 +++++++++++++++++++ 6 files changed, 218 insertions(+) create mode 100644 src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java create mode 100644 src/main/java/homework_5/custom_regex_matcher/Main.java create mode 100644 src/main/java/homework_5/power_of_number/Main.java create mode 100644 src/main/java/homework_5/power_of_number/PowerOfNumber.java create mode 100644 src/test/java/homework_5/custom_regex_matcher/CustomRegexMatcherTest.java create mode 100644 src/test/java/homework_5/power_of_number/PowerOfNumberTest.java diff --git a/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java b/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java new file mode 100644 index 00000000..7fbd2e7f --- /dev/null +++ b/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java @@ -0,0 +1,25 @@ +package homework_5.custom_regex_matcher; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class CustomRegexMatcher { + + final private String regex_email = "^[^0-9]\\w+@[^0-9]\\w+(\\.[a-z]{2,3}){1,2}$"; + //regex issues: + //username doesn't start with digit + //domain name doesn't start with digit + //domain zone length 2 or 3 chars + //accepts one or double domain zone + + final void readFromConsole(){ + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.print("Enter your email: "); + String inputString = reader.readLine(); + System.out.println(inputString.matches(regex_email)); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/src/main/java/homework_5/custom_regex_matcher/Main.java b/src/main/java/homework_5/custom_regex_matcher/Main.java new file mode 100644 index 00000000..6c809ffb --- /dev/null +++ b/src/main/java/homework_5/custom_regex_matcher/Main.java @@ -0,0 +1,8 @@ +package homework_5.custom_regex_matcher; + +public class Main { + + public static void main(String[] args) { + new CustomRegexMatcher().readFromConsole(); + } +} diff --git a/src/main/java/homework_5/power_of_number/Main.java b/src/main/java/homework_5/power_of_number/Main.java new file mode 100644 index 00000000..89300565 --- /dev/null +++ b/src/main/java/homework_5/power_of_number/Main.java @@ -0,0 +1,8 @@ +package homework_5.power_of_number; + +public class Main { + + public static void main(String[] args) { + new PowerOfNumber().run(); + } +} diff --git a/src/main/java/homework_5/power_of_number/PowerOfNumber.java b/src/main/java/homework_5/power_of_number/PowerOfNumber.java new file mode 100644 index 00000000..72703ee0 --- /dev/null +++ b/src/main/java/homework_5/power_of_number/PowerOfNumber.java @@ -0,0 +1,54 @@ +package homework_5.power_of_number; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigInteger; + +public class PowerOfNumber { + + private int number; + private int power; + private BigInteger powerOfNumber; + + public void run() { + try { + readFromConsole(); + if (power == 0) { + powerOfNumber = BigInteger.ONE; + } else if (number == 0) { + powerOfNumber = BigInteger.ZERO; + } else { + powerOfNumber = BigInteger.valueOf(number); + countPowerOfNumber(power); + } + System.out.printf("Power %s of number %s is: %s", power, number, powerOfNumber); + } catch (IOException | NullPointerException e) { + System.out.println("Only 2 non-negative integers are allowed"); + } + + } + + private void countPowerOfNumber(int power) { + if (power != 1) { + powerOfNumber = powerOfNumber.multiply(BigInteger.valueOf(number)); + power--; + countPowerOfNumber(power); + } + } + + private void readFromConsole() throws IOException, NullPointerException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { + System.out.print("Enter 2 positive integer numbers: "); + String inputString = reader.readLine(); + if (inputString.matches("^\\d+\\s\\d+$")) { + String[] paramArray = inputString.split("\\s+"); + number = Integer.parseInt(paramArray[0]); + power = Integer.parseInt(paramArray[1]); + } else { + throw new IOException(); + } + } + } + +} diff --git a/src/test/java/homework_5/custom_regex_matcher/CustomRegexMatcherTest.java b/src/test/java/homework_5/custom_regex_matcher/CustomRegexMatcherTest.java new file mode 100644 index 00000000..fa7dd0cd --- /dev/null +++ b/src/test/java/homework_5/custom_regex_matcher/CustomRegexMatcherTest.java @@ -0,0 +1,41 @@ +package homework_5.custom_regex_matcher; + +import base.UnitBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class PowerOfNumberTest extends UnitBase { + + private static String welcomeMessage = "Enter your email: "; + + @ParameterizedTest + @MethodSource("testCases") + void test_MainCases(final String input, final String expected) { + setInput(input); + new CustomRegexMatcher().readFromConsole(); + removeFromOutput(welcomeMessage); + printOut(); + String actual = getOutput(); + assertEquals(expected, actual); + } + + static Stream testCases() { + return Stream.of( + Arguments.of("abelyaevskov@gmail.com", "true"), + Arguments.of("abelyaevskov@narod.biz.ru", "true"), + Arguments.of("abelyaevskov", "false"), + Arguments.of("abelyaevskov@", "false"), + Arguments.of("0", "false"), + Arguments.of(" ", "false"), + Arguments.of("123abelyaevskov@gmail.com", "false"), + Arguments.of("abelyaevskov@123gmail.com", "false") + ); + } + + +} \ No newline at end of file diff --git a/src/test/java/homework_5/power_of_number/PowerOfNumberTest.java b/src/test/java/homework_5/power_of_number/PowerOfNumberTest.java new file mode 100644 index 00000000..1454e5eb --- /dev/null +++ b/src/test/java/homework_5/power_of_number/PowerOfNumberTest.java @@ -0,0 +1,82 @@ +package homework_5.power_of_number; + +import base.UnitBase; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.Random; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PowerOfNumberTest extends UnitBase { + + private static String welcomeMessage = "Enter 2 positive integer numbers: "; + private static String errorMessage = "Only 2 non-negative integers are allowed"; + + @ParameterizedTest + @MethodSource("testCases") + void test_MainCases(final String input, final String expected) { + setInput(input); + new PowerOfNumber().run(); + removeFromOutput(welcomeMessage); + printOut(); + String actual = getOutput(); + assertEquals(expected, actual); + } + + static Stream testCases() { + final Stream.Builder testCases = Stream.builder(); + + Random randomNumber = new Random(); + Random randomPower = new Random(); + + int numberDistribution = 150; + int powerDistribution = 101; + + for (int i = 0; i < 100; i++) { + int number = randomNumber.nextInt(numberDistribution); + int power = randomPower.nextInt(powerDistribution); + BigInteger powerOfNumber = BigInteger.valueOf(number).pow(power); + String input = String.format("%s %s", number, power); + String expectedOutput = String.format("Power %s of number %s is: %s", power, number, powerOfNumber); + testCases.add(Arguments.of(input, expectedOutput)); + } + + String input_power0 = String.format("%s %s", 15, 0); + String expectedOutput_power0 = String.format("Power %s of number %s is: %s", 0, 15, 1); + testCases.add(Arguments.of(input_power0, expectedOutput_power0)); + + String input_number0 = String.format("%s %s", 0, 99); + String expectedOutput_number0 = String.format("Power %s of number %s is: %s", 99, 0, 0); + testCases.add(Arguments.of(input_number0, expectedOutput_number0)); + + return testCases.build(); + } + + @ParameterizedTest + @MethodSource("wrongInput") + void test_wrongInput(final String input, final String expected) { + setInput(input); + new PowerOfNumber().run(); + removeFromOutput(welcomeMessage); + printOut(); + String actual = getOutput(); + assertTrue(actual.contains(expected)); + } + + static Stream wrongInput() { + return Stream.of( + Arguments.of("test", errorMessage), + Arguments.of("-5 0", errorMessage), + Arguments.of("5 -99", errorMessage), + Arguments.of("", errorMessage), + Arguments.of("0", errorMessage), + Arguments.of(" ", errorMessage) + ); + } + +} \ No newline at end of file From 5419db13d11f23d2071a355594499dc9abe8b2d1 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Tue, 31 Aug 2021 09:02:21 +0300 Subject: [PATCH 20/22] README update --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2185d111..408c8588 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ | HW2 | [Pyramid printer](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/PyramidPrinter/PyramidPrinter.java) | App reads positive integer numbers from the console and prints pyramid of "x" characters | | HW2 | [Random chars table](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_2/RandomCharsTable/RandomCharsTable.java) | App reads from the console width and length of the chart, strategy keyword (even or odd). Prints to the console the chart of random chars from A to Z, and in separate line all the chars (from the chart) that match strategy | | HW3 | [Immutable class example](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_3/ImmutableTask.java) | Example of an immutable class | +| HW4 | [Custom file reader](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_4/custom_file_reader/CustomFileReader.java) | Examples of 3 methods implementations for file reading | +| HW4 | [Singleton](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/AlexanderBelyaevskov/src/main/java/homework_4/singleton) | Examples of an singleton class | +| HW4 | [Custom Annotation](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/AlexanderBelyaevskov/src/main/java/homework_4/custom_annotation) | Example of an annotation that changes field name in ToString() method | +| HW5 | [Power of number](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_5/power_of_number/PowerOfNumber.java) | Power of number implementation with recursion method | +| HW5 | [Custom regex matcher](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java) | Input email argument check with regex | [CodingBat done page](https://codingbat.com/done?user=abelyaevskov@gmail.com&tag=6930560875) From 32bc69e684fdadcd9fe32c42c3345e3e09cc195c Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Thu, 9 Sep 2021 09:44:23 +0300 Subject: [PATCH 21/22] homework_6 --- README.md | 1 + .../MapProblemsCollisionGenerator.java | 31 ++++++++++++ .../MapProblemsMutableGenerator.java | 47 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 src/main/java/homework_6/map_problems_generator/MapProblemsCollisionGenerator.java create mode 100644 src/main/java/homework_6/map_problems_generator/MapProblemsMutableGenerator.java diff --git a/README.md b/README.md index 408c8588..f6cea378 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ | HW4 | [Custom Annotation](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/AlexanderBelyaevskov/src/main/java/homework_4/custom_annotation) | Example of an annotation that changes field name in ToString() method | | HW5 | [Power of number](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_5/power_of_number/PowerOfNumber.java) | Power of number implementation with recursion method | | HW5 | [Custom regex matcher](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java) | Input email argument check with regex | +| HW6 | [Map problems generator](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_6/map_problems_generator/MapProblemsCollisionGenerator.java) | Implement a class with overdid equals() and hashCode() methods, which generates 100% collision when used as key in HashMap collection.| [CodingBat done page](https://codingbat.com/done?user=abelyaevskov@gmail.com&tag=6930560875) diff --git a/src/main/java/homework_6/map_problems_generator/MapProblemsCollisionGenerator.java b/src/main/java/homework_6/map_problems_generator/MapProblemsCollisionGenerator.java new file mode 100644 index 00000000..a389e226 --- /dev/null +++ b/src/main/java/homework_6/map_problems_generator/MapProblemsCollisionGenerator.java @@ -0,0 +1,31 @@ +package homework_6.map_problems_generator; + +import java.util.HashMap; + +public class MapProblemsCollisionGenerator { + + public static void main(String[] args) { + + HashMap myHashMap = new HashMap<>(); + + MapProblemsMutableGenerator bugger1 = new MapProblemsMutableGenerator("Sasha", "bugger", 40); + MapProblemsMutableGenerator bugger2 = new MapProblemsMutableGenerator("Pasha", "troubleMaker", 30); + MapProblemsMutableGenerator bugger3 = new MapProblemsMutableGenerator("Yura", "juniorForever", 35); + + System.out.println("Put bugger 1"); + myHashMap.put(bugger1, 1); + System.out.println("Put bugger 2"); + myHashMap.put(bugger2, 2); + System.out.println("Put bugger 3"); + myHashMap.put(bugger3, 3); + + System.out.println("Change bugger2 nick"); + bugger2.setNickName("bigBug"); + + System.out.println("We can't get the value by key, since key HashCode() differs. Extracted value for bugger2 is: " + + myHashMap.get(bugger2)); + + System.out.println("HashMap keys: " + myHashMap.keySet()); + + } +} diff --git a/src/main/java/homework_6/map_problems_generator/MapProblemsMutableGenerator.java b/src/main/java/homework_6/map_problems_generator/MapProblemsMutableGenerator.java new file mode 100644 index 00000000..9ac32df6 --- /dev/null +++ b/src/main/java/homework_6/map_problems_generator/MapProblemsMutableGenerator.java @@ -0,0 +1,47 @@ +package homework_6.map_problems_generator; + +import java.util.Objects; + +public class MapProblemsMutableGenerator { + + private String Name; + private String nickName; + private int age; + + public void setName(String name) { + Name = name; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public void setAge(int age) { + this.age = age; + } + + public MapProblemsMutableGenerator(String name, String nickName, int age) { + Name = name; + this.nickName = nickName; + this.age = age; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MapProblemsMutableGenerator that = (MapProblemsMutableGenerator) o; + return age == that.age && Objects.equals(Name, that.Name) && Objects.equals(nickName, that.nickName); + } + + @Override + public int hashCode() { + //hashCode doesn't keep general contract + + //Whenever it is invoked on the same object more than once during an execution of a Java application, + //the hashCode method must consistently return the same integer. + // In other words for the same reference if MapProblemsMutableGenerator.equals() = true, hashCode() differs. + + return Objects.hash(Name, nickName, age); + } +} From 2338faff8900f4bde576408ae17b8e1b7fa15470 Mon Sep 17 00:00:00 2001 From: Alexander belyaevskov Date: Tue, 21 Sep 2021 08:16:27 +0300 Subject: [PATCH 22/22] homework_7 + course project --- README.md | 2 + src/main/java/course_project/Game.java | 168 ++++++++++++++++++ src/main/java/course_project/GameStatus.java | 7 + src/main/java/course_project/Main.java | 9 + .../java/course_project/MapPointType.java | 9 + src/main/java/course_project/Point.java | 83 +++++++++ .../java/course_project/SeaBattleMap.java | 164 +++++++++++++++++ src/main/java/course_project/Ship.java | 92 ++++++++++ .../java/course_project/ShipLocationType.java | 8 + src/main/java/homework_7/Cat.java | 38 ++++ src/main/java/homework_7/ChildKitten.java | 24 +++ src/main/java/homework_7/Kitten.java | 28 +++ .../java/homework_7/KittenToCatFunction.java | 6 + src/main/java/homework_7/Main.java | 18 ++ 14 files changed, 656 insertions(+) create mode 100644 src/main/java/course_project/Game.java create mode 100644 src/main/java/course_project/GameStatus.java create mode 100644 src/main/java/course_project/Main.java create mode 100644 src/main/java/course_project/MapPointType.java create mode 100644 src/main/java/course_project/Point.java create mode 100644 src/main/java/course_project/SeaBattleMap.java create mode 100644 src/main/java/course_project/Ship.java create mode 100644 src/main/java/course_project/ShipLocationType.java create mode 100644 src/main/java/homework_7/Cat.java create mode 100644 src/main/java/homework_7/ChildKitten.java create mode 100644 src/main/java/homework_7/Kitten.java create mode 100644 src/main/java/homework_7/KittenToCatFunction.java create mode 100644 src/main/java/homework_7/Main.java diff --git a/README.md b/README.md index f6cea378..bc6fb75b 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ | HW5 | [Power of number](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_5/power_of_number/PowerOfNumber.java) | Power of number implementation with recursion method | | HW5 | [Custom regex matcher](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java) | Input email argument check with regex | | HW6 | [Map problems generator](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_6/map_problems_generator/MapProblemsCollisionGenerator.java) | Implement a class with overdid equals() and hashCode() methods, which generates 100% collision when used as key in HashMap collection.| +| HW7 | [Funtional interface](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/homework_7/Main.java) | Custom functional interface implementation.| +| Course project | [Sea battle](https://github.com/NikolaevArtem/Java_Core_June_2021/blob/feature/AlexanderBelyaevskov/src/main/java/course_project/Main.java) | Sea battle console game.| [CodingBat done page](https://codingbat.com/done?user=abelyaevskov@gmail.com&tag=6930560875) diff --git a/src/main/java/course_project/Game.java b/src/main/java/course_project/Game.java new file mode 100644 index 00000000..885e7fdf --- /dev/null +++ b/src/main/java/course_project/Game.java @@ -0,0 +1,168 @@ +package course_project; + +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Scanner; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class Game { + + private final Scanner reader; + private final SeaBattleMap[] battleMaps = new SeaBattleMap[2]; + private final String mapsSpacing = " "; + + private SeaBattleMap activeBattleMap; + private String activePlayer; + + private GameStatus status; + private String currentInput; + + Game() { + reader = new Scanner(new InputStreamReader(System.in)); + } + + void run() { + System.out.println("Welcome to SEA BATTLE console game!"); + System.out.println("Follow instructions to play the game or type \"exit\" anytyme to terminate program"); + try { + start(); + runBattle(); + } finally { + reader.close(); + } + } + + private void start() { + status = GameStatus.SettingShips; + setBattleMaps(); + setShips(); + } + + private void runBattle() { + status = GameStatus.Battle; + + activeBattleMap = battleMaps[1]; + activePlayer = battleMaps[0].getPlayerName(); + + mainLoop: + while (true) { + for (int i = 0, j = 1; i < 2; i++, j--) { + while (true) { + printBattleMaps(); + if (readShootCommand()) + if (!activeBattleMap.shoot(new Point(currentInput))) { + break; + } + if (activeBattleMap.getShips().size() == 0) { + System.out.printf("%s wins! Congrats!", activePlayer); + System.out.println(); + break mainLoop; + } + } + activeBattleMap = battleMaps[i]; + activePlayer = battleMaps[j].getPlayerName(); + } + } + } + + private void setBattleMaps() { + for (int i = 0; i < 2; i++) { + battleMaps[i] = new SeaBattleMap(10, "Player " + (i + 1)); + } + } + + private boolean readShootCommand() { + System.out.printf("%s make a shoot (e.g. A1 or E9): ", activePlayer); + currentInput = reader.nextLine(); + if (currentInput.equals("exit")) { + throw new RuntimeException("Terminated by user"); + } + String shootValidationPattern = "[A-J]([1-9]{1}|10)$"; + if (!currentInput.matches(shootValidationPattern)) { + printErrorMessage("Wrong shoot command!"); + return false; + } + return true; + } + + private void printBattleMap(SeaBattleMap battleMap) { + System.out.println( + battleMap.getView(status).stream().collect(Collectors.joining(System.lineSeparator())) + ); + } + + private void printBattleMaps() { + ArrayList view1 = battleMaps[0].getView(status); + ArrayList view2 = battleMaps[1].getView(status); + + System.out.println( + Stream.iterate(0, i -> i + 1) + .limit(view1.size()) + .map(i -> view1.get(i).concat(mapsSpacing).concat(view2.get(i))) + .collect(Collectors.joining(System.lineSeparator())) + ); + } + + private void setShips() { + for (SeaBattleMap battleMap : battleMaps) { + activeBattleMap = battleMap; + while (true) { + if (setNSizeShip(4)) + break; + } + while (true) { + if (setNSizeShip(3)) + break; + } + while (true) { + if (setNSizeShip(2)) + break; + } + while (true) { + if (setNSizeShip(1)) + break; + } + } + } + + private boolean setNSizeShip(int size) { + int shipsCount = 5 - size - activeBattleMap.getNSizedShipsCount(size); + for (int i = 0; i < shipsCount; i++) { + printBattleMap(activeBattleMap); + System.out.printf("%s, enter position and location type (R = right, D = down) " + + "to set %s-size ship (e.g. A1 R or A1 D): ", activeBattleMap.getPlayerName(), size); + String input = reader.nextLine(); + if (input.equals("exit")) { + throw new RuntimeException("Terminated by user"); + } + String setShipsValidationPattern = "[A-J]([1-9]{1}|10)\\s([RD])$"; + if (!input.matches(setShipsValidationPattern)) { + printErrorMessage("Wrong ship position command!"); + return false; + } + + String[] inputParts = input.split("\\s"); + + ShipLocationType shipLocationType = ShipLocationType.TO_RIGHT; + if (inputParts[1].equals("D")) { + shipLocationType = ShipLocationType.TO_DOWN; + } + try { + activeBattleMap.addShip(new Point(inputParts[0]), size, shipLocationType); + } catch (IllegalArgumentException e) { + printErrorMessage(e.getMessage()); + return false; + } + + } + return true; + } + + private void printErrorMessage(String message) { + final String ANSI_RED = "\u001B[31m"; + final String ANSI_BLACK = "\u001B[0m"; + System.out.println(ANSI_RED + message + ANSI_BLACK); + } + +} diff --git a/src/main/java/course_project/GameStatus.java b/src/main/java/course_project/GameStatus.java new file mode 100644 index 00000000..4068b5fa --- /dev/null +++ b/src/main/java/course_project/GameStatus.java @@ -0,0 +1,7 @@ +package course_project; + +enum GameStatus { + + SettingShips, + Battle +} diff --git a/src/main/java/course_project/Main.java b/src/main/java/course_project/Main.java new file mode 100644 index 00000000..c1991f7a --- /dev/null +++ b/src/main/java/course_project/Main.java @@ -0,0 +1,9 @@ +package course_project; + +public class Main { + + public static void main(String[] args) { + new Game().run(); + } + +} diff --git a/src/main/java/course_project/MapPointType.java b/src/main/java/course_project/MapPointType.java new file mode 100644 index 00000000..e7e8885d --- /dev/null +++ b/src/main/java/course_project/MapPointType.java @@ -0,0 +1,9 @@ +package course_project; + +enum MapPointType { + + Ship, + FiredShip, + Emty, + Fired +} diff --git a/src/main/java/course_project/Point.java b/src/main/java/course_project/Point.java new file mode 100644 index 00000000..382da1d2 --- /dev/null +++ b/src/main/java/course_project/Point.java @@ -0,0 +1,83 @@ +package course_project; + +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +class Point { + + private final int x; + private final int y; + private MapPointType type; + + Point(String consoleInput) { + + int y = IntStream.iterate(65, i -> i+1) + .limit(10) + .mapToObj(i -> String.valueOf((char) i)) + .collect(Collectors.toList()) + .indexOf(consoleInput.substring(0,1)); + this.x = Integer.parseInt(consoleInput.substring(1))-1; + this.y = y; + } + + Point(int x, int y, MapPointType type) { + this.x = x; + this.y = y; + this.type = type; + } + + int getX() { + return x; + } + + int getY() { + return y; + } + + void setType(MapPointType type) { + this.type = type; + } + + MapPointType getType() { + return type; + } + + String getView(GameStatus status) { + if (status == GameStatus.Battle) { + return getBattleView(); + } + else { + return getSettingShipsView(); + } + } + + private String getSettingShipsView() { + if (getType() == MapPointType.Ship) { + return "\u25B2" + " "; + } + return " "; + } + + private String getBattleView() { + switch (getType() + ) { + case FiredShip: return "\u2713" + " "; + case Fired: return "\u00D7" + " "; + default: return " "; + } + } + + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Point point = (Point) o; + return x == point.x && y == point.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } +} diff --git a/src/main/java/course_project/SeaBattleMap.java b/src/main/java/course_project/SeaBattleMap.java new file mode 100644 index 00000000..11367354 --- /dev/null +++ b/src/main/java/course_project/SeaBattleMap.java @@ -0,0 +1,164 @@ +package course_project; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class SeaBattleMap { + + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_BLACK = "\u001B[0m"; + + private final Point[][] field; + private final int size; + + String getPlayerName() { + return playerName; + } + + private final String playerName; + private final List ships = new ArrayList<>(); + + SeaBattleMap(int size, String playerName) { + + this.size = size; + this.playerName = playerName; + + field = new Point[size][size]; + for (int i = 0, offsetX = 0; i < size; i++, offsetX++) { + for (int j = 0, offsetY = 0; j < size; j++, offsetY++) { + field[i][j] = new Point(offsetX, offsetY, MapPointType.Emty); + } + } + } + + void addShip(Point entry, int size, ShipLocationType type) throws IllegalArgumentException { + Ship ship = new Ship(field, entry, size, type); + ships.add(ship); + } + + int getNSizedShipsCount(int size) { + return ((Long) ships.stream() + .filter(s -> s.getSize() == size).count()).intValue(); + + } + + boolean shoot(Point point) { + Point fieldPoint = field[point.getX()][point.getY()]; + if (fieldPoint.getType() == MapPointType.Ship) { + fieldPoint.setType(MapPointType.FiredShip); + ships.removeIf(Ship::IsDestroyed); + System.out.println("Well done!"); + return true; + } else if (fieldPoint.getType() == MapPointType.FiredShip) { + System.out.println("It's already fired target, take a new one!"); + return true; + } + else { + fieldPoint.setType(MapPointType.Fired); + System.out.println("Bad luck! Move goes to another player"); + return false; + } + } + + List getShips() { + return ships; + } + + private int getX_Offset() { + return field[size - 1][size - 1].getX() + 1; + } + + private int getY_Offset() { + return field[size - 1][size - 1].getY() + 1; + } + + ArrayList getView(GameStatus status) { + + ArrayListImpl battleMapView = new ArrayListImpl(); + + battleMapView.add(playerName); + + String headerNumsEnumeration = Stream.iterate(1, i -> i + 1) + .limit(getX_Offset()) + .map(String::valueOf) + .collect(Collectors.joining(" ")); + + battleMapView.add(headerNumsEnumeration); + battleMapView.add( + getLineString(headerNumsEnumeration) + ); + + for (int y = 0, charIndex = 65; y < getY_Offset(); y++, charIndex++) { + StringBuilder sb = new StringBuilder(); + sb.append((char) charIndex); + sb.append("|"); + for (int x = 0; x < getX_Offset(); x++) { + sb.append( + field[x][y].getView(status) + ); + } + sb.append("|"); + battleMapView.add(sb.toString()); + } + + battleMapView.add( + getLineString(headerNumsEnumeration) + ); + + //center align + for (int i = 0; i < battleMapView.size(); i++) { + String s = battleMapView.get(i); + int maxStringLength = battleMapView.getMaxStringLength(); + int minLength = (int) Math.ceil((double) (maxStringLength - s.length()) / 2 + s.length()); + String fString = String.format("%%%ds", minLength); + if (minLength < maxStringLength) { + fString = String.format("%%%ds%%%ds", minLength, maxStringLength - minLength); + } + battleMapView.set(i, String.format(fString, s, " ")); + } + + //color ships marks after Formatter usage as Java's APIs don't natively understand ANSI color escape codes + for (int i = 0; i < battleMapView.size(); i++) { + String s = battleMapView.get(i); + if (s.contains("\u2713") || s.contains("\u00D7")) { + String coloredString = Arrays.stream(s.split("")) + .map(ss -> { + if (ss.contains("\u2713")) { + ss = ANSI_GREEN + ss + ANSI_BLACK; + } else if (ss.contains("\u00D7")) { + ss = ANSI_RED + ss + ANSI_BLACK; + } + return ss; + }) + .collect(Collectors.joining()); + + battleMapView.set(i, String.format(coloredString, s, " ")); + } + } + + return battleMapView; + } + + private String getLineString(String headerNumsEnumeration) { + return "+" + String.join("", Collections.nCopies(headerNumsEnumeration.length(), "-")) + "+"; + } + + private class ArrayListImpl extends ArrayList { + private int maxStringLength = 0; + + @Override + public boolean add(String s) { + maxStringLength = Math.max(maxStringLength, s.length()); + return super.add(s); + } + + public int getMaxStringLength() { + return maxStringLength; + } + } +} diff --git a/src/main/java/course_project/Ship.java b/src/main/java/course_project/Ship.java new file mode 100644 index 00000000..02d8cbdd --- /dev/null +++ b/src/main/java/course_project/Ship.java @@ -0,0 +1,92 @@ +package course_project; + +import java.util.Arrays; + +class Ship { + + private final Point[] points; + private final int size; + private final String errorMessage = "Wrong ship location!"; + + Ship(Point[][] field, Point entry, int size, ShipLocationType type) throws IllegalArgumentException { + points = new Point[size]; + this.size = size; + + + for (int i = 0, x = entry.getX(), y = entry.getY(); i < size; i++) { + Point point; + try { + point = field[x][y]; + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException(errorMessage); + } + if (point.getType() == MapPointType.Ship) { + throw new IllegalArgumentException(errorMessage); + } + checkNearestPoints(field, point); + points[i] = point; + switch (type) { + case TO_DOWN: + y++; + break; + case TO_RIGHT: + x++; + break; + default: + throw new UnsupportedOperationException(); + } + } + + for (Point point : points) { + point.setType(MapPointType.Ship); + } + + } + + private boolean IsShipPoint(Point point) { + return Arrays.asList(points).contains(point); + } + + boolean IsDestroyed () { + return Arrays.stream(points).allMatch(e -> e.getType() == MapPointType.FiredShip); + } + + private void checkNearestPoints(Point[][] field, Point entry) throws IllegalArgumentException { + + try { + if (field[entry.getX() - 1][entry.getY()].getType() == MapPointType.Ship && !IsShipPoint(entry)) { + throw new IllegalArgumentException(errorMessage); + } + } catch (IndexOutOfBoundsException e) { + + } + + try { + if (field[entry.getX() + 1][entry.getY()].getType() == MapPointType.Ship && !IsShipPoint(entry)) { + throw new IllegalArgumentException(errorMessage); + } + } catch (IndexOutOfBoundsException e) { + + } + + try { + if (field[entry.getX()][entry.getY() - 1].getType() == MapPointType.Ship && !IsShipPoint(entry)) { + throw new IllegalArgumentException(errorMessage); + } + } catch (IndexOutOfBoundsException e) { + + } + + try { + if (field[entry.getX()][entry.getY() + 1].getType() == MapPointType.Ship && !IsShipPoint(entry)) { + throw new IllegalArgumentException(errorMessage); + } + } catch (IndexOutOfBoundsException e) { + + } + } + + int getSize() { + return size; + } +} diff --git a/src/main/java/course_project/ShipLocationType.java b/src/main/java/course_project/ShipLocationType.java new file mode 100644 index 00000000..fcc2f3b8 --- /dev/null +++ b/src/main/java/course_project/ShipLocationType.java @@ -0,0 +1,8 @@ +package course_project; + +enum ShipLocationType { + + TO_RIGHT, + TO_DOWN + +} diff --git a/src/main/java/homework_7/Cat.java b/src/main/java/homework_7/Cat.java new file mode 100644 index 00000000..990835c3 --- /dev/null +++ b/src/main/java/homework_7/Cat.java @@ -0,0 +1,38 @@ +package homework_7; + +public class Cat { + private String name; + private int age; + private String color; + + @Override + public String toString() { + return "Cat{" + + "name='" + name + '\'' + + ", age=" + age + + ", color='" + color + '\'' + + '}'; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Cat(String name, int age, String color) { + this.name = name; + this.age = age; + this.color = color; + } +} diff --git a/src/main/java/homework_7/ChildKitten.java b/src/main/java/homework_7/ChildKitten.java new file mode 100644 index 00000000..cd54cd9b --- /dev/null +++ b/src/main/java/homework_7/ChildKitten.java @@ -0,0 +1,24 @@ +package homework_7; + +public class ChildKitten extends Kitten{ + + String color; + + public ChildKitten(String name, int age, String color) { + super(name, age); + this.color = color; + } + + public String getColor() { + return color; + } + + @Override + public String toString() { + return "ChildKitten{" + + "color='" + color + '\'' + + ", name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/src/main/java/homework_7/Kitten.java b/src/main/java/homework_7/Kitten.java new file mode 100644 index 00000000..3c5c0540 --- /dev/null +++ b/src/main/java/homework_7/Kitten.java @@ -0,0 +1,28 @@ +package homework_7; + +public class Kitten { + String name; + int age; + + public Kitten(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/src/main/java/homework_7/KittenToCatFunction.java b/src/main/java/homework_7/KittenToCatFunction.java new file mode 100644 index 00000000..b71700a1 --- /dev/null +++ b/src/main/java/homework_7/KittenToCatFunction.java @@ -0,0 +1,6 @@ +package homework_7; + +@FunctionalInterface +public interface KittenToCatFunction { + C grow(K kitten); +} diff --git a/src/main/java/homework_7/Main.java b/src/main/java/homework_7/Main.java new file mode 100644 index 00000000..24304f2f --- /dev/null +++ b/src/main/java/homework_7/Main.java @@ -0,0 +1,18 @@ +package homework_7; + +public class Main { + + public static void main(String[] args) { + + ChildKitten childKitten = new ChildKitten("Vasilisa", 0, "black"); + System.out.println("Kitten :" + childKitten); + + Cat grownKitten = ((KittenToCatFunction) kitten1 -> { + return new Cat(kitten1.getName(), kitten1.getAge() + 2, "black&white"); + }).grow(childKitten); + + System.out.println("Grown kitten :" + grownKitten); + + + } +}