CA-Cp / app_improved.py
Kshitij2604's picture
Update app_improved.py
cdb1307 verified
# app_improved.py — Redesigned UI
import io
import os
import json
import tempfile
import pandas as pd
# Compatibility shim for huggingface_hub
try:
import huggingface_hub as _hf
except Exception:
_hf = None
if _hf is not None:
if not hasattr(_hf, "HfFolder"):
class _HfFolder:
@staticmethod
def path(*args, **kwargs):
return None
_hf.HfFolder = _HfFolder
if not hasattr(_hf, "whoami"):
def _whoami(token=None):
return {}
_hf.whoami = _whoami
import gradio as gr
from solver import (
generate_random_instance,
solve_vrp_tw,
plot_solution,
parse_uploaded_csv,
make_template_dataframe,
)
# ---------- Design notes
# Goals:
# - Sidebar controls (compact) and large visualization area
# - Clear download buttons and readable metrics
# - Presets + small help text
TITLE = "Ride-Sharing Optimizer"
FOOTER = "Gradio UI — improved layout"
CUSTOM_CSS = r"""
:root{--bg:#0b1220;--panel:#0f1724;--muted:#94a3b8;--accent:#7c3aed}
body{background:linear-gradient(180deg,#061022 0%, var(--bg) 100%);color:#e6eef8}
.gradio-container{padding:18px}
.sidebar{background:var(--panel);padding:14px;border-radius:10px}
.brand{font-weight:700;font-size:18px;color:var(--accent)}
.small{color:var(--muted);font-size:13px}
.controls .gr-button{width:100%}
.metrics{background:rgba(255,255,255,0.02);padding:10px;border-radius:8px}
.table-wrap{max-height:280px;overflow:auto}
"""
# ---------- helpers
def format_metrics(metrics):
if not metrics:
return "No metrics available"
lines = [f"**Vehicles used:** {metrics.get('vehicles_used',0)} ",
f"**Capacity:** {metrics.get('capacity',0)} ",
f"**Total distance:** {metrics.get('total_distance',0):.2f}
"]
per = metrics.get('per_route_distance', [])
if per:
lines.append("**Per-route distances:**
")
for i, d in enumerate(per, 1):
load = metrics.get('per_route_load', [])[i-1] if metrics.get('per_route_load') else "-"
lines.append(f"- Route {i}: {d:.2f} (load {load}) ")
tw = metrics.get('time_window_report', {})
if tw:
lines.append('
**Time windows** ')
lines.append(f"- lateness count: {tw.get('total_lateness_count',0)} ")
lines.append(f"- total lateness: {tw.get('total_lateness',0):.2f} ")
lines.append(f"- status: {tw.get('status','-')} ")
return "
".join(lines)
# Safe file writer
def _write_df_to_temp(df):
tf = tempfile.NamedTemporaryFile(delete=False, suffix='.csv')
df.to_csv(tf.name, index=False)
tf.flush(); tf.close()
return tf.name
# ---------- core app functions (return types compatible with Gradio)
def run_generate(n_clients, n_vehicles, capacity, spread, demand_min, demand_max, seed, speed, preset):
# presets tweak spread / capacities
if preset == 'City (dense)':
spread = max(20, spread/2)
elif preset == 'Suburban':
spread = max(80, spread*1.5)
df = generate_random_instance(
n_clients=int(n_clients),
n_vehicles=int(n_vehicles),
capacity=int(capacity),
spread=float(spread),
demand_min=int(demand_min),
demand_max=int(demand_max),
seed=int(seed),
)
sol = solve_vrp_tw(df, depot=(0,0), n_vehicles=int(n_vehicles), capacity=int(capacity), speed=float(speed))
img = plot_solution(df, sol, depot=(0,0))
csv_path = _write_df_to_temp(sol['assignments_table'])
metrics_md = format_metrics(sol.get('metrics', {}))
return img, sol['assignments_table'], metrics_md, csv_path
def run_upload(file, n_vehicles, capacity, speed):
if file is None:
raise gr.Error('Please upload a CSV')
# Gradio's File returns a tempfile-like object with .name
df = parse_uploaded_csv(file.name if hasattr(file, 'name') else file)
sol = solve_vrp_tw(df, depot=(0,0), n_vehicles=int(n_vehicles), capacity=int(capacity), speed=float(speed))
img = plot_solution(df, sol, depot=(0,0))
csv_path = _write_df_to_temp(sol['assignments_table'])
metrics_md = format_metrics(sol.get('metrics', {}))
return img, sol['assignments_table'], metrics_md, csv_path
def download_template():
df = make_template_dataframe()
return _write_df_to_temp(df)
# ---------- UI
with gr.Blocks(title=TITLE, css=CUSTOM_CSS) as demo:
with gr.Row():
with gr.Column(scale=1):
with gr.Box(elem_classes='sidebar'):
gr.Markdown(f"<div class='brand'>{TITLE}</div>")
gr.Markdown("<div class='small'>Quickly generate scenarios or upload your data. Use presets for common patterns.</div>")
with gr.TabbedInterface():
with gr.Tab('Generate'):
preset = gr.Dropdown(['Default','City (dense)','Suburban'], value='Default', label='Preset')
n_clients = gr.Slider(5, 200, value=30, step=1, label='Clients')
n_vehicles = gr.Slider(1, 50, value=5, step=1, label='Vehicles')
capacity = gr.Slider(1, 100, value=10, step=1, label='Capacity')
spread = gr.Slider(10, 500, value=60, step=5, label='Spread')
demand_min = gr.Slider(1, 5, value=1, step=1, label='Demand min')
demand_max = gr.Slider(1, 10, value=3, step=1, label='Demand max')
seed = gr.Number(value=42, label='Seed')
speed = gr.Number(value=10.0, label='Vehicle speed')
gen_btn = gr.Button('Generate & Solve')
gen_dl = gr.File(label='Download last assignments')
with gr.Tab('Upload'):
upload_file = gr.File(label='Upload CSV (id,x,y,demand,tw_start,tw_end,service)')
up_vehicles = gr.Slider(1, 100, value=5, step=1, label='Vehicles')
up_capacity = gr.Slider(1, 200, value=15, step=1, label='Capacity')
up_speed = gr.Number(value=10.0, label='Vehicle speed')
up_btn = gr.Button('Optimize uploaded CSV')
tmpl_btn = gr.Button('Download template CSV')
up_dl = gr.File(label='Download assignments')
gr.Markdown('---')
gr.Markdown('*Tip: click a run button, then download CSV from the right panel.*', elem_classes='small')
with gr.Column(scale=2):
with gr.Box():
out_img = gr.Image(type='pil', label='Route map')
with gr.Row():
with gr.Column():
out_table = gr.Dataframe(headers=None, label='Assignments (table)', interactive=False)
with gr.Column(min_width=300):
out_metrics = gr.Markdown('No results yet', label='Metrics', elem_classes='metrics')
out_csv = gr.File(label='Download CSV')
gr.Markdown(f"---
{FOOTER}")
gen_btn.click(
fn=run_generate,
inputs=[n_clients, n_vehicles, capacity, spread, demand_min, demand_max, seed, speed, preset],
outputs=[out_img, out_table, out_metrics, gen_dl],
)
up_btn.click(
fn=run_upload,
inputs=[upload_file, up_vehicles, up_capacity, up_speed],
outputs=[out_img, out_table, out_metrics, up_dl],
)
tmpl_btn.click(fn=download_template, inputs=[], outputs=[up_dl])
if __name__ == '__main__':
demo.launch()