-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat(#95): 캐릭터 생성 #101
The head ref may contain hidden characters: "feature/#95-\uCE90\uB9AD\uD130-\uC0DD\uC131"
Feat(#95): 캐릭터 생성 #101
Changes from 14 commits
7c44b2c
a375a77
9b731d9
658f309
85bf864
17bd482
830c4cf
e93a695
709493b
c9e7767
85a1eaa
f1d9b9d
d10ff59
2b95853
687964c
0854646
8af2f98
60be7a2
32f9496
b9ddddf
25fac90
3108ac1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package org.nexters.jaknaesocore.domain.character.model; | ||
|
||
import java.math.BigDecimal; | ||
import java.time.LocalDate; | ||
import java.util.Comparator; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.RequiredArgsConstructor; | ||
import org.nexters.jaknaesocore.common.model.ScaledBigDecimal; | ||
import org.nexters.jaknaesocore.domain.member.model.Member; | ||
import org.nexters.jaknaesocore.domain.survey.model.Keyword; | ||
import org.nexters.jaknaesocore.domain.survey.model.KeywordMetrics; | ||
import org.nexters.jaknaesocore.domain.survey.model.KeywordScore; | ||
import org.nexters.jaknaesocore.domain.survey.model.SurveyBundle; | ||
import org.nexters.jaknaesocore.domain.survey.model.SurveySubmission; | ||
|
||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class Characters { | ||
|
||
private final Long characterNo; | ||
private final Member member; | ||
private final SurveyBundle bundle; | ||
private final List<KeywordScore> scores; | ||
private final List<SurveySubmission> submissions; | ||
private final Map<Keyword, ValueCharacter> valueCharacters; | ||
|
||
@Builder | ||
public static Characters of( | ||
final Long characterNo, | ||
final Member member, | ||
final SurveyBundle bundle, | ||
final List<KeywordScore> scores, | ||
final List<SurveySubmission> submissions, | ||
final Map<Keyword, ValueCharacter> valueCharacters) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 캐릭터 생성에 필요한 파라미터입니다.
|
||
return new Characters(characterNo, member, bundle, scores, submissions, valueCharacters); | ||
} | ||
|
||
public CharacterRecord provideCharacterRecord() { | ||
final List<ValueReport> valueReports = provideValueReport(); | ||
final ValueCharacter valueCharacter = findTopValueCharacter(valueReports); | ||
return CharacterRecord.builder() | ||
.characterNo("TODO 수정") | ||
.valueCharacter(valueCharacter) | ||
.valueReports(valueReports) | ||
.member(member) | ||
.surveyBundle(bundle) | ||
.valueReports(valueReports) | ||
.startDate(bundle.getCreatedAt().toLocalDate()) | ||
.endDate(LocalDate.now()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 두 부분은 번들내부의 제출 이력에서 submittedAt을 꺼내서 사용해야될 것 같아요 !! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아...! 번들 생성은 미리 해놓는 거였군요.. 😂 |
||
.build(); | ||
} | ||
|
||
private List<ValueReport> provideValueReport() { | ||
final Map<Keyword, KeywordMetrics> metricsMap = calculateKeywordMetrics(scores); | ||
final Map<Keyword, BigDecimal> weightMap = calculateKeywordWeights(metricsMap); | ||
|
||
return ValueReports.report(weightMap, metricsMap, submissions); | ||
} | ||
|
||
private Map<Keyword, KeywordMetrics> calculateKeywordMetrics(final List<KeywordScore> scores) { | ||
return scores.stream() | ||
.collect(Collectors.groupingBy(KeywordScore::getKeyword, Collectors.toList())) | ||
.entrySet() | ||
.stream() | ||
.collect( | ||
Collectors.toMap(Map.Entry::getKey, entry -> KeywordMetrics.create(entry.getValue()))); | ||
} | ||
|
||
private Map<Keyword, BigDecimal> calculateKeywordWeights( | ||
final Map<Keyword, KeywordMetrics> metricsMap) { | ||
int keywordCnt = metricsMap.size(); | ||
ScaledBigDecimal sumPerKeyword = | ||
ScaledBigDecimal.of(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(keywordCnt)); | ||
|
||
Map<Keyword, BigDecimal> weightMap = new HashMap<>(); | ||
metricsMap.forEach( | ||
(k, v) -> { | ||
var sum = v.getPositive().subtract(v.getNegative()); | ||
weightMap.put(k, sumPerKeyword.divide(sum).getValue()); | ||
}); | ||
return weightMap; | ||
} | ||
|
||
private ValueCharacter findTopValueCharacter(final List<ValueReport> valueReports) { | ||
final ValueReport topReport = | ||
valueReports.stream() | ||
.max(Comparator.comparing(ValueReport::getPercentage)) | ||
.orElseThrow(() -> new IllegalStateException("ValueReport가 비어 있습니다.")); | ||
|
||
return valueCharacters.get(topReport.getKeyword()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,34 @@ | ||
package org.nexters.jaknaesocore.domain.character.model; | ||
|
||
import jakarta.persistence.Embeddable; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import java.math.BigDecimal; | ||
import java.util.Objects; | ||
import lombok.AccessLevel; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.nexters.jaknaesocore.common.model.BaseTimeEntity; | ||
import org.nexters.jaknaesocore.common.model.ScaledBigDecimal; | ||
import org.nexters.jaknaesocore.domain.survey.model.Keyword; | ||
|
||
@EqualsAndHashCode | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@Embeddable | ||
public class ValueReport { | ||
@Entity | ||
public class ValueReport extends BaseTimeEntity { | ||
|
||
@Enumerated(EnumType.STRING) | ||
private Keyword keyword; | ||
|
||
private BigDecimal percentage; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "character_record_id") | ||
private CharacterRecord characterRecord; | ||
|
||
private ValueReport(final Keyword keyword, final BigDecimal percentage) { | ||
this.keyword = keyword; | ||
this.percentage = percentage; | ||
|
@@ -31,6 +38,27 @@ public static ValueReport of(final Keyword keyword, final ScaledBigDecimal perce | |
return new ValueReport(keyword, percentage.getValue()); | ||
} | ||
|
||
public void updateCharacterRecord(final CharacterRecord characterRecord) { | ||
this.characterRecord = characterRecord; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
ValueReport that = (ValueReport) o; | ||
return keyword == that.keyword && Objects.equals(percentage, that.percentage); | ||
} | ||
Comment on lines
+45
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. entity 객체 동일성을 키워드랑 퍼센티지로 계산하는 이유가 무엇인가요? 보통 entity는 식별자를 통해 객체 동일성을 판단해서 여쭤봅니다. 만약 이 비교가 필요한 로직이 있다면 VO를 따로 만드는 게 좋을 것 같습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 Entity에 |
||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(keyword, percentage); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "ValueReport{" + "keyword=" + keyword + ",percentage=" + percentage + "}"; | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package org.nexters.jaknaesocore.domain.character.repository; | ||
|
||
import org.nexters.jaknaesocore.domain.character.model.ValueReport; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ValueReportRepository extends JpaRepository<ValueReport, Long> {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분이 말씀하신
CharacterProvider
입니다.ValueReport
도 생성되는 게 이상해서.이름을 변경했습니다.Character
와 완벽하게 일치하는 엔티티가 없어서CharacterProvider
로 해도 문제 없을 것 같네요 😅