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()