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

Move Semester generation code #116

Merged
merged 33 commits into from
Mar 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
92cb2cd
Planner: Initialize weekType for each Day
dingheng4448 Mar 7, 2019
1a98449
Planner: Fix Codacy issue
dingheng4448 Mar 7, 2019
45f7915
Planner: Update code for initialisation of semester
dingheng4448 Mar 8, 2019
2c631df
Planner: Fix Codacy and checkstyle issues
dingheng4448 Mar 9, 2019
20b4abb
Merge branch 'master' into develop
dingheng4448 Mar 9, 2019
5ac6ca9
Planner: Fix build error
dingheng4448 Mar 9, 2019
7e5b58c
Planner: Dynamic generation of semester from date
dingheng4448 Mar 16, 2019
60d1cda
PlannerTest: Add JUnit test for generateSemester
dingheng4448 Mar 16, 2019
93b40ed
Merge remote-tracking branch 'origin/develop' into develop
dingheng4448 Mar 16, 2019
a8d57fe
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 17, 2019
a002fdc
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 17, 2019
dbcf1fd
Update documentation for view command
dingheng4448 Mar 17, 2019
f3ce309
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 17, 2019
8d35cfb
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 17, 2019
aa42b48
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 17, 2019
f0d916b
Add view command for monthly calendar view
dingheng4448 Mar 18, 2019
132bb01
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 18, 2019
1eded38
Fix Codacy issue
dingheng4448 Mar 18, 2019
db15e14
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 19, 2019
bfac078
UserGuide: Update user guide documentation
dingheng4448 Mar 19, 2019
936a880
UserGuide: Update user guide documentation
dingheng4448 Mar 19, 2019
6c679a2
UserGuide: Update user guide documentation
dingheng4448 Mar 20, 2019
a2c34fa
UserGuide: Update user guide documentation
dingheng4448 Mar 21, 2019
732c15e
Merge remote-tracking branch 'origin/develop' into develop
dingheng4448 Mar 21, 2019
e14f476
UserGuide: Update user guide documentation
dingheng4448 Mar 21, 2019
4b1781b
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 21, 2019
d7cb580
UserGuide: Update user guide documentation
dingheng4448 Mar 21, 2019
24ac7d5
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 21, 2019
9967d8d
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 23, 2019
17f1e8d
Moved Semester generation code
dingheng4448 Mar 24, 2019
48db5f1
Planner: remove unused imports
dingheng4448 Mar 24, 2019
fe1f0e4
Semester: undo minor change
dingheng4448 Mar 24, 2019
abcb88b
Merge branch 'master' of https://github.com/CS2113-AY1819S2-T08-3/mai…
dingheng4448 Mar 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions docs/DeveloperGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,32 @@ Classes used by multiple components are in the `planmysem.commons` package.

This section describes some noteworthy details on how certain features are implemented.

=== Initializing of the Planner and it's Semesters
=== Initialization of the Planner and it's Semester

==== Future Implementation
The Planner and it's Semester has to be initialized for _PlanMySem_ to work as all other features of _PlanMySem_ would
interact with this Semester object.

==== Current Implementation

Upon launching _PlanMySem_, the initialization of the Planner and it's Semester would be implemented via two steps:

1. Automatically generate the academic calendar from the current date.
2. Setup current Semester from the academic calendar.

//The academic calendar is dynamically generated by invoking the function
//based on the current date retrieved from the system clock.
//TBC
==== Design Considerations

===== Aspect: Generation of academic calendar

* *Alternative 1 (current choice):* Generate academic calendar by performing calculations from the current date.
** Pros: Generation of academic calendar is dynamic and will work for future dates.
** Cons: Computationally expensive as many operations have to be performed.

* *Alternative 2:* Retrieve academic calendar from a pre-generated file.
** Pros: Generation of academic calendar is efficient and not prone to calculation errors.
** Cons: Requires the pre-generated file which may be accidentally edited or deleted by the user.

=== Reinventing the Parser / Command Format and Structure

Expand Down
248 changes: 1 addition & 247 deletions src/planmysem/data/Planner.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package planmysem.data;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;

import javafx.util.Pair;
import planmysem.data.exception.IllegalValueException;
Expand All @@ -32,7 +26,7 @@ public class Planner {
* Creates an empty planner.
*/
public Planner() {
semester = generateSemester(LocalDate.now());
semester = Semester.generateSemester(LocalDate.now());
}

/**
Expand All @@ -44,246 +38,6 @@ public Planner(Semester semester) {
this.semester = new Semester(semester);
}

/**
* Generates current semester based on current date.
* As long as the current date falls within a semester, the generated semester is always the same.
*
* @param currentDate the current date when the program is run
* @return the current semester object
*/
public static Semester generateSemester(LocalDate currentDate) {
String acadSem;
String acadYear;
String[] semesterDetails;
int noOfWeeks;
LocalDate startDate;
LocalDate endDate;
List<LocalDate> datesList;
HashMap<Integer, String> acadCalMap;
HashMap<LocalDate, Day> days = new HashMap<>();
Set<LocalDate> recessDays = new HashSet<>();
Set<LocalDate> readingDays = new HashSet<>();
Set<LocalDate> normalDays = new HashSet<>();
Set<LocalDate> examDays = new HashSet<>();

acadCalMap = generateAcadCalMap(currentDate);
semesterDetails = getSemesterDetails(currentDate, acadCalMap);
acadSem = semesterDetails[1];
acadYear = semesterDetails[2];
noOfWeeks = Integer.parseInt(semesterDetails[3]);
startDate = LocalDate.parse(semesterDetails[4]);
endDate = LocalDate.parse(semesterDetails[5]);

// Initialise HashMap and Sets of all days in current semester
datesList = startDate.datesUntil(endDate).collect(Collectors.toList());
for (LocalDate date: datesList) {
int weekOfYear = date.get(WeekFields.ISO.weekOfWeekBasedYear());
String weekType = acadCalMap.get(weekOfYear).split("_")[0];
days.put(date, new Day(date.getDayOfWeek(), weekType));
switch (weekType) {
case "Recess Week":
recessDays.add(date);
break;
case "Reading Week":
readingDays.add(date);
break;
case "Examination Week":
examDays.add(date);
break;
default:
normalDays.add(date);
break;
}
}

return new Semester(acadSem, acadYear, days, startDate, endDate, noOfWeeks,
recessDays, readingDays, normalDays, examDays);
}

/**
* Generates academic calendar for a given date.
*
* @param date used to determine academic year
* @return details of academic calendar
*/
private static HashMap<Integer, String> generateAcadCalMap(LocalDate date) {
HashMap<Integer, String> acadCalMap = new HashMap<>();
LocalDate semOneStartDate = date;
LocalDate semTwoEndDate = date;
int currentMonth = date.getMonthValue();
int currentYear = date.getYear();
int semOneStartWeek;
int semTwoStartWeek;
int semTwoEndWeek;
int acadWeekNo;
int noOfWeeksInYear;
int vacationWeekNo;

if (currentMonth < 8) {
// Academic Year beginning from August of previous year
semOneStartDate = semOneStartDate.withYear(currentYear - 1).withMonth(8)
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
semOneStartWeek = semOneStartDate.get(WeekFields.ISO.weekOfWeekBasedYear());
semTwoEndDate = semTwoEndDate.withYear(currentYear).withMonth(8)
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)).minusDays(1);
semTwoEndWeek = semTwoEndDate.get(WeekFields.ISO.weekOfWeekBasedYear());
} else {
// Academic Year beginning from August of current year
semOneStartDate = semOneStartDate.withYear(currentYear).withMonth(8)
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
semOneStartWeek = semOneStartDate.get(WeekFields.ISO.weekOfWeekBasedYear());
semTwoEndDate = semTwoEndDate.withYear(currentYear + 1).withMonth(8)
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)).minusDays(1);
semTwoEndWeek = semTwoEndDate.get(WeekFields.ISO.weekOfWeekBasedYear());
}

// Sem 1 - Orientation Week
acadCalMap.put(semOneStartWeek, "Orientation Week_Sem 1");

// Sem 1 - Week 1 to 6
acadWeekNo = 1;
for (int i = semOneStartWeek + 1; i < semOneStartWeek + 7; i++) {
acadCalMap.put(i, "Week " + acadWeekNo + "_Sem 1");
acadWeekNo++;
}

// Sem 1 - Recess Week
acadCalMap.put(semOneStartWeek + 7, "Recess Week_Sem 1");

// Sem 1 - Week 7 to 13
acadWeekNo = 7;
for (int i = semOneStartWeek + 8; i < semOneStartWeek + 15; i++) {
acadCalMap.put(i, "Week " + acadWeekNo + "_Sem 1");
acadWeekNo++;
}

// Sem 1 - Reading & Examination Weeks
acadCalMap.put(semOneStartWeek + 15, "Reading Week_Sem 1");
acadCalMap.put(semOneStartWeek + 16, "Examination Week_Sem 1");
acadCalMap.put(semOneStartWeek + 17, "Examination Week_Sem 1");

// Sem 1 - Vacation
noOfWeeksInYear = (int) semOneStartDate.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum();
vacationWeekNo = semOneStartWeek + 18;
semTwoStartWeek = 1;
for (int i = 0; i < 5; i++) {
if ((vacationWeekNo + i) <= noOfWeeksInYear) {
acadCalMap.put(vacationWeekNo + i, "Vacation_Sem 1");
} else {
acadCalMap.put(semTwoStartWeek++, "Vacation_Sem 1");
}
}

// Sem 2 - Week 1 to 6
acadWeekNo = 1;
for (int i = semTwoStartWeek; i < semTwoStartWeek + 6; i++) {
acadCalMap.put(i, "Week " + acadWeekNo + "_Sem 2");
acadWeekNo++;
}

// Sem 2 - Recess Week
acadCalMap.put(semTwoStartWeek + 6, "Recess Week_Sem 2");

// Sem 2 - Week 7 to 13
acadWeekNo = 7;
for (int i = semTwoStartWeek + 7; i < semTwoStartWeek + 14; i++) {
acadCalMap.put(i, "Week " + acadWeekNo + "_Sem 2");
acadWeekNo++;
}

// Sem 2 - Reading & Examination Weeks
acadCalMap.put(semTwoStartWeek + 14, "Reading Week_Sem 2");
acadCalMap.put(semTwoStartWeek + 15, "Examination Week_Sem 2");
acadCalMap.put(semTwoStartWeek + 16, "Examination Week_Sem 2");

// Sem 2 - Vacation
vacationWeekNo = semTwoStartWeek + 17;
while (vacationWeekNo <= semTwoEndWeek) {
acadCalMap.put(vacationWeekNo++, "Vacation_Sem 2");
}

return acadCalMap;
}

/**
* Initialises current semester's details.
*
* @param date the current date when the program is run
* @param acadCalMap used to determine current academic week
* @return an array of Strings of the current semester's details
*/
private static String[] getSemesterDetails(LocalDate date, HashMap<Integer, String> acadCalMap) {
String acadWeek;
String acadSem;
String acadYear = null;
String noOfWeeks = null;
String[] acadWeekDetails;
LocalDate startDate = date;
LocalDate endDate = date;
int currentYear = date.getYear();
int currentWeekOfYear = date.get(WeekFields.ISO.weekOfWeekBasedYear());

// Initialise week numbers for certain weeks.
int firstWeekSemOne = 0;
int firstWeekSemOneHol = 0;
int lastWeekSemOneHol = 0;
int firstWeekSemTwo = 0;
int firstWeekSemTwoHol = 0;
for (Map.Entry<Integer, String> entry: acadCalMap.entrySet()) {
if ("Orientation Week_Sem 1".equals(entry.getValue())) {
firstWeekSemOne = entry.getKey();
} else if ("Examination Week_Sem 1".equals(entry.getValue())) {
firstWeekSemOneHol = entry.getKey() + 1;
} else if ("Week 1_Sem 2".equals(entry.getValue())) {
lastWeekSemOneHol = entry.getKey() - 1;
firstWeekSemTwo = entry.getKey();
} else if ("Examination Week_Sem 2".equals(entry.getValue())) {
firstWeekSemTwoHol = entry.getKey() + 1;
}
}

// Set semester details.
acadWeekDetails = acadCalMap.get(currentWeekOfYear).split("_");
acadWeek = acadWeekDetails[0];
acadSem = acadWeekDetails[1];
if ("Vacation".equals(acadWeek) && "Sem 1".equals(acadSem)) {
noOfWeeks = "5";
if (currentWeekOfYear < 4) {
acadYear = "AY" + (currentYear - 1) + "/" + currentYear;
startDate = startDate.withYear(currentYear - 1);
} else {
acadYear = "AY" + currentYear + "/" + (currentYear + 1);
endDate = endDate.withYear(currentYear + 1);
}
startDate = startDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemOneHol);
startDate = startDate.with(WeekFields.ISO.dayOfWeek(), 1);
endDate = endDate.with(WeekFields.ISO.weekOfWeekBasedYear(), lastWeekSemOneHol);
endDate = endDate.with(WeekFields.ISO.dayOfWeek(), 7);
} else if ("Vacation".equals(acadWeek) && "Sem 2".equals(acadSem)) {
noOfWeeks = "12";
acadYear = "AY" + (currentYear - 1) + "/" + currentYear;
startDate = startDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemTwoHol);
startDate = startDate.with(WeekFields.ISO.dayOfWeek(), 1);
endDate = endDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemTwoHol + 11);
endDate = endDate.with(WeekFields.ISO.dayOfWeek(), 7);
} else if ("Sem 1".equals(acadSem)) {
noOfWeeks = "18";
acadYear = "AY" + currentYear + "/" + (currentYear + 1);
startDate = startDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemOne);
startDate = startDate.with(WeekFields.ISO.dayOfWeek(), 1);
endDate = endDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemOne + 17);
endDate = endDate.with(WeekFields.ISO.dayOfWeek(), 7);
} else if ("Sem 2".equals(acadSem)) {
noOfWeeks = "17";
acadYear = "AY" + (currentYear - 1) + "/" + currentYear;
startDate = startDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemTwo);
startDate = startDate.with(WeekFields.ISO.dayOfWeek(), 1);
endDate = endDate.with(WeekFields.ISO.weekOfWeekBasedYear(), firstWeekSemTwo + 16);
endDate = endDate.with(WeekFields.ISO.dayOfWeek(), 7);
}
return new String[] {acadWeek, acadSem, acadYear, noOfWeeks, startDate.toString(), endDate.toString()};
}

/**
* Adds a day to the Planner.
*
Expand Down
Loading