Update app.py
Browse files
app.py
CHANGED
@@ -1,52 +1,65 @@
|
|
1 |
import pandas as pd
|
2 |
import gradio as gr
|
3 |
|
4 |
-
#
|
5 |
def convert_schedule(file_path, direction):
|
6 |
-
#
|
7 |
df = pd.read_excel(file_path, index_col=0)
|
|
|
|
|
|
|
8 |
|
9 |
-
#
|
10 |
-
|
11 |
-
if drop_cols:
|
12 |
-
df = df.drop(columns=drop_cols)
|
13 |
|
|
|
14 |
if direction == 'A to B':
|
15 |
-
#
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
pivot = df_melt.pivot_table(
|
20 |
-
index='Texter', columns='Header', values='Model', aggfunc='first'
|
21 |
-
)
|
22 |
-
result = pivot.reindex(columns=df.columns).fillna('')
|
23 |
else:
|
24 |
-
#
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
pivot = df_melt.pivot_table(
|
29 |
-
index='Model', columns='Header', values='Texter', aggfunc='first'
|
30 |
-
)
|
31 |
-
result = pivot.reindex(columns=df.columns).fillna('')
|
32 |
|
33 |
-
|
|
|
|
|
|
|
34 |
|
35 |
-
#
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
gr.Radio(['A to B', 'B to A'], label='Conversion Direction')
|
42 |
-
],
|
43 |
-
outputs=gr.Dataframe(label='Converted Schedule'),
|
44 |
-
title='Dynamic Schedule Converter',
|
45 |
-
description=('Upload an Excel file in Format A or B, '
|
46 |
-
'auto-clean blank/merged header rows, and convert between models-as-rows ↔ texters-as-rows.')
|
47 |
)
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
if __name__ == '__main__':
|
52 |
-
|
|
|
1 |
import pandas as pd
|
2 |
import gradio as gr
|
3 |
|
4 |
+
# Pivot between Model↔Texter schedules (7-day weekly format)
|
5 |
def convert_schedule(file_path, direction):
|
6 |
+
# 1. Load schedule: first column is index (Model or Texter), headers are days of the week
|
7 |
df = pd.read_excel(file_path, index_col=0)
|
8 |
+
# Ensure headers are strings and drop any 'Unnamed' placeholders
|
9 |
+
df.columns = df.columns.astype(str)
|
10 |
+
df = df.loc[:, ~df.columns.str.match(r'^Unnamed')]
|
11 |
|
12 |
+
# Determine the name of the index column after reset_index()
|
13 |
+
index_name = df.index.name or 'index'
|
|
|
|
|
14 |
|
15 |
+
# 2. Setup melting parameters based on direction
|
16 |
if direction == 'A to B':
|
17 |
+
# A-format: models in index, texters in cells → output: texters as rows, models as cell values
|
18 |
+
id_col = 'Model'
|
19 |
+
val_col = 'Texter'
|
20 |
+
df_reset = df.reset_index().rename(columns={index_name: id_col})
|
|
|
|
|
|
|
|
|
21 |
else:
|
22 |
+
# B-format: texters in index, models in cells → output: models as rows, texters as cell values
|
23 |
+
id_col = 'Texter'
|
24 |
+
val_col = 'Model'
|
25 |
+
df_reset = df.reset_index().rename(columns={index_name: id_col})
|
|
|
|
|
|
|
|
|
26 |
|
27 |
+
# 3. Melt into long form: [id_col, Day, val_col]
|
28 |
+
df_melt = df_reset.melt(id_vars=[id_col], var_name='Day', value_name=val_col)
|
29 |
+
# Drop empty assignments
|
30 |
+
df_melt = df_melt.dropna(subset=[val_col])
|
31 |
|
32 |
+
# 4. Pivot back to wide: index=val_col, columns=Day, values=id_col
|
33 |
+
pivot = df_melt.pivot_table(
|
34 |
+
index=val_col,
|
35 |
+
columns='Day',
|
36 |
+
values=id_col,
|
37 |
+
aggfunc='first'
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
)
|
39 |
+
|
40 |
+
# 5. Reorder columns to match original days order and fill empties
|
41 |
+
result = pivot.reindex(columns=df.columns.tolist(), fill_value='')
|
42 |
+
|
43 |
+
# Cleanup axis names for display
|
44 |
+
result.index.name = None
|
45 |
+
result.columns.name = None
|
46 |
+
return result
|
47 |
+
|
48 |
+
# Build Gradio app
|
49 |
+
iface = gr.Interface(
|
50 |
+
fn=convert_schedule,
|
51 |
+
inputs=[
|
52 |
+
gr.File(label='Upload Weekly Schedule (.xlsx)', file_count='single', type='filepath'),
|
53 |
+
gr.Radio(['A to B', 'B to A'], label='Convert Direction')
|
54 |
+
],
|
55 |
+
outputs=gr.Dataframe(label='Converted Schedule'),
|
56 |
+
title='7-Day Schedule Pivot',
|
57 |
+
description=(
|
58 |
+
'Upload a 7-column weekly schedule (Models vs Days), then flip between '
|
59 |
+
'Models→Texters or Texters→Models. Maintains original days order.'
|
60 |
+
),
|
61 |
+
allow_flagging='never'
|
62 |
+
)
|
63 |
|
64 |
if __name__ == '__main__':
|
65 |
+
iface.launch(server_name='0.0.0.0', server_port=7860)
|