File size: 3,949 Bytes
cdf2807 40ca158 aa3525b e22be08 40ca158 a3de3da 40ca158 cdf2807 40ca158 aa3525b cdf2807 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b af26c90 40ca158 af26c90 40ca158 aa3525b 40ca158 aa3525b 40ca158 aa3525b cdf2807 eb59eaa aa3525b |
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 |
import pandas as pd
import gradio as gr
# 7-Day Schedule Converter with explicit iteration and header fill
def convert_schedule(file_path, direction):
# 1. Load Excel sheet into DataFrame
# Read without header to inspect first two rows for header fill
raw = pd.read_excel(file_path, header=None)
# Extract potential header rows (skip first column)
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
# Load actual data with 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]
# 2. Ensure we have exactly the original 7 day columns
day_cols = list(df.columns)
# 3. Build mapping: for each Model (or Texter) assign days
assignments = {}
if direction == 'A to B':
# Rows are Models → output rows are Texters
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)
# Build output DataFrame
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:
# Rows are Texters → output rows are Models
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'
# 4. Cleanup axis names
result.index.name = None
result.columns.name = None
return result
# Gradio UI
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'),
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. Uses explicit iteration.'),
allow_flagging='never'
)
iface.launch(server_name='0.0.0.0', server_port=7860)
if __name__ == '__main__':
main()
|