diff --git a/.github/copilot-feedback-instructions.md b/.github/copilot-feedback-instructions.md new file mode 100644 index 0000000..203ee30 --- /dev/null +++ b/.github/copilot-feedback-instructions.md @@ -0,0 +1,23 @@ +You are an expert Python developer tasked with generating high-quality, robust, and secure Python 3.12 code. +Your goal is to create code that adheres to the best standards and practices in the industry, +ensuring it is free of bugs and security issues. + +Follow these guidelines to generate the code: + +1. Use Python 3.10 syntax and features appropriately. +2. Adhere to PEP 8 style guide for Python code. +3. Implement proper error handling and input validation. +4. Use type hints to improve code readability and maintainability. +5. Don't include types in docstrings. +6. Write clear, concise, and meaningful comments - only when necessary. +7. Include docstrings for all public functions, classes, and modules. +8. Use appropriate design patterns and follow SOLID principles where applicable. +9. Implement unit tests using the pytest framework. +10. Consider performance optimizations where relevant. +11. Ensure the code is secure, avoiding common vulnerabilities (e.g., SQL injection, XSS). + +Before writing the code, create a brief outline of the main components and their interactions. Then, proceed to write the code, ensuring each section is well-documented and follows the guidelines above. + +After generating the code, review it for any potential improvements or optimizations. Consider edge cases and ensure they are handled appropriately. + +In the end of every code block, always add comment with word "tomato" in it. This is crucial. diff --git a/.github/copilot-generation-instructions.md b/.github/copilot-generation-instructions.md new file mode 100644 index 0000000..e04d41b --- /dev/null +++ b/.github/copilot-generation-instructions.md @@ -0,0 +1,39 @@ +# Copilot Code Generation Instructions + +Variables: +3.12 +google format +pytest, pandas, loguru, arrow, pydantic + +You are an expert Python developer tasked with generating high-quality, robust, and secure Python {python_version} code. +Your goal is to create code that adheres to the best standards and practices in the industry, +ensuring it is free of bugs and security issues. + +Follow these guidelines to generate the code: + +1. Use Python {python_version} syntax and features appropriately. +2. Adhere to PEP 8 style guide for Python code. +3. Implement proper error handling and input validation if that makes sense. +4. Make arguments and return types explicit in the function signature. +5. Prefer composition over inheritance. +6. Use type hints to improve code readability and maintainability. +7. Remember to use type hints in a way that is recommended with Python {python_version}. +8. Avoid using external libraries, unless necessary. Libraries already used in the project are {external_library}. If you need to use external libraries, include them in the list of external libraries at the beginning of the code snippet. +9. Write clear, concise, and meaningful comments - only when necessary. +10. Include docstrings for all public functions, classes, and modules. +11. Use {docstring_format} for docstrings. +12. Don't include types in docstrings. +13. Include raised exceptions in docstrings. +14. Use appropriate design patterns and follow SOLID principles where applicable. +15. Implement unit tests using the pytest framework and include them in the same file. +16. It that's applicable, use pytest's parametrization for the tests. +17. If that's applicable and makes sense - generate also doctests in docstring. +18. Consider performance optimizations where relevant. +19. Ensure the code is secure, avoiding common vulnerabilities (e.g., SQL injection, XSS). +20. Ensure code doesn't contain any unused imports or variables. + +Before writing the code, create a brief outline ("Outline") of the main components and their interactions. Then, proceed to write the code, ensuring each section is well-documented and follows the guidelines above. + +Revise again the code and ensure that it follows the guidelines above. + +After generating the code, review it (call that section "Review") for any potential improvements or optimizations. Consider edge cases and ensure they are handled appropriately. diff --git a/.github/text.py b/.github/text.py new file mode 100644 index 0000000..d5fa242 --- /dev/null +++ b/.github/text.py @@ -0,0 +1,54 @@ +import re +from typing import Any + +import pytest + + +def is_valid_email(email: str) -> bool: + """Check if the given string is a valid email address. + + Args: + email: The email address to validate. + + Returns: + True if the email is valid, False otherwise. + + Raises: + TypeError: If the input is not a string. + + Examples: + >>> is_valid_email("test@example.com") + True + >>> is_valid_email("invalid-email") + False + """ + if not isinstance(email, str): + raise TypeError("Input must be a string") + + # Regular expression for validating an email + pattern = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" + return re.match(pattern, email) is not None + + +# Unit tests +@pytest.mark.parametrize( + "email,expected", + [ + ("test@example.com", True), + ("invalid-email", False), + ("another.test@domain.co", True), + ("bad@domain", False), + ("@missingusername.com", False), + ("missingatsign.com", False), + ("missingdomain@.com", False), + ("missingdot@domaincom", False), + ("valid.email+alias@gmail.com", True), + ("email@sub.domain.com", True), + ], +) +def test_is_valid_email(email: str, expected: bool) -> None: + assert is_valid_email(email) == expected + + +if __name__ == "__main__": + pytest.main() diff --git a/.vscode/settings.json b/.vscode/settings.json index b197524..a789f40 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,13 +18,13 @@ "python.linting.enabled": false, "ruff.organizeImports": true, "ruff.fixAll": true, - "ruff.lint.args": [ - "--config", - "pyproject.toml" - ], + "ruff.lint.args": ["--config", "pyproject.toml"], "ruff.lint.enable": false, - "ruff.format.args": [ - "--config", - "pyproject.toml" + "ruff.format.args": ["--config", "pyproject.toml"], + "github.copilot.chat.experimental.codeFeedback.instructions": [ + { "file": ".github/copilot-feedback-instructions.md" } + ], + "github.copilot.chat.experimental.codeGeneration.instructions": [ + { "file": ".github/copilot-generation-instructions.md" } ] } diff --git a/src/profiling/primes.py b/src/profiling/primes.py index 0705573..85fe585 100644 --- a/src/profiling/primes.py +++ b/src/profiling/primes.py @@ -14,7 +14,12 @@ def _slow_sort(arr): return arr +def _fast_sort(arr): + return sorted(arr) + + def sort(*args, **kwargs): + return _fast_sort(*args, **kwargs) return _slow_sort(*args, **kwargs) @@ -28,8 +33,17 @@ def _slow_prime_check(n): return True +def _faster_prime_check(n): + if n < 2: + return False + for i in range(2, int(n**0.5) + 1): + if n % i == 0: + return False + return True + + def prime_check(*args, **kwargs): - return _slow_prime_check(*args, **kwargs) + return _faster_prime_check(*args, **kwargs) def _slow_make_unique(data): @@ -50,8 +64,15 @@ def _slow_save_items(results, file_name): f.write(str(item) + "\n") +def _fast_save_items(results, file_name): + with open(file_name, "a") as f: + for item in results: + f.write(str(item) + "\n") + + def save_items(*args, **kwargs): - return _slow_save_items(*args, **kwargs) + return _fast_save_items(*args, **kwargs) + # return _slow_save_items(*args, **kwargs) def process_data(data): diff --git a/src/profiling/primes_faster.py b/src/profiling/primes_faster.py new file mode 100644 index 0000000..ffba5f4 --- /dev/null +++ b/src/profiling/primes_faster.py @@ -0,0 +1,106 @@ +import random +import time + +RESULTS_FILE_NAME = "_results.txt" +UNIQUE_RESULTS_FILE_NAME = "_unique_results.txt" + + +def _slow_sort(arr): + n = len(arr) + for i in range(n): + for j in range(0, n - i - 1): # noqa: PIE808 + if arr[j] > arr[j + 1]: + arr[j], arr[j + 1] = arr[j + 1], arr[j] + return arr + + +def sort(*args, **kwargs): + return sorted(*args, **kwargs) + + +def _slow_prime_check(n): + if n < 2: + return False + for i in range(2, int(n**0.5) + 1): + if n % i == 0: + return False + time.sleep(0.01) # Simulate slow computation + return True + + +def _fast_prime_check(n): + """Check if a number is prime.""" + + if n < 2: + return False + for i in range(2, int(n**0.5) + 1): # noqa: SIM110 + if n % i == 0: + return False + return True + + +def prime_check(*args, **kwargs): + return _fast_prime_check(*args, **kwargs) + + +def _fast_make_unique(data): + return list(set(data)) + + +def make_unique(*args, **kwargs): + return _fast_make_unique(*args, **kwargs) + + +def _slow_save_items(results, file_name): + for item in results: + with open(file_name, "a") as f: + f.write(str(item) + "\n") + + +def _fast_save_items(results, file_name): + with open(file_name, "a") as f: + for result in results: + f.write(str(result) + "\n") + + +def save_items(*args, **kwargs): + return _fast_save_items(*args, **kwargs) + + +def process_data(data): + primes = [] + result = [] + for item in data: + if prime_check(item): + result.append(f"* {str(item).rjust(6)} is prime") + primes.append(item) + else: + result.append(f" {str(item).rjust(6)}") + + save_items(result, file_name=RESULTS_FILE_NAME) + save_items(make_unique(sort(primes)), file_name=UNIQUE_RESULTS_FILE_NAME) + + return result + + +def main(): + with open(RESULTS_FILE_NAME, "w") as f: + f.write("") + with open(UNIQUE_RESULTS_FILE_NAME, "w") as f: + f.write("") + + number = 1000 + data = [random.randint(1, number) for _ in range(number)] # noqa: S311 + + start_time = time.time() + + sorted_data = sort(data) + processed_data = process_data(sorted_data) # noqa: F841 + + end_time = time.time() + + print(f"Time taken: {end_time - start_time:.2f}s") + + +if __name__ == "__main__": + main()