Created
March 19, 2023 06:49
-
-
Save Shrinks99/7c2f73a12f74f3fc4459e3dccb2e8f28 to your computer and use it in GitHub Desktop.
This script was entirely created by ChatGPT using its GPT-4 powered model over the course of about 4 hours of instruction. With my test dataset, it results in a 24% successful grouping of students based on their requests.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import csv | |
import re | |
def find_student(students, first_name, last_name=None): | |
for student in students: | |
if student['first_name'] == first_name and (last_name is None or student['last_name'] == last_name): | |
return student | |
return None | |
def check_avoid_list(student, notes): | |
pattern = re.compile(r'\b' + re.escape(student['first_name']) + r'\b') | |
if pattern.search(notes): | |
if student['last_name']: | |
pattern = re.compile(r'\b' + re.escape(student['last_name']) + r'\b') | |
return bool(pattern.search(notes)) | |
else: | |
return True | |
return False | |
def can_group_together(student1, student2): | |
if student1['gender_grouping'] == student2['gender_grouping']: | |
return True | |
if (student1['gender_grouping'] == "Either a single-gender (male) OR an all-gender cabin works for me." and | |
student2['gender_grouping'] != "Single-gender (female) cabin"): | |
return True | |
if (student1['gender_grouping'] == "Either a single-gender (female) OR an all-gender cabin works for me." and | |
student2['gender_grouping'] != "Single-gender (male) cabin"): | |
return True | |
if (student2['gender_grouping'] == "Either a single-gender (male) OR an all-gender cabin works for me." and | |
student1['gender_grouping'] != "Single-gender (female) cabin"): | |
return True | |
if (student2['gender_grouping'] == "Either a single-gender (female) OR an all-gender cabin works for me." and | |
student1['gender_grouping'] != "Single-gender (male) cabin"): | |
return True | |
return False | |
def group_students(students, max_groups, max_group_size): | |
groups = [] # Initialize an empty list of groups | |
# Iterate through each student in the students list | |
for student in students: | |
found_group = False | |
# Iterate through each existing group | |
for group in groups: | |
# Skip the group if it is already at the maximum size | |
if len(group) >= max_group_size: | |
continue | |
# Assume the student can join the group until proven otherwise | |
can_join_group = True | |
# Check if the student can join the group based on the group's members | |
for group_member in group: | |
if (not can_group_together(student, group_member) or | |
check_avoid_list(group_member, student['notes']) or | |
check_avoid_list(student, group_member['notes'])): | |
# If the student cannot join the group, set can_join_group to False and break the loop | |
can_join_group = False | |
break | |
# If the student can join the group, add the student to the group and set found_group to True | |
if can_join_group: | |
group.append(student) | |
found_group = True | |
break | |
# If the student has not found a group, find the best group based on friend requests and conflicts | |
if not found_group: | |
best_group = None | |
best_score = float('-inf') | |
# Iterate through each existing group | |
for group in groups: | |
# Skip the group if it is already at the maximum size | |
if len(group) >= max_group_size: | |
continue | |
friend_count = 0 | |
conflict_count = 0 | |
# Check for friend requests and conflicts within the group | |
for group_member in group: | |
if (not can_group_together(student, group_member) or | |
check_avoid_list(group_member, student['notes']) or | |
check_avoid_list(student, group_member['notes'])): | |
# Increment conflict_count if there is a conflict | |
conflict_count += 1 | |
continue | |
# Check if the student has any friend requests fulfilled in the group | |
for request_col in ['request1', 'request2', 'request3']: | |
if student[request_col]: | |
names = student[request_col].split() | |
first_name, last_name = names[0], names[1] if len(names) > 1 else None | |
if find_student([group_member], first_name, last_name): | |
friend_count += 1 | |
break | |
# Calculate the score for the group based on friend requests and conflicts | |
score = friend_count - conflict_count | |
# Update the best group and best_score if the current group has a higher score | |
if score > best_score: | |
best_score = score | |
best_group = group | |
# If the best group is found, add the student to the group and set found_group to True | |
if best_group: | |
best_group.append(student) | |
found_group = True | |
# If the student still hasn't found a group and there's room for more groups, create a new group with the student | |
if not found_group and len(groups) < max_groups: | |
groups.append([student]) | |
# If the student still hasn't found a group, find the group with the minimum conflicts and add the student to it | |
elif not found_group: | |
min_conflicts = float('inf') | |
best_group = None | |
# Iterate through each existing group | |
for group in groups: | |
# Skip the group if it is already at the maximum size | |
if len(group) >= max_group_size: | |
continue | |
# Calculate the number of conflicts in the group | |
conflicts = sum(1 for group_member in group if | |
(not can_group_together(student, group_member) or | |
check_avoid_list(group_member, student['notes']) or | |
check_avoid_list(student, group_member['notes']))) | |
# Update the best group and min_conflicts if the current group has fewer conflicts | |
if conflicts < min_conflicts: | |
min_conflicts = conflicts | |
best_group = group | |
# If no suitable group is found, use the first group in the list | |
if best_group is None: | |
best_group = groups[0] | |
# Add the student to the best group | |
best_group.append(student) | |
# Return the list of groups | |
return groups | |
def read_students_from_csv(file_path): | |
with open(file_path, newline='') as csvfile: | |
reader = csv.DictReader(csvfile) | |
return [row for row in reader] | |
def write_groups_to_csv(groups, students, output_file_path): | |
with open(output_file_path, 'w', newline='') as csvfile: | |
fieldnames = None | |
writer = None | |
for group_id, group in enumerate(groups, 1): | |
for student in group: | |
if fieldnames is None: | |
fieldnames = list(student.keys()) | |
fieldnames.insert(0, 'group_id') | |
writer = csv.DictWriter(csvfile, fieldnames=fieldnames) | |
writer.writeheader() | |
row = {'group_id': group_id, **student} | |
writer.writerow(row) | |
input_file_path = 'students.csv' | |
output_file_path = 'grouped_students.csv' | |
students = read_students_from_csv(input_file_path) | |
max_groups = 20 | |
optimal_group_size = 6 | |
max_group_size = 24 | |
groups = group_students(students, max_groups, optimal_group_size) | |
write_groups_to_csv(groups, students, output_file_path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment