Anupam251272 commited on
Commit
1516079
·
verified ·
1 Parent(s): 517fe2e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +382 -0
app.py ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
4
+ import random
5
+ import json
6
+ from typing import Dict, List, Optional
7
+ import numpy as np
8
+ import hashlib
9
+ import datetime
10
+ import pandas as pd
11
+ from sklearn.metrics.pairwise import cosine_similarity
12
+
13
+ class UserManager:
14
+ def __init__(self):
15
+ # Use a simple in-memory dictionary instead of Firebase
16
+ self.users = {}
17
+ self.progress = {}
18
+
19
+ def register_user(self, username: str, password: str) -> bool:
20
+ if username in self.users:
21
+ return False
22
+
23
+ # Hash password
24
+ hashed_password = hashlib.sha256(password.encode()).hexdigest()
25
+
26
+ # Store user data
27
+ self.users[username] = {
28
+ 'password_hash': hashed_password,
29
+ 'join_date': datetime.datetime.now(),
30
+ 'solved_problems': [],
31
+ 'skill_level': 'beginner'
32
+ }
33
+ self.progress[username] = {
34
+ 'arrays': 0,
35
+ 'graphs': 0,
36
+ 'dynamic_programming': 0,
37
+ 'trees': 0
38
+ }
39
+ return True
40
+
41
+ def authenticate(self, username: str, password: str) -> bool:
42
+ if username not in self.users:
43
+ return False
44
+
45
+ hashed_password = hashlib.sha256(password.encode()).hexdigest()
46
+ return self.users[username]['password_hash'] == hashed_password
47
+
48
+ def update_progress(self, username: str, topic: str, success: bool):
49
+ if success:
50
+ self.progress[username][topic] += 1
51
+
52
+ # Update skill level based on progress
53
+ total_solved = sum(self.progress[username].values())
54
+ if total_solved > 50:
55
+ self.users[username]['skill_level'] = 'advanced'
56
+ elif total_solved > 20:
57
+ self.users[username]['skill_level'] = 'intermediate'
58
+
59
+ class EnhancedProblemGenerator:
60
+ def __init__(self):
61
+ self.templates = {
62
+ "arrays": [
63
+ {
64
+ "title": "Two Sum",
65
+ "difficulty": "Easy",
66
+ "description": "Given an array of integers nums and an integer target, return indices of the two numbers that add up to target.",
67
+ "constraints": ["2 <= nums.length <= 104", "-109 <= nums[i] <= 109"],
68
+ "test_cases": [
69
+ {"input": "[2,7,11,15], target=9", "output": "[0,1]"},
70
+ {"input": "[3,2,4], target=6", "output": "[1,2]"}
71
+ ],
72
+ "hints": [
73
+ "Consider using a hash map to store previously seen numbers",
74
+ "Think about the complement of each number relative to the target"
75
+ ]
76
+ },
77
+ {
78
+ "title": "Maximum Subarray",
79
+ "difficulty": "Easy",
80
+ "description": "Find the contiguous subarray with the largest sum.",
81
+ "constraints": ["1 <= nums.length <= 105", "-104 <= nums[i] <= 104"],
82
+ "test_cases": [
83
+ {"input": "[-2,1,-3,4,-1,2,1,-5,4]", "output": "6"},
84
+ {"input": "[1]", "output": "1"}
85
+ ],
86
+ "hints": [
87
+ "Consider Kadane's algorithm",
88
+ "Think about when to reset your current sum"
89
+ ]
90
+ }
91
+ ],
92
+ "dynamic_programming": [
93
+ {
94
+ "title": "Climbing Stairs",
95
+ "difficulty": "Easy",
96
+ "description": "You are climbing a staircase. It takes n steps to reach the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?",
97
+ "constraints": ["1 <= n <= 45"],
98
+ "test_cases": [
99
+ {"input": "2", "output": "2"},
100
+ {"input": "3", "output": "3"}
101
+ ],
102
+ "hints": [
103
+ "Think about the Fibonacci sequence",
104
+ "Consider the last step you take"
105
+ ]
106
+ }
107
+ ],
108
+ "trees": [
109
+ {
110
+ "title": "Maximum Depth of Binary Tree",
111
+ "difficulty": "Easy",
112
+ "description": "Given the root of a binary tree, return its maximum depth.",
113
+ "constraints": ["The number of nodes in the tree is in the range [0, 104]"],
114
+ "test_cases": [
115
+ {"input": "[3,9,20,null,null,15,7]", "output": "3"},
116
+ {"input": "[1,null,2]", "output": "2"}
117
+ ],
118
+ "hints": [
119
+ "Consider using recursion",
120
+ "Think about the base case of an empty tree"
121
+ ]
122
+ }
123
+ ]
124
+ }
125
+
126
+ # Load AI model for hint generation
127
+ self.tokenizer = AutoTokenizer.from_pretrained("microsoft/CodeGPT-small-py")
128
+ self.model = AutoModelForCausalLM.from_pretrained("microsoft/CodeGPT-small-py")
129
+
130
+ def generate_ai_hint(self, problem: Dict, user_code: str) -> str:
131
+ prompt = f"""
132
+ Problem: {problem['description']}
133
+ User's code: {user_code}
134
+ Hint: Let me help you think about this problem.
135
+ """
136
+ inputs = self.tokenizer(prompt, return_tensors="pt", max_length=512, truncation=True)
137
+ outputs = self.model.generate(**inputs, max_length=200, num_return_sequences=1)
138
+ hint = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
139
+ return hint.split("Hint: ")[-1].strip()
140
+
141
+ def get_problem_for_user(self, username: str, user_manager: UserManager, topic: str) -> Dict:
142
+ user_level = user_manager.users[username]['skill_level']
143
+ available_problems = self.templates.get(topic.lower(), [])
144
+
145
+ if not available_problems:
146
+ return {"error": "Topic not found"}
147
+
148
+ # Filter problems based on user level
149
+ if user_level == 'beginner':
150
+ problems = [p for p in available_problems if p['difficulty'] == 'Easy']
151
+ elif user_level == 'intermediate':
152
+ problems = [p for p in available_problems if p['difficulty'] in ['Easy', 'Medium']]
153
+ else:
154
+ problems = available_problems
155
+
156
+ return random.choice(problems)
157
+
158
+ class EnhancedCodeEvaluator:
159
+ def __init__(self):
160
+ self.test_environment = {}
161
+
162
+ def analyze_complexity(self, code: str) -> str:
163
+ # Simple complexity analysis based on nested loops
164
+ if "while" not in code and "for" not in code:
165
+ return "O(1)"
166
+ elif code.count("for") + code.count("while") == 1:
167
+ return "O(n)"
168
+ elif code.count("for") + code.count("while") == 2:
169
+ return "O(n²)"
170
+ else:
171
+ return "O(n³) or higher"
172
+
173
+ def evaluate_code(self, code: str, test_cases: List[Dict]) -> Dict:
174
+ try:
175
+ # Create safe execution environment
176
+ local_dict = {}
177
+ exec(code, {"__builtins__": {}}, local_dict)
178
+
179
+ results = []
180
+ passed = 0
181
+
182
+ for test in test_cases:
183
+ try:
184
+ # Execute test case
185
+ test_result = eval(f"solution{test['input']}", local_dict)
186
+ expected = eval(test['output'])
187
+
188
+ if test_result == expected:
189
+ passed += 1
190
+ results.append({"status": "PASS", "input": test['input']})
191
+ else:
192
+ results.append({
193
+ "status": "FAIL",
194
+ "input": test['input'],
195
+ "expected": expected,
196
+ "got": test_result
197
+ })
198
+ except Exception as e:
199
+ results.append({
200
+ "status": "ERROR",
201
+ "input": test['input'],
202
+ "error": str(e)
203
+ })
204
+
205
+ # Analyze code complexity
206
+ complexity = self.analyze_complexity(code)
207
+
208
+ return {
209
+ "success": True,
210
+ "results": results,
211
+ "passed": passed,
212
+ "total": len(test_cases),
213
+ "complexity": complexity
214
+ }
215
+
216
+ except Exception as e:
217
+ return {
218
+ "success": False,
219
+ "error": str(e)
220
+ }
221
+
222
+ class EnhancedLeetCodeEducator:
223
+ def __init__(self):
224
+ self.problem_generator = EnhancedProblemGenerator()
225
+ self.code_evaluator = EnhancedCodeEvaluator()
226
+ self.user_manager = UserManager()
227
+
228
+ # Check for GPU availability
229
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
230
+ print(f"Using device: {self.device}")
231
+
232
+ # Initialize hint generator
233
+ self.hint_generator = pipeline("text-generation", model="microsoft/CodeGPT-small-py")
234
+
235
+ def register_user(self, username: str, password: str) -> str:
236
+ if self.user_manager.register_user(username, password):
237
+ return f"Successfully registered user: {username}"
238
+ return "Username already exists"
239
+
240
+ def login(self, username: str, password: str) -> bool:
241
+ return self.user_manager.authenticate(username, password)
242
+
243
+ def get_problem(self, username: str, topic: str) -> str:
244
+ if not self.user_manager.authenticate(username, ""): # Check if user exists
245
+ return "Please log in first"
246
+
247
+ problem = self.problem_generator.get_problem_for_user(username, self.user_manager, topic)
248
+ if "error" in problem:
249
+ return "Topic not found. Available topics: arrays, graphs, dynamic_programming, trees"
250
+
251
+ return f"""
252
+ Problem: {problem['title']}
253
+ Difficulty: {problem['difficulty']}
254
+
255
+ Description:
256
+ {problem['description']}
257
+
258
+ Constraints:
259
+ {chr(10).join(['- ' + c for c in problem['constraints']])}
260
+
261
+ Example Test Cases:
262
+ {chr(10).join([f'Input: {tc["input"]}, Output: {tc["output"]}' for tc in problem['test_cases']])}
263
+
264
+ Your current skill level: {self.user_manager.users[username]['skill_level']}
265
+ Problems solved in this topic: {self.user_manager.progress[username][topic]}
266
+ """
267
+
268
+ def get_hint(self, username: str, topic: str, code: str) -> str:
269
+ if not self.user_manager.authenticate(username, ""):
270
+ return "Please log in first"
271
+
272
+ problem = self.problem_generator.get_problem_for_user(username, self.user_manager, topic)
273
+ if "error" in problem:
274
+ return "Cannot generate hint: problem not found"
275
+
276
+ if not code:
277
+ # If no code provided, return a general hint
278
+ return random.choice(problem['hints'])
279
+
280
+ # Generate personalized hint based on user's code
281
+ return self.problem_generator.generate_ai_hint(problem, code)
282
+
283
+ def evaluate_submission(self, username: str, code: str, topic: str) -> str:
284
+ if not self.user_manager.authenticate(username, ""):
285
+ return "Please log in first"
286
+
287
+ problem = self.problem_generator.get_problem_for_user(username, self.user_manager, topic)
288
+ if "error" in problem:
289
+ return "Error: Could not find problem for evaluation"
290
+
291
+ results = self.code_evaluator.evaluate_code(code, problem['test_cases'])
292
+
293
+ if not results['success']:
294
+ return f"Error in code execution: {results['error']}"
295
+
296
+ # Update user progress
297
+ self.user_manager.update_progress(username, topic, results['passed'] == results['total'])
298
+
299
+ output = f"""
300
+ Evaluation Results:
301
+ Passed: {results['passed']}/{results['total']} test cases
302
+ Time Complexity: {results['complexity']}
303
+
304
+ Details:
305
+ """
306
+ for idx, result in enumerate(results['results']):
307
+ output += f"\nTest Case {idx + 1}: {result['status']}"
308
+ if result['status'] == 'FAIL':
309
+ output += f"\n Expected: {result['expected']}"
310
+ output += f"\n Got: {result['got']}"
311
+ elif result['status'] == 'ERROR':
312
+ output += f"\n Error: {result['error']}"
313
+
314
+ if results['passed'] < results['total']:
315
+ output += f"\n\nNeed a hint? Type 'hint' in the code box to get personalized help!"
316
+
317
+ return output
318
+
319
+ def create_enhanced_gradio_interface():
320
+ educator = EnhancedLeetCodeEducator()
321
+
322
+ def process_interaction(username, password, action, topic, code):
323
+ if action == "Register":
324
+ return educator.register_user(username, password)
325
+ elif action == "Login":
326
+ if educator.login(username, password):
327
+ return "Login successful!"
328
+ return "Invalid credentials"
329
+ elif action == "Get Problem":
330
+ return educator.get_problem(username, topic)
331
+ elif action == "Submit Solution":
332
+ if code.strip().lower() == "hint":
333
+ return educator.get_hint(username, topic, "")
334
+ else:
335
+ return educator.evaluate_submission(username, code, topic)
336
+ else:
337
+ return "Invalid action selected."
338
+
339
+ # Create the interface
340
+ iface = gr.Interface(
341
+ fn=process_interaction,
342
+ inputs=[
343
+ gr.Textbox(label="Username"),
344
+ gr.Textbox(label="Password", type="password"),
345
+ gr.Radio(
346
+ choices=["Register", "Login", "Get Problem", "Submit Solution"],
347
+ label="Action",
348
+ value="Register"
349
+ ),
350
+ gr.Dropdown(
351
+ choices=["arrays", "dynamic_programming", "trees"],
352
+ label="Topic",
353
+ value="arrays"
354
+ ),
355
+ gr.Code(language="python", label="Your Solution (type 'hint' for help)")
356
+ ],
357
+ outputs=gr.Textbox(label="Output", lines=10),
358
+ title="Enhanced LeetCode Educational Assistant",
359
+ description="""
360
+ Welcome to your personalized coding practice platform!
361
+
362
+ 1. Register or login to get started
363
+ 2. Choose a topic and get a problem
364
+ 3. Write your solution or type 'hint' for help
365
+ 4. Submit your code for evaluation
366
+
367
+ Your progress is tracked and problems are tailored to your skill level!
368
+ """,
369
+ examples=[
370
+ ["new_user", "password123", "Register", "arrays", ""],
371
+ ["new_user", "password123", "Login", "arrays", ""],
372
+ ["new_user", "password123", "Get Problem", "arrays", ""],
373
+ ["new_user", "password123", "Submit Solution", "arrays", "def solution(nums, target):\n seen = {}\n for i, num in enumerate(nums):\n complement = target - num\n if complement in seen:\n return [seen[complement], i]\n seen[num] = i\n return []"]
374
+ ],
375
+ theme="default"
376
+ )
377
+
378
+ return iface
379
+
380
+ # Create and launch the interface
381
+ interface = create_enhanced_gradio_interface()
382
+ interface.launch()