-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix_members.py
More file actions
151 lines (126 loc) · 5.8 KB
/
fix_members.py
File metadata and controls
151 lines (126 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python3
"""Fix the members sheet to match the current lab roster.
This script updates the members sheet based on the actual current
lab members list and moves others to alumni.
"""
from pathlib import Path
import openpyxl
# Current active members (as of Dec 2024)
CURRENT_MEMBERS = {
# Grad students
'claudia gonciulea': {'role': 'grad student', 'category': 'grad'},
'paxton fitzpatrick': {'role': 'grad student', 'category': 'grad'},
'xinming xu': {'role': 'grad student', 'category': 'grad'},
# Undergrads
'aidan miller': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'alexandra wingo': {'role': 'undergrad', 'category': 'undergrad'},
'alishba tahir': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'angelyn liu': {'role': 'undergrad', 'category': 'undergrad'},
'annabelle morrow': {'role': 'undergrad', 'category': 'undergrad'},
'azaire andre': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'ellie mattox': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'emmy thornton': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'evan mcdermid': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'jackson c. sandrich': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'jacob bacus': {'role': 'undergrad', 'category': 'undergrad'},
'jennifer xu': {'role': 'undergrad', 'category': 'undergrad'},
'luca gandrud': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
'om shah': {'role': 'undergrad', 'category': 'undergrad'},
'sam haskel': {'role': 'undergrad', 'category': 'undergrad'},
'sarah parigela': {'role': 'undergrad', 'category': 'undergrad'},
'will lehman': {'role': 'undergrad', 'category': 'undergrad', 'new': True},
# Active but not in initial list
'kevin chang': {'role': 'undergrad', 'category': 'undergrad'},
'andrew richardson': {'role': 'undergrad', 'category': 'undergrad'},
'ben hanson': {'role': 'undergrad', 'category': 'undergrad'},
'owen phillips': {'role': 'undergrad', 'category': 'undergrad'},
'joy maina': {'role': 'undergrad', 'category': 'undergrad'},
'chelsea joe': {'role': 'undergrad', 'category': 'undergrad'},
'jake mcdermid': {'role': 'undergrad', 'category': 'undergrad'},
}
def normalize_name(name):
"""Normalize a name for comparison."""
return ' '.join(str(name).lower().split())
def main():
project_root = Path(__file__).parent.parent
xlsx_path = project_root / 'data' / 'people.xlsx'
wb = openpyxl.load_workbook(xlsx_path)
# Get current members sheet data
ws_members = wb['members']
ws_alumni = wb['alumni_undergrads']
# Get headers
member_headers = [cell.value for cell in ws_members[1]]
alumni_headers = [cell.value for cell in ws_alumni[1]]
# Read current members
current_rows = []
rows_to_move_to_alumni = []
for row_idx in range(2, ws_members.max_row + 1):
row_data = [ws_members.cell(row=row_idx, column=col).value for col in range(1, len(member_headers) + 1)]
if not any(row_data):
continue
name = normalize_name(row_data[1]) if row_data[1] else ''
if name in CURRENT_MEMBERS:
# Keep this member, update role if needed
row_data[3] = CURRENT_MEMBERS[name]['role']
current_rows.append(row_data)
print(f"Keeping: {name}")
elif name:
# Move to alumni
rows_to_move_to_alumni.append({
'name': row_data[1],
'years': '2024' # Approximate end year
})
print(f"Moving to alumni: {name}")
# Add new members that aren't in the spreadsheet yet
existing_names = {normalize_name(r[1]) for r in current_rows if r[1]}
for name, info in CURRENT_MEMBERS.items():
if name not in existing_names:
new_row = [
'', # image
name, # name (will be title-cased later)
'', # name_url
info['role'],
'', # bio
'' # links_html
]
current_rows.append(new_row)
print(f"Adding new member: {name}")
# Clear members sheet (except header)
for row_idx in range(2, ws_members.max_row + 1):
for col_idx in range(1, len(member_headers) + 1):
ws_members.cell(row=row_idx, column=col_idx).value = None
# Sort members: grad students first, then undergrads
def sort_key(row):
role = (row[3] or '').lower()
name = (row[1] or '').lower()
if 'grad' in role:
return (0, name)
return (1, name)
current_rows.sort(key=sort_key)
# Write back members
for row_idx, row_data in enumerate(current_rows, start=2):
for col_idx, value in enumerate(row_data, start=1):
ws_members.cell(row=row_idx, column=col_idx).value = value
# Add moved members to alumni_undergrads
next_alumni_row = ws_alumni.max_row + 1
for alum in rows_to_move_to_alumni:
ws_alumni.cell(row=next_alumni_row, column=1).value = alum['name']
ws_alumni.cell(row=next_alumni_row, column=2).value = alum['years']
next_alumni_row += 1
print(f"Added to alumni_undergrads: {alum['name']}")
# Save
wb.save(xlsx_path)
print(f"\nSaved changes to {xlsx_path}")
# Print summary
print(f"\n=== Summary ===")
print(f"Active members: {len(current_rows)}")
print(f"Moved to alumni: {len(rows_to_move_to_alumni)}")
# Print new members that need CV additions
new_members = [name for name, info in CURRENT_MEMBERS.items() if info.get('new')]
if new_members:
print(f"\n=== New members to add to CV ===")
for name in sorted(new_members):
print(f" - {name.title()}")
wb.close()
if __name__ == '__main__':
main()