1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 00:29:09 -05:00

Add a summary of grades (#127)

This commit is contained in:
Rafał Borcz 2018-06-04 21:47:46 +02:00 committed by Mikołaj Pich
parent dde5775a41
commit 0e16519baf
40 changed files with 791 additions and 178 deletions

View File

@ -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<AttendanceHeaderItem.HeaderViewHolder, AttendanceSubItem> {
public class AttendanceHeader
extends AbstractExpandableHeaderItem<AttendanceHeader.HeaderViewHolder, AttendanceSubItem> {
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)

View File

@ -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<AttendanceSubItem.SubItemViewHolder, AttendanceHeaderItem> {
extends AbstractSectionableItem<AttendanceSubItem.SubItemViewHolder, AttendanceHeader> {
private AttendanceLesson lesson;
AttendanceSubItem(AttendanceHeaderItem header, AttendanceLesson lesson) {
AttendanceSubItem(AttendanceHeader header, AttendanceLesson lesson) {
super(header);
this.lesson = lesson;
}

View File

@ -8,7 +8,7 @@ public interface AttendanceTabContract {
interface View extends BaseContract.View {
void updateAdapterList(List<AttendanceHeaderItem> headerItems);
void updateAdapterList(List<AttendanceHeader> headerItems);
void onRefreshSuccess();

View File

@ -40,7 +40,7 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab
AttendanceTabContract.Presenter presenter;
@Inject
FlexibleAdapter<AttendanceHeaderItem> adapter;
FlexibleAdapter<AttendanceHeader> adapter;
private boolean isFragmentVisible = false;
@ -83,7 +83,7 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab
}
@Override
public void updateAdapterList(List<AttendanceHeaderItem> headerItems) {
public void updateAdapterList(List<AttendanceHeader> headerItems) {
adapter.updateDataSet(headerItems);
}

View File

@ -15,7 +15,7 @@ public abstract class AttendanceTabModule {
@PerChildFragment
@Provides
static FlexibleAdapter<AttendanceHeaderItem> provideAdapter() {
static FlexibleAdapter<AttendanceHeader> provideAdapter() {
return new FlexibleAdapter<>(null);
}
}

View File

@ -24,7 +24,7 @@ public class AttendanceTabPresenter extends BasePresenter<AttendanceTabContract.
private AbstractTask loadingTask;
private List<AttendanceHeaderItem> headerItems = new ArrayList<>();
private List<AttendanceHeader> headerItems = new ArrayList<>();
private String date;
@ -115,7 +115,7 @@ public class AttendanceTabPresenter extends BasePresenter<AttendanceTabContract.
for (Day day : dayList) {
day.resetAttendanceLessons();
AttendanceHeaderItem headerItem = new AttendanceHeaderItem(day);
AttendanceHeader headerItem = new AttendanceHeader(day);
if (isEmptyWeek) {
isEmptyWeek = day.getAttendanceLessons().isEmpty();

View File

@ -18,11 +18,11 @@ import eu.davidea.viewholders.FlexibleViewHolder;
import io.github.wulkanowy.R;
import io.github.wulkanowy.data.db.dao.entities.Day;
public class ExamsHeaderItem extends AbstractHeaderItem<ExamsHeaderItem.HeaderVieHolder> {
public class ExamsHeader extends AbstractHeaderItem<ExamsHeader.HeaderVieHolder> {
private Day day;
ExamsHeaderItem(Day day) {
ExamsHeader(Day day) {
this.day = day;
}
@ -32,7 +32,7 @@ public class ExamsHeaderItem extends AbstractHeaderItem<ExamsHeaderItem.HeaderVi
if (o == null || getClass() != o.getClass()) return false;
ExamsHeaderItem that = (ExamsHeaderItem) o;
ExamsHeader that = (ExamsHeader) o;
return new EqualsBuilder()
.append(day, that.day)

View File

@ -21,11 +21,11 @@ import io.github.wulkanowy.data.db.dao.entities.Exam;
import io.github.wulkanowy.ui.main.exams.ExamsDialogFragment;
public class ExamsSubItem
extends AbstractSectionableItem<ExamsSubItem.SubItemViewHolder, ExamsHeaderItem> {
extends AbstractSectionableItem<ExamsSubItem.SubItemViewHolder, ExamsHeader> {
private Exam exam;
ExamsSubItem(ExamsHeaderItem header, Exam exam) {
ExamsSubItem(ExamsHeader header, Exam exam) {
super(header);
this.exam = exam;
}

View File

@ -116,7 +116,7 @@ public class ExamsTabPresenter extends BasePresenter<ExamsTabContract.View>
for (Day day : dayList) {
day.resetExams();
ExamsHeaderItem headerItem = new ExamsHeaderItem(day);
ExamsHeader headerItem = new ExamsHeader(day);
List<Exam> examList = day.getExams();

View File

@ -12,7 +12,9 @@ public interface GradesContract {
interface View extends BaseContract.View, SwipeRefreshLayout.OnRefreshListener {
void updateAdapterList(List<GradeHeaderItem> headerItems);
void updateAdapterList(List<GradesHeader> headerItems);
void updateSummaryAdapterList(List<GradesSummarySubItem> 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<View> {

View File

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

View File

@ -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<GradeHeaderItem> adapter;
FlexibleAdapter<GradesHeader> adapter;
@Inject
FlexibleAdapter<GradesSummarySubItem> 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<GradeHeaderItem> headerItems) {
public void updateAdapterList(List<GradesHeader> headerItems) {
adapter.updateDataSet(headerItems);
}
@Override
public void updateSummaryAdapterList(List<GradesSummarySubItem> summarySubItems) {
summaryAdapter.updateDataSet(summarySubItems);
}
@Override
public void onRefreshSuccessNoGrade() {
showMessage(R.string.snackbar_no_grades);

View File

@ -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<GradeHeaderItem.HeaderViewHolder, GradesSubItem> {
public class GradesHeader
extends AbstractExpandableHeaderItem<GradesHeader.HeaderViewHolder, GradesSubItem> {
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);

View File

@ -12,7 +12,12 @@ public abstract class GradesModule {
abstract GradesContract.Presenter provideGradesPresenter(GradesPresenter gradesPresenter);
@Provides
static FlexibleAdapter<GradeHeaderItem> provideGradesAdapter() {
static FlexibleAdapter<GradesHeader> provideGradesAdapter() {
return new FlexibleAdapter<>(null);
}
@Provides
static FlexibleAdapter<GradesSummarySubItem> provideGradesSummaryAdapter() {
return new FlexibleAdapter<>(null);
}
}

View File

@ -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<GradesContract.View>
private OnFragmentIsReadyListener listener;
private List<GradeHeaderItem> headerItems = new ArrayList<>();
private List<GradesHeader> headerItems = new ArrayList<>();
private List<GradesSummarySubItem> 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<GradesContract.View>
if (!isFirstSight) {
isFirstSight = true;
reloadGrades();
}
}
@ -76,12 +85,6 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
.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<GradesContract.View>
boolean isShowSummary = getRepository().getSharedRepo().isShowGradesSummary();
headerItems = new ArrayList<>();
summarySubItems = new ArrayList<>();
for (Subject subject : subjectList) {
subject.resetGradeList();
List<Grade> 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<GradesSubItem> subItems = new ArrayList<>();
@ -159,6 +166,10 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
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<GradesContract.View>
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);

View File

@ -21,7 +21,7 @@ import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.utils.GradeUtils;
public class GradesSubItem
extends AbstractSectionableItem<GradesSubItem.SubItemViewHolder, GradeHeaderItem> {
extends AbstractSectionableItem<GradesSubItem.SubItemViewHolder, GradesHeader> {
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

View File

@ -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<GradesSummaryHeader.HeaderViewHolder> {
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<IFlexible> adapter) {
return new HeaderViewHolder(view, adapter);
}
@Override
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, HeaderViewHolder holder, int position, List<Object> 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);
}
}
}

View File

@ -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<GradesSummarySubItem.SubItemViewHolder, GradesSummaryHeader> {
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<IFlexible> adapter) {
return new SubItemViewHolder(view, adapter);
}
@Override
public void bindViewHolder(FlexibleAdapter<IFlexible> adapter, SubItemViewHolder holder, int position, List<Object> 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());
}
}
}

View File

@ -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<TimetableHeaderItem.HeaderViewHolder, TimetableSubItem> {
public class TimetableHeader
extends AbstractExpandableHeaderItem<TimetableHeader.HeaderViewHolder, TimetableSubItem> {
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)

View File

@ -25,11 +25,11 @@ import io.github.wulkanowy.ui.main.timetable.TimetableDialogFragment;
public class TimetableSubItem
extends AbstractSectionableItem<TimetableSubItem.SubItemViewHolder, TimetableHeaderItem> {
extends AbstractSectionableItem<TimetableSubItem.SubItemViewHolder, TimetableHeader> {
private TimetableLesson lesson;
TimetableSubItem(TimetableHeaderItem header, TimetableLesson lesson) {
TimetableSubItem(TimetableHeader header, TimetableLesson lesson) {
super(header);
this.lesson = lesson;
}

View File

@ -8,7 +8,7 @@ public interface TimetableTabContract {
interface View extends BaseContract.View {
void updateAdapterList(List<TimetableHeaderItem> headerItems);
void updateAdapterList(List<TimetableHeader> headerItems);
void expandItem(int item);

View File

@ -44,7 +44,7 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo
TimetableTabContract.Presenter presenter;
@Inject
FlexibleAdapter<TimetableHeaderItem> adapter;
FlexibleAdapter<TimetableHeader> adapter;
private boolean isFragmentVisible = false;
@ -86,7 +86,7 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo
}
@Override
public void updateAdapterList(List<TimetableHeaderItem> headerItems) {
public void updateAdapterList(List<TimetableHeader> headerItems) {
adapter.updateDataSet(headerItems);
}

View File

@ -15,7 +15,7 @@ public abstract class TimetableTabModule {
@PerChildFragment
@Provides
static FlexibleAdapter<TimetableHeaderItem> provideTimetableAdapter() {
static FlexibleAdapter<TimetableHeader> provideTimetableAdapter() {
return new FlexibleAdapter<>(null);
}
}

View File

@ -28,7 +28,7 @@ public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.Vi
private AbstractTask loadingTask;
private List<TimetableHeaderItem> headerItems = new ArrayList<>();
private List<TimetableHeader> headerItems = new ArrayList<>();
private String date;
@ -117,7 +117,7 @@ public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.Vi
for (Day day : dayList) {
day.resetTimetableLessons();
TimetableHeaderItem headerItem = new TimetableHeaderItem(day);
TimetableHeader headerItem = new TimetableHeader(day);
if (isFreeWeek) {
isFreeWeek = day.getFreeDay();

View File

@ -6,6 +6,7 @@ import java.util.regex.Pattern;
import io.github.wulkanowy.R;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.Subject;
public final class GradeUtils {
@ -16,53 +17,33 @@ public final class GradeUtils {
throw new IllegalStateException("Utility class");
}
public static float calculate(List<Grade> gradeList) {
public static float calculateWeightedAverage(List<Grade> 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<Subject> 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<Subject> 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<Subject> 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));
}
}

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z" />
</vector>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFF"
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2z" />
<path
android:fillColor="#FFF"
android:pathData="M12,2a10,10 0,1 0,0 20,10 10,0 0,0 0,-20zM12,20a8,8 0,1 1,0 -16,8 8,0 0,1
0,16z" />
</vector>

View File

@ -1,4 +1,4 @@
<!-- drawable/exclamation.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"

View File

@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
</vector>

View File

@ -6,45 +6,166 @@
android:layout_height="match_parent"
tools:context="io.github.wulkanowy.ui.main.grades.GradesFragment">
<RelativeLayout
android:id="@+id/grade_fragment_no_item_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="@+id/grade_fragment_no_item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/grade_fragment_no_item_text"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:minHeight="100dp"
android:minWidth="100dp"
android:tint="@android:color/black"
app:srcCompat="@drawable/ic_menu_grade_26dp"
tools:ignore="contentDescription" />
<TextView
android:id="@+id/grade_fragment_no_item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="46dp"
android:text="@string/fragment_no_grades"
android:gravity="center"
android:textSize="20sp" />
</RelativeLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/grade_fragment_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/grade_fragment_recycler"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/grade_fragment_details_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/grade_fragment_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/grade_fragment_summary_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<RelativeLayout
android:id="@+id/grade_fragment_summary_calculated_container"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp"
android:layout_toLeftOf="@id/grade_fragment_summary_final_container"
android:layout_toStartOf="@id/grade_fragment_summary_final_container">
<TextView
android:id="@+id/grade_fragment_summary_calculated_average_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="@string/grades_summary_calculated_average"
android:textSize="16sp" />
<TextView
android:id="@+id/grade_fragment_summary_calculated_average"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/grade_fragment_summary_calculated_average_text"
android:layout_centerHorizontal="true"
android:text="6,00"
android:textSize="21sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/grade_fragment_summary_final_container"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginEnd="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="20dp">
<TextView
android:id="@+id/grade_fragment_summary_final_average_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:minLines="2"
android:text="@string/grades_summary_final_average"
android:textSize="16sp" />
<TextView
android:id="@+id/grade_fragment_summary_final_average"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/grade_fragment_summary_final_average_text"
android:layout_centerHorizontal="true"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:text="6,00"
android:textSize="21sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/grade_fragment_summary_predicted_container"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="20dp"
android:layout_toEndOf="@id/grade_fragment_summary_final_container"
android:layout_toRightOf="@id/grade_fragment_summary_final_container">
<TextView
android:id="@+id/grade_fragment_summary_predicted_average_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:maxLines="2"
android:text="@string/grades_summary_predicted_average"
android:textSize="16sp" />
<TextView
android:id="@+id/grade_fragment_summary_predicted_average"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/grade_fragment_summary_predicted_average_text"
android:layout_centerHorizontal="true"
android:text="6,00"
android:textSize="21sp" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/grade_fragment_summary_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/grade_fragment_summary_calculated_container"
android:layout_marginTop="20dp" />
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
<RelativeLayout
android:id="@+id/grade_fragment_no_item_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="@+id/grade_fragment_no_item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/grade_fragment_no_item_text"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:minHeight="100dp"
android:minWidth="100dp"
android:tint="@android:color/black"
app:srcCompat="@drawable/ic_menu_grade_26dp"
tools:ignore="contentDescription" />
<TextView
android:id="@+id/grade_fragment_no_item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="46dp"
android:gravity="center"
android:text="@string/fragment_no_grades"
android:textSize="20sp" />
</RelativeLayout>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>

View File

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

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EEE"
android:paddingBottom="7dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="7dp">
<TextView
android:id="@+id/grades_summary_header_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="40dp"
android:layout_marginRight="40dp"
android:layout_toLeftOf="@id/grades_summary_header_average"
android:layout_toStartOf="@id/grades_summary_header_average"
android:text="@string/app_name"
android:textSize="17sp" />
<TextView
android:id="@+id/grades_summary_header_average"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="end"
android:text="@string/app_name"
android:textSize="12sp" />
</RelativeLayout>

View File

@ -0,0 +1,75 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/grades_summary_subitem_predicted_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/ic_border"
android:minHeight="35dp">
<TextView
android:id="@+id/grades_summary_subitem_predicted_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
android:text="@string/grades_predicted_rating"
android:textSize="14sp" />
<TextView
android:id="@+id/grades_summary_subitem_predicted_grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="25dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="25dp"
android:layout_marginStart="10dp"
android:layout_toEndOf="@id/grades_summary_subitem_predicted_name"
android:layout_toRightOf="@id/grades_summary_subitem_predicted_name"
android:gravity="end"
android:text="@string/app_name"
android:textSize="12sp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/grades_summary_subitem_final_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/grades_summary_subitem_predicted_container"
android:background="@drawable/ic_border"
android:minHeight="35dp">
<TextView
android:id="@+id/grades_summary_subitem_final_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
android:text="@string/grades_final_rating"
android:textSize="14sp" />
<TextView
android:id="@+id/grades_summary_subitem_final_grade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="25dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="25dp"
android:layout_marginStart="10dp"
android:layout_toEndOf="@id/grades_summary_subitem_final_name"
android:layout_toRightOf="@id/grades_summary_subitem_final_name"
android:gravity="end"
android:text="@string/app_name"
android:textSize="12sp" />
</RelativeLayout>
</RelativeLayout>

View File

@ -0,0 +1,20 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="io.github.wulkanowy.timetable.MainActivity">
<item
android:id="@+id/action_semester_switch"
android:icon="@drawable/ic_action_menu_semester"
android:orderInCategory="2"
android:title="@string/switch_semester"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_summary_switch"
android:icon="@drawable/ic_action_menu_summary"
android:orderInCategory="1"
android:title="@string/action_title_summary"
app:showAsAction="ifRoom" />
</menu>

View File

@ -1,13 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="io.github.wulkanowy.timetable.MainActivity"
>
<item
android:id="@+id/action_filter"
android:orderInCategory="100"
android:title="@string/switch_semester"
android:icon="@drawable/ic_filter_list_black_24dp"
app:showAsAction="always"
/>
</menu>

View File

@ -81,6 +81,9 @@
<string name="info_free_week">Brak lekcji w tym tygodniu</string>
<string name="timetable_subitem_room">Sala %s</string>
<string name="grades_predicted_rating">Przewidywana</string>
<string name="grades_final_rating">Końcowa</string>
<plurals name="numberOfGradesPlurals">
<item quantity="one">%d ocena</item>
<item quantity="few">%d oceny</item>
@ -154,4 +157,10 @@
<string name="exams_no_entries">Brak sprawdzianów w tym tygodniu</string>
<string name="exams_type">Typ</string>
<string name="exams_dialog_entry_date">Data wpisu</string>
<string name="grades_summary_calculated_average">Obliczona średnia</string>
<string name="grades_summary_predicted_average">Szacowana średnia</string>
<string name="grades_summary_final_average">Końcowa średnia</string>
<string name="action_title_summary">Podsumowanie</string>
<string name="action_title_details">Szczegóły</string>
</resources>

View File

@ -80,6 +80,9 @@
<string name="info_grades_final_rating">Final: %1$s</string>
<string name="info_free_week">No lesson in this week</string>
<string name="grades_predicted_rating">Predicted</string>
<string name="grades_final_rating">Final</string>
<string name="timetable_subitem_room">Room %s</string>
<plurals name="numberOfGradesPlurals">
@ -149,4 +152,10 @@
<string name="exams_no_entries">No exams in this week</string>
<string name="exams_type">Type</string>
<string name="exams_dialog_entry_date">Date of entry</string>
<string name="grades_summary_calculated_average">Calculated average</string>
<string name="grades_summary_predicted_average">Predicted average</string>
<string name="grades_summary_final_average">Final average</string>
<string name="action_title_summary">Summary</string>
<string name="action_title_details">Details</string>
</resources>

View File

@ -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<Grade> 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<Subject> 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<Grade> gradeList = new ArrayList<>();
gradeList.add(new Grade().setValue("np.").setWeight("1,00"));
Assert.assertEquals(-1f, GradeUtils.calculate(gradeList), 0.0f);
List<Subject> 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(""));
}
}