mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Improve validate solutions script & fix pre-commit error (#3253)
* Trying to time every solution * Proposal 2 for timing PE solutions: - Use pytest fixture along with --capture=no flag to print out the top DURATIONS slowest solution at the end of the test sessions. - Remove the print part and try ... except ... block from the test function. * Proposal 3 for timing PE solutions: Completely changed the way I was performing the tests. Instead of parametrizing the problem numbers and expected output, I will parametrize the solution file path. Steps: - Collect all the solution file paths - Convert the paths into a Python module - Call solution on the module - Assert the answer with the expected results For assertion, it was needed to convert the JSON list object to Python dictionary object which required changing the JSON file itself. * Add type hints for variables * Fix whitespace in single_qubit_measure
This commit is contained in:
parent
6e01004535
commit
29b32d3553
|
@ -16,10 +16,8 @@ jobs:
|
|||
script:
|
||||
- pytest --doctest-modules --durations=10 --cov-report=term-missing:skip-covered --cov=project_euler/ project_euler/
|
||||
- name: Project Euler Solution
|
||||
install:
|
||||
- pip install pytest-subtests
|
||||
script:
|
||||
- pytest --tb=short project_euler/validate_solutions.py
|
||||
- pytest --tb=short --durations=10 project_euler/validate_solutions.py
|
||||
after_success:
|
||||
- scripts/build_directory_md.py 2>&1 | tee DIRECTORY.md
|
||||
notifications:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@ import importlib.util
|
|||
import json
|
||||
import pathlib
|
||||
from types import ModuleType
|
||||
from typing import Generator
|
||||
from typing import Dict, List
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -13,42 +13,44 @@ PROJECT_EULER_ANSWERS_PATH = PROJECT_EULER_DIR_PATH.joinpath(
|
|||
)
|
||||
|
||||
with open(PROJECT_EULER_ANSWERS_PATH) as file_handle:
|
||||
PROBLEM_ANSWERS = json.load(file_handle)
|
||||
PROBLEM_ANSWERS: Dict[str, str] = json.load(file_handle)
|
||||
|
||||
|
||||
def generate_solution_modules(
|
||||
dir_path: pathlib.Path,
|
||||
) -> Generator[ModuleType, None, None]:
|
||||
# Iterating over every file or directory
|
||||
for file_path in dir_path.iterdir():
|
||||
if file_path.suffix != ".py" or file_path.name.startswith(("_", "test")):
|
||||
def convert_path_to_module(file_path: pathlib.Path) -> ModuleType:
|
||||
"""Converts a file path to a Python module"""
|
||||
spec = importlib.util.spec_from_file_location(file_path.name, str(file_path))
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def collect_solution_file_paths() -> List[pathlib.Path]:
|
||||
"""Collects all the solution file path in the Project Euler directory"""
|
||||
solution_file_paths = []
|
||||
for problem_dir_path in PROJECT_EULER_DIR_PATH.iterdir():
|
||||
if problem_dir_path.is_file() or problem_dir_path.name.startswith("_"):
|
||||
continue
|
||||
# Importing the source file through the given path
|
||||
# https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
|
||||
spec = importlib.util.spec_from_file_location(file_path.name, str(file_path))
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
yield module
|
||||
for file_path in problem_dir_path.iterdir():
|
||||
if file_path.suffix != ".py" or file_path.name.startswith(("_", "test")):
|
||||
continue
|
||||
solution_file_paths.append(file_path)
|
||||
return solution_file_paths
|
||||
|
||||
|
||||
@pytest.mark.parametrize("problem_number, expected", PROBLEM_ANSWERS)
|
||||
def test_project_euler(subtests, problem_number: int, expected: str):
|
||||
problem_dir = PROJECT_EULER_DIR_PATH.joinpath(f"problem_{problem_number:02}")
|
||||
# Check if the problem directory exist. If not, then skip.
|
||||
if problem_dir.is_dir():
|
||||
for solution_module in generate_solution_modules(problem_dir):
|
||||
# All the tests in a loop is considered as one test by pytest so, use
|
||||
# subtests to make sure all the subtests are considered as different.
|
||||
with subtests.test(
|
||||
msg=f"Problem {problem_number} tests", solution_module=solution_module
|
||||
):
|
||||
try:
|
||||
answer = str(solution_module.solution())
|
||||
assert answer == expected, f"Expected {expected} but got {answer}"
|
||||
except (AssertionError, AttributeError, TypeError) as err:
|
||||
print(
|
||||
f"problem_{problem_number:02}/{solution_module.__name__}: {err}"
|
||||
)
|
||||
raise
|
||||
else:
|
||||
pytest.skip(f"Solution {problem_number} does not exist yet.")
|
||||
def expand_parameters(param: pathlib.Path) -> str:
|
||||
"""Expand parameters in pytest parametrize"""
|
||||
project_dirname = param.parent.name
|
||||
solution_filename = param.name
|
||||
return f"{project_dirname}/{solution_filename}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"solution_path", collect_solution_file_paths(), ids=expand_parameters
|
||||
)
|
||||
def test_project_euler(solution_path: pathlib.Path):
|
||||
"""Testing for all Project Euler solutions"""
|
||||
problem_number: str = solution_path.parent.name[8:] # problem_[extract his part]
|
||||
expected: str = PROBLEM_ANSWERS[problem_number]
|
||||
solution_module = convert_path_to_module(solution_path)
|
||||
answer = str(solution_module.solution())
|
||||
assert answer == expected, f"Expected {expected} but got {answer}"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build a simple bare-minimum quantum circuit that starts with a single
|
||||
qubit (by default, in state 0), runs the experiment 1000 times, and
|
||||
Build a simple bare-minimum quantum circuit that starts with a single
|
||||
qubit (by default, in state 0), runs the experiment 1000 times, and
|
||||
finally prints the total count of the states finally observed.
|
||||
Qiskit Docs: https://qiskit.org/documentation/getting_started.html
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user