From 2638b6fa2b626bdd3f61c68d33427d58a7a205fb Mon Sep 17 00:00:00 2001 From: Heesoo Date: Tue, 17 Dec 2024 17:45:49 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[docs]=20README=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-HS.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 README-HS.md diff --git a/README-HS.md b/README-HS.md new file mode 100644 index 0000000..a01ce45 --- /dev/null +++ b/README-HS.md @@ -0,0 +1,23 @@ +## 기능 요구사항 +1. 좌표값 입력 : 에러 출력 후 다시 입력 + - 괄호 분리 -> 괄호가 아닌 경우 에러 + - 쉼표 분리 -> 쉼표가 아닌 경우 에러 + - 구분자 '-' 분리 -> 구분자 아닌 경우 에러 + - 숫자 0~24 인지 검증 -> 아닌 경우 에러 +2. 거리 계산 출력 + +## 프로그래밍 요구사항 +1. depth 1로 구현 +2. else 사용 금지 +3. 메서드 길이 10줄 넘어가지 않도록 구현 +4. 메소드 한가지 일만 하도록 구현 +5. 일급 컬렉션 사용 + +**\* 상속 또는 인터페이스 사용해서 구현** + +## 실행 결과 +``` +좌표를 입력하세요. +(10,10)-(14,15) +두 점 사이 거리는 6.403124 +``` From 2f0da0ab5d0780045226514dab3a7f6fe116285f Mon Sep 17 00:00:00 2001 From: Heesoo Date: Fri, 27 Dec 2024 22:44:07 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[feat]=20=EC=A2=8C=ED=91=9C=EA=B3=84?= =?UTF-8?q?=EC=82=B0=EA=B8=B0(=EC=84=A0=EA=B8=B8=EC=9D=B4)=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/CoordinateMain.java | 17 ++++ src/main/java/io/CoordinateScanner.java | 67 ++++++++++++++++ src/main/java/io/ResultView.java | 16 ++++ src/main/java/messages/ErrorMessages.java | 8 ++ src/main/java/model/Calculator.java | 30 +++++++ src/main/java/model/Coordinate.java | 37 +++++++++ src/main/java/model/Point.java | 50 ++++++++++++ src/main/java/model/Points.java | 35 ++++++++ src/main/java/util/StringUtil.java | 14 ++++ src/test/java/io/CoordinateScannerTest.java | 67 ++++++++++++++++ src/test/java/model/CalculatorTest.java | 89 +++++++++++++++++++++ src/test/java/model/CoordinateTest.java | 35 ++++++++ src/test/java/model/PointTest.java | 55 +++++++++++++ src/test/java/model/PointsTest.java | 37 +++++++++ 15 files changed, 558 insertions(+), 1 deletion(-) create mode 100644 src/main/java/CoordinateMain.java create mode 100644 src/main/java/io/CoordinateScanner.java create mode 100644 src/main/java/io/ResultView.java create mode 100644 src/main/java/messages/ErrorMessages.java create mode 100644 src/main/java/model/Calculator.java create mode 100644 src/main/java/model/Coordinate.java create mode 100644 src/main/java/model/Point.java create mode 100644 src/main/java/model/Points.java create mode 100644 src/main/java/util/StringUtil.java create mode 100644 src/test/java/io/CoordinateScannerTest.java create mode 100644 src/test/java/model/CalculatorTest.java create mode 100644 src/test/java/model/CoordinateTest.java create mode 100644 src/test/java/model/PointTest.java create mode 100644 src/test/java/model/PointsTest.java diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f80bbf..d2880ba 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/CoordinateMain.java b/src/main/java/CoordinateMain.java new file mode 100644 index 0000000..72d728f --- /dev/null +++ b/src/main/java/CoordinateMain.java @@ -0,0 +1,17 @@ +import io.ResultView; +import model.Calculator; +import model.Points; +import io.CoordinateScanner; + +public class CoordinateMain { + public static void main(String[] args) { + CoordinateScanner scanner = new CoordinateScanner(); + Points points = scanner.input(); + + Calculator calculator = new Calculator(points); + double result = calculator.distance(); + + ResultView resultView = new ResultView(result); + resultView.print(); + } +} diff --git a/src/main/java/io/CoordinateScanner.java b/src/main/java/io/CoordinateScanner.java new file mode 100644 index 0000000..ab0f022 --- /dev/null +++ b/src/main/java/io/CoordinateScanner.java @@ -0,0 +1,67 @@ +package io; + +import messages.ErrorMessages; +import model.Point; +import model.Points; +import util.StringUtil; + +import java.util.List; +import java.util.Scanner; +import java.util.regex.MatchResult; +import java.util.regex.Pattern; + +public class CoordinateScanner { + + private final Scanner scanner; + + public CoordinateScanner(){ + scanner = new Scanner(System.in); + } + + public Points input(){ + System.out.println("좌표를 입력하세요."); + String input = scanner.nextLine(); + + return validDots(input); + + } + + public Points validDots(String input){ + Points points; + + try{ + isCorrectFormat(input); + points = parseNumber(input); + } catch (IllegalArgumentException ex){ + System.out.println(ex.getMessage()); + return input(); + } + + return points; + } + + + public void isCorrectFormat(String input){ + if(!input.matches("\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)")){ + throw new IllegalArgumentException(ErrorMessages.INVALID_FORMAT_INPUT); + } + } + + public Points parseNumber(String input){ + List numbers = Pattern.compile("\\d+") + .matcher(input) + .results() + .map(MatchResult::group) + .map(StringUtil::parseDouble) + .toList(); + + Point point1 = Point.from(numbers.get(0), numbers.get(1)); + Point point2 = Point.from(numbers.get(2), numbers.get(3)); + + return new Points(point1, point2); + } + + + + +} diff --git a/src/main/java/io/ResultView.java b/src/main/java/io/ResultView.java new file mode 100644 index 0000000..9b4e0f8 --- /dev/null +++ b/src/main/java/io/ResultView.java @@ -0,0 +1,16 @@ +package io; + +public class ResultView { + + private double result; + + public ResultView(double result){ + this.result = result; + } + + public void print(){ + System.out.println("두 점 사이 거리는 " + result); + } + + +} diff --git a/src/main/java/messages/ErrorMessages.java b/src/main/java/messages/ErrorMessages.java new file mode 100644 index 0000000..6299ec3 --- /dev/null +++ b/src/main/java/messages/ErrorMessages.java @@ -0,0 +1,8 @@ +package messages; + +public class ErrorMessages { + public static final String INVALID_FORMAT_INPUT = "잘못된 입력 포맷입니다. 다시 입력해주세요."; + public static final String INVALID_NUMBER_INPUT = "좌표는 숫자만 입력 가능합니다. 다시 입력해주세요."; + public static final String INVALID_RANGE_INPUT = "좌표의 0부터 24까지 입력 가능합니다. 다시 입력해주세요."; + +} diff --git a/src/main/java/model/Calculator.java b/src/main/java/model/Calculator.java new file mode 100644 index 0000000..1d34590 --- /dev/null +++ b/src/main/java/model/Calculator.java @@ -0,0 +1,30 @@ +package model; + +public class Calculator { + public static final int SQUARE_EXPONENT = 2; + + private final Points points; + + public Calculator(Points points){ + this.points = points; + } + + public double distance(){ + // 제곱근((A.x - B.x)^제곱 + (A.y - B.y)^제곱) + double xDistance = powOfTwo(points.minusX()); + double yDistance = powOfTwo(points.minusY()); + + return plusAndSquareRoot(xDistance, yDistance); + } + + public double powOfTwo(double minusCoordinate){ + return Math.pow(minusCoordinate, SQUARE_EXPONENT); + } + + public double plusAndSquareRoot(double xDistance, double yDistance){ + return Math.sqrt(xDistance + yDistance); + } + + + +} diff --git a/src/main/java/model/Coordinate.java b/src/main/java/model/Coordinate.java new file mode 100644 index 0000000..1522aca --- /dev/null +++ b/src/main/java/model/Coordinate.java @@ -0,0 +1,37 @@ +package model; + + +import java.util.Objects; + +public class Coordinate { + private static final double MAX_COORDINATION = 24.0; + private static final double MIN_COORDINATION = 0.0; + + private final double coordination; + + public Coordinate(double coordination){ + this.coordination = coordination; + } + + public double getCoordination(){ + return coordination; + } + + public boolean isCorrectRange() { + return coordination <= MAX_COORDINATION && coordination >= MIN_COORDINATION; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Coordinate that = (Coordinate) o; + return Double.compare(coordination, that.coordination) == 0; + } + + @Override + public int hashCode() { + return Objects.hashCode(coordination); + } +} + diff --git a/src/main/java/model/Point.java b/src/main/java/model/Point.java new file mode 100644 index 0000000..28b4c18 --- /dev/null +++ b/src/main/java/model/Point.java @@ -0,0 +1,50 @@ +package model; + +import messages.ErrorMessages; + +import java.util.Objects; + +public class Point { + private Coordinate x; + private Coordinate y; + + public Point(Coordinate x, Coordinate y){ + this.x = x; + this.y = y; + validateRange(); + } + + public static Point from(double x, double y) { + return new Point( + new Coordinate(x), + new Coordinate(y) + ); + } + + public double getX(){ + return x.getCoordination(); + } + + public double getY(){ + return y.getCoordination(); + } + + public void validateRange(){ + if(!x.isCorrectRange() || !y.isCorrectRange()){ + throw new IllegalArgumentException(ErrorMessages.INVALID_RANGE_INPUT); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Point point = (Point) o; + return Objects.equals(x, point.x) && Objects.equals(y, point.y); + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } +} diff --git a/src/main/java/model/Points.java b/src/main/java/model/Points.java new file mode 100644 index 0000000..a4a1de4 --- /dev/null +++ b/src/main/java/model/Points.java @@ -0,0 +1,35 @@ +package model; + +import java.util.Objects; + +public class Points { + + private final Point point1; + private final Point point2; + + public Points(Point point1, Point point2){ + this.point1 = point1; + this.point2 = point2; + } + + public double minusX(){ + return point1.getX() - point2.getX(); + } + + public double minusY(){ + return point1.getY() - point2.getY(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Points points = (Points) o; + return Objects.equals(point1, points.point1) && Objects.equals(point2, points.point2); + } + + @Override + public int hashCode() { + return Objects.hash(point1, point2); + } +} diff --git a/src/main/java/util/StringUtil.java b/src/main/java/util/StringUtil.java new file mode 100644 index 0000000..813fc2e --- /dev/null +++ b/src/main/java/util/StringUtil.java @@ -0,0 +1,14 @@ +package util; + +import messages.ErrorMessages; + +public class StringUtil { + + public static double parseDouble(String number){ + try{ + return Double.parseDouble(number); + } catch (NumberFormatException ex){ + throw new IllegalArgumentException(ErrorMessages.INVALID_NUMBER_INPUT); + } + } +} diff --git a/src/test/java/io/CoordinateScannerTest.java b/src/test/java/io/CoordinateScannerTest.java new file mode 100644 index 0000000..267c5f1 --- /dev/null +++ b/src/test/java/io/CoordinateScannerTest.java @@ -0,0 +1,67 @@ +package io; + +import messages.ErrorMessages; +import model.Coordinate; +import model.Point; +import model.Points; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class CoordinateScannerTest { + + @ParameterizedTest + @ValueSource(strings = { + "(10,10)-(14,15)", + "(0,0)-(24,24)", + "(15,15)-(0,0)" + }) + @DisplayName("입력 포맷 검증") + void isCorrectFormat(String input){ + // given + CoordinateScanner scanner = new CoordinateScanner(); + + // when, then + assertDoesNotThrow(() -> scanner.isCorrectFormat(input)); + } + + @ParameterizedTest + @ValueSource(strings = { + "(10,10-(14,15)", + "(00)-(24,24)", + "(15,)-(0,0)", + "(10,10)(14,15)", + "(10, 130)-(14, 15)", + "(10,10)-14,15)" + }) + @DisplayName("입력 포맷 검증 시 예외 발생") + void isInvalidCorrectFormat(String input){ + // given + CoordinateScanner scanner = new CoordinateScanner(); + + // when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.isCorrectFormat(input)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_FORMAT_INPUT); + } + + @Test + @DisplayName("입력값 파싱 후 Points 객체 생성") + void parseNumber(){ + // given + CoordinateScanner scanner = new CoordinateScanner(); + Points mockPoints = new Points(Point.from(10, 10), Point.from(14, 15)); + + // when + Points points = scanner.parseNumber("(10,10)-(14,15)"); + + // then + assertThat(points.equals(mockPoints)).isTrue(); + } + +} \ No newline at end of file diff --git a/src/test/java/model/CalculatorTest.java b/src/test/java/model/CalculatorTest.java new file mode 100644 index 0000000..38767a1 --- /dev/null +++ b/src/test/java/model/CalculatorTest.java @@ -0,0 +1,89 @@ +package model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CalculatorTest { + + @Test + @DisplayName("거리 계산") + void distance(){ + // given + Point point1 = Point.from(10.0, 10.0); + Point point2 = Point.from(14.0, 15.0); + Points points = new Points(point1, point2); + + Calculator calculator = new Calculator(points); + + // when + double response = calculator.distance(); + + // then + assertThat(response).isEqualTo(6.4031242374328485); + } + + @Test + @DisplayName("거리 계산 시 점 좌표가 0인 경우") + void distancePointZero(){ + // given + Point point1 = Point.from(0.0, 0.0); + Point point2 = Point.from(14.0, 15.0); + Points points = new Points(point1, point2); + + Calculator calculator = new Calculator(points); + + // when + double response = calculator.distance(); + + // then + assertThat(response).isEqualTo(20.518284528683193); + } + + @Test + @DisplayName("거리 계산 시 점 좌표가 전부 0인 경우") + void distancePointAllZero(){ + // given + Point point1 = Point.from(0.0, 0.0); + Point point2 = Point.from(0.0, 0.0); + Points points = new Points(point1, point2); + + Calculator calculator = new Calculator(points); + + // when + double response = calculator.distance(); + + // then + assertThat(response).isEqualTo(0.0); + } + + @Test + @DisplayName("제곱 연산") + void powOfTwo(){ + // given + Points points = new Points(Point.from(10.0, 10.0), Point.from(14.0, 15.0)); + Calculator calculator = new Calculator(points); + + // when + double response = calculator.powOfTwo(5.0); + + // then + assertThat(response).isEqualTo(25.0); + } + + @Test + @DisplayName("제곱근 연산") + void plusAndSquareRoot(){ + // given + Points points = new Points(Point.from(10.0, 10.0), Point.from(14.0, 15.0)); + Calculator calculator = new Calculator(points); + + // when + double response = calculator.plusAndSquareRoot(4.0, 5.0); + + // then + assertThat(response).isEqualTo(3.0); + } +} diff --git a/src/test/java/model/CoordinateTest.java b/src/test/java/model/CoordinateTest.java new file mode 100644 index 0000000..7acc4f3 --- /dev/null +++ b/src/test/java/model/CoordinateTest.java @@ -0,0 +1,35 @@ +package model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CoordinateTest { + + @Test + @DisplayName("입력값 검증으로 true 반환") + void isCorrectRangeTrue(){ + // given + Coordinate coordinate = new Coordinate(24.0); + + // when + boolean response = coordinate.isCorrectRange(); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("입력값 검증으로 false 반환") + void isCorrectRangeFalse(){ + // given + Coordinate coordinate = new Coordinate(24.1); + + // when + boolean response = coordinate.isCorrectRange(); + + // then + assertThat(response).isFalse(); + } +} diff --git a/src/test/java/model/PointTest.java b/src/test/java/model/PointTest.java new file mode 100644 index 0000000..d240031 --- /dev/null +++ b/src/test/java/model/PointTest.java @@ -0,0 +1,55 @@ +package model; + +import messages.ErrorMessages; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class PointTest { + + @Test + @DisplayName("x, y 좌표값 범위 유효성 검사") + void validateRange(){ + // given + Point point = Point.from(24.0, 0.0); + + // when, then + assertDoesNotThrow(point::validateRange); + } + + @Test + @DisplayName("x 좌표값 범위 초과로 예외 발생") + void validateRange_overRangeX(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> Point.from(24.1, 0.0)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RANGE_INPUT); + + } + + @Test + @DisplayName("y 좌표값 범위 초과로 예외 발생") + void validateRange_overRangeY(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> Point.from(24.0, -0.9)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RANGE_INPUT); + + } + + @Test + @DisplayName("x, y 좌표값 범위 초과로 예외 발생") + void validateRange_overRangeXY(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> Point.from(24.1, -0.9)); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RANGE_INPUT); + + } +} diff --git a/src/test/java/model/PointsTest.java b/src/test/java/model/PointsTest.java new file mode 100644 index 0000000..750078b --- /dev/null +++ b/src/test/java/model/PointsTest.java @@ -0,0 +1,37 @@ +package model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class PointsTest { + + @Test + @DisplayName("x 좌표 거리 계산") + void minusX(){ + // given + Points points = new Points(Point.from(10.0, 10.0), Point.from(14.0, 15.0)); + + // when + double response = points.minusX(); + + // then + assertThat(response).isEqualTo(-4.0); + } + + @Test + @DisplayName("y 좌표 거리 계산") + void minusY(){ + // given + Points points = new Points(Point.from(10.0, 10.0), Point.from(14.0, 15.0)); + + // when + double response = points.minusY(); + + // then + assertThat(response).isEqualTo(-5.0); + } + +} \ No newline at end of file From 45a95c5add78559f549f990ddec62d2e7c9a0a47 Mon Sep 17 00:00:00 2001 From: Heesoo Date: Fri, 27 Dec 2024 22:53:08 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[test]=20=EB=AC=B8=EC=9E=90=EC=97=B4=20doub?= =?UTF-8?q?le=20=EB=B3=80=EA=B2=BD=20=ED=95=A8=EC=88=98=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/util/StringUtil.java | 4 ++-- src/test/java/util/StringUtilTest.java | 31 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 src/test/java/util/StringUtilTest.java diff --git a/src/main/java/util/StringUtil.java b/src/main/java/util/StringUtil.java index 813fc2e..32ea3ad 100644 --- a/src/main/java/util/StringUtil.java +++ b/src/main/java/util/StringUtil.java @@ -4,9 +4,9 @@ public class StringUtil { - public static double parseDouble(String number){ + public static double parseDouble(String numStr){ try{ - return Double.parseDouble(number); + return Double.parseDouble(numStr); } catch (NumberFormatException ex){ throw new IllegalArgumentException(ErrorMessages.INVALID_NUMBER_INPUT); } diff --git a/src/test/java/util/StringUtilTest.java b/src/test/java/util/StringUtilTest.java new file mode 100644 index 0000000..f5df257 --- /dev/null +++ b/src/test/java/util/StringUtilTest.java @@ -0,0 +1,31 @@ +package util; + +import messages.ErrorMessages; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class StringUtilTest { + @Test + @DisplayName("문자열 Double 로 변경") + void parseDouble(){ + // given, when + double response = StringUtil.parseDouble("10"); + + // then + assertThat(response).isEqualTo(10.0); + } + + @Test + @DisplayName("문자열 Double 로 변경 시 예외 발생") + void parseDoubleException(){ + // given, when + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> StringUtil.parseDouble("입력")); + + // then + assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_NUMBER_INPUT); + } + +} \ No newline at end of file From 104ee9bc67daf707c6f017e44a1ef435eaae3469 Mon Sep 17 00:00:00 2001 From: Heesoo Date: Fri, 27 Dec 2024 23:04:00 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[refactor]=20getter=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=ED=9B=84=20=EB=BA=84=EC=85=88=20=EA=B4=80=EB=A0=A8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/model/Coordinate.java | 9 +++++---- src/main/java/model/Point.java | 9 +++++---- src/main/java/model/Points.java | 4 ++-- src/test/java/model/CoordinateTest.java | 15 ++++++++++++++ src/test/java/model/PointTest.java | 26 +++++++++++++++++++++++++ src/test/java/model/PointsTest.java | 1 - 6 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/main/java/model/Coordinate.java b/src/main/java/model/Coordinate.java index 1522aca..fe60008 100644 --- a/src/main/java/model/Coordinate.java +++ b/src/main/java/model/Coordinate.java @@ -13,14 +13,14 @@ public Coordinate(double coordination){ this.coordination = coordination; } - public double getCoordination(){ - return coordination; - } - public boolean isCorrectRange() { return coordination <= MAX_COORDINATION && coordination >= MIN_COORDINATION; } + public double minus(Coordinate other) { + return this.coordination - other.coordination; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -33,5 +33,6 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(coordination); } + } diff --git a/src/main/java/model/Point.java b/src/main/java/model/Point.java index 28b4c18..d431cfd 100644 --- a/src/main/java/model/Point.java +++ b/src/main/java/model/Point.java @@ -21,12 +21,12 @@ public static Point from(double x, double y) { ); } - public double getX(){ - return x.getCoordination(); + public double minusX(Point other) { + return this.x.minus(other.x); } - public double getY(){ - return y.getCoordination(); + public double minusY(Point other){ + return this.y.minus(other.y); } public void validateRange(){ @@ -47,4 +47,5 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(x, y); } + } diff --git a/src/main/java/model/Points.java b/src/main/java/model/Points.java index a4a1de4..d105704 100644 --- a/src/main/java/model/Points.java +++ b/src/main/java/model/Points.java @@ -13,11 +13,11 @@ public Points(Point point1, Point point2){ } public double minusX(){ - return point1.getX() - point2.getX(); + return point1.minusX(point2); } public double minusY(){ - return point1.getY() - point2.getY(); + return point1.minusY(point2); } @Override diff --git a/src/test/java/model/CoordinateTest.java b/src/test/java/model/CoordinateTest.java index 7acc4f3..eb8abfa 100644 --- a/src/test/java/model/CoordinateTest.java +++ b/src/test/java/model/CoordinateTest.java @@ -32,4 +32,19 @@ void isCorrectRangeFalse(){ // then assertThat(response).isFalse(); } + + @Test + @DisplayName("coordinate 값 뺄셈") + void minus(){ + // given + Coordinate coordinate1 = new Coordinate(10); + Coordinate coordinate2 = new Coordinate(5); + + // when + double response = coordinate1.minus(coordinate2); + + // then + assertThat(response).isEqualTo(5); + + } } diff --git a/src/test/java/model/PointTest.java b/src/test/java/model/PointTest.java index d240031..9be53ea 100644 --- a/src/test/java/model/PointTest.java +++ b/src/test/java/model/PointTest.java @@ -52,4 +52,30 @@ void validateRange_overRangeXY(){ assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_RANGE_INPUT); } + + @Test + @DisplayName("x 값 뺄셈") + void minusX(){ + // given + Point point1 = Point.from(10, 10); + Point point2 = Point.from(5, 5); + + // when + double response = point1.minusX(point2); + + assertThat(response).isEqualTo(5); + } + + @Test + @DisplayName("y 값 뺄셈") + void minusY(){ + // given + Point point1 = Point.from(10, 10); + Point point2 = Point.from(5, 5); + + // when + double response = point1.minusY(point2); + + assertThat(response).isEqualTo(5); + } } diff --git a/src/test/java/model/PointsTest.java b/src/test/java/model/PointsTest.java index 750078b..1c0a91f 100644 --- a/src/test/java/model/PointsTest.java +++ b/src/test/java/model/PointsTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; class PointsTest { From 23ce8f43e95ecf23fc8a35980641419a985087cd Mon Sep 17 00:00:00 2001 From: Heesoo Date: Wed, 1 Jan 2025 19:08:29 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[feat]=20=EA=B7=B8=EB=9E=98=ED=94=84=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README-HS.md | 29 +++++++- src/main/java/CoordinateMain.java | 2 +- src/main/java/io/ResultView.java | 55 +++++++++++++++- src/main/java/model/Coordinate.java | 14 ++++ src/main/java/model/Point.java | 24 +++++++ src/main/java/model/Points.java | 12 ++++ src/test/java/model/CoordinateTest.java | 29 +++++++- src/test/java/model/PointTest.java | 88 +++++++++++++++++++++++++ src/test/java/model/PointsTest.java | 44 +++++++++++++ 9 files changed, 293 insertions(+), 4 deletions(-) diff --git a/README-HS.md b/README-HS.md index a01ce45..53d0454 100644 --- a/README-HS.md +++ b/README-HS.md @@ -13,11 +13,38 @@ 4. 메소드 한가지 일만 하도록 구현 5. 일급 컬렉션 사용 -**\* 상속 또는 인터페이스 사용해서 구현** ## 실행 결과 ``` 좌표를 입력하세요. (10,10)-(14,15) + +24| + | +22| + | +20| + | +18| + | +16| + | +14| + | . +12| + | +10| . + | + 8| + | + 6| + | + 4| + | + 2| + | + +ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ + 0 2 4 6 8 10 12 14 16 18 20 22 24 두 점 사이 거리는 6.403124 + ``` diff --git a/src/main/java/CoordinateMain.java b/src/main/java/CoordinateMain.java index 72d728f..12f2c21 100644 --- a/src/main/java/CoordinateMain.java +++ b/src/main/java/CoordinateMain.java @@ -11,7 +11,7 @@ public static void main(String[] args) { Calculator calculator = new Calculator(points); double result = calculator.distance(); - ResultView resultView = new ResultView(result); + ResultView resultView = new ResultView(points, result); resultView.print(); } } diff --git a/src/main/java/io/ResultView.java b/src/main/java/io/ResultView.java index 9b4e0f8..3d57c3f 100644 --- a/src/main/java/io/ResultView.java +++ b/src/main/java/io/ResultView.java @@ -1,16 +1,69 @@ package io; +import model.Points; + public class ResultView { + private static final int MAX_X = 24; + private static final int MAX_Y = 24; + private static final int MAX_X_LINE = 48; + private Points points; private double result; - public ResultView(double result){ + private StringBuilder sb; + + public ResultView(Points points, double result){ + this.points = points; this.result = result; + this.sb = new StringBuilder(); } public void print(){ + System.out.println(drawGraph()); System.out.println("두 점 사이 거리는 " + result); } + public String drawGraph(){ + drawY(); + drawX(); + + return sb.toString(); + } + + public void drawY(){ + for(int i=MAX_Y; i>0; i--){ + drawYLine(i); + points.drawPoints(i, sb); + sb.append("\n"); + } + } + + public void drawYLine(int i){ + String str = " |"; + + if (i % 2 == 0){ + str = String.format("%2d|", i); + } + + sb.append(str); + } + + + public void drawX(){ + drawXLine(); + + sb.append(" "); + + for(int i=0; i<=MAX_X; i+=2){ + sb.append(String.format("%-6d", i)); + } + } + + public void drawXLine(){ + sb.append(" +") + .append("―".repeat(MAX_X_LINE)) + .append("\n"); + } + } diff --git a/src/main/java/model/Coordinate.java b/src/main/java/model/Coordinate.java index fe60008..1798fbf 100644 --- a/src/main/java/model/Coordinate.java +++ b/src/main/java/model/Coordinate.java @@ -6,6 +6,7 @@ public class Coordinate { private static final double MAX_COORDINATION = 24.0; private static final double MIN_COORDINATION = 0.0; + private static final int GRAPH_SPACE = 3; private final double coordination; @@ -17,10 +18,23 @@ public boolean isCorrectRange() { return coordination <= MAX_COORDINATION && coordination >= MIN_COORDINATION; } + public boolean equals(double e){ + return coordination == e; + } + + public int getGraphPosition(){ + return (int) (coordination * GRAPH_SPACE); + } + + public int getGraphPositionDifference(Coordinate other){ + return (int) minus(other) * GRAPH_SPACE; + } + public double minus(Coordinate other) { return this.coordination - other.coordination; } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/model/Point.java b/src/main/java/model/Point.java index d431cfd..9d168c3 100644 --- a/src/main/java/model/Point.java +++ b/src/main/java/model/Point.java @@ -35,6 +35,29 @@ public void validateRange(){ } } + public void drawPointIfMatchY(int yValue, StringBuilder sb){ + if (isEqualY(yValue)){ + sb.append(" ".repeat(x.getGraphPosition())) + .append("ㆍ"); + } + } + + public void drawPointIfMatchY(int yValue, StringBuilder sb, Point other){ + if (isEqualY(yValue)){ + sb.append(" ".repeat(x.getGraphPositionDifference(other.x))) + .append("ㆍ"); + } + } + + public boolean isEqualY(int yValue){ + return y.equals(yValue); + } + + public boolean isEqualY(Point other){ + return y.equals(other.y); + } + + @Override public boolean equals(Object o) { if (this == o) return true; @@ -49,3 +72,4 @@ public int hashCode() { } } + diff --git a/src/main/java/model/Points.java b/src/main/java/model/Points.java index d105704..13f0255 100644 --- a/src/main/java/model/Points.java +++ b/src/main/java/model/Points.java @@ -32,4 +32,16 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(point1, point2); } + + public void drawPoints(int yValue, StringBuilder sb){ + point1.drawPointIfMatchY(yValue, sb); + + if (point1.isEqualY(point2)){ + point2.drawPointIfMatchY(yValue, sb, point1); + return; + } + + point2.drawPointIfMatchY(yValue, sb); + + } } diff --git a/src/test/java/model/CoordinateTest.java b/src/test/java/model/CoordinateTest.java index eb8abfa..faa82c9 100644 --- a/src/test/java/model/CoordinateTest.java +++ b/src/test/java/model/CoordinateTest.java @@ -34,7 +34,7 @@ void isCorrectRangeFalse(){ } @Test - @DisplayName("coordinate 값 뺄셈") + @DisplayName("좌표값 뺄셈") void minus(){ // given Coordinate coordinate1 = new Coordinate(10); @@ -47,4 +47,31 @@ void minus(){ assertThat(response).isEqualTo(5); } + + @Test + @DisplayName("그래프 좌표 위치 반환") + void getGraphPosition(){ + // given + Coordinate coordinate1 = new Coordinate(10); + + // when + int response = coordinate1.getGraphPosition(); + + // then + assertThat(response).isEqualTo(30); + } + + @Test + @DisplayName("다른 점과 y값이 같은 경우 그래프 좌표 위치 반환") + void getGraphPositionDifference(){ + // given + Coordinate coordinate1 = new Coordinate(10); + Coordinate coordinate2 = new Coordinate(7); + + // when + int response = coordinate1.getGraphPositionDifference(coordinate2); + + // then + assertThat(response).isEqualTo(9); + } } diff --git a/src/test/java/model/PointTest.java b/src/test/java/model/PointTest.java index 9be53ea..0202e2f 100644 --- a/src/test/java/model/PointTest.java +++ b/src/test/java/model/PointTest.java @@ -63,6 +63,7 @@ void minusX(){ // when double response = point1.minusX(point2); + // then assertThat(response).isEqualTo(5); } @@ -76,6 +77,93 @@ void minusY(){ // when double response = point1.minusY(point2); + // then assertThat(response).isEqualTo(5); } + + @Test + @DisplayName("y 좌표 같아 좌표 그림 추가") + void drawPointIfMatchY(){ + // given + Point point1 = Point.from(2, 1); + StringBuilder sb = new StringBuilder(); + + // when + point1.drawPointIfMatchY(1, sb); + + // then + assertThat(sb.toString()).isEqualTo(" ㆍ"); + } + + @Test + @DisplayName("y 좌표 같지 않아서 좌표 그림 추가 안됨") + void drawPointIfNotMatchY(){ + // given + Point point1 = Point.from(2, 1); + StringBuilder sb = new StringBuilder(); + + // when + point1.drawPointIfMatchY(5, sb); + + // then + assertThat(sb.isEmpty()).isTrue(); + } + + @Test + @DisplayName("다른 점과 y 좌표 같은 같으면서 인자로 넘어온 y 값과 같아 좌표 그림 추가") + void drawPointIfMatchY_matchOtherPoint(){ + // given + Point point1 = Point.from(2, 1); + Point point2 = Point.from(3, 1); + StringBuilder sb = new StringBuilder(); + + // when + point1.drawPointIfMatchY(1, sb, point2); + + // then + assertThat(sb.toString()).isEqualTo(" ㆍ"); + } + + @Test + @DisplayName("다른 점과 y 좌표 같은 같으면서 인자로 넘어온 y 값과 같지 않아 좌표 그림 추가 안됨") + void drawPointIfNotMatchY_matchOtherPoint(){ + // given + Point point1 = Point.from(2, 1); + Point point2 = Point.from(3, 1); + StringBuilder sb = new StringBuilder(); + + // when + point1.drawPointIfMatchY(5, sb, point2); + + // then + assertThat(sb.isEmpty()).isTrue(); + } + + @Test + @DisplayName("y 좌표 같아 true 반환") + void isEqualY_true(){ + // given + Point point1 = Point.from(2, 10); + + // when + boolean response = point1.isEqualY(10); + + // then + assertThat(response).isTrue(); + } + + @Test + @DisplayName("y 좌표 같아 false 반환") + void isEqualY_false(){ + // given + Point point1 = Point.from(2, 10); + + // when + boolean response = point1.isEqualY(5); + + // then + assertThat(response).isFalse(); + } + + } diff --git a/src/test/java/model/PointsTest.java b/src/test/java/model/PointsTest.java index 1c0a91f..068667e 100644 --- a/src/test/java/model/PointsTest.java +++ b/src/test/java/model/PointsTest.java @@ -33,4 +33,48 @@ void minusY(){ assertThat(response).isEqualTo(-5.0); } + @Test + @DisplayName("점 2개 다 y 값 같은 좌표 그림 생성") + void drawPoints_pointsMatchY(){ + // given + Points points = new Points(Point.from(2.0, 1.0), Point.from(3.0, 1.0)); + StringBuilder sb = new StringBuilder(); + + // when + points.drawPoints(1, sb); + + // then + assertThat(sb.toString()).isEqualTo(" ㆍ ㆍ"); + } + + + @Test + @DisplayName("점 1개만 y 값이 같은 그림 생성") + void drawPoints_pointMatchY(){ + // given + Points points = new Points(Point.from(2.0, 1.0), Point.from(3.0, 2.0)); + StringBuilder sb = new StringBuilder(); + + // when + points.drawPoints(1, sb); + + // then + assertThat(sb.toString()).isEqualTo(" ㆍ"); + } + + @Test + @DisplayName("모든 점이 y 값과 다른 경우") + void drawPoints_pointsNotMatchY(){ + // given + Points points = new Points(Point.from(2.0, 1.0), Point.from(3.0, 2.0)); + StringBuilder sb = new StringBuilder(); + + // when + points.drawPoints(10, sb); + + // then + assertThat(sb.isEmpty()).isTrue(); + } + + } \ No newline at end of file From ebd2c1e2115dae424c0fbf8c1bea23896cc93112 Mon Sep 17 00:00:00 2001 From: Heesoo Date: Wed, 1 Jan 2025 19:12:08 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[refactor]=20=EC=9E=85=EB=A0=A5=20=ED=8F=AC?= =?UTF-8?q?=EB=A7=B7=20=EA=B2=80=EC=A6=9D=EB=AC=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/CoordinateScanner.java | 10 ++-- src/test/java/io/CoordinateScannerTest.java | 53 +++++++++++++++++++-- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/CoordinateScanner.java b/src/main/java/io/CoordinateScanner.java index ab0f022..50ee12c 100644 --- a/src/main/java/io/CoordinateScanner.java +++ b/src/main/java/io/CoordinateScanner.java @@ -30,7 +30,7 @@ public Points validDots(String input){ Points points; try{ - isCorrectFormat(input); + checkMatchFormat(input); points = parseNumber(input); } catch (IllegalArgumentException ex){ System.out.println(ex.getMessage()); @@ -41,12 +41,16 @@ public Points validDots(String input){ } - public void isCorrectFormat(String input){ - if(!input.matches("\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)")){ + public void checkMatchFormat(String input){ + if(!isMatchFormat(input)){ throw new IllegalArgumentException(ErrorMessages.INVALID_FORMAT_INPUT); } } + public boolean isMatchFormat(String input){ + return input.matches("\\([0-9]{1,2},[0-9]{1,2}\\)-\\([0-9]{1,2},[0-9]{1,2}\\)"); + } + public Points parseNumber(String input){ List numbers = Pattern.compile("\\d+") .matcher(input) diff --git a/src/test/java/io/CoordinateScannerTest.java b/src/test/java/io/CoordinateScannerTest.java index 267c5f1..15881dc 100644 --- a/src/test/java/io/CoordinateScannerTest.java +++ b/src/test/java/io/CoordinateScannerTest.java @@ -1,7 +1,6 @@ package io; import messages.ErrorMessages; -import model.Coordinate; import model.Point; import model.Points; import org.junit.jupiter.api.DisplayName; @@ -21,12 +20,12 @@ class CoordinateScannerTest { "(15,15)-(0,0)" }) @DisplayName("입력 포맷 검증") - void isCorrectFormat(String input){ + void checkMatchFormat(String input){ // given CoordinateScanner scanner = new CoordinateScanner(); // when, then - assertDoesNotThrow(() -> scanner.isCorrectFormat(input)); + assertDoesNotThrow(() -> scanner.checkMatchFormat(input)); } @ParameterizedTest @@ -39,17 +38,61 @@ void isCorrectFormat(String input){ "(10,10)-14,15)" }) @DisplayName("입력 포맷 검증 시 예외 발생") - void isInvalidCorrectFormat(String input){ + void checkMatchFormat_exception(String input){ // given CoordinateScanner scanner = new CoordinateScanner(); // when - IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.isCorrectFormat(input)); + IllegalArgumentException fail = assertThrows(IllegalArgumentException.class, () -> scanner.checkMatchFormat(input)); // then assertThat(fail.getMessage()).isEqualTo(ErrorMessages.INVALID_FORMAT_INPUT); } + + @ParameterizedTest + @ValueSource(strings = { + "(10,10)-(14,15)", + "(0,0)-(24,24)", + "(15,15)-(0,0)" + }) + @DisplayName("입력 포맷 검증") + void isMatchFormat(String input){ + // given + CoordinateScanner scanner = new CoordinateScanner(); + + // when + boolean response = scanner.isMatchFormat(input); + + // then + assertThat(response).isTrue(); + + } + + @ParameterizedTest + @ValueSource(strings = { + "(10,10-(14,15)", + "(00)-(24,24)", + "(15,)-(0,0)", + "(10,10)(14,15)", + "(10, 130)-(14, 15)", + "(10,10)-14,15)" + }) + @DisplayName("입력 포맷 검증 시 예외 발생") + void isNotMatchFormat(String input){ + // given + CoordinateScanner scanner = new CoordinateScanner(); + + // when + boolean response = scanner.isMatchFormat(input); + + // then + assertThat(response).isFalse(); + } + + + + @Test @DisplayName("입력값 파싱 후 Points 객체 생성") void parseNumber(){