0Learn commited on
Commit
69b23f1
·
verified ·
1 Parent(s): 559adf5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -151
app.py CHANGED
@@ -1,157 +1,31 @@
1
- import gradio as gr
2
- import math
3
- import re
4
- from fastapi import FastAPI, HTTPException
5
- from pydantic import BaseModel, field_validator
6
-
 
 
7
  app = FastAPI()
8
 
9
- ALLOWED_FUNCTIONS = {'sin', 'cos', 'tan', 'log', 'ln', 'sqrt', 'abs', 'pow'}
10
- ALLOWED_CONSTANTS = {'pi', 'e'}
11
-
12
- class Expression(BaseModel):
13
- expr: str
14
-
15
- @field_validator('expr')
16
- @classmethod
17
- def validate_expression(cls, v: str) -> str:
18
- if not v:
19
- raise ValueError("Expression cannot be empty")
20
-
21
- # Check for invalid characters
22
- invalid_chars = re.findall(r'[^\d\s\+\-\*/\(\)\^\.\w]', v)
23
- if invalid_chars:
24
- raise ValueError(f"Invalid characters found: {', '.join(invalid_chars)}")
25
-
26
- # Check for invalid function names or constants
27
- tokens = re.findall(r'\b[a-zA-Z_]\w*\b', v)
28
- invalid_tokens = [token for token in tokens if token not in ALLOWED_FUNCTIONS and token not in ALLOWED_CONSTANTS]
29
- if invalid_tokens:
30
- raise ValueError(f"Invalid function or constant names: {', '.join(invalid_tokens)}")
31
-
32
- return v
33
-
34
- @app.post("/calculate")
35
- async def calculate_api(expression: Expression):
36
- try:
37
- result = evaluate_expression(expression.expr)
38
- return {"result": result}
39
- except ValueError as e:
40
- raise HTTPException(status_code=400, detail=str(e))
41
- except Exception as e:
42
- raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
43
-
44
- def evaluate_expression(expr: str) -> float:
45
- safe_dict = {
46
- 'sin': math.sin, 'cos': math.cos, 'tan': math.tan,
47
- 'log': math.log10, 'ln': math.log, 'sqrt': math.sqrt,
48
- 'pi': math.pi, 'e': math.e,
49
- 'abs': abs, 'pow': pow
50
- }
51
- try:
52
- # Replace '^' with '**' for exponentiation
53
- expr = expr.replace('^', '**')
54
- return eval(expr, {"__builtins__": None}, safe_dict)
55
- except ZeroDivisionError:
56
- raise ValueError("Division by zero is not allowed")
57
- except ValueError as e:
58
- raise ValueError(f"Math domain error: {str(e)}")
59
- except Exception as e:
60
- raise ValueError(f"Invalid expression: {str(e)}")
61
-
62
- # Global variable to store calculation history
63
- history = []
64
-
65
- def calculate(expression):
66
- try:
67
- result = evaluate_expression(expression)
68
- result_str = f"{result:.8f}".rstrip('0').rstrip('.')
69
- global history
70
- history.append(f"{expression} = {result_str}")
71
- history = history[-5:]
72
- return "0", result_str, "\n".join(reversed(history))
73
- except Exception as e:
74
- return expression, f"Error: {str(e)}", "\n".join(reversed(history))
75
-
76
- def update_expression(expression, value):
77
- if expression == "0" and value not in ['.', '(', ')']:
78
- return value
79
- if value in ['sin', 'cos', 'tan', 'log', 'ln', 'sqrt']:
80
- return expression + value + '('
81
- return expression + value
82
-
83
- def backspace(expression):
84
- return expression[:-1] if len(expression) > 1 else "0"
85
 
86
- def clear(expression):
87
- return "0"
88
 
89
- css = """
90
- .calculator-display { font-family: 'Digital-7', 'Courier New', monospace; font-size: 24px; }
91
- .calculator-result { font-family: 'Digital-7', 'Courier New', monospace; font-size: 72px; }
92
- .calculator-button { font-family: 'Arial', sans-serif; font-size: 18px; }
93
- .number-button { background-color: #e0e0e0; }
94
- .basic-op-button { background-color: #f0f0f0; }
95
- .advanced-op-button { background-color: #ffa500; }
96
- .calculator-box { border: 1px solid #ccc; padding: 10px; margin: 5px; border-radius: 5px; }
97
- """
98
 
99
- with gr.Blocks(css=css) as iface:
100
- gr.Markdown("# Scientific Calculator")
101
-
102
- with gr.Row():
103
- with gr.Column(scale=2):
104
- display = gr.Textbox(value="0", label="Display", elem_classes=["calculator-display"])
105
- with gr.Column(scale=1):
106
- result_display = gr.Textbox(value="", label="Result", elem_classes=["calculator-result"])
107
-
108
- with gr.Row():
109
- history_display = gr.Textbox(label="History (Last 5 Calculations)", lines=5)
110
-
111
- with gr.Row():
112
- with gr.Column(scale=2):
113
- with gr.Column(elem_classes=["calculator-box"]):
114
- # Number pad (3x4 grid)
115
- for i in range(3):
116
- with gr.Row():
117
- for j in range(3):
118
- num = str(7 - 3*i + j)
119
- gr.Button(num, elem_classes=["calculator-button", "number-button"]).click(
120
- lambda x, v=num: update_expression(x, v), inputs=display, outputs=display)
121
- with gr.Row():
122
- gr.Button("0", elem_classes=["calculator-button", "number-button"]).click(
123
- lambda x: update_expression(x, "0"), inputs=display, outputs=display)
124
- gr.Button(".", elem_classes=["calculator-button", "number-button"]).click(
125
- lambda x: update_expression(x, "."), inputs=display, outputs=display)
126
- gr.Button("=", elem_classes=["calculator-button", "basic-op-button"]).click(
127
- calculate, inputs=display, outputs=[display, result_display, history_display])
128
-
129
- with gr.Column(scale=1):
130
- with gr.Column(elem_classes=["calculator-box"]):
131
- # Basic operations
132
- for op, symbol in [("add", "+"), ("sub", "-"), ("mul", "*"), ("div", "/")]:
133
- gr.Button(symbol, elem_classes=["calculator-button", "basic-op-button"]).click(
134
- lambda x, v=symbol: update_expression(x, v), inputs=display, outputs=display)
135
- gr.Button("(", elem_classes=["calculator-button", "basic-op-button"]).click(
136
- lambda x: update_expression(x, "("), inputs=display, outputs=display)
137
- gr.Button(")", elem_classes=["calculator-button", "basic-op-button"]).click(
138
- lambda x: update_expression(x, ")"), inputs=display, outputs=display)
139
- gr.Button("C", elem_classes=["calculator-button", "basic-op-button"]).click(
140
- clear, inputs=display, outputs=display)
141
- gr.Button("⌫", elem_classes=["calculator-button", "basic-op-button"]).click(
142
- backspace, inputs=display, outputs=display)
143
-
144
- with gr.Column(scale=1):
145
- with gr.Column(elem_classes=["calculator-box"]):
146
- # Advanced operations
147
- for func in ["sin", "cos", "tan", "log", "ln", "sqrt"]:
148
- gr.Button(func, elem_classes=["calculator-button", "advanced-op-button"]).click(
149
- lambda x, v=func: update_expression(x, v), inputs=display, outputs=display)
150
- gr.Button("^", elem_classes=["calculator-button", "advanced-op-button"]).click(
151
- lambda x: update_expression(x, "^"), inputs=display, outputs=display)
152
- gr.Button("π", elem_classes=["calculator-button", "advanced-op-button"]).click(
153
- lambda x: update_expression(x, "pi"), inputs=display, outputs=display)
154
- gr.Button("e", elem_classes=["calculator-button", "advanced-op-button"]).click(
155
- lambda x: update_expression(x, "e"), inputs=display, outputs=display)
156
 
157
- iface.launch()
 
 
 
1
+ import uvicorn
2
+ from fastapi import FastAPI
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from backend import app as backend_app
5
+ from frontend import create_interface
6
+ import threading
7
+
8
+ # Create the main FastAPI app
9
  app = FastAPI()
10
 
11
+ # Add CORS middleware
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ # Include the backend routes
21
+ app.include_router(backend_app)
22
 
23
+ # Create the Gradio interface
24
+ iface = create_interface()
 
 
 
 
 
 
 
25
 
26
+ # Mount the Gradio app
27
+ app = gr.mount_gradio_app(app, iface, path="/")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ if __name__ == "__main__":
30
+ # Run the FastAPI server
31
+ uvicorn.run(app, host="0.0.0.0", port=7860)