Fix force average calc from two semesters (#870)
This commit is contained in:
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.preferences
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@ -17,8 +18,8 @@ class PreferencesRepository @Inject constructor(
|
||||
val isShowPresent: Boolean
|
||||
get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
|
||||
|
||||
val gradeAverageMode: String
|
||||
get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)
|
||||
val gradeAverageMode: GradeAverageMode
|
||||
get() = GradeAverageMode.getByValue(getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode))
|
||||
|
||||
val gradeAverageForceCalc: Boolean
|
||||
get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
|
||||
|
@ -0,0 +1,11 @@
|
||||
package io.github.wulkanowy.ui.modules.grade
|
||||
|
||||
enum class GradeAverageMode(val value: String) {
|
||||
ALL_YEAR("all_year"),
|
||||
ONE_SEMESTER("only_one_semester"),
|
||||
BOTH_SEMESTERS("both_semesters");
|
||||
|
||||
companion object {
|
||||
fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ONE_SEMESTER
|
||||
}
|
||||
}
|
@ -8,6 +8,9 @@ import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ALL_YEAR
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.BOTH_SEMESTERS
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ONE_SEMESTER
|
||||
import io.github.wulkanowy.utils.calcAverage
|
||||
import io.github.wulkanowy.utils.changeModifier
|
||||
import io.reactivex.Single
|
||||
@ -19,21 +22,21 @@ class GradeAverageProvider @Inject constructor(
|
||||
private val preferencesRepository: PreferencesRepository
|
||||
) {
|
||||
|
||||
private val plusModifier = preferencesRepository.gradePlusModifier
|
||||
private val plusModifier get() = preferencesRepository.gradePlusModifier
|
||||
|
||||
private val minusModifier = preferencesRepository.gradeMinusModifier
|
||||
private val minusModifier get() = preferencesRepository.gradeMinusModifier
|
||||
|
||||
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean = false): Single<List<GradeDetailsWithAverage>> {
|
||||
return semesterRepository.getSemesters(student).flatMap { semesters ->
|
||||
when (preferencesRepository.gradeAverageMode) {
|
||||
"only_one_semester" -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh)
|
||||
"all_year" -> calculateWholeYearAverage(student, semesters, semesterId, forceRefresh)
|
||||
else -> throw IllegalArgumentException("Incorrect grade average mode: ${preferencesRepository.gradeAverageMode} ")
|
||||
ONE_SEMESTER -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh)
|
||||
BOTH_SEMESTERS -> calculateBothSemestersAverage(student, semesters, semesterId, forceRefresh)
|
||||
ALL_YEAR -> calculateAllYearAverage(student, semesters, semesterId, forceRefresh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateWholeYearAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
|
||||
private fun calculateBothSemestersAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
|
||||
val selectedSemester = semesters.single { it.semesterId == semesterId }
|
||||
val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 }
|
||||
|
||||
@ -44,11 +47,30 @@ class GradeAverageProvider @Inject constructor(
|
||||
getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails ->
|
||||
selectedDetails.map { selected ->
|
||||
val second = secondDetails.singleOrNull { it.subject == selected.subject }
|
||||
selected.copy(
|
||||
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||
(selected.grades + second?.grades.orEmpty()).calcAverage()
|
||||
} else (selected.average + (second?.average ?: selected.average)) / 2
|
||||
)
|
||||
selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||
val selectedGrades = selected.grades.updateModifiers(student).calcAverage()
|
||||
(selectedGrades + (second?.grades?.updateModifiers(student)?.calcAverage() ?: selectedGrades)) / 2
|
||||
} else (selected.average + (second?.average ?: selected.average)) / 2)
|
||||
}
|
||||
}
|
||||
} else Single.just(selectedDetails)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateAllYearAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
|
||||
val selectedSemester = semesters.single { it.semesterId == semesterId }
|
||||
val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 }
|
||||
|
||||
return getSemesterDetailsWithAverage(student, selectedSemester, forceRefresh).flatMap { selectedDetails ->
|
||||
val isAnyAverage = selectedDetails.any { it.average != .0 }
|
||||
|
||||
if (selectedSemester != firstSemester) {
|
||||
getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails ->
|
||||
selectedDetails.map { selected ->
|
||||
val second = secondDetails.singleOrNull { it.subject == selected.subject }
|
||||
selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||
(selected.grades.updateModifiers(student) + second?.grades?.updateModifiers(student).orEmpty()).calcAverage()
|
||||
} else selected.average)
|
||||
}
|
||||
}
|
||||
} else Single.just(selectedDetails)
|
||||
@ -65,9 +87,7 @@ class GradeAverageProvider @Inject constructor(
|
||||
GradeDetailsWithAverage(
|
||||
subject = summary.subject,
|
||||
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||
(if (student.loginMode == Sdk.Mode.SCRAPPER.name)
|
||||
grades.map { it.changeModifier(plusModifier, minusModifier) }
|
||||
else grades).calcAverage()
|
||||
grades.updateModifiers(student).calcAverage()
|
||||
} else summary.average,
|
||||
points = summary.pointsSum,
|
||||
summary = summary,
|
||||
@ -92,10 +112,14 @@ class GradeAverageProvider @Inject constructor(
|
||||
proposedPoints = "",
|
||||
finalPoints = "",
|
||||
pointsSum = "",
|
||||
average = if (calcAverage) (if (student.loginMode == Sdk.Mode.SCRAPPER.name) {
|
||||
details.map { it.changeModifier(plusModifier, minusModifier) }
|
||||
} else details).calcAverage() else .0
|
||||
average = if (calcAverage) details.updateModifiers(student).calcAverage() else .0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<Grade>.updateModifiers(student: Student): List<Grade> {
|
||||
return if (student.loginMode == Sdk.Mode.SCRAPPER.name) {
|
||||
map { it.changeModifier(plusModifier, minusModifier) }
|
||||
} else this
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
</string-array>
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Durchschnittsnote für das 2. Semester</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Durchschnitt der Bewertungen für das ganze Jahr</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
|
@ -35,8 +35,9 @@
|
||||
<item>Kolory ocen w dzienniku</item>
|
||||
</string-array>
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Średnia ocen z 2 semestru</item>
|
||||
<item>Średnia ocen z całego roku</item>
|
||||
<item>Średnia ocen z drugiego semestru</item>
|
||||
<item>Średnia średnich z obu semestrów</item>
|
||||
<item>Średnia wszystkich ocen z całego roku</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
<item>Nie pokazuj</item>
|
||||
|
@ -36,6 +36,7 @@
|
||||
</string-array>
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Средняя оценка со 2 семестра</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Средняя оценка с целого года</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
|
@ -36,6 +36,7 @@
|
||||
</string-array>
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Середня оцінка з 2 семестру</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Середня оцінка за весь рік</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
|
@ -88,10 +88,12 @@
|
||||
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Average of grades only from the 2nd semester</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Average of grades from the whole year</item>
|
||||
</string-array>
|
||||
<string-array name="grade_average_mode_values" translatable="false">
|
||||
<item>only_one_semester</item>
|
||||
<item>both_semesters</item>
|
||||
<item>all_year</item>
|
||||
</string-array>
|
||||
|
||||
|
Reference in New Issue
Block a user