kreemyyyy commited on
Commit
aa3525b
·
verified ·
1 Parent(s): cf08e9a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -47
app.py CHANGED
@@ -1,68 +1,92 @@
1
  import pandas as pd
2
  import gradio as gr
3
 
4
- # Pivot between Model↔Texter schedules (7-day weekly format), handling merged headers
 
 
5
  def convert_schedule(file_path, direction):
6
- # 1. Try reading with two header rows for merged timeslot/day layouts
7
  try:
8
  df = pd.read_excel(file_path, header=[0,1], index_col=0)
9
- # Extract the second-level headers (actual days)
10
- second_level = df.columns.get_level_values(1).astype(str)
11
- # If these are all unnamed, fallback
12
- if all(lbl.startswith('Unnamed') for lbl in second_level):
13
  raise ValueError
14
- df.columns = second_level
15
  except Exception:
16
- # Fallback: single header row, simple day labels
17
  df = pd.read_excel(file_path, header=0, index_col=0)
18
  df.columns = df.columns.astype(str)
19
 
20
- # 2. Drop any 'Unnamed' or blank header columns
21
- df = df.loc[:, ~df.columns.str.match(r'^Unnamed')]
22
-
23
- # 3. Determine id/val columns
24
- if direction == 'A to B':
25
- id_col, val_col = 'Model', 'Texter'
26
- else:
27
- id_col, val_col = 'Texter', 'Model'
28
 
29
- # 4. Melt into long format
30
- df_reset = df.reset_index().rename(columns={df.index.name or df.columns.name or '': id_col})
31
- df_melt = df_reset.melt(id_vars=[id_col], var_name='Day', value_name=val_col)
32
- df_melt = df_melt.dropna(subset=[val_col])
33
 
34
- # 5. Pivot table: join duplicates with comma
35
- pivot = df_melt.pivot_table(
36
- index=val_col,
37
- columns='Day',
38
- values=id_col,
39
- aggfunc=lambda x: ', '.join(map(str, x))
40
- )
41
- pivot = pivot.fillna('')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- # 6. Reorder columns to match original
44
- result = pivot.reindex(columns=df.columns.tolist(), fill_value='')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
- # Cleanup axis names
47
  result.index.name = None
48
  result.columns.name = None
49
  return result
50
 
51
- # Build Gradio app
52
- iface = gr.Interface(
53
- fn=convert_schedule,
54
- inputs=[
55
- gr.File(label='Upload Weekly Schedule (.xlsx)', file_count='single', type='filepath'),
56
- gr.Radio(['A to B', 'B to A'], label='Convert Direction')
57
- ],
58
- outputs=gr.Dataframe(label='Converted Schedule'),
59
- title='7-Day Schedule Pivot',
60
- description=(
61
- 'Upload a 7-column weekly schedule (Models vs Days), then flip between '
62
- 'Models→Texters or Texters→Models. Maintains original days order, even with merged headers.'
63
- ),
64
- allow_flagging='never'
65
- )
66
 
67
  if __name__ == '__main__':
68
- iface.launch(server_name='0.0.0.0', server_port=7860)
 
1
  import pandas as pd
2
  import gradio as gr
3
 
4
+ # Conversion by explicit iteration: map texters models per day
5
+ # Handles merged headers, multi-row headers, and 'OFF' days
6
+
7
  def convert_schedule(file_path, direction):
8
+ # -- 1. Load Excel with potential two-row header for merged cells --
9
  try:
10
  df = pd.read_excel(file_path, header=[0,1], index_col=0)
11
+ # Use second header row as actual day labels
12
+ days = df.columns.get_level_values(1).astype(str)
13
+ # If all are unnamed, treat as single-header
14
+ if all(lbl.startswith('Unnamed') for lbl in days):
15
  raise ValueError
16
+ df.columns = days
17
  except Exception:
 
18
  df = pd.read_excel(file_path, header=0, index_col=0)
19
  df.columns = df.columns.astype(str)
20
 
21
+ # -- 2. Clean up: drop any phantom 'Unnamed' columns --
22
+ df = df.loc[:, ~df.columns.str.match(r'^Unnamed')] # keep only real day columns
 
 
 
 
 
 
23
 
24
+ # Order of days as in the original sheet
25
+ day_cols = list(df.columns)
 
 
26
 
27
+ # -- 3. Build assignment mapping --
28
+ # For A→B: iterate models (rows), assign each texter
29
+ # For B→A: iterate texters (rows), assign each model
30
+ assignments = {}
31
+ if direction == 'A to B':
32
+ for model in df.index:
33
+ for day in day_cols:
34
+ texters = df.at[model, day]
35
+ # split if multiple names in one cell
36
+ for texter in str(texters).split(','):
37
+ texter = texter.strip()
38
+ if not texter or texter.lower() in ['nan', 'none']:
39
+ continue
40
+ if texter not in assignments:
41
+ # initialize all days as empty list
42
+ assignments[texter] = {d: [] for d in day_cols}
43
+ assignments[texter][day].append(str(model))
44
+ # After populating, convert lists to comma-joined or 'OFF'
45
+ index = sorted(assignments.keys())
46
+ result = pd.DataFrame(index=index, columns=day_cols)
47
+ for texter, days_map in assignments.items():
48
+ for day in day_cols:
49
+ models = days_map.get(day, [])
50
+ result.at[texter, day] = ', '.join(models) if models else 'OFF'
51
 
52
+ else: # B→A
53
+ for texter in df.index:
54
+ for day in day_cols:
55
+ models = df.at[texter, day]
56
+ for model in str(models).split(','):
57
+ model = model.strip()
58
+ if not model or model.lower() in ['nan', 'none']:
59
+ continue
60
+ if model not in assignments:
61
+ assignments[model] = {d: [] for d in day_cols}
62
+ assignments[model][day].append(str(texter))
63
+ index = sorted(assignments.keys())
64
+ result = pd.DataFrame(index=index, columns=day_cols)
65
+ for model, days_map in assignments.items():
66
+ for day in day_cols:
67
+ texters = days_map.get(day, [])
68
+ result.at[model, day] = ', '.join(texters) if texters else 'OFF'
69
 
70
+ # -- 4. Cleanup axis names --
71
  result.index.name = None
72
  result.columns.name = None
73
  return result
74
 
75
+ # -- Gradio UI definition --
76
+ def main():
77
+ iface = gr.Interface(
78
+ fn=convert_schedule,
79
+ inputs=[
80
+ gr.File(label='Upload Weekly Schedule (.xlsx)', file_count='single', type='filepath'),
81
+ gr.Radio(['A to B', 'B to A'], label='Conversion Direction')
82
+ ],
83
+ outputs=gr.Dataframe(label='Converted Schedule'),
84
+ title='7-Day Schedule Converter',
85
+ description=('Upload a 7-column weekly schedule (Models vs Days) and flip '
86
+ 'between Models→Texters or Texters→Models with explicit iteration.'),
87
+ allow_flagging='never'
88
+ )
89
+ iface.launch(server_name='0.0.0.0', server_port=7860)
90
 
91
  if __name__ == '__main__':
92
+ main()