Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions .internal/pre_commit_tools/notebook_uniformity.py
Original file line number Diff line number Diff line change
@@ -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))
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion algorithms/QML/qsvm/qsvm.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@
"id": "67",
"metadata": {},
"source": [
"## Reference\n",
"## References\n",
"\n",
"<a id='learning'>[1]</a> [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",
Expand Down
2 changes: 1 addition & 1 deletion algorithms/foundational/simon/simon.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@
"id": "45",
"metadata": {},
"source": [
"## Reference\n",
"## References\n",
"\n",
"<a id='original-paper'>[1]</a> [ 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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@
"id": "22",
"metadata": {},
"source": [
"## Reference\n",
"## References\n",
"<a id='gm-qaoa'>[1]</a>: [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)"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@
"id": "25",
"metadata": {},
"source": [
"### Reference\n",
"### References\n",
"\n",
"[1] https://arxiv.org/pdf/2101.10279\n",
"\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@
"id": "28",
"metadata": {},
"source": [
"## Reference\n",
"## References\n",
"<a id='OpPower'>[1]</a> [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"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@
"id": "20",
"metadata": {},
"source": [
"## Reference\n",
"## References\n",
"<a id='cvar'>[1]</a> [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)"
]
}
Expand Down
2 changes: 1 addition & 1 deletion applications/optimization/qaoa_in_qaoa/qaoa_in_qaoa.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@
"id": "22",
"metadata": {},
"source": [
"## Reference\n",
"## References\n",
"<a id='QOA'>[1]</a>: [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)"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
]
},
{
Expand Down Expand Up @@ -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)"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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."
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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()"
]
},
{
Expand Down Expand Up @@ -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()"
]
},
{
Expand Down Expand Up @@ -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()"
]
},
{
Expand Down Expand Up @@ -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()"
]
},
{
Expand Down
Loading
Loading