NSamson1 commited on
Commit
2eafb6d
·
verified ·
1 Parent(s): c0006f8

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +181 -37
src/streamlit_app.py CHANGED
@@ -1,40 +1,184 @@
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 altair as alt
 
 
2
  import streamlit as st
3
 
4
+ "import streamlit as st
5
+ import pandas as pd
6
+ import os
7
+ import zipfile
8
+ from PIL import Image
9
+ import sympy as sp
10
+ import time
11
+ from sentence_transformers import SentenceTransformer
12
+ from sklearn.metrics.pairwise import cosine_similarity
13
+
14
+ # Page config
15
+ st.set_page_config(page_title="🎓 Smart Math Teacher", layout="centered")
16
+
17
+ # Custom CSS
18
+ st.markdown("""
19
+ <style>
20
+ .fun-title { font-size: 40px; color: #ff3399; text-align: center; font-family: 'Comic Sans MS', cursive; }
21
+ .question-box { border: 4px dotted #ffcc00; padding: 20px; border-radius: 20px; background-color: #fff7e6; font-size: 20px; }
22
+ .stButton > button { font-size: 18px; background-color: #00cc99; color: white; border-radius: 10px; padding: 10px; }
23
+ .stTextInput > div > input { font-size: 18px; }
24
+ </style>
25
+ """, unsafe_allow_html=True)
26
+
27
+ # Welcome title
28
+ st.markdown("<div class='fun-title'>🧠✨ Welcome to the Smart Math Teacher! ✨🧠</div>", unsafe_allow_html=True)
29
+
30
+ # Age group setup
31
+ age_groups = {
32
+ "4-6 Age Group": {"dataset": "Dataset%20for%204-6%20Age%20Group.xlsx", "zip_file": "Image_for_group_4-6.zip", "image_folder": "Image_for_group_4-6"},
33
+ "7-9 Age Group": {"dataset": "Dataset%20for%207-9%20Age%20Group.xlsx", "zip_file": "Image_for_group_7-9.zip", "image_folder": "Image_for_group_7-9"},
34
+ "13-15 Age Group": {"dataset": "Dataset%20for%2013-15%20Age%20Group.xlsx", "zip_file": "Image_for_group_13-15.zip", "image_folder": "Image_for_group_13-15"},
35
+ }
36
+
37
+ selected_age_group = st.selectbox("🧒 Select your Age Group:", list(age_groups.keys()))
38
+
39
+ # Initialize session
40
+ if "session_initialized" not in st.session_state or st.session_state.age_group != selected_age_group:
41
+ st.session_state.age_group = selected_age_group
42
+ st.session_state.category = None
43
+ st.session_state.question_index = 0
44
+ st.session_state.show_answer = False
45
+ st.session_state.show_steps = False
46
+ st.session_state.session_initialized = True
47
+
48
+ # Load dataset
49
+ group_info = age_groups[selected_age_group]
50
+ dataset_path = group_info["dataset"]
51
+ zip_path = group_info["zip_file"]
52
+ image_folder = group_info["image_folder"]
53
+
54
+ os.makedirs(image_folder, exist_ok=True)
55
+ if not any(f.lower().endswith(('.png', '.jpg', '.jpeg')) for f in os.listdir(image_folder)):
56
+ if os.path.exists(zip_path):
57
+ with zipfile.ZipFile(zip_path, "r") as zip_ref:
58
+ zip_ref.extractall(image_folder)
59
+
60
+ if not os.path.exists(dataset_path):
61
+ st.error(f"Dataset not found: {dataset_path}")
62
+ st.stop()
63
+
64
+ df = pd.read_excel(dataset_path)
65
+ df['category'] = df['category'].astype(str).str.strip()
66
+
67
+ # Category selection
68
+ categories = sorted(df['category'].dropna().unique())
69
+ selected_category = st.selectbox("📚 Choose a Math Category:", options=categories)
70
+
71
+ # Update session if category changes
72
+ if st.session_state.category != selected_category:
73
+ st.session_state.category = selected_category
74
+ st.session_state.question_index = 0
75
+ st.session_state.show_answer = False
76
+ st.session_state.show_steps = False
77
+ st.rerun()
78
+
79
+ # Filter questions by selected category only
80
+ subset_df = df[df['category'] == selected_category].reset_index(drop=True)
81
+
82
+ if not subset_df.empty and st.session_state.question_index < len(subset_df):
83
+ question = subset_df.iloc[st.session_state.question_index]
84
+ progress = int((st.session_state.question_index / len(subset_df)) * 100)
85
+ st.progress(progress)
86
+
87
+ st.markdown(f"<div class='question-box'>📘 <b>Question {st.session_state.question_index + 1}:</b><br><br>{question['problem']}</div>", unsafe_allow_html=True)
88
+
89
+ # Display image
90
+ if pd.notna(question.get('image')):
91
+ image_name = str(question['image']).strip()
92
+ for root, _, files in os.walk(image_folder):
93
+ for file in files:
94
+ if file.lower().startswith(image_name.lower()) or os.path.splitext(file)[0].lower() == image_name.lower():
95
+ try:
96
+ st.image(Image.open(os.path.join(root, file)), use_column_width=True)
97
+ except:
98
+ st.warning("❌ Image couldn't be loaded.")
99
+ break
100
+
101
+ user_ans = st.text_input("📝 Your Answer:", key=f"ans_{st.session_state.question_index}")
102
+
103
+ if st.button("✅ Submit Answer"):
104
+ if str(user_ans).strip().lower() == str(question['answer']).strip().lower():
105
+ st.success("🎉 Correct! Well done!")
106
+ st.balloons()
107
+ time.sleep(2)
108
+ st.session_state.question_index += 1
109
+ st.session_state.show_answer = False
110
+ st.session_state.show_steps = False
111
+ st.rerun()
112
+ else:
113
+ st.error("❌ Try again or view the correct answer below.")
114
+ st.session_state.show_answer = True
115
+ st.session_state.show_steps = False
116
+
117
+ if st.session_state.show_answer:
118
+ st.info(f"✅ Correct Answer: **{question['answer']}**")
119
+ if selected_age_group in ["7-9 Age Group", "13-15 Age Group"]:
120
+ if st.button("🔍 Show Steps"):
121
+ st.session_state.show_steps = True
122
+ if st.session_state.show_steps and pd.notna(question.get("steps", None)):
123
+ st.success(f"### 🪄 Steps:\n{question['steps']}")
124
+
125
+ if st.button("⏭️ Skip"):
126
+ st.session_state.question_index += 1
127
+ st.session_state.show_answer = False
128
+ st.session_state.show_steps = False
129
+ st.rerun()
130
+ elif subset_df.empty:
131
+ st.warning("⚠️ No questions available in this category. Try another one.")
132
+ else:
133
+ st.success("🏁 You've completed all questions in this category!")
134
+
135
+ # -------------------------------------------------------------
136
+ # ✅ Enhanced "Ask Any Math Question" Section Using MiniLM Model
137
+ # -------------------------------------------------------------
138
+
139
+ @st.cache_resource
140
+ def load_model():
141
+ return SentenceTransformer("all-MiniLM-L6-v2")
142
+
143
+ model = load_model()
144
+
145
+ qa_pairs = {
146
+ "what is the area of a triangle": "Area = (1/2) × base × height",
147
+ "what is the area of a square": "Area = side²",
148
+ "what is the area of a circle": "Area = π × radius²",
149
+ "perimeter of square": "Perimeter = 4 × side",
150
+ "perimeter of rectangle": "Perimeter = 2 × (length + width)",
151
+ "volume of cube": "Volume = side³",
152
+ "volume of sphere": "Volume = (4/3) × π × radius³",
153
+ "what is pi": "π ≈ 3.14159",
154
+ "how to calculate speed": "Speed = Distance ÷ Time",
155
+ "what is the derivative of x squared": "The derivative of x² is 2x."
156
+ }
157
+
158
+ qa_questions = list(qa_pairs.keys())
159
+ qa_embeddings = model.encode(qa_questions)
160
+
161
+ st.markdown("## 💡 Ask Any Math Question")
162
+ question_input = st.text_input("Ask a question like 'What is the area of a circle?' or 'Derivative of x^2'")
163
+
164
+ if question_input:
165
+ user_embedding = model.encode([question_input])
166
+ scores = cosine_similarity(user_embedding, qa_embeddings)[0]
167
+ best_idx = scores.argmax()
168
+ best_score = scores[best_idx]
169
+
170
+ if best_score > 0.6:
171
+ st.success(f"🤖 Answer:\n\n**{qa_pairs[qa_questions[best_idx]]}**")
172
+ else:
173
+ try:
174
+ if "derivative" in question_input.lower():
175
+ expr = question_input.lower().split("of")[-1].strip()
176
+ var = sp.symbols('x')
177
+ derivative = sp.diff(sp.sympify(expr.replace("^", "**")), var)
178
+ st.success(f"🧮 Derivative of {expr} is:\n\n**{derivative}**")
179
+ else:
180
+ result = sp.sympify(question_input.replace("^", "**"))
181
+ simplified = sp.simplify(result)
182
+ st.success(f"✅ Answer: {simplified}")
183
+ except Exception as e:
184
+ st.warning(f"⚠️ Couldn't understand the question. Error: {e}")