From a6e0c0a5a3c444971b257d916547c74a663ee91c Mon Sep 17 00:00:00 2001 From: Rohit Bansal Date: Sun, 16 Aug 2026 02:32:53 +0530 Subject: [PATCH 1/2] Fixed the issue by adding multiple platforms and fixing the UI --- backend/ai_service.py | 48 +++-- backend/test_features.py | 5 +- backend/test_mock_ai.py | 26 ++- frontend/index.html | 381 ++++++++++++++++++++++++++++++++++----- 4 files changed, 393 insertions(+), 67 deletions(-) diff --git a/backend/ai_service.py b/backend/ai_service.py index 71aaf7e..eb168d6 100644 --- a/backend/ai_service.py +++ b/backend/ai_service.py @@ -95,9 +95,21 @@ def get_explain_prompt(code: str, lang: str) -> str: [Identify the primary DSA patterns, algorithms, or data structures used in this code, e.g. Sliding Window, DFS, Hash Table, Stack, Binary Search. Provide 1-2 sentences explaining why this pattern fits the problem.] DSA_PATTERN_END -LEETCODE_PROBLEMS_START -[Suggest 3 related LeetCode problems that practice this pattern. For each, output: Title | Link (use standard https://leetcode.com/problems/... urls). Use newlines to separate.] -LEETCODE_PROBLEMS_END +PLATFORM_PROBLEMS_START +[Suggest 4-5 related practice problems for this pattern. CRITICAL MANDATE: You MUST include problems from AT LEAST 3 DIFFERENT PLATFORMS (mix of GeeksforGeeks, HackerRank, Codeforces, Coding Ninjas, Codolio, and LeetCode). DO NOT output only LeetCode links. For each problem, output strictly on a new line: Platform | Title | Link (use actual valid problem URLs like https://www.geeksforgeeks.org/..., https://www.hackerrank.com/..., https://codeforces.com/..., https://leetcode.com/...).] +PLATFORM_PROBLEMS_END + +OPTIMIZED_CODE_START +[Provide the absolute most optimal version of the analyzed code in terms of time and space complexity. Do NOT use markdown code fences inside this tag.] +OPTIMIZED_CODE_END + +OPTIMIZED_TIME_COMPLEXITY_START +[State the exact Big-O time complexity of the optimized code, e.g. O(N) linear time.] +OPTIMIZED_TIME_COMPLEXITY_END + +OPTIMIZED_SPACE_COMPLEXITY_START +[State the exact Big-O space complexity of the optimized code, e.g. O(1) constant space.] +OPTIMIZED_SPACE_COMPLEXITY_END PRACTICE_EXERCISES_START [Provide 3 practice questions (Beginner, Intermediate, Advanced) that build on this concept. For each, output the difficulty, aim, and a brief sample input/output. Use clean Markdown structure.] @@ -154,11 +166,13 @@ def get_dry_run_prompt(code: str, lang: str, test_case: str = None) -> str: DRY_RUN_END FLOWCHART_START -[Generate a beautiful, logical Mermaid.js control flow diagram (graph TD) showing the execution flow of the code. -Use clean shapes and semantic nodes: -- Start/End steps: Use rounded brackets with double-quoted labels like `A("Start"):::startEnd` or `Z("End"):::startEnd`. -- Conditionals/Decisions: Use brace nodes with double-quoted labels like `B{{"Is condition met?"}}:::decision` (write this with double curly braces) and label paths clearly using `-- Yes -->` or `-- No -->`. -- Standard statements/process: Use square brackets with double-quoted labels like `C["Process/Action"]:::default`. +[Generate a clean, valid Mermaid.js control flow diagram (graph TD) showing the execution flow of the code. +CRITICAL MERMAID SYNTAX RULES: +1. ALWAYS wrap ALL node label texts inside double quotes, e.g. `A["Start"]:::startEnd` or `B["Initialize maxi = 0"]:::default`. +2. NEVER put spaces before `:::` (write `:::default`, NOT ` ::: default`). +3. DO NOT use semicolons `;` at the end of lines. +4. If using subgraphs, ALWAYS wrap the subgraph name in double quotes, e.g. `subgraph "findi(root, &maxi)"`. +5. Label decision paths strictly using `-->|"Yes"|`. Include these class definitions in the flowchart output to apply our custom color theme: classDef default fill:#122858,stroke:#3ecfb2,stroke-width:1.5px,color:#f3f5ed; @@ -168,7 +182,12 @@ def get_dry_run_prompt(code: str, lang: str, test_case: str = None) -> str: FLOWCHART_END RECURSION_TREE_START -[If the code uses recursion, generate a beautiful, logical Mermaid.js graph TD diagram representing the recursion tree of the execution with the actual arguments and values. Use custom color classes. If the code does not use recursion, write RECURSION_NONE. +[If the code uses recursion, generate a clean, valid Mermaid.js graph TD diagram representing the recursion tree of the execution with the actual arguments and values. Use custom color classes. If the code does not use recursion, write RECURSION_NONE. +CRITICAL MERMAID SYNTAX RULES: +1. ALWAYS wrap ALL node label texts in double quotes, e.g. `A["solve(5)"]:::default`. +2. NEVER put spaces before `:::`. +3. If using subgraphs, ALWAYS wrap the title in double quotes, e.g. `subgraph "solve(n)"`. + Include these class definitions in the flowchart output to apply our custom color theme: classDef default fill:#122858,stroke:#3ecfb2,stroke-width:1.5px,color:#f3f5ed; classDef decision fill:#0f2348,stroke:#c9a84c,stroke-width:1.5px,color:#c9a84c; @@ -196,13 +215,13 @@ async def analyze_code(code: str, language: str, test_case: str = None, api_key: prompt2 = get_dry_run_prompt(code, language, test_case) async def call_gemini(prompt: str): - for attempt in range(2): + for attempt in range(3): try: response = await asyncio.to_thread(client.models.generate_content, model=MODEL_NAME, contents=prompt) return response.text except Exception as e: - if "429" in str(e) and attempt == 0: - await asyncio.sleep(5) + if ("429" in str(e) or "RESOURCE_EXHAUSTED" in str(e)) and attempt < 2: + await asyncio.sleep(4 * (attempt + 1)) else: raise e @@ -220,7 +239,10 @@ async def call_gemini(prompt: str): "space_complexity": _extract(r1, "SPACE_COMPLEXITY_START", "SPACE_COMPLEXITY_END"), "suggestions": _extract(r1, "SUGGESTIONS_START", "SUGGESTIONS_END"), "dsa_pattern": _extract(r1, "DSA_PATTERN_START", "DSA_PATTERN_END"), - "leetcode_problems": _extract(r1, "LEETCODE_PROBLEMS_START", "LEETCODE_PROBLEMS_END"), + "platform_problems": _extract(r1, "PLATFORM_PROBLEMS_START", "PLATFORM_PROBLEMS_END"), + "optimized_code": _extract(r1, "OPTIMIZED_CODE_START", "OPTIMIZED_CODE_END"), + "optimized_time_complexity": _extract(r1, "OPTIMIZED_TIME_COMPLEXITY_START", "OPTIMIZED_TIME_COMPLEXITY_END"), + "optimized_space_complexity": _extract(r1, "OPTIMIZED_SPACE_COMPLEXITY_START", "OPTIMIZED_SPACE_COMPLEXITY_END"), "practice_exercises":_extract(r1, "PRACTICE_EXERCISES_START", "PRACTICE_EXERCISES_END"), "interview_questions":_extract(r1, "INTERVIEW_QUESTIONS_START", "INTERVIEW_QUESTIONS_END"), "algorithm": _extract(r1, "ALGORITHM_START", "ALGORITHM_END"), diff --git a/backend/test_features.py b/backend/test_features.py index 471d88b..a4a0c22 100644 --- a/backend/test_features.py +++ b/backend/test_features.py @@ -35,7 +35,10 @@ async def test_all(): print(f" Time complexity: {res.get('time_complexity')}") print("\n--- NEW LEARNING PLATFORM FIELDS ---") print(f" DSA Pattern: {res.get('dsa_pattern')}") - print(f" LeetCode Problems: {res.get('leetcode_problems')}") + print(f" Platform Problems: {res.get('platform_problems')}") + print(f" Optimized Code: {res.get('optimized_code')}") + print(f" Optimized Time Complexity: {res.get('optimized_time_complexity')}") + print(f" Optimized Space Complexity: {res.get('optimized_space_complexity')}") print(f" Practice Exercises: {res.get('practice_exercises')}") print(f" Interview Questions: {res.get('interview_questions')}") print(f" Algorithm: {res.get('algorithm')}") diff --git a/backend/test_mock_ai.py b/backend/test_mock_ai.py index 518683e..565c097 100644 --- a/backend/test_mock_ai.py +++ b/backend/test_mock_ai.py @@ -42,9 +42,23 @@ Simple Output Pattern DSA_PATTERN_END -LEETCODE_PROBLEMS_START -Hello World | https://leetcode.com/problems/hello-world -LEETCODE_PROBLEMS_END +PLATFORM_PROBLEMS_START +LeetCode | Hello World | https://leetcode.com/problems/hello-world +GeeksforGeeks | Print Hello World | https://www.geeksforgeeks.org/print-hello-world +HackerRank | Say Hello World | https://www.hackerrank.com/challenges/say-hello-world +PLATFORM_PROBLEMS_END + +OPTIMIZED_CODE_START +print('hello') +OPTIMIZED_CODE_END + +OPTIMIZED_TIME_COMPLEXITY_START +O(1) constant time +OPTIMIZED_TIME_COMPLEXITY_END + +OPTIMIZED_SPACE_COMPLEXITY_START +O(1) constant space +OPTIMIZED_SPACE_COMPLEXITY_END PRACTICE_EXERCISES_START Q1. Print something else. @@ -106,7 +120,7 @@ async def run_mock_test(): # Side effect function to return different mock responses call_count = 0 - def mock_generate_content(model, contents): + def mock_generate_content(model, contents, **kwargs): nonlocal call_count call_count += 1 if call_count == 1: @@ -124,6 +138,10 @@ def mock_generate_content(model, contents): assert result["time_complexity"] == "O(1) constant time", f"Got {result['time_complexity']}" assert result["recursion_tree"] == "RECURSION_NONE", f"Got {result['recursion_tree']}" assert "Prints hello" in result["dry_run"], f"Got {result['dry_run']}" + assert "GeeksforGeeks" in result["platform_problems"], f"Got {result['platform_problems']}" + assert result["optimized_code"] == "print('hello')", f"Got {result['optimized_code']}" + assert result["optimized_time_complexity"] == "O(1) constant time", f"Got {result['optimized_time_complexity']}" + assert result["optimized_space_complexity"] == "O(1) constant space", f"Got {result['optimized_space_complexity']}" print("[SUCCESS] Unit test passed! Parallel prompt queries executed and parsed correctly.") diff --git a/frontend/index.html b/frontend/index.html index c9919ff..16cdfb2 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -65,9 +65,12 @@ background: var(--bg); color: var(--tx1); font-family: var(--fb); + height: 100vh; min-height: 100vh; + display: flex; + flex-direction: column; -webkit-font-smoothing: antialiased; - overflow-x: hidden + overflow: hidden } .hidden { @@ -85,10 +88,10 @@ } .hdr { - position: sticky; - top: 0; + position: relative; z-index: 100; height: 56px; + flex-shrink: 0; background: rgba(10, 25, 49, .95); backdrop-filter: blur(20px); border-bottom: 1px solid var(--b1) @@ -218,14 +221,17 @@ .layout { max-width: 1480px; + width: 100%; margin: 0 auto; - padding: 18px 22px; + padding: 14px 22px; display: flex; flex-direction: row; - min-height: calc(100vh - 56px); + flex: 1 1 0%; + height: calc(100vh - 56px); position: relative; z-index: 1; gap: 0; + overflow: hidden; } .resizer { @@ -279,7 +285,8 @@ gap: 12px; box-shadow: 0 8px 32px rgba(0, 0, 0, .4); position: relative; - overflow: hidden + height: 100%; + overflow-y: auto; } .panel::before { @@ -292,9 +299,20 @@ background: linear-gradient(90deg, transparent, rgba(201, 168, 76, .22), transparent) } + .panel::-webkit-scrollbar, + .pr::-webkit-scrollbar { + width: 4px + } + + .panel::-webkit-scrollbar-thumb, + .pr::-webkit-scrollbar-thumb { + background: var(--b2); + border-radius: 2px + } + .pr { overflow-y: auto; - max-height: calc(100vh - 56px - 36px) + height: 100%; } .pr::-webkit-scrollbar { @@ -2090,6 +2108,100 @@ opacity: 1; transform: translateY(0); } + + /* Glassmorphic Multi-Platform Dropdown & Optimized Code Container */ + .dsa-hdr-wrap { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-bottom: 10px; + } + + .dsa-platform-sel-wr { + position: relative; + display: inline-flex; + align-items: center; + } + + .dsa-platform-select { + background: var(--bg3); + border: 1px solid var(--b2); + border-radius: var(--r1); + color: var(--tx1); + font-family: var(--fui); + font-size: 0.68rem; + font-weight: 600; + padding: 5px 26px 5px 10px; + outline: none; + cursor: pointer; + appearance: none; + -webkit-appearance: none; + backdrop-filter: blur(8px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + transition: all 0.25s ease; + } + + .dsa-platform-select:hover { + background: var(--bg4); + border-color: var(--gold); + color: var(--gold); + box-shadow: 0 4px 16px rgba(201, 168, 76, 0.15); + } + + .dsa-platform-select:focus { + border-color: var(--blue); + box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.25); + } + + .optcode-card { + background: var(--bg3); + border: 1px solid var(--b1); + border-radius: var(--r2); + padding: 14px; + margin-top: 14px; + margin-bottom: 16px; + transition: all 0.3s ease; + } + + .optcode-card:hover { + border-color: rgba(62, 207, 178, 0.3); + box-shadow: 0 6px 20px rgba(62, 207, 178, 0.08); + } + + .optcode-hdr { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 10px; + } + + .optcode-badges { + display: flex; + gap: 8px; + align-items: center; + margin-bottom: 8px; + } + + .optcode-badge { + font-family: var(--fm); + font-size: 0.66rem; + padding: 3px 8px; + border-radius: 4px; + font-weight: 600; + } + + .optcode-badge.time { + background: var(--gold2); + border: 1px solid rgba(201, 168, 76, 0.25); + color: var(--gold); + } + + .optcode-badge.space { + background: var(--teal2); + border: 1px solid rgba(62, 207, 178, 0.25); + color: var(--teal); + } @@ -2338,6 +2450,21 @@

Ready to analyze

Optimization Suggestions
+ + +