Shivaaaahdjdnd/code_analysis
0
1import ast2import re3import difflib4import subprocess5import tempfile6import os7import json8import traceback9from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline10import torch11from config import config, get_complexity_score, get_language_config, AI_PATTERNS12 13 14class CodingAnalyzer:15 def __init__(self):16 self.config = config17 self.setup_ai_model()18 19 def setup_ai_model(self):20 """Setup Qwen2.5-1.5B-Instruct model for code analysis (CPU-friendly)"""21 try:22 model_config = self.config.model23 print(f"๐ Loading {model_config.model_name} model...")24 25 use_fp16 = torch.cuda.is_available()26 dtype = torch.float16 if use_fp16 else torch.float3227 28 self.model = AutoModelForCausalLM.from_pretrained(29 model_config.model_name,30 torch_dtype=dtype,31 trust_remote_code=model_config.trust_remote_code,32 low_cpu_mem_usage=True33 )34 35 device = "cuda" if torch.cuda.is_available() else "cpu"36 self.model = self.model.to(device)37 print(f"๐ Running on: {device.upper()}")38 39 self.tokenizer = AutoTokenizer.from_pretrained(40 model_config.model_name,41 trust_remote_code=model_config.trust_remote_code42 )43 44 self.pipe = pipeline(45 "text-generation",46 model=self.model,47 tokenizer=self.tokenizer,48 max_new_tokens=model_config.max_new_tokens,49 temperature=model_config.temperature,50 do_sample=model_config.do_sample,51 top_p=model_config.top_p,52 repetition_penalty=model_config.repetition_penalty53 )54 55 param_count = sum(p.numel() for p in self.model.parameters()) / 1e956 print(f"โ
{model_config.model_name} loaded! ({param_count:.2f}B params)")57 58 except Exception as e:59 print(f"โ Model load failed: {e}")60 print(f"๐ Traceback:\n{traceback.format_exc()}")61 print("๐ Falling back to rule-based analysis...")62 self.pipe = None63 64 def _call_ai(self, messages):65 """66 Centralized helper to call the Qwen chat pipeline.67 Supports chat template format.68 Returns generated text string or raises on failure.69 """70 if self.pipe is None:71 raise RuntimeError("AI pipeline not available")72 73 output = self.pipe(messages, return_full_text=False)74 75 if isinstance(output, list) and len(output) > 0:76 first = output[0]77 if isinstance(first, dict) and 'generated_text' in first:78 return first['generated_text']79 if isinstance(first, list) and len(first) > 0 and 'generated_text' in first[0]:80 return first[0]['generated_text']81 82 raise ValueError(f"Unexpected pipeline output format: {type(output)}")83 84 def analyze_solution(self, question, user_code, correct_solution, language="python", difficulty="medium", test_cases=None):85 """Main analysis function"""86 results = {87 'status': 'completed',88 'overall_score': 0,89 'max_score': 100,90 'analysis': {91 'correctness': {},92 'code_quality': {},93 'efficiency': {},94 'ai_detection': {},95 'similarity': {},96 'test_results': {}97 },98 'feedback': '',99 'recommendations': []100 }101 102 try:103 # 1. Correctness Analysis (40 points)104 correctness = self.analyze_correctness(user_code, correct_solution, test_cases, language)105 results['analysis']['correctness'] = correctness106 results['overall_score'] += correctness['score']107 108 # 2. Code Quality Analysis (25 points)109 quality = self.analyze_code_quality(user_code, language)110 results['analysis']['code_quality'] = quality111 results['overall_score'] += quality['score']112 113 # 3. Efficiency Analysis (20 points)114 efficiency = self.analyze_efficiency(user_code, correct_solution, language)115 results['analysis']['efficiency'] = efficiency116 results['overall_score'] += efficiency['score']117 118 # 4. AI Detection (10 points penalty)119 ai_detection = self.detect_ai_generated(user_code, language)120 results['analysis']['ai_detection'] = ai_detection121 results['overall_score'] -= ai_detection['penalty']122 123 # 5. Similarity Analysis (5 points penalty)124 similarity = self.analyze_similarity(user_code, correct_solution)125 results['analysis']['similarity'] = similarity126 results['overall_score'] -= similarity['penalty']127 128 # Generate feedback and recommendations129 results['feedback'] = self.generate_feedback(results['analysis'], question, difficulty)130 results['recommendations'] = self.generate_recommendations(results['analysis'])131 132 results['overall_score'] = max(0, min(100, results['overall_score']))133 134 except Exception as e:135 results['status'] = 'error'136 results['error'] = str(e)137 print(f"โ analyze_solution failed: {e}\n{traceback.format_exc()}")138 139 return results140 141 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ142 # 1. CORRECTNESS143 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ144 145 def analyze_correctness(self, user_code, correct_solution, test_cases, language):146 """Correctness analysis: syntax + real test execution + AI review"""147 result = {148 'score': 0,149 'max_score': 40,150 'syntax_valid': False,151 'logic_correct': False,152 'test_cases_passed': 0,153 'total_test_cases': 0,154 'execution_errors': [],155 'ai_analysis': ''156 }157 158 try:159 # --- Syntax check (Python only via AST) ---160 if language == 'python':161 try:162 ast.parse(user_code)163 result['syntax_valid'] = True164 except SyntaxError as e:165 result['execution_errors'].append(f"Syntax Error: {str(e)}")166 result['score'] = 0167 return result168 else:169 # For other languages assume syntax valid (no AST available)170 result['syntax_valid'] = True171 172 # --- Real test execution for Python ---173 if language == 'python' and test_cases:174 passed, total, errors = self._run_python_tests(user_code, test_cases)175 result['test_cases_passed'] = passed176 result['total_test_cases'] = total177 result['execution_errors'].extend(errors)178 179 if total > 0:180 pass_ratio = passed / total181 result['score'] = int(10 + 30 * pass_ratio) # 10 syntax + up to 30 logic182 result['logic_correct'] = pass_ratio >= 0.8183 else:184 result['score'] = 10 # only syntax points if no tests185 186 # --- AI-powered review ---187 if self.pipe:188 correctness_prompt = f"""Analyze this code solution for correctness:189 190User Code:191{user_code}192 193Reference Solution:194{correct_solution}195 196Evaluate:1971. Syntax validity (0-10 points)1982. Logic correctness (0-30 points)1993. Edge case handling2004. Algorithm accuracy201 202Respond ONLY with valid JSON, no extra text:203{{"syntax_score": 8, "logic_score": 25, "analysis": "your explanation here"}}"""204 205 messages = [206 {"role": "system", "content": "You are an expert code reviewer. Respond with valid JSON only, no markdown, no extra text."},207 {"role": "user", "content": correctness_prompt}208 ]209 210 try:211 ai_response = self._call_ai(messages)212 json_match = re.search(r'\{.*?\}', ai_response, re.DOTALL)213 if json_match:214 ai_eval = json.loads(json_match.group())215 syntax_score = min(10, max(0, int(ai_eval.get('syntax_score', 0))))216 logic_score = min(30, max(0, int(ai_eval.get('logic_score', 0))))217 # If no real tests ran, use AI score218 if result['total_test_cases'] == 0:219 result['score'] = syntax_score + logic_score220 result['logic_correct'] = logic_score >= 25221 result['ai_analysis'] = ai_eval.get('analysis', '')222 except Exception as e:223 print(f"โ ๏ธ Correctness AI analysis failed: {e}")224 # Fallback: syntax valid = 10 + 30 base225 if result['total_test_cases'] == 0:226 result['score'] = 40 if result['syntax_valid'] else 0227 result['logic_correct'] = result['syntax_valid']228 else:229 # No AI: give full marks if syntax valid and no tests failed230 if result['total_test_cases'] == 0 and result['syntax_valid']:231 result['score'] = 40232 result['logic_correct'] = True233 234 except Exception as e:235 result['execution_errors'].append(str(e))236 print(f"โ analyze_correctness failed: {e}")237 238 return result239 240 def _run_python_tests(self, user_code, test_cases):241 """Actually execute Python code against test cases using subprocess"""242 passed = 0243 total = len(test_cases)244 errors = []245 246 for tc in test_cases:247 input_data = tc.get('input', '')248 expected = str(tc.get('expected_output', '')).strip()249 input_repr = repr(input_data)250 251 # Build test script without backslashes inside f-strings (Python 3.10 compat)252 lines = [253 user_code,254 "",255 "import sys",256 "import ast as _ast",257 "result = None",258 "try:",259 " src = '''",260 user_code,261 " '''",262 " tree = _ast.parse(src)",263 " func_names = [node.name for node in _ast.walk(tree) if isinstance(node, _ast.FunctionDef)]",264 " if func_names:",265 " fn = globals()[func_names[0]]",266 " args = " + input_repr,267 " if isinstance(args, (list, tuple)):",268 " result = fn(*args)",269 " else:",270 " result = fn(args)",271 " print(result)",272 "except Exception as e:",273 " print('ERROR: ' + str(e), file=sys.stderr)",274 " sys.exit(1)",275 ]276 test_script = "\n".join(lines)277 278 try:279 proc = subprocess.run(280 ['python3', '-c', test_script],281 capture_output=True, text=True,282 timeout=self.config.analysis.test_timeout283 )284 actual = proc.stdout.strip()285 if proc.returncode == 0 and actual == expected:286 passed += 1287 else:288 if proc.stderr:289 errors.append(proc.stderr.strip()[:200])290 except subprocess.TimeoutExpired:291 errors.append("Test timed out (>" + str(self.config.analysis.test_timeout) + "s)")292 except Exception as e:293 errors.append(str(e))294 295 return passed, total, errors296 297 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ298 # 2. CODE QUALITY299 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ300 301 def analyze_code_quality(self, user_code, language):302 """Code quality analysis: AI-powered with rule-based fallback"""303 result = {304 'score': 0,305 'max_score': 25,306 'readability': 0,307 'structure': 0,308 'naming': 0,309 'comments': 0,310 'best_practices': 0,311 'ai_analysis': ''312 }313 314 try:315 if self.pipe:316 quality_prompt = f"""Analyze this {language} code for quality:317 318Code:319{user_code}320 321Score each (0-5 points):3221. readability: formatting, line length, clarity3232. structure: functions/classes, organization3243. naming: variable and function names3254. comments: documentation quality3265. best_practices: language conventions327 328Respond ONLY with valid JSON:329{{"readability": 4, "structure": 4, "naming": 3, "comments": 1, "best_practices": 3, "analysis": "explanation"}}"""330 331 messages = [332 {"role": "system", "content": "You are a code quality expert. Respond with valid JSON only, no markdown."},333 {"role": "user", "content": quality_prompt}334 ]335 336 try:337 ai_response = self._call_ai(messages)338 json_match = re.search(r'\{.*?\}', ai_response, re.DOTALL)339 if json_match:340 ai_eval = json.loads(json_match.group())341 result['readability'] = min(5, max(0, int(ai_eval.get('readability', 0))))342 result['structure'] = min(5, max(0, int(ai_eval.get('structure', 0))))343 result['naming'] = min(5, max(0, int(ai_eval.get('naming', 0))))344 result['comments'] = min(5, max(0, int(ai_eval.get('comments', 0))))345 result['best_practices'] = min(5, max(0, int(ai_eval.get('best_practices', 0))))346 result['ai_analysis'] = ai_eval.get('analysis', '')347 result['score'] = sum([result['readability'], result['structure'],348 result['naming'], result['comments'], result['best_practices']])349 return result350 else:351 raise ValueError("No JSON in AI response")352 except Exception as e:353 print(f"โ ๏ธ Code quality AI failed: {e}")354 self._basic_quality_analysis(user_code, language, result)355 else:356 self._basic_quality_analysis(user_code, language, result)357 358 except Exception as e:359 print(f"โ analyze_code_quality failed: {e}")360 self._basic_quality_analysis(user_code, language, result)361 362 return result363 364 def _basic_quality_analysis(self, user_code, language, result):365 """Rule-based quality analysis fallback"""366 lines = user_code.split('\n')367 avg_line_length = sum(len(l) for l in lines) / len(lines) if lines else 0368 comment_lines = sum(1 for l in lines if l.strip().startswith('#'))369 370 result['readability'] = 5 if avg_line_length < 80 else (3 if avg_line_length < 120 else 1)371 result['structure'] = 4 if 'def ' in user_code else 2372 result['naming'] = 3 # neutral default373 result['comments'] = min(5, comment_lines)374 result['best_practices'] = 3 # neutral default375 376 result['score'] = sum([result['readability'], result['structure'],377 result['naming'], result['comments'], result['best_practices']])378 379 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ380 # 3. EFFICIENCY381 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ382 383 def analyze_efficiency(self, user_code, correct_solution, language):384 """Efficiency analysis: AI complexity detection with regex fallback"""385 result = {386 'score': 0,387 'max_score': 20,388 'time_complexity': 'Unknown',389 'space_complexity': 'Unknown',390 'optimization_score': 0,391 'ai_analysis': ''392 }393 394 try:395 if self.pipe:396 efficiency_prompt = f"""Analyze algorithm efficiency:397 398User Code:399{user_code}400 401Reference Solution:402{correct_solution}403 404Evaluate:4051. Time Complexity in Big O4062. Space Complexity in Big O4073. Efficiency score (0-20 points)4084. Optimization opportunities409 410Respond ONLY with valid JSON:411{{"time_complexity": "O(n)", "space_complexity": "O(1)", "efficiency_score": 15, "analysis": "explanation"}}"""412 413 messages = [414 {"role": "system", "content": "You are an algorithm complexity expert. Respond with valid JSON only, no markdown."},415 {"role": "user", "content": efficiency_prompt}416 ]417 418 try:419 ai_response = self._call_ai(messages)420 json_match = re.search(r'\{.*?\}', ai_response, re.DOTALL)421 if json_match:422 ai_eval = json.loads(json_match.group())423 result['time_complexity'] = ai_eval.get('time_complexity', 'Unknown')424 result['space_complexity'] = ai_eval.get('space_complexity', 'Unknown')425 result['score'] = min(20, max(0, int(ai_eval.get('efficiency_score', 0))))426 result['optimization_score'] = result['score']427 result['ai_analysis'] = ai_eval.get('analysis', '')428 return result429 else:430 raise ValueError("No JSON in AI response")431 except Exception as e:432 print(f"โ ๏ธ Efficiency AI failed: {e}")433 self._basic_efficiency_analysis(user_code, result)434 else:435 self._basic_efficiency_analysis(user_code, result)436 437 except Exception as e:438 print(f"โ analyze_efficiency failed: {e}")439 self._basic_efficiency_analysis(user_code, result)440 441 return result442 443 def _basic_efficiency_analysis(self, user_code, result):444 """Rule-based complexity detection"""445 nested_loops = len(re.findall(r'for\s.+\n.*for\s', user_code))446 while_nested = len(re.findall(r'while\s.+\n.*while\s', user_code))447 total_nested = nested_loops + while_nested448 449 if total_nested == 0:450 complexity_score = 15451 result['time_complexity'] = 'O(n) or better'452 elif total_nested == 1:453 complexity_score = 10454 result['time_complexity'] = 'O(nยฒ)'455 else:456 complexity_score = 5457 result['time_complexity'] = 'O(nยณ) or worse'458 459 # Bonus for efficient data structures460 if 'dict' in user_code or '{' in user_code or 'set(' in user_code:461 complexity_score = min(20, complexity_score + 3)462 463 result['space_complexity'] = 'O(n)' if ('list(' in user_code or '[]' in user_code) else 'O(1)'464 result['optimization_score'] = complexity_score465 result['score'] = min(20, complexity_score)466 467 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ468 # 4. AI DETECTION469 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ470 471 def detect_ai_generated(self, user_code, language):472 """Detect AI-generated code patterns"""473 result = {474 'penalty': 0,475 'max_penalty': 10,476 'ai_probability': 0,477 'indicators': [],478 'ai_analysis': ''479 }480 481 try:482 if self.pipe:483 ai_detection_prompt = f"""Analyze if this code is AI-generated:484 485Code:486{user_code}487 488Look for:4891. Overly verbose comments4902. Perfect documentation style4913. Generic variable names (result, output, temp)4924. Unnatural comment patterns4935. Typical ChatGPT/AI structure494 495Respond ONLY with valid JSON:496{{"ai_probability": 20, "penalty_score": 2, "indicators": ["reason1"], "analysis": "explanation"}}497ai_probability: 0-100, penalty_score: 0-10"""498 499 messages = [500 {"role": "system", "content": "You are an expert at detecting AI-generated code. Respond with valid JSON only, no markdown."},501 {"role": "user", "content": ai_detection_prompt}502 ]503 504 try:505 ai_response = self._call_ai(messages)506 json_match = re.search(r'\{.*?\}', ai_response, re.DOTALL)507 if json_match:508 ai_eval = json.loads(json_match.group())509 result['ai_probability'] = min(100, max(0, int(ai_eval.get('ai_probability', 0))))510 result['penalty'] = min(10, max(0, int(ai_eval.get('penalty_score', 0))))511 result['indicators'] = ai_eval.get('indicators', [])512 result['ai_analysis'] = ai_eval.get('analysis', '')513 return result514 else:515 raise ValueError("No JSON in AI response")516 except Exception as e:517 print(f"โ ๏ธ AI detection failed: {e}")518 self._basic_ai_detection(user_code, language, result)519 else:520 self._basic_ai_detection(user_code, language, result)521 522 except Exception as e:523 print(f"โ detect_ai_generated failed: {e}")524 self._basic_ai_detection(user_code, language, result)525 526 return result527 528 def _basic_ai_detection(self, user_code, language, result):529 """Rule-based AI detection fallback"""530 ai_score = 0531 lines = user_code.split('\n')532 533 comment_ratio = sum(1 for l in lines if l.strip().startswith('#')) / len(lines) if lines else 0534 if comment_ratio > 0.3:535 ai_score += 3536 result['indicators'].append('Excessive comments (>30% of lines)')537 538 for pattern in AI_PATTERNS:539 if re.search(pattern, user_code, re.IGNORECASE):540 ai_score += 2541 result['indicators'].append(f'Generic AI comment pattern: {pattern}')542 break543 544 # Generic variable names545 if re.search(r'\bresult\b|\boutput\b|\btemp\b|\bans\b', user_code):546 ai_score += 1547 result['indicators'].append('Generic variable names (result/output/temp)')548 549 result['ai_probability'] = min(100, ai_score * 15)550 result['penalty'] = min(10, ai_score)551 552 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ553 # 5. SIMILARITY554 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ555 556 def analyze_similarity(self, user_code, correct_solution):557 """Similarity / plagiarism check"""558 result = {559 'penalty': 0,560 'max_penalty': 5,561 'similarity_ratio': 0,562 'ai_analysis': ''563 }564 565 try:566 # Normalize both codes567 user_clean = re.sub(r'#.*', '', user_code).replace(' ', '').replace('\n', '')568 correct_clean = re.sub(r'#.*', '', correct_solution).replace(' ', '').replace('\n', '')569 similarity = difflib.SequenceMatcher(None, user_clean, correct_clean).ratio()570 result['similarity_ratio'] = round(similarity, 2)571 572 if self.pipe:573 similarity_prompt = f"""Analyze code similarity for plagiarism:574 575User Code:576{user_code}577 578Reference Solution:579{correct_solution}580 581Similarity Ratio: {similarity:.2f}582 583Evaluate:5841. Structural similarity5852. Algorithm approach5863. Variable naming patterns5874. Is it copying or just same logic?5885. Penalty (0-5 points)589 590Respond ONLY with valid JSON:591{{"penalty_score": 2, "is_plagiarism": false, "analysis": "explanation"}}"""592 593 messages = [594 {"role": "system", "content": "You are a plagiarism detection expert. Respond with valid JSON only, no markdown."},595 {"role": "user", "content": similarity_prompt}596 ]597 598 try:599 ai_response = self._call_ai(messages)600 json_match = re.search(r'\{.*?\}', ai_response, re.DOTALL)601 if json_match:602 ai_eval = json.loads(json_match.group())603 result['penalty'] = min(5, max(0, int(ai_eval.get('penalty_score', 0))))604 result['ai_analysis'] = ai_eval.get('analysis', '')605 return result606 else:607 raise ValueError("No JSON in AI response")608 except Exception as e:609 print(f"โ ๏ธ Similarity AI failed: {e}")610 self._basic_similarity_penalty(similarity, result)611 else:612 self._basic_similarity_penalty(similarity, result)613 614 except Exception as e:615 print(f"โ analyze_similarity failed: {e}")616 617 return result618 619 def _basic_similarity_penalty(self, similarity, result):620 """Rule-based similarity penalty"""621 if similarity > 0.95:622 result['penalty'] = 5623 elif similarity > 0.85:624 result['penalty'] = 3625 elif similarity > 0.75:626 result['penalty'] = 1627 else:628 result['penalty'] = 0629 630 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ631 # 6. FEEDBACK & RECOMMENDATIONS632 # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ633 634 def generate_feedback(self, analysis, question, difficulty):635 """Generate comprehensive AI-powered feedback"""636 correctness = analysis['correctness']637 quality = analysis['code_quality']638 efficiency = analysis['efficiency']639 ai_detection = analysis['ai_detection']640 similarity = analysis['similarity']641 642 if not self.pipe:643 total = (correctness['score'] + quality['score'] + efficiency['score']644 - ai_detection['penalty'] - similarity['penalty'])645 return (646 f"Rule-based analysis completed. "647 f"Correctness: {correctness['score']}/40, "648 f"Quality: {quality['score']}/25, "649 f"Efficiency: {efficiency['score']}/20 | "650 f"Time complexity: {efficiency.get('time_complexity', 'Unknown')}. "651 f"Overall: {total}/100."652 )653 654 try:655 feedback_prompt = f"""Give constructive feedback for this coding solution:656 657Problem: {question}658Difficulty: {difficulty}659 660Scores:661- Correctness: {correctness['score']}/40662- Code Quality: {quality['score']}/25663- Efficiency: {efficiency['score']}/20664- AI Penalty: {ai_detection['penalty']}/10665- Similarity Penalty: {similarity['penalty']}/5666 667Details:668- Syntax Valid: {correctness['syntax_valid']}669- Tests Passed: {correctness.get('test_cases_passed', 0)}/{correctness.get('total_test_cases', 0)}670- Time Complexity: {efficiency['time_complexity']}671- Space Complexity: {efficiency['space_complexity']}672 673Write 3-5 sentences covering strengths, weaknesses, and specific improvements."""674 675 messages = [676 {"role": "system", "content": "You are an expert coding instructor. Give clear, constructive feedback in 3-5 sentences."},677 {"role": "user", "content": feedback_prompt}678 ]679 680 return self._call_ai(messages)681 682 except Exception as e:683 print(f"โ ๏ธ Feedback generation failed: {e}")684 total = (correctness['score'] + quality['score'] + efficiency['score']685 - ai_detection['penalty'] - similarity['penalty'])686 return f"Analysis completed. Score: {total}/100. Time complexity: {efficiency.get('time_complexity', 'Unknown')}."687 688 def generate_recommendations(self, analysis):689 """Generate actionable recommendations"""690 if not self.pipe:691 return self._basic_recommendations(analysis)692 693 try:694 correctness = analysis['correctness']695 quality = analysis['code_quality']696 efficiency = analysis['efficiency']697 ai_detection = analysis['ai_detection']698 699 recommendations_prompt = f"""Generate 3-5 specific actionable recommendations:700 701Scores:702- Correctness: {correctness['score']}/40703- Quality: {quality['score']}/25704- Efficiency: {efficiency['score']}/20705- AI Detection Penalty: {ai_detection['penalty']}706 707Issues:708- Syntax Valid: {correctness['syntax_valid']}709- Time Complexity: {efficiency['time_complexity']}710- AI Indicators: {ai_detection['indicators']}711 712Respond ONLY with valid JSON:713{{"recommendations": ["action 1", "action 2", "action 3"]}}"""714 715 messages = [716 {"role": "system", "content": "You are a coding mentor. Respond with valid JSON only, no markdown."},717 {"role": "user", "content": recommendations_prompt}718 ]719 720 try:721 ai_response = self._call_ai(messages)722 json_match = re.search(r'\{.*?\}', ai_response, re.DOTALL)723 if json_match:724 ai_eval = json.loads(json_match.group())725 recs = ai_eval.get('recommendations', [])726 if recs:727 return recs[:5]728 except Exception as e:729 print(f"โ ๏ธ Recommendations AI failed: {e}")730 731 except Exception as e:732 print(f"โ generate_recommendations failed: {e}")733 734 return self._basic_recommendations(analysis)735 736 def _basic_recommendations(self, analysis):737 """Rule-based recommendations fallback"""738 recommendations = []739 correctness = analysis['correctness']740 quality = analysis['code_quality']741 efficiency = analysis['efficiency']742 ai_detection = analysis['ai_detection']743 744 if not correctness['syntax_valid']:745 recommendations.append("Fix syntax errors before submission")746 if correctness.get('test_cases_passed', 0) < correctness.get('total_test_cases', 1):747 recommendations.append("Debug logic to pass all test cases")748 if quality['score'] < 15:749 recommendations.append("Improve code readability and add comments")750 if 'O(nยฒ)' in efficiency.get('time_complexity', ''):751 recommendations.append("Optimize algorithm โ consider using a hash map to reduce to O(n)")752 if 'O(nยณ)' in efficiency.get('time_complexity', ''):753 recommendations.append("Critical: algorithm is O(nยณ) or worse โ needs major optimization")754 if ai_detection['penalty'] > 5:755 recommendations.append("Ensure code originality โ avoid AI-generated patterns")756 if quality.get('comments', 0) == 0:757 recommendations.append("Add docstrings and inline comments for better documentation")758 759 return recommendations[:5]760 761 def execute_test_case(self, code, test_case, language):762 """Kept for API compatibility โ use _run_python_tests for actual execution"""763 if language == 'python' and test_case:764 passed, total, _ = self._run_python_tests(code, [test_case])765 return passed == total766 return True