Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements stats feature #114

Merged
merged 28 commits into from
Oct 26, 2019
Merged

Conversation

jietung
Copy link

@jietung jietung commented Oct 24, 2019

No description provided.

@jietung jietung added this to the v1.3 milestone Oct 24, 2019
# Conflicts:
#	src/main/java/seedu/exercise/logic/Logic.java
#	src/main/java/seedu/exercise/logic/LogicManager.java
#	src/main/java/seedu/exercise/logic/parser/ExerciseBookParser.java
#	src/main/java/seedu/exercise/model/Model.java
#	src/main/java/seedu/exercise/model/ModelManager.java
/**
* Update statistic about deleted exercise.
*/
private void updateStatistic(Model model) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can consider placing this method in the model class and just call model.updateStatistics().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines +32 to +35
if (startDate == null && endDate == null) {
this.startDate = Date.getOneWeekBeforeToday();
this.endDate = Date.getToday();
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this null behaviour well. Include it in the documentation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* Generates and returns statistic for different chart type.
*/
public Statistic generateStatistic() {
HashMap<String, Double> data;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this hashmap for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted. I forgot to delete.


return generatePieChartStatistic();

} else { //barchart

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may want to add else if (chart.equals("barchart")) and a else block that throws an exception

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may want to consider using switch case to make it easier to read

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 26 to 27
public static final Prefix PREFIX_STARTDATE = new Prefix("s/");
public static final Prefix PREFIX_ENDDATE = new Prefix("e/");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

START_DATE and END_DATE

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;

/**
* Represents an Exercise's date in ExerHealth.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the documentation here to reflect what the date now does. It is no longer just an Exercise's date

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* Returns today's Date.
*/
public static Date getToday() {
LocalDate today = LocalDate.now(ZoneId.of("Asia/Singapore"));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may want to use ZoneId.systemDefault() instead of hardcoding our zone

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 55 to 56
barChart.setTitle(statistic.getCategory() + " (" + statistic.getStartDate()
+ " to " + statistic.getEndDate() + ")");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to abstract this portion out into a Util class so all your xxxPanels can use it to format the title text.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 25 to 35
public StatisticBuilder() {
this.category = DEFAULT_CATEGORY;
this.chart = DEFAULT_CHART;
this.startDate = new Date(DEFAULT_START_DATE);
this.endDate = new Date(DEFAULT_END_DATE);
this.properties = new ArrayList<>();
this.values = new ArrayList<>();
}

public Statistic build() {
return new Statistic(category, chart, startDate, endDate, properties, values);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not how a builder would look like. This is more of a get a default statistics. Look at #96 under CustomPropertyBuilder to see how it would look like

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/**
* Compute exercise count with filtered exercises list.
*/
private HashMap<String, Double> getTotalExerciseCount() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can just return a list of double and abstract out the methods. The getTotalExerciseCount() is very similar to getTotalExerciseQuantity(). Entirely up to you if you wish to change

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To minimize confusion between this method and the one below, can consider calling this getTotalExerciseFrequency()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to getTotalExerciseFrequency()

@@ -79,6 +80,11 @@
*/
void setGuiSettings(GuiSettings guiSettings);

/**
* Returns the Statistic.
*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be slightly more descriptive about this comment. Maybe "Returns the Statistic object currently in focus" or something that describe its purpose.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

StatsFactory statsFactory = new StatsFactory(exercises, chart, category, startDate, endDate);
Statistic statistic = statsFactory.generateStatistic();
model.updateStatistic(statistic);
return new CommandResult("Chart displayed");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can consider replacing this magic literal with a MESSAGE_STATS_DISPLAY_SUCCESS

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/**
* Compute exercise count with filtered exercises list.
*/
private HashMap<String, Double> getTotalExerciseCount() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To minimize confusion between this method and the one below, can consider calling this getTotalExerciseFrequency()

int numberOfDaysApart = Date.numberOfDaysBetween(startDate, endDate);

if (numberOfDaysApart > 31) {
throw new ParseException("Start date and end date are too far apart");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to specify what's the max difference in the error messages. Also, better to store the error messages in a static final String. Same for below

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

} else if (argMultimap.arePrefixesPresent(PREFIX_ENDDATE)
&& !argMultimap.arePrefixesPresent(PREFIX_STARTDATE)) { //only end date present

throw new ParseException("Start date must be provided.");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can simply use "Start date must be provided with end date" for both

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

} else if (chart.equals("linechart")) {
chartPlaceholder.getChildren().add(new LineChartPanel(statistic).getRoot());
} else {
chartPlaceholder.getChildren().add(new PieChartPanel(statistic).getRoot());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if (chart.equals("piechart")) {

} else {
// Default chart / some text to show chart display error
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

ReadOnlyResourceBook<Exercise> exercises = model.getExerciseBookData();
Statistic outdatedStatistic = model.getStatistic();
StatsFactory statsFactory = new StatsFactory(exercises, outdatedStatistic.getChart(),
outdatedStatistic.getCategory(), outdatedStatistic.getStartDate(), outdatedStatistic.getEndDate());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to implement a constructor in StatsFactory that takes in exercises and an outdatedStatistic object so that you don't violate Law of Demeter.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved this method to model.

private String chart;
private String category;
private Date startDate;
private Date endDate;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to implement immutable variables instead

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


return generatePieChartStatistic();

} else { //barchart
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may want to consider using switch case to make it easier to read

String trimmedEndDate = endDate.trim();
parseDate(trimmedEndDate);
if (!Date.isEndDateAfterStartDate(startDate.toString(), trimmedEndDate)) {
throw new ParseException("End date must be before ");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParseException should be "End date must be before start date"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (eDate.compareTo(sDate) < 0) {
return false;
} else {
return true;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can simplify this expression to:
return eDate.compareTo(sDate) >= 0

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


if (d.compareTo(sDate) >= 0 && d.compareTo(eDate) <= 0) {
return true;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can simplify this expression as well

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


throw new ParseException("Start date must be provided.");

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if both start date and end date are not present?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will set start day as a week before today's date and end date as today's date

ArrayList<Double> values = new ArrayList<>();

for (String n : names) {
values.add(data.get(n));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be expressed as:
return new ArrayList<>(data.values())

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need it to correspond to the list of strings, so i did it this way.

/**
* Compute exercise quantity with filtered exercises list.
*/
private HashMap<String, Double> getTotalExerciseQuantity() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming of this method (and getTotalExerciseCount) can be misleading.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have changed it to getTotalExerciseFrequency()

StatsFactory statsFactory = new StatsFactory(exercises, chart, category, startDate, endDate);
Statistic statistic = statsFactory.generateStatistic();
model.updateStatistic(statistic);
return new CommandResult("Chart displayed");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May want to store the message in CommandResult as a private final String MESSAGE_SUCCESS in this class.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

# Conflicts:
#	src/main/java/seedu/exercise/logic/parser/CliSyntax.java
#	src/main/java/seedu/exercise/logic/parser/ParserUtil.java
#	src/main/java/seedu/exercise/model/Model.java
#	src/main/java/seedu/exercise/model/ModelManager.java
#	src/test/java/seedu/exercise/logic/commands/AddExerciseCommandTest.java
@@ -143,7 +147,7 @@ public static Date parseEndDate(Date startDate, String endDate) throws ParseExce
String trimmedEndDate = endDate.trim();
parseDate(trimmedEndDate);
if (!Date.isEndDateAfterStartDate(startDate.toString(), trimmedEndDate)) {
throw new ParseException("End date must be before ");
throw new ParseException("End date must be after start date");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be better if the message is stored in a final String MESSAGE_INVALID_END_DATE in the ParserUtil class or Date class

Copy link

@t-cheepeng t-cheepeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

# Conflicts:
#	src/main/java/seedu/exercise/logic/parser/CliSyntax.java
#	src/main/java/seedu/exercise/model/Model.java
@t-cheepeng t-cheepeng merged commit 780bbaa into AY1920S1-CS2103T-T09-2:master Oct 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants