diff --git a/.internal/pre_commit_tools/notebook_uniformity.py b/.internal/pre_commit_tools/notebook_uniformity.py new file mode 100755 index 000000000..9e613c2ee --- /dev/null +++ b/.internal/pre_commit_tools/notebook_uniformity.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Pre-commit hook: auto-fix simple notebook-uniformity conventions. + +This is the enforcement counterpart to the read-only audit in +``.internal/notebook_uniformity_report.py`` — a home for the uniformity rules +that are simple and safe enough to fix automatically. + +Each rule edits the notebook in place when ``auto_fix`` is set and returns a +short message describing the violation (or ``NO_ERROR`` when the notebook already +conforms). Add a rule by writing such a function and appending it to +``UNIFORMITY_RULES``. + +Currently enforced: + - a references section heading is plural ("References", not "Reference"). +""" + +import re +import sys +from collections.abc import Callable, Iterable + +import nbformat + +NO_ERROR = "" + +# Edits `nb` in place when `auto_fix`; returns a message describing the +# violation/fix, or NO_ERROR when the notebook already conforms. +UniformityRule = Callable[[nbformat.NotebookNode, bool], str] + + +class Config: + # if True, the hook does nothing (safety switch) + IS_DISABLED: bool = False + # if True, fix notebooks in place; if False, only report violations + SHOULD_AUTO_FIX: bool = True + + +_SINGULAR_REFERENCES_HEADING = re.compile( + r"^(#{1,6}[ \t]+)([Rr])eference([ \t]*)$", re.MULTILINE +) + + +def references_heading_is_plural(nb: nbformat.NotebookNode, auto_fix: bool) -> str: + """A references section heading should read "References", never "Reference".""" + found: list[str] = [] + + def to_plural(match: re.Match) -> str: + found.append(match.group(0).strip()) + return f"{match.group(1)}{match.group(2)}eferences{match.group(3)}" + + for cell in nb.cells: + if cell.cell_type != "markdown": + continue + fixed_source = _SINGULAR_REFERENCES_HEADING.sub(to_plural, cell.source) + if auto_fix: + cell.source = fixed_source + + if not found: + return NO_ERROR + return f"singular heading {found} — use the plural 'References'" + + +_OLD_RESULT_PARSE = re.compile(r"\.result\(\)\s*\[\s*0\s*\]\s*\.value") + + +def results_use_result_value(nb: nbformat.NotebookNode, auto_fix: bool) -> str: + """Parse execution results via `.result_value()`, not `.result()[0].value`.""" + count = 0 + for cell in nb.cells: + if cell.cell_type != "code": + continue + if not (hits := len(_OLD_RESULT_PARSE.findall(cell.source))): + continue + count += hits + if auto_fix: + cell.source = _OLD_RESULT_PARSE.sub(".result_value()", cell.source) + if not count: + return NO_ERROR + return f".result()[0].value should be .result_value() ({count} occurrence(s))" + + +_CIRCUIT_SHOW_METHOD = re.compile(r"\b(qprog\w*|quantum_program\w*|qp)\.show\(\)") + + +def show_uses_function_form(nb: nbformat.NotebookNode, auto_fix: bool) -> str: + """Show a circuit with show(qprog), not the qprog.show() method form.""" + count = 0 + for cell in nb.cells: + if cell.cell_type != "code": + continue + if not (hits := _CIRCUIT_SHOW_METHOD.findall(cell.source)): + continue + count += len(hits) + if auto_fix: + cell.source = _CIRCUIT_SHOW_METHOD.sub(r"show(\1)", cell.source) + if not count: + return NO_ERROR + return f"qprog.show() should be show(qprog) ({count} occurrence(s))" + + +UNIFORMITY_RULES: list[UniformityRule] = [ + references_heading_is_plural, + results_use_result_value, + show_uses_function_form, +] + + +def main(full_file_paths: Iterable[str], auto_fix: bool) -> bool: + if Config.IS_DISABLED: + return True + result = True + for path in full_file_paths: + result &= check_notebook(path, auto_fix) + return result + + +def check_notebook(notebook_path: str, auto_fix: bool) -> bool: + nb = nbformat.read(notebook_path, as_version=4) + messages = [msg for rule in UNIFORMITY_RULES if (msg := rule(nb, auto_fix))] + if not messages: + return True + + if auto_fix: + nbformat.write(nb, notebook_path) + header = "auto-fixed (please `git add`)" if auto_fix else "violations" + print(f"{notebook_path}: {header}") + for message in messages: + print(f"\t{message}") + return False + + +if __name__ == "__main__": + sys.exit(not main(sys.argv[1:], Config.SHOULD_AUTO_FIX)) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b26052eca..68595bc1a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -117,3 +117,12 @@ repos: language: python files: \.ipynb$ require_serial: true + - id: notebook-uniformity + name: Enforce notebook uniformity + description: Auto-fix simple uniformity conventions (e.g. plural "References" heading) + entry: .internal/pre_commit_tools/notebook_uniformity.py + language: python + files: \.ipynb$ + additional_dependencies: + - "nbformat" + require_serial: true diff --git a/algorithms/QML/qsvm/qsvm.ipynb b/algorithms/QML/qsvm/qsvm.ipynb index 2d5271d27..59a6af4e6 100644 --- a/algorithms/QML/qsvm/qsvm.ipynb +++ b/algorithms/QML/qsvm/qsvm.ipynb @@ -1079,7 +1079,7 @@ "id": "67", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "\n", "[1] [Havlíček, V., Córcoles, A. D., Temme, K., Harrow, A. W., Kandala, A., Chow, J. M., & Gambetta, J. M. (2019). Supervised learning with quantum-enhanced feature spaces. Nature, 567(7747), 209-212.](https://arxiv.org/abs/1804.11326)\n", "\n", diff --git a/algorithms/foundational/simon/simon.ipynb b/algorithms/foundational/simon/simon.ipynb index 5cdd24aab..2fce30e18 100644 --- a/algorithms/foundational/simon/simon.ipynb +++ b/algorithms/foundational/simon/simon.ipynb @@ -746,7 +746,7 @@ "id": "45", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "\n", "[1] [ Simon, D. R. (1997). On the power of quantum computation. SIAM journal on computing, 26(5), 1474-1483.](https://epubs.siam.org/doi/abs/10.1137/S0097539796298637)\n", "\n", diff --git a/algorithms/quantum_primitives/hadamard_test/hadamard_test.ipynb b/algorithms/quantum_primitives/hadamard_test/hadamard_test.ipynb index dd9fdca43..0af68ab7f 100644 --- a/algorithms/quantum_primitives/hadamard_test/hadamard_test.ipynb +++ b/algorithms/quantum_primitives/hadamard_test/hadamard_test.ipynb @@ -283,7 +283,7 @@ "qprog_with_execution_preferences = synthesize(qmod_with_execution_preferences)\n", "job = execute(qprog_with_execution_preferences)\n", "\n", - "results = job.result()[0].value.counts\n", + "results = job.result_value().counts\n", "P_0 = (results[\"0\"]) / tot_num_shots\n", "P_1 = (results[\"1\"]) / tot_num_shots\n", "print(r\"P_0={}\".format(P_0))\n", diff --git a/algorithms/search_and_optimization/grover_mixer_qaoa/gm_qaoa.ipynb b/algorithms/search_and_optimization/grover_mixer_qaoa/gm_qaoa.ipynb index 03653509b..d8fad962f 100644 --- a/algorithms/search_and_optimization/grover_mixer_qaoa/gm_qaoa.ipynb +++ b/algorithms/search_and_optimization/grover_mixer_qaoa/gm_qaoa.ipynb @@ -652,7 +652,7 @@ "id": "22", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "[1]: [A. Bärtschi, S. Eidenbenz. \"Grover Mixers for QAOA: Shifting Complexity from Mixer Design to State Preparation\" \tarXiv:2006.00354 (2020).](https://arxiv.org/abs/2006.00354)" ] } diff --git a/applications/chemistry/protein_folding/protein_folding_with_quantum_walk/qfold.ipynb b/applications/chemistry/protein_folding/protein_folding_with_quantum_walk/qfold.ipynb index 1d171246a..6a5624223 100644 --- a/applications/chemistry/protein_folding/protein_folding_with_quantum_walk/qfold.ipynb +++ b/applications/chemistry/protein_folding/protein_folding_with_quantum_walk/qfold.ipynb @@ -587,7 +587,7 @@ "id": "25", "metadata": {}, "source": [ - "### Reference\n", + "### References\n", "\n", "[1] https://arxiv.org/pdf/2101.10279\n", "\n", diff --git a/applications/finance/portfolio_optimization_hhl/HHL_portfolio.ipynb b/applications/finance/portfolio_optimization_hhl/HHL_portfolio.ipynb index 38ccf4f2b..a60c918c4 100644 --- a/applications/finance/portfolio_optimization_hhl/HHL_portfolio.ipynb +++ b/applications/finance/portfolio_optimization_hhl/HHL_portfolio.ipynb @@ -2632,7 +2632,7 @@ "id": "47", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "\n", "- [1] P. Rebentrost and S. Lloyd, “Quantum computational finance: quantum algorithm for portfolio optimization“, https://arxiv.org/abs/1811.03975\n", "- [2] 7-3. Portfolio optimization using HHL algorithm: https://dojo.qulacs.org/en/latest/notebooks/7.3_application_of_HHL_algorithm.html" diff --git a/applications/image_processing/quantum_hadamard_edge_detection/quantum_image_edge_detection.ipynb b/applications/image_processing/quantum_hadamard_edge_detection/quantum_image_edge_detection.ipynb index 76780edac..4d35be8dd 100644 --- a/applications/image_processing/quantum_hadamard_edge_detection/quantum_image_edge_detection.ipynb +++ b/applications/image_processing/quantum_hadamard_edge_detection/quantum_image_edge_detection.ipynb @@ -521,7 +521,7 @@ "qprog = set_quantum_program_execution_preferences(\n", " qprog, preferences=ExecutionPreferences(num_shots=200000)\n", ")\n", - "res = execute(qprog).result()[0].value\n", + "res = execute(qprog).result_value()\n", "res.dataframe" ] }, diff --git a/applications/optimization/electric_grid_optimization/electric_grid_optimization.ipynb b/applications/optimization/electric_grid_optimization/electric_grid_optimization.ipynb index cd15c133c..9d4663536 100644 --- a/applications/optimization/electric_grid_optimization/electric_grid_optimization.ipynb +++ b/applications/optimization/electric_grid_optimization/electric_grid_optimization.ipynb @@ -853,7 +853,7 @@ "id": "28", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "[1] [O. V. Shemelova, E. V. Yakovleva, T. G. Makuseva, I. I. Eremina, and O. N. Makusev. (2019). Solving optimization problems when designing power supply circuits. E3S Web of Conferences 124, 04011.](https://www.e3s-conferences.org/articles/e3sconf/pdf/2019/50/e3sconf_ses18_04011.pdf)\n" ] } diff --git a/applications/optimization/kidney_exchange/kidney_exchange_problem.ipynb b/applications/optimization/kidney_exchange/kidney_exchange_problem.ipynb index 72f431912..207902bea 100644 --- a/applications/optimization/kidney_exchange/kidney_exchange_problem.ipynb +++ b/applications/optimization/kidney_exchange/kidney_exchange_problem.ipynb @@ -624,7 +624,7 @@ "id": "20", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "[1] [Barkoutsos, P. K., Nannicini, G., Robert, A., Tavernelli, I., & Woerner, S. (2020). Improving variational quantum optimization using CVaR. Quantum, 4, 256.](https://arxiv.org/abs/1907.04769)" ] } diff --git a/applications/optimization/qaoa_in_qaoa/qaoa_in_qaoa.ipynb b/applications/optimization/qaoa_in_qaoa/qaoa_in_qaoa.ipynb index 03988bf33..0b3a5c3c6 100644 --- a/applications/optimization/qaoa_in_qaoa/qaoa_in_qaoa.ipynb +++ b/applications/optimization/qaoa_in_qaoa/qaoa_in_qaoa.ipynb @@ -210,7 +210,7 @@ " subgraph_res = execute(qprog)\n", " ordered_solution = get_optimization_solution_from_pyo(\n", " pyo_model=pyo_model,\n", - " vqe_result=subgraph_res.result()[0].value,\n", + " vqe_result=subgraph_res.result_value(),\n", " penalty_energy=qaoa_config.penalty_energy,\n", " )\n", " # sort by cost and then by count\n", diff --git a/applications/optimization/robust_posture_optimization/robust_posture_optimization.ipynb b/applications/optimization/robust_posture_optimization/robust_posture_optimization.ipynb index b9d7fe082..1f99bcfa6 100644 --- a/applications/optimization/robust_posture_optimization/robust_posture_optimization.ipynb +++ b/applications/optimization/robust_posture_optimization/robust_posture_optimization.ipynb @@ -420,7 +420,7 @@ "id": "22", "metadata": {}, "source": [ - "## Reference\n", + "## References\n", "[1]: [T. Otani, A. Takanishi, N. Hara, Y.Takita and K.Kimura. \"Quantum computation for robot posture optimization.\" Scientific Reports volume 15, 28508 (2025).](https://www.nature.com/articles/s41598-025-12109-0)" ] } diff --git a/community/basic_examples/hw_aware_synthesis/hw_aware_synthesis.ipynb b/community/basic_examples/hw_aware_synthesis/hw_aware_synthesis.ipynb index ca44f270b..0a06551c5 100644 --- a/community/basic_examples/hw_aware_synthesis/hw_aware_synthesis.ipynb +++ b/community/basic_examples/hw_aware_synthesis/hw_aware_synthesis.ipynb @@ -463,7 +463,7 @@ "print(\n", " f\"Synthesized MCX cx-count for grid connectivity is {qprog_grid.transpiled_circuit.count_ops['cx']}\"\n", ")\n", - "qprog_grid.show()" + "show(qprog_grid)" ] }, { @@ -528,7 +528,7 @@ "print(\n", " f\"Synthesized MCX cx-count for star connectivity is {qprog.transpiled_circuit.count_ops['cx']}\"\n", ")\n", - "qprog.show()" + "show(qprog)" ] }, { diff --git a/community/paper_implementation_project/Block_encoding-ND_Laplacian/ND_Laplacian_BE.ipynb b/community/paper_implementation_project/Block_encoding-ND_Laplacian/ND_Laplacian_BE.ipynb index 1b66363f0..9052fbf8d 100644 --- a/community/paper_implementation_project/Block_encoding-ND_Laplacian/ND_Laplacian_BE.ipynb +++ b/community/paper_implementation_project/Block_encoding-ND_Laplacian/ND_Laplacian_BE.ipynb @@ -520,7 +520,7 @@ "print(\"Gate counts:\", qprog.transpiled_circuit.count_ops)\n", "\n", "job = execute(qprog)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "# Post processing\n", "reduced_state = get_projected_state_vector(results, \"j\", {\"l\": 0})\n", @@ -746,7 +746,7 @@ "print(\"Gate counts:\", qprog.transpiled_circuit.count_ops)\n", "\n", "job = execute(qprog)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "# Post processing\n", "reduced_state = get_projected_state_vector(results, \"j\", {\"l\": 0, \"k\": 0})\n", @@ -788,7 +788,7 @@ "id": "14", "metadata": {}, "source": [ - "### Reference\n", + "### References\n", "\n", "- Sturm, A., & Schillo, N. (2025). Efficient and Explicit Block Encoding of Finite Difference Discretizations of the Laplacian. arXiv preprint https://arxiv.org/abs/2509.02429" ] diff --git a/community/paper_implementation_project/block_encoding/select_structures_BE.ipynb b/community/paper_implementation_project/block_encoding/select_structures_BE.ipynb index b1056b988..f40891048 100644 --- a/community/paper_implementation_project/block_encoding/select_structures_BE.ipynb +++ b/community/paper_implementation_project/block_encoding/select_structures_BE.ipynb @@ -586,7 +586,7 @@ ], "source": [ "job = execute(qprog)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "\n", "reduced_state = get_projected_state_vector(results, \"j\", {\"s\": 0, \"data\": 0})\n", @@ -868,7 +868,7 @@ "\n", "\n", "job = execute(qprog)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "\n", "reduced_state = get_projected_state_vector(results, \"j\", {\"s\": 0, \"data\": 0, \"dlt\": 0})\n", @@ -1114,7 +1114,7 @@ "print(\"The circuit depth is:\", circuit_depth)\n", "\n", "job = execute(qprog)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "reduced_state = get_projected_state_vector(results, \"j\", {\"s\": 0, \"data\": 0})\n", "print(\"The reduced state vector for j when s=0, data=0 is:\")\n", @@ -1418,7 +1418,7 @@ "print(\"The circuit depth is:\", circuit_depth)\n", "\n", "job = execute(qprog)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "# Post processing\n", "reduced_state = get_projected_state_vector(results, \"j\", {\"s\": 0, \"data\": 0, \"dlt\": 0})\n", @@ -1447,7 +1447,7 @@ "id": "32", "metadata": {}, "source": [ - "### Reference\n", + "### References\n", "\n", "- Sunderhauf, C., Campbell, E., Camps, J.: Block-encoding structured matrices fordata input in quantum computing. Quantum 8, 1226 (2024) https://doi.org/10.22331/q-2024-01-11-1226." ] diff --git a/community/paper_implementation_project/explicit_quantum_circuits_for_block_encoding/quantum_walks_via_efficient_blockencoding.ipynb b/community/paper_implementation_project/explicit_quantum_circuits_for_block_encoding/quantum_walks_via_efficient_blockencoding.ipynb index b83036c1f..f63910fc1 100644 --- a/community/paper_implementation_project/explicit_quantum_circuits_for_block_encoding/quantum_walks_via_efficient_blockencoding.ipynb +++ b/community/paper_implementation_project/explicit_quantum_circuits_for_block_encoding/quantum_walks_via_efficient_blockencoding.ipynb @@ -508,7 +508,7 @@ "show(qprog_ebt)\n", "\n", "job = execute(qprog_ebt)\n", - "results = job.result()[0].value\n", + "results = job.result_value()\n", "\n", "# Post-processing to get the reduced state vector of the register j when rest of the registers are in zero state\n", "reduced_state = get_projected_state_vector(\n", @@ -1099,7 +1099,7 @@ "print(\"The circuit depth is:\", circuit_depth)\n", "\n", "job = execute(qprog_sbc)\n", - "results = job.result()[0].value" + "results = job.result_value()" ] }, { @@ -1254,7 +1254,7 @@ "print(\"The circuit depth is:\", circuit_depth)\n", "\n", "job = execute(qprog_sbc)\n", - "results = job.result()[0].value" + "results = job.result_value()" ] }, { @@ -1560,7 +1560,7 @@ "print(\"The circuit depth is:\", circuit_depth)\n", "\n", "job = execute(qprog_nmd)\n", - "results = job.result()[0].value" + "results = job.result_value()" ] }, { @@ -1672,7 +1672,7 @@ "print(\"The circuit depth is:\", circuit_depth)\n", "\n", "job = execute(qprog_md)\n", - "results = job.result()[0].value" + "results = job.result_value()" ] }, { diff --git a/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb b/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb index 8a84367de..975f883e0 100644 --- a/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb +++ b/community/paper_implementation_project/quantum_compression_algorithm_for_symmetric_states/quantum_compression_algorithm_for_symmetric_states.ipynb @@ -469,7 +469,7 @@ "\n", "quantum_program1 = synthesize(main)\n", "job1 = execute(quantum_program1)\n", - "results1 = job1.result()[0].value.parsed_counts\n", + "results1 = job1.result_value().parsed_counts\n", "show(quantum_program1)\n", "results1" ] @@ -525,7 +525,7 @@ "model2 = create_model(main)\n", "quantum_program2 = synthesize(model2)\n", "job2 = execute(quantum_program2)\n", - "results2 = job2.result()[0].value.parsed_counts\n", + "results2 = job2.result_value().parsed_counts\n", "show(quantum_program2)\n", "results2" ] @@ -589,7 +589,7 @@ "model3 = create_model(main)\n", "quantum_program3 = synthesize(model3)\n", "job3 = execute(quantum_program3)\n", - "results3 = job3.result()[0].value.parsed_counts\n", + "results3 = job3.result_value().parsed_counts\n", "show(quantum_program3)\n", "results3" ] diff --git a/tutorials/basic_tutorials/qmci_pi_estimation/qmci_pi_estimation.ipynb b/tutorials/basic_tutorials/qmci_pi_estimation/qmci_pi_estimation.ipynb index b65243f9c..040ed796f 100644 --- a/tutorials/basic_tutorials/qmci_pi_estimation/qmci_pi_estimation.ipynb +++ b/tutorials/basic_tutorials/qmci_pi_estimation/qmci_pi_estimation.ipynb @@ -672,7 +672,7 @@ "id": "29", "metadata": {}, "source": [ - "## Reference \n", + "## References \n", "[1] [Quantum circuit to estimate pi using quantum amplitude estimation](https://arxiv.org/abs/2008.02623)\n", "\n", "[2] [Iterative Quantum Amplitude Estimation, Granko et al., 2019](https://www.nature.com/articles/s41534-021-00379-1)" diff --git a/tutorials/basic_tutorials/quantum_primitives/hadamard_test_tutorial/hadamard_test_tutorial.ipynb b/tutorials/basic_tutorials/quantum_primitives/hadamard_test_tutorial/hadamard_test_tutorial.ipynb index d7f39be24..6dcad0bed 100644 --- a/tutorials/basic_tutorials/quantum_primitives/hadamard_test_tutorial/hadamard_test_tutorial.ipynb +++ b/tutorials/basic_tutorials/quantum_primitives/hadamard_test_tutorial/hadamard_test_tutorial.ipynb @@ -283,7 +283,7 @@ "qprog_with_execution_preferences = synthesize(qmod_with_execution_preferences)\n", "job = execute(qprog_with_execution_preferences)\n", "\n", - "results = job.result()[0].value.counts\n", + "results = job.result_value().counts\n", "P_0 = (results[\"0\"]) / tot_num_shots\n", "P_1 = (results[\"1\"]) / tot_num_shots\n", "print(r\"P_0={}\".format(P_0))\n",