File size: 3,167 Bytes
6bf7ea7
 
 
 
 
 
 
 
 
 
 
 
00ae7fd
6bf7ea7
 
 
 
 
 
00ae7fd
6bf7ea7
 
 
 
 
 
00ae7fd
 
6bf7ea7
 
00ae7fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bf7ea7
 
 
 
 
 
00ae7fd
6bf7ea7
 
 
00ae7fd
 
 
 
 
 
 
6bf7ea7
 
 
 
 
 
00ae7fd
 
6bf7ea7
 
 
00ae7fd
6bf7ea7
 
 
 
 
 
 
00ae7fd
6bf7ea7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
00ae7fd
6bf7ea7
 
 
 
 
 
 
 
 
 
00ae7fd
 
 
 
6bf7ea7
 
 
 
 
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
import gradio as gr

# -------------- Data Structures --------------

Inventory = [
    (1, "Apples", 250),
    (2, "Cherry", 650),
    (3, "Chickoo", 50),
    (4, "Grapes", 90),
    (5, "Mangoes", 150),
]

# make lookup by ID
inventory_dict = {
    item_id: {"name": name, "price": price}
    for item_id, name, price in Inventory
}

def calculate_total(cart):
    return sum(entry["quantity"] * entry["unit_price"] for entry in cart)


# -------------- Cart Operations --------------

def add_to_cart(selection, cart):
    """
    - selection: string like "3 - Chickoo ($50)"
    - cart: list of dicts carried in gr.State
    """
    item_id = int(selection.split(" - ")[0])
    item_info = inventory_dict[item_id]
    # see if it’s already in cart
    for entry in cart:
        if entry["id"] == item_id:
            entry["quantity"] += 1
            break
    else:
        cart.append({
            "id": item_id,
            "name": item_info["name"],
            "unit_price": item_info["price"],
            "quantity": 1
        })

    # build table for display
    table = []
    for idx, e in enumerate(cart):
        line_total = e["quantity"] * e["unit_price"]
        table.append([idx + 1, e["name"], e["quantity"], e["unit_price"], line_total])

    total = calculate_total(cart)
    return cart, table, f"${total:.2f}"


def remove_from_cart(idx, cart):
    """
    Remove entire line by its displayed index.
    """
    i = int(idx) - 1
    if 0 <= i < len(cart):
        cart.pop(i)

    table = []
    for j, e in enumerate(cart):
        line_total = e["quantity"] * e["unit_price"]
        table.append([j + 1, e["name"], e["quantity"], e["unit_price"], line_total])

    total = calculate_total(cart)
    return cart, table, f"${total:.2f}"


# -------------- Gradio UI --------------

with gr.Blocks(title="Shopping Cart with Aggregation") as demo:
    gr.Markdown("## 🛒 Shopping Cart (Aggregated)")

    with gr.Row():
        product_dd = gr.Dropdown(
            choices=[f"{i} - {n} (${p})" for i, n, p in Inventory],
            label="Select Product to Add"
        )
        add_btn = gr.Button("Add to Cart")

    cart_state = gr.State([])

    cart_display = gr.Dataframe(
        headers=["#", "Name", "Quantity", "Unit Price", "Line Total"],
        interactive=False,
        label="Your Cart"
    )

    total_box = gr.Textbox(value="$0.00", label="Total", interactive=False)

    add_btn.click(
        fn=add_to_cart,
        inputs=[product_dd, cart_state],
        outputs=[cart_state, cart_display, total_box]
    )

    gr.Markdown("---")

    with gr.Row():
        remove_idx = gr.Number(value=1, label="Remove Line #", precision=0)
        remove_btn = gr.Button("Remove from Cart")

    remove_btn.click(
        fn=remove_from_cart,
        inputs=[remove_idx, cart_state],
        outputs=[cart_state, cart_display, total_box]
    )

    gr.Markdown(
        """
        **Usage**  
        1. **Add to Cart**: duplicates increase quantity.  
        2. **Remove Line #**: deletes that product entirely.  
        3. **Total** auto-recalculates.
        """
    )

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