File size: 3,726 Bytes
a0f06fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# app.py
"""Simple Unit Converter (Gradio) for Hugging Face Spaces.
- Put this file at the repo root as `app.py` (Spaces uses this as the entry point).
- Minimal dependencies: gradio only.
"""

import gradio as gr

# --- Unit factors to a base unit ---
UNITS = {
    "Mass": {
        "kg": 1.0,
        "g": 0.001,
        "lb (pound)": 0.45359237,
        "oz (ounce)": 0.028349523125
    },
    "Length": {
        "m": 1.0,
        "cm": 0.01,
        "mm": 0.001,
        "ft (foot)": 0.3048,
        "in (inch)": 0.0254
    },
    "Volume": {
        "L (liter)": 1.0,
        "mL (milliliter)": 0.001,
        "US gallon": 3.785411784,
        "US quart": 0.946352946
    },
    # Temperature handled with formulas instead of factors
    "Temperature": ["C", "F", "K"]
}

def update_units(category):
    """Update From/To dropdowns when Category changes."""
    if category == "Temperature":
        choices = UNITS["Temperature"]
    else:
        choices = list(UNITS[category].keys())
    from_default = choices[0]
    to_default = choices[1] if len(choices) > 1 else choices[0]
    return gr.update(choices=choices, value=from_default), gr.update(choices=choices, value=to_default)

def convert(value, category, from_unit, to_unit, precision):
    """Convert `value` from `from_unit` to `to_unit` inside `category`."""
    # Input validation
    try:
        val = float(value)
    except Exception:
        return "❗ Enter a valid number."

    # quick return if same unit
    if from_unit == to_unit:
        fmt = f"{{:.{precision}f}}"
        return f"{fmt.format(val)} {from_unit} = {fmt.format(val)} {to_unit}"

    # Temperature conversions (Celsius as intermediate)
    if category == "Temperature":
        # to Celsius
        if from_unit == "C":
            c = val
        elif from_unit == "F":
            c = (val - 32) * 5.0 / 9.0
        elif from_unit == "K":
            c = val - 273.15
        else:
            return "❗ Unknown temperature unit."

        # from Celsius to target
        if to_unit == "C":
            res = c
        elif to_unit == "F":
            res = c * 9.0 / 5.0 + 32
        elif to_unit == "K":
            res = c + 273.15
        else:
            return "❗ Unknown temperature unit."
    else:
        # factor-based conversion: value -> base -> target
        factors = UNITS[category]
        try:
            f_from = factors[from_unit]
            f_to = factors[to_unit]
        except KeyError:
            return "❗ Unknown unit for selected category."
        value_in_base = val * f_from
        res = value_in_base / f_to

    fmt = f"{{:.{precision}f}}"
    return f"{fmt.format(val)} {from_unit} = {fmt.format(res)} {to_unit}"

# --- Build Gradio UI ---
with gr.Blocks() as demo:
    gr.Markdown("## πŸ” Simple Unit Converter\nChoose category, units, value, then press Convert.")
    with gr.Row():
        category_dd = gr.Dropdown(choices=list(UNITS.keys()), value="Mass", label="Category")
        precision = gr.Slider(minimum=0, maximum=6, step=1, value=4, label="Decimals")
    with gr.Row():
        from_dd = gr.Dropdown(choices=list(UNITS["Mass"].keys()), value="kg", label="From unit")
        to_dd = gr.Dropdown(choices=list(UNITS["Mass"].keys()), value="g", label="To unit")
    value_in = gr.Number(value=1.0, label="Value to convert")
    convert_btn = gr.Button("Convert")
    output_txt = gr.Textbox(label="Result", interactive=False)

    # callbacks
    category_dd.change(fn=update_units, inputs=category_dd, outputs=[from_dd, to_dd])
    convert_btn.click(fn=convert, inputs=[value_in, category_dd, from_dd, to_dd, precision], outputs=output_txt)

# Entry point for Spaces
if __name__ == "__main__":
    demo.launch()