166 lines
4.1 KiB
Markdown
166 lines
4.1 KiB
Markdown
# 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 reload
|
|
* `test.py`
|
|
* `description.md`
|
|
|
|
**Example `manifest.json`:**
|
|
|
|
```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](https://www.w3schools.com/) or [Python Docs](https://docs.python.org/3/)
|
|
* Good formatting is always appreciated
|
|
|
|
---
|
|
|
|
## Developing & Running Locally
|
|
|
|
To run the backend during development:
|
|
|
|
```bash
|
|
python -m flask --app ./src/app.py --host=0.0.0.0 --port=5000
|
|
```
|
|
|
|
For production testing:
|
|
|
|
**Linux:**
|
|
|
|
```bash
|
|
python -m gunicorn -w 4 -b 0.0.0.0:8000 src.app:app
|
|
```
|
|
|
|
**Windows:**
|
|
|
|
```bat
|
|
:: 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:
|
|
|
|
1. Check if the code is used anywhere; if critical, branch into a testing branch first.
|
|
2. Ensure essential functionality is preserved.
|
|
|
|
---
|
|
|
|
## Committing Changes
|
|
|
|
* Ensure your editor uses **LF** line endings (`\n`) instead of CRLF.
|
|
* To automatically fix CRLF on commit:
|
|
|
|
```bash
|
|
git config core.autocrlf input
|
|
git add --renormalize .
|
|
git commit -m "Major Change"
|
|
```
|
|
|
|
* Recommended workflow:
|
|
|
|
1. Fork
|
|
2. Make changes
|
|
3. Submit a PR
|
|
4. 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`):**
|
|
|
|
```python
|
|
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`):**
|
|
|
|
```python
|
|
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
|
|
|
|
1. **Class Naming:** `Test<FunctionOrModuleName>`
|
|
2. **Method Naming:** `test_<what_is_being_tested>`
|
|
3. **Use tuples** `(input, expected_output)` for test cases
|
|
4. Include **edge cases** (empty strings, wrong formats)
|
|
5. **Print results** clearly for easier debugging
|
|
6. **Catch exceptions** and display failing input before raising
|