File size: 4,262 Bytes
cdf2807 41a9969 cdf2807 bc36177 cdf2807 41a9969 aa3525b e22be08 4814b0a 40ca158 4814b0a a3de3da 4814b0a 40ca158 41a9969 40ca158 cdf2807 4814b0a 40ca158 41a9969 40ca158 4814b0a aa3525b cdf2807 41a9969 aa3525b 4814b0a 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b 40ca158 4814b0a 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b af26c90 4814b0a af26c90 bc36177 4814b0a 0d205a7 1fd5317 41a9969 bc36177 af26c90 41a9969 4814b0a aa3525b 40ca158 aa3525b bc36177 aa3525b 41a9969 aa3525b cdf2807 eb59eaa 4814b0a |
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 |
import pandas as pd
import openpyxl # ensure XLSX engine is available
import gradio as gr
import uuid
import os
# 7-Day Schedule Converter with explicit iteration and header fill and download support
def convert_schedule(file_path, direction):
# 1. Load raw header rows to determine day labels
raw = pd.read_excel(file_path, header=None)
header1 = raw.iloc[0, 1:].astype(object)
header2 = raw.iloc[1, 1:].astype(object)
# Decide which header row to use: prefer second if fully populated
if header2.notna().all() and not header2.str.startswith('Unnamed').any():
days = header2.tolist()
data_start = 2
else:
# Forward-fill merged first-row headers
days = []
last = None
for val in header1:
if pd.isna(val) or str(val).startswith('Unnamed'):
days.append(last)
else:
last = str(val)
days.append(last)
data_start = 1
# 2. Load actual data using resolved day columns
df = pd.read_excel(
file_path,
header=data_start,
index_col=0,
usecols=[0] + list(range(1, len(days) + 1))
)
df.columns = [str(day) for day in days]
# 3. Retain original day column order
day_cols = list(df.columns)
# 4. Build assignment mapping via explicit iteration
assignments = {}
if direction == 'A to B':
# Models in rows → Texters as rows
for model in df.index.astype(str):
for day in day_cols:
cell = df.at[model, day]
for texter in str(cell).split(','):
texter = texter.strip()
if not texter or texter.lower() in ['nan', 'none']:
continue
assignments.setdefault(texter, {d: [] for d in day_cols})
assignments[texter][day].append(model)
index = sorted(assignments.keys())
result = pd.DataFrame(index=index, columns=day_cols)
for texter, days_map in assignments.items():
for day in day_cols:
models = days_map.get(day, [])
result.at[texter, day] = ', '.join(models) if models else 'OFF'
else:
# Texters in rows → Models as rows
for texter in df.index.astype(str):
for day in day_cols:
cell = df.at[texter, day]
for model in str(cell).split(','):
model = model.strip()
if not model or model.lower() in ['nan', 'none']:
continue
assignments.setdefault(model, {d: [] for d in day_cols})
assignments[model][day].append(texter)
index = sorted(assignments.keys())
result = pd.DataFrame(index=index, columns=day_cols)
for model, days_map in assignments.items():
for day in day_cols:
texters = days_map.get(day, [])
result.at[model, day] = ', '.join(texters) if texters else 'OFF'
# 5. Cleanup axis names
result.index.name = None
result.columns.name = None
# 6. Save to Excel for download
os.makedirs('/mnt/data', exist_ok=True)
output_filename = f"converted_{uuid.uuid4().hex}.xlsx"
output_path = os.path.join('/mnt/data', output_filename)
result.to_excel(output_path, engine='openpyxl', index=True)
return result, output_path
# Gradio UI definition
def main():
iface = gr.Interface(
fn=convert_schedule,
inputs=[
gr.File(label='Upload Weekly Schedule (.xlsx)', file_count='single', type='filepath'),
gr.Radio(['A to B', 'B to A'], label='Convert Direction')
],
outputs=[
gr.Dataframe(label='Converted Schedule'),
gr.File(label='Download Converted Excel')
],
title='7-Day Schedule Converter',
description=(
'Upload a 7-column weekly schedule (Models vs Days) with merged or single headers, '
'then flip between Models→Texters or Texters→Models. Download the result as .xlsx.'
),
allow_flagging='never'
)
iface.launch(server_name='0.0.0.0', server_port=7860)
if __name__ == '__main__':
main()
|