KarthikGarlapati commited on
Commit
b357fbc
·
verified ·
1 Parent(s): e2548b0

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +213 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,215 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ import sympy as sp
5
+ from sympy.parsing.sympy_parser import parse_expr
6
+ from sympy.utilities.lambdify import lambdify
7
+ import io
8
+ import os
9
+ import base64
10
+ from datetime import datetime
11
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
12
+
13
+ # Create required directories
14
+ os.makedirs("uploads", exist_ok=True)
15
+
16
+ # Page config
17
+ st.set_page_config(page_title="Equation2Graph", page_icon="📈", layout="wide")
18
+
19
+ # Session state
20
+ if 'history' not in st.session_state:
21
+ st.session_state.history = []
22
+
23
+ # Initialize NLP model
24
+ @st.cache_resource
25
+ def load_nlp_model():
26
+ try:
27
+ tokenizer = AutoTokenizer.from_pretrained("t5-small")
28
+ model = AutoModelForSeq2SeqLM.from_pretrained("t5-small")
29
+ return tokenizer, model
30
+ except Exception as e:
31
+ st.warning(f"⚠ AI model could not be loaded: {str(e)}. Falling back to basic equation parsing.")
32
+ return None, None
33
+
34
+ # Load models
35
+ tokenizer, model = load_nlp_model()
36
+
37
+ def convert_nl_to_equation(nl_input):
38
+ """Convert natural language to equation using AI model or fallback to basic parsing"""
39
+ if tokenizer and model:
40
+ try:
41
+ inputs = tokenizer.encode(nl_input, return_tensors="pt", truncation=True)
42
+ outputs = model.generate(inputs, max_length=50)
43
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
44
+ except Exception as e:
45
+ st.error(f"Error in AI conversion: {str(e)}")
46
+ return basic_nl_to_equation(nl_input)
47
+ else:
48
+ return basic_nl_to_equation(nl_input)
49
+
50
+ def basic_nl_to_equation(text):
51
+ """Basic natural language to equation conversion"""
52
+ # Define basic math terms
53
+ terms = {
54
+ 'squared': '^2',
55
+ 'cubed': '^3',
56
+ 'plus': '+',
57
+ 'minus': '-',
58
+ 'times': '*',
59
+ 'multiply by': '*',
60
+ 'divided by': '/',
61
+ 'over': '/',
62
+ 'to the power of': '^',
63
+ 'sin of': 'sin(',
64
+ 'cos of': 'cos(',
65
+ 'tan of': 'tan(',
66
+ 'exponential of': 'exp(',
67
+ 'log of': 'log(',
68
+ 'absolute value of': 'abs('
69
+ }
70
+
71
+ # Normalize text
72
+ text = text.lower().strip()
73
+
74
+ # Replace terms
75
+ for term, symbol in terms.items():
76
+ text = text.replace(term, symbol)
77
+
78
+ # Clean up the equation
79
+ text = text.replace(' ', '')
80
+ if text.count('(') > text.count(')'):
81
+ text += ')' # Close any unclosed parentheses
82
+
83
+ # Remove any invalid characters
84
+ text = ''.join(c for c in text if c.isalnum() or c in '+-*/^().')
85
+ return text
86
+
87
+ def parse_and_validate_equation(equation_str):
88
+ try:
89
+ equation_str = equation_str.replace('^', '')
90
+ expr = parse_expr(equation_str)
91
+ x = sp.Symbol('x')
92
+ f = lambdify(x, expr, modules=['numpy'])
93
+ return f, expr
94
+ except Exception as e:
95
+ st.error(f"Error parsing equation: {str(e)}")
96
+ return None, None
97
+
98
+ def plot_equation(f, expr, x_range=(-10, 10), points=1000):
99
+ try:
100
+ fig, ax = plt.subplots(figsize=(10, 6))
101
+ x = np.linspace(x_range[0], x_range[1], points)
102
+ y = f(x)
103
+ ax.plot(x, y, '-b', label=str(expr))
104
+ ax.grid(True, alpha=0.3)
105
+ ax.axhline(y=0, color='k', linestyle='-', alpha=0.3)
106
+ ax.axvline(x=0, color='k', linestyle='-', alpha=0.3)
107
+ ax.set_xlabel('x')
108
+ ax.set_ylabel('y')
109
+ ax.set_title(f'Graph of {str(expr)}')
110
+ ax.legend()
111
+ return fig
112
+ except Exception as e:
113
+ st.error(f"Error plotting equation: {str(e)}")
114
+ return None
115
+
116
+ def get_download_link(fig):
117
+ buf = io.BytesIO()
118
+ fig.savefig(buf, format='png', bbox_inches='tight')
119
+ buf.seek(0)
120
+ b64 = base64.b64encode(buf.read()).decode()
121
+ return f'<a href="data:image/png;base64,{b64}" download="equation_plot.png">📥 Download Plot</a>'
122
+
123
+ # Header
124
+ st.title("📈 Equation2Graph")
125
+ st.markdown("Visualize mathematical equations instantly, from symbolic or natural language input!")
126
+
127
+ # Columns
128
+ col1, col2 = st.columns([2, 1])
129
+
130
+ with col1:
131
+ # Natural language input
132
+ st.subheader("🗣 Describe your equation (optional)")
133
+ nl_input = st.text_input(
134
+ "Enter your equation in plain English:",
135
+ placeholder="e.g., the square of x plus two times x plus one"
136
+ )
137
+
138
+ equation = ""
139
+ if nl_input:
140
+ equation = convert_nl_to_equation(nl_input)
141
+ if equation:
142
+ st.success(f"Converted to equation: {equation}")
143
+ else:
144
+ st.error("Failed to convert input")
145
+
146
+ # Direct equation input (fallback or primary)
147
+ equation = st.text_input(
148
+ "Or enter your equation directly:",
149
+ value=equation,
150
+ placeholder="e.g., x^2 + 2*x + 1"
151
+ )
152
+
153
+ # Plot settings
154
+ with st.expander("⚙ Plot Settings"):
155
+ col_a, col_b = st.columns(2)
156
+ with col_a:
157
+ x_min = st.number_input("X-axis minimum", value=-10.0)
158
+ with col_b:
159
+ x_max = st.number_input("X-axis maximum", value=10.0)
160
+ points = st.slider("Number of points", 100, 2000, 1000)
161
+
162
+ # Process and plot
163
+ if equation:
164
+ f, expr = parse_and_validate_equation(equation)
165
+ if f and expr:
166
+ fig = plot_equation(f, expr, (x_min, x_max), points)
167
+ if fig:
168
+ st.pyplot(fig)
169
+ st.markdown(get_download_link(fig), unsafe_allow_html=True)
170
+ if equation not in [h['equation'] for h in st.session_state.history]:
171
+ st.session_state.history.append({
172
+ 'equation': equation,
173
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
174
+ })
175
+
176
+ with col2:
177
+ st.subheader("📚 Example Equations")
178
+ examples = [
179
+ "x^2 + 2*x + 1",
180
+ "sin(x) + cos(x)",
181
+ "exp(-x^2)",
182
+ "x^3 - 4*x",
183
+ "tan(x)",
184
+ "log(abs(x))"
185
+ ]
186
+ for ex in examples:
187
+ if st.button(ex):
188
+ st.experimental_set_query_params(equation=ex)
189
+
190
+ st.subheader("📖 Recent Equations")
191
+ for item in reversed(st.session_state.history[-5:]):
192
+ st.text(f"{item['equation']}")
193
+ st.caption(f"Plotted on: {item['timestamp']}")
194
+
195
+ with st.expander("ℹ How to use Equation2Graph"):
196
+ st.markdown("""
197
+ ### Instructions:
198
+ 1. Describe or type your equation
199
+ 2. The graph updates automatically
200
+ 3. Adjust plot settings if needed
201
+ 4. Download the graph as PNG
202
+
203
+ ### Natural Language Support:
204
+ - Try: "the square of x plus two times x"
205
+ - You can still type equations like: x^2 + 2*x
206
+
207
+ ### Supported Math Functions:
208
+ - Basic: +, -, *, /, ^
209
+ - Trig: sin(x), cos(x), tan(x)
210
+ - Exponential/log: exp(x), log(x)
211
+ """)
212
 
213
+ # Footer
214
+ st.markdown("---")
215
+ st.markdown("Equation2Graph | Now with 🧠 AI-powered equation parser | Made by webwhiz")