import matplotlib.pyplot as plt import numpy as np import pandas as pd import xlsxwriter cuts_all = { 'Spanish': {'2026': {'C': [49, 50], 'B': [73, 63], 'T': [99, 80], 'L': [0, 20], 'U': [100, 80]}}, 'French': {'2010': {'C': [40, 50], 'B': [68, 59], 'T': [99, 80], 'L': [0, 20], 'U': [100, 80]}}, 'German': {'2010': {'C': [34, 50], 'B': [56, 60], 'T': [86, 80], 'L': [0, 20], 'U': [87, 80]}} } col_dict = { 'raw': 'Raw Score', 'ss_lin':'SS Linear', 'ss_elb':'SS Segments', 'ss_lin_ur':'SS Linear (unrounded)', 'ss_elb_ur':'SS Segments (unrounded)', } def ab(top, bot, cuts): _a = (cuts[top][1] - cuts[bot][1]) / (cuts[top][0] - cuts[bot][0]) _b = cuts[top][1] - _a * cuts[top][0] return _a, _b def round_clip(a, low, high): return np.clip(np.round(a, 0), low, high) def conversion(cuts): a, b = ab('T', 'C', cuts) a1, b1 = ab('B', 'C', cuts) a2, b2 = ab('T', 'B', cuts) raw = np.arange(cuts['L'][0], cuts['U'][0]+1) raw1 = np.arange(cuts['L'][0], cuts['B'][0]) raw2 = np.arange(cuts['B'][0], cuts['U'][0]+1) ss_lin_ur = raw * a + b ss_elb_ur = np.append(raw1 * a1 + b1, raw2 * a2 + b2) data = pd.DataFrame({ 'raw': raw, 'ss_lin': round_clip(ss_lin_ur, cuts['L'][1], cuts['U'][1]), 'ss_elb': round_clip(ss_elb_ur, cuts['L'][1], cuts['U'][1]), 'ss_lin_ur': ss_lin_ur, 'ss_elb_ur': ss_elb_ur }) data = data.sort_values(by="raw", ascending=False) return data def plot(data, subject, year, cuts): fig, ax = plt.subplots() ax.plot(data.raw, data.ss_lin_ur, label='Linear') ax.plot(data.raw, data.ss_elb_ur, color='magenta', label='Segments') ax.plot([cuts['L'][0], cuts['U'][0]], [cuts['C'][1], cuts['C'][1]], color='green', linewidth=0.5) ax.plot([cuts['L'][0], cuts['U'][0]], [cuts['B'][1], cuts['B'][1]], color='orange', linewidth=0.5) ax.set_xlabel('Raw Score') ax.set_ylabel('Scale Score') ax.set_title(f'Conversions: CLEP {subject} ({year})') ax.legend() plt.tight_layout() plt.savefig(f'output/CLEP_{subject}_conversion_{year}.pdf') def save_excel(data, subject, year, cuts): workbook = xlsxwriter.Workbook(f'output/CLEP_{subject}_conversion_{year}.xlsx') worksheet = workbook.add_worksheet('conversion') bold = workbook.add_format({'bold': True}) cut_red0 = workbook.add_format({'bold': True, 'font_color': 'red'}) cut_red2 = workbook.add_format({'bold': True, 'font_color': 'red', 'num_format': '#.00'}) dec0 = workbook.add_format({'num_format': '#0'}) dec2 = workbook.add_format({'num_format': '#.0'}) i, j = 0, 0 for col in data.columns: for row in data[col]: fmt = dec0 val = data[col].iloc[j] raw = data.raw.iloc[j] if j == 0: # column header worksheet.write(j, i, col_dict[col], bold) if (raw == cuts['C'][0] or raw == cuts['B'][0]): if i<3: fmt = cut_red0 else: fmt = cut_red2 else: if i>2: fmt = dec2 worksheet.write(j+1, i, val, fmt) j += 1 i += 1 j = 0 workbook.close() def main(subject, year): cuts = cuts_all[subject][year] data = conversion(cuts) plot(data, subject, year, cuts) save_excel(data, subject, year, cuts) if __name__ == "__main__": main('Spanish', '2026')