File size: 4,709 Bytes
c63af23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import gradio as gr

MAX_QUEUE = 10

def _normalize_name(name: str) -> str:
    return (name or "").strip()

def _parse_age(age_text: str):
    age_text = (age_text or "").strip()
    if not age_text:
        return None, "Please enter an age."
    try:
        age = int(age_text)
    except ValueError:
        return None, "Age must be a whole number."
    if age < 0 or age > 130:
        return None, "Please enter a realistic age (0–130)."
    return age, None

def _sorted_queue(queue):
    # Oldest first; ties broken by entry order (seq)
    return sorted(queue, key=lambda x: (-x["age"], x["seq"]))

def _render(queue):
    if not queue:
        return "Queue is empty."
    q_sorted = _sorted_queue(queue)

    lines = ["### Smart Queue (Oldest First)"]
    for idx, item in enumerate(q_sorted, start=1):
        lines.append(f"**#{idx}** β€” {item['name']} (Age {item['age']})")
    lines.append("")
    lines.append(f"Slots used: **{len(queue)}/{MAX_QUEUE}**")
    lines.append("Rule: **Oldest first**; if ages tie, **earlier signup first**.")
    return "\n\n".join(lines)

def add_to_queue(name, age_text, queue_state, seq_state):
    queue_state = queue_state or []
    seq_state = int(seq_state or 1)

    if len(queue_state) >= MAX_QUEUE:
        return queue_state, seq_state, _render(queue_state), f"❌ Queue is full (max {MAX_QUEUE}). Please reset or serve next.", gr.update(), gr.update()

    name = _normalize_name(name)
    if not name:
        return queue_state, seq_state, _render(queue_state), "❌ Please enter a name.", gr.update(), gr.update()

    age, err = _parse_age(age_text)
    if err:
        return queue_state, seq_state, _render(queue_state), f"❌ {err}", gr.update(), gr.update()

    queue_state.append({"name": name, "age": age, "seq": seq_state})
    seq_state += 1

    # After adding, show their *current* position in the sorted queue
    q_sorted = _sorted_queue(queue_state)
    position = next(i for i, p in enumerate(q_sorted, start=1) if p["name"] == name and p["age"] == age and p["seq"] == seq_state - 1)

    msg = f"βœ… Added **{name}** (Age {age}). Current queue position: **#{position}** (oldest-first ordering)."
    return queue_state, seq_state, _render(queue_state), msg, gr.update(value=""), gr.update(value="")

def serve_next(queue_state):
    queue_state = queue_state or []
    if not queue_state:
        return queue_state, _render(queue_state), "Queue is empty. Nothing to serve."

    q_sorted = _sorted_queue(queue_state)
    next_person = q_sorted[0]

    # Remove by unique seq
    queue_state = [p for p in queue_state if p["seq"] != next_person["seq"]]
    msg = f"➑️ Served: **{next_person['name']}** (Age {next_person['age']})."
    return queue_state, _render(queue_state), msg

def reset_queue():
    queue_state = []
    seq_state = 1
    return queue_state, seq_state, _render(queue_state), "πŸ”„ Queue reset. You can add up to 10 people.", gr.update(value=""), gr.update(value="")

with gr.Blocks(title="Smart Queue (Oldest First)") as demo:
    gr.Markdown(
        "# πŸ‘₯ Smart Queue (Oldest First)\n"
        "Enter **name** and **age**. The queue is ordered by **oldest first**.\n"
        "If ages are the same, the earlier signup comes first.\n"
        "**Maximum 10 people**."
    )

    queue_state = gr.State([])
    seq_state = gr.State(1)  # internal counter to preserve signup order

    with gr.Row():
        name_in = gr.Textbox(label="Name", placeholder="e.g., Anna")
        age_in = gr.Textbox(label="Age", placeholder="e.g., 29")

    with gr.Row():
        add_btn = gr.Button("Join Queue", variant="primary")
        serve_btn = gr.Button("Serve Next")
        reset_btn = gr.Button("Reset Queue")

    status = gr.Markdown("Ready.")
    queue_view = gr.Markdown(_render([]))

    add_btn.click(
        add_to_queue,
        inputs=[name_in, age_in, queue_state, seq_state],
        outputs=[queue_state, seq_state, queue_view, status, name_in, age_in],
    )

    # Enter key on either field submits
    name_in.submit(
        add_to_queue,
        inputs=[name_in, age_in, queue_state, seq_state],
        outputs=[queue_state, seq_state, queue_view, status, name_in, age_in],
    )
    age_in.submit(
        add_to_queue,
        inputs=[name_in, age_in, queue_state, seq_state],
        outputs=[queue_state, seq_state, queue_view, status, name_in, age_in],
    )

    serve_btn.click(
        serve_next,
        inputs=[queue_state],
        outputs=[queue_state, queue_view, status],
    )

    reset_btn.click(
        reset_queue,
        inputs=[],
        outputs=[queue_state, seq_state, queue_view, status, name_in, age_in],
    )

if __name__ == "__main__":
    demo.launch()