@draig/lexis-two 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +3 -3
  2. package/package.json +7 -2
  3. package/.claude-plugin/marketplace.json +0 -29
  4. package/.claude-plugin/plugin.json +0 -9
  5. package/.codex-plugin/plugin.json +0 -31
  6. package/.env.example +0 -8
  7. package/.github/FUNDING.yml +0 -1
  8. package/.github/copilot-instructions.md +0 -47
  9. package/.github/plugin/marketplace.json +0 -20
  10. package/.github/plugin/plugin.json +0 -16
  11. package/.github/workflows/deploy-site.yml +0 -53
  12. package/.github/workflows/test.yml +0 -29
  13. package/AUDIT.md +0 -74
  14. package/SPECXIS.md +0 -576
  15. package/benchmarks/README.md +0 -114
  16. package/benchmarks/arms/baseline.js +0 -2
  17. package/benchmarks/arms/caveman-SKILL.md +0 -67
  18. package/benchmarks/arms/caveman.js +0 -8
  19. package/benchmarks/arms/lexis-two.js +0 -10
  20. package/benchmarks/arms/ponytail.js +0 -6
  21. package/benchmarks/behavior.js +0 -58
  22. package/benchmarks/behavior.yaml +0 -40
  23. package/benchmarks/benchmark-local.py +0 -156
  24. package/benchmarks/benchmark-opencode-go.js +0 -294
  25. package/benchmarks/correctness.js +0 -294
  26. package/benchmarks/lib/aggregate-opencode-go.js +0 -103
  27. package/benchmarks/lib/load-env.js +0 -31
  28. package/benchmarks/lib/opencode-go-client.js +0 -151
  29. package/benchmarks/loc.js +0 -13
  30. package/benchmarks/opencode-go-models.json +0 -31
  31. package/benchmarks/promptfooconfig.yaml +0 -41
  32. package/benchmarks/prompts.json +0 -15
  33. package/benchmarks/render-opencode-go-report.js +0 -28
  34. package/benchmarks/results/2026-06-15-llama3.2-local.md +0 -76
  35. package/benchmarks/results/2026-06-16-opencode-go.md +0 -56
  36. package/benchmarks/results/opencode-go-2026-06-16-report.html +0 -226
  37. package/benchmarks/results/opencode-go-2026-06-16.json +0 -1339
  38. package/docs/assets/lexis-two-nobg.png +0 -0
  39. package/docs/assets/logo.png +0 -0
  40. package/docs/assets/logo.svg +0 -4
  41. package/docs/portability.md +0 -147
  42. package/docs/site.md +0 -52
  43. package/gemini-extension.json +0 -7
  44. package/pi-extension/index.js +0 -161
  45. package/pi-extension/package.json +0 -8
  46. package/pi-extension/test/extension.test.js +0 -89
  47. package/pi-extension/test/helpers.test.js +0 -35
  48. package/scripts/check-rule-copies.js +0 -82
  49. package/site/astro.config.mjs +0 -18
  50. package/site/package-lock.json +0 -4913
  51. package/site/package.json +0 -14
  52. package/site/public/CNAME +0 -1
  53. package/site/public/assets/lexis-two-nobg.png +0 -0
  54. package/site/public/assets/logo.png +0 -0
  55. package/site/public/assets/logo.svg +0 -4
  56. package/site/public/robots.txt +0 -4
  57. package/site/src/components/Adapt.astro +0 -33
  58. package/site/src/components/Benchmarks.astro +0 -232
  59. package/site/src/components/Commands.astro +0 -33
  60. package/site/src/components/Ecosystem.astro +0 -30
  61. package/site/src/components/Example.astro +0 -77
  62. package/site/src/components/Footer.astro +0 -28
  63. package/site/src/components/Header.astro +0 -87
  64. package/site/src/components/Hero.astro +0 -58
  65. package/site/src/components/Home.astro +0 -46
  66. package/site/src/components/Hosts.astro +0 -62
  67. package/site/src/components/Install.astro +0 -143
  68. package/site/src/components/LanguageSwitcher.astro +0 -82
  69. package/site/src/components/Philosophy.astro +0 -23
  70. package/site/src/components/Stacks.astro +0 -33
  71. package/site/src/components/Suggested.astro +0 -39
  72. package/site/src/data/opencode-go-benchmark.json +0 -230
  73. package/site/src/i18n/en.ts +0 -155
  74. package/site/src/i18n/es.ts +0 -158
  75. package/site/src/i18n/index.ts +0 -14
  76. package/site/src/layouts/Layout.astro +0 -114
  77. package/site/src/pages/benchmarks.astro +0 -4
  78. package/site/src/pages/es/benchmarks.astro +0 -4
  79. package/site/src/pages/es/index.astro +0 -10
  80. package/site/src/pages/index.astro +0 -10
  81. package/site/src/styles/global.css +0 -780
  82. package/site/tsconfig.json +0 -3
  83. package/tests/behavior.test.js +0 -80
  84. package/tests/commands.test.js +0 -40
  85. package/tests/copilot-plugin.test.js +0 -33
  86. package/tests/correctness.test.js +0 -191
  87. package/tests/gemini-extension.test.js +0 -78
  88. package/tests/hooks-windows.test.js +0 -48
  89. package/tests/hooks.test.js +0 -177
  90. package/tests/opencode-plugin.test.js +0 -64
@@ -1,1339 +0,0 @@
1
- {
2
- "date": "2026-06-16",
3
- "repeat": 3,
4
- "models": [
5
- "kimi-k2.6",
6
- "deepseek-v4-pro",
7
- "qwen3.7-max",
8
- "minimax-m3"
9
- ],
10
- "arms": [
11
- "baseline",
12
- "lexis-two"
13
- ],
14
- "tasks": [
15
- {
16
- "id": "email",
17
- "prompt": "Write me a Python function that validates email addresses."
18
- },
19
- {
20
- "id": "debounce",
21
- "prompt": "Add debounce to a search input in vanilla JavaScript. It currently fires an API call on every keystroke."
22
- },
23
- {
24
- "id": "csv-sum",
25
- "prompt": "Write Python code that reads sales.csv and sums the 'amount' column."
26
- },
27
- {
28
- "id": "countdown",
29
- "prompt": "Build me a countdown timer component in React that counts down from a given number of seconds."
30
- },
31
- {
32
- "id": "rate-limit",
33
- "prompt": "Add rate limiting to my FastAPI endpoint so users can't spam it."
34
- }
35
- ],
36
- "results": {
37
- "kimi-k2.6": {
38
- "baseline": {
39
- "email": [
40
- {
41
- "loc": 60,
42
- "correct": true,
43
- "timeSec": 14.996,
44
- "usage": {
45
- "inputTokens": 18,
46
- "outputTokens": 3228
47
- },
48
- "response": "Here are three approaches, ranging from a practical regex to a robust, RFC-compliant solution.\n\n### 1. Practical Regex (No dependencies)\nBest for simple forms and quick validation. It catches 99% of invalid inputs without being unreadable.\n\n```python\nimport re\n\ndef validate_email(email: str) -> bool:\n \"\"\"\n Validates email format with practical constraints.\n Returns True if valid, False otherwise.\n \"\"\"\n if not email or not isinstance(email, str):\n return False\n \n email = email.strip().lower()\n \n # Length check (RFC 5321)\n if len(email) > 254:\n return False\n \n # Basic pattern: local@domain.tld\n pattern = r'^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$'\n if not re.match(pattern, email):\n return False\n \n # Split for extra structural checks\n local, domain = email.rsplit('@', 1)\n \n # Local part max 64 chars\n if len(local) > 64:\n return False\n \n # No consecutive dots\n if '..' in local or '..' in domain:\n return False\n \n # No leading/trailing dots in local part\n if local.startswith('.') or local.endswith('.'):\n return False\n \n # Domain can't start/end with hyphen\n if domain.startswith('-') or domain.endswith('-'):\n return False\n \n return True\n\n\n# --- Test cases ---\nif __name__ == \"__main__\":\n tests = [\n \"user@example.com\", # True\n \"user.name+tag@example.co.uk\", # True\n \"user..name@example.com\", # False (consecutive dots)\n \".user@example.com\", # False (leading dot)\n \"user@example\", # False (no TLD)\n \"user@-example.com\", # False (leading hyphen)\n \"a\" * 65 + \"@example.com\", # False (local part too long)\n ]\n \n for email in tests:\n print(f\"{email:<35} -> {validate_email(email)}\")\n```\n\n### 2. Built-in `email` module (More robust, RFC-compliant)\nPython 3.6+ has a built-in parser that is far more reliable than any regex. Use this if you want to avoid regex nightmares.\n\n```python\nfrom email.headerregistry import Address\nfrom email.errors import HeaderParseError\n\ndef validate_email_builtin(email: str) -> bool:\n \"\"\"Validates email using Python's built-in RFC parser.\"\"\"\n if not email or not isinstance(email, str):\n return False\n \n try:\n Address(addr_spec=email.strip())\n return True\n except (HeaderParseError, ValueError, TypeError):\n return False\n```\n\n### 3. Production-grade (Recommended for real apps)\nIf you are building a real application, use the **`email-validator`** library. It validates syntax, normalizes Unicode, checks domain length, and can optionally verify MX records.\n\n```bash\npip install email-validator\n```\n\n```python\nfrom email_validator import validate_email, EmailNotValidError\n\ndef validate_email_production(email: str) -> dict | None:\n try:\n info = validate_email(email.strip(), check_deliverability=False)\n return {\n \"valid\": True,\n \"normalized\": info.normalized, # e.g., Test.User+spam@gmail.com -> test.user@gmail.com\n \"domain\": info.domain,\n }\n except EmailNotValidError as e:\n return {\"valid\": False, \"error\": str(e)}\n\n# Usage\nresult = validate_email_production(\"User@Example.COM\")\n# Returns: {'valid': True, 'normalized': 'user@example.com', 'domain': 'example.com'}\n```\n\n### Important Caveats\n- **Validation ≠ Verification**: These check *format*, not whether the inbox exists or can receive mail.\n- **Don't over-regex**: The \"perfect\" RFC 5322 email regex is thousands of characters long and impossible to maintain. Use a library for strict validation.\n- **Unicode/International emails**: The regex above is ASCII-only. If you need to support `用户@例子.中国`, use the built-in `email` module or the `email-validator` library."
49
- },
50
- {
51
- "loc": 46,
52
- "correct": false,
53
- "timeSec": 19.619,
54
- "usage": {
55
- "inputTokens": 18,
56
- "outputTokens": 4256
57
- },
58
- "response": "Here are three approaches, from **built-in & robust** to **lightweight** to **production-grade**.\n\n### Option 1: Built-in (Recommended for most apps)\nUses Python’s standard `email` module. It understands RFC 5322 syntax and requires no third-party dependencies.\n\n```python\nfrom email.headerregistry import Address\n\ndef validate_email(email):\n \"\"\"\n Validate email using Python's built-in email library.\n Returns True for valid internet email addresses, False otherwise.\n \"\"\"\n if not isinstance(email, str) or not email.strip():\n return False\n\n email = email.strip()\n\n # RFC 5321: total length must not exceed 254 characters\n if len(email) > 254:\n return False\n\n try:\n addr = Address(addr_spec=email)\n \n # Must have both local and domain parts\n if not addr.username or not addr.domain:\n return False\n \n # For internet email, we typically require a dot in the domain\n # (e.g. user@example.com, not just user@localhost)\n if '.' not in addr.domain:\n return False\n \n return True\n except (ValueError, TypeError):\n return False\n\n\n# Examples\nprint(validate_email(\"user@example.com\")) # True\nprint(validate_email(\"user.name+tag@example.co.uk\")) # True\nprint(validate_email(\"user@localhost\")) # False\nprint(validate_email(\"bad email\")) # False\nprint(validate_email(\"user@\")) # False\n```\n\n---\n\n### Option 2: Lightweight Regex\nIf you just need a quick format check without importing anything heavy. \n**Note:** This rejects some obscure-but-valid addresses (e.g. IP address domains, quoted strings) and accepts a few rare invalid ones.\n\n```python\nimport re\n\ndef validate_email_regex(email):\n \"\"\"Simple, fast regex validation. Good for basic UI feedback.\"\"\"\n if not isinstance(email, str):\n return False\n\n email = email.strip()\n \n # Overall length limit\n if len(email) > 254:\n return False\n\n # Local part must be <= 64 chars per RFC 5321\n if len(email.split('@')[0]) > 64:\n return False\n\n pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')\n return bool(pattern.match(email))\n```\n\n---\n\n### Option 3: Production-grade (Best)\nInstall the [`email-validator`](https://pypi.org/project/email-validator/) library. It handles internationalized domains (IDN), quoted local parts, and can even check DNS/MX records if you want.\n\n```bash\npip install email-validator\n```\n\n```python\nfrom email_validator import validate_email, EmailNotValidError\n\ndef validate_email_production(email):\n \"\"\"Strict validation. Recommended for production backends.\"\"\"\n try:\n # check_deliverability=True does a DNS/MX lookup (slower)\n validate_email(email, check_deliverability=False)\n return True\n except EmailNotValidError:\n return False\n```\n\n---\n\n### Important caveat\n**Format validation alone cannot prove an email is real.** The only way to truly validate an email address is to send a confirmation message with a verification link or code."
59
- },
60
- {
61
- "loc": 43,
62
- "correct": false,
63
- "timeSec": 7.094,
64
- "usage": {
65
- "inputTokens": 18,
66
- "outputTokens": 1430
67
- },
68
- "response": "Here are two approaches, depending on your needs:\n\n## Option 1: Using the `email-validator` library (Recommended)\n\nThis is the most robust approach for production. It properly parses the address according to RFC specs and validates the domain format.\n\n```python\nfrom email_validator import validate_email, EmailNotValidError\n\ndef is_valid_email(email: str) -> bool:\n \"\"\"\n Validate an email address using the email-validator library.\n \n Args:\n email: The email address to validate\n \n Returns:\n bool: True if valid, False otherwise\n \"\"\"\n try:\n # check_deliverability=False skips DNS lookup (faster, just checks format)\n validate_email(email, check_deliverability=False)\n return True\n except EmailNotValidError:\n return False\n\n\n# Usage\nif __name__ == \"__main__\":\n print(is_valid_email(\"user@example.com\")) # True\n print(is_valid_email(\"user.name+tag@example.co\")) # True\n print(is_valid_email(\"invalid-email\")) # False\n print(is_valid_email(\"user@.com\")) # False\n```\n\n**Install it with:** `pip install email-validator`\n\n---\n\n## Option 2: Pure Python with regex (No dependencies)\n\nUse this if you cannot install external packages. Note that this is a **practical** check, not a strict RFC-compliant one (email validation via regex is notoriously complex).\n\n```python\nimport re\n\ndef is_valid_email(email: str) -> bool:\n \"\"\"\n Validate an email address using regex.\n Checks for a reasonable local part, @ symbol, and domain with TLD.\n \n Args:\n email: The email address to validate\n \n Returns:\n bool: True if valid, False otherwise\n \"\"\"\n if not email or len(email) > 254:\n return False\n \n # Practical regex for common email formats\n pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n \n if not re.match(pattern, email):\n return False\n \n # Additional check: local part (before @) shouldn't exceed 64 chars\n local_part = email.split('@')[0]\n if len(local_part) > 64:\n return False\n \n return True\n\n\n# Usage\nif __name__ == \"__main__\":\n print(is_valid_email(\"user@example.com\")) # True\n print(is_valid_email(\"user@sub.example.co.uk\")) # True\n print(is_valid_email(\"user name@example.com\")) # False (space)\n print(is_valid_email(\"user@example\")) # False (no TLD)\n```\n\n---\n\n### Important Caveats\n\nNo validation function can confirm that:\n1. **The email actually exists** — it only checks format\n2. **The domain has a mail server** — you'd need DNS/deliverability checks for that\n3. **The user owns the inbox** — you must send a confirmation email to verify that\n\n**Recommendation:** Use Option 1 for production applications, and always send a verification email if the address matters."
69
- }
70
- ],
71
- "debounce": [
72
- {
73
- "loc": 63,
74
- "correct": true,
75
- "timeSec": 6.804,
76
- "usage": {
77
- "inputTokens": 31,
78
- "outputTokens": 1334
79
- },
80
- "response": "Here's a complete, production-ready solution. The key is to **create the debounced function once** (not inside the event listener) and use an `AbortController` to cancel any in-flight requests if the user keeps typing.\n\n### 1. The Debounce Utility\n\n```javascript\nfunction debounce(func, wait) {\n let timeoutId;\n\n return function (...args) {\n const context = this;\n \n clearTimeout(timeoutId);\n \n timeoutId = setTimeout(() => {\n func.apply(context, args);\n }, wait);\n };\n}\n```\n\n### 2. Full Working Example\n\n```html\n<input type=\"text\" id=\"search\" placeholder=\"Search...\" autocomplete=\"off\" />\n<div id=\"results\"></div>\n```\n\n```javascript\nconst searchInput = document.getElementById('search');\nconst resultsContainer = document.getElementById('results');\n\n// Store AbortController so we can cancel previous requests\nlet currentAbortController = null;\n\nasync function fetchResults(query) {\n // Cancel previous request if it exists\n if (currentAbortController) {\n currentAbortController.abort();\n }\n \n currentAbortController = new AbortController();\n \n try {\n resultsContainer.textContent = 'Loading...';\n \n const response = await fetch(\n `https://api.example.com/search?q=${encodeURIComponent(query)}`,\n { signal: currentAbortController.signal }\n );\n \n if (!response.ok) throw new Error('Network response was not ok');\n \n const data = await response.json();\n renderResults(data);\n \n } catch (error) {\n if (error.name === 'AbortError') {\n // Request was cancelled because user typed more; ignore silently\n return;\n }\n resultsContainer.textContent = 'Error fetching results';\n console.error(error);\n }\n}\n\n// Create debounced version ONCE outside the listener\nconst debouncedSearch = debounce((event) => {\n const query = event.target.value.trim();\n \n if (!query) {\n resultsContainer.innerHTML = '';\n return;\n }\n \n fetchResults(query);\n}, 300); // 300ms wait after last keystroke\n\n// Attach listener\nsearchInput.addEventListener('input', debouncedSearch);\n\n// Optional: Cleanup on page unload to prevent memory leaks\nwindow.addEventListener('beforeunload', () => {\n if (currentAbortController) {\n currentAbortController.abort();\n }\n});\n```\n\n### Key Points\n\n| Pattern | Why It Matters |\n|--------|----------------|\n| **Define `debounce` once** | If you put `debounce()` inside `addEventListener`, every keystroke creates a new timer and nothing gets debounced. |\n| **Use `AbortController`** | Prevents race conditions where an older slow request finishes after a newer fast one, overwriting the results. |\n| **Handle `AbortError`** | Don't show error messages to the user when a request is intentionally cancelled. |\n| **Trim empty strings** | Avoids firing API calls for whitespace or empty input. |\n\n### If you need to cancel the pending search manually\n\n```javascript\n// Clear the pending debounce timer (e.g., if user clears the input)\nfunction clearPendingSearch() {\n // We need to expose the timeout ID from our debounce function\n}\n\n// Better debounce with a .cancel() method\nfunction debounce(func, wait) {\n let timeoutId;\n\n const debounced = function (...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), wait);\n };\n\n debounced.cancel = () => clearTimeout(timeoutId);\n \n return debounced;\n}\n\n// Usage\ndebouncedSearch.cancel(); // Prevents the next pending call from firing\n```"
81
- },
82
- {
83
- "loc": 64,
84
- "correct": false,
85
- "timeSec": 6.997,
86
- "usage": {
87
- "inputTokens": 31,
88
- "outputTokens": 1257
89
- },
90
- "response": "Here's a clean vanilla JS implementation. The key is wrapping your API call in a **debounce** function that resets a timer on every keystroke:\n\n```javascript\n// Reusable debounce utility\nfunction debounce(func, delay) {\n let timeoutId;\n return function(...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n\n// Your actual search function\nasync function performSearch(query) {\n if (!query) return;\n \n console.log('Fetching results for:', query);\n \n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);\n const data = await response.json();\n renderResults(data);\n}\n\n// Create debounced version (300ms is a common sweet spot)\nconst debouncedSearch = debounce(performSearch, 300);\n\n// Attach to input\ndocument.getElementById('search-input').addEventListener('input', (e) => {\n debouncedSearch(e.target.value);\n});\n```\n\n---\n\n### Full Working Example\n\n```html\n<input type=\"text\" id=\"search\" placeholder=\"Search...\" />\n<div id=\"results\"></div>\n\n<script>\n function debounce(fn, delay) {\n let timer;\n return function(...args) {\n clearTimeout(timer);\n timer = setTimeout(() => fn.apply(this, args), delay);\n };\n }\n\n const searchInput = document.getElementById('search');\n const resultsDiv = document.getElementById('results');\n\n async function fetchResults(query) {\n if (!query) {\n resultsDiv.innerHTML = '';\n return;\n }\n \n resultsDiv.innerHTML = '<p>Loading...</p>';\n \n try {\n const res = await fetch(`https://api.example.com/search?q=${query}`);\n const data = await res.json();\n resultsDiv.innerHTML = data.map(item => `<p>${item.name}</p>`).join('');\n } catch (err) {\n resultsDiv.innerHTML = '<p>Error fetching results</p>';\n }\n }\n\n const debouncedFetch = debounce(fetchResults, 300);\n searchInput.addEventListener('input', (e) => debouncedFetch(e.target.value));\n</script>\n```\n\n---\n\n### Bonus: Cancel Pending Requests\n\nIf the user types quickly, you might still get **race conditions** (an older request finishing after a newer one). Combine debounce with an `AbortController`:\n\n```javascript\nlet abortController;\n\nconst debouncedSearch = debounce(async (query) => {\n if (abortController) abortController.abort();\n \n abortController = new AbortController();\n \n try {\n const res = await fetch(`/api/search?q=${query}`, {\n signal: abortController.signal\n });\n const data = await res.json();\n renderResults(data);\n } catch (err) {\n if (err.name === 'AbortError') return; // Ignore cancellations\n console.error('Search failed:', err);\n }\n}, 300);\n```\n\n### Key Points\n- **Delay**: `300ms` is standard for search. Adjust based on your API latency.\n- `.apply(this, args)` preserves the correct `this` context if you pass a method instead of an arrow function.\n- Always handle the **empty query** case inside the debounced function so you don't fire a pointless request."
91
- },
92
- {
93
- "loc": 52,
94
- "correct": true,
95
- "timeSec": 10.502,
96
- "usage": {
97
- "inputTokens": 31,
98
- "outputTokens": 2435
99
- },
100
- "response": "Here is a clean, reusable debounce implementation and how to wire it up to your search input.\n\n### 1. The debounce utility\n\n```javascript\nfunction debounce(func, delay) {\n let timeoutId;\n return function(...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n```\n\n### 2. Complete search example\n\nThis waits **300ms** after the user stops typing before calling the API. It also uses an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to cancel any in-flight request if the user starts typing again.\n\n```javascript\nconst searchInput = document.getElementById('search');\nconst resultsContainer = document.getElementById('results');\n\n// Keep track of the active request so we can cancel it\nlet currentController = null;\n\nasync function fetchResults(query) {\n // Cancel previous request if it exists\n if (currentController) {\n currentController.abort();\n }\n currentController = new AbortController();\n\n // Don't search on empty input\n if (!query.trim()) {\n resultsContainer.innerHTML = '';\n return;\n }\n\n try {\n resultsContainer.innerHTML = '<p>Loading...</p>';\n\n const response = await fetch(\n `/api/search?q=${encodeURIComponent(query)}`,\n { signal: currentController.signal }\n );\n\n if (!response.ok) throw new Error('Network response was not ok');\n\n const data = await response.json();\n renderResults(data);\n } catch (error) {\n // Ignore abort errors (they're expected when typing quickly)\n if (error.name === 'AbortError') return;\n \n resultsContainer.innerHTML = '<p>Error fetching results.</p>';\n }\n}\n\n// Wrap the handler in debounce\nconst debouncedSearch = debounce((event) => {\n fetchResults(event.target.value);\n}, 300);\n\nsearchInput.addEventListener('input', debouncedSearch);\n```\n\n### 3. How it works\n\n| Step | What happens |\n|------|--------------|\n| 1 | User types a key. |\n| 2 | `input` event fires, calling the debounced wrapper. |\n| 3 | `clearTimeout` cancels the previous timer. |\n| 4 | A new 300ms timer starts. |\n| 5 | If the user types another key before 300ms elapses, repeat from step 2. |\n| 6 | Once the user pauses for 300ms, the timer fires and executes `fetchResults`. |\n\n### 4. Optional: Cleanup on page unmount\n\nIf you ever need to remove the listener or teardown the component, keep the reference to the debounced function:\n\n```javascript\n// Remove listener later\nsearchInput.removeEventListener('input', debouncedSearch);\n```\n\nIf you also need to cancel a pending timer (e.g., the user navigates away while the timer is waiting), you can extend the debounce to expose a `cancel` method:\n\n```javascript\nfunction debounce(func, delay) {\n let timeoutId;\n \n const debounced = function(...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), delay);\n };\n \n debounced.cancel = () => clearTimeout(timeoutId);\n \n return debounced;\n}\n\n// Usage\nconst debouncedSearch = debounce((e) => fetchResults(e.target.value), 300);\n\n// Later, when tearing down\ndebouncedSearch.cancel();\nsearchInput.removeEventListener('input', debouncedSearch);\n```"
101
- }
102
- ],
103
- "csv-sum": [
104
- {
105
- "loc": 18,
106
- "correct": true,
107
- "timeSec": 4.095,
108
- "usage": {
109
- "inputTokens": 23,
110
- "outputTokens": 761
111
- },
112
- "response": "Here are two approaches, depending on whether you have **pandas** installed:\n\n### Option 1: Pure Python (no dependencies)\nUses the built-in `csv` module. This is safer if your data might have missing or malformed values.\n\n```python\nimport csv\n\ntotal = 0.0\ncount = 0\n\nwith open('sales.csv', newline='', encoding='utf-8') as f:\n reader = csv.DictReader(f)\n for row in reader:\n try:\n amount = float(row['amount'])\n total += amount\n count += 1\n except (ValueError, KeyError):\n # Skips rows where 'amount' is missing or not a number\n continue\n\nprint(f\"Total amount: {total:,.2f}\")\nprint(f\"Rows summed: {count}\")\n```\n\n### Option 2: Using Pandas (shorter, best for data analysis)\n```python\nimport pandas as pd\n\ndf = pd.read_csv('sales.csv')\ntotal = df['amount'].sum()\n\nprint(f\"Total amount: {total:,.2f}\")\n```\n\n**Notes:**\n- Replace `'amount'` with the exact column header name if it differs in case (e.g., `'Amount'`).\n- If the CSV uses a different delimiter (like semicolons), add `delimiter=';'` to `csv.DictReader` or `pd.read_csv('sales.csv', sep=';')`."
113
- },
114
- {
115
- "loc": 12,
116
- "correct": true,
117
- "timeSec": 5.53,
118
- "usage": {
119
- "inputTokens": 23,
120
- "outputTokens": 1077
121
- },
122
- "response": "Here are two ways to do this:\n\n### Option 1: Using the built-in `csv` module (no extra libraries)\n```python\nimport csv\n\ntotal = 0.0\n\nwith open('sales.csv', 'r', newline='') as file:\n reader = csv.DictReader(file)\n for row in reader:\n amount = float(row['amount'].strip())\n total += amount\n\nprint(f\"Total amount: {total:.2f}\")\n```\n\n### Option 2: Using **pandas** (best for large files or data analysis)\n```python\nimport pandas as pd\n\ndf = pd.read_csv('sales.csv')\ntotal = df['amount'].sum()\n\nprint(f\"Total amount: {total:.2f}\")\n```\n\n**Notes:**\n- If your CSV has currency symbols (e.g., `$1,200.50`), use `amount = float(row['amount'].replace('$', '').replace(',', ''))` before converting.\n- The `newline=''` argument in the `csv` version is recommended by Python's documentation to prevent blank-line issues on Windows."
123
- },
124
- {
125
- "loc": 34,
126
- "correct": true,
127
- "timeSec": 5.767,
128
- "usage": {
129
- "inputTokens": 23,
130
- "outputTokens": 1217
131
- },
132
- "response": "Here are two ways to do it, depending on whether you want to use an external library or stick to the standard library.\n\n### Option 1: Using **pandas** (best for data analysis)\n\n```python\nimport pandas as pd\n\ntry:\n df = pd.read_csv('sales.csv')\n total = df['amount'].sum()\n print(f\"Total amount: {total:.2f}\")\nexcept FileNotFoundError:\n print(\"Error: sales.csv not found.\")\nexcept KeyError:\n print(\"Error: 'amount' column not found in the CSV.\")\nexcept Exception as e:\n print(f\"An error occurred: {e}\")\n```\n\n**Note:** Install pandas first if you haven't already: \n`pip install pandas`\n\n---\n\n### Option 2: Using the **csv** module (no installation required)\n\n```python\nimport csv\n\ndef sum_amount_column(filename):\n total = 0.0\n row_count = 0\n\n try:\n with open(filename, 'r', newline='') as file:\n reader = csv.DictReader(file)\n \n if 'amount' not in reader.fieldnames:\n raise KeyError(f\"'amount' column not found. Available columns: {reader.fieldnames}\")\n \n for row in reader:\n amount_str = row['amount'].strip()\n if amount_str: # skip empty values\n total += float(amount_str)\n row_count += 1\n\n print(f\"Total amount: {total:.2f} (from {row_count} rows)\")\n return total\n\n except FileNotFoundError:\n print(f\"Error: '{filename}' not found.\")\n except ValueError as e:\n print(f\"Error: Could not convert a value to float. Check your data: {e}\")\n except KeyError as e:\n print(f\"Error: {e}\")\n\n# Run it\nsum_amount_column('sales.csv')\n```\n\n**Tip:** If your `amount` column contains currency symbols (e.g., `$1,234.56`), replace `float(amount_str)` with a cleaning step like `float(amount_str.replace('$', '').replace(',', ''))`."
133
- }
134
- ],
135
- "countdown": [
136
- {
137
- "loc": 403,
138
- "correct": true,
139
- "timeSec": 22.661,
140
- "usage": {
141
- "inputTokens": 26,
142
- "outputTokens": 5799
143
- },
144
- "response": "```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Flux Chronometer | Interactive React Timer</title>\n \n <!-- Tailwind CSS -->\n <script src=\"https://cdn.tailwindcss.com\"></script>\n \n <!-- React & ReactDOM -->\n <script crossorigin src=\"https://unpkg.com/react@18/umd/react.development.js\"></script>\n <script crossorigin src=\"https://unpkg.com/react-dom@18/umd/react-dom.development.js\"></script>\n \n <!-- Babel for JSX -->\n <script src=\"https://unpkg.com/@babel/standalone/babel.min.js\"></script>\n \n <!-- Google Fonts -->\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@300;400;600;800&display=swap\" rel=\"stylesheet\">\n \n <!-- Lucide Icons -->\n <script src=\"https://unpkg.com/lucide@latest\"></script>\n\n <style>\n body {\n font-family: 'Inter', sans-serif;\n background-color: #0f172a;\n color: #e2e8f0;\n overflow: hidden; /* Prevent scrollbars for full screen app feel */\n }\n\n /* Custom Scrollbar for lists */\n .custom-scrollbar::-webkit-scrollbar {\n width: 6px;\n }\n .custom-scrollbar::-webkit-scrollbar-track {\n background: #1e293b;\n }\n .custom-scrollbar::-webkit-scrollbar-thumb {\n background: #475569;\n border-radius: 3px;\n }\n .custom-scrollbar::-webkit-scrollbar-thumb:hover {\n background: #64748b;\n }\n\n /* Animations */\n @keyframes pulse-ring {\n 0% { transform: scale(1); opacity: 0.5; }\n 100% { transform: scale(1.1); opacity: 0; }\n }\n \n @keyframes tick-tock {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .animate-pulse-ring {\n animation: pulse-ring 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n .font-mono {\n font-family: 'JetBrains Mono', monospace;\n }\n\n /* Glassmorphism */\n .glass-panel {\n background: rgba(30, 41, 59, 0.7);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border: 1px solid rgba(255, 255, 255, 0.1);\n box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Input focus styles */\n input[type=number]::-webkit-inner-spin-button, \n input[type=number]::-webkit-outer-spin-button { \n -webkit-appearance: none; \n margin: 0; \n }\n </style>\n</head>\n<body class=\"h-screen w-full flex items-center justify-center bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900\">\n\n <div id=\"root\" class=\"w-full h-full flex items-center justify-center p-4\"></div>\n\n <script type=\"text/babel\">\n const { useState, useEffect, useRef } = React;\n \n // --- Icon Components (using SVG directly for reliability) ---\n const PlayIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>\n );\n const PauseIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect></svg>\n );\n const RotateCcwIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"></path><path d=\"M3 3v5h5\"></path></svg>\n );\n const PlusIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg>\n );\n const TrashIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><path d=\"M3 6h18\"></path><path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"></path><path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"></path></svg>\n );\n const BellIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\"></path><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\"></path></svg>\n );\n const ClockIcon = ({ className }) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className}><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 6 12 12 16 14\"></polyline></svg>\n );\n\n // --- Helper Functions ---\n const formatTime = (seconds) => {\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n return {\n h: h.toString().padStart(2, '0'),\n m: m.toString().padStart(2, '0'),\n s: s.toString().padStart(2, '0')\n };\n };\n\n const getColor = (percentage) => {\n if (percentage > 50) return 'text-emerald-400';\n if (percentage > 20) return 'text-amber-400';\n return 'text-rose-500';\n };\n\n const getProgressColor = (percentage) => {\n if (percentage > 50) return '#34d399'; // emerald-400\n if (percentage > 20) return '#fbbf24'; // amber-400\n return '#f43f5e'; // rose-500\n };\n\n // --- Main Component ---\n const CountdownTimer = () => {\n const [duration, setDuration] = useState(300); // Default 5 mins\n const [timeLeft, setTimeLeft] = useState(300);\n const [isActive, setIsActive] = useState(false);\n const [isPaused, setIsPaused] = useState(false);\n const [inputH, setInputH] = useState(0);\n const [inputM, setInputM] = useState(5);\n const [inputS, setInputS] = useState(0);\n const [presets, setPresets] = useState([\n { label: 'Focus', time: 1500, color: 'bg-emerald-500' },\n { label: 'Short Break', time: 300, color: 'bg-blue-500' },\n { label: 'Long Break', time: 900, color: 'bg-purple-500' }\n ]);\n const [history, setHistory] = useState([]);\n const [audioEnabled, setAudioEnabled] = useState(true);\n\n const timerRef = useRef(null);\n const audioContextRef = useRef(null);\n\n // Audio System\n const playAlarm = () => {\n if (!audioContextRef.current) {\n audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();\n }\n const ctx = audioContextRef.current;\n const oscillator = ctx.createOscillator();\n const gainNode = ctx.createGain();\n\n oscillator.type = 'sine';\n oscillator.frequency.setValueAtTime(440, ctx.currentTime); // A4\n oscillator.frequency.exponentialRampToValueAtTime(880, ctx.currentTime + 0.1); // A5\n \n gainNode.gain.setValueAtTime(0.1, ctx.currentTime);\n gainNode.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.5);\n\n oscillator.connect(gainNode);\n gainNode.connect(ctx.destination);\n\n oscillator.start();\n oscillator.stop(ctx.currentTime + 0.5);\n };\n\n // Timer Logic\n useEffect(() => {\n if (isActive && timeLeft > 0) {\n timerRef.current = setInterval(() => {\n setTimeLeft((prev) => prev - 1);\n }, 1000);\n } else if (timeLeft === 0 && isActive) {\n setIsActive(false);\n setIsPaused(false);\n if (audioEnabled) playAlarm();\n // Add to history\n const now = new Date();\n setHistory(prev => [{\n id: Date.now(),\n duration: duration,\n completed: now.toLocaleTimeString(),\n label: 'Completed'\n }, ...prev]);\n }\n\n return () => clearInterval(timerRef.current);\n }, [isActive, timeLeft]);\n\n // Controls\n const toggleTimer = () => {\n if (timeLeft === 0) {\n resetTimer();\n } else {\n setIsActive(!isActive);\n setIsPaused(!isPaused ? true : false);\n }\n };\n\n const resetTimer = () => {\n setIsActive(false);\n setIsPaused(false);\n setTimeLeft(duration);\n clearInterval(timerRef.current);\n };\n\n const setNewTime = (seconds) => {\n setDuration(seconds);\n setTimeLeft(seconds);\n setIsActive(false);\n setIsPaused(false);\n };\n\n const handleInputChange = () => {\n const total = (parseInt(inputH) || 0) * 3600 + (parseInt(inputM) || 0) * 60 + (parseInt(inputS) || 0);\n if (total > 0) {\n setNewTime(total);\n }\n };\n\n const addPreset = () => {\n const total = (parseInt(inputH) || 0) * 3600 + (parseInt(inputM) || 0) * 60 + (parseInt(inputS) || 0);\n if (total > 0) {\n const newPreset = {\n label: 'Custom',\n time: total,\n color: 'bg-slate-500'\n };\n setPresets([...presets, newPreset]);\n }\n };\n\n const removePreset = (index) => {\n const newPresets = [...presets];\n newPresets.splice(index, 1);\n setPresets(newPresets);\n };\n\n // Visuals\n const percentage = duration > 0 ? (timeLeft / duration) * 100 : 0;\n const { h, m, s } = formatTime(timeLeft);\n const colorClass = getColor(percentage);\n const strokeColor = getProgressColor(percentage);\n \n // SVG Circle Math\n const radius = 120;\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - (percentage / 100) * circumference;\n\n return (\n <div className=\"flex flex-col lg:flex-row gap-8 w-full max-w-5xl mx-auto h-full lg:h-auto items-center justify-center p-4\">\n \n {/* Left Panel: Controls & Inputs */}\n <div className=\"glass-panel rounded-3xl p-6 w-full lg:w-1/3 flex flex-col gap-6 shadow-2xl z-10\">\n <div className=\"flex justify-between items-center border-b border-slate-700 pb-4\">\n <h2 className=\"text-xl font-bold text-white flex items-center gap-2\">\n <ClockIcon className=\"w-5 h-5 text-blue-400\" />\n Timer Settings\n </h2>\n <div className=\"flex gap-2\">\n <button \n onClick={() => setAudioEnabled(!audioEnabled)}\n className={`p-2 rounded-full transition-colors ${audioEnabled ? 'bg-blue-500/20 text-blue-400' : 'bg-slate-700 text-slate-400'}`}\n title=\"Toggle Sound\"\n >\n <BellIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n\n {/* Input Fields */}\n <div className=\"grid grid-cols-3 gap-2 text-center\">\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-xs text-slate-400 uppercase font-semibold\">Hours</label>\n <input \n type=\"number\" \n min=\"0\" \n max=\"99\" \n value={inputH} \n onChange={(e) => setInputH(e.target.value)}\n className=\"bg-slate-800/50 border border-slate-700 rounded-lg p-3 text-center text-xl font-mono focus:outline-none focus:border-blue-500 transition-colors\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-xs text-slate-400 uppercase font-semibold\">Minutes</label>\n <input \n type=\"number\" \n min=\"0\" \n max=\"59\" \n value={inputM} \n onChange={(e) => setInputM(e.target.value)}\n className=\"bg-slate-800/50 border border-slate-700 rounded-lg p-3 text-center text-xl font-mono focus:outline-none focus:border-blue-500 transition-colors\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-xs text-slate-400 uppercase font-semibold\">Seconds</label>\n <input \n type=\"number\" \n min=\"0\" \n max=\"59\" \n value={inputS} \n onChange={(e) => setInputS(e.target.value)}\n className=\"bg-slate-800/50 border border-slate-700 rounded-lg p-3 text-center text-xl font-mono focus:outline-none focus:border-blue-500 transition-colors\"\n />\n </div>\n </div>\n\n <button \n onClick={handleInputChange}\n className=\"w-full bg-blue-600 hover:bg-blue-500 text-white py-3 rounded-lg font-semibold transition-all shadow-lg shadow-blue-900/50 active:scale-95\"\n >\n Set Time\n </button>\n\n {/* Presets */}\n <div className=\"space-y-3\">\n <div className=\"flex justify-between items-center\">\n <h3 className=\"text-sm font-semibold text-slate-300\">Presets</h3>\n <button onClick={addPreset} className=\"text-xs text-blue-400 hover:text-blue-300 flex items-center gap-1\">\n <PlusIcon className=\"w-3 h-3\" /> Save Current\n </button>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {presets.map((preset, idx) => (\n <div key={idx} className=\"relative group\">\n <button \n onClick={() => setNewTime(preset.time)}\n className={`px-3 py-2 rounded-lg text-xs font-medium text-white transition-transform hover:scale-105 ${preset.color} shadow-lg`}\n >\n {preset.label}\n <div className=\"text-[10px] opacity-80 font-mono\">{formatTime(preset.time).m}:{formatTime(preset.time).s}</div>\n </button>\n {/* Remove button on hover */}\n <button \n onClick={(e) => { e.stopPropagation(); removePreset(idx); }}\n className=\"absolute -top-2 -right-2 bg-slate-800 text-rose-400 rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity shadow-sm hover:text-rose-300\"\n >\n <TrashIcon className=\"w-3 h-3\" />\n </button>\n </div>\n ))}\n </div>\n </div>\n </div>\n\n {/* Center Panel: The Clock */}\n <div className=\"relative flex-1 flex flex-col items-center justify-center min-h-[400px]\">\n \n {/* SVG Circle Progress */}\n <div className=\"relative w-[320px] h-[320px]\">\n {/* Background Ring */}\n <svg className=\"w-full h-full transform -rotate-90 drop-shadow-2xl\">\n <circle\n cx=\"160\"\n cy=\"160\"\n r={radius}\n stroke=\"currentColor\"\n strokeWidth=\"12\"\n fill=\"transparent\"\n className=\"text-slate-800\"\n />\n {/* Progress Ring */}\n <circle\n cx=\"160\"\n cy=\"160\"\n r={radius}\n stroke={strokeColor}\n strokeWidth=\"12\"\n fill=\"transparent\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n strokeLinecap=\"round\"\n className=\"transition-all duration-1000 ease-linear\"\n />\n </svg>\n\n {/* Inner Content */}\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\n <div className={`text-7xl font-mono font-bold tracking-tighter ${colorClass} transition-colors duration-500 drop-shadow-lg`}>\n {h !== '00' && <span>{h}:</span>}\n {m}:{s}\n </div>\n <div className=\"text-slate-500 text-sm mt-2 uppercase tracking-widest font-semibold\">\n {isActive ? 'Running' : isPaused ? 'Paused' : 'Ready'}\n </div>\n </div>\n\n {/* Pulse Effect when active */}\n {isActive && (\n <div className=\"absolute inset-0 rounded-full border-4 border-slate-700 opacity-20 animate-pulse-ring pointer-events-none\"></div>\n )}\n </div>\n\n {/* Main Controls */}\n <div className=\"flex items-center gap-6 mt-8\">\n <button \n onClick={toggleTimer}\n className={`w-20 h-20 rounded-full flex items-center justify-center transition-all duration-300 shadow-2xl active:scale-95 ${\n isActive \n ? 'bg-amber-500 hover:bg-amber-400 text-white shadow-amber-500/30' \n : 'bg-emerald-500 hover:bg-emerald-400 text-white shadow-emerald-500/30'\n }`}\n >\n {isActive ? <PauseIcon className=\"w-8 h-8\" /> : <PlayIcon className=\"w-8 h-8 ml-1\" />}\n </button>\n \n <button \n onClick={resetTimer}\n className=\"w-14 h-14 rounded-full bg-slate-700 hover:bg-slate-600 text-white flex items-center justify-center transition-all shadow-lg active:scale-95\"\n title=\"Reset\"\n >\n <RotateCcwIcon className=\"w-6 h-6\" />\n </button>\n </div>\n </div>\n\n {/* Right Panel: History */}\n <div className=\"glass-panel rounded-3xl p-6 w-full lg:w-1/4 h-64 lg:h-[500px] flex flex-col shadow-2xl z-10\">\n <h2 className=\"text-lg font-bold text-white mb-4 flex items-center gap-2\">\n <div className=\"w-2 h-2 bg-emerald-400 rounded-full animate-pulse\"></div>\n Session Log\n </h2>\n <div className=\"flex-1 overflow-y-auto custom-scrollbar space-y-3 pr-2\">\n {history.length === 0 ? (\n <div className=\"text-slate-500 text-center mt-10 text-sm italic\">\n No completed sessions yet.\n </div>\n ) : (\n history.map((item) => (\n <div key={item.id} className=\"bg-slate-800/50 p-3 rounded-lg border border-slate-700/50 flex justify-between items-center hover:bg-slate-800 transition-colors\">\n <div>\n <div className=\"text-xs text-slate-400 font-mono\">{item.completed}</div>\n <div className=\"text-sm font-semibold text-slate-200\">{item.label}</div>\n </div>\n <div className=\"text-xs font-mono text-emerald-400 bg-emerald-400/10 px-2 py-1 rounded\">\n {formatTime(item.duration).h !== '00' && formatTime(item.duration).h + ':'}\n {formatTime(item.duration).m}:{formatTime(item.duration).s}\n </div>\n </div>\n ))\n )}\n </div>\n </div>\n\n </div>\n );\n };\n\n const root = ReactDOM.createRoot(document.getElementById('root'));\n root.render(<CountdownTimer />);\n </script>\n</body>\n</html>\n```"
145
- },
146
- {
147
- "loc": 467,
148
- "correct": true,
149
- "timeSec": 24.579,
150
- "usage": {
151
- "inputTokens": 26,
152
- "outputTokens": 5515
153
- },
154
- "response": "```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Chronos Flux | Advanced Temporal Interface</title>\n \n <!-- Tailwind CSS -->\n <script src=\"https://cdn.tailwindcss.com\"></script>\n \n <!-- React & ReactDOM -->\n <script crossorigin src=\"https://unpkg.com/react@18/umd/react.production.min.js\"></script>\n <script crossorigin src=\"https://unpkg.com/react-dom@18/umd/react-dom.production.min.js\"></script>\n \n <!-- Babel for JSX -->\n <script src=\"https://unpkg.com/@babel/standalone/babel.min.js\"></script>\n\n <!-- FontAwesome -->\n <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n\n <!-- Google Fonts -->\n <link href=\"https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Rajdhani:wght@300;500;700&display=swap\" rel=\"stylesheet\">\n\n <script>\n tailwind.config = {\n theme: {\n extend: {\n fontFamily: {\n 'orbitron': ['Orbitron', 'sans-serif'],\n 'rajdhani': ['Rajdhani', 'sans-serif'],\n },\n colors: {\n 'neon-blue': '#00f3ff',\n 'neon-purple': '#bc13fe',\n 'neon-green': '#0aff0a',\n 'dark-bg': '#050505',\n 'panel-bg': '#0a0a0a',\n },\n animation: {\n 'pulse-fast': 'pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite',\n 'glitch': 'glitch 1s linear infinite',\n },\n keyframes: {\n glitch: {\n '2%, 64%': { transform: 'translate(2px,0) skew(0deg)' },\n '4%, 60%': { transform: 'translate(-2px,0) skew(0deg)' },\n '62%': { transform: 'translate(0,0) skew(5deg)' },\n }\n }\n }\n }\n }\n </script>\n\n <style>\n body {\n background-color: #050505;\n color: #e0e0e0;\n overflow-x: hidden;\n }\n\n /* Custom Scrollbar */\n ::-webkit-scrollbar {\n width: 8px;\n }\n ::-webkit-scrollbar-track {\n background: #0a0a0a;\n }\n ::-webkit-scrollbar-thumb {\n background: #333;\n border-radius: 4px;\n }\n ::-webkit-scrollbar-thumb:hover {\n background: #00f3ff;\n }\n\n /* Range Slider Styling */\n input[type=range] {\n -webkit-appearance: none; \n background: transparent; \n }\n input[type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n height: 20px;\n width: 20px;\n border-radius: 50%;\n background: #00f3ff;\n cursor: pointer;\n margin-top: -8px; \n box-shadow: 0 0 10px #00f3ff;\n }\n input[type=range]::-webkit-slider-runnable-track {\n width: 100%;\n height: 4px;\n cursor: pointer;\n background: #333;\n border-radius: 2px;\n }\n\n /* Glassmorphism */\n .glass-panel {\n background: rgba(20, 20, 20, 0.7);\n backdrop-filter: blur(10px);\n border: 1px solid rgba(255, 255, 255, 0.1);\n box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Neon Glows */\n .glow-text {\n text-shadow: 0 0 10px rgba(0, 243, 255, 0.7), 0 0 20px rgba(0, 243, 255, 0.5);\n }\n .glow-border {\n box-shadow: 0 0 15px rgba(0, 243, 255, 0.3);\n }\n .glow-border-red {\n box-shadow: 0 0 15px rgba(255, 0, 0, 0.3);\n }\n\n /* SVG Circle Progress */\n .progress-ring__circle {\n transition: stroke-dashoffset 0.35s;\n transform: rotate(-90deg);\n transform-origin: 50% 50%;\n }\n </style>\n</head>\n<body>\n\n <div id=\"root\"></div>\n\n <script type=\"text/babel\">\n const { useState, useEffect, useRef, useCallback } = React;\n\n // --- Sound Effects ---\n // Using simple AudioContext beeps to avoid external dependencies\n const audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n \n const playSound = (type) => {\n if (audioCtx.state === 'suspended') audioCtx.resume();\n const oscillator = audioCtx.createOscillator();\n const gainNode = audioCtx.createGain();\n \n oscillator.connect(gainNode);\n gainNode.connect(audioCtx.destination);\n \n if (type === 'click') {\n oscillator.type = 'sine';\n oscillator.frequency.setValueAtTime(800, audioCtx.currentTime);\n oscillator.frequency.exponentialRampToValueAtTime(300, audioCtx.currentTime + 0.1);\n gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime);\n gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1);\n oscillator.start();\n oscillator.stop(audioCtx.currentTime + 0.1);\n } else if (type === 'alarm') {\n oscillator.type = 'square';\n oscillator.frequency.setValueAtTime(440, audioCtx.currentTime);\n oscillator.frequency.setValueAtTime(880, audioCtx.currentTime + 0.2);\n gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime);\n gainNode.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 0.5);\n oscillator.start();\n oscillator.stop(audioCtx.currentTime + 0.5);\n }\n };\n\n // --- Helper Functions ---\n const formatTime = (seconds) => {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;\n };\n\n // --- Components ---\n\n // 1. Visual Background Component\n const MatrixBackground = () => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const ctx = canvas.getContext('2d');\n \n let width = canvas.width = window.innerWidth;\n let height = canvas.height = window.innerHeight;\n\n const columns = Math.floor(width / 20);\n const drops = Array(columns).fill(1);\n\n const draw = () => {\n ctx.fillStyle = 'rgba(5, 5, 5, 0.05)'; // Fade effect\n ctx.fillRect(0, 0, width, height);\n\n ctx.fillStyle = '#00f3ff'; // Text color\n ctx.font = '15px monospace';\n\n for (let i = 0; i < drops.length; i++) {\n const text = String.fromCharCode(0x30A0 + Math.random() * 96);\n ctx.fillText(text, i * 20, drops[i] * 20);\n\n if (drops[i] * 20 > height && Math.random() > 0.975) {\n drops[i] = 0;\n }\n drops[i]++;\n }\n };\n\n const interval = setInterval(draw, 33);\n \n const handleResize = () => {\n width = canvas.width = window.innerWidth;\n height = canvas.height = window.innerHeight;\n };\n window.addEventListener('resize', handleResize);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener('resize', handleResize);\n };\n }, []);\n\n return <canvas ref={canvasRef} className=\"absolute top-0 left-0 w-full h-full opacity-20 pointer-events-none\" />;\n };\n\n // 2. Circular Progress Component\n const CircularProgress = ({ percentage, timeLeft, totalTime, isRunning, isWarning }) => {\n const radius = 120;\n const stroke = 8;\n const normalizedRadius = radius - stroke * 2;\n const circumference = normalizedRadius * 2 * Math.PI;\n const strokeDashoffset = circumference - (percentage / 100) * circumference;\n\n // Determine color based on state\n let color = '#00f3ff'; // Cyan\n if (isWarning) color = '#ff0000'; // Red\n if (!isRunning && timeLeft === totalTime) color = '#555'; // Idle\n\n return (\n <div className=\"relative flex justify-center items-center mb-8\">\n <svg height={radius * 2.5} width={radius * 2.5} className=\"drop-shadow-2xl\">\n <circle\n stroke=\"#1a1a1a\"\n strokeWidth={stroke}\n fill=\"transparent\"\n r={normalizedRadius}\n cx={radius * 1.25}\n cy={radius * 1.25}\n />\n <circle\n className=\"progress-ring__circle\"\n stroke={color}\n strokeWidth={stroke}\n strokeDasharray={circumference + ' ' + circumference}\n style={{ strokeDashoffset, strokeLinecap: 'round' }}\n fill=\"transparent\"\n r={normalizedRadius}\n cx={radius * 1.25}\n cy={radius * 1.25}\n />\n {/* Filter for glow effect */}\n <defs>\n <filter id=\"glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur stdDeviation=\"4\" result=\"coloredBlur\"/>\n <feMerge>\n <feMergeNode in=\"coloredBlur\"/>\n <feMergeNode in=\"SourceGraphic\"/>\n </feMerge>\n </filter>\n </defs>\n <circle\n stroke={color}\n strokeWidth={stroke}\n strokeDasharray={circumference + ' ' + circumference}\n style={{ strokeDashoffset, strokeLinecap: 'round', opacity: 0.3, filter: 'url(#glow)' }}\n fill=\"transparent\"\n r={normalizedRadius}\n cx={radius * 1.25}\n cy={radius * 1.25}\n />\n </svg>\n <div className=\"absolute flex flex-col items-center justify-center text-center\">\n <span className={`text-6xl font-orbitron font-bold tracking-widest ${isWarning ? 'text-red-500 animate-pulse' : 'text-white'}`}>\n {formatTime(timeLeft)}\n </span>\n <span className=\"text-xs font-rajdhani text-gray-400 mt-2 uppercase tracking-widest\">\n {isRunning ? 'Time Remaining' : 'Paused'}\n </span>\n </div>\n </div>\n );\n };\n\n // 3. Main Application Component\n const App = () => {\n const [timeLeft, setTimeLeft] = useState(60);\n const [totalTime, setTotalTime] = useState(60);\n const [isRunning, setIsRunning] = useState(false);\n const [isWarning, setIsWarning] = useState(false);\n const [inputValue, setInputValue] = useState(60);\n const [activeTab, setActiveTab] = useState('timer'); // 'timer' or 'presets'\n const [logs, setLogs] = useState([]);\n\n const timerRef = useRef(null);\n\n // Calculate Percentage\n const percentage = (timeLeft / totalTime) * 100;\n\n // Handle Timer Logic\n useEffect(() => {\n if (isRunning) {\n timerRef.current = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n clearInterval(timerRef.current);\n setIsRunning(false);\n setIsWarning(false);\n playSound('alarm');\n addLog('Timer Completed');\n return 0;\n }\n if (prev <= 10) {\n setIsWarning(true);\n playSound('click'); // Ticking sound\n }\n return prev - 1;\n });\n }, 1000);\n } else {\n clearInterval(timerRef.current);\n }\n\n return () => clearInterval(timerRef.current);\n }, [isRunning]);\n\n // Event Handlers\n const handleStart = () => {\n if (timeLeft > 0) {\n playSound('click');\n setIsRunning(true);\n addLog('Timer Started');\n if (timeLeft !== totalTime) {\n // Resume\n } else {\n // Fresh start\n }\n }\n };\n\n const handlePause = () => {\n playSound('click');\n setIsRunning(false);\n setIsWarning(false);\n addLog('Timer Paused');\n };\n\n const handleReset = () => {\n playSound('click');\n setIsRunning(false);\n setIsWarning(false);\n setTimeLeft(totalTime);\n addLog('Timer Reset');\n };\n\n const handleSetTime = () => {\n const newTime = parseInt(inputValue);\n if (newTime && newTime > 0) {\n playSound('click');\n setTotalTime(newTime);\n setTimeLeft(newTime);\n setIsRunning(false);\n setIsWarning(false);\n addLog(`Time set to ${newTime}s`);\n }\n };\n\n const addLog = (msg) => {\n const now = new Date();\n const timeString = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n setLogs(prev => [{ time: timeString, message: msg }, ...prev].slice(0, 5));\n };\n\n const applyPreset = (seconds) => {\n playSound('click');\n setInputValue(seconds);\n setTotalTime(seconds);\n setTimeLeft(seconds);\n setIsRunning(false);\n setIsWarning(false);\n addLog(`Preset loaded: ${seconds}s`);\n };\n\n return (\n <div className=\"relative min-h-screen flex items-center justify-center font-rajdhani selection:bg-neon-blue selection:text-black\">\n <MatrixBackground />\n \n {/* Main Container */}\n <div className=\"relative z-10 w-full max-w-md p-6 mx-4\">\n \n {/* Header */}\n <div className=\"text-center mb-8\">\n <h1 className=\"text-4xl font-orbitron font-bold text-transparent bg-clip-text bg-gradient-to-r from-neon-blue to-neon-purple glow-text mb-2\">\n CHRONOS FLUX\n </h1>\n <p className=\"text-gray-400 text-sm tracking-[0.2em]\">TEMPORAL MANAGEMENT UNIT v2.0</p>\n </div>\n\n {/* Main Card */}\n <div className=\"glass-panel rounded-2xl p-8 border border-gray-800 shadow-2xl relative overflow-hidden\">\n {/* Decorative Corner Lines */}\n <div className=\"absolute top-0 left-0 w-4 h-4 border-t-2 border-l-2 border-neon-blue\"></div>\n <div className=\"absolute top-0 right-0 w-4 h-4 border-t-2 border-r-2 border-neon-blue\"></div>\n <div className=\"absolute bottom-0 left-0 w-4 h-4 border-b-2 border-l-2 border-neon-blue\"></div>\n <div className=\"absolute bottom-0 right-0 w-4 h-4 border-b-2 border-r-2 border-neon-blue\"></div>\n\n {/* Circular Display */}\n <div className=\"flex justify-center\">\n <CircularProgress \n percentage={percentage} \n timeLeft={timeLeft} \n totalTime={totalTime}\n isRunning={isRunning}\n isWarning={isWarning}\n />\n </div>\n\n {/* Controls */}\n <div className=\"grid grid-cols-3 gap-4 mb-6\">\n <button \n onClick={isRunning ? handlePause : handleStart}\n className={`py-3 rounded-lg font-bold tracking-wider transition-all duration-300 flex items-center justify-center gap-2\n ${isRunning \n ? 'bg-yellow-500/20 text-yellow-400 hover:bg-yellow-500/40 border border-yellow-500/50' \n : 'bg-neon-blue/20 text-neon-blue hover:bg-neon-blue/40 border border-neon-blue/50'}`}\n >\n <i className={`fas ${isRunning ? 'fa-pause' : 'fa-play'}`}></i>\n {isRunning ? 'PAUSE' : 'START'}\n </button>\n \n <button \n onClick={handleReset}\n className=\"bg-gray-800/50 text-gray-300 hover:bg-gray-700 border border-gray-600 rounded-lg py-3 font-bold tracking-wider transition-all duration-300 flex items-center justify-center gap-2\"\n >\n <i className=\"fas fa-undo\"></i> RESET\n </button>\n \n <button \n onClick={() => {\n setIsRunning(false);\n setIsWarning(false);\n setTimeLeft(0);\n addLog('Timer Stopped');\n }}\n className=\"bg-red-500/20 text-red-500 hover:bg-red-500/40 border border-red-500/50 rounded-lg py-3 font-bold tracking-wider transition-all duration-300 flex items-center justify-center gap-2\"\n >\n <i className=\"fas fa-stop\"></i> STOP\n </button>\n </div>\n\n {/* Configuration Tabs */}\n <div className=\"flex border-b border-gray-800 mb-4\">\n <button \n onClick={() => setActiveTab('timer')}\n className={`flex-1 pb-2 text-sm font-bold tracking-wider transition-colors ${activeTab === 'timer' ? 'text-neon-blue border-b-2 border-neon-blue' : 'text-gray-500 hover:text-gray-300'}`}\n >\n SET TIME\n </button>\n <button \n onClick={() => setActiveTab('presets')}\n className={`flex-1 pb-2 text-sm font-bold tracking-wider transition-colors ${activeTab === 'presets' ? 'text-neon-blue border-b-2 border-neon-blue' : 'text-gray-500 hover:text-gray-300'}`}\n >\n PRESETS\n </button>\n </div>\n\n {/* Tab Content */}\n <div className=\"h-24\">\n {activeTab === 'timer' ? (\n <div className=\"flex flex-col gap-3 animate-fade-in\">\n <div className=\"flex items-center gap-2\">\n <input \n type=\"number\" \n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n className=\"bg-black/50 border border-gray-700 rounded-lg p-2 text-white font-mono w-full focus:border-neon-blue focus:outline-none focus:shadow-[0_0_10px_rgba(0,243,255,0.3)] transition-all\"\n placeholder=\"Enter seconds...\"\n />\n <button \n onClick={handleSetTime}\n className=\"bg-neon-blue text-black font-bold py-2 px-4 rounded-lg hover:bg-white transition-colors\"\n >\n SET\n </button>\n </div>\n <div className=\"flex items-center gap-2\">\n <i className=\"fas fa-sliders-h text-gray-500 text-xs\"></i>\n <input \n type=\"range\" \n min=\"10\" \n max=\"3600\" \n step=\"10\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n className=\"w-full h-1 bg-gray-800 rounded-lg appearance-none cursor-pointer\"\n />\n <span className=\"text-xs font-mono text-gray-400 w-12 text-right\">{inputValue}s</span>\n </div>\n </div>\n ) : (\n <div className=\"grid grid-cols-3 gap-2 animate-fade-in\">\n <button onClick={() => applyPreset(30)} className=\"bg-gray-800 hover:bg-gray-700 border border-gray-700 text-xs py-2 rounded text-gray-300 transition-colors\">30s</button>\n <button onClick={() => applyPreset(60)} className=\"bg-gray-800 hover:bg-gray-700 border border-gray-700 text-xs py-2 rounded text-gray-300 transition-colors\">1m</button>\n <button onClick={() => applyPreset(300)} className=\"bg-gray-800 hover:bg-gray-700 border border-gray-700 text-xs py-2 rounded text-gray-300 transition-colors\">5m</button>\n <button onClick={() => applyPreset(900)} className=\"bg-gray-800 hover:bg-gray-700 border border-gray-700 text-xs py-2 rounded text-gray-300 transition-colors\">15m</button>\n <button onClick={() => applyPreset(1800)} className=\"bg-gray-800 hover:bg-gray-700 border border-gray-700 text-xs py-2 rounded text-gray-300 transition-colors\">30m</button>\n <button onClick={() => applyPreset(3600)} className=\"bg-gray-800 hover:bg-gray-700 border border-gray-700 text-xs py-2 rounded text-gray-300 transition-colors\">1h</button>\n </div>\n )}\n </div>\n </div>\n\n {/* Logs Panel */}\n <div className=\"mt-4 glass-panel rounded-lg p-4 border border-gray-800\">\n <h3 className=\"text-xs font-orbitron text-gray-500 mb-2 flex items-center gap-2\">\n <i className=\"fas fa-terminal\"></i> SYSTEM LOGS\n </h3>\n <div className=\"space-y-1 font-mono text-xs text-gray-400 h-20 overflow-y-auto\">\n {logs.length === 0 && <span className=\"opacity-50\">System idle...</span>}\n {logs.map((log, idx) => (\n <div key={idx} className=\"flex gap-2\">\n <span className=\"text-neon-blue\">[{log.time}]</span>\n <span className=\"text-gray-300\">{log.message}</span>\n </div>\n ))}\n </div>\n </div>\n\n </div>\n </div>\n );\n };\n\n const root = ReactDOM.createRoot(document.getElementById('root'));\n root.render(<App />);\n </script>\n</body>\n</html>\n```"
155
- },
156
- {
157
- "loc": 413,
158
- "correct": true,
159
- "timeSec": 21.468,
160
- "usage": {
161
- "inputTokens": 26,
162
- "outputTokens": 5360
163
- },
164
- "response": "```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>FlowTimer | Precision React Countdown</title>\n \n <!-- Tailwind CSS -->\n <script src=\"https://cdn.tailwindcss.com\"></script>\n \n <!-- React & ReactDOM -->\n <script crossorigin src=\"https://unpkg.com/react@18/umd/react.development.js\"></script>\n <script crossorigin src=\"https://unpkg.com/react-dom@18/umd/react-dom.development.js\"></script>\n \n <!-- Babel for JSX -->\n <script src=\"https://unpkg.com/@babel/standalone/babel.min.js\"></script>\n \n <!-- Lucide Icons -->\n <script src=\"https://unpkg.com/lucide@latest\"></script>\n \n <!-- Google Fonts -->\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@300;400;600;800&display=swap\" rel=\"stylesheet\">\n\n <style>\n body {\n font-family: 'Inter', sans-serif;\n background-color: #0f172a;\n color: #f8fafc;\n }\n .mono-font {\n font-family: 'JetBrains Mono', monospace;\n }\n /* Custom Scrollbar */\n ::-webkit-scrollbar {\n width: 8px;\n }\n ::-webkit-scrollbar-track {\n background: #1e293b; \n }\n ::-webkit-scrollbar-thumb {\n background: #475569; \n border-radius: 4px;\n }\n ::-webkit-scrollbar-thumb:hover {\n background: #64748b; \n }\n \n /* Animation for the timer circle */\n .timer-ring {\n transition: stroke-dashoffset 0.5s linear, stroke 0.3s ease;\n transform: rotate(-90deg);\n transform-origin: 50% 50%;\n }\n \n /* Input hiding number spinner */\n input[type=number]::-webkit-inner-spin-button, \n input[type=number]::-webkit-outer-spin-button { \n -webkit-appearance: none; \n margin: 0; \n }\n \n /* Pulse animation for finished state */\n @keyframes pulse-red {\n 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }\n 70% { box-shadow: 0 0 0 20px rgba(239, 68, 68, 0); }\n 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }\n }\n .alarm-pulse {\n animation: pulse-red 1.5s infinite;\n }\n </style>\n</head>\n<body>\n <div id=\"root\"></div>\n\n <script type=\"text/babel\">\n const { useState, useEffect, useRef } = React;\n\n // --- Audio Context Helper for Browser Autoplay Policy ---\n const playBeep = () => {\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (!AudioContext) return;\n \n const ctx = new AudioContext();\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n \n osc.connect(gain);\n gain.connect(ctx.destination);\n \n osc.type = 'sine';\n osc.frequency.value = 880; // A5\n gain.gain.value = 0.1;\n \n osc.start();\n osc.stop(ctx.currentTime + 0.2);\n } catch (e) {\n console.error(\"Audio error\", e);\n }\n };\n\n const playAlarm = () => {\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (!AudioContext) return;\n \n const ctx = new AudioContext();\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n \n osc.connect(gain);\n gain.connect(ctx.destination);\n \n osc.type = 'square';\n osc.frequency.value = 440; \n gain.gain.value = 0.1;\n \n // Siren effect\n osc.frequency.linearRampToValueAtTime(880, ctx.currentTime + 0.5);\n osc.frequency.linearRampToValueAtTime(440, ctx.currentTime + 1.0);\n \n osc.start();\n osc.stop(ctx.currentTime + 1.0);\n } catch (e) {\n console.error(\"Audio error\", e);\n }\n };\n\n // --- Main Component ---\n const TimerApp = () => {\n const [timeLeft, setTimeLeft] = useState(0);\n const [initialTime, setInitialTime] = useState(0);\n const [isActive, setIsActive] = useState(false);\n const [isPaused, setIsPaused] = useState(false);\n const [mode, setMode] = useState('setup'); // setup, running, finished\n const [inputHours, setInputHours] = useState(0);\n const [inputMinutes, setInputMinutes] = useState(5);\n const [inputSeconds, setInputSeconds] = useState(0);\n const [taskName, setTaskName] = useState(\"Focus Session\");\n const [showTaskInput, setShowTaskInput] = useState(false);\n\n const timerRef = useRef(null);\n\n // Timer Logic\n useEffect(() => {\n if (isActive && !isPaused && timeLeft > 0) {\n timerRef.current = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n clearInterval(timerRef.current);\n setIsActive(false);\n setMode('finished');\n playAlarm();\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n } else {\n clearInterval(timerRef.current);\n }\n\n return () => clearInterval(timerRef.current);\n }, [isActive, isPaused, timeLeft]);\n\n // Formatting\n const formatTime = (totalSeconds) => {\n const h = Math.floor(totalSeconds / 3600);\n const m = Math.floor((totalSeconds % 3600) / 60);\n const s = totalSeconds % 60;\n return `${h > 0 ? h + ':' : ''}${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;\n };\n\n // Controls\n const startTimer = () => {\n const totalSeconds = (parseInt(inputHours) || 0) * 3600 + (parseInt(inputMinutes) || 0) * 60 + (parseInt(inputSeconds) || 0);\n if (totalSeconds <= 0) return;\n \n setInitialTime(totalSeconds);\n setTimeLeft(totalSeconds);\n setIsActive(true);\n setIsPaused(false);\n setMode('running');\n playBeep();\n };\n\n const togglePause = () => {\n setIsPaused(!isPaused);\n playBeep();\n };\n\n const resetTimer = () => {\n setIsActive(false);\n setIsPaused(false);\n setMode('setup');\n setTimeLeft(0);\n playBeep();\n };\n\n const addTime = (seconds) => {\n setTimeLeft(prev => prev + seconds);\n setInitialTime(prev => prev + seconds);\n };\n\n // Circular Progress Calculation\n const radius = 120;\n const circumference = 2 * Math.PI * radius;\n const progress = initialTime > 0 ? timeLeft / initialTime : 0;\n const dashoffset = circumference - (progress * circumference);\n\n // Color Logic based on progress\n const getColor = () => {\n if (mode === 'finished') return 'text-red-500';\n if (progress > 0.6) return 'text-emerald-400';\n if (progress > 0.3) return 'text-amber-400';\n return 'text-rose-500';\n };\n \n const getStrokeColor = () => {\n if (mode === 'finished') return '#ef4444';\n if (progress > 0.6) return '#34d399';\n if (progress > 0.3) return '#fbbf24';\n return '#f43f5e';\n };\n\n // Presets\n const presets = [\n { label: 'Pomodoro', m: 25, s: 0 },\n { label: 'Short Break', m: 5, s: 0 },\n { label: 'Long Break', m: 15, s: 0 },\n { label: '1 Min', m: 1, s: 0 }\n ];\n\n return (\n <div className=\"min-h-screen flex flex-col items-center justify-center bg-slate-900 text-slate-100 p-4 relative overflow-hidden\">\n \n {/* Background Ambient Effects */}\n <div className=\"absolute top-0 left-0 w-full h-full overflow-hidden -z-10 opacity-30 pointer-events-none\">\n <div className=\"absolute top-10 left-10 w-72 h-72 bg-indigo-500 rounded-full mix-blend-multiply filter blur-3xl animate-blob\"></div>\n <div className=\"absolute top-10 right-10 w-72 h-72 bg-purple-500 rounded-full mix-blend-multiply filter blur-3xl animate-blob animation-delay-2000\"></div>\n <div className=\"absolute -bottom-8 left-20 w-72 h-72 bg-pink-500 rounded-full mix-blend-multiply filter blur-3xl animate-blob animation-delay-4000\"></div>\n </div>\n\n {/* Header */}\n <header className=\"absolute top-0 w-full p-6 flex justify-between items-center\">\n <div className=\"flex items-center gap-2\">\n <i data-lucide=\"clock\" className=\"w-6 h-6 text-indigo-400\"></i>\n <h1 className=\"text-xl font-bold tracking-wider text-indigo-100\">FlowTimer</h1>\n </div>\n <div className=\"text-xs text-slate-500 font-mono\">v1.0.2</div>\n </header>\n\n {/* Main Card */}\n <div className={`w-full max-w-md bg-slate-800/50 backdrop-blur-xl border border-slate-700 rounded-3xl shadow-2xl p-8 flex flex-col items-center transition-all duration-500 ${mode === 'finished' ? 'alarm-pulse border-red-500/50' : ''}`}>\n \n {/* Task Name Display/Edit */}\n <div className=\"mb-8 w-full text-center h-8\">\n {mode === 'setup' ? (\n <button \n onClick={() => setShowTaskInput(!showTaskInput)}\n className=\"text-sm text-slate-400 hover:text-indigo-400 transition-colors flex items-center justify-center gap-2 mx-auto\"\n >\n <i data-lucide=\"edit-3\" className=\"w-3 h-3\"></i>\n {showTaskInput ? 'Cancel' : 'Set Task Name'}\n </button>\n ) : (\n <h2 className=\"text-xl font-medium text-slate-200 truncate px-4 animate-fade-in\">{taskName}</h2>\n )}\n \n {showTaskInput && mode === 'setup' && (\n <input \n type=\"text\" \n autoFocus\n placeholder=\"What are you focusing on?\"\n className=\"bg-slate-900 border border-slate-600 rounded px-3 py-1 text-sm w-full text-center focus:outline-none focus:border-indigo-500 transition-colors\"\n value={taskName}\n onChange={(e) => setTaskName(e.target.value)}\n onBlur={() => setShowTaskInput(false)}\n onKeyDown={(e) => e.key === 'Enter' && setShowTaskInput(false)}\n />\n )}\n </div>\n\n {/* Timer Display */}\n <div className=\"relative mb-10 group\">\n {/* SVG Ring */}\n <svg className=\"w-72 h-72 transform -rotate-90 drop-shadow-2xl\">\n <circle\n cx=\"144\"\n cy=\"144\"\n r={radius}\n stroke=\"currentColor\"\n strokeWidth=\"8\"\n fill=\"transparent\"\n className=\"text-slate-700/50\"\n />\n <circle\n cx=\"144\"\n cy=\"144\"\n r={radius}\n stroke={getStrokeColor()}\n strokeWidth=\"8\"\n fill=\"transparent\"\n strokeDasharray={circumference}\n strokeDashoffset={dashoffset}\n strokeLinecap=\"round\"\n className=\"timer-ring\"\n />\n </svg>\n\n {/* Time Text */}\n <div className=\"absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center\">\n <div className={`text-6xl font-bold mono-font tracking-tighter ${mode === 'finished' ? 'text-red-500 animate-pulse' : 'text-slate-100'}`}>\n {mode === 'setup' ? \n <span className=\"text-slate-500 text-4xl\">--:--</span> : \n formatTime(timeLeft)\n }\n </div>\n <div className=\"text-slate-400 text-sm mt-2 font-medium uppercase tracking-widest\">\n {mode === 'setup' ? 'Ready' : isPaused ? 'Paused' : mode === 'finished' ? 'Time Up' : 'Remaining'}\n </div>\n </div>\n </div>\n\n {/* Input Area (Setup Mode) */}\n {mode === 'setup' && (\n <div className=\"w-full space-y-6 animate-fade-in-up\">\n <div className=\"flex gap-2 justify-center\">\n <div className=\"flex flex-col items-center gap-1\">\n <label className=\"text-xs text-slate-500 uppercase\">Hrs</label>\n <input \n type=\"number\" \n min=\"0\" \n max=\"99\"\n value={inputHours}\n onChange={(e) => setInputHours(Math.max(0, parseInt(e.target.value) || 0))}\n className=\"w-20 bg-slate-900 border border-slate-700 rounded-lg p-3 text-center text-xl font-mono focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all\"\n />\n </div>\n <div className=\"text-2xl font-bold text-slate-600 pt-8\">:</div>\n <div className=\"flex flex-col items-center gap-1\">\n <label className=\"text-xs text-slate-500 uppercase\">Min</label>\n <input \n type=\"number\" \n min=\"0\" \n max=\"59\"\n value={inputMinutes}\n onChange={(e) => setInputMinutes(Math.max(0, Math.min(59, parseInt(e.target.value) || 0)))}\n className=\"w-20 bg-slate-900 border border-slate-700 rounded-lg p-3 text-center text-xl font-mono focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all\"\n />\n </div>\n <div className=\"text-2xl font-bold text-slate-600 pt-8\">:</div>\n <div className=\"flex flex-col items-center gap-1\">\n <label className=\"text-xs text-slate-500 uppercase\">Sec</label>\n <input \n type=\"number\" \n min=\"0\" \n max=\"59\"\n value={inputSeconds}\n onChange={(e) => setInputSeconds(Math.max(0, Math.min(59, parseInt(e.target.value) || 0)))}\n className=\"w-20 bg-slate-900 border border-slate-700 rounded-lg p-3 text-center text-xl font-mono focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all\"\n />\n </div>\n </div>\n\n {/* Presets */}\n <div className=\"flex flex-wrap justify-center gap-2\">\n {presets.map((p, idx) => (\n <button \n key={idx}\n onClick={() => {\n setInputHours(0);\n setInputMinutes(p.m);\n setInputSeconds(p.s);\n }}\n className=\"px-3 py-1 rounded-full bg-slate-700/50 hover:bg-indigo-600/20 hover:text-indigo-400 border border-slate-700 hover:border-indigo-500/50 text-xs transition-all\"\n >\n {p.label}\n </button>\n ))}\n </div>\n\n <button \n onClick={startTimer}\n className=\"w-full py-4 bg-indigo-600 hover:bg-indigo-500 text-white rounded-xl font-bold text-lg shadow-lg shadow-indigo-500/20 transition-all transform hover:scale-[1.02] active:scale-95 flex items-center justify-center gap-2\"\n >\n <i data-lucide=\"play\" className=\"w-5 h-5 fill-current\"></i>\n Start Focus\n </button>\n </div>\n )}\n\n {/* Controls (Running Mode) */}\n {(mode === 'running' || mode === 'finished') && (\n <div className=\"w-full space-y-4 animate-fade-in\">\n <div className=\"flex gap-4 justify-center\">\n <button \n onClick={togglePause}\n className=\"flex-1 py-4 bg-slate-700 hover:bg-slate-600 text-white rounded-xl font-bold text-lg transition-all active:scale-95 flex items-center justify-center gap-2\"\n >\n {isPaused ? <i data-lucide=\"play\" className=\"w-5 h-5 fill-current\"></i> : <i data-lucide=\"pause\" className=\"w-5 h-5 fill-current\"></i>}\n {isPaused ? 'Resume' : 'Pause'}\n </button>\n \n <button \n onClick={resetTimer}\n className=\"flex-1 py-4 bg-slate-700 hover:bg-rose-600 text-white rounded-xl font-bold text-lg transition-all active:scale-95 flex items-center justify-center gap-2\"\n >\n <i data-lucide=\"square\" className=\"w-5 h-5 fill-current\"></i>\n Stop\n </button>\n </div>\n\n {/* Quick Adjustments */}\n <div className=\"flex justify-center gap-2 pt-2\">\n <button onClick={() => addTime(60)} className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 border border-slate-700 text-xs text-slate-400 transition-colors\">\n +1 Min\n </button>\n <button onClick={() => addTime(300)} className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 border border-slate-700 text-xs text-slate-400 transition-colors\">\n +5 Min\n </button>\n <button onClick={() => addTime(600)} className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 border border-slate-700 text-xs text-slate-400 transition-colors\">\n +10 Min\n </button>\n </div>\n </div>\n )}\n </div>\n \n {/* Footer Info */}\n <div className=\"mt-8 text-center\">\n <p className=\"text-slate-500 text-sm max-w-xs mx-auto\">\n Designed for deep work. Set your intention, remove distractions, and flow.\n </p>\n </div>\n </div>\n );\n };\n\n const root = ReactDOM.createRoot(document.getElementById('root'));\n root.render(<TimerApp />);\n\n // Initialize Lucide Icons after render\n setTimeout(() => {\n lucide.createIcons();\n }, 100);\n </script>\n \n <script>\n // Tailwind Custom Config for animations\n tailwind.config = {\n theme: {\n extend: {\n animation: {\n blob: \"blob 7s infinite\",\n 'fade-in': \"fadeIn 0.5s ease-out\",\n 'fade-in-up': \"fadeInUp 0.5s ease-out\",\n },\n keyframes: {\n blob: {\n \"0%\": { transform: \"translate(0px, 0px) scale(1)\" },\n \"33%\": { transform: \"translate(30px, -50px) scale(1.1)\" },\n \"66%\": { transform: \"translate(-20px, 20px) scale(0.9)\" },\n \"100%\": { transform: \"translate(0px, 0px) scale(1)\" },\n },\n fadeIn: {\n \"0%\": { opacity: \"0\" },\n \"100%\": { opacity: \"1\" },\n },\n fadeInUp: {\n \"0%\": { opacity: \"0\", transform: \"translateY(20px)\" },\n \"100%\": { opacity: \"1\", transform: \"translateY(0)\" },\n },\n },\n },\n },\n };\n </script>\n</body>\n</html>\n```"
165
- }
166
- ],
167
- "rate-limit": [
168
- {
169
- "loc": 62,
170
- "correct": true,
171
- "timeSec": 9.316,
172
- "usage": {
173
- "inputTokens": 22,
174
- "outputTokens": 2139
175
- },
176
- "response": "The cleanest way to add rate limiting to FastAPI is with **slowapi** (a port of Flask-Limiter). It supports in-memory stores for development and Redis/Postgres for production.\n\nHere’s a complete, production-ready setup.\n\n### 1. Install\n\n```bash\npip install slowapi\n# For production (distributed / persistent):\n# pip install redis\n```\n\n### 2. Basic Setup\n\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\n\napp = FastAPI()\n\n# Create a limiter. `get_remote_address` uses the client IP by default.\nlimiter = Limiter(key_func=get_remote_address)\n\n# Attach it to the app\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\n# Optional: global limit applied to all routes unless exempted\napp.add_middleware(SlowAPIMiddleware)\n\n\n@app.get(\"/health\")\n@limiter.limit(\"10/minute\") # 10 requests per minute per IP\nasync def health_check(request: Request):\n # IMPORTANT: you must accept `request` as an argument\n return {\"status\": \"ok\"}\n\n\n@app.post(\"/contact\")\n@limiter.limit(\"5/minute\") # stricter limit for expensive endpoints\nasync def contact_form(request: Request):\n return {\"message\": \"Form submitted\"}\n\n\n@app.get(\"/search\")\n@limiter.limit(\"2/second\") # burst limit\nasync def search(request: Request, q: str):\n return {\"results\": []}\n```\n\n### 3. Important Notes\n\n- **The `request: Request` argument is required.** Slowapi needs to inspect the request object to determine the client IP and apply the limit. If you forget it, the decorator will raise an error.\n- **Rate limit string format:** `\"5/minute\"`, `\"10/hour\"`, `\"2/second\"`, `\"100/day\"`, etc.\n\n---\n\n### 4. Per-User (Authenticated) Instead of Per-IP\n\nIf users are logged in, you usually want to rate-limit by **user ID** rather than IP address so multiple people behind a corporate NAT don’t share one bucket.\n\n```python\nfrom fastapi import Request, Depends\nfrom fastapi.security import OAuth2PasswordBearer\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n\nasync def get_user_id_from_token(token: str = Depends(oauth2_scheme)) -> str:\n # ... decode JWT and return user_id\n return \"user_123\"\n\n# Key function that uses the authenticated user\ndef rate_limit_key_func(request: Request):\n # Fallback to IP if no auth (optional)\n return request.state.user_id if hasattr(request.state, \"user_id\") else get_remote_address(request)\n\nlimiter = Limiter(key_func=rate_limit_key_func)\n\n@app.get(\"/profile\")\n@limiter.limit(\"30/minute\")\nasync def profile(request: Request, user_id: str = Depends(get_user_id_from_token)):\n request.state.user_id = user_id\n return {\"user\": user_id}\n```\n\n---\n\n### 5. Behind a Proxy? (X-Forwarded-For)\n\nIf your app sits behind Nginx/Cloudflare, `request.client.host` will be the load balancer’s IP. Use the `X-Forwarded-For` header for the real client IP.\n\n```python\ndef get_real_ip(request: Request) -> str:\n forwarded = request.headers.get(\"x-forwarded-for\")\n if forwarded:\n return forwarded.split(\",\")[0].strip()\n return request.client.host or \"127.0.0.1\"\n\nlimiter = Limiter(key_func=get_real_ip)\n```\n\n---\n\n### 6. Production: Use Redis\n\nBy default, slowapi stores counters in memory. If you run multiple workers (Uvicorn/Gunicorn), each process has its own memory. Use a Redis backend so all workers share the same limits.\n\n```python\nfrom limits.storage import RedisStorage\n\n# Pass the storage URI to the limiter\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379\"\n)\n```\n\n---\n\n### 7. Lightweight DIY Alternative (No Dependencies)\n\nIf you want something minimal without installing `slowapi`, use a custom dependency. \n**Warning:** This only works on a single server instance (memory is not shared across workers), and you should add TTL cleanup to avoid memory leaks.\n\n```python\nimport time\nfrom fastapi import Request, HTTPException, Depends\nfrom collections import defaultdict\n\n# In-memory store: {ip: [list_of_timestamps]}\nclients = defaultdict(list)\n\nasync def rate_limiter(request: Request, max_requests: int = 10, window: int = 60):\n ip = request.client.host or \"unknown\"\n now = time.time()\n\n # Clean old entries older than `window` seconds\n clients[ip] = [t for t in clients[ip] if now - t < window]\n\n if len(clients[ip]) >= max_requests:\n raise HTTPException(status_code=429, detail=\"Rate limit exceeded\")\n\n clients[ip].append(now)\n return True\n\n@app.get(\"/items\")\nasync def read_items(request: Request, allowed: bool = Depends(rate_limiter)):\n return {\"data\": \"Hello\"}\n```\n\n**Recommendation:** Use **slowapi** for anything serious. Use the DIY version only for internal tools or single-instance deployments."
177
- },
178
- {
179
- "loc": 84,
180
- "correct": true,
181
- "timeSec": 8.816,
182
- "usage": {
183
- "inputTokens": 22,
184
- "outputTokens": 1696
185
- },
186
- "response": "Here are the most practical ways to add rate limiting to FastAPI, ranging from **quick decorator-based** limits to **production-ready** distributed limiting.\n\n## Option 1: `slowapi` (Recommended)\n\nThe `slowapi` library is the standard choice for FastAPI. It’s a port of Flask-Limiter.\n\n### 1. Install\n```bash\npip install slowapi redis\n```\n\n### 2. Basic Setup\n```python\nfrom fastapi import FastAPI, Request, Depends\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\n\n# Create the limiter\nlimiter = Limiter(key_func=get_remote_address)\n\napp = FastAPI()\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\n# Optional: apply limits to all routes by default\napp.add_middleware(SlowAPIMiddleware)\n\n@app.get(\"/health\")\n@limiter.limit(\"10/minute\") # 10 requests per minute per IP\nasync def health_check(request: Request):\n return {\"status\": \"ok\"}\n\n@app.post(\"/submit\")\n@limiter.limit(\"5/minute\") # 5 requests per minute\nasync def submit_data(request: Request):\n return {\"message\": \"Data received\"}\n\n@app.get(\"/burst\")\n@limiter.limit(\"1/second;10/minute\") # 1 per second, max 10 per minute\nasync def burst_endpoint(request: Request):\n return {\"message\": \"Burst allowed\"}\n```\n\n**Critical:** The endpoint **must** accept `request: Request` as the first argument. `slowapi` injects the limiter through it.\n\n---\n\n### 3. Per-User (Authenticated) Rate Limiting\nIf you have login/auth, rate limit by user ID instead of IP to prevent users from rotating IPs:\n\n```python\nfrom fastapi import Depends, HTTPException\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\n\nsecurity = HTTPBearer()\n\nasync def get_current_user_id(credentials: HTTPAuthorizationCredentials = Depends(security)):\n # Your auth logic here\n return \"user_123\"\n\n# Key function that uses user ID\ndef rate_limit_key_func(request: Request):\n # Fallback to IP if no auth\n return request.state.user_id if hasattr(request.state, \"user_id\") else get_remote_address(request)\n\nlimiter = Limiter(key_func=rate_limit_key_func)\n\n@app.get(\"/premium\")\n@limiter.limit(\"100/minute\")\nasync def premium_endpoint(\n request: Request,\n user_id: str = Depends(get_current_user_id)\n):\n request.state.user_id = user_id # attach to request for the key function\n return {\"message\": \"Premium data\"}\n```\n\n---\n\n### 4. Production: Redis-backed Storage\nFor multiple server instances, use Redis so the limit is shared across all API instances:\n\n```python\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379/0\", # or rediss:// for TLS\n storage_options={\"socket_connect_timeout\": 30},\n)\n```\n\n---\n\n## Option 2: Custom Middleware (Global Limiter)\n\nIf you want a simple global limit without extra dependencies:\n\n```python\nimport time\nfrom fastapi import FastAPI, Request, HTTPException\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom collections import defaultdict\n\napp = FastAPI()\n\nclass RateLimitMiddleware(BaseHTTPMiddleware):\n def __init__(self, app, max_requests: int, window_seconds: int):\n super().__init__(app)\n self.max_requests = max_requests\n self.window = window_seconds\n self.clients = defaultdict(list)\n \n async def dispatch(self, request: Request, call_next):\n client_ip = request.client.host\n now = time.time()\n \n # Clean old requests\n self.clients[client_ip] = [\n req_time for req_time in self.clients[client_ip]\n if now - req_time < self.window\n ]\n \n if len(self.clients[client_ip]) >= self.max_requests:\n raise HTTPException(status_code=429, detail=\"Rate limit exceeded\")\n \n self.clients[client_ip].append(now)\n return await call_next(request)\n\n# Apply 100 requests per minute globally per IP\napp.add_middleware(RateLimitMiddleware, max_requests=100, window_seconds=60)\n\n@app.get(\"/items\")\nasync def get_items():\n return {\"items\": []}\n```\n\n**Note:** This in-memory approach only works on a single server instance.\n\n---\n\n## Quick Reference: Limit Syntax\n\n| String | Meaning |\n|--------|---------|\n| `\"5/minute\"` | 5 requests per minute |\n| `\"10/hour\"` | 10 per hour |\n| `\"1/second\"` | 1 per second |\n| `\"100/day\"` | 100 per day |\n| `\"5/minute;50/hour\"` | 5 per minute **AND** max 50 per hour |\n\n## Recommended Setup for Production\n\n```python\n# Use Redis + authenticated user keys + custom 429 response\nfrom slowapi import Limiter\nfrom slowapi.wrappers import Limit\nfrom fastapi.responses import JSONResponse\n\nlimiter = Limiter(\n key_func=get_remote_address, \n storage_uri=\"redis://redis:6379\",\n default_limits=[\"200/minute\"] # global default for all routes\n)\n\n@app.exception_handler(RateLimitExceeded)\nasync def custom_rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=429,\n content={\"error\": \"Too many requests. Slow down.\", \"retry_after\": 60}\n )\n```\n\n**Pro tip:** Always return a `429` status with a `Retry-After` header so well-behaved clients back off automatically. `slowapi` handles this automatically if you use its default exception handler."
187
- },
188
- {
189
- "loc": 59,
190
- "correct": true,
191
- "timeSec": 17.605,
192
- "usage": {
193
- "inputTokens": 22,
194
- "outputTokens": 4145
195
- },
196
- "response": "Here are the two best ways to add rate limiting to FastAPI. **Option 1** (`slowapi`) is the quickest to set up (in-memory by default). **Option 2** (`fastapi-limiter`) is best for production if you already have Redis.\n\n---\n\n### Option 1: `slowapi` (Recommended for quick setup)\n\nThis is a port of Flask-Limiter. It defaults to in-memory storage, but you can point it to Redis later.\n\n#### 1. Install\n```bash\npip install slowapi\n```\n\n#### 2. Wire it into your app\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\n\napp = FastAPI()\n\n# Limit by IP address (change this if you want per-user or per-API-key limits)\nlimiter = Limiter(key_func=get_remote_address)\n\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\napp.add_middleware(SlowAPIMiddleware)\n```\n\n#### 3. Decorate endpoints\n```python\n@app.get(\"/public\")\n@limiter.limit(\"10/minute\") # 10 requests per minute per IP\nasync def public_endpoint(request: Request):\n # IMPORTANT: `request: Request` must be in the signature\n return {\"message\": \"This is rate limited by IP\"}\n\n\n@app.post(\"/heavy-job\")\n@limiter.limit(\"1/minute\") # strict limit\nasync def heavy_job(request: Request):\n return {\"message\": \"Processing...\"}\n\n\n@app.get(\"/unlimited\") # no decorator = no limit\nasync def unlimited():\n return {\"message\": \"Free for all\"}\n```\n\n**What the client sees once they exceed the limit:**\n```json\nHTTP 429 Too Many Requests\n{\n \"error\": \"Rate limit exceeded: 10 per 1 minute\"\n}\n```\n\nSlowapi also auto-injects helpful headers like `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `Retry-After`.\n\n---\n\n### Option 2: `fastapi-limiter` (Best for distributed systems / multiple workers)\n\nIf you run multiple FastAPI workers (e.g., with Gunicorn/Uvicorn), in-memory stores won’t share state. Use Redis instead.\n\n#### 1. Install\n```bash\npip install fastapi-limiter redis\n```\n\n#### 2. Add it to your app\n```python\nfrom fastapi import FastAPI, Depends\nimport redis.asyncio as redis\nfrom fastapi_limiter import FastAPILimiter\nfrom fastapi_limiter.depends import RateLimiter\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup():\n redis_connection = redis.from_url(\n \"redis://localhost:6379\",\n encoding=\"utf-8\",\n decode_responses=True\n )\n await FastAPILimiter.init(redis_connection)\n\n@app.get(\"/spam\", dependencies=[Depends(RateLimiter(times=5, seconds=60))])\nasync def spam_endpoint():\n return {\"message\": \"Only 5 requests per minute per IP\"}\n```\n\n---\n\n### Bonus: Limit by user/API key instead of IP\n\nIf your users are authenticated and you want per-account limits, swap the key function.\n\n#### With `slowapi`\n```python\nfrom fastapi import Request\n\ndef rate_limit_key_func(request: Request) -> str:\n # Example: use an API key header, or fall back to IP\n api_key = request.headers.get(\"X-API-Key\")\n if api_key:\n return f\"apikey:{api_key}\"\n return get_remote_address(request)\n\nlimiter = Limiter(key_func=rate_limit_key_func)\n```\n\n#### With `fastapi-limiter`\nOverride the identifier function during startup:\n```python\nasync def custom_identifier(request: Request):\n api_key = request.headers.get(\"X-API-Key\")\n if api_key:\n return api_key\n return request.client.host\n\n@app.on_event(\"startup\")\nasync def startup():\n redis_connection = redis.from_url(\"redis://localhost:6379\")\n await FastAPILimiter.init(redis_connection, identifier=custom_identifier)\n```\n\n---\n\n### Quick rule of thumb\n\n| Setup | Use this |\n|-------|----------|\n| Single instance, quick win | `slowapi` |\n| Multiple workers / Kubernetes | `fastapi-limiter` + Redis |\n| Need to share state across nodes | Redis backend with either library |\n\nIf you paste your current endpoint code here, I can show you exactly where to drop the decorator."
197
- }
198
- ]
199
- },
200
- "lexis-two": {
201
- "email": [
202
- {
203
- "loc": 13,
204
- "correct": false,
205
- "timeSec": 7.944,
206
- "usage": {
207
- "inputTokens": 1531,
208
- "outputTokens": 1548
209
- },
210
- "response": "```python\nfrom email.headerregistry import Address\n\ndef is_valid_email(email: str) -> bool:\n if not email:\n return False\n try:\n Address(addr_spec=email)\n return True\n except ValueError:\n return False\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"a@b.co\") is True\n assert is_valid_email(\"bad\") is False\n assert is_valid_email(\"\") is False\n```\n→ skipped: regex / third-party libs; add when you need RFC 6531 internationalized addresses or custom domain rules."
211
- },
212
- {
213
- "loc": 13,
214
- "correct": false,
215
- "timeSec": 10.644,
216
- "usage": {
217
- "inputTokens": 1531,
218
- "outputTokens": 2151
219
- },
220
- "response": "```python\nfrom email.headerregistry import Address\n\ndef is_valid_email(addr: str) -> bool:\n if not addr or \"@\" not in addr:\n return False\n try:\n Address(addr_spec=addr)\n return True\n except ValueError:\n return False\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"a@b.co\")\n assert not is_valid_email(\"bad\")\n assert not is_valid_email(\"\")\n```\n\nSkipped: custom regex / third-party validators. \nAdd when: you need custom rules (e.g., disposable domains, specific TLDs). \n`email.headerregistry` covers RFC-compliant parsing."
221
- },
222
- {
223
- "loc": 13,
224
- "correct": false,
225
- "timeSec": 5.461,
226
- "usage": {
227
- "inputTokens": 1531,
228
- "outputTokens": 1101
229
- },
230
- "response": "```python\nfrom email.headerregistry import Address\n\ndef is_valid_email(s: str) -> bool:\n if not s or \"@\" not in s:\n return False\n try:\n Address(addr=s)\n return True\n except ValueError:\n return False\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"a@b.co\")\n assert not is_valid_email(\"bad\")\n assert not is_valid_email(\"\")\n```\n\nSkipped: regex and third-party validators. Add when: you need deliverability checks (DNS/MX verification)."
231
- }
232
- ],
233
- "debounce": [
234
- {
235
- "loc": 10,
236
- "correct": true,
237
- "timeSec": 7.311,
238
- "usage": {
239
- "inputTokens": 1544,
240
- "outputTokens": 1297
241
- },
242
- "response": "```javascript\nconst debounce = (fn, wait) => {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n};\n```\n\n```javascript\ndocument.querySelector('#search').addEventListener('input', debounce(e => {\n fetch(`/api/search?q=${encodeURIComponent(e.target.value)}`);\n}, 300));\n```\n\nSkipped: `immediate`/`maxWait` flags and `AbortController` cancellation. Add when you need instant first-keystroke feedback or want to abort in-flight fetches."
243
- },
244
- {
245
- "loc": 8,
246
- "correct": true,
247
- "timeSec": 5.146,
248
- "usage": {
249
- "inputTokens": 1544,
250
- "outputTokens": 1047
251
- },
252
- "response": "```javascript\nfunction debounce(fn, wait = 300) {\n let t;\n return (...args) => { clearTimeout(t); t = setTimeout(() => fn(...args), wait); };\n}\n```\n\n```javascript\n// lexis: 300ms default; drop to 150ms if results feel sluggish\ndocument.getElementById('search').addEventListener(\n 'input',\n debounce(e => fetch('/api/search?q=' + encodeURIComponent(e.target.value)), 300)\n);\n```\n\nSkipped: leading-edge execution, cancel/flush methods, AbortController for in-flight requests. Add when users need immediate feedback or stale request races on slow networks."
253
- },
254
- {
255
- "loc": 11,
256
- "correct": true,
257
- "timeSec": 7.106,
258
- "usage": {
259
- "inputTokens": 1544,
260
- "outputTokens": 1458
261
- },
262
- "response": "```javascript\n// lexis: trailing-edge only; add leading/cancel if UX needs immediate\n// feedback or pending request control\nfunction debounce(fn, wait) {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n}\n```\n\n```javascript\ndocument.getElementById('search')\n .addEventListener('input', debounce(e => {\n fetch(`/api?q=${encodeURIComponent(e.target.value)}`).then(r => r.json());\n }, 300));\n```\n\nSkipped: leading/trailing options, maxWait, cancel. Add when: UX needs immediate first keystroke or request abortion."
263
- }
264
- ],
265
- "csv-sum": [
266
- {
267
- "loc": 3,
268
- "correct": true,
269
- "timeSec": 5.982,
270
- "usage": {
271
- "inputTokens": 1536,
272
- "outputTokens": 874
273
- },
274
- "response": "```python\nimport csv\n\nwith open(\"sales.csv\") as f:\n print(sum(float(r[\"amount\"]) for r in csv.DictReader(f)))\n```\n\nSkipped: error handling, header validation. Add when `sales.csv` might be missing or the `amount` column could contain non-numeric or empty values."
275
- },
276
- {
277
- "loc": 4,
278
- "correct": true,
279
- "timeSec": 7.75,
280
- "usage": {
281
- "inputTokens": 1536,
282
- "outputTokens": 1207
283
- },
284
- "response": "```python\nimport csv\n\nwith open(\"sales.csv\", newline=\"\") as f:\n total = sum(float(row[\"amount\"]) for row in csv.DictReader(f))\n\nprint(total)\n```\n\nSkipped: header validation, error handling, currency parsing. Add when: headers vary, amounts contain '$'/commas, or file is untrusted."
285
- },
286
- {
287
- "loc": 4,
288
- "correct": true,
289
- "timeSec": 3.983,
290
- "usage": {
291
- "inputTokens": 1536,
292
- "outputTokens": 694
293
- },
294
- "response": "```python\nimport csv\n\nwith open(\"sales.csv\") as f:\n total = sum(float(row[\"amount\"]) for row in csv.DictReader(f))\n\nprint(total)\n```\n\nSkipped: error handling, empty/malformed rows. Add when real data has blanks or non-numeric amounts."
295
- }
296
- ],
297
- "countdown": [
298
- {
299
- "loc": 11,
300
- "correct": true,
301
- "timeSec": 10.436,
302
- "usage": {
303
- "inputTokens": 1539,
304
- "outputTokens": 1787
305
- },
306
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nexport default function Countdown({ seconds }) {\n const [remaining, setRemaining] = useState(seconds);\n\n useEffect(() => {\n const id = setInterval(() => setRemaining(r => Math.max(0, r - 1)), 1000);\n return () => clearInterval(id);\n }, []);\n\n const m = Math.floor(remaining / 60).toString().padStart(2, '0');\n const s = (remaining % 60).toString().padStart(2, '0');\n return <div>{m}:{s}</div>;\n}\n```\n\nSkipped: prop-change reset, pause/resume, and custom hook extraction. Add when you need to control the timer from outside or reuse the logic elsewhere."
307
- },
308
- {
309
- "loc": 13,
310
- "correct": true,
311
- "timeSec": 13.821,
312
- "usage": {
313
- "inputTokens": 1539,
314
- "outputTokens": 2736
315
- },
316
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nexport default function Countdown({ seconds }) {\n const [left, setLeft] = useState(seconds);\n\n useEffect(() => setLeft(seconds), [seconds]);\n\n useEffect(() => {\n if (left <= 0) return;\n const id = setTimeout(() => setLeft(l => l - 1), 1000);\n return () => clearTimeout(id);\n }, [left]);\n\n const m = Math.floor(left / 60);\n const s = left % 60;\n return <div>{m}:{s.toString().padStart(2, '0')}</div>;\n}\n```\n\nSkipped: pause/reset buttons, `date-fns`, ms-level drift correction. Add controls when users need to interact; switch to a `Date` deadline if sub-second accuracy matters."
317
- },
318
- {
319
- "loc": 16,
320
- "correct": true,
321
- "timeSec": 14.853,
322
- "usage": {
323
- "inputTokens": 1539,
324
- "outputTokens": 3004
325
- },
326
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nexport default function Countdown({ seconds }) {\n const [left, setLeft] = useState(seconds);\n\n useEffect(() => {\n const id = setInterval(() => {\n setLeft(l => {\n if (l <= 1) { clearInterval(id); return 0; }\n return l - 1;\n });\n }, 1000);\n return () => clearInterval(id);\n }, []); // lexis: functional update avoids stale deps; remount with key={seconds} to reset\n\n const m = Math.floor(left / 60);\n const s = left % 60;\n\n return <div>{m}:{s.toString().padStart(2, '0')}</div>;\n}\n```\n\n```jsx\n// Usage: <Countdown seconds={90} />\n```\n\nSkipped: prop-driven reset, pause/stop, drift correction. Add when you need controls or sub-second precision."
327
- }
328
- ],
329
- "rate-limit": [
330
- {
331
- "loc": 23,
332
- "correct": true,
333
- "timeSec": 18.117,
334
- "usage": {
335
- "inputTokens": 1535,
336
- "outputTokens": 3631
337
- },
338
- "response": "```python\nimport time\nfrom fastapi import FastAPI, Request, HTTPException, Depends\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\n\n# lexis: fixed-window per-IP dict. Bursts at window boundary; add sliding window or Redis only if that matters.\n_limits: dict[str, tuple[int, float]] = {}\n\ndef rate_limit(request: Request, max_req: int = 10, window: int = 60):\n ip = request.client.host if request.client else \"unknown\"\n now = time.time()\n count, start = _limits.get(ip, (0, now))\n if now - start > window:\n count, start = 0, now\n if count >= max_req:\n raise HTTPException(status_code=429, detail=\"Rate limit exceeded\")\n _limits[ip] = (count + 1, start)\n\n@app.get(\"/items\")\nasync def items(_: bool = Depends(rate_limit)):\n return {\"ok\": True}\n\nif __name__ == \"__main__\":\n client = TestClient(app)\n for i in range(12):\n r = client.get(\"/items\")\n assert r.status_code == (200 if i < 10 else 429), r.status_code\n print(\"rate_limit ok\")\n```\n\nskipped: `slowapi` / Redis limiter. add when you run multiple workers or need distributed rate limiting."
339
- },
340
- {
341
- "loc": 24,
342
- "correct": true,
343
- "timeSec": 21.343,
344
- "usage": {
345
- "inputTokens": 1535,
346
- "outputTokens": 4898
347
- },
348
- "response": "```python\nfrom fastapi import FastAPI, Request, Depends, HTTPException\nfrom collections import defaultdict\nimport time, sys\n\napp = FastAPI()\n\n# lexis: in-memory per-process limiter. Resets on restart. Behind a proxy all users share one bucket; upgrade to edge/nginx or redis-backed store if you scale.\nbuckets = defaultdict(list)\n\ndef limiter(max: int = 10, window: int = 60):\n def check(request: Request):\n now = time.time()\n ip = request.client.host if request.client else \"unknown\"\n bucket = buckets[ip]\n bucket[:] = [t for t in bucket if now - t < window]\n if len(bucket) >= max:\n raise HTTPException(429, \"Too many requests\")\n bucket.append(now)\n return check\n\n@app.get(\"/endpoint\")\nasync def endpoint(_=Depends(limiter(max=10, window=60))):\n return {\"ok\": True}\n\nif __name__ == \"__main__\":\n b = defaultdict(list); t = time.time()\n b[\"x\"] = [t - 5, t - 70]\n b[\"x\"][:] = [i for i in b[\"x\"] if t - i < 60]\n assert len(b[\"x\"]) == 1\n print(\"limiter ok\", file=sys.stderr)\n```\n\nSkipped: `slowapi` / redis dependency. Add when: you run multiple instances or need persistent, cross-process limits."
349
- },
350
- {
351
- "loc": 21,
352
- "correct": true,
353
- "timeSec": 16.161,
354
- "usage": {
355
- "inputTokens": 1535,
356
- "outputTokens": 3157
357
- },
358
- "response": "```python\nfrom fastapi import FastAPI, Request, Depends, HTTPException\nimport time\n\napp = FastAPI()\n\n# lexis: in-memory per-IP sliding window. Shared-nothing; upgrade when you scale horizontally.\n_calls: dict[str, list[float]] = {}\n\ndef limit(request: Request, max_requests: int = 10, window: int = 60):\n ip = request.client.host if request.client else \"unknown\"\n now = time.time()\n recent = [t for t in _calls.get(ip, []) if now - t < window]\n if len(recent) >= max_requests:\n raise HTTPException(status_code=429, detail=\"Rate limit exceeded\")\n recent.append(now)\n _calls[ip] = recent\n\n@app.get(\"/spam\")\ndef spam(_=Depends(limit)):\n return {\"ok\": True}\n\n# sanity check\nif __name__ == \"__main__\":\n from fastapi.testclient import TestClient\n client = TestClient(app)\n for i in range(12):\n r = client.get(\"/spam\")\n assert r.status_code == (200 if i < 10 else 429), r.status_code\n```\n\n→ skipped: Redis-backed distributed limiter; add when you run multiple workers."
359
- }
360
- ]
361
- }
362
- },
363
- "deepseek-v4-pro": {
364
- "baseline": {
365
- "email": [
366
- {
367
- "loc": 58,
368
- "correct": true,
369
- "timeSec": 48.55,
370
- "usage": {
371
- "inputTokens": 93,
372
- "outputTokens": 2454
373
- },
374
- "response": "Below is a Python function that performs a pragmatic email validation using regular expressions and standard length checks. It catches most invalid formats while noting a few limitations (such as internationalized domains or quoted local parts). For production use, consider the `email-validator` library (PyPI), which fully adheres to RFC standards.\n\n```python\nimport re\nfrom typing import Union\n\ndef validate_email(email: str) -> bool:\n \"\"\"\n Validate an email address for common formatting rules.\n\n Args:\n email: The string to check.\n\n Returns:\n True if the email passes basic validation, False otherwise.\n \"\"\"\n # Must be a non-empty string\n if not isinstance(email, str) or not email:\n return False\n\n # Maximum total length according to RFC 5321\n if len(email) > 254:\n return False\n\n # -------------------------------------------------------------------\n # Regex explanation (simplified for typical addresses):\n # local part: allowed characters (letters, digits, and !#$%&'*+/=?^_`{|}~-)\n # domain part: labels that start/end with alphanumeric, hyphens allowed inside,\n # separated by dots, and a TLD of at least 2 letters.\n # This regex intentionally does not support:\n # - Quoted local parts (e.g., \"john..doe\"@example.com)\n # - Internationalized email addresses (IDN / UTF-8)\n # - IP address domains (e.g., user@[192.168.1.1])\n # -------------------------------------------------------------------\n pattern = re.compile(\n r\"^(?P<local>[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+)\" # local part\n r\"@(?P<domain>\" # domain part\n r\"(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)\" # subdomain(s)\n r\"+[a-zA-Z]{2,}\" # TLD\n r\")$\"\n )\n\n match = pattern.match(email)\n if not match:\n return False\n\n local = match.group('local')\n domain = match.group('domain')\n\n # Local part max length (RFC 5321)\n if len(local) > 64:\n return False\n\n # Domain max length (RFC 1035)\n if len(domain) > 255:\n return False\n\n # Commonly rejected patterns in the local part\n if '..' in local:\n return False\n if local.startswith('.') or local.endswith('.'):\n return False\n\n return True\n\n\n# ------------------ usage example ------------------\nif __name__ == \"__main__\":\n test_emails = [\n \"simple@example.com\",\n \"very.common@example.com\",\n \"disposable.style.email.with+symbol@example.com\",\n \"other.email-with-hyphen@example.com\",\n \"fully-qualified-domain@example.com\",\n \"user.name+tag+sorting@example.com\",\n \"x@example.com\", # one-letter local part\n \"example-indeed@strange-example.com\",\n # invalid ones\n \"plainaddress\",\n \"@missing-local.org\",\n \"missing-domain@.com\",\n \"two..dots@example.com\",\n \".starts-with-dot@example.com\",\n \"ends-with-dot.@example.com\",\n \"special-char-()-@example.com\",\n \"just\\\"not\\\"right@example.com\",\n \"this\\\\ still\\\"not\\\\allowed@example.com\",\n \"over-65-characters-local-part###########################################@example.com\",\n ]\n\n for e in test_emails:\n print(f\"{e:60} -> {validate_email(e)}\")\n```\n\n**Key points:**\n\n- **Length checks:** The whole email (≤254 chars), local part (≤64), and domain (≤255) are verified.\n- **Regex:** Covers the vast majority of everyday email addresses. It rejects missing `@`, empty local/domain, consecutive dots, or leading/trailing dots in the local part.\n- **Limitations:** For full RFC 5321/5322 compliance (including quoted strings, IP domains, and internationalized addresses), use the dedicated [`email-validator`](https://pypi.org/project/email-validator/) package. The above function is a lightweight, dependency-free solution that works for most typical use cases.\n\nYou can adjust the regex to be stricter or more lenient depending on your specific needs."
375
- },
376
- {
377
- "loc": 36,
378
- "correct": true,
379
- "timeSec": 37.21,
380
- "usage": {
381
- "inputTokens": 93,
382
- "outputTokens": 2117
383
- },
384
- "response": "Here's a Python function that validates email addresses using a regular expression and several length constraints derived from email standards (RFC 5321/5322). It covers the vast majority of real‑world addresses while remaining simple.\n\n```python\nimport re\n\ndef validate_email(email: str) -> bool:\n \"\"\"\n Validate an email address based on format and length constraints.\n\n Args:\n email (str): The email address to validate.\n\n Returns:\n bool: True if the email appears valid, False otherwise.\n\n Notes:\n - This is a simplified validator. It does not fully implement all\n RFC rules (e.g., quoted local parts, IP‑address domains, comments).\n - For production use, consider a dedicated library like `email-validator`.\n \"\"\"\n if not isinstance(email, str) or not email:\n return False\n\n # Overall email length limit (RFC 5321: 254 octets)\n if len(email) > 254:\n return False\n\n # Split local and domain parts\n parts = email.split('@')\n if len(parts) != 2:\n return False\n local_part, domain_part = parts[0], parts[1]\n\n # Local part max 64 octets, domain max 253 characters\n if len(local_part) > 64 or len(domain_part) > 253:\n return False\n\n # Regular expression: common allowed characters + structural rules\n # - Local part: letters, digits, dots, underscores, percent, plus, hyphen\n # - Domain: letters, digits, hyphens, dots, must contain at least one dot\n # - TLD: letters only, minimum 2 characters\n pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n if not re.match(pattern, email):\n return False\n\n return True\n```\n\n**Usage example:**\n\n```python\nprint(validate_email(\"user@example.com\")) # True\nprint(validate_email(\"invalid-email\")) # False\n```\n\n**Important caveat:** \nThis function intentionally avoids the full complexity of RFC 5322. For stricter compliance (e.g., handling quoted strings like `\"very.(),:;<>[]\\\".VERY.\\\"very@\\\\ \\\"very\\\".unusual\"@strange.example.com`), use the lightweight third‑party library [`email-validator`](https://github.com/JoshData/python-email-validator), which also checks domain deliverability:\n\n```python\n# pip install email-validator\nfrom email_validator import validate_email, EmailNotValidError\n\ndef is_valid_email(email: str) -> bool:\n try:\n validate_email(email, check_deliverability=True) # checks DNS / MX records\n return True\n except EmailNotValidError:\n return False\n```"
385
- },
386
- {
387
- "loc": 29,
388
- "correct": true,
389
- "timeSec": 26.705,
390
- "usage": {
391
- "inputTokens": 93,
392
- "outputTokens": 1133
393
- },
394
- "response": "Below is a Python function that validates email addresses using a regular expression. It checks the overall structure (local part, `@`, domain, and TLD) and covers most common use cases. For more exotic valid addresses (e.g., quoted strings, IP‑address domains), you’d need a more sophisticated parser, but this works well for typical input.\n\n```python\nimport re\nfrom email.utils import parseaddr\n\ndef validate_email(email: str) -> bool:\n \"\"\"\n Return True if the given string appears to be a valid email address,\n False otherwise.\n\n The function first uses the standard library's `parseaddr` to extract\n the actual address (stripping display names), then checks its structure\n with a regular expression.\n\n Rules enforced:\n - local part: letters, digits, and characters ._%+-\n - exactly one '@' symbol\n - domain: letters, digits, hyphens, and dots\n - top-level domain (TLD): at least two letters (e.g., .com, .org)\n\n Examples:\n >>> validate_email(\"user@example.com\")\n True\n >>> validate_email(\"invalid@@example.com\")\n False\n >>> validate_email(\"John Doe <john.doe@company.co.uk>\")\n True\n >>> validate_email(\"plain.address\")\n False\n \"\"\"\n # Extract the pure email address from a potentially formatted string.\n name, addr = parseaddr(email)\n\n # If parseaddr couldn't find an address, it returns an empty string.\n if not addr:\n return False\n\n # Regular expression covering common RFC 5322 allowed characters in a\n # simplified manner. It does not support quoted local parts, comments,\n # IP domain literals, or non-ASCII characters (IDN).\n pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n\n return re.match(pattern, addr) is not None\n```\n\n**How it works:** \n1. `email.utils.parseaddr` splits a string like `\"John Doe <john.doe@company.co.uk>\"` into a display name and the address itself. It gracefully handles missing angle brackets and returns an empty string if no address is found. \n2. The regular expression then verifies that the address contains only allowed characters and has the basic `local@domain.tld` structure. \n\n**Notes & limitations:** \n- The regex deliberately excludes quotes, spaces, and special characters in the local part (even though they are technically valid per the RFC) to reject addresses that are rarely used in practice and often indicate input errors. \n- Internationalized domain names (IDNs) are not covered; you can adapt the regex or call `email` methods for those if needed. \n- For critical production validation, consider sending a confirmation email — syntactical checks alone cannot guarantee an address actually exists or accepts mail. \n\nYou can extend the function easily by modifying the regex or adding additional checks (e.g., length limits, DNS lookup of the domain)."
395
- }
396
- ],
397
- "debounce": [
398
- {
399
- "loc": 61,
400
- "correct": true,
401
- "timeSec": 31.934,
402
- "usage": {
403
- "inputTokens": 106,
404
- "outputTokens": 1452
405
- },
406
- "response": "To prevent your search input from firing an API call on every single keystroke, you need **debouncing**. Debouncing ensures that the API call is made only after the user stops typing for a specified delay (e.g., 300ms). This reduces server load and improves performance.\n\nHere’s how to implement it in vanilla JavaScript.\n\n---\n\n## 1. Create a reusable debounce function\n\nThe core idea is to wrap your API call inside a function that clears the previous timeout and sets a new one each time the event triggers.\n\n```javascript\nfunction debounce(func, delay) {\n let timeoutId;\n \n // Return a new function that wraps the original\n return function(...args) {\n // Clear the previous timer\n clearTimeout(timeoutId);\n \n // Set a new timer\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n```\n\n- `func`: the function you want to execute (your API call).\n- `delay`: the wait time in milliseconds after the last keystroke.\n\n---\n\n## 2. Apply it to your search input\n\nAssume you have an `<input>` with an event listener that currently calls `fetchResults(query)` on every `input` event.\n\n```html\n<input type=\"text\" id=\"search\" placeholder=\"Search...\" />\n```\n\n### Before (problematic)\n```javascript\ndocument.getElementById('search').addEventListener('input', (e) => {\n fetchResults(e.target.value); // ❌ fires on every keystroke\n});\n```\n\n### After (debounced)\n```javascript\nconst searchInput = document.getElementById('search');\n\n// Debounced version of your API call\nconst debouncedFetch = debounce((query) => {\n fetchResults(query);\n}, 300); // 300ms delay\n\nsearchInput.addEventListener('input', (e) => {\n debouncedFetch(e.target.value);\n});\n```\n\nNow `fetchResults` will only be called **once**, 300ms after the user stops typing.\n\n---\n\n## 3. Complete working example\n\nHere’s a full HTML page demonstrating the concept (the API call is simulated with a `console.log`):\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Debounced Search</title>\n</head>\n<body>\n <label for=\"search\">Search:</label>\n <input type=\"text\" id=\"search\" placeholder=\"Type to search...\" />\n\n <script>\n // 1. Debounce utility\n function debounce(func, delay) {\n let timeoutId;\n return function(...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n }\n\n // 2. Simulated API call\n function fetchResults(query) {\n console.log('API call with:', query);\n // Here you would do: fetch(`/search?q=${query}`)...\n }\n\n // 3. Attach debounced listener\n const searchInput = document.getElementById('search');\n const debouncedSearch = debounce(fetchResults, 300);\n\n searchInput.addEventListener('input', (e) => {\n debouncedSearch(e.target.value);\n });\n </script>\n</body>\n</html>\n```\n\n---\n\n## 4. Important details\n\n### Choosing the delay\n- **200–300ms** is typical for search inputs – it feels responsive without being too aggressive.\n- For operations like resizing or scrolling, you might use **100–150ms**.\n- For autosave features, **1–2 seconds** may be appropriate.\n\n### The `apply(this, args)` pattern\nUsing `func.apply(this, args)` preserves the correct `this` context and passes along any arguments (like the input value) to the original function. This makes the debounce wrapper safe to reuse.\n\n### Cleanup (memory leak prevention)\nIf you later remove the input element from the DOM (e.g., in a single-page app), the timeout might still fire and cause errors. To avoid that, keep a reference to the timeout and clear it when the component is destroyed:\n\n```javascript\nconst debouncedFunc = debounce(originalFunc, 300);\n// Later, when cleaning up:\nclearTimeout(debouncedFunc._timeoutId); // You'd need to expose it\n\n// Alternative: make timeoutId accessible\nfunction debounce(func, delay) {\n let timeoutId;\n const debounced = function(...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => func.apply(this, args), delay);\n };\n debounced.cancel = () => clearTimeout(timeoutId);\n return debounced;\n}\n```\n\nNow you can call `debouncedSearch.cancel()` if needed.\n\n### Leading / trailing execution\nThe example above uses **trailing debounce** (executes after the delay). If you need the API to fire immediately on the first keystroke and then ignore subsequent ones (leading debounce), you can extend the function, but for most search inputs, trailing is what you want.\n\n---\n\nBy adding this small utility, you’ll dramatically reduce unnecessary network requests while keeping the user experience smooth."
407
- },
408
- {
409
- "loc": 74,
410
- "correct": true,
411
- "timeSec": 21.122,
412
- "usage": {
413
- "inputTokens": 106,
414
- "outputTokens": 1260
415
- },
416
- "response": "To prevent your search input from firing an API call on every keystroke, you can implement a **debounce** function in vanilla JavaScript. Debouncing ensures that the API call is only made after the user has stopped typing for a specified amount of time (e.g., 300ms).\n\nHere's a step-by-step guide:\n\n---\n\n### 1. A reusable `debounce` function\n```javascript\nfunction debounce(func, delay) {\n let timeoutId;\n return function (...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n```\n\n**How it works:** \nEvery time the debounced function is called, it clears the previous timer and starts a new one. The original function only executes once the timer completes without being reset.\n\n---\n\n### 2. Applying it to the search input\nAssume your existing code looks something like this:\n```javascript\nconst searchInput = document.getElementById('search');\n\nsearchInput.addEventListener('input', (event) => {\n const query = event.target.value;\n fetchResults(query); // your API call\n});\n```\n\nRefactor it using the debounce utility:\n```javascript\nconst searchInput = document.getElementById('search');\n\n// Create a debounced version of your search function\nconst debouncedSearch = debounce((query) => {\n fetchResults(query);\n}, 300); // 300ms delay\n\nsearchInput.addEventListener('input', (event) => {\n const query = event.target.value;\n debouncedSearch(query);\n});\n```\n\nNow `fetchResults` will be called **only once** 300ms after the user stops typing.\n\n---\n\n### 3. Advanced: Canceling previous API requests\nIf the user types again before the API responds, you might want to abort the earlier request to avoid race conditions. Use the `AbortController` API:\n\n```javascript\nlet controller = null;\n\nasync function fetchResults(query) {\n // Cancel the previous request if it's still pending\n if (controller) {\n controller.abort();\n }\n\n controller = new AbortController();\n const signal = controller.signal;\n\n try {\n const response = await fetch(`/api/search?q=${query}`, { signal });\n const data = await response.json();\n // update UI with data\n } catch (error) {\n if (error.name !== 'AbortError') {\n console.error('Search failed:', error);\n }\n }\n}\n```\n\nCombine this with the debounce for an optimal experience.\n\n---\n\n### 4. Complete working example\n```html\n<input type=\"text\" id=\"search\" placeholder=\"Type to search...\" />\n\n<script>\nfunction debounce(func, delay) {\n let timeout;\n return function (...args) {\n clearTimeout(timeout);\n timeout = setTimeout(() => func.apply(this, args), delay);\n };\n}\n\nlet abortController = null;\n\nasync function performSearch(query) {\n // Abort previous request\n if (abortController) abortController.abort();\n abortController = new AbortController();\n\n try {\n const res = await fetch(`/search?q=${encodeURIComponent(query)}`, {\n signal: abortController.signal,\n });\n const data = await res.json();\n console.log('Results:', data);\n } catch (err) {\n if (err.name !== 'AbortError') console.error(err);\n }\n}\n\nconst debouncedSearch = debounce(performSearch, 300);\n\ndocument.getElementById('search').addEventListener('input', (e) => {\n debouncedSearch(e.target.value);\n});\n</script>\n```\n\n---\n\n### 5. Choosing the right delay\n- **~300–500ms** is typical for search inputs – it feels responsive but reduces load.\n- For long/complex queries you might increase it; for autocomplete you may go as low as 150ms.\n\n### 6. Leading vs. trailing edge\nThe classic debounce (above) fires on the **trailing edge** (after the user stops). If you want the first keystroke to fire immediately and then wait, you can implement a **leading-edge debounce**. That’s less common for search but easy to adapt:\n\n```javascript\nfunction debounceLeading(func, delay) {\n let timeout;\n return function (...args) {\n if (!timeout) func.apply(this, args);\n clearTimeout(timeout);\n timeout = setTimeout(() => (timeout = null), delay);\n };\n}\n```\n\n---\n\nBy adding debounce (and optionally request cancellation), you drastically reduce unnecessary API calls, improve performance, and provide a smoother user experience."
417
- },
418
- {
419
- "loc": 50,
420
- "correct": true,
421
- "timeSec": 19.796,
422
- "usage": {
423
- "inputTokens": 106,
424
- "outputTokens": 1123
425
- },
426
- "response": "To prevent overwhelming your API with a request on every keystroke, implement a **debounce** function. Debouncing ensures that the API call only fires after the user has stopped typing for a specified delay (e.g., 300 milliseconds).\n\nHere's a clean vanilla JavaScript implementation:\n\n```javascript\n/**\n * Creates a debounced version of a function that delays its execution\n * until after `delay` milliseconds have elapsed since the last invocation.\n * @param {Function} func - The function to debounce.\n * @param {number} delay - The debounce delay in milliseconds.\n * @returns {Function} - The debounced function.\n */\nfunction debounce(func, delay) {\n let timeoutId;\n return function (...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n```\n\n### HTML\n\n```html\n<input type=\"text\" id=\"search\" placeholder=\"Search...\" />\n<div id=\"results\"></div>\n```\n\n### JavaScript with API call\n\n```javascript\nconst searchInput = document.getElementById('search');\nconst resultsDiv = document.getElementById('results');\n\n// The actual search logic\nasync function performSearch(query) {\n if (!query.trim()) {\n resultsDiv.innerHTML = '';\n return;\n }\n try {\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);\n const data = await response.json();\n // Update the UI with results\n resultsDiv.innerHTML = data.map(item => `<p>${item.name}</p>`).join('');\n } catch (error) {\n console.error('Search failed:', error);\n }\n}\n\n// Create a debounced version that waits 300ms after the last keystroke\nconst debouncedSearch = debounce((event) => {\n performSearch(event.target.value);\n}, 300);\n\n// Attach the event listener\nsearchInput.addEventListener('input', debouncedSearch);\n```\n\n### How it works\n\n- Each keystroke clears the previous timer and sets a new one.\n- Only when the user pauses (no new keystrokes for 300ms) does `performSearch` actually execute.\n- The first keystroke after a pause will still wait the full delay. If you want an immediate execution on the first keystroke and then debounce subsequent ones, use a **leading‑edge debounce**, but the trailing‑edge version above is the most common and network‑friendly.\n\n### Bonus: Canceling in‑flight requests\n\nIf a new keystroke arrives while a previous API call is still pending, you may want to cancel that stale request to avoid race conditions. Use an `AbortController`:\n\n```javascript\nlet abortController = null;\n\nasync function performSearch(query) {\n // Cancel any ongoing request\n if (abortController) abortController.abort();\n\n if (!query.trim()) {\n resultsDiv.innerHTML = '';\n return;\n }\n\n abortController = new AbortController();\n try {\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {\n signal: abortController.signal\n });\n const data = await response.json();\n resultsDiv.innerHTML = data.map(item => `<p>${item.name}</p>`).join('');\n } catch (error) {\n if (error.name !== 'AbortError') {\n console.error('Search failed:', error);\n }\n }\n}\n```\n\nNow your search input efficiently debounces user input and avoids unnecessary API calls."
427
- }
428
- ],
429
- "csv-sum": [
430
- {
431
- "loc": 25,
432
- "correct": true,
433
- "timeSec": 10.365,
434
- "usage": {
435
- "inputTokens": 98,
436
- "outputTokens": 561
437
- },
438
- "response": "```python\nimport csv\nimport sys\n\ndef sum_amount_column(filename='sales.csv'):\n \"\"\"Read a CSV file and return the sum of the 'amount' column.\"\"\"\n total = 0.0\n try:\n with open(filename, mode='r', newline='', encoding='utf-8') as file:\n reader = csv.DictReader(file)\n # Check if 'amount' column exists\n if 'amount' not in reader.fieldnames:\n raise ValueError(f\"Column 'amount' not found in {filename}\")\n \n for row_num, row in enumerate(reader, start=2): # start=2 because of header\n try:\n total += float(row['amount'])\n except (ValueError, TypeError) as e:\n print(f\"Warning: Skipping row {row_num} due to invalid amount: {row.get('amount')}\", file=sys.stderr)\n return total\n except FileNotFoundError:\n print(f\"Error: The file '{filename}' was not found.\", file=sys.stderr)\n sys.exit(1)\n except Exception as e:\n print(f\"An error occurred: {e}\", file=sys.stderr)\n sys.exit(1)\n\nif __name__ == \"__main__\":\n total_amount = sum_amount_column()\n print(f\"Total amount: {total_amount}\")\n```"
439
- },
440
- {
441
- "loc": 10,
442
- "correct": true,
443
- "timeSec": 8.917,
444
- "usage": {
445
- "inputTokens": 98,
446
- "outputTokens": 401
447
- },
448
- "response": "```python\nimport csv\n\ntotal = 0.0\n\nwith open('sales.csv', mode='r', newline='', encoding='utf-8') as file:\n reader = csv.DictReader(file)\n for row in reader:\n try:\n total += float(row['amount'])\n except (ValueError, KeyError) as e:\n print(f\"Skipping row due to error: {e}\")\n\nprint(f\"Total amount: {total}\")\n```"
449
- },
450
- {
451
- "loc": 33,
452
- "correct": true,
453
- "timeSec": 29.799,
454
- "usage": {
455
- "inputTokens": 98,
456
- "outputTokens": 1630
457
- },
458
- "response": "```python\nimport csv\nimport re\n\ntotal = 0.0\n\ntry:\n with open('sales.csv', 'r', encoding='utf-8-sig') as file:\n reader = csv.DictReader(file)\n \n # Find the 'amount' column, ignoring case and surrounding whitespace\n amount_column = None\n for col in reader.fieldnames:\n if col.strip().lower() == 'amount':\n amount_column = col\n break\n \n if amount_column is None:\n raise ValueError(\"Column 'amount' not found in CSV header.\")\n \n # Process each row\n for row in reader:\n raw_value = row[amount_column].strip()\n if not raw_value:\n continue\n \n # Remove currency symbols, commas, and other non-numeric characters\n cleaned = re.sub(r'[^\\d.\\-]', '', raw_value)\n if cleaned:\n try:\n total += float(cleaned)\n except ValueError:\n print(f\"Warning: Could not convert '{raw_value}' to float. Skipping.\")\n \n print(f\"Total amount: {total}\")\n\nexcept FileNotFoundError:\n print(\"Error: 'sales.csv' not found.\")\nexcept Exception as e:\n print(f\"An error occurred: {e}\")\n```\n\n**Alternatively**, if you have **pandas** installed, the task becomes a one‑liner:\n\n```python\nimport pandas as pd\n\ndf = pd.read_csv('sales.csv')\ndf.columns = df.columns.str.strip().str.lower()\ntotal = df['amount'].sum()\nprint(f\"Total amount: {total}\")\n```"
459
- }
460
- ],
461
- "countdown": [
462
- {
463
- "loc": 113,
464
- "correct": true,
465
- "timeSec": 82.153,
466
- "usage": {
467
- "inputTokens": 102,
468
- "outputTokens": 4387
469
- },
470
- "response": "Below is a fully functional React countdown timer component built with hooks. It accepts an initial number of seconds, counts down in real time, and provides controls to start, pause, resume, and reset. You can also pass an optional callback that fires when the timer reaches zero.\n\n```tsx\nimport React, { useState, useEffect, useRef } from 'react';\n\n/* --------------------- Types --------------------- */\ninterface CountdownTimerProps {\n /** Number of seconds to count down from */\n initialSeconds: number;\n /** Called when the timer reaches 0 */\n onComplete?: () => void;\n /** Whether the timer should start automatically on mount (default: true) */\n autoStart?: boolean;\n}\n\n/* --------------------- Component --------------------- */\nconst CountdownTimer: React.FC<CountdownTimerProps> = ({\n initialSeconds,\n onComplete,\n autoStart = true,\n}) => {\n const [timeLeft, setTimeLeft] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(autoStart);\n const [isPaused, setIsPaused] = useState(false);\n\n const intervalRef = useRef<NodeJS.Timeout | null>(null);\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n\n // Reset timer when initialSeconds or autoStart changes\n useEffect(() => {\n setTimeLeft(initialSeconds);\n setIsRunning(autoStart);\n setIsPaused(false);\n }, [initialSeconds, autoStart]);\n\n // Main interval logic\n useEffect(() => {\n // Only start interval if running, not paused, and time remains\n if (isRunning && !isPaused && timeLeft > 0) {\n intervalRef.current = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n // Timer finished\n clearInterval(intervalRef.current!);\n onCompleteRef.current?.();\n setIsRunning(false);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }\n\n // Cleanup on state change or unmount\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [isRunning, isPaused]); // intentionally omit timeLeft\n\n // ---------- Controls ----------\n const start = () => {\n setTimeLeft((prev) => (prev <= 0 ? initialSeconds : prev));\n setIsRunning(true);\n setIsPaused(false);\n };\n\n const togglePause = () => {\n setIsPaused((prev) => !prev);\n };\n\n const reset = () => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n setTimeLeft(initialSeconds);\n setIsRunning(false);\n setIsPaused(false);\n };\n\n // ---------- Formatting ----------\n const formatTime = (totalSeconds: number): string => {\n const mins = Math.floor(totalSeconds / 60);\n const secs = totalSeconds % 60;\n return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n };\n\n // ---------- Render ----------\n return (\n <div style={{ textAlign: 'center', fontFamily: 'monospace' }}>\n <div style={{ fontSize: '3rem', margin: '1rem 0' }}>\n {formatTime(timeLeft)}\n </div>\n\n <div>\n {(!isRunning || isPaused) && timeLeft > 0 && (\n <button onClick={start} style={buttonStyle}>\n Start\n </button>\n )}\n {isRunning && !isPaused && (\n <button onClick={togglePause} style={buttonStyle}>\n Pause\n </button>\n )}\n {isPaused && (\n <button onClick={togglePause} style={buttonStyle}>\n Resume\n </button>\n )}\n <button onClick={reset} style={buttonStyle}>\n Reset\n </button>\n </div>\n </div>\n );\n};\n\n/* --------------------- Styles --------------------- */\nconst buttonStyle: React.CSSProperties = {\n margin: '0 0.5rem',\n padding: '0.5rem 1.2rem',\n fontSize: '1rem',\n cursor: 'pointer',\n border: '1px solid #ccc',\n borderRadius: '4px',\n background: '#f5f5f5',\n};\n\nexport default CountdownTimer;\n```\n\n---\n\n### Usage Example\n\n```tsx\nimport React from 'react';\nimport CountdownTimer from './CountdownTimer';\n\nconst App = () => (\n <div>\n <h2>5‑Minute Timer</h2>\n <CountdownTimer\n initialSeconds={300} // 5 minutes\n autoStart={false} // user must click Start\n onComplete={() => alert('Time’s up!')}\n />\n </div>\n);\n\nexport default App;\n```\n\n### Key Features\n- **Controls** – Start, Pause, Resume, and Reset buttons.\n- **Auto‑start** – Optional, controlled via the `autoStart` prop.\n- **Completion callback** – Triggers `onComplete` exactly once when `00:00` is reached.\n- **Self‑cleaning intervals** – No memory leaks; intervals are cleared on pause, reset, unmount, and timer expiry.\n- **Responsive** – The display shows `MM:SS` format; easily styleable via inline styles or CSS modules.\n\nThe component is written in TypeScript but works identically if you drop the interface and type annotations for plain JSX."
471
- },
472
- {
473
- "loc": 119,
474
- "correct": false,
475
- "timeSec": 28.189,
476
- "usage": {
477
- "inputTokens": 102,
478
- "outputTokens": 1854
479
- },
480
- "response": "Here's a versatile React countdown timer component with start, pause, reset functionality, precise time tracking, and cleanup. It accepts an initial number of seconds and provides an optional callback when the countdown completes.\n\n```tsx\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\n\ninterface CountdownTimerProps {\n initialSeconds: number;\n onComplete?: () => void;\n autoStart?: boolean;\n format?: 'mm:ss' | 'hh:mm:ss';\n className?: string;\n}\n\nconst formatTime = (totalSeconds: number, format: 'mm:ss' | 'hh:mm:ss' = 'mm:ss'): string => {\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n const pad = (num: number) => String(num).padStart(2, '0');\n\n if (format === 'hh:mm:ss' || hours > 0) {\n return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;\n }\n return `${pad(minutes)}:${pad(seconds)}`;\n};\n\nconst CountdownTimer: React.FC<CountdownTimerProps> = ({\n initialSeconds,\n onComplete,\n autoStart = true,\n format = 'mm:ss',\n className,\n}) => {\n const [remainingSeconds, setRemainingSeconds] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(autoStart);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const onCompleteRef = useRef(onComplete);\n const endTimeRef = useRef<number>(0);\n\n // Keep the callback ref updated\n useEffect(() => {\n onCompleteRef.current = onComplete;\n }, [onComplete]);\n\n // Sync remainingSeconds when initialSeconds changes (if not running)\n useEffect(() => {\n if (!isRunning) {\n setRemainingSeconds(initialSeconds);\n }\n }, [initialSeconds, isRunning]);\n\n // Core countdown logic using date-based precision\n useEffect(() => {\n if (isRunning && remainingSeconds > 0) {\n // Calculate the exact end time when starting/resuming\n endTimeRef.current = Date.now() + remainingSeconds * 1000;\n\n intervalRef.current = setInterval(() => {\n const now = Date.now();\n const remaining = Math.max(0, Math.round((endTimeRef.current - now) / 1000));\n\n setRemainingSeconds(remaining);\n\n if (remaining <= 0) {\n clearInterval(intervalRef.current!);\n intervalRef.current = null;\n setIsRunning(false);\n onCompleteRef.current?.();\n }\n }, 200); // Check more frequently for better accuracy\n } else if (!isRunning || remainingSeconds <= 0) {\n // Cleanup interval if paused or completed\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [isRunning]); // Restart effect when isRunning changes\n\n const start = useCallback(() => {\n if (remainingSeconds > 0) setIsRunning(true);\n }, [remainingSeconds]);\n\n const pause = useCallback(() => setIsRunning(false), []);\n \n const reset = useCallback(() => {\n setIsRunning(false);\n setRemainingSeconds(initialSeconds);\n }, [initialSeconds]);\n\n const toggle = useCallback(() => {\n if (remainingSeconds <= 0) {\n reset();\n setIsRunning(true); // auto-start after reset\n } else {\n setIsRunning(prev => !prev);\n }\n }, [remainingSeconds, reset]);\n\n return (\n <div className={`countdown-timer ${className || ''}`} role=\"timer\" aria-live=\"polite\">\n <div className=\"time-display\" style={{ fontSize: '2em', fontVariantNumeric: 'tabular-nums' }}>\n {formatTime(remainingSeconds, format)}\n </div>\n <div className=\"controls\" style={{ marginTop: '0.5em' }}>\n <button onClick={start} disabled={isRunning || remainingSeconds <= 0}>\n Start\n </button>\n <button onClick={pause} disabled={!isRunning}>\n Pause\n </button>\n <button onClick={reset}>\n Reset\n </button>\n <button onClick={toggle}>\n {isRunning ? 'Pause' : remainingSeconds <= 0 ? 'Restart' : 'Start'}\n </button>\n </div>\n </div>\n );\n};\n\nexport default CountdownTimer;\n```\n\n## Usage Example\n\n```tsx\nimport CountdownTimer from './CountdownTimer';\n\nfunction App() {\n const handleComplete = () => alert('Time is up!');\n\n return (\n <div>\n <h1>Countdown Timer</h1>\n <CountdownTimer \n initialSeconds={120} \n onComplete={handleComplete} \n autoStart={false} \n format=\"mm:ss\"\n />\n </div>\n );\n}\n```\n\n## Key Features\n\n- **Accurate timing** – Uses `Date.now()` to compute remaining time, avoiding drift even when the browser tab is inactive.\n- **Controls** – Start, pause, reset, and a combined toggle button for convenience.\n- **Auto-start** – Configurable via the `autoStart` prop.\n- **Callback** – Fires `onComplete` when the countdown reaches zero.\n- **Formatting** – Supports `mm:ss` and `hh:mm:ss` display.\n- **Accessible** – Uses `role=\"timer\"` and `aria-live` for screen readers.\n- **Cleanup** – Properly clears intervals on unmount to prevent memory leaks.\n\nFeel free to adjust the styles or remove controls for a simpler, auto-running timer."
481
- },
482
- {
483
- "loc": 102,
484
- "correct": true,
485
- "timeSec": 33.662,
486
- "usage": {
487
- "inputTokens": 102,
488
- "outputTokens": 2523
489
- },
490
- "response": "Below is a full-featured **React countdown timer component** that counts down from a given number of seconds. It supports `Start`, `Pause`, `Resume`, and `Reset` actions, calls an optional `onComplete` callback when it reaches zero, and can optionally auto‑start.\n\n```tsx\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\n\ninterface CountdownTimerProps {\n /** Total seconds to count down from */\n initialSeconds: number;\n /** Callback fired when the countdown reaches 0 */\n onComplete?: () => void;\n /** Whether the timer should start immediately on mount / when initialSeconds changes */\n autoStart?: boolean;\n}\n\nconst CountdownTimer: React.FC<CountdownTimerProps> = ({\n initialSeconds,\n onComplete,\n autoStart = false,\n}) => {\n const [timeLeft, setTimeLeft] = useState<number>(initialSeconds);\n const [isRunning, setIsRunning] = useState<boolean>(autoStart);\n const intervalRef = useRef<NodeJS.Timeout | null>(null);\n\n // Keep the latest callback in a ref to avoid stale closures\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n\n // Helper to clear the interval\n const clearTimer = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n }, []);\n\n // Start (or resume) the timer\n const startTimer = useCallback(() => {\n if (timeLeft > 0) {\n setIsRunning(true);\n }\n }, [timeLeft]);\n\n // Pause the timer without resetting\n const pauseTimer = useCallback(() => {\n setIsRunning(false);\n clearTimer();\n }, [clearTimer]);\n\n // Reset the timer to the initial value\n const resetTimer = useCallback(() => {\n clearTimer();\n setTimeLeft(initialSeconds);\n setIsRunning(false);\n }, [initialSeconds, clearTimer]);\n\n // Core interval effect\n useEffect(() => {\n if (isRunning && timeLeft > 0) {\n intervalRef.current = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n // We reach 0 → clear and fire callback\n clearTimer();\n setIsRunning(false);\n if (onCompleteRef.current) {\n onCompleteRef.current();\n }\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }\n\n // Cleanup on effect re-run or unmount\n return clearTimer;\n }, [isRunning, clearTimer]); // timeLeft intentionally omitted – we use functional update\n\n // When the initialSeconds prop changes, reset the timer\n useEffect(() => {\n setTimeLeft(initialSeconds);\n setIsRunning(autoStart);\n }, [initialSeconds, autoStart]);\n\n // Display formatting (mm:ss)\n const formatTime = (totalSeconds: number): string => {\n const mins = Math.floor(totalSeconds / 60);\n const secs = totalSeconds % 60;\n return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n };\n\n const isFresh = timeLeft === initialSeconds && !isRunning;\n\n return (\n <div className=\"countdown-timer\">\n <div className=\"time-display\" role=\"timer\" aria-live=\"polite\">\n {formatTime(timeLeft)}\n </div>\n <div className=\"controls\">\n {!isRunning && timeLeft > 0 && isFresh && (\n <button onClick={startTimer}>Start</button>\n )}\n {isRunning && <button onClick={pauseTimer}>Pause</button>}\n {!isRunning && timeLeft > 0 && !isFresh && (\n <button onClick={startTimer}>Resume</button>\n )}\n <button onClick={resetTimer} disabled={isFresh}>\n Reset\n </button>\n </div>\n </div>\n );\n};\n\nexport default CountdownTimer;\n```\n\n---\n\n### Usage Example\n\n```tsx\nimport React from 'react';\nimport CountdownTimer from './CountdownTimer';\n\nconst App: React.FC = () => {\n const handleComplete = () => {\n alert('Time is up!');\n };\n\n return (\n <div>\n <h2>Countdown: 150 seconds (2:30)</h2>\n <CountdownTimer\n initialSeconds={150}\n onComplete={handleComplete}\n autoStart={false}\n />\n </div>\n );\n};\n```\n\n---\n\n### Key Features\n\n- **Accurate counting** – uses functional state updates to avoid stale closures.\n- **Safe side effects** – the interval is always cleaned up when the component unmounts or the timer stops.\n- **Responsive to prop changes** – resetting when `initialSeconds` changes (e.g., from a parent).\n- **Accessible** – includes `role=\"timer\"` and `aria-live=\"polite\"` for screen readers.\n- **Zero external dependencies** – relies only on React hooks (`useState`, `useEffect`, `useRef`, `useCallback`).\n\nYou can easily style the component by targeting the CSS classes `.countdown-timer`, `.time-display`, and `.controls`."
491
- }
492
- ],
493
- "rate-limit": [
494
- {
495
- "loc": 53,
496
- "correct": true,
497
- "timeSec": 23.996,
498
- "usage": {
499
- "inputTokens": 98,
500
- "outputTokens": 1296
501
- },
502
- "response": "To prevent spam on your FastAPI endpoint, you can implement **rate limiting**—which restricts how many requests a user can make within a given time window. The easiest way is to use the `slowapi` library, but you can also write custom middleware.\n\nHere’s a step-by-step guide:\n\n---\n\n## 1. Using `slowapi` (Recommended)\n\n`slowapi` is a FastAPI-friendly wrapper around the `limits` library. It supports in-memory, Redis, and other backends.\n\n### Installation\n```bash\npip install slowapi\n# optional for Redis backend\npip install redis\n```\n\n### Basic Setup\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\n\n# Create a limiter with a key function (IP address here)\nlimiter = Limiter(key_func=get_remote_address)\n\napp = FastAPI()\n\n# Attach the limiter's state to the app\napp.state.limiter = limiter\n\n# Register the rate limit exceeded handler\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n```\n\n### Apply to an Endpoint\n```python\n@app.get(\"/limited\")\n@limiter.limit(\"5/minute\") # <-- rate limit string\nasync def limited_endpoint(request: Request):\n return {\"message\": \"You can call this 5 times per minute.\"}\n```\n\n**Rate limit string format:** `\"5/minute\"`, `\"10/second\"`, `\"100/hour\"`, `\"50/day\"`, etc.\n\n### Multiple Limits (e.g., burst + sustained)\n```python\n@limiter.limit(\"5/minute; 20/hour\")\nasync def multi_limited(request: Request):\n ...\n```\n\n---\n\n## 2. Using Redis (Production)\nSwitch to Redis to share limits across multiple workers:\n\n```python\nfrom slowapi.storage import RedisStorage\nimport redis\n\nredis_client = redis.Redis(host=\"localhost\", port=6379, db=0)\nlimiter = Limiter(key_func=get_remote_address, storage=RedisStorage(redis_client))\n```\n\n---\n\n## 3. Custom Key Function (e.g., by user ID)\nIf your app uses authentication, you might want to limit by user instead of IP:\n\n```python\nasync def get_user_id(request: Request) -> str:\n user = request.user # depends on your auth setup\n return user.id if user else get_remote_address(request)\n\nlimiter = Limiter(key_func=get_user_id)\n```\n\n---\n\n## 4. Custom Middleware (No External Library)\nIf you prefer a minimal solution, you can write your own middleware using an in‑memory store or Redis:\n\n### In‑Memory Example (Not for multi‑worker production)\n```python\nimport time\nfrom collections import defaultdict\nfrom fastapi import Request, HTTPException\n\nrequest_counts = defaultdict(list)\n\ndef rate_limit(limit: int, window: int):\n def decorator(func):\n async def wrapper(request: Request):\n client_ip = request.client.host\n now = time.time()\n # Remove timestamps outside the window\n request_counts[client_ip] = [t for t in request_counts[client_ip] if now - t < window]\n if len(request_counts[client_ip]) >= limit:\n raise HTTPException(status_code=429, detail=\"Too many requests\")\n request_counts[client_ip].append(now)\n return await func(request)\n return wrapper\n return decorator\n\n@app.get(\"/custom-limited\")\n@rate_limit(limit=5, window=60) # 5 requests per 60 seconds\nasync def custom_limited(request: Request):\n return {\"message\": \"Custom rate limit works!\"}\n```\n\n> ⚠️ This simple in‑memory approach won’t work with multiple processes/servers and doesn’t auto‑clean old entries. Use Redis or a dedicated library in production.\n\n---\n\n## 5. Customizing the 429 Response\nWith `slowapi`, you can override the error handler:\n\n```python\nfrom slowapi.errors import RateLimitExceeded\n\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=429,\n content={\"detail\": f\"Rate limit exceeded. Try again in {exc.retry_after} seconds.\"},\n headers={\"Retry-After\": str(exc.retry_after)}\n )\n```\n\n---\n\n## 6. Important Considerations\n- **Header info:** `slowapi` automatically adds `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `Retry-After` headers.\n- **Granularity:** Consider limiting per user, per IP, or per API key depending on your authentication.\n- **Persistence:** Use Redis for shared state in multi-worker deployments (Gunicorn/Uvicorn with multiple workers).\n- **Storage backends:** `slowapi` supports in‑memory, Redis, Memcached, DynamoDB, and others.\n\n---\n\nBy adding just a decorator with `slowapi`, you can effectively protect your endpoint from abuse. Start simple with in‑memory limits, and scale to Redis when needed."
503
- },
504
- {
505
- "loc": 53,
506
- "correct": true,
507
- "timeSec": 31.551,
508
- "usage": {
509
- "inputTokens": 98,
510
- "outputTokens": 1792
511
- },
512
- "response": "To prevent abuse and manage traffic, you can add rate limiting to your FastAPI endpoints. The easiest way is to use a dedicated library like **`slowapi`**, which is built on top of the battle-tested [`limits`](https://limits.readthedocs.io/) package. It works with in-memory storage (for development) or Redis (for production/multi-worker setups).\n\nBelow is a step-by-step guide, plus a lightweight alternative if you prefer a custom solution.\n\n---\n\n## Option 1: Using `slowapi` (Recommended)\n\n### 1. Install the library\n```bash\npip install slowapi\n# For Redis support:\npip install slowapi[redis]\n```\n\n### 2. Basic setup\nCreate a `Limiter` instance, register the middleware, and apply limits to your routes.\n\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\nfrom slowapi.util import get_remote_address\n\napp = FastAPI()\n\n# The key function determines who the client is. Here we use IP address.\nlimiter = Limiter(key_func=get_remote_address)\n\n# Attach the limiter to the app (so middleware and dependencies can access it)\napp.state.limiter = limiter\n\n# Handle 429 responses gracefully\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\n# The middleware is required for the limiter to function\napp.add_middleware(SlowAPIMiddleware)\n\n@app.get(\"/health\")\n@limiter.limit(\"10/minute\") # max 10 requests per minute per IP\nasync def health(request: Request):\n return {\"status\": \"ok\"}\n\n@app.get(\"/resource\")\n@limiter.limit(\"5/minute\")\nasync def get_resource(request: Request):\n return {\"data\": \"Here is your resource\"}\n```\n\n### 3. Custom client identification (e.g., by user ID)\nIf your users are authenticated, you probably want to limit by user ID instead of IP. Just provide a custom `key_func`:\n\n```python\nfrom slowapi.util import get_remote_address\n\ndef get_user_or_ip(request: Request):\n user = getattr(request.state, \"user\", None) # depends on your auth setup\n if user and hasattr(user, \"id\"):\n return user.id\n return get_remote_address(request)\n\nlimiter = Limiter(key_func=get_user_or_ip)\n```\n\n### 4. Using a Redis backend (production)\nBy default, rate limits are stored in memory and lost on restart. Switch to Redis for persistence and shared state across workers:\n\n```python\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379/0\" # or rediss:// for TLS\n)\n```\n\n### 5. Advanced limits\n- Multiple limits on one endpoint: `@limiter.limit(\"5/second;100/minute;2000/day\")`\n- Apply globally with middleware (instead of per-route) – see [slowapi docs](https://slowapi.readthedocs.io/en/latest/).\n\n---\n\n## Option 2: Lightweight custom dependency (in‑memory only)\n\nIf you don’t want an external library and are running a single‑process app, you can implement a simple sliding‑window limiter using a `Depends`.\n\n```python\nimport time\nfrom collections import defaultdict\nfrom fastapi import FastAPI, Depends, HTTPException, Request\n\napp = FastAPI()\n# In-memory store: { client_key: [timestamps] }\nrate_limit_store = defaultdict(list)\n\ndef rate_limiter(max_requests: int, window: int):\n async def limiter(request: Request):\n client_ip = request.client.host\n now = time.time()\n # Remove timestamps outside the window\n rate_limit_store[client_ip] = [\n t for t in rate_limit_store[client_ip] if now - t < window\n ]\n if len(rate_limit_store[client_ip]) >= max_requests:\n raise HTTPException(status_code=429, detail=\"Rate limit exceeded\")\n rate_limit_store[client_ip].append(now)\n return limiter\n\n@app.get(\"/custom\")\nasync def custom_endpoint(\n request: Request,\n _: None = Depends(rate_limiter(max_requests=5, window=60))\n):\n return {\"message\": \"You are within the limit\"}\n```\n\n⚠️ This custom version **does not** clean up old entries and will **not work across multiple workers** unless you use a shared store like Redis.\n\n---\n\n## Which approach should you choose?\n- **`slowapi`** – proven, scalable, supports multiple backends, and integrates cleanly.\n- **Custom dependency** – only for the simplest single‑process demos or if you have extremely specific needs.\n\nFor any production system, go with `slowapi` + Redis. It will save you from edge cases like clock drift, distributed state, and proper HTTP 429 headers."
513
- },
514
- {
515
- "loc": 77,
516
- "correct": true,
517
- "timeSec": 37.27,
518
- "usage": {
519
- "inputTokens": 98,
520
- "outputTokens": 2167
521
- },
522
- "response": "To prevent clients from spamming your FastAPI endpoint, you can integrate a rate‑limiting mechanism. The most straightforward approach is to use the `slowapi` library, which is built on top of `limits` and works seamlessly with FastAPI (or Starlette). Below I’ll walk you through the setup, configuration, and usage, both for development (in‑memory storage) and for production (with Redis).\n\n---\n\n## 1. Choose a Rate‑Limiting Library\n\n**Recommended:** [`slowapi`](https://pypi.org/project/slowapi/) – a simple, well‑maintained implementation that can be applied as a decorator, a dependency, or as middleware.\n\n**Alternatives:** \n- [`fastapi-limiter`](https://github.com/long2ice/fastapi-limiter) (uses Redis, decorator‑based) \n- Custom implementation using `asyncio`, `redis`, or in‑memory stores.\n\nIn this guide we’ll focus on `slowapi`.\n\n---\n\n## 2. Installation\n\n```bash\npip install slowapi\n# For production with Redis (recommended for multi‑process / multi‑worker setups):\npip install limits[redis] redis\n```\n\n---\n\n## 3. Global Setup (In‑Memory Example)\n\nCreate a `Limiter` instance, attach it to the FastAPI app’s state, and add the `SlowAPIASGIMiddleware` (or use the `limit` dependency when you need more control).\n\n```python\nfrom fastapi import FastAPI\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.middleware import SlowAPIASGIMiddleware\nfrom slowapi.errors import RateLimitExceeded\n\nlimiter = Limiter(key_func=get_remote_address)\napp = FastAPI()\n\n# Register the rate‑limit handler\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n# Add the middleware (this injects rate‑limit headers and handles early rejection)\napp.add_middleware(SlowAPIASGIMiddleware)\n```\n\n**Key points:** \n- `key_func` determines how a client is identified. Here we use the client’s remote IP – `get_remote_address` is a built‑in helper that extracts the IP from the request. \n- The middleware and exception handler ensure that when a limit is exceeded, the client receives a `429 Too Many Requests` response.\n\n---\n\n## 4. Apply Rate Limiting to an Endpoint\n\n### 4.1 Decorator Style\n\n```python\n@app.get(\"/items\")\n@limiter.limit(\"5/minute\") # ≤ 5 requests per minute per client\nasync def read_items(request: Request):\n return {\"items\": [...]}\n```\n\n### 4.2 Dependency Style (more control, e.g., for multiple limits)\n\n```python\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(key_func=get_remote_address)\n\n@app.get(\"/login\")\nasync def login(request: Request, rate_limit = Depends(limiter.limit(\"3/minute\"))):\n # your login logic\n return {\"message\": \"ok\"}\n```\n\nWhen using `Depends`, the limit is checked before the endpoint function runs. The `rate_limit` argument is not used inside the function; it just forces the dependency to execute.\n\n---\n\n## 5. Production Setup – Redis Backend\n\nIn‑memory storage works only within a single process. If you run your app with multiple workers (e.g., `uvicorn --workers 4`), each worker maintains its own counters – clients can bypass the limit by hitting different workers. Redis solves this.\n\n**Configure `slowapi` with Redis:**\n\n```python\nfrom slowapi import Limiter\nfrom slowapi.storage import RedisStorage\nimport redis\n\nredis_client = redis.from_url(\"redis://localhost:6379/0\")\nstorage = RedisStorage(redis_client)\nlimiter = Limiter(key_func=get_remote_address, storage=storage)\n# ... rest of the setup is identical\n```\n\nYou can also use `limits`'s built‑in Redis support by simply passing the Redis URL:\n\n```python\nlimiter = Limiter(key_func=get_remote_address, storage_uri=\"redis://localhost:6379/0\")\n```\n\n---\n\n## 6. Different Rate‑Limit Strategies\n\n`slowapi` supports several algorithms via its `limits` parameter:\n\n- Fixed window: `\"5/minute\"` – allows up to 5 requests in a calendar minute.\n- Moving window: `\"5/minute/moving\"` – smoother, counts the last 60 seconds.\n- Token bucket (more suitable for bursting): `\"5 per 1 minute\"` with a max burst.\n- Custom callables: you can provide your own function.\n\nExample with token bucket:\n```python\n@limiter.limit(\"5/10seconds;3/minute\") # two overlapping limits\nasync def special_endpoint(request: Request): ...\n```\n\n---\n\n## 7. Full Example Application\n\n```python\nimport redis\nfrom fastapi import FastAPI, Request, Depends\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.middleware import SlowAPIASGIMiddleware\nfrom slowapi.errors import RateLimitExceeded\n\n# Use Redis in production, fallback to in-memory for development\ntry:\n r = redis.from_url(\"redis://localhost:6379/0\")\n storage_uri = \"redis://localhost:6379/0\"\nexcept:\n r = None\n storage_uri = \"memory://\"\n\nlimiter = Limiter(key_func=get_remote_address, storage_uri=storage_uri)\napp = FastAPI()\n\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\napp.add_middleware(SlowAPIASGIMiddleware)\n\n@app.get(\"/public\")\n@limiter.limit(\"10/minute\")\nasync def public_endpoint(request: Request):\n return {\"message\": \"This is rate limited\"}\n\n@app.get(\"/admin\")\n@limiter.limit(\"2/minute\")\nasync def admin_endpoint(request: Request, user: str = Depends(verify_admin)):\n return {\"message\": f\"Hello admin {user}\"}\n```\n\n---\n\n## 8. Important Considerations\n\n- **Client identification:** The default `get_remote_address` uses the request’s IP. If your app is behind a proxy, make sure you extract the original IP correctly (e.g., using the `X-Forwarded-For` header). `slowapi` provides a `get_ipaddr` function, or you can write your own `key_func`.\n\n- **Error response customization:** The default `_rate_limit_exceeded_handler` returns a plain text response. You can override it to return JSON:\n\n```python\nfrom slowapi.errors import RateLimitExceeded\nfrom starlette.responses import JSONResponse\n\n@app.exception_handler(RateLimitExceeded)\nasync def custom_rate_limit_handler(request, exc):\n return JSONResponse(\n status_code=429,\n content={\"detail\": \"Rate limit exceeded. Try again later.\"}\n )\n```\n\n- **Exempting endpoints:** You can skip the middleware for certain routes or use `@limiter.limit(None)`.\n\n- **Testing:** During tests you might want to disable limits – you can reach into `app.state.limiter` and mock or reset the storage.\n\n---\n\n## 9. Alternative: `fastapi-limiter`\n\nIf you only need Redis‑backed, decorator‑based limiting, [`fastapi-limiter`](https://github.com/long2ice/fastapi-limiter) is another popular choice:\n\n```python\nfrom fastapi import FastAPI\nfrom fastapi_limiter import FastAPILimiter\nfrom fastapi_limiter.depends import RateLimiter\nimport redis.asyncio as redis\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup():\n r = redis.from_url(\"redis://localhost:6379\", encoding=\"utf-8\", decode_responses=True)\n await FastAPILimiter.init(r)\n\n@app.get(\"/\")\n@RateLimiter(times=5, seconds=60) # 5 requests per 60 seconds\nasync def root():\n return {\"message\": \"Hello\"}\n```\n\nIt uses asynchronous Redis and is purely dependency‑based.\n\n---\n\nBy adding rate limiting, you protect your server from abuse, accidental overuse, or brute‑force attacks. Start with the in‑memory setup for development, then move to Redis when you scale horizontally."
523
- }
524
- ]
525
- },
526
- "lexis-two": {
527
- "email": [
528
- {
529
- "loc": 9,
530
- "correct": true,
531
- "timeSec": 58.203,
532
- "usage": {
533
- "inputTokens": 1815,
534
- "outputTokens": 2695
535
- },
536
- "response": "```python\nimport re\n\ndef is_valid_email(email: str) -> bool:\n # lexis: simple regex covers 99% of practical use cases; full RFC 5322 is overkill here\n return re.match(r'^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$', email) is not None\n\nif __name__ == \"__main__\":\n # lexis: runnable self-check\n assert is_valid_email(\"user@example.com\") == True\n assert is_valid_email(\"invalid\") == False\n assert is_valid_email(\"a@b.c\") == True\n assert is_valid_email(\"no.dot@domain\") == False\n print(\"All checks passed\")\n```\n\nSkipped: RFC 5322 edge cases (quoted local parts, comments, IP domains). Add when bounce rates rise, a spec demands strict compliance, or you need to support internal-only addresses without dots."
537
- },
538
- {
539
- "loc": 2,
540
- "correct": true,
541
- "timeSec": 68.671,
542
- "usage": {
543
- "inputTokens": 1815,
544
- "outputTokens": 3328
545
- },
546
- "response": "```python\nimport re\nis_valid_email = re.compile(r'^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$').match\n```\n→ skipped: RFC 5322 edge cases; add `email-validator` when the regex breaks."
547
- },
548
- {
549
- "loc": 14,
550
- "correct": false,
551
- "timeSec": 83.012,
552
- "usage": {
553
- "inputTokens": 1815,
554
- "outputTokens": 4113
555
- },
556
- "response": "```python\nfrom email.headerregistry import Address\nfrom email.errors import HeaderParseError\n\ndef is_valid_email(email: str) -> bool:\n \"\"\"Syntactic email validation using the stdlib's RFC parser.\"\"\"\n try:\n Address(addr_spec=email)\n return True\n except (HeaderParseError, ValueError):\n return False\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"user@example.com\")\n assert not is_valid_email(\"not-an-email\")\n assert not is_valid_email(\"\")\n print(\"ok\")\n```\n\nSkipped: custom regex, third‑party libs. Uses `email.headerregistry.Address` (RFC 5322 coverage). For most apps, sending a confirmation email is the only real validation—this catches obvious typos."
557
- }
558
- ],
559
- "debounce": [
560
- {
561
- "loc": 12,
562
- "correct": true,
563
- "timeSec": 19.516,
564
- "usage": {
565
- "inputTokens": 1828,
566
- "outputTokens": 915
567
- },
568
- "response": "```javascript\nfunction debounce(fn, delay) {\n let timer;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => fn(...args), delay);\n };\n}\n```\n\n```javascript\n// Wiring (adjust selector and API endpoint as needed)\ndocument.getElementById('search').addEventListener('input',\n debounce((e) => {\n fetch(`/search?q=${encodeURIComponent(e.target.value)}`);\n }, 300)\n);\n```\n\n→ skipped: immediate or flush options, `AbortController` to cancel in-flight requests. Add when a specific use case demands them, or when requests complete out of order."
569
- },
570
- {
571
- "loc": 11,
572
- "correct": true,
573
- "timeSec": 16.342,
574
- "usage": {
575
- "inputTokens": 1828,
576
- "outputTokens": 779
577
- },
578
- "response": "```javascript\n// lexis: simplest debounce, no leading/trailing options\nfunction debounce(fn, delay) {\n let timer;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => fn(...args), delay);\n };\n}\n```\n```javascript\n// wiring (example: 300ms delay)\nconst searchInput = document.getElementById('search');\nsearchInput.addEventListener('input', debounce(() => {\n fetchResults(searchInput.value);\n}, 300));\n```\n\n→ skipped: leading/trailing edge modes, immediate invocation, AbortController for cancelling in-flight requests. Add those when UX needs them."
579
- },
580
- {
581
- "loc": 13,
582
- "correct": false,
583
- "timeSec": 16.821,
584
- "usage": {
585
- "inputTokens": 1828,
586
- "outputTokens": 829
587
- },
588
- "response": "```javascript\nfunction debounce(fn, delay) {\n let timer; // lexis: timer per invocation, holds one pending call\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => fn(...args), delay);\n };\n}\n\n// Attach to your input (assumes id=\"search-input\")\nconst handleSearch = debounce(async (e) => {\n const query = e.target.value.trim();\n if (!query) return;\n const res = await fetch(`/search?q=${encodeURIComponent(query)}`);\n // use res\n}, 300);\n\ndocument.querySelector('#search-input')?.addEventListener('input', handleSearch);\n```\nSkipped: cancellation of in‑flight requests, leading‑edge debounce. Add when you need AbortController or immediate first call."
589
- }
590
- ],
591
- "csv-sum": [
592
- {
593
- "loc": 15,
594
- "correct": true,
595
- "timeSec": 32.892,
596
- "usage": {
597
- "inputTokens": 1820,
598
- "outputTokens": 1379
599
- },
600
- "response": "```python\nimport csv\n\ndef sum_amount(path=\"sales.csv\"):\n \"\"\"Return the sum of the 'amount' column in a CSV file.\"\"\"\n total = 0.0\n with open(path, newline=\"\") as f:\n for row in csv.DictReader(f):\n val = row.get(\"amount\")\n if val:\n try:\n total += float(val)\n except ValueError:\n pass # lexis: skip non‑numeric values, add logging if unclean data is a problem\n return total\n\nif __name__ == \"__main__\":\n print(sum_amount())\n```\n\n→ Skipped: `pandas`, custom error recovery, CLI arguments. Add when you need DataFrames or this is part of a larger pipeline."
601
- },
602
- {
603
- "loc": 3,
604
- "correct": true,
605
- "timeSec": 20.693,
606
- "usage": {
607
- "inputTokens": 1820,
608
- "outputTokens": 1032
609
- },
610
- "response": "```python\nimport csv\n\nwith open('sales.csv') as f:\n print(sum(float(row['amount']) for row in csv.DictReader(f)))\n```\n\nSkipped: error handling, CSV dialect options, and decimal precision. Add when needed."
611
- },
612
- {
613
- "loc": 4,
614
- "correct": true,
615
- "timeSec": 25.552,
616
- "usage": {
617
- "inputTokens": 1820,
618
- "outputTokens": 1217
619
- },
620
- "response": "```python\nimport csv\n\nwith open('sales.csv', newline='') as f:\n total = sum(float(row['amount']) for row in csv.DictReader(f))\nprint(f'{total:.2f}')\n```\n\nSkipped: error handling for missing/bad data or absent file. Add when the input is untrusted."
621
- }
622
- ],
623
- "countdown": [
624
- {
625
- "loc": 12,
626
- "correct": true,
627
- "timeSec": 22.059,
628
- "usage": {
629
- "inputTokens": 1824,
630
- "outputTokens": 1046
631
- },
632
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nconst CountdownTimer = ({ seconds }) => {\n const [remaining, setRemaining] = useState(seconds);\n useEffect(() => {\n setRemaining(seconds);\n if (seconds <= 0) return;\n const id = setInterval(() => setRemaining(r => (r > 0 ? r - 1 : 0)), 1000);\n return () => clearInterval(id);\n }, [seconds]);\n return <span>{remaining}</span>;\n};\n\nexport default CountdownTimer;\n```\n\nskipped: exact clearing of interval at zero (keeps ticking harmlessly), custom hook extraction; add when sub‑second precision or massive instance count makes the no‑op setState matter."
633
- },
634
- {
635
- "loc": 13,
636
- "correct": true,
637
- "timeSec": 45.493,
638
- "usage": {
639
- "inputTokens": 1824,
640
- "outputTokens": 2543
641
- },
642
- "response": "```jsx\nimport React, { useState, useEffect } from 'react';\n\nexport default function CountdownTimer({ initialSeconds }) {\n const [timeLeft, setTimeLeft] = useState(initialSeconds);\n\n useEffect(() => {\n if (timeLeft <= 0) return;\n const timeout = setTimeout(() => setTimeLeft(t => t - 1), 1000);\n return () => clearTimeout(timeout);\n }, [timeLeft]);\n\n const minutes = Math.floor(timeLeft / 60);\n const seconds = timeLeft % 60;\n const formatted = `${minutes}:${seconds.toString().padStart(2, '0')}`;\n\n return <span>{formatted}</span>;\n}\n```\n\nSkipped: restart on prop change, on-complete callback, custom formatting, accessibility (live region), and any external dependency. Add when the UX requires them."
643
- },
644
- {
645
- "loc": 10,
646
- "correct": true,
647
- "timeSec": 65.358,
648
- "usage": {
649
- "inputTokens": 1824,
650
- "outputTokens": 2843
651
- },
652
- "response": "```jsx\nimport React, { useState, useEffect } from 'react';\n\nexport default function CountdownTimer({ seconds = 0 }) {\n const [timeLeft, setTimeLeft] = useState(Math.max(0, seconds));\n\n useEffect(() => {\n if (timeLeft <= 0) return;\n const id = setTimeout(() => setTimeLeft(timeLeft - 1), 1000);\n return () => clearTimeout(id);\n }, [timeLeft]);\n\n return <span role=\"timer\" aria-live=\"polite\">{timeLeft}</span>;\n}\n```\n`// lexis: setTimeout chain avoids interval management.`\n\n**skipped:** pause/resume, onComplete callback, mid‑stream prop‑change handling. Use `key={seconds}` on the component if you need it to restart when the prop changes."
653
- }
654
- ],
655
- "rate-limit": [
656
- {
657
- "loc": 32,
658
- "correct": true,
659
- "timeSec": 73.502,
660
- "usage": {
661
- "inputTokens": 1820,
662
- "outputTokens": 3669
663
- },
664
- "response": "```python\n# lexis: in-memory per-worker rate limiter; no new deps needed.\n# For multi-worker or persistent limits, pip install slowapi + Redis.\nfrom collections import defaultdict\nimport time\nfrom fastapi import FastAPI, Request, HTTPException\n\nclass RateLimiter:\n def __init__(self):\n self.requests = defaultdict(list)\n\n def __call__(self, max_req: int, period: float):\n async def limiter(request: Request):\n now = time.time()\n ip = request.client.host # lexis: direct client IP; use X-Forwarded-For if proxied\n self.requests[ip] = [t for t in self.requests[ip] if now - t <= period]\n if len(self.requests[ip]) >= max_req:\n raise HTTPException(429, \"Too many requests\")\n self.requests[ip].append(now)\n return limiter\n\nlimiter = RateLimiter() # singleton, one per process\n\n# --- usage (apply to any endpoint) ---\n# from fastapi import Depends\n# @app.get(\"/spam\", dependencies=[Depends(limiter(max_req=5, period=60))])\n# async def spam_endpoint(): ...\n\n# --- minimal self-check ---\nif __name__ == \"__main__\":\n class FakeRequest:\n class client:\n host = \"127.0.0.1\"\n\n async def demo():\n check = limiter(3, 10) # max 3 req / 10 s\n for _ in range(3):\n await check(FakeRequest()) # ok\n try:\n await check(FakeRequest()) # should block\n except HTTPException as e:\n assert e.status_code == 429\n else:\n raise AssertionError(\"rate limit not enforced\")\n\n import asyncio; asyncio.run(demo())\n print(\"OK – rate limiting works\")\n```\n\n**Skipped:** persistent/shared storage, proxy header handling, endpoint-specific via decorator (use `Depends`). **Add when:** you need multi-worker consistency (then `pip install slowapi` with Redis/Etcd backend) or graceful per-key cleanup."
665
- },
666
- {
667
- "loc": 20,
668
- "correct": true,
669
- "timeSec": 47.007,
670
- "usage": {
671
- "inputTokens": 1820,
672
- "outputTokens": 2684
673
- },
674
- "response": "```python\nimport time\nfrom collections import defaultdict\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom starlette.responses import Response\n\nclass RateLimitMiddleware(BaseHTTPMiddleware):\n def __init__(self, app, max_requests=100, window=60):\n super().__init__(app)\n self.max_requests = max_requests\n self.window = window\n self._clients = defaultdict(list) # lexis: in-memory per-process store\n\n async def dispatch(self, request, call_next):\n ip = request.client.host\n now = time.time()\n # Keep only requests within the window\n self._clients[ip] = [t for t in self._clients[ip] if now - t < self.window]\n if len(self._clients[ip]) >= self.max_requests:\n return Response(\"Too many requests\", status_code=429)\n self._clients[ip].append(now)\n return await call_next(request)\n\n# In main.py\napp = FastAPI()\napp.add_middleware(RateLimitMiddleware, max_requests=100, window=60)\n```\n\nSkipped: proxy headers, per‑endpoint limits, shared state for multi‑process. \nAdd when behind a reverse proxy or scaling beyond one process."
675
- },
676
- {
677
- "loc": 18,
678
- "correct": true,
679
- "timeSec": 39.076,
680
- "usage": {
681
- "inputTokens": 1820,
682
- "outputTokens": 1725
683
- },
684
- "response": "```python\n# lexis: in-memory sliding window; single process only, lost on restart. Use Redis when you need shared state or persistence.\nimport time\nfrom collections import defaultdict\nfrom fastapi import Request, HTTPException\nimport asyncio\n\nclass RateLimiter:\n def __init__(self, max_requests: int = 5, window_seconds: int = 60):\n self.max_requests = max_requests\n self.window = window_seconds\n self.requests: defaultdict[str, list[float]] = defaultdict(list)\n self.lock = asyncio.Lock()\n\n async def __call__(self, request: Request):\n ip = request.client.host\n now = time.time()\n async with self.lock:\n # lexis: O(k) trim where k = requests in window. Acceptable for spam prevention.\n self.requests[ip] = [t for t in self.requests[ip] if now - t < self.window]\n if len(self.requests[ip]) >= self.max_requests:\n raise HTTPException(status_code=429, detail=\"Too many requests\")\n self.requests[ip].append(now)\n\n# Apply to a specific endpoint (or globally with app.dependency_overrides):\n# from fastapi import Depends\n# @app.get(\"/sensitive\", dependencies=[Depends(RateLimiter(max_requests=10, window_seconds=60))])\n```\nSkipped: persistent store (Redis), distributed coordination, configurable per-route limits via env. Add when you spawn multiple workers or need to survive restarts."
685
- }
686
- ]
687
- }
688
- },
689
- "qwen3.7-max": {
690
- "baseline": {
691
- "email": [
692
- {
693
- "loc": 36,
694
- "correct": true,
695
- "timeSec": 43.099,
696
- "usage": {
697
- "inputTokens": 20,
698
- "outputTokens": 2284
699
- },
700
- "response": "Here are the two best ways to validate an email address in Python, depending on your needs. \n\n### 1. The Quick & Built-in Way (Regular Expressions)\nIf you just need basic syntax validation without installing external packages, use the built-in `re` module. \n\n```python\nimport re\n\ndef is_valid_email_regex(email: str) -> bool:\n \"\"\"\n Validates an email address using a regular expression.\n Checks for basic syntax correctness.\n \"\"\"\n # A practical, widely-used regex pattern for email validation\n pattern = r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\n \n # re.fullmatch ensures the entire string matches the pattern\n if re.fullmatch(pattern, email):\n return True\n return False\n\n# --- Examples ---\nprint(is_valid_email_regex(\"user@example.com\")) # True\nprint(is_valid_email_regex(\"first.last@domain.co.uk\")) # True\nprint(is_valid_email_regex(\"user+tag@gmail.com\")) # True\nprint(is_valid_email_regex(\"invalid-email@domain\")) # False (missing TLD)\nprint(is_valid_email_regex(\"@missingusername.com\")) # False\n```\n\n### 2. The Production-Ready Way (Recommended)\nRegular expressions only check **syntax**. They will happily accept `fake_user@nonexistent-domain-12345.com`. \n\nFor real-world applications (like user registration), you should use the **`email-validator`** library. It checks syntax, verifies that the domain actually exists (via DNS lookup), and catches disposable/invalid domains.\n\nFirst, install the library:\n```bash\npip install email-validator\n```\n\nThen, use this function:\n\n```python\nfrom email_validator import validate_email, EmailNotValidError\n\ndef is_valid_email_production(email: str) -> dict:\n \"\"\"\n Validates an email address thoroughly (Syntax + DNS check).\n Returns a dictionary with validation status and normalized email.\n \"\"\"\n try:\n # Check that the email address is valid\n valid = validate_email(email, check_deliverability=True)\n \n return {\n \"is_valid\": True,\n \"normalized\": valid.normalized, # e.g., lowercased, stripped of unnecessary tags\n \"domain\": valid.domain\n }\n \n except EmailNotValidError as e:\n # The exception message contains a human-readable explanation\n return {\n \"is_valid\": False,\n \"error\": str(e)\n }\n\n# --- Examples ---\nprint(is_valid_email_production(\"User@GMAIL.com\")) \n# {'is_valid': True, 'normalized': 'user@gmail.com', 'domain': 'gmail.com'}\n\nprint(is_valid_email_production(\"user@this-domain-does-not-exist-12345.com\")) \n# {'is_valid': False, 'error': 'The domain name this-domain-does-not-exist-12345.com does not exist.'}\n```\n\n### Which one should you use?\n* **Use Regex** if you are doing simple data cleaning, parsing text files, or building a quick script where you only care if the string \"looks\" like an email.\n* **Use `email-validator`** if you are building a web app, sending automated emails, or need to prevent users from signing up with fake or misspelled domains (like `user@gmial.com`)."
701
- },
702
- {
703
- "loc": 39,
704
- "correct": true,
705
- "timeSec": 60.016,
706
- "usage": {
707
- "inputTokens": 20,
708
- "outputTokens": 2710
709
- },
710
- "response": "When it comes to email validation in Python, there are two main approaches depending on your needs: a **quick Regex check** (using built-in libraries) and a **production-grade check** (using a third-party library that verifies domain existence).\n\nHere is a guide to both, along with the golden rule of email validation.\n\n---\n\n### Method 1: The Pragmatic Regex (Built-in)\nIf you just need a quick sanity check to ensure the user didn't type gibberish, use the `re` module. This regex covers 99% of standard email addresses while rejecting obvious typos.\n\n```python\nimport re\n\n# Pre-compile the regex for better performance if checking multiple emails\nEMAIL_REGEX = re.compile(\n r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-]{2,}$\"\n)\n\ndef is_valid_email_regex(email: str) -> bool:\n \"\"\"\n Validates an email address using a standard regular expression.\n \"\"\"\n if not isinstance(email, str):\n return False\n \n return bool(EMAIL_REGEX.match(email))\n\n# --- Tests ---\nprint(is_valid_email_regex(\"user@example.com\")) # True\nprint(is_valid_email_regex(\"first.last@domain.co.uk\"))# True\nprint(is_valid_email_regex(\"user+tag@gmail.com\")) # True\nprint(is_valid_email_regex(\"invalid-email@domain\")) # False (No TLD)\nprint(is_valid_email_regex(\"@missingusername.com\")) # False\n```\n\n**Pros:** No external dependencies, very fast.\n**Cons:** Doesn't check if the domain actually exists (e.g., `user@fake-domain-12345.com` will pass).\n\n---\n\n### Method 2: Production-Grade Validation (Recommended)\nFor real-world applications (like user registration), you should use the **`email-validator`** library. \n\nIt doesn't just check syntax; it checks if the domain exists and has valid **MX (Mail Exchange) DNS records**, meaning the domain is actually capable of receiving emails. It also normalizes the email (e.g., lowercasing the domain).\n\nFirst, install the library:\n```bash\npip install email-validator\n```\n\nThen, use this function:\n\n```python\nfrom email_validator import validate_email, EmailNotValidError\n\ndef is_valid_email_production(email: str) -> dict:\n \"\"\"\n Validates email syntax and checks if the domain has valid MX records.\n Returns a dict with status, normalized email, and error message.\n \"\"\"\n try:\n # Check that the email address is valid\n valid = validate_email(email, check_deliverability=True)\n \n return {\n \"is_valid\": True,\n \"normalized\": valid.normalized, # e.g., 'User@Gmail.com' -> 'User@gmail.com'\n \"error\": None\n }\n except EmailNotValidError as e:\n return {\n \"is_valid\": False,\n \"normalized\": None,\n \"error\": str(e)\n }\n\n# --- Tests ---\nprint(is_valid_email_production(\"user@gmail.com\")) \n# {'is_valid': True, 'normalized': 'user@gmail.com', 'error': None}\n\nprint(is_valid_email_production(\"user@this-domain-does-not-exist-12345.com\")) \n# {'is_valid': False, 'normalized': None, 'error': 'The domain part after the @ sign...'}\n\nprint(is_valid_email_production(\"user@.com\")) \n# {'is_valid': False, 'normalized': None, 'error': 'An email address must have...'}\n```\n\n**Pros:** Catches fake domains, handles internationalized domain names (IDNs), and normalizes formatting.\n**Cons:** Requires an external library and makes a network request (DNS lookup), which takes a few milliseconds.\n\n---\n\n### ⚠️ The Golden Rule of Email Validation\n**The only 100% accurate way to validate an email address is to send a confirmation link to it.** \n\nEven the best DNS checks cannot tell you if:\n1. The specific mailbox exists (e.g., `john.doe@gmail.com` vs `john.doe123@gmail.com`).\n2. The user's inbox is full.\n3. The user made a typo in their own name (e.g., `jon.doe@gmail.com` instead of `john.doe@gmail.com`).\n\n**Best Practice Architecture:**\n1. Use **Method 1 (Regex)** on the Frontend/Client-side for instant UI feedback.\n2. Use **Method 2 (Library)** on the Backend when the form is submitted to block fake domains.\n3. Send a **Verification Email** with a magic link or OTP to prove ownership of the inbox."
711
- },
712
- {
713
- "loc": 49,
714
- "correct": true,
715
- "timeSec": 58.608,
716
- "usage": {
717
- "inputTokens": 20,
718
- "outputTokens": 3123
719
- },
720
- "response": "When it comes to validating email addresses in Python, there are two main approaches depending on your needs:\n\n1. **The Quick Regex Method:** Best for simple scripts, basic form validation, and situations where you don't want to install third-party packages.\n2. **The Production-Grade Method:** Best for real-world applications where you need to handle international characters, verify domain existence, and prevent typos.\n\nHere are both solutions.\n\n---\n\n### Method 1: The Quick Regex Approach (No Dependencies)\nThis uses Python's built-in `re` module. It checks for standard email formatting (e.g., `user@domain.com`) without requiring external libraries.\n\n```python\nimport re\n\ndef is_valid_email_regex(email: str) -> bool:\n \"\"\"\n Validates an email address using a regular expression.\n Good for basic syntax checking.\n \"\"\"\n # Regex breakdown:\n # ^[a-zA-Z0-9_.+-]+ : Local part (allows letters, numbers, dots, underscores, pluses, hyphens)\n # @ : The @ symbol\n # [a-zA-Z0-9-]+ : Domain name\n # (\\.[a-zA-Z0-9-]+)*: Optional subdomains\n # \\.[a-zA-Z]{2,}$ : Top-level domain (e.g., .com, .org, .co.uk) must be at least 2 letters\n pattern = r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z]{2,}$\"\n \n if re.match(pattern, email):\n return True\n return False\n\n# --- Test Cases ---\nif __name__ == \"__main__\":\n emails_to_test = [\n \"user@example.com\", # Valid\n \"firstname.lastname@domain.co.uk\", # Valid\n \"user+tag@sub.domain.org\", # Valid\n \"invalid-email\", # Invalid (no @)\n \"user@domain\", # Invalid (no TLD like .com)\n \"@missingusername.com\", # Invalid\n \"user@.com\" # Invalid\n ]\n\n for email in emails_to_test:\n print(f\"{email:<35} -> {is_valid_email_regex(email)}\")\n```\n\n---\n\n### Method 2: The Production-Grade Approach (Recommended)\nRegular expressions cannot check if a domain actually exists, nor do they handle Internationalized Domain Names (IDNs) well. For production apps, use the industry-standard **`email-validator`** library.\n\nFirst, install the library:\n```bash\npip install email-validator\n```\n\nThen, use this function:\n\n```python\nfrom email_validator import validate_email, EmailNotValidError\n\ndef is_valid_email_production(email: str, check_deliverability: bool = True) -> tuple[bool, str]:\n \"\"\"\n Validates an email address using the email-validator library.\n \n Args:\n email: The email string to validate.\n check_deliverability: If True, performs DNS checks to ensure the domain can receive mail.\n (Set to False for unit testing or offline environments).\n \n Returns:\n A tuple of (is_valid: bool, normalized_email_or_error: str)\n \"\"\"\n try:\n # Validate and normalize the email\n valid = validate_email(email, check_deliverability=check_deliverability)\n \n # Return True and the normalized email (e.g., lowercased, IDN encoded)\n return True, valid.normalized\n \n except EmailNotValidError as e:\n # Return False and the human-readable error message\n return False, str(e)\n\n# --- Test Cases ---\nif __name__ == \"__main__\":\n test_emails = [\n \"User@Example.COM\", # Valid (will be normalized to lowercase)\n \"test@nonexistent-domain-12345.com\", # Invalid (Domain doesn't exist / no MX records)\n \"user@domain.c\", # Invalid (TLD too short/invalid)\n ]\n\n for email in test_emails:\n is_valid, result = is_valid_email_production(email)\n status = f\"VALID ({result})\" if is_valid else f\"INVALID ({result})\"\n print(f\"{email:<35} -> {status}\")\n```\n\n### Why Method 2 is better for Production:\n1. **Normalization:** It converts `User@Example.COM` to `user@example.com`, preventing duplicate accounts in your database.\n2. **Deliverability Checks:** It checks DNS MX records to ensure the domain (like `gmail.com` or `company.com`) is actually set up to receive emails.\n3. **Internationalization:** It properly handles non-ASCII characters in both the local part and the domain name.\n4. **Better Error Messages:** It tells you *why* an email failed (e.g., \"The domain name does not exist\"), which is great for user-facing error alerts.\n\n### 💡 The Golden Rule of Email Validation\nNo code can verify if an email address belongs to the person typing it, or if the inbox isn't full. **The only 100% foolproof way to validate an email address is to send a confirmation link to it.** Use the code above to filter out typos and bad formatting, but always rely on a verification email for actual account creation."
721
- }
722
- ],
723
- "debounce": [
724
- {
725
- "loc": 49,
726
- "correct": true,
727
- "timeSec": 38.113,
728
- "usage": {
729
- "inputTokens": 31,
730
- "outputTokens": 2017
731
- },
732
- "response": "Here is how to implement a debounce function in vanilla JavaScript and apply it to your search input. \n\n### 1. The Debounce Utility Function\nA debounce function works by resetting a timer every time it is called. The target function only executes once the timer completes without being interrupted by a new keystroke.\n\n```javascript\nfunction debounce(func, delay) {\n let timeoutId;\n \n return function (...args) {\n // Clear the previous timer on every new keystroke\n clearTimeout(timeoutId);\n \n // Set a new timer\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n```\n\n### 2. Implementation\nHere is how you wire it up to your HTML input and your API call.\n\n```html\n<input type=\"text\" id=\"search-input\" placeholder=\"Search...\" autocomplete=\"off\" />\n```\n\n```javascript\nconst searchInput = document.getElementById('search-input');\n\n// 1. Create your API call function\nasync function fetchSearchResults(query) {\n if (!query.trim()) {\n console.log(\"Clearing results...\");\n return;\n }\n\n console.log(`Fetching API results for: \"${query}\"`);\n \n try {\n // Replace with your actual API endpoint\n // const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);\n // const data = await response.json();\n // renderResults(data);\n } catch (error) {\n console.error(\"Search failed:\", error);\n }\n}\n\n// 2. Wrap your API call in the debounce function (e.g., 500ms delay)\nconst debouncedSearch = debounce(fetchSearchResults, 500);\n\n// 3. Attach the debounced function to the 'input' event\nsearchInput.addEventListener('input', (event) => {\n debouncedSearch(event.target.value);\n});\n```\n\n---\n\n### 💡 Pro-Tip: Preventing Race Conditions\nWhen dealing with search inputs, **debouncing alone isn't always enough**. If a user types \"A\" (triggers request 1), pauses, and then types \"AB\" (triggers request 2), Request 1 might take longer to resolve and overwrite the correct \"AB\" results on the screen.\n\nYou can fix this by combining your debounce with an **`AbortController`** to cancel outdated API requests:\n\n```javascript\nlet currentController = null;\n\nasync function fetchSearchResults(query) {\n if (!query.trim()) return;\n\n // Cancel the previous pending request if it exists\n if (currentController) {\n currentController.abort();\n }\n\n // Create a new controller for the current request\n currentController = new AbortController();\n\n try {\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {\n signal: currentController.signal // Pass the signal to fetch\n });\n \n const data = await response.json();\n console.log(\"Rendering:\", data);\n \n } catch (error) {\n if (error.name === 'AbortError') {\n console.log('Request canceled because a new keystroke occurred.');\n } else {\n console.error(\"Actual API error:\", error);\n }\n }\n}\n\nconst debouncedSearch = debounce(fetchSearchResults, 500);\ndocument.getElementById('search-input').addEventListener('input', (e) => debouncedSearch(e.target.value));\n```"
733
- },
734
- {
735
- "loc": 39,
736
- "correct": false,
737
- "timeSec": 28.222,
738
- "usage": {
739
- "inputTokens": 31,
740
- "outputTokens": 1461
741
- },
742
- "response": "Here is the complete vanilla JavaScript solution. \n\nTo fix this, we need to create a **debounce function**. A debounce function acts as a wrapper: it delays the execution of your API call until the user has stopped typing for a specified amount of time (e.g., 300 milliseconds).\n\n### The Solution\n\n```javascript\n// 1. Create a reusable debounce utility function\nfunction debounce(func, delay) {\n let timeoutId;\n \n return function (...args) {\n // Clear the previous timer every time the function is called\n clearTimeout(timeoutId);\n \n // Set a new timer\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n\n// 2. Define your API call\nfunction fetchSearchResults(query) {\n if (!query) {\n console.log(\"Clearing results...\");\n return;\n }\n \n console.log(`API CALL: Fetching results for \"${query}\"`);\n // fetch(`/api/search?q=${query}`)\n // .then(response => response.json())\n // .then(data => renderResults(data));\n}\n\n// 3. Wrap your API call in the debounce function (300ms delay)\nconst debouncedSearch = debounce(fetchSearchResults, 300);\n\n// 4. Attach it to the input event\nconst searchInput = document.getElementById('search-input');\n\nsearchInput.addEventListener('input', (event) => {\n debouncedSearch(event.target.value);\n});\n```\n\n### HTML Context\n```html\n<input type=\"text\" id=\"search-input\" placeholder=\"Search...\" autocomplete=\"off\" />\n```\n\n---\n\n### How it works:\n1. **The Closure (`timeoutId`)**: When `debounce` is called, it creates a private variable `timeoutId`. Because the returned inner function has access to this variable (closure), it can remember the timer across multiple keystrokes.\n2. **`clearTimeout`**: Every time the user presses a key, the `input` event fires. The inner function immediately cancels the *previous* pending timer.\n3. **`setTimeout`**: It then starts a *new* timer. If the user doesn't press another key before the `delay` (300ms) runs out, the timer finishes and finally executes `fetchSearchResults`.\n\n---\n\n### 💡 Pro-Tip: Preventing Race Conditions\nDebouncing stops you from *sending* too many requests, but it doesn't prevent **race conditions** (e.g., Request A takes 2 seconds, Request B takes 500ms. Request B finishes first, but Request A overwrites it later). \n\nIf you are using the modern `fetch` API, you should pair your debounce with an `AbortController`:\n\n```javascript\nlet currentController = null;\n\nfunction fetchSearchResults(query) {\n // Cancel the previous request if it's still pending\n if (currentController) {\n currentController.abort();\n }\n \n currentController = new AbortController();\n \n fetch(`/api/search?q=${query}`, { signal: currentController.signal })\n .then(res => res.json())\n .then(data => {\n console.log(\"Rendering data:\", data);\n })\n .catch(err => {\n if (err.name !== 'AbortError') {\n console.error(\"Actual error:\", err);\n }\n });\n}\n```"
743
- },
744
- {
745
- "loc": 48,
746
- "correct": false,
747
- "timeSec": 32.691,
748
- "usage": {
749
- "inputTokens": 31,
750
- "outputTokens": 1683
751
- },
752
- "response": "Here is the complete vanilla JavaScript solution. \n\nTo fix this, you need a **debounce utility function**. Debouncing ensures that your API call only fires after the user has *stopped* typing for a specified amount of time (e.g., 300 milliseconds).\n\n### 1. The HTML\n```html\n<input type=\"text\" id=\"search-input\" placeholder=\"Search...\" />\n<ul id=\"results\"></ul>\n```\n\n### 2. The JavaScript\n```javascript\n// 1. Create the Debounce Utility Function\nfunction debounce(func, delay) {\n let timeoutId;\n \n return function (...args) {\n // Clear the previous timeout every time the function is called\n clearTimeout(timeoutId);\n \n // Set a new timeout\n timeoutId = setTimeout(() => {\n func.apply(this, args);\n }, delay);\n };\n}\n\n// 2. Define your API call function\nfunction fetchSearchResults(query) {\n // Ignore empty queries\n if (!query.trim()) {\n console.log(\"Clearing results...\");\n return;\n }\n\n console.log(`Fetching API results for: \"${query}\"`);\n \n // Example API Call:\n // fetch(`/api/search?q=${encodeURIComponent(query)}`)\n // .then(res => res.json())\n // .then(data => renderResults(data));\n}\n\n// 3. Create a debounced version of your API call (300ms delay)\nconst debouncedSearch = debounce(fetchSearchResults, 300);\n\n// 4. Attach the debounced function to the input event\nconst searchInput = document.getElementById('search-input');\n\nsearchInput.addEventListener('input', (event) => {\n debouncedSearch(event.target.value);\n});\n```\n\n### How it works:\n1. **The Closure:** The `debounce` function returns a new function that \"remembers\" the `timeoutId` variable even after `debounce` has finished executing.\n2. **`clearTimeout`:** Every time the user presses a key, the `input` event fires. The returned function immediately cancels the previous pending timer.\n3. **`setTimeout`:** It then sets a *new* timer for 300ms. \n4. **Execution:** The API call (`func.apply`) only actually runs if 300ms passes *without* the user pressing another key.\n\n---\n\n### 💡 Pro-Tip: Preventing Race Conditions\nDebouncing stops the API from being *called* too many times, but it doesn't cancel requests that are already in flight. If the user types \"App\" (triggers request), waits 300ms, and then types \"Apple\" (triggers second request), the \"App\" request might resolve *after* the \"Apple\" request, showing the wrong results.\n\nYou can fix this using the native **`AbortController`**:\n\n```javascript\nlet currentController = null;\n\nasync function fetchSearchResults(query) {\n if (!query.trim()) return;\n\n // Cancel the previous in-flight request if it exists\n if (currentController) {\n currentController.abort();\n }\n\n // Create a new controller for this request\n currentController = new AbortController();\n\n try {\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {\n signal: currentController.signal // Pass the signal to fetch\n });\n \n const data = await response.json();\n console.log(\"Rendering:\", data);\n \n } catch (error) {\n if (error.name === 'AbortError') {\n console.log('Previous request was canceled.');\n } else {\n console.error('Actual error:', error);\n }\n }\n}\n\n// The rest of the debounce setup remains exactly the same\nconst debouncedSearch = debounce(fetchSearchResults, 300);\ndocument.getElementById('search-input').addEventListener('input', (e) => {\n debouncedSearch(e.target.value);\n});\n```"
753
- }
754
- ],
755
- "csv-sum": [
756
- {
757
- "loc": 19,
758
- "correct": true,
759
- "timeSec": 28.186,
760
- "usage": {
761
- "inputTokens": 25,
762
- "outputTokens": 1449
763
- },
764
- "response": "Here are two ways to do this in Python. \n\n### Method 1: Using `pandas` (Recommended)\nIf you are doing data analysis, `pandas` is the standard and most efficient tool. It automatically handles missing values (NaNs) when summing.\n\n*Note: You may need to install pandas first using `pip install pandas`.*\n\n```python\nimport pandas as pd\n\n# Read the CSV file into a DataFrame\ndf = pd.read_csv('sales.csv')\n\n# Sum the 'amount' column\ntotal_amount = df['amount'].sum()\n\nprint(f\"Total sales amount: {total_amount}\")\n```\n\n### Method 2: Using the built-in `csv` module\nIf you don't want to install any external libraries, you can use Python's built-in `csv` module. This method includes a `try-except` block to safely skip rows where the amount might be missing or formatted incorrectly.\n\n```python\nimport csv\n\ntotal_amount = 0.0\n\ntry:\n with open('sales.csv', mode='r', encoding='utf-8') as file:\n reader = csv.DictReader(file)\n \n for row in reader:\n try:\n # Convert the value to a float and add it to the total\n total_amount += float(row['amount'])\n except (ValueError, KeyError):\n # Skips rows where 'amount' is missing, empty, or not a number\n continue\n \n print(f\"Total sales amount: {total_amount}\")\n\nexcept FileNotFoundError:\n print(\"Error: The file 'sales.csv' was not found.\")\n```\n\n### 💡 Tip for messy data (Pandas)\nIf your CSV has messy data (like currency symbols e.g., `$100.00` or text like `N/A`), you can clean it on the fly with pandas before summing:\n\n```python\n# Remove '$' and ',' characters, coerce errors to NaN, then sum\ndf['amount'] = pd.to_numeric(df['amount'].replace({'\\$': '', ',': ''}, regex=True), errors='coerce')\ntotal_amount = df['amount'].sum()\n```"
765
- },
766
- {
767
- "loc": 23,
768
- "correct": true,
769
- "timeSec": 26.66,
770
- "usage": {
771
- "inputTokens": 25,
772
- "outputTokens": 1390
773
- },
774
- "response": "Here are two ways to do this in Python. \n\n### Method 1: Using `pandas` (Recommended)\n`pandas` is the standard library for data manipulation in Python. It is the easiest and most efficient method, especially for larger datasets.\n\n*Note: You may need to install it first using `pip install pandas`.*\n\n```python\nimport pandas as pd\n\ntry:\n # Read the CSV file into a DataFrame\n df = pd.read_csv('sales.csv')\n \n # Sum the 'amount' column\n total_amount = df['amount'].sum()\n \n print(f\"Total Sales Amount: {total_amount}\")\n\nexcept FileNotFoundError:\n print(\"Error: 'sales.csv' not found. Please check the file path.\")\nexcept KeyError:\n print(\"Error: The column 'amount' was not found in the CSV file.\")\n```\n\n### Method 2: Using the built-in `csv` module\nIf you don't want to install any external libraries, you can use Python's built-in `csv` module.\n\n```python\nimport csv\n\ntotal_amount = 0.0\n\ntry:\n with open('sales.csv', mode='r', encoding='utf-8') as file:\n reader = csv.DictReader(file)\n \n for row in reader:\n # Convert the string value to a float and add it to the total\n total_amount += float(row['amount'])\n \n print(f\"Total Sales Amount: {total_amount}\")\n\nexcept FileNotFoundError:\n print(\"Error: 'sales.csv' not found. Please check the file path.\")\nexcept KeyError:\n print(\"Error: The column 'amount' was not found in the CSV file.\")\nexcept ValueError:\n print(\"Error: Found non-numeric data in the 'amount' column.\")\n```\n\n### 💡 Quick Tips:\n* **File Path**: Ensure `sales.csv` is in the same directory as your Python script, or provide the full/relative path (e.g., `'data/sales.csv'`).\n* **Missing Values**: If your CSV has empty rows in the `amount` column, the `pandas` method will automatically ignore them (`NaN` values). If you use the `csv` module method, you might need to add a check like `if row['amount']:` before converting to a `float` to avoid `ValueError`s."
775
- },
776
- {
777
- "loc": 11,
778
- "correct": true,
779
- "timeSec": 19.924,
780
- "usage": {
781
- "inputTokens": 25,
782
- "outputTokens": 953
783
- },
784
- "response": "Here are two ways to do this in Python. \n\n### Method 1: Using `pandas` (Recommended)\nThis is the most common and concise method if you are doing data analysis. You will need to install pandas first (`pip install pandas`) if you haven't already.\n\n```python\nimport pandas as pd\n\n# Read the CSV file into a DataFrame\ndf = pd.read_csv('sales.csv')\n\n# Calculate the sum of the 'amount' column\ntotal_amount = df['amount'].sum()\n\nprint(f\"Total Sales Amount: {total_amount}\")\n```\n\n### Method 2: Using the built-in `csv` module\nUse this method if you don't want to install any external third-party libraries.\n\n```python\nimport csv\n\ntotal_amount = 0.0\n\n# Open and read the CSV file\nwith open('sales.csv', mode='r', encoding='utf-8') as file:\n reader = csv.DictReader(file)\n \n # Iterate through each row and add the amount to the total\n for row in reader:\n total_amount += float(row['amount'])\n\nprint(f\"Total Sales Amount: {total_amount}\")\n```\n\n### 💡 Tips:\n* **Missing Values:** If your CSV has empty/missing values in the `amount` column, the `pandas` method will handle them automatically (ignoring `NaN` values). If you use the `csv` module, you might need to add a check like `if row['amount']:` before converting to `float()` to avoid errors.\n* **Currency Symbols:** If your `amount` column contains currency symbols (like `$100.00`), you will need to clean the strings before summing them. In pandas, you can do this with: `df['amount'].replace('[$,]', '', regex=True).astype(float).sum()`"
785
- }
786
- ],
787
- "countdown": [
788
- {
789
- "loc": 272,
790
- "correct": true,
791
- "timeSec": 52.281,
792
- "usage": {
793
- "inputTokens": 28,
794
- "outputTokens": 2826
795
- },
796
- "response": "# React Countdown Timer Component\n\nHere's a fully-featured, styled countdown timer component with start/pause/reset controls and a circular progress ring.\n\n## `CountdownTimer.jsx`\n\n```jsx\nimport React, { useState, useEffect, useCallback, useRef } from \"react\";\n\nconst CountdownTimer = ({\n initialSeconds = 60,\n onComplete = () => {},\n size = 200,\n strokeWidth = 8,\n autoStart = false,\n}) => {\n const [timeLeft, setTimeLeft] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(autoStart);\n const [isComplete, setIsComplete] = useState(false);\n const intervalRef = useRef(null);\n\n // --- Core timer logic ---\n useEffect(() => {\n if (isRunning && timeLeft > 0) {\n intervalRef.current = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n clearInterval(intervalRef.current);\n setIsRunning(false);\n setIsComplete(true);\n onComplete();\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }\n\n return () => clearInterval(intervalRef.current);\n }, [isRunning, timeLeft > 0, onComplete]);\n\n // --- Controls ---\n const start = () => {\n if (timeLeft > 0 && !isComplete) {\n setIsRunning(true);\n }\n };\n\n const pause = () => {\n setIsRunning(false);\n };\n\n const reset = () => {\n clearInterval(intervalRef.current);\n setTimeLeft(initialSeconds);\n setIsRunning(false);\n setIsComplete(false);\n };\n\n // --- Formatting ---\n const formatTime = (totalSeconds) => {\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) {\n return `${String(hours).padStart(2, \"0\")}:${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}`;\n }\n return `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}`;\n };\n\n // --- Circular progress math ---\n const radius = (size - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n const progress = timeLeft / initialSeconds;\n const strokeDashoffset = circumference * (1 - progress);\n\n // --- Dynamic color based on remaining time ---\n const getColor = () => {\n if (isComplete) return \"#ef4444\";\n if (progress <= 0.1) return \"#ef4444\"; // red\n if (progress <= 0.25) return \"#f97316\"; // orange\n if (progress <= 0.5) return \"#eab308\"; // yellow\n return \"#3b82f6\"; // blue\n };\n\n const color = getColor();\n\n return (\n <div style={styles.container}>\n {/* SVG Ring */}\n <div style={{ position: \"relative\", width: size, height: size }}>\n <svg\n width={size}\n height={size}\n style={{ transform: \"rotate(-90deg)\" }}\n >\n {/* Background circle */}\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"#1e293b\"\n strokeWidth={strokeWidth}\n />\n {/* Progress circle */}\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke={color}\n strokeWidth={strokeWidth}\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n strokeLinecap=\"round\"\n style={{\n transition: \"stroke-dashoffset 0.5s ease, stroke 0.5s ease\",\n }}\n />\n </svg>\n\n {/* Time display overlaid on the ring */}\n <div style={styles.timeOverlay}>\n <span\n style={{\n ...styles.timeText,\n fontSize: size * 0.2,\n color: isComplete ? \"#ef4444\" : \"#f8fafc\",\n }}\n >\n {formatTime(timeLeft)}\n </span>\n <span style={styles.label}>\n {isComplete\n ? \"Time's up!\"\n : isRunning\n ? \"Running\"\n : timeLeft < initialSeconds\n ? \"Paused\"\n : \"Ready\"}\n </span>\n </div>\n </div>\n\n {/* Controls */}\n <div style={styles.controls}>\n {!isRunning && !isComplete && (\n <button\n onClick={start}\n style={{ ...styles.button, ...styles.startButton }}\n onMouseEnter={(e) =>\n (e.currentTarget.style.transform = \"scale(1.05)\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.transform = \"scale(1)\")\n }\n >\n ▶ Start\n </button>\n )}\n\n {isRunning && (\n <button\n onClick={pause}\n style={{ ...styles.button, ...styles.pauseButton }}\n onMouseEnter={(e) =>\n (e.currentTarget.style.transform = \"scale(1.05)\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.transform = \"scale(1)\")\n }\n >\n ⏸ Pause\n </button>\n )}\n\n <button\n onClick={reset}\n style={{ ...styles.button, ...styles.resetButton }}\n onMouseEnter={(e) =>\n (e.currentTarget.style.transform = \"scale(1.05)\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.transform = \"scale(1)\")\n }\n >\n ↺ Reset\n </button>\n </div>\n </div>\n );\n};\n\n// --- Styles ---\nconst styles = {\n container: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"24px\",\n padding: \"40px\",\n borderRadius: \"20px\",\n background: \"linear-gradient(145deg, #0f172a, #1e293b)\",\n boxShadow: \"0 25px 50px rgba(0, 0, 0, 0.4)\",\n fontFamily:\n \"'SF Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace\",\n },\n timeOverlay: {\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"4px\",\n },\n timeText: {\n fontWeight: \"700\",\n letterSpacing: \"2px\",\n lineHeight: 1,\n },\n label: {\n fontSize: \"12px\",\n color: \"#94a3b8\",\n textTransform: \"uppercase\",\n letterSpacing: \"2px\",\n fontWeight: \"500\",\n },\n controls: {\n display: \"flex\",\n gap: \"12px\",\n },\n button: {\n padding: \"12px 28px\",\n fontSize: \"14px\",\n fontWeight: \"600\",\n border: \"none\",\n borderRadius: \"10px\",\n cursor: \"pointer\",\n letterSpacing: \"0.5px\",\n transition: \"all 0.2s ease\",\n color: \"#ffffff\",\n },\n startButton: {\n background: \"linear-gradient(135deg, #3b82f6, #2563eb)\",\n boxShadow: \"0 4px 15px rgba(59, 130, 246, 0.4)\",\n },\n pauseButton: {\n background: \"linear-gradient(135deg, #f97316, #ea580c)\",\n boxShadow: \"0 4px 15px rgba(249, 115, 22, 0.4)\",\n },\n resetButton: {\n background: \"linear-gradient(135deg, #475569, #334155)\",\n boxShadow: \"0 4px 15px rgba(71, 85, 105, 0.3)\",\n },\n};\n\nexport default CountdownTimer;\n```\n\n## Usage in `App.jsx`\n\n```jsx\nimport React from \"react\";\nimport CountdownTimer from \"./CountdownTimer\";\n\nexport default function App() {\n const handleComplete = () => {\n alert(\"⏰ Timer finished!\");\n };\n\n return (\n <div\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"48px\",\n background: \"#0f172a\",\n }}\n >\n <h1 style={{ color: \"#f8fafc\", fontFamily: \"sans-serif\" }}>\n Countdown Timer\n </h1>\n\n {/* Basic 60-second timer */}\n <CountdownTimer initialSeconds={60} onComplete={handleComplete} />\n\n {/* Larger 5-minute timer */}\n <CountdownTimer\n initialSeconds={300}\n size={250}\n strokeWidth={10}\n onComplete={() => console.log(\"5 min done!\")}\n />\n\n {/* Auto-starting 10-second timer */}\n <CountdownTimer\n initialSeconds={10}\n autoStart={true}\n size={150}\n strokeWidth={6}\n />\n </div>\n );\n}\n```\n\n## Features\n\n| Feature | Details |\n|---|---|\n| **Circular progress ring** | SVG-based ring that depletes as time runs out |\n| **Color transitions** | Blue → Yellow → Orange → Red as time gets low |\n| **Smart formatting** | Shows `MM:SS` or `HH:MM:SS` depending on duration |\n| **Controls** | Start, Pause, and Reset buttons |\n| **Status label** | Shows Ready / Running / Paused / Time's up |\n| **Completion callback** | `onComplete` fires when the timer hits zero |\n| **Auto-start option** | Pass `autoStart={true}` to begin immediately |\n| **Configurable size** | `size` and `strokeWidth` props control dimensions |\n| **Proper cleanup** | `clearInterval` on unmount to prevent memory leaks |\n\n> **Tip:** To add sound on completion, pass a function to `onComplete` that plays an audio file using the Web Audio API or an `<audio>` element."
797
- },
798
- {
799
- "loc": 124,
800
- "correct": true,
801
- "timeSec": 66.045,
802
- "usage": {
803
- "inputTokens": 28,
804
- "outputTokens": 3580
805
- },
806
- "response": "Here is a complete, production-ready Countdown Timer component in React. \n\nIt includes **Start/Pause** and **Reset** controls, formats the time into `MM:SS`, prevents memory leaks by properly cleaning up intervals, and accepts an optional `onComplete` callback.\n\n### The Component (`CountdownTimer.jsx`)\n\n```jsx\nimport React, { useState, useEffect, useRef } from 'react';\n\nconst CountdownTimer = ({ initialSeconds, onComplete }) => {\n const [timeLeft, setTimeLeft] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(false);\n const prevTimeLeft = useRef(initialSeconds);\n\n // Sync with prop changes and reset timer\n useEffect(() => {\n setTimeLeft(initialSeconds);\n setIsRunning(false);\n prevTimeLeft.current = initialSeconds;\n }, [initialSeconds]);\n\n // Handle the countdown interval\n useEffect(() => {\n if (!isRunning) return;\n\n const intervalId = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n setIsRunning(false);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n // Cleanup interval on unmount or when isRunning changes\n return () => clearInterval(intervalId);\n }, [isRunning]);\n\n // Trigger onComplete callback when timer hits 0\n useEffect(() => {\n if (prevTimeLeft.current > 0 && timeLeft === 0 && onComplete) {\n onComplete();\n }\n prevTimeLeft.current = timeLeft;\n }, [timeLeft, onComplete]);\n\n // Helper to format seconds into MM:SS\n const formatTime = (seconds) => {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n };\n\n const handleStartPause = () => {\n if (timeLeft > 0) {\n setIsRunning(!isRunning);\n }\n };\n\n const handleReset = () => {\n setIsRunning(false);\n setTimeLeft(initialSeconds);\n };\n\n return (\n <div style={styles.container}>\n <div style={styles.timerDisplay}>\n {formatTime(timeLeft)}\n </div>\n \n <div style={styles.controls}>\n <button \n onClick={handleStartPause} \n style={styles.button}\n disabled={timeLeft === 0}\n >\n {isRunning ? 'Pause' : timeLeft === initialSeconds ? 'Start' : 'Resume'}\n </button>\n \n <button \n onClick={handleReset} \n style={{...styles.button, ...styles.resetButton}}\n >\n Reset\n </button>\n </div>\n </div>\n );\n};\n\n// Basic inline styles for a clean look\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n padding: '2rem',\n borderRadius: '12px',\n backgroundColor: '#f8f9fa',\n boxShadow: '0 4px 6px rgba(0,0,0,0.1)',\n width: '250px'\n },\n timerDisplay: {\n fontSize: '3.5rem',\n fontWeight: 'bold',\n fontVariantNumeric: 'tabular-nums', // Keeps numbers from jumping around\n color: '#212529',\n marginBottom: '1.5rem'\n },\n controls: {\n display: 'flex',\n gap: '10px',\n width: '100%'\n },\n button: {\n flex: 1,\n padding: '0.75rem 1rem',\n fontSize: '1rem',\n fontWeight: '600',\n border: 'none',\n borderRadius: '8px',\n cursor: 'pointer',\n backgroundColor: '#0d6efd',\n color: 'white',\n transition: 'opacity 0.2s',\n },\n resetButton: {\n backgroundColor: '#6c757d',\n }\n};\n\nexport default CountdownTimer;\n```\n\n### How to use it (`App.jsx`)\n\n```jsx\nimport React from 'react';\nimport CountdownTimer from './CountdownTimer';\n\nfunction App() {\n const handleTimerComplete = () => {\n alert('Time is up! ⏰');\n };\n\n return (\n <div style={{ display: 'flex', justifyContent: 'center', marginTop: '50px' }}>\n {/* Example: 5 minutes (300 seconds) */}\n <CountdownTimer \n initialSeconds={300} \n onComplete={handleTimerComplete} \n />\n </div>\n );\n}\n\nexport default App;\n```\n\n### Key Design Decisions & Best Practices Used:\n1. **Functional State Updates (`prev => ...`)**: Inside the `setInterval`, we use `setTimeLeft((prev) => prev - 1)`. This prevents \"stale closure\" bugs where the interval might reference an outdated version of the state.\n2. **Minimal Dependencies**: The interval `useEffect` only depends on `[isRunning]`. Because of the functional state update, we don't need to put `timeLeft` in the dependency array, which prevents the interval from being destroyed and recreated every single second (improving performance and preventing drift).\n3. **`fontVariantNumeric: 'tabular-nums'`**: This CSS property ensures that the numbers are monospaced. Without it, the colon and numbers will visually \"jump\" left and right as the width of the numbers change (e.g., from `1` to `0`).\n4. **Safe `onComplete` Trigger**: We use a `useRef` to track the previous time. This ensures the completion callback doesn't accidentally fire on the very first render if the component is initialized with `0` seconds.\n5. **Cleanup Function**: `return () => clearInterval(intervalId)` guarantees that if the component unmounts or the timer is paused, the interval is completely wiped from memory."
807
- },
808
- {
809
- "loc": 117,
810
- "correct": false,
811
- "timeSec": 33.536,
812
- "usage": {
813
- "inputTokens": 28,
814
- "outputTokens": 1783
815
- },
816
- "response": "# React Countdown Timer Component\n\nHere's a clean, drift-resistant countdown timer using React hooks. It stores a target end time (rather than just decrementing) so the countdown stays accurate even if the browser throttles the tab.\n\n## `CountdownTimer.jsx`\n\n```jsx\nimport { useState, useEffect, useRef, useCallback } from \"react\";\n\n/**\n * CountdownTimer\n *\n * Props:\n * initialSeconds : number — starting value (required)\n * onComplete : () => void — called when the timer reaches 0\n * autoStart : boolean — start immediately (default: true)\n */\nexport default function CountdownTimer({\n initialSeconds,\n onComplete,\n autoStart = true,\n}) {\n const [remaining, setRemaining] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(autoStart);\n\n // Refs keep values stable across intervals without re-subscribing.\n const endTimeRef = useRef(null);\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n\n const stop = useCallback(() => {\n setIsRunning(false);\n endTimeRef.current = null;\n }, []);\n\n const start = useCallback(() => {\n if (remaining <= 0) return;\n endTimeRef.current = Date.now() + remaining * 1000;\n setIsRunning(true);\n }, [remaining]);\n\n const reset = useCallback(() => {\n setRemaining(initialSeconds);\n endTimeRef.current = null;\n setIsRunning(autoStart);\n if (autoStart) {\n endTimeRef.current = Date.now() + initialSeconds * 1000;\n }\n }, [initialSeconds, autoStart]);\n\n // Main tick loop\n useEffect(() => {\n if (!isRunning) return;\n\n // If we just started and have no end time yet, anchor it now.\n if (!endTimeRef.current) {\n endTimeRef.current = Date.now() + remaining * 1000;\n }\n\n const id = setInterval(() => {\n const msLeft = endTimeRef.current - Date.now();\n if (msLeft <= 0) {\n setRemaining(0);\n setIsRunning(false);\n endTimeRef.current = null;\n onCompleteRef.current?.();\n } else {\n setRemaining(Math.ceil(msLeft / 1000));\n }\n }, 250); // 4x/sec for smooth updates without heavy CPU use\n\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isRunning]);\n\n // Handle changes to initialSeconds prop\n useEffect(() => {\n reset();\n }, [initialSeconds]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const minutes = Math.floor(remaining / 60);\n const seconds = remaining % 60;\n const display = `${String(minutes).padStart(2, \"0\")}:${String(seconds).padStart(2, \"0\")}`;\n\n return (\n <div style={styles.container}>\n <div style={styles.time}>{display}</div>\n <div style={styles.controls}>\n {!isRunning && remaining > 0 && (\n <button style={styles.button} onClick={start}>\n Start\n </button>\n )}\n {isRunning && (\n <button style={styles.button} onClick={stop}>\n Pause\n </button>\n )}\n <button style={styles.button} onClick={reset}>\n Reset\n </button>\n </div>\n </div>\n );\n}\n\nconst styles = {\n container: {\n display: \"inline-flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n padding: \"1.5rem 2rem\",\n borderRadius: \"12px\",\n background: \"#0f172a\",\n color: \"#f8fafc\",\n fontFamily: \"system-ui, sans-serif\",\n },\n time: {\n fontSize: \"3rem\",\n fontWeight: 600,\n fontVariantNumeric: \"tabular-nums\",\n letterSpacing: \"0.05em\",\n },\n controls: {\n display: \"flex\",\n gap: \"0.5rem\",\n marginTop: \"1rem\",\n },\n button: {\n padding: \"0.5rem 1rem\",\n border: \"none\",\n borderRadius: \"6px\",\n background: \"#3b82f6\",\n color: \"white\",\n cursor: \"pointer\",\n fontSize: \"0.9rem\",\n },\n};\n```\n\n## Usage\n\n```jsx\nimport CountdownTimer from \"./CountdownTimer\";\n\nexport default function App() {\n return (\n <div style={{ padding: \"2rem\" }}>\n <h2>Tea brewing…</h2>\n <CountdownTimer\n initialSeconds={180}\n onComplete={() => alert(\"Time's up! ☕\")}\n />\n </div>\n );\n}\n```\n\n## How it works\n\n- **Drift resistance** — Instead of `remaining -= 1` each second, the component computes `endTime = Date.now() + remaining * 1000` once when started, then derives the displayed value from `endTime - Date.now()`. Even if the tab is backgrounded or a tick is delayed, the display snaps to the correct value on the next tick.\n- **Stable callbacks** — `onComplete` is stored in a ref so you can pass a new function each render without resetting the timer.\n- **Cleanup** — `useEffect` returns a cleanup that clears the interval on pause or unmount, preventing memory leaks.\n- **Prop changes** — Changing `initialSeconds` automatically resets the timer.\n\n## Possible extensions\n\n- Add a `format` prop (`\"ms\" | \"s\" | \"hms\"`) to show milliseconds or hours.\n- Accept an `onChange` callback to react to each tick.\n- Use `useImperativeHandle` + `forwardRef` to expose `start()`/`pause()`/`reset()` to parent components.\n- Add a circular progress ring using an SVG `stroke-dashoffset` driven by `remaining / initialSeconds`."
817
- }
818
- ],
819
- "rate-limit": [
820
- {
821
- "loc": 37,
822
- "correct": true,
823
- "timeSec": 44.606,
824
- "usage": {
825
- "inputTokens": 25,
826
- "outputTokens": 2327
827
- },
828
- "response": "Implementing rate limiting is an essential defensive measure to protect your API from abuse, brute-force attacks, and Denial of Service (DoS) attempts. \n\nIn FastAPI, you can implement rate limiting at the **Application Level** (using Python libraries) or at the **Infrastructure Level** (using reverse proxies or API gateways). \n\nHere is a guide on how to implement both, starting with the most common application-level approach.\n\n### Method 1: Application-Level Rate Limiting (using `slowapi`)\nThe most popular library for adding rate limiting directly to FastAPI routes is `slowapi`, which is built on top of the `limits` library.\n\n**1. Install the dependencies:**\n```bash\npip install fastapi slowapi uvicorn\n```\n*(Note: For production with multiple workers, you will also need Redis: `pip install redis`)*\n\n**2. Implement the Limiter:**\nHere is a complete, minimal example showing how to limit an endpoint to 5 requests per minute per IP address.\n\n```python\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\n\n# Initialize the limiter\n# Warning: If behind a reverse proxy (like Nginx or Cloudflare), \n# get_remote_address might return the proxy's IP. See \"Important Security Considerations\" below.\nlimiter = Limiter(key_func=get_remote_address)\n\napp = FastAPI()\napp.state.limiter = limiter\n\n# Custom exception handler to return a clean 429 Too Many Requests response\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_exceeded_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=status.HTTP_429_TOO_MANY_REQUESTS,\n content={\n \"error\": \"Rate limit exceeded\",\n \"detail\": f\"Please try again later. Limit: {exc.limit}\"\n },\n )\n\n# Apply the limit to specific endpoints\n@app.get(\"/public-data\")\n@limiter.limit(\"5/minute\")\nasync def get_public_data(request: Request):\n return {\"message\": \"Here is your data!\"}\n\n# Endpoints without the decorator are not limited\n@app.get(\"/health\")\nasync def health_check():\n return {\"status\": \"healthy\"}\n```\n\n#### Using Redis for Production (Multi-Worker)\nBy default, `slowapi` stores rate limit counters in **memory**. If you run Uvicorn with multiple workers (e.g., `uvicorn main:app --workers 4`), each worker will have its own memory, meaning a user could bypass the limit by hitting different workers.\n\nTo fix this, use a shared Redis backend:\n```python\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379/0\" # Point to your Redis instance\n)\n```\n\n---\n\n### Method 2: Infrastructure-Level Rate Limiting (Best Practice)\nWhile application-level limiting is great for specific business logic (e.g., \"limit password resets to 3 per hour\"), **infrastructure-level rate limiting is highly recommended for general spam/DoS protection.** \n\nHandling rate limiting at the edge prevents malicious traffic from ever reaching your Python application, saving CPU and memory.\n\n* **Nginx:** Use the `limit_req_zone` and `limit_req` directives.\n* **Cloudflare / AWS WAF:** Use their managed rate-limiting rules to block IPs that exceed a certain threshold of requests per minute.\n* **API Gateways:** If using AWS API Gateway, Kong, or Tyk, configure the rate-limiting plugins native to those platforms.\n\n---\n\n### ⚠️ Important Security Considerations\n\n1. **IP Spoofing and Proxies (`X-Forwarded-For`)**\n If your FastAPI app sits behind a load balancer, Nginx, or Cloudflare, `get_remote_address` will likely return the IP of the *proxy*, not the user. This will cause all users to share the same rate limit bucket, effectively locking out your entire user base.\n * **Fix:** You must configure a custom `key_func` that securely reads the `X-Forwarded-For` or `X-Real-IP` header. **Only do this if you have explicitly configured your proxy to overwrite these headers** so attackers cannot spoof them.\n ```python\n def get_real_ip(request: Request) -> str:\n # ONLY use this if your reverse proxy is configured to securely overwrite X-Forwarded-For\n forwarded_for = request.headers.get(\"X-Forwarded-For\")\n if forwarded_for:\n return forwarded_for.split(\",\")[0].strip()\n return request.client.host if request.client else \"unknown\"\n \n limiter = Limiter(key_func=get_real_ip)\n ```\n\n2. **Distributed Botnets**\n IP-based rate limiting struggles against distributed botnets (where thousands of requests come from thousands of different IPs). To mitigate this:\n * Implement **User/Token-based rate limiting** for authenticated endpoints (limit by `user_id` or `api_key` instead of IP).\n * Use CAPTCHAs or proof-of-work challenges for sensitive unauthenticated endpoints (like login or registration).\n\n3. **Endpoint Specificity**\n Apply stricter limits to expensive or sensitive operations (e.g., `/login`, `/register`, `/send-reset-email`, `/generate-report`) and looser limits to cheap, read-only operations (e.g., `/get-public-config`)."
829
- },
830
- {
831
- "loc": 40,
832
- "correct": true,
833
- "timeSec": 42.698,
834
- "usage": {
835
- "inputTokens": 25,
836
- "outputTokens": 2124
837
- },
838
- "response": "Implementing rate limiting is a crucial defensive measure to protect your FastAPI application from abuse, brute-force attacks, and accidental resource exhaustion. \n\nThe most common and robust way to add rate limiting to FastAPI is by using the **`slowapi`** library, which is an extension of the popular `limits` library designed specifically for Starlette/FastAPI.\n\n### Step 1: Install Dependencies\nYou will need `slowapi` and `fastapi`. If you plan to run your app with multiple workers or across multiple servers in production, you will also want `redis` to act as a centralized state store.\n\n```bash\npip install fastapi uvicorn slowapi\n# Optional: pip install redis (for production/distributed setups)\n```\n\n### Step 2: Implement Rate Limiting in FastAPI\n\nHere is a complete, working example. It includes setting up the limiter, applying it to an endpoint, and handling the `429 Too Many Requests` error gracefully.\n\n```python\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\n\n# 1. Initialize the Limiter\n# By default, this uses an in-memory store and limits by the client's IP address.\nlimiter = Limiter(key_func=get_remote_address)\n\napp = FastAPI()\n# Attach the limiter to the app's state\napp.state.limiter = limiter\n\n# 2. Create a custom exception handler for RateLimitExceeded\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_exceeded_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=status.HTTP_429_TOO_MANY_REQUESTS,\n content={\n \"detail\": \"Rate limit exceeded. Please try again later.\",\n \"limit\": exc.limit.limit,\n \"retry_after\": exc.retry_after\n },\n )\n\n# 3. Apply the rate limit to your endpoint\n@app.get(\"/api/data\")\n@limiter.limit(\"5/minute\") # Allows 5 requests per minute per IP\nasync def get_data(request: Request):\n \"\"\"\n Note: The `request: Request` parameter is REQUIRED in the endpoint \n signature so slowapi can extract the IP address.\n \"\"\"\n return {\"message\": \"Here is your data!\"}\n\n# Example of a stricter limit for a sensitive endpoint (e.g., login)\n@app.post(\"/api/login\")\n@limiter.limit(\"3/minute\")\nasync def login(request: Request):\n return {\"message\": \"Login successful!\"}\n```\n\n### Step 3: Production Considerations (Crucial)\n\nThe default setup above uses an **in-memory store**. This is fine for local development or a single-worker deployment, but it has limitations in production:\n1. **Multiple Workers:** If you run Uvicorn with multiple workers (e.g., `uvicorn main:app --workers 4`), each worker has its own memory. A user could bypass the limit by hitting different workers.\n2. **Multiple Servers:** If you use a load balancer across several instances, the memory is not shared.\n\n#### Solution: Use Redis for Distributed Rate Limiting\nTo fix this, configure `slowapi` to use Redis as the backend storage.\n\n```python\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379/0\", # Point to your Redis instance\n # storage_options={\"socket_connect_timeout\": 30} # Optional Redis args\n)\n```\n\n#### Alternative: Identify Users by API Key or JWT\nLimiting by IP address (`get_remote_address`) can be problematic if your users are behind a corporate NAT or proxy (many users sharing one IP). If your API requires authentication, it is better to rate-limit by User ID or API Key.\n\nYou can define a custom `key_func`:\n\n```python\ndef get_api_key(request: Request):\n # Extract API key from headers (e.g., \"X-API-Key\")\n return request.headers.get(\"X-API-Key\", \"anonymous\")\n\nlimiter = Limiter(key_func=get_api_key)\n```\n\n### Best Practice: Edge / WAF Rate Limiting\nWhile application-level rate limiting (like `slowapi`) is excellent for business-logic limits (e.g., \"User X can only generate 5 reports per day\"), it still requires your Python server to process the request, consume memory, and open a database connection before rejecting it.\n\nFor high-volume public APIs, the most effective defense against spam and DDoS attacks is to implement rate limiting at the **Edge** or **Web Application Firewall (WAF)** level *before* the traffic ever reaches your FastAPI server. \n* **Cloudflare:** Offers built-in rate-limiting rules.\n* **AWS WAF / API Gateway:** Can throttle requests per IP or API key.\n* **Nginx:** Can be configured with the `limit_req_zone` module to drop excessive requests at the reverse-proxy layer."
839
- },
840
- {
841
- "loc": 50,
842
- "correct": true,
843
- "timeSec": 41.728,
844
- "usage": {
845
- "inputTokens": 25,
846
- "outputTokens": 2254
847
- },
848
- "response": "Implementing rate limiting is a crucial defensive measure to protect your FastAPI application from spam, brute-force attacks, and accidental Denial of Service (DoS). \n\nThe most robust and widely used library for rate limiting in FastAPI is **`slowapi`** (which is a wrapper around the `limits` library).\n\nHere is a complete guide to setting it up, along with crucial production considerations.\n\n### Step 1: Install SlowAPI\nInstall the library via pip:\n```bash\npip install slowapi\n```\n\n### Step 2: Basic Implementation (In-Memory)\nHere is how to add a basic rate limiter that restricts users to **5 requests per minute** based on their IP address.\n\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom fastapi.responses import JSONResponse\n\n# Initialize the limiter (defaults to in-memory storage)\nlimiter = Limiter(key_func=get_remote_address)\n\napp = FastAPI()\n\n# Attach the limiter to the app's state\napp.state.limiter = limiter\n\n# Add a custom exception handler to return a clean 429 JSON response\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=429,\n content={\n \"error\": \"Too Many Requests\",\n \"detail\": f\"Rate limit exceeded. Try again in {exc.retry_after} seconds.\"\n },\n )\n\n# Apply the limiter to specific endpoints\n@app.get(\"/api/data\")\n@limiter.limit(\"5/minute\")\nasync def get_data(request: Request):\n return {\"message\": \"Here is your data!\"}\n\n# You can also apply different limits to different endpoints\n@app.post(\"/api/login\")\n@limiter.limit(\"3/minute\")\nasync def login(request: Request):\n return {\"message\": \"Login attempt recorded.\"}\n```\n\n---\n\n### ⚠️ Crucial Production Considerations\n\nIf you are deploying this to production, the basic setup above will likely fail or block legitimate users due to two common architectural patterns: **Reverse Proxies** and **Multiple Workers**.\n\n#### 1. Handling Reverse Proxies (Nginx, Cloudflare, AWS ALB)\nIf your FastAPI app sits behind a reverse proxy or load balancer, `get_remote_address` will see the IP address of the *proxy*, not the actual user. This means all users will share the same rate limit bucket and get blocked almost immediately.\n\nTo fix this, you must tell FastAPI to trust the `X-Forwarded-For` headers using the `ProxyHeadersMiddleware` from `uvicorn.middleware.proxy_headers`:\n\n```python\nfrom uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware\n\n# Trust the X-Forwarded-For header from your proxy\napp.add_middleware(ProxyHeadersMiddleware, trusted_hosts=[\"YOUR_PROXY_IP_OR_*\"])\n```\n*Note: Ensure your proxy is configured to overwrite/scrub incoming `X-Forwarded-For` headers so malicious users cannot spoof their IPs.*\n\n#### 2. Handling Multiple Workers (Distributed Rate Limiting)\nBy default, `slowapi` stores rate limit counters in the memory of the Python process. If you run Uvicorn with multiple workers (e.g., `uvicorn main:app --workers 4`) or deploy across multiple servers, each worker will have its own separate memory. A user could bypass the limit by hitting different workers.\n\nTo fix this, use a shared backend like **Redis**.\n\n```bash\npip install redis\n```\n\n```python\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\n# Configure SlowAPI to use Redis as the storage backend\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379/0\", # Your Redis connection string\n strategy=\"fixed-window\", # or \"moving-window\"\n)\n```\n\n---\n\n### Alternative: Rate Limiting by API Key or User ID\nIf your API requires authentication, rate limiting by IP address is often insufficient (e.g., multiple users behind a corporate NAT will share an IP). Instead, you should rate limit by their API Key or User ID.\n\nYou can do this by providing a custom `key_func` to SlowAPI:\n\n```python\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import APIKeyHeader\n\nAPI_KEY_HEADER = APIKeyHeader(name=\"X-API-Key\")\n\n# Mock database of valid API keys\nVALID_KEYS = {\"user123_key\": \"user_123\", \"user456_key\": \"user_456\"}\n\ndef get_user_id(request: Request) -> str:\n # Extract the API key from the header\n api_key = request.headers.get(\"X-API-Key\")\n if not api_key or api_key not in VALID_KEYS:\n raise HTTPException(status_code=401, detail=\"Invalid API Key\")\n \n # Return the User ID to be used as the rate limit bucket key\n return VALID_KEYS[api_key]\n\n# Initialize limiter with the custom key function\nlimiter = Limiter(key_func=get_user_id)\n\n@app.get(\"/api/secure-data\")\n@limiter.limit(\"100/hour\")\nasync def secure_data(request: Request):\n return {\"message\": \"Secure data accessed.\"}\n```\n\n### Summary of Best Practices\n1. **Always return `429 Too Many Requests`** when a limit is hit, and include the `Retry-After` header so well-behaved clients know when to retry.\n2. **Use Redis** for storage if you are running more than one Uvicorn worker.\n3. **Be careful with IP spoofing** if you are not behind a trusted reverse proxy that manages the `X-Forwarded-For` header.\n4. **Apply stricter limits** to sensitive endpoints (like `/login` or `/password-reset`) to prevent brute-force attacks, and looser limits to general data retrieval."
849
- }
850
- ]
851
- },
852
- "lexis-two": {
853
- "email": [
854
- {
855
- "loc": 14,
856
- "correct": true,
857
- "timeSec": 38.788,
858
- "usage": {
859
- "inputTokens": 1574,
860
- "outputTokens": 1958
861
- },
862
- "response": "```python\nimport re\n\ndef is_valid_email(email: str) -> bool:\n if not isinstance(email, str) or not email:\n return False\n # lexis: naive regex stops garbage; add `email-validator` if you need RFC 5322 strictness or DNS checks.\n return bool(re.match(r\"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$\", email))\n\ndef demo():\n assert is_valid_email(\"user@example.com\")\n assert is_valid_email(\"user+tag@sub.domain.co.uk\")\n assert not is_valid_email(\"user@example\")\n assert not is_valid_email(\"user @example.com\")\n assert not is_valid_email(\"\")\n assert not is_valid_email(None)\n\nif __name__ == \"__main__\":\n demo()\n```\n\nSkipped: RFC 5322 strict parsing and DNS MX lookups. \nAdd `email-validator` when you need deliverability checks or strict compliance."
863
- },
864
- {
865
- "loc": 14,
866
- "correct": true,
867
- "timeSec": 39.721,
868
- "usage": {
869
- "inputTokens": 1574,
870
- "outputTokens": 2055
871
- },
872
- "response": "```python\nfrom email.headerregistry import Address\nfrom email.errors import HeaderParseError\n\ndef is_valid_email(s: str) -> bool:\n if not s: return False\n try:\n Address(addr_spec=s)\n return True\n except (HeaderParseError, ValueError, IndexError, TypeError):\n return False\n\n# lexis: minimal self-check for parser edge cases\nif __name__ == \"__main__\":\n assert is_valid_email(\"user+tag@sub.domain.co.uk\")\n assert not is_valid_email(\"\")\n assert not is_valid_email(\"missing-at-sign\")\n assert not is_valid_email(\"@no-local.com\")\n```\n\nSkipped: DNS MX lookups and strict public-TLD regex. Add when: you must verify the mailbox actually exists or need to block local/intranet domains."
873
- },
874
- {
875
- "loc": 10,
876
- "correct": true,
877
- "timeSec": 39.348,
878
- "usage": {
879
- "inputTokens": 1574,
880
- "outputTokens": 2094
881
- },
882
- "response": "```python\nimport re\n\ndef is_valid_email(email: str) -> bool:\n if not isinstance(email, str):\n return False\n # lexis: basic regex covers 99% of UI needs, RFC 5322 full regex is a bug farm.\n return bool(re.match(r\"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$\", email))\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"user@example.com\")\n assert not is_valid_email(\"invalid-email\")\n assert not is_valid_email(\"\")\n assert not is_valid_email(None)\n```\n\n→ skipped: strict RFC 5322 parsing and external libs like `email-validator`, add when you must support quoted local parts, IDN domains, or DNS MX verification."
883
- }
884
- ],
885
- "debounce": [
886
- {
887
- "loc": 9,
888
- "correct": false,
889
- "timeSec": 34.811,
890
- "usage": {
891
- "inputTokens": 1585,
892
- "outputTokens": 1771
893
- },
894
- "response": "```javascript\nfunction debounce(fn, wait) {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n}\n\ndocument.getElementById('search').addEventListener('input', debounce(e => {\n // fetch(`/api/search?q=${e.target.value}`)\n}, 300));\n```\n\n→ Skipped: Lodash and `AbortController` for in-flight requests.\n→ Add `AbortController` when slow networks cause stale search results to overwrite fresh ones."
895
- },
896
- {
897
- "loc": 10,
898
- "correct": true,
899
- "timeSec": 26.496,
900
- "usage": {
901
- "inputTokens": 1585,
902
- "outputTokens": 1374
903
- },
904
- "response": "```javascript\nexport const debounce = (fn, wait) => {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n};\n```\n\n```javascript\n// DOM wiring\ndocument.getElementById('search').addEventListener('input', debounce(e => {\n fetch(`/api/search?q=${encodeURIComponent(e.target.value)}`);\n}, 300));\n```\n\n→ skipped: leading-edge execution and `cancel()`, add when the initial 300ms delay annoys users or you need to clear timers on component unmount."
905
- },
906
- {
907
- "loc": 7,
908
- "correct": true,
909
- "timeSec": 27.973,
910
- "usage": {
911
- "inputTokens": 1585,
912
- "outputTokens": 1385
913
- },
914
- "response": "```javascript\nexport function debounce(fn, wait) {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n}\n```\n\n```javascript\n// document.getElementById('search').addEventListener('input', debounce(e => fetch(`/api?q=${e.target.value}`), 300));\n```\n\nSkipped: Lodash and `AbortController`. Add `AbortController` to cancel in-flight requests if delayed firing still causes race conditions on slow networks."
915
- }
916
- ],
917
- "csv-sum": [
918
- {
919
- "loc": 3,
920
- "correct": true,
921
- "timeSec": 24.16,
922
- "usage": {
923
- "inputTokens": 1579,
924
- "outputTokens": 1247
925
- },
926
- "response": "```python\nimport csv\n\nwith open(\"sales.csv\") as f:\n print(sum(float(row[\"amount\"]) for row in csv.DictReader(f)))\n```\n\n→ skipped: pandas and dirty-data handling, add when the file exceeds memory or contains malformed/missing rows."
927
- },
928
- {
929
- "loc": 4,
930
- "correct": true,
931
- "timeSec": 26.696,
932
- "usage": {
933
- "inputTokens": 1579,
934
- "outputTokens": 1335
935
- },
936
- "response": "```python\nimport csv\n\nwith open('sales.csv') as f:\n total = sum(float(row['amount']) for row in csv.DictReader(f))\nprint(total)\n```\n\n→ skipped: `pandas` and dirty-row handling. Add when data is malformed or file exceeds RAM."
937
- },
938
- {
939
- "loc": 8,
940
- "correct": true,
941
- "timeSec": 36.898,
942
- "usage": {
943
- "inputTokens": 1579,
944
- "outputTokens": 1959
945
- },
946
- "response": "```python\nimport csv\nimport io\n\ndef sum_amount(file_obj):\n return sum(float(r['amount']) for r in csv.DictReader(file_obj)) # lexis: float() prevents crash on \"1.5\"\n\nif __name__ == '__main__':\n with open('sales.csv') as f:\n print(sum_amount(f))\n \n # lexis: minimal parser check\n assert sum_amount(io.StringIO(\"id,amount\\n1,10.5\\n2,20\\n\")) == 30.5\n```\n\n→ skipped: pandas and dirty-data error handling. Add when rows contain malformed numbers or you need complex aggregations."
947
- }
948
- ],
949
- "countdown": [
950
- {
951
- "loc": 10,
952
- "correct": true,
953
- "timeSec": 38.458,
954
- "usage": {
955
- "inputTokens": 1582,
956
- "outputTokens": 2062
957
- },
958
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nexport function Countdown({ initialSeconds }) {\n const [s, setS] = useState(initialSeconds);\n \n useEffect(() => {\n if (s <= 0) return;\n const id = setInterval(() => setS(x => x - 1), 1000);\n return () => clearInterval(id);\n }, [s]);\n\n return <span>{s}</span>;\n}\n```\n\n→ skipped: MM:SS formatting, pause/reset controls, and `onComplete` callbacks. Add when the UI explicitly requires them."
959
- },
960
- {
961
- "loc": 10,
962
- "correct": true,
963
- "timeSec": 31.291,
964
- "usage": {
965
- "inputTokens": 1582,
966
- "outputTokens": 1660
967
- },
968
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nexport function Countdown({ initialSeconds }) {\n const [s, setS] = useState(initialSeconds);\n \n useEffect(() => {\n if (s <= 0) return;\n const id = setInterval(() => setS(v => v - 1), 1000);\n return () => clearInterval(id);\n }, [s]);\n\n return <span>{s > 0 ? s : \"Done\"}</span>;\n}\n```\n\n→ skipped: MM:SS formatting, pause/resume controls, reset on prop change. Add when explicitly requested."
969
- },
970
- {
971
- "loc": 10,
972
- "correct": true,
973
- "timeSec": 41.174,
974
- "usage": {
975
- "inputTokens": 1582,
976
- "outputTokens": 2184
977
- },
978
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nexport function Countdown({ seconds }) {\n const [time, setTime] = useState(seconds);\n\n useEffect(() => {\n if (time <= 0) return;\n const id = setTimeout(() => setTime(time - 1), 1000);\n return () => clearTimeout(id);\n }, [time]);\n\n return <span>{time}</span>;\n}\n```\n\n→ skipped: MM:SS formatting, pause/reset controls, and prop-change resets (just pass `key={seconds}` to the component instead). add when UX demands."
979
- }
980
- ],
981
- "rate-limit": [
982
- {
983
- "loc": 0,
984
- "correct": false,
985
- "timeSec": 18.97,
986
- "error": "fetch failed",
987
- "response": ""
988
- },
989
- {
990
- "loc": 23,
991
- "correct": true,
992
- "timeSec": 39.445,
993
- "usage": {
994
- "inputTokens": 1579,
995
- "outputTokens": 2121
996
- },
997
- "response": "```python\nfrom fastapi import FastAPI, Request, HTTPException\nimport time\n\napp = FastAPI()\n_hits = {}\n\ndef rate_limit(ip: str, limit: int = 10, window: int = 60):\n now = time.time()\n _hits[ip] = [t for t in _hits.get(ip, []) if now - t < window]\n if len(_hits[ip]) >= limit:\n raise HTTPException(429, \"Too Many Requests\")\n _hits[ip].append(now)\n\n@app.get(\"/\")\nasync def root(request: Request):\n # lexis: in-memory single-worker limit. Use slowapi/Redis for multi-worker.\n rate_limit(request.client.host or \"unknown\")\n return {\"msg\": \"ok\"}\n\nif __name__ == \"__main__\":\n _hits.clear()\n for _ in range(10): rate_limit(\"test_ip\")\n try:\n rate_limit(\"test_ip\")\n assert False, \"Should have blocked\"\n except HTTPException as e:\n assert e.status_code == 429\n print(\"Self-check passed.\")\n```\n\n→ skipped: `slowapi` dependency and Redis backend. \n→ add when: deploying multiple workers or needing distributed rate limits."
998
- },
999
- {
1000
- "loc": 17,
1001
- "correct": true,
1002
- "timeSec": 54.063,
1003
- "usage": {
1004
- "inputTokens": 1579,
1005
- "outputTokens": 2933
1006
- },
1007
- "response": "```python\nfrom fastapi import FastAPI, Request, HTTPException, Depends\nfrom fastapi.testclient import TestClient\nimport time\n\napp = FastAPI()\nhits = {}\n\ndef limit(req: Request):\n ip = req.client.host if req.client else \"test\"\n # lexis: in-memory, single-worker. Use Redis/slowapi for multi-worker.\n hits[ip] = [t for t in hits.get(ip, []) if time.time() - t < 60]\n if len(hits[ip]) >= 5: raise HTTPException(429, \"Rate limit exceeded\")\n hits[ip].append(time.time())\n\n@app.get(\"/\", dependencies=[Depends(limit)])\ndef root():\n return {\"msg\": \"ok\"}\n\nif __name__ == \"__main__\":\n client = TestClient(app)\n for _ in range(5): assert client.get(\"/\").status_code == 200\n assert client.get(\"/\").status_code == 429\n```\n\n→ skipped: `slowapi`/Redis and reverse-proxy limits. Add Redis when scaling past one worker; use Nginx/Cloudflare for edge-level DDoS protection."
1008
- }
1009
- ]
1010
- }
1011
- },
1012
- "minimax-m3": {
1013
- "baseline": {
1014
- "email": [
1015
- {
1016
- "loc": 60,
1017
- "correct": false,
1018
- "timeSec": 13.415,
1019
- "usage": {
1020
- "inputTokens": 59,
1021
- "outputTokens": 679
1022
- },
1023
- "response": "# Email Validation Function\n\nHere's a robust Python function for validating email addresses:\n\n```python\nimport re\n\ndef validate_email(email):\n \"\"\"\n Validates an email address using regex pattern matching.\n \n Args:\n email (str): The email address to validate.\n \n Returns:\n bool: True if the email is valid, False otherwise.\n \"\"\"\n if not isinstance(email, str):\n return False\n \n # Comprehensive regex pattern for email validation\n pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n \n return re.match(pattern, email) is not None\n\n\n# Example usage\nif __name__ == \"__main__\":\n test_emails = [\n \"user@example.com\",\n \"john.doe+work@company.co.uk\",\n \"invalid.email\",\n \"@example.com\",\n \"user@\",\n \"user@.com\",\n \"\",\n None,\n \"user @example.com\",\n \"very.long.email-address@subdomain.example.com\"\n ]\n \n for email in test_emails:\n result = validate_email(email)\n print(f\"{str(email):50} → {'Valid' if result else 'Invalid'}\")\n```\n\n## Output:\n```\nuser@example.com → Valid\njohn.doe+work@company.co.uk → Valid\ninvalid.email → Invalid\n@example.com → Invalid\nuser@ → Invalid\nuser@.com → Invalid\n → Invalid\nNone → Invalid\nuser @example.com → Invalid\nvery.long.email-address@subdomain.example.com → Valid\n```\n\n## Alternative: Using Python's Built-in `email` Module\n\nFor stricter validation following RFC standards, you can use the `email` module:\n\n```python\nfrom email.utils import parseaddr\n\ndef validate_email_strict(email):\n \"\"\"\n Validates email using Python's email parser (RFC-compliant).\n \n Args:\n email (str): The email address to validate.\n \n Returns:\n bool: True if the email is valid, False otherwise.\n \"\"\"\n if not isinstance(email, str) or not email:\n return False\n \n try:\n name, addr = parseaddr(email)\n # Check that parseaddr found a valid address\n if not addr or '@' not in addr:\n return False\n \n # Split and verify local and domain parts\n local, domain = addr.rsplit('@', 1)\n if not local or not domain or '.' not in domain:\n return False\n \n return True\n except Exception:\n return False\n```\n\n## Key Points:\n\n1. **Type checking** — Handles non-string inputs gracefully\n2. **Regex pattern** — Validates basic structure: `local@domain.tld`\n3. **Edge cases** — Catches empty strings, missing parts, invalid characters\n4. **TLD requirement** — Ensures at least 2 characters in the top-level domain\n5. **Character restrictions** — Allows common valid characters in local and domain parts\n\nChoose the **regex version** for quick validation or the **`email` module version** for RFC compliance. For production use, consider also implementing DNS verification to confirm the domain actually has MX records."
1024
- },
1025
- {
1026
- "loc": 55,
1027
- "correct": true,
1028
- "timeSec": 13.731,
1029
- "usage": {
1030
- "inputTokens": 59,
1031
- "outputTokens": 715
1032
- },
1033
- "response": "# Email Validation in Python\n\nHere's a robust email validation function using a regex pattern:\n\n```python\nimport re\n\ndef validate_email(email):\n \"\"\"\n Validates an email address using a regular expression.\n \n Args:\n email (str): The email address to validate.\n \n Returns:\n bool: True if the email is valid, False otherwise.\n \"\"\"\n if not isinstance(email, str):\n return False\n \n # RFC 5322 simplified pattern\n pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n \n return bool(re.match(pattern, email))\n```\n\n## Usage Examples\n\n```python\n# Test cases\nemails = [\n \"user@example.com\", # Valid\n \"john.doe+work@company.co\", # Valid\n \"user_name@sub.example.org\", # Valid\n \"invalid.email\", # Invalid (no @)\n \"@example.com\", # Invalid (no local part)\n \"user@\", # Invalid (no domain)\n \"user@example\", # Invalid (no TLD)\n \"user @example.com\", # Invalid (space)\n \"\", # Invalid (empty)\n]\n\nfor email in emails:\n status = \"✓ Valid\" if validate_email(email) else \"✗ Invalid\"\n print(f\"{email!r:35} -> {status}\")\n```\n\n## Alternative: Using the `email` Module\n\nFor more strict, RFC-compliant validation, use Python's built-in `email` module:\n\n```python\nfrom email.utils import parseaddr\n\ndef validate_email_strict(email):\n \"\"\"\n Validates an email using Python's email parser.\n \n Args:\n email (str): The email address to validate.\n \n Returns:\n bool: True if valid format, False otherwise.\n \"\"\"\n if not isinstance(email, str) or not email:\n return False\n \n name, addr = parseaddr(email)\n \n # Check that parseaddr identified it as a proper address\n if not addr or addr != email:\n return False\n \n # Basic structural validation\n if '@' not in addr:\n return False\n \n local, domain = addr.rsplit('@', 1)\n if not local or not domain or '.' not in domain:\n return False\n \n return True\n```\n\n## Recommendation\n\nFor most use cases, **the regex version is sufficient and faster**. However, if you need strict RFC compliance (e.g., for a form validator), consider these tips:\n\n1. **Don't over-validate** — Even strict regex won't catch every edge case (e.g., disposable domains, typos like `gmial.com`).\n2. **Send a confirmation email** — The only reliable way to confirm an email exists is to send a verification message.\n3. **For production use**, consider libraries like [`email-validator`](https://pypi.org/project/email-validator/):\n ```bash\n pip install email-validator\n ```\n ```python\n from email_validator import validate_email, EmailNotValidError\n \n def is_valid(email):\n try:\n validate_email(email, check_deliverability=True)\n return True\n except EmailNotValidError:\n return False\n ```\n\nThis `email-validator` library even checks if the domain has valid MX records, giving you a much higher confidence level."
1034
- },
1035
- {
1036
- "loc": 39,
1037
- "correct": true,
1038
- "timeSec": 10.034,
1039
- "usage": {
1040
- "inputTokens": 59,
1041
- "outputTokens": 531
1042
- },
1043
- "response": "Here's a Python function to validate email addresses using a practical approach:\n\n```python\nimport re\n\ndef validate_email(email):\n \"\"\"\n Validates an email address.\n Returns True if valid, False otherwise.\n \"\"\"\n if not isinstance(email, str):\n return False\n \n # Basic length check\n if len(email) > 254:\n return False\n \n # Pattern: local-part @ domain . tld\n pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n \n if not re.match(pattern, email):\n return False\n \n # Additional checks\n local, domain = email.rsplit('@', 1)\n \n # Local part checks\n if not local or len(local) > 64:\n return False\n if local.startswith('.') or local.endswith('.'):\n return False\n if '..' in local:\n return False\n \n # Domain checks\n if not domain or '..' in domain:\n return False\n if not re.match(r'^[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$', domain):\n return False\n \n return True\n\n\n# Example usage\nif __name__ == \"__main__\":\n test_emails = [\n \"user@example.com\",\n \"first.last@company.co.uk\",\n \"invalid.email@\",\n \"@example.com\",\n \"user@.com\",\n \"user..name@example.com\",\n \"user@example.c\",\n \"user name@example.com\",\n ]\n \n for email in test_emails:\n result = validate_email(email)\n print(f\"{email}: {'Valid' if result else 'Invalid'}\")\n```\n\n**What this does:**\n\n- **Pattern matching**: Uses a regex to check the basic structure (`local@domain.tld`)\n- **Length limits**: Enforces RFC 5321 limits (64 chars for local, 254 for total)\n- **Local part validation**: No leading/trailing dots, no consecutive dots\n- **Domain validation**: Ensures a valid TLD (at least 2 characters)\n- **Type check**: Returns `False` for non-string inputs\n\n**Note on limitations:**\n\nThis is a **pragmatic validator** — it catches most malformed addresses but can't verify if an email actually exists or is deliverable. For that, you'd need to send a verification email or use a dedicated service. For most use cases (form validation, etc.), this works well."
1044
- }
1045
- ],
1046
- "debounce": [
1047
- {
1048
- "loc": 59,
1049
- "correct": false,
1050
- "timeSec": 12.285,
1051
- "usage": {
1052
- "inputTokens": 72,
1053
- "outputTokens": 701
1054
- },
1055
- "response": "# Debouncing a Search Input in Vanilla JavaScript\n\nHere's a clean implementation with explanations:\n\n## The Core Idea\n\nDebounce delays a function call until a specified time has passed *without* another invocation. Each new keystroke resets the timer, so the API only fires once the user stops typing.\n\n## Implementation\n\n```html\n<input type=\"text\" id=\"search\" placeholder=\"Search...\">\n```\n\n```javascript\nfunction debounce(fn, delay) {\n let timeoutId;\n\n return function (...args) {\n // Clear any pending invocation\n clearTimeout(timeoutId);\n\n // Schedule a new one\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n }, delay);\n };\n}\n\n// Your API call function\nasync function fetchResults(query) {\n if (!query.trim()) return;\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);\n const data = await response.json();\n console.log('Results:', data);\n // renderResults(data);\n}\n\n// Wrap it with debounce — 300ms feels snappy and avoids most redundant calls\nconst debouncedSearch = debounce(fetchResults, 300);\n\n// Wire it up\nconst input = document.getElementById('search');\ninput.addEventListener('input', (e) => {\n debouncedSearch(e.target.value);\n});\n```\n\n## Why 300ms?\n\n- **Under 200ms**: Not much benefit; the user is still actively typing.\n- **200–400ms**: Sweet spot. Feels instant but cuts most bursts.\n- **Over 500ms**: Feels laggy for fast typists.\n\n## Optional Enhancements\n\n**1. Cancel in-flight requests** (avoid race conditions where an older slow response overwrites a newer one):\n\n```javascript\nfunction debounceAsync(fn, delay) {\n let timeoutId;\n let controller;\n\n return function (...args) {\n clearTimeout(timeoutId);\n\n timeoutId = setTimeout(async () => {\n // Abort any previous request\n if (controller) controller.abort();\n controller = new AbortController();\n\n try {\n await fn(controller.signal, ...args);\n } catch (err) {\n if (err.name !== 'AbortError') throw err;\n }\n }, delay);\n };\n}\n\nasync function fetchResults(signal, query) {\n if (!query.trim()) return;\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal });\n const data = await response.json();\n console.log('Results:', data);\n}\n\nconst debouncedSearch = debounceAsync(fetchResults, 300);\n```\n\n**2. Add a leading-edge trigger** (fire immediately on first keystroke, then debounce subsequent ones — useful when the input might be empty initially):\n\n```javascript\nfunction debounce(fn, delay, { leading = false } = {}) {\n let timeoutId;\n let called = false;\n\n return function (...args) {\n if (leading && !called) {\n fn.apply(this, args);\n called = true;\n }\n\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n called = false;\n if (!leading) fn.apply(this, args);\n }, delay);\n };\n}\n```\n\nThe basic version at the top covers 90% of search-input cases. Add request cancellation if you find stale results appearing when the user keeps typing."
1056
- },
1057
- {
1058
- "loc": 70,
1059
- "correct": false,
1060
- "timeSec": 13.85,
1061
- "usage": {
1062
- "inputTokens": 72,
1063
- "outputTokens": 818
1064
- },
1065
- "response": "# Debounced Search Input in Vanilla JavaScript\n\nHere's a clean implementation that delays the API call until the user stops typing:\n\n## Basic Implementation\n\n```javascript\nconst searchInput = document.getElementById('search-input');\nlet debounceTimer;\n\nsearchInput.addEventListener('input', (e) => {\n clearTimeout(debounceTimer);\n \n debounceTimer = setTimeout(() => {\n performSearch(e.target.value);\n }, 300);\n});\n\nfunction performSearch(query) {\n fetch(`/api/search?q=${encodeURIComponent(query)}`)\n .then(res => res.json())\n .then(data => renderResults(data))\n .catch(err => console.error(err));\n}\n```\n\n## Reusable Debounce Utility\n\nFor multiple inputs, extract the logic:\n\n```javascript\nfunction debounce(fn, delay = 300) {\n let timer;\n return function (...args) {\n clearTimeout(timer);\n timer = setTimeout(() => fn.apply(this, args), delay);\n };\n}\n\nconst searchInput = document.getElementById('search-input');\n\nconst handleSearch = debounce((query) => {\n fetch(`/api/search?q=${encodeURIComponent(query)}`)\n .then(res => res.json())\n .then(renderResults)\n .catch(console.error);\n}, 300);\n\nsearchInput.addEventListener('input', (e) => handleSearch(e.target.value));\n```\n\n## Full Version with Loading & Error States\n\n```javascript\nfunction debounce(fn, delay) {\n let timer;\n return function (...args) {\n clearTimeout(timer);\n timer = setTimeout(() => fn.apply(this, args), delay);\n };\n}\n\nconst searchInput = document.getElementById('search-input');\nconst resultsContainer = document.getElementById('results');\nlet activeRequest;\n\nconst handleSearch = debounce(async (query) => {\n // Abort previous request if still in flight\n if (activeRequest) activeRequest.abort();\n \n // Empty query → clear results\n if (!query.trim()) {\n resultsContainer.innerHTML = '';\n return;\n }\n \n // Show loading state\n resultsContainer.innerHTML = '<p>Searching...</p>';\n \n try {\n const controller = new AbortController();\n activeRequest = controller;\n \n const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n \n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n \n const data = await res.json();\n renderResults(data);\n } catch (err) {\n if (err.name === 'AbortError') return; // expected\n resultsContainer.innerHTML = `<p class=\"error\">Error: ${err.message}</p>`;\n }\n}, 300);\n\nsearchInput.addEventListener('input', (e) => handleSearch(e.target.value));\n\nfunction renderResults(data) {\n if (!data.length) {\n resultsContainer.innerHTML = '<p>No results found.</p>';\n return;\n }\n resultsContainer.innerHTML = data\n .map(item => `<li>${item.title}</li>`)\n .join('');\n}\n```\n\n## Key Points\n\n| Concern | Solution |\n|---------|----------|\n| **Excess API calls** | `setTimeout` delays execution until typing pauses |\n| **Rapid typing** | `clearTimeout` cancels pending calls on each keystroke |\n| **Stale responses** | `AbortController` cancels in-flight requests |\n| **Reusability** | Higher-order `debounce()` function |\n| **UX feedback** | Loading & empty states |\n\n## Tuning the Delay\n\n- **100–200ms** — feels instant, good for fast autocomplete\n- **300ms** — balanced (most common default)\n- **500ms+** — when the API is expensive or rate-limited\n\nThe 300ms sweet spot matches typical user typing pauses and feels responsive without flooding your API."
1066
- },
1067
- {
1068
- "loc": 66,
1069
- "correct": false,
1070
- "timeSec": 12.657,
1071
- "usage": {
1072
- "inputTokens": 72,
1073
- "outputTokens": 710
1074
- },
1075
- "response": "# Debouncing a Search Input\n\nHere's how to add debouncing to your search input so the API only fires after the user stops typing.\n\n## Core Implementation\n\n```javascript\nfunction debounce(fn, delay) {\n let timeoutId;\n return function (...args) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n }, delay);\n };\n}\n\nconst searchInput = document.getElementById('search');\nconst resultsList = document.getElementById('results');\n\nasync function fetchResults(query) {\n if (!query) {\n resultsList.innerHTML = '';\n return;\n }\n try {\n const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`);\n const data = await res.json();\n renderResults(data);\n } catch (err) {\n console.error('Search failed:', err);\n }\n}\n\nconst debouncedSearch = debounce(fetchResults, 300);\n\nsearchInput.addEventListener('input', (e) => {\n debouncedSearch(e.target.value);\n});\n```\n\n## What's Happening\n\n- **`debounce(fn, delay)`** returns a wrapper that clears any pending timer on each call and only invokes `fn` once the user pauses for `delay` ms.\n- `fetchResults` only runs when the debounce timer fires, not on every keystroke.\n- `encodeURIComponent` keeps the query safe in the URL.\n\n## Optional Enhancements\n\n**1. Cancel in-flight requests when a new one starts** — useful if results could arrive out of order:\n\n```javascript\nfunction debounceAsync(fn, delay) {\n let timeoutId;\n let controller;\n\n return function (...args) {\n clearTimeout(timeoutId);\n controller?.abort();\n controller = new AbortController();\n\n return new Promise((resolve, reject) => {\n timeoutId = setTimeout(async () => {\n try {\n const result = await fn(...args, controller.signal);\n resolve(result);\n } catch (err) {\n if (err.name !== 'AbortError') reject(err);\n }\n }, delay);\n });\n };\n}\n\nasync function fetchResults(query, signal) {\n const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal });\n return res.json();\n}\n\nconst debouncedSearch = debounceAsync(fetchResults, 300);\n```\n\n**2. Show a loading state** for queries over a threshold:\n\n```javascript\nlet loadingTimer;\nsearchInput.addEventListener('input', (e) => {\n clearTimeout(loadingTimer);\n loadingTimer = setTimeout(() => {\n resultsList.classList.add('loading');\n }, 200); // show spinner if request takes >200ms to fire\n debouncedSearch(e.target.value).finally(() => {\n resultsList.classList.remove('loading');\n });\n});\n```\n\n**3. Minimum query length** to avoid wasted requests:\n\n```javascript\nconst debouncedSearch = debounce((query) => {\n if (query.length < 2) return;\n fetchResults(query);\n}, 300);\n```\n\n## Choosing a Delay\n\n| Delay | Use case |\n|-------|----------|\n| 150–200 ms | Feels instant, great for small datasets |\n| 300 ms | Good default for most APIs |\n| 500 ms | Heavy endpoints, expensive operations |\n\nStart with **300 ms** and adjust based on how snappy it feels."
1076
- }
1077
- ],
1078
- "csv-sum": [
1079
- {
1080
- "loc": 18,
1081
- "correct": true,
1082
- "timeSec": 6.508,
1083
- "usage": {
1084
- "inputTokens": 64,
1085
- "outputTokens": 367
1086
- },
1087
- "response": "Here's a simple Python solution:\n\n```python\nimport csv\n\ndef sum_sales_amount(filename):\n total = 0.0\n with open(filename, 'r', newline='') as f:\n reader = csv.DictReader(f)\n for row in reader:\n total += float(row['amount'])\n return total\n\nif __name__ == '__main__':\n total = sum_sales_amount('sales.csv')\n print(f\"Total sales: {total:.2f}\")\n```\n\n**How it works:**\n1. Opens `sales.csv` using `csv.DictReader`, which reads each row as a dictionary keyed by column name.\n2. Iterates through each row, converting the `'amount'` value to a float and adding it to `total`.\n3. Returns the final sum.\n\n**Example `sales.csv`:**\n```csv\nid,product,amount\n1,Widget,10.50\n2,Gadget,25.00\n3,Widget,15.75\n```\n**Output:** `Total sales: 51.25`\n\n**Notes & alternatives:**\n- If your file has no header or a different structure, you can use `csv.reader` and index columns by position instead.\n- For larger files, `pandas` is faster and more flexible:\n ```python\n import pandas as pd\n df = pd.read_csv('sales.csv')\n print(df['amount'].sum())\n ```\n- If some `amount` entries may be missing or non-numeric, wrap the conversion in a `try/except` to skip bad rows, or use `pandas.read_csv(..., na_values=[''])` to handle them gracefully.\n\nLet me know if you need it adapted (e.g., for different delimiters, handling missing values, or a specific file layout)."
1088
- },
1089
- {
1090
- "loc": 33,
1091
- "correct": true,
1092
- "timeSec": 6.729,
1093
- "usage": {
1094
- "inputTokens": 64,
1095
- "outputTokens": 451
1096
- },
1097
- "response": "Here's Python code that reads a `sales.csv` file and sums the `amount` column:\n\n```python\nimport csv\n\ndef sum_sales_amount(filename):\n total = 0\n with open(filename, 'r', newline='') as csvfile:\n reader = csv.DictReader(csvfile)\n for row in reader:\n total += float(row['amount'])\n return total\n\n# Usage\nif __name__ == \"__main__\":\n filename = 'sales.csv'\n total_amount = sum_sales_amount(filename)\n print(f\"Total sales amount: {total_amount}\")\n```\n\n**A few notes about this code:**\n\n1. **Using `csv.DictReader`** - This allows access to columns by name (e.g., `row['amount']`), making the code more readable and resilient to column order changes.\n\n2. **Type conversion** - `float()` is used to convert the string values from the CSV to numbers before summing.\n\n**Alternative using pandas** (if you have it installed):\n\n```python\nimport pandas as pd\n\ndf = pd.read_csv('sales.csv')\ntotal = df['amount'].sum()\nprint(f\"Total sales amount: {total}\")\n```\n\n**Handling potential issues:**\n\nFor production code, you might want to handle:\n- Missing values\n- Non-numeric values in the amount column\n- File not found errors\n\nHere's a more robust version:\n\n```python\nimport csv\n\ndef sum_sales_amount(filename):\n total = 0\n with open(filename, 'r', newline='') as csvfile:\n reader = csv.DictReader(csvfile)\n for row_number, row in enumerate(reader, start=2): # start=2 accounts for header\n try:\n total += float(row['amount'])\n except (ValueError, KeyError) as e:\n print(f\"Warning: Skipping row {row_number} due to error: {e}\")\n return total\n\nif __name__ == \"__main__\":\n try:\n total = sum_sales_amount('sales.csv')\n print(f\"Total sales amount: {total}\")\n except FileNotFoundError:\n print(\"Error: sales.csv not found\")\n```"
1098
- },
1099
- {
1100
- "loc": 45,
1101
- "correct": true,
1102
- "timeSec": 9.047,
1103
- "usage": {
1104
- "inputTokens": 64,
1105
- "outputTokens": 599
1106
- },
1107
- "response": "Here's a simple, robust solution that reads `sales.csv` and sums the `amount` column. I'll provide a few variants for different scenarios.\n\n## Basic version (assumes header row, no missing values)\n\n```python\nimport csv\n\ntotal = 0.0\nwith open('sales.csv', newline='') as f:\n reader = csv.DictReader(f)\n for row in reader:\n total += float(row['amount'])\n\nprint(f\"Total: {total:.2f}\")\n```\n\n## Using pandas (cleaner for larger files / reports)\n\n```python\nimport pandas as pd\n\ndf = pd.read_csv('sales.csv')\ntotal = df['amount'].sum()\nprint(f\"Total: {total:.2f}\")\n```\n\n## Defensive version (handles missing/blank values, currency symbols, commas)\n\n```python\nimport csv\n\ndef parse_amount(value):\n if value is None:\n return 0.0\n value = value.strip().replace(',', '').replace('$', '')\n if not value:\n return 0.0\n return float(value)\n\ntotal = 0.0\nwith open('sales.csv', newline='', encoding='utf-8') as f:\n reader = csv.DictReader(f)\n for row in reader:\n total += parse_amount(row.get('amount', ''))\n\nprint(f\"Total: {total:.2f}\")\n```\n\n## Command-line version (pass the file path as an argument)\n\n```python\nimport csv\nimport sys\n\ndef parse_amount(value):\n if not value:\n return 0.0\n return float(value.replace(',', '').replace('$', '').strip())\n\ndef sum_amounts(path):\n total = 0.0\n with open(path, newline='', encoding='utf-8') as f:\n reader = csv.DictReader(f)\n for row in reader:\n total += parse_amount(row.get('amount', ''))\n return total\n\nif __name__ == \"__main__\":\n path = sys.argv[1] if len(sys.argv) > 1 else 'sales.csv'\n print(f\"Total: {sum_amounts(path):.2f}\")\n```\n\n### Which to use?\n- **Pandas version** is best if you already use pandas or need to do more analysis later.\n- **DictReader version** is a good stdlib default — no extra dependencies.\n- **Defensive version** is recommended for real-world CSVs that may have blanks or currency formatting.\n\n### Example `sales.csv`\n```csv\nid,date,amount\n1,2024-01-01,100.50\n2,2024-01-02,250.00\n3,2024-01-03,75.25\n```\n\nExpected output: `Total: 425.75`\n\nWant me to extend this (group by category, filter by date, write to a summary file)?"
1108
- }
1109
- ],
1110
- "countdown": [
1111
- {
1112
- "loc": 112,
1113
- "correct": true,
1114
- "timeSec": 12.771,
1115
- "usage": {
1116
- "inputTokens": 67,
1117
- "outputTokens": 1030
1118
- },
1119
- "response": "# Countdown Timer Component in React\n\nHere's a clean, reusable countdown timer component with start, pause, and reset functionality:\n\n```jsx\nimport React, { useState, useEffect, useRef } from 'react';\n\nconst CountdownTimer = ({ initialSeconds = 60, onComplete }) => {\n const [seconds, setSeconds] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(false);\n const intervalRef = useRef(null);\n const onCompleteRef = useRef(onComplete);\n\n // Keep the latest onComplete callback in a ref\n useEffect(() => {\n onCompleteRef.current = onComplete;\n }, [onComplete]);\n\n useEffect(() => {\n if (isRunning && seconds > 0) {\n intervalRef.current = setInterval(() => {\n setSeconds((prev) => {\n if (prev <= 1) {\n setIsRunning(false);\n if (onCompleteRef.current) {\n onCompleteRef.current();\n }\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, [isRunning]);\n\n const handleStart = () => setIsRunning(true);\n const handlePause = () => setIsRunning(false);\n const handleReset = () => {\n setIsRunning(false);\n setSeconds(initialSeconds);\n };\n\n // Format seconds as MM:SS\n const formatTime = (totalSeconds) => {\n const minutes = Math.floor(totalSeconds / 60);\n const secs = totalSeconds % 60;\n return `${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n };\n\n return (\n <div style={styles.container}>\n <div style={styles.display}>{formatTime(seconds)}</div>\n <div style={styles.controls}>\n {!isRunning ? (\n <button onClick={handleStart} disabled={seconds === 0} style={styles.button}>\n Start\n </button>\n ) : (\n <button onClick={handlePause} style={styles.button}>\n Pause\n </button>\n )}\n <button onClick={handleReset} style={styles.button}>\n Reset\n </button>\n </div>\n {seconds === 0 && <p style={styles.completeText}>Time's up!</p>}\n </div>\n );\n};\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n padding: '20px',\n fontFamily: 'sans-serif',\n },\n display: {\n fontSize: '64px',\n fontWeight: 'bold',\n marginBottom: '20px',\n fontVariantNumeric: 'tabular-nums',\n },\n controls: {\n display: 'flex',\n gap: '10px',\n },\n button: {\n padding: '10px 20px',\n fontSize: '16px',\n cursor: 'pointer',\n border: '1px solid #ccc',\n borderRadius: '4px',\n background: '#fff',\n },\n completeText: {\n marginTop: '15px',\n color: '#d9534f',\n fontWeight: 'bold',\n },\n};\n\nexport default CountdownTimer;\n```\n\n## Usage Example\n\n```jsx\nimport React from 'react';\nimport CountdownTimer from './CountdownTimer';\n\nconst App = () => {\n const handleComplete = () => {\n console.log('Countdown finished!');\n // Trigger sound, notification, modal, etc.\n };\n\n return (\n <div>\n <h1>My Countdown Timer</h1>\n <CountdownTimer\n initialSeconds={120}\n onComplete={handleComplete}\n />\n </div>\n );\n};\n\nexport default App;\n```\n\n## Key Features\n\n- **Configurable duration** via the `initialSeconds` prop\n- **Start/Pause/Reset** controls\n- **MM:SS formatting** for readability\n- **Completion callback** via the `onComplete` prop\n- **Clean state management** with proper interval cleanup to prevent memory leaks\n- **Auto-stops** when reaching zero\n\n## How It Works\n\n1. The `useState` hook tracks remaining seconds and running state\n2. A `useEffect` hook sets up the interval when running, with cleanup on unmount or when stopped\n3. When the timer hits zero, it stops automatically and fires the `onComplete` callback\n4. The `useRef` for the callback ensures we always use the latest version without re-running the effect\n\nYou can easily extend this by adding props for custom styling, labels, or a \"tick\" callback for progress tracking."
1120
- },
1121
- {
1122
- "loc": 67,
1123
- "correct": true,
1124
- "timeSec": 12.629,
1125
- "usage": {
1126
- "inputTokens": 67,
1127
- "outputTokens": 813
1128
- },
1129
- "response": "# React Countdown Timer Component\n\nHere's a clean, reusable countdown timer component:\n\n```jsx\nimport { useState, useEffect, useRef } from 'react';\n\nfunction CountdownTimer({ initialSeconds = 60, onComplete }) {\n const [secondsLeft, setSecondsLeft] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(false);\n const intervalRef = useRef(null);\n const onCompleteRef = useRef(onComplete);\n\n // Keep the latest onComplete callback without restarting the interval\n useEffect(() => {\n onCompleteRef.current = onComplete;\n }, [onComplete]);\n\n useEffect(() => {\n if (!isRunning) return;\n\n intervalRef.current = setInterval(() => {\n setSecondsLeft((prev) => {\n if (prev <= 1) {\n clearInterval(intervalRef.current);\n setIsRunning(false);\n onCompleteRef.current?.();\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(intervalRef.current);\n }, [isRunning]);\n\n const start = () => {\n if (secondsLeft > 0) setIsRunning(true);\n };\n\n const pause = () => {\n setIsRunning(false);\n clearInterval(intervalRef.current);\n };\n\n const reset = (newSeconds = initialSeconds) => {\n pause();\n setSecondsLeft(newSeconds);\n };\n\n const formatTime = (totalSeconds) => {\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;\n };\n\n return (\n <div style={{ fontFamily: 'monospace', textAlign: 'center' }}>\n <h1 style={{ fontSize: '4rem', margin: '0' }}>{formatTime(secondsLeft)}</h1>\n <div style={{ marginTop: '1rem' }}>\n <button onClick={start} disabled={isRunning || secondsLeft === 0}>\n Start\n </button>{' '}\n <button onClick={pause} disabled={!isRunning}>\n Pause\n </button>{' '}\n <button onClick={() => reset()}>Reset</button>\n </div>\n </div>\n );\n}\n\nexport default CountdownTimer;\n```\n\n## Usage Example\n\n```jsx\nimport CountdownTimer from './CountdownTimer';\n\nfunction App() {\n const handleComplete = () => {\n alert('Time is up!');\n };\n\n return (\n <div style={{ padding: '2rem' }}>\n <CountdownTimer initialSeconds={90} onComplete={handleComplete} />\n </div>\n );\n}\n```\n\n## Key Features\n\n- **Configurable duration** via the `initialSeconds` prop\n- **Start / Pause / Reset** controls\n- **MM:SS formatting** with zero-padding\n- **Completion callback** via `onComplete` prop\n- **Stable callback reference** — the `onComplete` is stored in a ref so updating it doesn't restart the timer\n\n## A Few Notes\n\n1. **Drift over long durations**: Using `setInterval` can drift up to ~1s per minute. For a more accurate timer, you can compute the end time once and check `Date.now()` against it on each tick. Let me know if you'd like that version.\n2. **Accessibility**: For production, consider adding `aria-live=\"polite\"` to the time display and proper labels on the buttons.\n3. **Styling**: The inline styles are minimal — feel free to swap them for CSS modules, Tailwind, or styled-components.\n\nWant me to extend this with a progress bar, sound alert, or a higher-accuracy version?"
1130
- },
1131
- {
1132
- "loc": 141,
1133
- "correct": true,
1134
- "timeSec": 21.467,
1135
- "usage": {
1136
- "inputTokens": 67,
1137
- "outputTokens": 1287
1138
- },
1139
- "response": "# Countdown Timer Component in React\n\nHere's a complete, reusable countdown timer component with start, pause, and reset functionality.\n\n## CountdownTimer.jsx\n\n```jsx\nimport React, { useState, useEffect, useRef } from 'react';\n\nconst CountdownTimer = ({ initialSeconds = 60, onComplete }) => {\n const [seconds, setSeconds] = useState(initialSeconds);\n const [isRunning, setIsRunning] = useState(false);\n const intervalRef = useRef(null);\n\n useEffect(() => {\n if (isRunning && seconds > 0) {\n intervalRef.current = setInterval(() => {\n setSeconds((prev) => {\n if (prev <= 1) {\n setIsRunning(false);\n if (onComplete) onComplete();\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n }\n\n return () => clearInterval(intervalRef.current);\n }, [isRunning, seconds, onComplete]);\n\n const handleStart = () => {\n if (seconds > 0) setIsRunning(true);\n };\n\n const handlePause = () => setIsRunning(false);\n\n const handleReset = () => {\n setIsRunning(false);\n setSeconds(initialSeconds);\n };\n\n const formatTime = (totalSeconds) => {\n const mins = Math.floor(totalSeconds / 60);\n const secs = totalSeconds % 60;\n return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n };\n\n const isFinished = seconds === 0;\n\n return (\n <div style={styles.container}>\n <h2 style={styles.title}>Countdown Timer</h2>\n\n <div style={{\n ...styles.display,\n color: seconds <= 10 && seconds > 0 ? '#e74c3c' : '#2c3e50',\n }}>\n {formatTime(seconds)}\n </div>\n\n {isFinished && <p style={styles.finishedText}>Time's up! 🎉</p>}\n\n <div style={styles.buttonGroup}>\n <button\n onClick={handleStart}\n disabled={isRunning || isFinished}\n style={{ ...styles.button, ...styles.startButton }}\n >\n Start\n </button>\n\n <button\n onClick={handlePause}\n disabled={!isRunning}\n style={{ ...styles.button, ...styles.pauseButton }}\n >\n Pause\n </button>\n\n <button\n onClick={handleReset}\n style={{ ...styles.button, ...styles.resetButton }}\n >\n Reset\n </button>\n </div>\n </div>\n );\n};\n\nconst styles = {\n container: {\n fontFamily: 'system-ui, sans-serif',\n textAlign: 'center',\n padding: '2rem',\n maxWidth: '400px',\n margin: '2rem auto',\n border: '2px solid #ecf0f1',\n borderRadius: '12px',\n boxShadow: '0 4px 12px rgba(0,0,0,0.08)',\n backgroundColor: '#fff',\n },\n title: {\n margin: '0 0 1rem',\n color: '#34495e',\n fontSize: '1.5rem',\n },\n display: {\n fontSize: '4rem',\n fontWeight: 'bold',\n fontVariantNumeric: 'tabular-nums',\n margin: '1.5rem 0',\n transition: 'color 0.3s ease',\n },\n finishedText: {\n color: '#27ae60',\n fontSize: '1.2rem',\n margin: '0.5rem 0',\n },\n buttonGroup: {\n display: 'flex',\n gap: '0.5rem',\n justifyContent: 'center',\n flexWrap: 'wrap',\n },\n button: {\n padding: '0.6rem 1.2rem',\n fontSize: '1rem',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n color: '#fff',\n fontWeight: '600',\n transition: 'opacity 0.2s ease, transform 0.1s ease',\n },\n startButton: { backgroundColor: '#27ae60' },\n pauseButton: { backgroundColor: '#f39c12' },\n resetButton: { backgroundColor: '#95a5a6' },\n};\n\nexport default CountdownTimer;\n```\n\n## Example Usage\n\n```jsx\nimport React from 'react';\nimport CountdownTimer from './CountdownTimer';\n\nfunction App() {\n const handleTimerComplete = () => {\n console.log('Timer finished!');\n alert('Countdown complete!');\n };\n\n return (\n <div>\n <h1>My App</h1>\n <CountdownTimer initialSeconds={120} onComplete={handleTimerComplete} />\n </div>\n );\n}\n\nexport default App;\n```\n\n## Features\n\n- **Configurable duration** via the `initialSeconds` prop\n- **Start/Pause/Reset controls** with proper disabled states\n- **MM:SS formatting** for readability\n- **Visual warning** when under 10 seconds (turns red)\n- **Completion callback** via the `onComplete` prop\n- **Memory-safe** with proper interval cleanup in `useEffect`\n- **Self-correcting timing** using functional state updates\n\n## Optional Enhancements\n\nIf you want to extend it further, you could add:\n\n```jsx\n// Custom time input\n<input\n type=\"number\"\n value={seconds}\n onChange={(e) => setSeconds(Math.max(0, parseInt(e.target.value) || 0))}\n disabled={isRunning}\n/>\n\n// Progress bar\n<progress value={initialSeconds - seconds} max={initialSeconds} />\n```\n\nThe component is fully self-contained, dependency-free, and works with any React 16.8+ project (hooks-based)."
1140
- }
1141
- ],
1142
- "rate-limit": [
1143
- {
1144
- "loc": 64,
1145
- "correct": true,
1146
- "timeSec": 15.458,
1147
- "usage": {
1148
- "inputTokens": 63,
1149
- "outputTokens": 1057
1150
- },
1151
- "response": "# Rate Limiting for FastAPI Endpoints\n\nHere are several approaches, from simple to production-ready:\n\n## Option 1: Using `slowapi` (Recommended - Easiest)\n\n`slowapi` is a port of Flask's `flask-limiter` library for FastAPI.\n\n**Install:**\n```bash\npip install slowapi\n```\n\n**Basic implementation:**\n\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\n\nlimiter = Limiter(key_func=get_remote_address)\napp = FastAPI()\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\n@app.get(\"/endpoint\")\n@limiter.limit(\"5/minute\")\ndef my_endpoint(request: Request):\n return {\"message\": \"Hello!\"}\n```\n\n**Important:** The `request: Request` parameter is required for `slowapi` to extract the client IP.\n\n## Option 2: Using `fastapi-limiter` (Redis-backed, async)\n\nBest for distributed/multi-instance deployments.\n\n**Install:**\n```bash\npip install fastapi-limiter[redis]\n```\n\n**Setup:**\n\n```python\nfrom fastapi import FastAPI, Depends\nfrom fastapi_limiter import FastAPILimiter\nfrom fastapi_limiter.decorator import rate_limit\nfrom contextlib import asynccontextmanager\nimport redis.asyncio as redis\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n redis_connection = redis.from_url(\"redis://localhost:6379\")\n await FastAPILimiter.init(redis_connection)\n yield\n await FastAPILimiter.close()\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/endpoint\")\n@rate_limit(\"5/minute\")\nasync def my_endpoint():\n return {\"message\": \"Hello!\"}\n```\n\n## Option 3: Custom Middleware (No Dependencies)\n\nIf you want full control without dependencies:\n\n```python\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\nfrom collections import defaultdict\nfrom time import time\nimport asyncio\n\napp = FastAPI()\n\n# In-memory storage (replace with Redis for production)\nrequest_counts = defaultdict(list)\nRATE_LIMIT = 5 # requests\nWINDOW = 60 # seconds\n\n@app.middleware(\"http\")\nasync def rate_limit_middleware(request: Request, call_next):\n if request.url.path != \"/endpoint\":\n return await call_next(request)\n \n client_ip = request.client.host\n now = time()\n \n # Clean old requests\n request_counts[client_ip] = [\n t for t in request_counts[client_ip] if now - t < WINDOW\n ]\n \n # Check limit\n if len(request_counts[client_ip]) >= RATE_LIMIT:\n return JSONResponse(\n status_code=429,\n content={\"error\": \"Too many requests. Try again later.\"},\n headers={\"Retry-After\": str(WINDOW)}\n )\n \n request_counts[client_ip].append(now)\n return await call_next(request)\n```\n\n## Option 4: By User/API Key (Authentication-aware)\n\nIf you want to rate limit by authenticated user instead of IP:\n\n```python\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom fastapi import Request, Depends\nfrom fastapi.security import APIKeyHeader\n\napi_key_header = APIKeyHeader(name=\"X-API-Key\")\n\ndef get_api_key(request: Request, api_key: str = Depends(api_key_header)):\n return api_key or get_remote_address(request)\n\nlimiter = Limiter(key_func=get_api_key)\n```\n\n## Rate Limit Formats\n\nBoth libraries support flexible limits:\n- `\"5/minute\"` - 5 per minute\n- `\"100/hour\"` - 100 per hour\n- `\"1000/day\"` - 1000 per day\n- `\"10/second\"` - 10 per second\n- `\"100/minute;1000/hour\"` - combined limits\n\n## Which Should You Choose?\n\n| Scenario | Recommendation |\n|----------|---------------|\n| Simple app, single instance | `slowapi` |\n| Multi-instance / production | `fastapi-limiter` (Redis) |\n| No dependencies, learning | Custom middleware |\n| Different limits per user tier | `slowapi` with custom key function |\n\n## Key Considerations\n\n1. **Reverse proxies**: If behind nginx/Cloudflare, use `request.headers.get(\"x-forwarded-for\")` instead of `request.client.host` (and configure `key_func` accordingly).\n2. **Storage**: In-memory won't work across multiple servers. Use Redis for production.\n3. **Return headers**: Include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `Retry-After` for good API hygiene.\n4. **Exempt paths**: Don't rate-limit health checks (`/health`, `/docs`).\n\nWant me to extend this with a specific use case (e.g., per-user tiers, sliding window, or token bucket algorithm)?"
1152
- },
1153
- {
1154
- "loc": 59,
1155
- "correct": true,
1156
- "timeSec": 14.89,
1157
- "usage": {
1158
- "inputTokens": 63,
1159
- "outputTokens": 917
1160
- },
1161
- "response": "# Rate Limiting for FastAPI\n\nHere are a few approaches, from simplest to most production-ready.\n\n## Option 1: Using `slowapi` (Recommended)\n\n`slowapi` wraps the `limits` library and is the most common FastAPI rate-limiting solution.\n\n```bash\npip install slowapi\n```\n\n```python\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\n\napp = FastAPI()\n\n# Key function: identifies the client (use IP, API key, user ID, etc.)\nlimiter = Limiter(key_func=get_remote_address)\napp.state.limiter = limiter\napp.add_middleware(SlowAPIMiddleware)\n\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=429,\n content={\"detail\": \"Too many requests. Please slow down.\"},\n headers={\"Retry-After\": str(exc.detail)},\n )\n\n@app.get(\"/api/resource\")\n@limiter.limit(\"5/minute\") # 5 requests per minute per IP\nasync def get_resource(request: Request):\n return {\"message\": \"Here's your data\"}\n```\n\n### Per-user / per-API-key limiting\n\nSwap `get_remote_address` for a custom function:\n\n```python\nfrom fastapi import Header\nfrom slowapi.util import get_remote_address\n\ndef api_key_or_ip(api_key: str = Header(default=\"\"), request: Request = None):\n return api_key if api_key else get_remote_address(request)\n\nlimiter = Limiter(key_func=api_key_or_ip)\n```\n\n## Option 2: Using a Token Bucket manually\n\nIf you want full control without external dependencies:\n\n```python\nimport time\nfrom collections import defaultdict\nfrom fastapi import FastAPI, Request, HTTPException\n\napp = FastAPI()\n\n# bucket: {client_id: (tokens, last_refill_time)}\nbuckets: dict[str, tuple[float, float]] = defaultdict(lambda: (5.0, time.time()))\n\nRATE = 5 # tokens\nPER_SECONDS = 60 # refill window\n\nasync def rate_limit(request: Request):\n client_id = request.client.host\n tokens, last = buckets[client_id]\n now = time.time()\n\n # Refill\n elapsed = now - last\n refill = (elapsed / PER_SECONDS) * RATE\n tokens = min(RATE, tokens + refill)\n\n if tokens < 1:\n retry_after = int((1 - tokens) / (RATE / PER_SECONDS))\n raise HTTPException(\n status_code=429,\n detail=\"Too many requests\",\n headers={\"Retry-After\": str(retry_after)},\n )\n\n buckets[client_id] = (tokens - 1, now)\n\n@app.get(\"/api/resource\", dependencies=[Depends(rate_limit)])\nasync def get_resource():\n return {\"message\": \"Here's your data\"}\n```\n\n⚠️ Caveat: in-memory state is per-process. Use Redis if you run multiple workers.\n\n## Option 3: Redis-backed (multi-worker / production)\n\nFor accurate limits across multiple app instances:\n\n```bash\npip install slowapi redis\n```\n\n```python\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\nlimiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379/0\",\n)\n```\n\nThe rest of the code is identical to Option 1.\n\n## Which to pick?\n\n| Scenario | Use |\n|---|---|\n| Single-process dev/small app | `slowapi` in-memory |\n| Multiple workers / production | `slowapi` + Redis |\n| Need custom logic (token bucket, dynamic limits) | manual or `limits` library directly |\n| Already have an API gateway (NGINX, Cloudflare, Kong) | rate-limit there instead |\n\nA couple of practical tips:\n\n- Apply the limit **per route**, not globally — login attempts and read endpoints need different limits.\n- Return a `Retry-After` header so well-behaved clients can back off intelligently.\n- Behind a reverse proxy, configure `key_func` to use `X-Forwarded-For` (and trust the proxy), or you'll rate-limit the proxy itself."
1162
- },
1163
- {
1164
- "loc": 44,
1165
- "correct": true,
1166
- "timeSec": 14.212,
1167
- "usage": {
1168
- "inputTokens": 63,
1169
- "outputTokens": 754
1170
- },
1171
- "response": "Here's how to add rate limiting to a FastAPI endpoint using the `slowapi` library (a maintained port of Flask-Limiter):\n\n## Installation\n\n```bash\npip install slowapi\n```\n\n## Basic Setup\n\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\n\napp = FastAPI()\n\n# Initialize the limiter\nlimiter = Limiter(key_func=get_remote_address)\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\n\n@app.get(\"/api/resource\")\n@limiter.limit(\"5/minute\") # 5 requests per minute per IP\nasync def my_endpoint(request: Request):\n return {\"message\": \"Success\"}\n\n\n@app.get(\"/api/strict\")\n@limiter.limit(\"1/second\")\nasync def strict_endpoint(request: Request):\n return {\"message\": \"Strict rate limit applied\"}\n```\n\n## Key Points\n\n- **`key_func=get_remote_address`** — keys limits by client IP. Swap this for a custom function if you want to limit by API key, user ID, etc.\n- **`request: Request`** — must be in the function signature so `slowapi` can access it\n- **Rate string format** — `\"5/minute\"`, `\"100/hour\"`, `\"10/second\"`, `\"1000/day\"`\n\n## Custom Key (e.g., by API key from header)\n\n```python\nfrom slowapi import Limiter\nfrom fastapi import Request\n\n\ndef api_key_or_ip(request: Request) -> str:\n return request.headers.get(\"X-API-Key\") or get_remote_address(request)\n\n\nlimiter = Limiter(key_func=api_key_or_ip)\n\n\n@app.post(\"/api/data\")\n@limiter.limit(\"100/hour\")\nasync def create_data(request: Request):\n return {\"status\": \"created\"}\n```\n\n## Custom Error Response\n\n```python\nfrom fastapi.responses import JSONResponse\n\n\ndef custom_rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(\n status_code=429,\n content={\n \"error\": \"Too many requests\",\n \"retry_after\": exc.detail,\n },\n )\n\n\napp.add_exception_handler(RateLimitExceeded, custom_rate_limit_handler)\n```\n\n## Rate Limiting the Entire App (vs. per-endpoint)\n\n```python\n@app.get(\"/anything\")\n@limiter.limit(\"10/minute\")\nasync def anything(request: Request):\n ...\n```\n\nYou can also apply limits globally or to routers, but per-endpoint via decorator is the most common pattern.\n\n## Production Tips\n\n- **Behind a proxy?** Make sure you trust `X-Forwarded-For` headers — configure your ASGI server (e.g., uvicorn with `--proxy-headers`) and use `slowapi`'s `get_remote_address` carefully, or pass `forwarded=True` options.\n- **Storage backend** — by default `slowapi` uses in-memory storage (single process). For multi-process/multi-server deployments, configure a Redis backend:\n\n ```python\n limiter = Limiter(\n key_func=get_remote_address,\n storage_uri=\"redis://localhost:6379\",\n )\n ```\n\n Install with `pip install slowapi[redis]` or `pip install redis`.\n\n- **Test it** — hit the endpoint 6 times in a minute and the 6th will return `429 Too Many Requests`.\n\nWant me to show a version that uses `fastapi-limiter` (async-native, Redis-only) instead, or one that applies limits based on authenticated user identity?"
1172
- }
1173
- ]
1174
- },
1175
- "lexis-two": {
1176
- "email": [
1177
- {
1178
- "loc": 13,
1179
- "correct": true,
1180
- "timeSec": 6.683,
1181
- "usage": {
1182
- "inputTokens": 1561,
1183
- "outputTokens": 232
1184
- },
1185
- "response": "```python\nimport re\n\ndef is_valid_email(s: str) -> bool:\n if not s or len(s) > 254:\n return False\n return bool(re.fullmatch(r\"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\", s))\n\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"a@b.co\")\n assert is_valid_email(\"first.last+tag@sub.example.com\")\n assert not is_valid_email(\"\")\n assert not is_valid_email(\"no-at-sign\")\n assert not is_valid_email(\"a@b\")\n assert not is_valid_email(\"a@b.1\")\n print(\"ok\")\n```\n\nStdlib `re.fullmatch` with one pattern. Rejects empty, caps at RFC's 254-char limit, and won't crash on whitespace or weird unicode the way `email.headerregistry.Address` will if you forget the empty-check. → Skipped: full RFC 5322 grammar (regex can't hold it anyway), add `email-validator` lib when you need deliverability checks, not just shape."
1186
- },
1187
- {
1188
- "loc": 5,
1189
- "correct": true,
1190
- "timeSec": 3.725,
1191
- "usage": {
1192
- "inputTokens": 153,
1193
- "outputTokens": 96
1194
- },
1195
- "response": "```python\nimport re\n\ndef is_valid_email(s: str) -> bool:\n if not s:\n return False\n return bool(re.fullmatch(r\"[^@\\s]+@[^@\\s]+\\.[^@\\s]+\", s))\n```\n\n→ Skipped: RFC 5322 compliance, IDN/punycode, deliverability checks, `email.headerregistry` round-trip. Add when the regex fails a real address or accepts a fake one in practice."
1196
- },
1197
- {
1198
- "loc": 9,
1199
- "correct": true,
1200
- "timeSec": 16.741,
1201
- "usage": {
1202
- "inputTokens": 14,
1203
- "outputTokens": 155
1204
- },
1205
- "response": "```python\nimport re\n\nEMAIL = re.compile(r\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z]{2,}$\")\n\ndef is_valid_email(s: str) -> bool:\n return bool(s) and bool(EMAIL.match(s))\n\n\nif __name__ == \"__main__\":\n assert is_valid_email(\"a@b.co\")\n assert not is_valid_email(\"a@b\")\n assert not is_valid_email(\"@b.co\")\n assert not is_valid_email(\"\")\n```\n\nStdlib `re` covers it. One regex, one check, one self-test. → skipped: MX lookup, IDN, length cap; add when you actually send mail and a false positive bites you."
1206
- }
1207
- ],
1208
- "debounce": [
1209
- {
1210
- "loc": 13,
1211
- "correct": true,
1212
- "timeSec": 3.905,
1213
- "usage": {
1214
- "inputTokens": 166,
1215
- "outputTokens": 128
1216
- },
1217
- "response": "```javascript\nfunction debounce(fn, wait) {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n}\n```\n\n```html\n<!-- wiring -->\n<script>\n const input = document.querySelector('#search');\n const search = debounce(q => fetch(`/api?q=${encodeURIComponent(q)}`), 300);\n input.addEventListener('input', e => search(e.target.value));\n</script>\n```\n\n→ skipped: cancel-in-flight + min-length guard, add when results flicker or you hit the server with `\"a\"`."
1218
- },
1219
- {
1220
- "loc": 7,
1221
- "correct": true,
1222
- "timeSec": 3.323,
1223
- "usage": {
1224
- "inputTokens": 14,
1225
- "outputTokens": 110
1226
- },
1227
- "response": "```javascript\nfunction debounce(fn, wait) {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n}\n\n// const input = document.querySelector('#search');\n// const onSearch = debounce(q => fetch(`/api?q=${encodeURIComponent(q)}`), 300);\n// input.addEventListener('input', e => onSearch(e.target.value));\n```\n→ skipped: cancel-token for in-flight requests, add when results can arrive out of order."
1228
- },
1229
- {
1230
- "loc": 10,
1231
- "correct": true,
1232
- "timeSec": 3.81,
1233
- "usage": {
1234
- "inputTokens": 14,
1235
- "outputTokens": 123
1236
- },
1237
- "response": "```javascript\nfunction debounce(fn, wait) {\n let t;\n return (...args) => {\n clearTimeout(t);\n t = setTimeout(() => fn(...args), wait);\n };\n}\n```\n\nWire it up:\n\n```javascript\nconst input = document.querySelector('#search');\nconst search = debounce((q) => fetch(`/api?q=${encodeURIComponent(q)}`), 300);\n\ninput.addEventListener('input', (e) => search(e.target.value));\n```\n\n→ skipped: cancel/leading/invoke-once options, add when you need a \"search now\" button."
1238
- }
1239
- ],
1240
- "csv-sum": [
1241
- {
1242
- "loc": 4,
1243
- "correct": true,
1244
- "timeSec": 2.187,
1245
- "usage": {
1246
- "inputTokens": 158,
1247
- "outputTokens": 41
1248
- },
1249
- "response": "```python\nimport csv\n\nwith open('sales.csv', newline='') as f:\n total = sum(float(row['amount']) for row in csv.DictReader(f))\n print(total)\n```"
1250
- },
1251
- {
1252
- "loc": 4,
1253
- "correct": true,
1254
- "timeSec": 2.563,
1255
- "usage": {
1256
- "inputTokens": 14,
1257
- "outputTokens": 60
1258
- },
1259
- "response": "```python\nimport csv\n\nwith open('sales.csv', newline='') as f:\n total = sum(float(row['amount']) for row in csv.DictReader(f))\n\nprint(total)\n```\n\n→ skipped: error handling, currency parsing, locale. Add when the CSV has weird money formats."
1260
- },
1261
- {
1262
- "loc": 3,
1263
- "correct": true,
1264
- "timeSec": 3.264,
1265
- "usage": {
1266
- "inputTokens": 14,
1267
- "outputTokens": 57
1268
- },
1269
- "response": "```python\nimport csv\n\nwith open(\"sales.csv\") as f:\n print(sum(float(row[\"amount\"]) for row in csv.DictReader(f)))\n```\n\nSkipped: error handling, empty-file guard, locale-aware parsing. Add when the input stops being well-formed CSV."
1270
- }
1271
- ],
1272
- "countdown": [
1273
- {
1274
- "loc": 13,
1275
- "correct": true,
1276
- "timeSec": 2.719,
1277
- "usage": {
1278
- "inputTokens": 161,
1279
- "outputTokens": 146
1280
- },
1281
- "response": "```jsx\nimport { useState, useEffect } from 'react'\n\nexport function Countdown({ seconds, onDone }) {\n const [remaining, setRemaining] = useState(seconds)\n\n useEffect(() => {\n if (remaining <= 0) return\n const id = setTimeout(() => setRemaining(r => r - 1), 1000)\n return () => clearTimeout(id)\n }, [remaining])\n\n useEffect(() => {\n if (remaining === 0) onDone?.()\n }, [remaining, onDone])\n\n return <span>{remaining}s</span>\n}\n```\n\n→ skipped: pause/resume, formatting (`mm:ss`), start controls, add when needed."
1282
- },
1283
- {
1284
- "loc": 18,
1285
- "correct": true,
1286
- "timeSec": 4.428,
1287
- "usage": {
1288
- "inputTokens": 14,
1289
- "outputTokens": 209
1290
- },
1291
- "response": "```jsx\nimport { useState, useEffect } from 'react';\n\nfunction Countdown({ seconds, onDone = () => {} }) {\n const [remaining, setRemaining] = useState(seconds);\n\n useEffect(() => {\n if (remaining <= 0) return;\n const id = setInterval(() => {\n setRemaining(r => {\n if (r <= 1) { clearInterval(id); onDone(); return 0; }\n return r - 1;\n });\n }, 1000);\n return () => clearInterval(id);\n }, [remaining, onDone]);\n\n const m = Math.floor(remaining / 60);\n const s = remaining % 60;\n return <span>{m}:{s.toString().padStart(2, '0')}</span>;\n}\n\nexport default Countdown;\n```\n\nskipped: pause/resume, prop, styling, add when you need them. Pass `seconds={120}`, optional `onDone` fires at 0."
1292
- },
1293
- {
1294
- "loc": 21,
1295
- "correct": true,
1296
- "timeSec": 6.394,
1297
- "usage": {
1298
- "inputTokens": 14,
1299
- "outputTokens": 210
1300
- },
1301
- "response": "```jsx\nimport { useState, useEffect, useRef } from \"react\";\n\nexport function Countdown({ seconds, onDone }) {\n const [remaining, setRemaining] = useState(seconds);\n const onDoneRef = useRef(onDone);\n onDoneRef.current = onDone;\n\n useEffect(() => {\n if (remaining <= 0) return;\n const id = setInterval(() => {\n setRemaining(r => {\n if (r <= 1) {\n clearInterval(id);\n onDoneRef.current?.();\n return 0;\n }\n return r - 1;\n });\n }, 1000);\n return () => clearInterval(id);\n }, [remaining <= 0]);\n\n return <span>{remaining}s</span>;\n}\n```\n\nUsage: `<Countdown seconds={60} onDone={() => console.log(\"done\")} />`\n\nSkipped: prop validation, pause/resume controls, formatting (mm:ss), styling. Add when you actually need them."
1302
- }
1303
- ],
1304
- "rate-limit": [
1305
- {
1306
- "loc": 15,
1307
- "correct": true,
1308
- "timeSec": 4.817,
1309
- "usage": {
1310
- "inputTokens": 157,
1311
- "outputTokens": 191
1312
- },
1313
- "response": "Using FastAPI's built-in `slowapi` won't add it — you already have the `limits` ecosystem via `slowapi`. One decorator.\n\n```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\nlimiter = Limiter(key_func=get_remote_address)\napp.state.limiter = limiter\n\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse({\"error\": \"rate_limited\"}, status_code=429)\n\n@app.get(\"/ping\")\n@limiter.limit(\"5/minute\")\nasync def ping(request: Request):\n return {\"ok\": True}\n```\n\n→ skipped: per-user auth-based key, Redis backend. Add when you have login or run >1 worker."
1314
- },
1315
- {
1316
- "loc": 10,
1317
- "correct": true,
1318
- "timeSec": 4.36,
1319
- "usage": {
1320
- "inputTokens": 14,
1321
- "outputTokens": 120
1322
- },
1323
- "response": "```python\nfrom fastapi import FastAPI, Request, HTTPException\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\n\napp = FastAPI()\nlimiter = Limiter(key_func=get_remote_address)\napp.state.limiter = limiter\n\n@app.get(\"/endpoint\")\n@limiter.limit(\"10/minute\")\nasync def endpoint(request: Request):\n return {\"ok\": True}\n```\n\nInstall: `pip install slowapi`\n\n→ skipped: per-user auth-based limits, in-memory backend is single-process (use Redis backend if you scale workers), add when multi-instance."
1324
- },
1325
- {
1326
- "loc": 16,
1327
- "correct": true,
1328
- "timeSec": 6.555,
1329
- "usage": {
1330
- "inputTokens": 14,
1331
- "outputTokens": 181
1332
- },
1333
- "response": "```python\nfrom fastapi import FastAPI, Request\nfrom slowapi import Limiter\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom fastapi.responses import JSONResponse\n\nlimiter = Limiter(key_func=get_remote_address)\napp = FastAPI()\napp.state.limiter = limiter\n\n@app.exception_handler(RateLimitExceeded)\nasync def rate_limit_handler(request: Request, exc: RateLimitExceeded):\n return JSONResponse(status_code=429, content={\"detail\": \"Too many requests\"})\n\n@app.get(\"/ping\")\n@limiter.limit(\"10/minute\")\nasync def ping(request: Request):\n return {\"pong\": True}\n```\n\n```bash\npip install slowapi\n```\n\nSkipped: per-user auth-based limits (uses IP), Redis backend (in-memory, single process). Add when you need multi-instance or user-aware limits."
1334
- }
1335
- ]
1336
- }
1337
- }
1338
- }
1339
- }