1
0

Fix force average calc from two semesters (#870)

This commit is contained in:
Mikołaj Pich
2020-06-10 17:28:49 +02:00
committed by GitHub
parent 522a36d670
commit 5c84c8d5b1
10 changed files with 206 additions and 53 deletions

View File

@ -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)

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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">

View File

@ -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>

View File

@ -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">

View File

@ -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">

View File

@ -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>