File size: 4,512 Bytes
7a85164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import gradio as gr

# ---------- Inventory (ID, Name, Price) ----------
INVENTORY = [
    (101, "Hammer", 120),
    (102, "Screwdriver Set", 350),
    (103, "Drill Machine", 2500),
    (104, "Pliers", 180),
    (105, "Wrench", 220),
]

# Helpers for lookup and display
ID_TO_ITEM = {str(i): (i, name, price) for i, name, price in INVENTORY}

def format_inventory_option(t):
    i, name, price = t
    return f"{i}{name} (${price})"

INVENTORY_OPTIONS = [(str(i), format_inventory_option((i, n, p))) for i, n, p in INVENTORY]

def cart_to_text(cart):
    if not cart:
        return "Cart is empty."
    lines = []
    for i, name, price in cart:
        lines.append(f"{i}{name}: ${price}")
    subtotal = sum(p for _, _, p in cart)
    lines.append("-" * 28)
    lines.append(f"Items: {len(cart)}   Subtotal: ${subtotal}")
    return "\n".join(lines)

def cart_remove_choices(cart):
    # return (values, labels) pairs for the remove dropdown
    values = []
    labels = []
    for idx, (i, name, price) in enumerate(cart):
        # value is cart index (as str) so we can remove the specific occurrence
        values.append(str(idx))
        labels.append(f"{i}{name} (${price})")
    return values, labels

# ---------- Actions ----------
def add_to_cart(add_id, cart):
    cart = list(cart or [])
    if add_id and add_id in ID_TO_ITEM:
        cart.append(ID_TO_ITEM[add_id])
        msg = "Item added."
    else:
        msg = "Select an item to add."

    remove_vals, remove_labels = cart_remove_choices(cart)
    return (
        cart,                                 # state
        cart_to_text(cart),                   # cart display
        gr.Dropdown(choices=list(zip(remove_labels, remove_vals))),  # update remove dropdown
        msg                                   # info message
    )

def remove_from_cart(remove_index, cart):
    cart = list(cart or [])
    if remove_index is None or remove_index == "":
        msg = "Select an item to remove."
    else:
        idx = int(remove_index)
        if 0 <= idx < len(cart):
            removed = cart.pop(idx)
            msg = f"Removed: {removed[1]}."
        else:
            msg = "Invalid selection."

    remove_vals, remove_labels = cart_remove_choices(cart)
    return (
        cart,
        cart_to_text(cart),
        gr.Dropdown(choices=list(zip(remove_labels, remove_vals))),
        msg
    )

def calculate_total(cart):
    cart = list(cart or [])
    total = sum(p for _, _, p in cart)
    return f"${total}"

def clear_cart(_btn, cart):
    cart = []
    remove_vals, remove_labels = cart_remove_choices(cart)
    return (
        cart,
        cart_to_text(cart),
        gr.Dropdown(choices=list(zip(remove_labels, remove_vals))),
        "Cart cleared.",
        "$0"
    )

# ---------- UI ----------
with gr.Blocks(theme="soft") as demo:
    gr.Markdown("# Hardware Store Billing\nAdd / remove tools and calculate the total.")

    cart_state = gr.State([])  # list of tuples (id, name, price)

    with gr.Row():
        add_dd = gr.Dropdown(
            choices=[(label, value) for value, label in INVENTORY_OPTIONS],
            label="Select tool to ADD to cart",
            value=None,
            allow_custom_value=False,
        )
        remove_dd = gr.Dropdown(
            choices=[],
            label="Select tool in cart to REMOVE",
            value=None,
            allow_custom_value=False,
        )

    with gr.Row():
        add_btn = gr.Button("Add Tool", variant="primary")
        remove_btn = gr.Button("Remove Tool", variant="secondary")
        clear_btn = gr.Button("Clear Cart")

    cart_box = gr.Textbox(label="Cart", value="Cart is empty.", lines=10)
    info = gr.Markdown("")  # action feedback

    with gr.Row():
        calc_btn = gr.Button("Calculate Total", variant="primary")
        total_out = gr.Textbox(label="Total", value="$0")

    # Wire events
    add_btn.click(
        add_to_cart,
        inputs=[add_dd, cart_state],
        outputs=[cart_state, cart_box, remove_dd, info],
    )

    remove_btn.click(
        remove_from_cart,
        inputs=[remove_dd, cart_state],
        outputs=[cart_state, cart_box, remove_dd, info],
    )

    clear_btn.click(
        clear_cart,
        inputs=[clear_btn, cart_state],
        outputs=[cart_state, cart_box, remove_dd, info, total_out],
    )

    calc_btn.click(
        calculate_total,
        inputs=[cart_state],
        outputs=[total_out],
    )

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