diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
index 255883f..82a43f7 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/Team.java
@@ -91,7 +91,7 @@ public abstract class Team
extends BasicEntity {
public String toString() {
StringBuilder sb = new StringBuilder();
for (P p : this.getMembers()) {
- sb.append(p.toString()).append(", ");
+ sb.append(p.getFullName()).append(", ");
}
return sb.toString();
}
diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
index 0723148..774991d 100644
--- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
+++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/team_importing/StudentTeamImporter.java
@@ -11,7 +11,10 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
/**
* Provides some methods to streamline the process of transforming a CSV file of student data into a list of valid teams
@@ -33,19 +36,27 @@ public class StudentTeamImporter {
List studentEntries = extractStudentsFromRecords(records);
+ System.out.println("<<< Entries (" + studentEntries.size() + ") >>>");
for (StudentRecordEntry entry : studentEntries) {
System.out.println(entry.toString());
}
- return new ArrayList<>();
+ List studentTeams = generateTeamsFromStudentEntries(studentEntries, 0);
+ System.out.println("<<< Teams (" + studentTeams.size() + ") >>>");
+ for (StudentTeam team : studentTeams) {
+ System.out.println("Team: " + team);
+ }
+
+ return studentTeams;
}
/**
* Extracts all student data from a list of records, and automatically discards outdated responses (those where the
* same student submitted more than once).
* @param records The list of records in the CSV file.
- * @return A mapping for each timestamp to
+ * @return A list of all student entries. A student entry is an intermediate object used to organize the parsed data
+ * from each record in the CSV file.
*/
private static List extractStudentsFromRecords(Iterable records) {
List studentEntries = new ArrayList<>();
@@ -73,7 +84,93 @@ public class StudentTeamImporter {
return studentEntries;
}
+ /**
+ * Generates a list of teams from a list of unique student entries. The algorithm is described as follows:
+ *
+ * 1. Select the next student from the list of entries.
+ * 2. If the student (A) has specified a partner (B), search for that partner (B) in the list of entries.
+ * 3. If the partner (B) also specified the student (A) as their preferred partner, a team is created from the two.
+ * a. Pop both student entries from the list of entries.
+ * 4. Else, place student (A) in a queue of single students.
+ * a. Pop student (A) from the list of entries.
+ * 5. If the list of entries is not empty, go to 1.
+ * 6. The list of entries is now empty, and zero or more entries exist in a queue of single students.
+ * 7. Pop two (or as many as possible) students randomly from the queue, and form a team from them.
+ * 8. Repeat until the queue of single students is empty.
+ * 9. There is now a list of student teams and no student should remain unprocessed.
+ *
+ * @param entries A list of record entries.
+ * @param seed A seed to use for randomization of single student teams.
+ * @return A list of student teams.
+ */
+ private static List generateTeamsFromStudentEntries(List entries, long seed) {
+ List teams = new ArrayList<>();
+ List singleStudentsEntryQueue = new ArrayList<>();
+ Random random = new Random(seed);
+ // Realize step 5. Loop until there are no more processed entries.
+ while (!entries.isEmpty()) {
+ // Step 1. Select the next student from the list of entries.
+ StudentRecordEntry entry = entries.remove(0);
+
+ // Step 2. If the student has a partner, search for that partner.
+ if (entry.hasPartner()) {
+ boolean partnerFound = false; // Use this to keep track of if a partner is actually found.
+ for (int i = 0; i < entries.size(); i++) {
+ StudentRecordEntry secondEntry = entries.get(i);
+ // Step 3. If the partner specifies their partner as the student (both want each other), then create a team.
+ if (
+ entry.getPartnerStudent().equals(secondEntry.getStudent())
+ && secondEntry.hasPartner()
+ && secondEntry.getPartnerStudent().equals(entry.getStudent())
+ ) {
+ partnerFound = true;
+
+ entries.remove(i); // Step 3a. The first student has been popped, so pop this one.
+
+ StudentTeam team = new StudentTeam();
+ team.addMember(entry.getStudent());
+ team.addMember(secondEntry.getStudent());
+ teams.add(team);
+
+ break;
+ }
+ }
+
+ // Step 4. If no partner was found, then add this entry to the queue of single students.
+ if (!partnerFound) {
+ singleStudentsEntryQueue.add(entry);
+ }
+ } else {
+ // Also Step 4. The student chose to have no partner, so add this entry to the queue of single students.
+ singleStudentsEntryQueue.add(entry);
+ }
+ }
+
+ // We are now at step 6.
+ while (!singleStudentsEntryQueue.isEmpty()) {
+ StudentTeam team = new StudentTeam();
+ StudentRecordEntry firstRandomEntry = singleStudentsEntryQueue.remove(random.nextInt(singleStudentsEntryQueue.size()));
+ team.addMember(firstRandomEntry.getStudent());
+
+ // Check if there's another student in the queue.
+ if (!singleStudentsEntryQueue.isEmpty()) {
+ StudentRecordEntry secondRandomEntry = singleStudentsEntryQueue.remove(random.nextInt(singleStudentsEntryQueue.size()));
+ team.addMember(secondRandomEntry.getStudent());
+ }
+
+ teams.add(team);
+ }
+
+ return teams;
+ }
+
+ /**
+ * Scans a list of student entries and removes entries which are outdated by newer entries by the same student, such
+ * that the resulting list contains only one unique entry per student.
+ * @param studentEntries The list of student entries, possibly containing duplicates.
+ * @return A list of student entries in which all outdated duplicates have been removed.
+ */
private static List removeDuplicateEntries(List studentEntries) {
List uniqueStudentEntries = new ArrayList<>();