From 0e16519baf03bcb6d49bbb54f9cbdba95e4f45ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Mon, 4 Jun 2018 21:47:46 +0200 Subject: [PATCH] Add a summary of grades (#127) --- ...eHeaderItem.java => AttendanceHeader.java} | 8 +- .../attendance/tab/AttendanceSubItem.java | 4 +- .../attendance/tab/AttendanceTabContract.java | 2 +- .../attendance/tab/AttendanceTabFragment.java | 4 +- .../attendance/tab/AttendanceTabModule.java | 2 +- .../tab/AttendanceTabPresenter.java | 4 +- ...{ExamsHeaderItem.java => ExamsHeader.java} | 6 +- .../ui/main/exams/tab/ExamsSubItem.java | 4 +- .../ui/main/exams/tab/ExamsTabPresenter.java | 2 +- .../ui/main/grades/GradesContract.java | 6 +- .../ui/main/grades/GradesDialogFragment.java | 2 +- .../ui/main/grades/GradesFragment.java | 92 ++++++--- ...GradeHeaderItem.java => GradesHeader.java} | 12 +- .../ui/main/grades/GradesModule.java | 7 +- .../ui/main/grades/GradesPresenter.java | 55 +++++- .../ui/main/grades/GradesSubItem.java | 6 +- .../ui/main/grades/GradesSummaryHeader.java | 87 ++++++++ .../ui/main/grades/GradesSummarySubItem.java | 83 ++++++++ ...leHeaderItem.java => TimetableHeader.java} | 8 +- .../main/timetable/tab/TimetableSubItem.java | 4 +- .../timetable/tab/TimetableTabContract.java | 2 +- .../timetable/tab/TimetableTabFragment.java | 4 +- .../timetable/tab/TimetableTabModule.java | 2 +- .../timetable/tab/TimetableTabPresenter.java | 4 +- .../io/github/wulkanowy/utils/GradeUtils.java | 121 +++++++++--- .../res/drawable/ic_action_menu_semester.xml | 10 + .../res/drawable/ic_action_menu_summary.xml | 13 ++ .../main/res/drawable/ic_exclamation_24dp.xml | 2 +- .../drawable/ic_filter_list_black_24dp.xml | 5 - app/src/main/res/layout/fragment_grades.xml | 187 ++++++++++++++---- .../{grade_dialog.xml => grades_dialog.xml} | 0 .../{grade_header.xml => grades_header.xml} | 4 +- .../{grade_subitem.xml => grades_subitem.xml} | 0 .../main/res/layout/grades_summary_header.xml | 34 ++++ .../res/layout/grades_summary_subitem.xml | 75 +++++++ app/src/main/res/menu/grades_action_menu.xml | 20 ++ app/src/main/res/menu/semester_switch.xml | 13 -- app/src/main/res/values-pl/strings.xml | 9 + app/src/main/res/values/strings.xml | 9 + .../wulkanowy/utils/GradeUtilsTest.java | 57 ++++-- 40 files changed, 791 insertions(+), 178 deletions(-) rename app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/{AttendanceHeaderItem.java => AttendanceHeader.java} (95%) rename app/src/main/java/io/github/wulkanowy/ui/main/exams/tab/{ExamsHeaderItem.java => ExamsHeader.java} (92%) rename app/src/main/java/io/github/wulkanowy/ui/main/grades/{GradeHeaderItem.java => GradesHeader.java} (94%) create mode 100644 app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummaryHeader.java create mode 100644 app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummarySubItem.java rename app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/{TimetableHeaderItem.java => TimetableHeader.java} (95%) create mode 100644 app/src/main/res/drawable/ic_action_menu_semester.xml create mode 100644 app/src/main/res/drawable/ic_action_menu_summary.xml delete mode 100644 app/src/main/res/drawable/ic_filter_list_black_24dp.xml rename app/src/main/res/layout/{grade_dialog.xml => grades_dialog.xml} (100%) rename app/src/main/res/layout/{grade_header.xml => grades_header.xml} (97%) rename app/src/main/res/layout/{grade_subitem.xml => grades_subitem.xml} (100%) create mode 100644 app/src/main/res/layout/grades_summary_header.xml create mode 100644 app/src/main/res/layout/grades_summary_subitem.xml create mode 100644 app/src/main/res/menu/grades_action_menu.xml delete mode 100644 app/src/main/res/menu/semester_switch.xml diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceHeaderItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceHeader.java similarity index 95% rename from app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceHeaderItem.java rename to app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceHeader.java index 1c55f40c..940d1fd2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceHeaderItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceHeader.java @@ -24,12 +24,12 @@ import eu.davidea.viewholders.ExpandableViewHolder; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.Day; -public class AttendanceHeaderItem - extends AbstractExpandableHeaderItem { +public class AttendanceHeader + extends AbstractExpandableHeaderItem { private Day day; - AttendanceHeaderItem(Day day) { + AttendanceHeader(Day day) { this.day = day; } @@ -39,7 +39,7 @@ public class AttendanceHeaderItem if (o == null || getClass() != o.getClass()) return false; - AttendanceHeaderItem that = (AttendanceHeaderItem) o; + AttendanceHeader that = (AttendanceHeader) o; return new EqualsBuilder() .append(day, that.day) diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceSubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceSubItem.java index 6b6246d2..65c8329e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceSubItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceSubItem.java @@ -23,11 +23,11 @@ import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson; import io.github.wulkanowy.ui.main.attendance.AttendanceDialogFragment; class AttendanceSubItem - extends AbstractSectionableItem { + extends AbstractSectionableItem { private AttendanceLesson lesson; - AttendanceSubItem(AttendanceHeaderItem header, AttendanceLesson lesson) { + AttendanceSubItem(AttendanceHeader header, AttendanceLesson lesson) { super(header); this.lesson = lesson; } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabContract.java index d7c45904..a83e67e8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabContract.java @@ -8,7 +8,7 @@ public interface AttendanceTabContract { interface View extends BaseContract.View { - void updateAdapterList(List headerItems); + void updateAdapterList(List headerItems); void onRefreshSuccess(); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabFragment.java index 7b5ad1ce..8de47469 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabFragment.java @@ -40,7 +40,7 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab AttendanceTabContract.Presenter presenter; @Inject - FlexibleAdapter adapter; + FlexibleAdapter adapter; private boolean isFragmentVisible = false; @@ -83,7 +83,7 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab } @Override - public void updateAdapterList(List headerItems) { + public void updateAdapterList(List headerItems) { adapter.updateDataSet(headerItems); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabModule.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabModule.java index 01bb9aa4..380a221f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabModule.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabModule.java @@ -15,7 +15,7 @@ public abstract class AttendanceTabModule { @PerChildFragment @Provides - static FlexibleAdapter provideAdapter() { + static FlexibleAdapter provideAdapter() { return new FlexibleAdapter<>(null); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabPresenter.java index 787b6eb9..7d0c26e5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/tab/AttendanceTabPresenter.java @@ -24,7 +24,7 @@ public class AttendanceTabPresenter extends BasePresenter headerItems = new ArrayList<>(); + private List headerItems = new ArrayList<>(); private String date; @@ -115,7 +115,7 @@ public class AttendanceTabPresenter extends BasePresenter { +public class ExamsHeader extends AbstractHeaderItem { private Day day; - ExamsHeaderItem(Day day) { + ExamsHeader(Day day) { this.day = day; } @@ -32,7 +32,7 @@ public class ExamsHeaderItem extends AbstractHeaderItem { + extends AbstractSectionableItem { private Exam exam; - ExamsSubItem(ExamsHeaderItem header, Exam exam) { + ExamsSubItem(ExamsHeader header, Exam exam) { super(header); this.exam = exam; } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/exams/tab/ExamsTabPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/exams/tab/ExamsTabPresenter.java index 062c0fd8..b60a4607 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/exams/tab/ExamsTabPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/exams/tab/ExamsTabPresenter.java @@ -116,7 +116,7 @@ public class ExamsTabPresenter extends BasePresenter for (Day day : dayList) { day.resetExams(); - ExamsHeaderItem headerItem = new ExamsHeaderItem(day); + ExamsHeader headerItem = new ExamsHeader(day); List examList = day.getExams(); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesContract.java index 5583f98c..d2423ec8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesContract.java @@ -12,7 +12,9 @@ public interface GradesContract { interface View extends BaseContract.View, SwipeRefreshLayout.OnRefreshListener { - void updateAdapterList(List headerItems); + void updateAdapterList(List headerItems); + + void updateSummaryAdapterList(List summarySubItems); void showNoItem(boolean show); @@ -28,6 +30,8 @@ public interface GradesContract { boolean isMenuVisible(); + void setSummaryAverages(String calculatedValue, String predictedValue, String finalValue ); + } interface Presenter extends BaseContract.Presenter { diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesDialogFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesDialogFragment.java index b8da5a96..17ebc6e6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesDialogFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesDialogFragment.java @@ -71,7 +71,7 @@ public class GradesDialogFragment extends DialogFragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.grade_dialog, container, false); + View view = inflater.inflate(R.layout.grades_dialog, container, false); ButterKnife.bind(this, view); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesFragment.java index 09c0a1bb..0d43b683 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesFragment.java @@ -13,6 +13,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import java.util.List; @@ -27,17 +28,38 @@ import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; public class GradesFragment extends BaseFragment implements GradesContract.View { + @BindView(R.id.grade_fragment_summary_container) + View summary; + + @BindView(R.id.grade_fragment_details_container) + View details; + @BindView(R.id.grade_fragment_recycler) RecyclerView recyclerView; + @BindView(R.id.grade_fragment_summary_recycler) + RecyclerView summaryRecyclerView; + @BindView(R.id.grade_fragment_no_item_container) View noItemView; @BindView(R.id.grade_fragment_swipe_refresh) SwipeRefreshLayout refreshLayout; + @BindView(R.id.grade_fragment_summary_predicted_average) + TextView predictedAverage; + + @BindView(R.id.grade_fragment_summary_calculated_average) + TextView calculatedAverage; + + @BindView(R.id.grade_fragment_summary_final_average) + TextView finalAverage; + @Inject - FlexibleAdapter adapter; + FlexibleAdapter adapter; + + @Inject + FlexibleAdapter summaryAdapter; @Inject GradesContract.Presenter presenter; @@ -66,43 +88,57 @@ public class GradesFragment extends BaseFragment implements GradesContract.View @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.semester_switch, menu); + inflater.inflate(R.menu.grades_action_menu, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.action_filter) { - presenter.onSemesterSwitchActive(); - CharSequence[] items = new CharSequence[]{ - getResources().getString(R.string.semester_text, 1), - getResources().getString(R.string.semester_text, 2), - }; - new AlertDialog.Builder(getContext()) - .setTitle(R.string.switch_semester) - .setNegativeButton(R.string.cancel, null) - .setSingleChoiceItems(items, this.currentSemester, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - presenter.onSemesterChange(which); - dialog.cancel(); - } - }).show(); - return true; - } else { - return super.onOptionsItemSelected(item); + switch (item.getItemId()) { + case R.id.action_semester_switch: + presenter.onSemesterSwitchActive(); + CharSequence[] items = new CharSequence[]{ + getResources().getString(R.string.semester_text, 1), + getResources().getString(R.string.semester_text, 2), + }; + new AlertDialog.Builder(getContext()) + .setTitle(R.string.switch_semester) + .setNegativeButton(R.string.cancel, null) + .setSingleChoiceItems(items, this.currentSemester, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + presenter.onSemesterChange(which); + dialog.cancel(); + } + }).show(); + return true; + case R.id.action_summary_switch: + boolean isDetailsVisible = details.getVisibility() == View.VISIBLE; + + item.setTitle(isDetailsVisible ? R.string.action_title_details : R.string.action_title_summary); + details.setVisibility(isDetailsVisible ? View.INVISIBLE : View.VISIBLE); + summary.setVisibility(isDetailsVisible ? View.VISIBLE : View.INVISIBLE); + return true; + default: + return super.onOptionsItemSelected(item); } } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { noItemView.setVisibility(View.GONE); + summary.setVisibility(View.INVISIBLE); + details.setVisibility(View.VISIBLE); adapter.setAutoCollapseOnExpand(true); adapter.setAutoScrollOnExpand(true); adapter.expandItemsAtStartUp(); + summaryAdapter.setDisplayHeadersAtStartUp(true); recyclerView.setLayoutManager(new SmoothScrollLinearLayoutManager(view.getContext())); recyclerView.setAdapter(adapter); + summaryRecyclerView.setLayoutManager(new SmoothScrollLinearLayoutManager(view.getContext())); + summaryRecyclerView.setAdapter(summaryAdapter); + summaryRecyclerView.setNestedScrollingEnabled(false); refreshLayout.setColorSchemeResources(android.R.color.black); refreshLayout.setOnRefreshListener(this); @@ -116,6 +152,13 @@ public class GradesFragment extends BaseFragment implements GradesContract.View } } + @Override + public void setSummaryAverages(String calculatedValue, String predictedValue, String finalValue) { + calculatedAverage.setText(calculatedValue); + predictedAverage.setText(predictedValue); + finalAverage.setText(finalValue); + } + @Override public void setActivityTitle() { setTitle(getString(R.string.grades_text)); @@ -141,10 +184,15 @@ public class GradesFragment extends BaseFragment implements GradesContract.View } @Override - public void updateAdapterList(List headerItems) { + public void updateAdapterList(List headerItems) { adapter.updateDataSet(headerItems); } + @Override + public void updateSummaryAdapterList(List summarySubItems) { + summaryAdapter.updateDataSet(summarySubItems); + } + @Override public void onRefreshSuccessNoGrade() { showMessage(R.string.snackbar_no_grades); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradeHeaderItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesHeader.java similarity index 94% rename from app/src/main/java/io/github/wulkanowy/ui/main/grades/GradeHeaderItem.java rename to app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesHeader.java index 33e96189..c39fcc4d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradeHeaderItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesHeader.java @@ -20,14 +20,14 @@ import io.github.wulkanowy.data.db.dao.entities.Subject; import io.github.wulkanowy.utils.AnimationUtils; import io.github.wulkanowy.utils.GradeUtils; -public class GradeHeaderItem - extends AbstractExpandableHeaderItem { +public class GradesHeader + extends AbstractExpandableHeaderItem { private Subject subject; private final boolean isShowSummary; - GradeHeaderItem(Subject subject, boolean isShowSummary) { + GradesHeader(Subject subject, boolean isShowSummary) { this.subject = subject; this.isShowSummary = isShowSummary; } @@ -38,7 +38,7 @@ public class GradeHeaderItem if (o == null || getClass() != o.getClass()) return false; - GradeHeaderItem that = (GradeHeaderItem) o; + GradesHeader that = (GradesHeader) o; return new EqualsBuilder() .append(subject, that.subject) @@ -54,7 +54,7 @@ public class GradeHeaderItem @Override public int getLayoutRes() { - return R.layout.grade_header; + return R.layout.grades_header; } @Override @@ -126,7 +126,7 @@ public class GradeHeaderItem } private String getGradesAverageString() { - float average = GradeUtils.calculate(item.getGradeList()); + float average = GradeUtils.calculateWeightedAverage(item.getGradeList()); if (average < 0) { return resources.getString(R.string.info_no_average); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesModule.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesModule.java index edf00d3b..25eeef48 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesModule.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesModule.java @@ -12,7 +12,12 @@ public abstract class GradesModule { abstract GradesContract.Presenter provideGradesPresenter(GradesPresenter gradesPresenter); @Provides - static FlexibleAdapter provideGradesAdapter() { + static FlexibleAdapter provideGradesAdapter() { + return new FlexibleAdapter<>(null); + } + + @Provides + static FlexibleAdapter provideGradesSummaryAdapter() { return new FlexibleAdapter<>(null); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesPresenter.java index ee6e0cb3..0f4d363c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesPresenter.java @@ -9,6 +9,7 @@ import org.threeten.bp.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import javax.inject.Inject; @@ -18,6 +19,7 @@ import io.github.wulkanowy.data.db.dao.entities.Subject; import io.github.wulkanowy.ui.base.BasePresenter; import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; import io.github.wulkanowy.utils.FabricUtils; +import io.github.wulkanowy.utils.GradeUtils; import io.github.wulkanowy.utils.async.AbstractTask; import io.github.wulkanowy.utils.async.AsyncListeners; @@ -31,12 +33,20 @@ public class GradesPresenter extends BasePresenter private OnFragmentIsReadyListener listener; - private List headerItems = new ArrayList<>(); + private List headerItems = new ArrayList<>(); + + private List summarySubItems = new ArrayList<>(); private boolean isFirstSight = false; private int semesterName; + private float finalAverage; + + private float predictedAverage; + + private float calculatedAverage; + @Inject GradesPresenter(RepositoryContract repository) { super(repository); @@ -56,7 +66,6 @@ public class GradesPresenter extends BasePresenter if (!isFirstSight) { isFirstSight = true; - reloadGrades(); } } @@ -76,12 +85,6 @@ public class GradesPresenter extends BasePresenter .putCustomAttribute("Name", semesterName)); } - private void reloadGrades() { - loadingTask = new AbstractTask(); - loadingTask.setOnFirstLoadingListener(this); - loadingTask.execute(); - } - @Override public void onFragmentVisible(boolean isVisible) { if (isVisible) { @@ -140,13 +143,17 @@ public class GradesPresenter extends BasePresenter boolean isShowSummary = getRepository().getSharedRepo().isShowGradesSummary(); headerItems = new ArrayList<>(); + summarySubItems = new ArrayList<>(); for (Subject subject : subjectList) { subject.resetGradeList(); List gradeList = subject.getGradeList(); + GradesSummaryHeader summaryHeader = new GradesSummaryHeader(subject, GradeUtils.calculateWeightedAverage(gradeList)); + summarySubItems.add(new GradesSummarySubItem(summaryHeader, subject)); + if (!gradeList.isEmpty()) { - GradeHeaderItem headerItem = new GradeHeaderItem(subject, isShowSummary); + GradesHeader headerItem = new GradesHeader(subject, isShowSummary); List subItems = new ArrayList<>(); @@ -159,6 +166,10 @@ public class GradesPresenter extends BasePresenter headerItems.add(headerItem); } } + + finalAverage = GradeUtils.calculateSubjectsAverage(subjectList, false); + predictedAverage = GradeUtils.calculateSubjectsAverage(subjectList, true); + calculatedAverage = GradeUtils.calculateDetailedSubjectsAverage(subjectList); } @Override @@ -170,9 +181,35 @@ public class GradesPresenter extends BasePresenter public void onEndLoadingAsync(boolean result, Exception exception) { getView().showNoItem(headerItems.isEmpty()); getView().updateAdapterList(headerItems); + + setSummaryAverages(); + getView().updateSummaryAdapterList(summarySubItems); + listener.onFragmentIsReady(); } + private void setSummaryAverages() { + getView().setSummaryAverages( + getFormattedAverage(calculatedAverage), + getFormattedAverage(predictedAverage), + getFormattedAverage(finalAverage) + ); + } + + private String getFormattedAverage(float average) { + if (-1.0f == average) { + return "-- --"; + } + + return String.format(Locale.FRANCE, "%.2f", average); + } + + private void reloadGrades() { + loadingTask = new AbstractTask(); + loadingTask.setOnFirstLoadingListener(this); + loadingTask.execute(); + } + private void cancelAsyncTasks() { if (refreshTask != null) { refreshTask.cancel(true); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSubItem.java index de9c54c6..82b338ae 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSubItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSubItem.java @@ -21,7 +21,7 @@ import io.github.wulkanowy.data.db.dao.entities.Grade; import io.github.wulkanowy.utils.GradeUtils; public class GradesSubItem - extends AbstractSectionableItem { + extends AbstractSectionableItem { private Grade grade; @@ -29,7 +29,7 @@ public class GradesSubItem private View subjectAlertImage; - GradesSubItem(GradeHeaderItem header, Grade grade) { + GradesSubItem(GradesHeader header, Grade grade) { super(header); this.grade = grade; } @@ -64,7 +64,7 @@ public class GradesSubItem @Override public int getLayoutRes() { - return R.layout.grade_subitem; + return R.layout.grades_subitem; } @Override diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummaryHeader.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummaryHeader.java new file mode 100644 index 00000000..a06fa0d5 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummaryHeader.java @@ -0,0 +1,87 @@ +package io.github.wulkanowy.ui.main.grades; + +import android.view.View; +import android.widget.TextView; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.ButterKnife; +import eu.davidea.flexibleadapter.FlexibleAdapter; +import eu.davidea.flexibleadapter.items.AbstractHeaderItem; +import eu.davidea.flexibleadapter.items.IFlexible; +import eu.davidea.viewholders.FlexibleViewHolder; +import io.github.wulkanowy.R; +import io.github.wulkanowy.data.db.dao.entities.Subject; + +class GradesSummaryHeader extends AbstractHeaderItem { + + private Subject subject; + + private String average; + + GradesSummaryHeader(Subject subject, float average) { + this.subject = subject; + this.average = String.format(Locale.FRANCE, "%.2f", average); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + GradesSummaryHeader that = (GradesSummaryHeader) o; + + return new EqualsBuilder() + .append(subject, that.subject) + .append(average, that.average) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(subject) + .append(average) + .toHashCode(); + } + + @Override + public int getLayoutRes() { + return R.layout.grades_summary_header; + } + + @Override + public HeaderViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + return new HeaderViewHolder(view, adapter); + } + + @Override + public void bindViewHolder(FlexibleAdapter adapter, HeaderViewHolder holder, int position, List payloads) { + holder.onBind(subject, average); + } + + static class HeaderViewHolder extends FlexibleViewHolder { + + @BindView(R.id.grades_summary_header_name) + TextView name; + + @BindView(R.id.grades_summary_header_average) + TextView average; + + HeaderViewHolder(View view, FlexibleAdapter adapter) { + super(view, adapter); + ButterKnife.bind(this, view); + } + + void onBind(Subject item, String value) { + name.setText(item.getName()); + average.setText("-1,00".equals(value) ? "" : value); + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummarySubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummarySubItem.java new file mode 100644 index 00000000..8ca9e484 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/main/grades/GradesSummarySubItem.java @@ -0,0 +1,83 @@ +package io.github.wulkanowy.ui.main.grades; + +import android.view.View; +import android.widget.TextView; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import eu.davidea.flexibleadapter.FlexibleAdapter; +import eu.davidea.flexibleadapter.items.AbstractSectionableItem; +import eu.davidea.flexibleadapter.items.IFlexible; +import eu.davidea.viewholders.FlexibleViewHolder; +import io.github.wulkanowy.R; +import io.github.wulkanowy.data.db.dao.entities.Subject; + +public class GradesSummarySubItem + extends AbstractSectionableItem { + + private Subject subject; + + public GradesSummarySubItem(GradesSummaryHeader header, Subject subject) { + super(header); + this.subject = subject; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + GradesSummarySubItem that = (GradesSummarySubItem) o; + + return new EqualsBuilder() + .append(subject, that.subject) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(subject) + .toHashCode(); + } + + @Override + public int getLayoutRes() { + return R.layout.grades_summary_subitem; + } + + @Override + public SubItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + return new SubItemViewHolder(view, adapter); + } + + @Override + public void bindViewHolder(FlexibleAdapter adapter, SubItemViewHolder holder, int position, List payloads) { + holder.onBind(subject); + } + + static class SubItemViewHolder extends FlexibleViewHolder { + + @BindView(R.id.grades_summary_subitem_final_grade) + TextView finalGrade; + + @BindView(R.id.grades_summary_subitem_predicted_grade) + TextView predictedGrade; + + SubItemViewHolder(View view, FlexibleAdapter adapter) { + super(view, adapter); + ButterKnife.bind(this, view); + } + + void onBind(Subject item) { + predictedGrade.setText(item.getPredictedRating()); + finalGrade.setText(item.getFinalRating()); + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableHeaderItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableHeader.java similarity index 95% rename from app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableHeaderItem.java rename to app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableHeader.java index 7e932f78..93fab822 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableHeaderItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableHeader.java @@ -24,12 +24,12 @@ import eu.davidea.viewholders.ExpandableViewHolder; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.Day; -public class TimetableHeaderItem - extends AbstractExpandableHeaderItem { +public class TimetableHeader + extends AbstractExpandableHeaderItem { private Day day; - TimetableHeaderItem(Day day) { + TimetableHeader(Day day) { this.day = day; } @@ -39,7 +39,7 @@ public class TimetableHeaderItem if (o == null || getClass() != o.getClass()) return false; - TimetableHeaderItem that = (TimetableHeaderItem) o; + TimetableHeader that = (TimetableHeader) o; return new EqualsBuilder() .append(day, that.day) diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableSubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableSubItem.java index 4d64b54b..2bf47b33 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableSubItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableSubItem.java @@ -25,11 +25,11 @@ import io.github.wulkanowy.ui.main.timetable.TimetableDialogFragment; public class TimetableSubItem - extends AbstractSectionableItem { + extends AbstractSectionableItem { private TimetableLesson lesson; - TimetableSubItem(TimetableHeaderItem header, TimetableLesson lesson) { + TimetableSubItem(TimetableHeader header, TimetableLesson lesson) { super(header); this.lesson = lesson; } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabContract.java index 254060a2..0814ff3c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabContract.java @@ -8,7 +8,7 @@ public interface TimetableTabContract { interface View extends BaseContract.View { - void updateAdapterList(List headerItems); + void updateAdapterList(List headerItems); void expandItem(int item); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabFragment.java index e0a30e8d..87db5195 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabFragment.java @@ -44,7 +44,7 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo TimetableTabContract.Presenter presenter; @Inject - FlexibleAdapter adapter; + FlexibleAdapter adapter; private boolean isFragmentVisible = false; @@ -86,7 +86,7 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo } @Override - public void updateAdapterList(List headerItems) { + public void updateAdapterList(List headerItems) { adapter.updateDataSet(headerItems); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabModule.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabModule.java index 3e1645f3..1afb055f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabModule.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabModule.java @@ -15,7 +15,7 @@ public abstract class TimetableTabModule { @PerChildFragment @Provides - static FlexibleAdapter provideTimetableAdapter() { + static FlexibleAdapter provideTimetableAdapter() { return new FlexibleAdapter<>(null); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabPresenter.java index 8841a750..42f2424d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/tab/TimetableTabPresenter.java @@ -28,7 +28,7 @@ public class TimetableTabPresenter extends BasePresenter headerItems = new ArrayList<>(); + private List headerItems = new ArrayList<>(); private String date; @@ -117,7 +117,7 @@ public class TimetableTabPresenter extends BasePresenter gradeList) { + public static float calculateWeightedAverage(List gradeList) { float counter = 0f; float denominator = 0f; for (Grade grade : gradeList) { - int integerWeight = getIntegerForWeightOfGrade(grade.getWeight()); - float floatValue = getMathematicalValueOfGrade(grade.getValue()); + int weight = getWeightValue(grade.getWeight()); + float value = getWeightedGradeValue(grade.getValue()); - if (floatValue != -1f) { - counter += floatValue * integerWeight; - denominator += integerWeight; + if (value != -1.0f) { + counter += value * weight; + denominator += weight; } } if (counter == 0f) { - return -1f; - } else { - return counter / denominator; + return -1.0f; } + return counter / denominator; } - private static float getMathematicalValueOfGrade(String valueOfGrade) { - if (valueOfGrade.matches("[-|+|=]{0,2}[0-6]") - || valueOfGrade.matches("[0-6][-|+|=]{0,2}")) { - if (valueOfGrade.matches("[-][0-6]") - || valueOfGrade.matches("[0-6][-]")) { - String replacedValue = valueOfGrade.replaceAll("[-]", ""); - return Float.valueOf(replacedValue) - 0.33f; - } else if (valueOfGrade.matches("[+][0-6]") - || valueOfGrade.matches("[0-6][+]")) { - String replacedValue = valueOfGrade.replaceAll("[+]", ""); - return Float.valueOf((replacedValue)) + 0.33f; - } else if (valueOfGrade.matches("[-|=]{1,2}[0-6]") - || valueOfGrade.matches("[0-6][-|=]{1,2}")) { - String replacedValue = valueOfGrade.replaceAll("[-|=]{1,2}", ""); - return Float.valueOf((replacedValue)) - 0.5f; - } else { - return Float.valueOf(valueOfGrade); - } - } else { - return -1; - } + public static float calculateSubjectsAverage(List subjectList, boolean usePredicted) { + return calculateSubjectsAverage(subjectList, usePredicted, false); } - private static int getIntegerForWeightOfGrade(String weightOfGrade) { - return Integer.valueOf(weightOfGrade.substring(0, weightOfGrade.length() - 3)); + public static float calculateDetailedSubjectsAverage(List subjectList) { + return calculateSubjectsAverage(subjectList, false, true); } public static int getValueColor(String value) { @@ -93,4 +74,80 @@ public final class GradeUtils { return R.color.default_grade; } } + + private static float calculateSubjectsAverage(List subjectList, boolean usePredicted, boolean useSubjectsAverages) { + float counter = 0f; + float denominator = 0f; + + for (Subject subject : subjectList) { + float value; + + if (useSubjectsAverages) { + value = calculateWeightedAverage(subject.getGradeList()); + } else { + value = getGradeValue(usePredicted ? subject.getPredictedRating() : subject.getFinalRating()); + } + + if (value != -1.0f) { + counter += Math.round(value); + denominator++; + } + } + + if (counter == 0) { + return -1.0f; + } + + return counter / denominator; + } + + private static float getGradeValue(String grade) { + if (validGradePattern.matcher(grade).matches()) { + return getWeightedGradeValue(grade); + } + + return getVerbalGradeValue(grade); + } + + private static float getVerbalGradeValue(String grade) { + switch (grade) { + case "celujący": + return 6f; + case "bardzo dobry": + return 5f; + case "dobry": + return 4f; + case "dostateczny": + return 3f; + case "dopuszczający": + return 2f; + case "niedostateczny": + return 1f; + default: + return -1f; + } + } + + private static float getWeightedGradeValue(String value) { + if (validGradePattern.matcher(value).matches()) { + if (value.matches("[-][0-6]") || value.matches("[0-6][-]")) { + String replacedValue = value.replaceAll("[-]", ""); + return Float.valueOf(replacedValue) - 0.33f; + } else if (value.matches("[+][0-6]") || value.matches("[0-6][+]")) { + String replacedValue = value.replaceAll("[+]", ""); + return Float.valueOf((replacedValue)) + 0.33f; + } else if (value.matches("[-|=]{1,2}[0-6]") || value.matches("[0-6][-|=]{1,2}")) { + String replacedValue = value.replaceAll("[-|=]{1,2}", ""); + return Float.valueOf((replacedValue)) - 0.5f; + } else { + return Float.valueOf(value); + } + } else { + return -1; + } + } + + private static int getWeightValue(String weightOfGrade) { + return Integer.valueOf(weightOfGrade.substring(0, weightOfGrade.length() - 3)); + } } diff --git a/app/src/main/res/drawable/ic_action_menu_semester.xml b/app/src/main/res/drawable/ic_action_menu_semester.xml new file mode 100644 index 00000000..b7acb9df --- /dev/null +++ b/app/src/main/res/drawable/ic_action_menu_semester.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_action_menu_summary.xml b/app/src/main/res/drawable/ic_action_menu_summary.xml new file mode 100644 index 00000000..1b2a93b8 --- /dev/null +++ b/app/src/main/res/drawable/ic_action_menu_summary.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_exclamation_24dp.xml b/app/src/main/res/drawable/ic_exclamation_24dp.xml index 4d3c91cf..14950458 100644 --- a/app/src/main/res/drawable/ic_exclamation_24dp.xml +++ b/app/src/main/res/drawable/ic_exclamation_24dp.xml @@ -1,4 +1,4 @@ - + - - diff --git a/app/src/main/res/layout/fragment_grades.xml b/app/src/main/res/layout/fragment_grades.xml index f00b3108..f0642987 100644 --- a/app/src/main/res/layout/fragment_grades.xml +++ b/app/src/main/res/layout/fragment_grades.xml @@ -6,45 +6,166 @@ android:layout_height="match_parent" tools:context="io.github.wulkanowy.ui.main.grades.GradesFragment"> - - - - - - - - + android:layout_height="match_parent"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/app/src/main/res/layout/grade_dialog.xml b/app/src/main/res/layout/grades_dialog.xml similarity index 100% rename from app/src/main/res/layout/grade_dialog.xml rename to app/src/main/res/layout/grades_dialog.xml diff --git a/app/src/main/res/layout/grade_header.xml b/app/src/main/res/layout/grades_header.xml similarity index 97% rename from app/src/main/res/layout/grade_header.xml rename to app/src/main/res/layout/grades_header.xml index 032ad675..41b98076 100644 --- a/app/src/main/res/layout/grade_header.xml +++ b/app/src/main/res/layout/grades_header.xml @@ -51,6 +51,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/grade_header_average_text" + android:layout_marginEnd="10dp" + android:layout_marginRight="10dp" android:layout_marginTop="5dp" android:text="@string/info_grades_predicted_rating" android:textColor="@color/secondary_text" @@ -61,8 +63,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/grade_header_average_text" - android:layout_marginLeft="10dp" - android:layout_marginStart="10dp" android:layout_marginTop="5dp" android:layout_toEndOf="@+id/grade_header_predicted_rating_text" android:layout_toRightOf="@+id/grade_header_predicted_rating_text" diff --git a/app/src/main/res/layout/grade_subitem.xml b/app/src/main/res/layout/grades_subitem.xml similarity index 100% rename from app/src/main/res/layout/grade_subitem.xml rename to app/src/main/res/layout/grades_subitem.xml diff --git a/app/src/main/res/layout/grades_summary_header.xml b/app/src/main/res/layout/grades_summary_header.xml new file mode 100644 index 00000000..3055721f --- /dev/null +++ b/app/src/main/res/layout/grades_summary_header.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/grades_summary_subitem.xml b/app/src/main/res/layout/grades_summary_subitem.xml new file mode 100644 index 00000000..c7715092 --- /dev/null +++ b/app/src/main/res/layout/grades_summary_subitem.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/grades_action_menu.xml b/app/src/main/res/menu/grades_action_menu.xml new file mode 100644 index 00000000..0533ae39 --- /dev/null +++ b/app/src/main/res/menu/grades_action_menu.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/main/res/menu/semester_switch.xml b/app/src/main/res/menu/semester_switch.xml deleted file mode 100644 index 6f8a027e..00000000 --- a/app/src/main/res/menu/semester_switch.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index aeb828d1..715e8ada 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -81,6 +81,9 @@ Brak lekcji w tym tygodniu Sala %s + Przewidywana + Końcowa + %d ocena %d oceny @@ -154,4 +157,10 @@ Brak sprawdzianów w tym tygodniu Typ Data wpisu + + Obliczona średnia + Szacowana średnia + Końcowa średnia + Podsumowanie + Szczegóły diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ffea541..d7cf1806 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -80,6 +80,9 @@ Final: %1$s No lesson in this week + Predicted + Final + Room %s @@ -149,4 +152,10 @@ No exams in this week Type Date of entry + + Calculated average + Predicted average + Final average + Summary + Details diff --git a/app/src/test/java/io/github/wulkanowy/utils/GradeUtilsTest.java b/app/src/test/java/io/github/wulkanowy/utils/GradeUtilsTest.java index 92a0b42c..1a5f9e4a 100644 --- a/app/src/test/java/io/github/wulkanowy/utils/GradeUtilsTest.java +++ b/app/src/test/java/io/github/wulkanowy/utils/GradeUtilsTest.java @@ -1,6 +1,5 @@ package io.github.wulkanowy.utils; -import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; @@ -8,11 +7,14 @@ import java.util.List; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.Grade; +import io.github.wulkanowy.data.db.dao.entities.Subject; + +import static org.junit.Assert.assertEquals; public class GradeUtilsTest { @Test - public void averageTest() { + public void weightedAverageTest() { List gradeList = new ArrayList<>(); gradeList.add(new Grade().setValue("np.").setWeight("1,00")); gradeList.add(new Grade().setValue("-5").setWeight("10,00")); @@ -29,31 +31,48 @@ public class GradeUtilsTest { gradeList1.add(new Grade().setValue("5+").setWeight("10,00")); gradeList1.add(new Grade().setValue("5").setWeight("10,00")); - Assert.assertEquals(4.8f, GradeUtils.calculate(gradeList), 0.0f); - Assert.assertEquals(4.8f, GradeUtils.calculate(gradeList1), 0.0f); + assertEquals(4.8f, GradeUtils.calculateWeightedAverage(gradeList), 0.0f); + assertEquals(4.8f, GradeUtils.calculateWeightedAverage(gradeList1), 0.0f); } @Test - public void errorAverageTest() { + public void subjectsAverageTest() { + List subjectList = new ArrayList<>(); + subjectList.add(new Subject().setPredictedRating("2").setFinalRating("3")); + subjectList.add(new Subject().setPredictedRating("niedostateczny").setFinalRating("dopuszczający")); + subjectList.add(new Subject().setPredictedRating("dostateczny").setFinalRating("dobry")); + subjectList.add(new Subject().setPredictedRating("bardzo dobry").setFinalRating("celujący")); + subjectList.add(new Subject().setPredictedRating("2/3").setFinalRating("-4")); + + assertEquals(3.8f, GradeUtils.calculateSubjectsAverage(subjectList, false), 0.0f); + assertEquals(2.75f, GradeUtils.calculateSubjectsAverage(subjectList, true), 0.0f); + } + + @Test + public void abnormalAverageTest() { List gradeList = new ArrayList<>(); gradeList.add(new Grade().setValue("np.").setWeight("1,00")); - Assert.assertEquals(-1f, GradeUtils.calculate(gradeList), 0.0f); + List subjectList = new ArrayList<>(); + subjectList.add(new Subject().setFinalRating("nieklasyfikowany")); + + assertEquals(-1f, GradeUtils.calculateWeightedAverage(gradeList), 0.0f); + assertEquals(-1f, GradeUtils.calculateSubjectsAverage(subjectList, false), 0.0f); } @Test - public void getValueColor() { - Assert.assertEquals(R.color.six_grade, GradeUtils.getValueColor("-6")); - Assert.assertEquals(R.color.five_grade, GradeUtils.getValueColor("--5")); - Assert.assertEquals(R.color.four_grade, GradeUtils.getValueColor("=4")); - Assert.assertEquals(R.color.three_grade, GradeUtils.getValueColor("3-")); - Assert.assertEquals(R.color.two_grade, GradeUtils.getValueColor("2--")); - Assert.assertEquals(R.color.two_grade, GradeUtils.getValueColor("2=")); - Assert.assertEquals(R.color.one_grade, GradeUtils.getValueColor("1+")); - Assert.assertEquals(R.color.one_grade, GradeUtils.getValueColor("+1")); - Assert.assertEquals(R.color.default_grade, GradeUtils.getValueColor("6 (.XI)")); - Assert.assertEquals(R.color.default_grade, GradeUtils.getValueColor("Np")); - Assert.assertEquals(R.color.default_grade, GradeUtils.getValueColor("7")); - Assert.assertEquals(R.color.default_grade, GradeUtils.getValueColor("")); + public void getValueColorTest() { + assertEquals(R.color.six_grade, GradeUtils.getValueColor("-6")); + assertEquals(R.color.five_grade, GradeUtils.getValueColor("--5")); + assertEquals(R.color.four_grade, GradeUtils.getValueColor("=4")); + assertEquals(R.color.three_grade, GradeUtils.getValueColor("3-")); + assertEquals(R.color.two_grade, GradeUtils.getValueColor("2--")); + assertEquals(R.color.two_grade, GradeUtils.getValueColor("2=")); + assertEquals(R.color.one_grade, GradeUtils.getValueColor("1+")); + assertEquals(R.color.one_grade, GradeUtils.getValueColor("+1")); + assertEquals(R.color.default_grade, GradeUtils.getValueColor("6 (.XI)")); + assertEquals(R.color.default_grade, GradeUtils.getValueColor("Np")); + assertEquals(R.color.default_grade, GradeUtils.getValueColor("7")); + assertEquals(R.color.default_grade, GradeUtils.getValueColor("")); } }