Skip to content

Commit 020ddca

Browse files
Update extract_submissions.py
1 parent e24e5f1 commit 020ddca

File tree

1 file changed

+75
-51
lines changed

1 file changed

+75
-51
lines changed
Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
from openpyxl import Workbook
2-
from openpyxl.styles import Font
3-
from openpyxl.utils import get_column_letter
41
import os
52
import csv
63
import random
74
from collections import defaultdict
5+
from openpyxl import Workbook
6+
from openpyxl.styles import Alignment, Font
7+
from openpyxl.utils import get_column_letter
8+
from openpyxl.worksheet.datavalidation import DataValidation
89

9-
# === Load data ===
10+
# Load deduplicated submissions
1011
with open("ambassador/ambassador_submissions_deduped.csv", newline='', encoding='utf-8') as f:
1112
reader = csv.DictReader(f)
1213
submissions = list(reader)
1314

15+
# Define reviewers
1416
reviewers = [f"Reviewer {i}" for i in range(1, 8)]
1517

1618
# Define rubric
@@ -39,82 +41,104 @@
3941
("Motivation and Vision", "Vision", "Proposed goals or initiatives that align with the mission of the PyTorch Foundation?")
4042
]
4143

42-
# Define category mapping
43-
categories = ["Technical Expertise", "Open Source Contributions", "Thought Leadership and Technical Writing",
44-
"Community Engagement and Evangelism", "Online Influence and Reach", "Alignment and Values",
45-
"Motivation and Vision"]
44+
summary_categories = [
45+
"Technical Expertise",
46+
"Open Source Contributions",
47+
"Thought Leadership and Technical Writing",
48+
"Community Engagement and Evangelism",
49+
"Online Influence and Reach",
50+
"Alignment and Values",
51+
"Motivation and Vision"
52+
]
4653

47-
# Build a lookup for rubric indexes
48-
category_map = defaultdict(list)
49-
for i, (cat, _, _) in enumerate(rubric):
50-
category_map[cat].append(i)
54+
output_folder = "ambassador/reviewer_sheets_excel"
55+
os.makedirs(output_folder, exist_ok=True)
5156

52-
# Random reviewer assignment
5357
assignments = []
5458
reviewer_counts = defaultdict(int)
5559
for submission in submissions:
56-
sorted_reviewers = sorted(reviewers, key=lambda r: reviewer_counts[r])
57-
assigned = random.sample(sorted_reviewers[:4], 2)
60+
assigned = random.sample(sorted(reviewers, key=lambda r: reviewer_counts[r])[:4], 2)
5861
for reviewer in assigned:
5962
reviewer_counts[reviewer] += 1
6063
assignments.append((submission, reviewer))
6164

62-
# Output directory
63-
output_dir = "ambassador/reviewer_sheets_excel"
64-
os.makedirs(output_dir, exist_ok=True)
65-
66-
# Generate Excel with 2 sheets per reviewer
6765
for reviewer in reviewers:
6866
wb = Workbook()
6967
ws = wb.active
7068
ws.title = "Review Sheet"
69+
summary_ws = wb.create_sheet("Score Summary")
7170

72-
# Summary worksheet
73-
summary_ws = wb.create_sheet(title="Score Summary")
74-
summary_headers = ["Submission ID", "First Name", "Last Name"] + categories + ["Final Score"]
75-
summary_ws.append(summary_headers)
76-
for col in summary_ws[1]:
77-
col.font = Font(bold=True)
71+
headers = [
72+
"Submission ID", "First Name", "Last Name", "Submission Summary",
73+
"Reviewer's Comment", "Category", "Subcategory", "Question", "Score"
74+
]
75+
ws.append(headers)
76+
for col in range(1, len(headers) + 1):
77+
ws.cell(row=1, column=col).font = Font(bold=True)
78+
79+
dv = DataValidation(type="list", formula1='"Yes,No,N/A"', allow_blank=True)
80+
ws.add_data_validation(dv)
7881

7982
row_idx = 2
80-
summary_row = 2
83+
candidate_ranges = []
8184

8285
for submission, assigned_reviewer in assignments:
8386
if assigned_reviewer != reviewer:
8487
continue
8588

86-
issue_id = submission["Issue #"]
87-
name_parts = submission["Nominee Name"].split()
88-
first_name = name_parts[0] if name_parts else ""
89-
last_name = name_parts[-1] if len(name_parts) > 1 else ""
89+
sid = submission["Issue #"]
90+
name = submission["Nominee Name"].split()
91+
fname = name[0]
92+
lname = name[-1] if len(name) > 1 else ""
93+
summary = f"""Contributions:\n{submission.get("Contributions", "")}
9094
91-
category_rows = defaultdict(list)
92-
start_row = row_idx
95+
Ambassador Pitch:\n{submission.get("Ambassador Pitch", "")}
9396
97+
Additional Notes:\n{submission.get("Extra Notes", "")}"""
98+
99+
start = row_idx
94100
for cat, subcat, question in rubric:
95-
ws.append([
96-
issue_id, first_name, last_name, "", "", cat, subcat, question, ""
97-
])
98-
category_rows[cat].append(row_idx)
101+
ws.append([sid, fname, lname, summary, "", cat, subcat, question, ""])
99102
row_idx += 1
103+
end = row_idx - 1
104+
candidate_ranges.append((sid, fname, lname, start, end))
105+
106+
for col in [1, 2, 3, 4]:
107+
ws.merge_cells(start_row=start, end_row=end, start_column=col, end_column=col)
108+
cell = ws.cell(row=start, column=col)
109+
cell.alignment = Alignment(vertical="top", wrap_text=True)
110+
111+
for r in range(start, end + 1):
112+
dv.add(ws[f"I{r}"])
113+
114+
for col in ws.columns:
115+
max_len = max((len(str(cell.value)) if cell.value else 0) for cell in col)
116+
ws.column_dimensions[get_column_letter(col[0].column)].width = min(max_len + 5, 50)
100117

101-
# Write summary formulas
102-
formulas = []
103-
for cat in categories:
118+
summary_ws.append(["Submission ID", "First Name", "Last Name"] + summary_categories + ["Final Score"])
119+
for col in range(1, summary_ws.max_column + 1):
120+
summary_ws.cell(row=1, column=col).font = Font(bold=True)
121+
122+
for sid, fname, lname, start, end in candidate_ranges:
123+
category_rows = defaultdict(list)
124+
for r in range(start, end + 1):
125+
category = ws.cell(row=r, column=6).value
126+
if category in summary_categories:
127+
category_rows[category].append(r)
128+
129+
formula_cells = []
130+
for cat in summary_categories:
104131
if cat in category_rows:
105132
rng = category_rows[cat]
106-
formula = f"=SUMPRODUCT(--('{ws.title}'!I{rng[0]}:I{rng[-1]}=\"Yes\"))"
107-
formulas.append(formula)
133+
formula = f"=SUMPRODUCT(--('Review Sheet'!I{rng[0]}:I{rng[-1]}=\"Yes\"))"
108134
else:
109-
formulas.append("")
110-
111-
total_formula = f"=SUM({','.join([chr(68+i) + str(summary_row) for i in range(3, 3+len(categories))])})"
135+
formula = "0"
136+
formula_cells.append(formula)
112137

113-
summary_ws.append([issue_id, first_name, last_name] + formulas + [total_formula])
114-
summary_row += 1
138+
final_formula = f"=SUM({','.join([get_column_letter(i + 4) + str(summary_ws.max_row + 1) for i in range(len(formula_cells))])})"
139+
summary_ws.append([sid, fname, lname] + formula_cells + [final_formula])
115140

116-
# Save file
117-
reviewer_file = os.path.join(output_dir, f"{reviewer.replace(' ', '_').lower()}_sheet.xlsx")
118-
wb.save(reviewer_file)
141+
path = os.path.join(output_folder, f"{reviewer.replace(' ', '_').lower()}_sheet.xlsx")
142+
wb.save(path)
119143

120-
print("✅ All reviewer sheets generated with corrected formulas and aligned categories.")
144+
print("✅ Reviewer sheets generated with fixed formulas and matching structure.")

0 commit comments

Comments
 (0)