QPP - Quick Problem Platfrom
This is a lightweight, LeetCode-inspired problem-solving platform. You can run the server locally, contribute problems, and write unit tests.
Getting Started
Run the provided bash/batch script to start the server.
File Structure for Problems
Create a folder inside /problems/ named after your problem. Each folder must contain:
manifest.json# Dont worry you can change the info anytime to reloadtest.pydescription.md
Example manifest.json:
{
"title": "Title of the Problem",
"description": "Write a very short description here",
"description_md": "problems/problempath/description.md",
"difficulty": "easy || medium || hard",
"test_code": "problems/problempath/test.py"
}
This structure is mandatory but ensures the easiest workflow.
Writing Problem Descriptions
-
Use simple and easy-to-understand language. Avoid overly technical explanations.
-
Syntax:
- Normal Markdown
- Start headings with
##(looks cleaner than#) - Include cross-links to resources, e.g., W3Schools or Python Docs
-
Good formatting is always appreciated
Developing & Running Locally
To run the backend during development:
python -m flask --app ./src/app.py --host=0.0.0.0 --port=5000
For production testing:
Linux:
python -m gunicorn -w 4 -b 0.0.0.0:8000 src.app:app
Windows:
:: Create database folder if missing
md .\src\database
python -m waitress --listen=0.0.0.0:8000 src.app:app
Ensure all required packages are installed via
requirements.txt. Python is versatile enough for this small backend.
Migrating Legacy Code
When removing or refactoring legacy code:
- Check if the code is used anywhere; if critical, branch into a testing branch first.
- Ensure essential functionality is preserved.
Committing Changes
- Ensure your editor uses LF line endings (
\n) instead of CRLF. - To automatically fix CRLF on commit:
git config core.autocrlf input
git add --renormalize .
git commit -m "Major Change"
-
Recommended workflow:
- Fork
- Make changes
- Submit a PR
- Review & merge
Using WSL with VS Code for development is recommended for consistent line endings on Windows.
Writing Unit Tests
Follow this convention when writing unittests. Implement the function first, then write tests.
Example: Phone Number Validation
Function (phone_validation.py):
import re
def is_valid_phone_number(phone_number: str) -> bool:
"""Return True if phone_number matches '123-456-7890' format."""
return bool(re.search(r"^(\d{3}-){2}\d{4}$", phone_number))
Unit Test (test_phone_validation.py):
import unittest
from phone_validation import is_valid_phone_number
class TestPhoneNumberRegex(unittest.TestCase):
def test_if_valid(self):
test_cases = [
("123-456-7890", True),
("111-222-3333", True),
("abc-def-ghij", False),
("1234567890", False),
("123-45-67890", False),
("12-3456-7890", False),
("", False),
]
print("\nPHONE NUMBER VALIDATION TEST RESULTS")
for phone, expected in test_cases:
try:
actual = is_valid_phone_number(phone)
status = "✓ PASS" if actual == expected else "✗ FAIL"
print(f"{status} | Input: '{phone}' -> Got: {actual} | Expected: {expected}")
self.assertEqual(actual, expected)
except Exception as e:
print(f"✗ ERROR | Input: '{phone}' -> Exception: {e}")
raise
if __name__ == "__main__":
unittest.main(verbosity=2)
✅ Unit Test Guidelines
- Class Naming:
Test<FunctionOrModuleName> - Method Naming:
test_<what_is_being_tested> - Use tuples
(input, expected_output)for test cases - Include edge cases (empty strings, wrong formats)
- Print results clearly for easier debugging
- Catch exceptions and display failing input before raising