diff --git a/src/main/java/com/johngrib/objects/_12_lecture/FormattedGradeLecture.java b/src/main/java/com/johngrib/objects/_12_lecture/FormattedGradeLecture.java new file mode 100644 index 0000000..9da67e5 --- /dev/null +++ b/src/main/java/com/johngrib/objects/_12_lecture/FormattedGradeLecture.java @@ -0,0 +1,13 @@ +package com.johngrib.objects._12_lecture; + +import java.util.List; + +public class FormattedGradeLecture extends GradeLecture { + public FormattedGradeLecture(String name, int pass, List grades, List scores) { + super(name, pass, grades, scores); + } + + public String formatAverage() { + return String.format("Avg: %1.1f", super.average()); + } +} diff --git a/src/main/java/com/johngrib/objects/_12_lecture/Grade.java b/src/main/java/com/johngrib/objects/_12_lecture/Grade.java new file mode 100644 index 0000000..e9f0623 --- /dev/null +++ b/src/main/java/com/johngrib/objects/_12_lecture/Grade.java @@ -0,0 +1,23 @@ +package com.johngrib.objects._12_lecture; + +import lombok.Getter; + +public class Grade { + @Getter + private String name; + private int upper, lower; + + public Grade(String name, int upper, int lower) { + this.name = name; + this.upper = upper; + this.lower = lower; + } + + public boolean isName(String name) { + return this.name.equals(name); + } + + public boolean include(int score) { + return lower <= score && score <= upper; + } +} diff --git a/src/main/java/com/johngrib/objects/_12_lecture/GradeLecture.java b/src/main/java/com/johngrib/objects/_12_lecture/GradeLecture.java new file mode 100644 index 0000000..42792e8 --- /dev/null +++ b/src/main/java/com/johngrib/objects/_12_lecture/GradeLecture.java @@ -0,0 +1,55 @@ +package com.johngrib.objects._12_lecture; + +import java.util.List; +import java.util.stream.Collectors; + +public class GradeLecture extends Lecture { + private List grades; + + public GradeLecture(String title, int pass, List grades, List scores) { + super(title, pass, scores); + this.grades = grades; + } + + @Override + public String evaluate() { + return super.evaluate() + ", " + gradeStatistics(); + } + + private String gradeStatistics() { + return grades.stream() + .map(grade -> format(grade)) + .collect(Collectors.joining(" ")); + } + + private String format(Grade grade) { + return String.format("%s:%d", grade.getName(), gradeCount(grade)); + } + + private long gradeCount(Grade grade) { + return getScores().stream() + .filter(grade::include) + .count(); + } + + public double average(String gradeName) { + return grades.stream() + .filter(each -> each.isName(gradeName)) + .findFirst() + .map(this::gradeAverage) + .orElse(0d); + } + + private double gradeAverage(Grade grade) { + return getScores().stream() + .filter(grade::include) + .mapToInt(Integer::intValue) + .average() + .orElse(0); + } + + @Override + public String getEvaluationMethod() { + return "Grade"; + } +} diff --git a/src/main/java/com/johngrib/objects/_12_lecture/Lecture.java b/src/main/java/com/johngrib/objects/_12_lecture/Lecture.java new file mode 100644 index 0000000..c55ff81 --- /dev/null +++ b/src/main/java/com/johngrib/objects/_12_lecture/Lecture.java @@ -0,0 +1,55 @@ +package com.johngrib.objects._12_lecture; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Lecture { + /** 이수 여부를 판단할 기준 점수. */ + private int pass; + + private String title; + private List scores = new ArrayList<>(); + + public Lecture(String title, int pass, List scores) { + this.title = title; + this.pass = pass; + this.scores = scores; + } + + /** 전체 학생들의 평균 성적을 리턴한다. */ + public double average() { + return scores.stream() + .mapToInt(Integer::intValue) + .average() + .orElse(0); + } + + /** 전체 학생들의 성적을 리턴한다. */ + public List getScores() { + return Collections.unmodifiableList(scores); + } + + /** 강의를 이수한 학생의 수와 낙제한 학생의 수를 형식에 맞게 구성한 문자열을 리턴한다. */ + public String evaluate() { + return String.format("Pass:%d Fail:%d", passCount(), failCount()); + } + + private long passCount() { + return scores.stream() + .filter(score -> score >= pass) + .count(); + } + + private long failCount() { + return scores.size() - passCount(); + } + + public String stats() { + return String.format("Title: %s, Evaluation Method: %s", title, getEvaluationMethod()); + } + + public String getEvaluationMethod() { + return "Pass or Fail"; + } +} diff --git a/src/test/java/com/johngrib/objects/_12_lecture/GradeLectureTest.java b/src/test/java/com/johngrib/objects/_12_lecture/GradeLectureTest.java new file mode 100644 index 0000000..583f55f --- /dev/null +++ b/src/test/java/com/johngrib/objects/_12_lecture/GradeLectureTest.java @@ -0,0 +1,38 @@ +package com.johngrib.objects._12_lecture; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("GradeLecture") +class GradeLectureTest { + Lecture givenLecture() { + return new GradeLecture( + "객체지향 프로그래밍", + 70, + Arrays.asList( + new Grade("A", 100, 95), + new Grade("B", 94, 80), + new Grade("C", 79, 70), + new Grade("D", 69, 50), + new Grade("F", 49, 0)), + Arrays.asList(81, 95, 75, 50, 45)); + } + + @Nested + @DisplayName("evaluate 메소드") + class Describe_evaluate { + @Test + @DisplayName("이수한 학생의 수와 낙제한 학생의 수를 표현하는 문자열을 리턴한다") + void it_returns_formatted_string() { + final String result = givenLecture().evaluate(); + + Assertions.assertEquals(result, "Pass:3 Fail:2, A:1 B:1 C:1 D:1 F:1"); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/johngrib/objects/_12_lecture/LectureTest.java b/src/test/java/com/johngrib/objects/_12_lecture/LectureTest.java new file mode 100644 index 0000000..8c46b3c --- /dev/null +++ b/src/test/java/com/johngrib/objects/_12_lecture/LectureTest.java @@ -0,0 +1,33 @@ +package com.johngrib.objects._12_lecture; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("Lecture") +class LectureTest { + Lecture givenLecture() { + return new Lecture( + "객체지향 프로그래밍", + 70, + Arrays.asList(81, 95, 75, 50, 45) + ); + } + + @Nested + @DisplayName("evaluate 메소드") + class Describe_evaluate { + @Test + @DisplayName("이수한 학생의 수와 낙제한 학생의 수를 표현하는 문자열을 리턴한다") + void it_returns_formatted_string() { + final String result = givenLecture().evaluate(); + + Assertions.assertEquals(result, "Pass:3 Fail:2"); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/johngrib/objects/_12_lecture/Professor.java b/src/test/java/com/johngrib/objects/_12_lecture/Professor.java new file mode 100644 index 0000000..1fc12f4 --- /dev/null +++ b/src/test/java/com/johngrib/objects/_12_lecture/Professor.java @@ -0,0 +1,16 @@ +package com.johngrib.objects._12_lecture; + +public class Professor { + private String name; + private Lecture lecture; + + public Professor(String name, Lecture lecture) { + this.name = name; + this.lecture = lecture; + } + + public String compileStatistics() { + return String.format("[%s] %s - Avg: %.1f", + name, lecture.evaluate(), lecture.average()); + } +} diff --git a/src/test/java/com/johngrib/objects/_12_lecture/ProfessorTest.java b/src/test/java/com/johngrib/objects/_12_lecture/ProfessorTest.java new file mode 100644 index 0000000..7fae285 --- /dev/null +++ b/src/test/java/com/johngrib/objects/_12_lecture/ProfessorTest.java @@ -0,0 +1,59 @@ +package com.johngrib.objects._12_lecture; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("Professor") +class ProfessorTest { + + @Nested + @DisplayName("compileStatistics 메소드") + class Describe_compileStatistics { + @Nested + @DisplayName("다익스트라 교수의 알고리즘 Lecture 라면") + class Context_with_dijkstra { + Professor givenProfessor() { + return new Professor("다익스트라", + new Lecture("알고리즘", 70, Arrays.asList(81, 95, 75, 50, 45))); + } + + @Test + @DisplayName("이수한 학생의 수, 낙제한 학생의 수, 평균을 표현하는 문자열을 리턴한다") + void it_returns_statistics() { + final String result = givenProfessor().compileStatistics(); + + assertEquals(result, "[다익스트라] Pass:3 Fail:2 - Avg: 69.2"); + } + } + + @Nested + @DisplayName("다익스트라 교수의 알고리즘 GradeLecture 라면") + class Context_with_dijkstra_grade_lecture { + Professor givenProfessor() { + return new Professor("다익스트라", + new GradeLecture("알고리즘", 70, + Arrays.asList( + new Grade("A", 100, 95), + new Grade("B", 94, 80), + new Grade("C", 79, 70), + new Grade("D", 69, 50), + new Grade("F", 49, 0)), + Arrays.asList(81, 95, 75, 50, 45))); + } + + @Test + @DisplayName("이수한 학생의 수, 낙제한 학생의 수, 각 학점별 수, 평균을 표현하는 문자열을 리턴한다") + void it_returns_statistics() { + final String result = givenProfessor().compileStatistics(); + + assertEquals(result, "[다익스트라] Pass:3 Fail:2, A:1 B:1 C:1 D:1 F:1 - Avg: 69.2"); + } + } + } + +} \ No newline at end of file