Skip to content

Commit 5787ac4

Browse files
Merge branch 'master' into improve-maths-check-polygon
2 parents 5f53d14 + 6883049 commit 5787ac4

394 files changed

Lines changed: 15816 additions & 2114 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ This is **Devcontainer** configuration to provide a consistent development envir
1313

1414
## Usage
1515

16-
1. Install [**Docker** ](https://www.docker.com/get-started/) and [**Visual Studio Code**](https://code.visualstudio.com/)
16+
1. Install [**Docker**](https://www.docker.com/get-started/) and [**Visual Studio Code**](https://code.visualstudio.com/)
1717
2. Install the **Remote - Containers** extension in VS Code
1818

1919
- Do `CTRL+P`, paste this command and press `Enter`
2020

2121
```shell
2222
ext install ms-vscode-remote.remote-containers
2323
```
24+
2425
3. Open this repository in VS Code
2526
4. When prompted, click **"Reopen in Container"**
2627
5. Wait for the environment to build and initialize

.github/dependabot.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ updates:
66
directory: "/"
77
schedule:
88
interval: "daily"
9+
cooldown:
10+
default-days: 7

.github/pull_request_template.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
### Describe your change:
2-
3-
1+
### Describe your change
42

53
* [ ] Add an algorithm?
64
* [ ] Fix a bug or typo in an existing algorithm?
75
* [ ] Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
86
* [ ] Documentation change?
97

10-
### Checklist:
8+
### Checklist
9+
1110
* [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md).
1211
* [ ] This pull request is all my own work -- I have not plagiarized.
1312
* [ ] I know that pull requests will not be merged if they fail the automated tests.
14-
* [ ] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
13+
* [ ] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
1514
* [ ] All new Python files are placed inside an existing directory.
1615
* [ ] All filenames are in all lowercase characters with no spaces or dashes.
1716
* [ ] All functions and variable names follow Python naming conventions.
1817
* [ ] All function parameters and return values are annotated with Python [type hints](https://docs.python.org/3/library/typing.html).
1918
* [ ] All functions have [doctests](https://docs.python.org/3/library/doctest.html) that pass the automated testing.
2019
* [ ] All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
21-
* [ ] If this pull request resolves one or more open issues then the description above includes the issue number(s) with a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue): "Fixes #ISSUE-NUMBER".
20+
* [ ] If this pull request resolves one or more open issues, then the description above includes the issue number(s) with a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue): "Fixes #ISSUE-NUMBER".

.github/skills/code-review/SKILL.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ suggest the fix — never just "rejected".
3333
- [ ] Descriptive variable and function names (no single letters where a word helps).
3434
- [ ] Code is formatted and lint-clean (`ruff`, `pre-commit`).
3535

36+
> **Optional hint:** When a PR hand-writes a simple class that is mostly a
37+
> bundle of fields (a manual `__init__` plus `__repr__`/`__eq__`), it is worth
38+
> **suggesting** `from typing import NamedTuple` or
39+
> `from dataclasses import dataclass` where they would simplify the code. These
40+
> are underutilized tools that our contributors would benefit from using where
41+
> they make sense. Offer it as an optional improvement, not a blocker — do not
42+
> request changes solely because a class was written the longhand way.
43+
3644
#### When a PR fails `ruff check`
3745

3846
Don't just report the failure — try the mechanical fixes and recommend the one
@@ -61,7 +69,7 @@ flagged. Also, paste the concrete command you ran.
6169

6270
Emit exactly these headings so reviews are comparable and easy to automate:
6371

64-
```
72+
```text
6573
### Is this an algorithm? — <yes/no + one-line why>
6674
### Duplicate / prior-art check — <#NNNN | none found>
6775
### Coding style — <pass | issues: …>

.github/skills/new-pull-request/SKILL.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ clear, kind, tested, type-hinted, mergeable contribution.
1010
Make sure that the local `master` branch is synced with `upstream/master` before
1111
creating a new pull request.
1212

13-
Create a new clearly named branch for the pull request. Pull request changes must
13+
Create a new clearly named branch for the pull request. Pull request changes must
1414
not be made or submitted on the `master` branch.
1515

1616
Never hand-edit or revert the `uv.lock` file. If you add a legitimate
@@ -19,7 +19,13 @@ hand. A hand-modified `uv.lock` makes the `algorithms-keeper` bot close the pull
1919
request as invalid, and even a repo maintainer cannot undo that.
2020

2121
Always check at least one Markdown checkbox in the pull request description (the "Describe your change" section), or the
22-
`algorithms-keeper` bot will close the pull request as invalid. Any repo maintainer can undo this if you @mention them on the closed pull request.
22+
`algorithms-keeper` bot will close the pull request as invalid — and it does
23+
this *before* a human reads the PR, so a genuinely good change gets closed for a
24+
formatting reason. This applies to **every** pull request, including CI, docs,
25+
and tooling changes that are not algorithms: tick the boxes that genuinely apply
26+
so the body is never submitted with all boxes empty. Any repo maintainer can
27+
undo this if you @mention them on the closed pull request, but re-opening is
28+
often unreliable, so it is far better to get it right the first time.
2329

2430
### 1. Before contributing / Is this an algorithm?
2531

@@ -41,6 +47,11 @@ Always check at least one Markdown checkbox in the pull request description (the
4147
- [ ] Public functions/classes have **type hints**.
4248
- [ ] Public functions have **doctests that actually pass**.
4349
- [ ] Descriptive variable and function names (no single letters where a word helps).
50+
- [ ] For a simple class that is mostly a bundle of fields, **consider**
51+
`from typing import NamedTuple` or `from dataclasses import dataclass`
52+
instead of a hand-written `__init__`/`__repr__`/`__eq__`. These are
53+
underutilized tools that make simple classes shorter and clearer — use
54+
them where they genuinely simplify the code, not everywhere.
4455
- [ ] Code is formatted and lint-clean (`ruff`, `pre-commit`).
4556
- [ ] `DIRECTORY.md` and `README.md` are **not hand-edited** — the
4657
`algorithms-keeper` bot regenerates them automatically after merge.
@@ -50,3 +61,15 @@ Always check at least one Markdown checkbox in the pull request description (the
5061
- [ ] At least one **Wikipedia (or equivalent) URL** documenting the algorithm.
5162
- [ ] Docstring explains what the function does and its parameters/returns.
5263
- [ ] No unnecessary third-party dependencies.
64+
65+
## Before you click "Create pull request"
66+
67+
This is the final gate. Do not open the pull request until every item here is true:
68+
69+
- [ ] At least one Markdown checkbox in the PR description is checked. **Verify
70+
this by re-reading the rendered body** — if every box is still `- [ ]`, the
71+
`algorithms-keeper` bot will auto-close the PR before any human sees it.
72+
Check the boxes that genuinely apply to this change; never submit an
73+
all-empty checklist, even for a CI, docs, or tooling PR.
74+
- [ ] The branch is not `master`, and `master` is synced with `upstream/master`.
75+
- [ ] `uv.lock` was not hand-edited.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Skill: Review an open issue for TheAlgorithms/Python
2+
3+
Triage an open issue — most often one carrying the `bug` label — **together with
4+
every pull request attached to it**, and produce a verdict a maintainer can act on
5+
without re-doing the work. The goal is a review that any triager (human or AI) can
6+
run the same way every time, and that ends in an explicit list of `Closes #NNNNN`
7+
lines the maintainer can paste into a merge commit.
8+
9+
This repo exists to **teach visitors to fix bugs by doing**. So the default is to
10+
merge adequate existing contributor work, not to open a fresh PR that races them.
11+
Only open your own PR when no attached PR adequately solves the issue.
12+
13+
## How to run this skill
14+
15+
### 1. Reproduce before you trust the report
16+
17+
- Check out current `master` and actually **run the failing case** from the issue.
18+
- If it reproduces, say so and paste the minimal reproducer (inputs → observed
19+
output, e.g. `nan` + a `RuntimeWarning`).
20+
- If you **cannot** confirm it locally — an optional dependency isn't installed,
21+
the failure needs an external service, the report is too vague — **say that
22+
explicitly rather than guessing.** "Not reproducible in a vanilla checkout"
23+
is a real, useful verdict.
24+
25+
### 2. Classify the issue
26+
27+
Sort each issue into one bucket and act accordingly:
28+
29+
- **Confirmed bug with an adequate open PR** → recommend the specific PR to merge.
30+
- **Confirmed bug, no adequate PR** → open a new PR yourself (see step 5).
31+
- **Not a bug / working-as-intended** → recommend closing, and explain why (e.g.
32+
binary search returning *an* index of a duplicate is correct, not a defect).
33+
- **Feature request mislabeled as a bug** → recommend dropping the `bug` label; do
34+
**not** close it as a bug.
35+
- **Too vague / needs reporter info** → comment **on the issue itself** asking for
36+
the one concrete thing missing (a file path, a traceback, a reproducer), and note
37+
it should be closed if no answer arrives.
38+
- **Environment / optional-dependency, not an algorithm defect** → note it needs
39+
someone with that environment; it is not fixable in a vanilla checkout.
40+
41+
### 3. Examine every attached PR — pick one, name the duplicates
42+
43+
For a bug with several open PRs:
44+
45+
- **Verify each fix's doctest values numerically** against a trusted reference
46+
(`scipy`, `numpy.linalg`, `geopy`, or a brute-force check over random inputs).
47+
Don't take a doctest's word for it — confirm the number.
48+
- Prefer the **first-in PR with the smallest correct diff** that follows repo
49+
convention (doctests over new test files, `raise` over `assert`, no unrelated
50+
reindentation or churn of clean doctests into floating-point noise).
51+
- **Reject out-of-scope "fixes"** — e.g. swapping a real divide-by-zero for a
52+
`1e-15` magic constant makes results implementation-defined. Fix the issue, not
53+
more.
54+
- Identify the byte-for-byte **duplicates** so the maintainer can close them with
55+
thanks in the same action.
56+
57+
### 4. Emit the verdict — fixed output shape
58+
59+
Post one comment that a maintainer can act on directly. For each issue give a
60+
one-line rationale and the exact autoclose line. Two formatting rules matter a lot
61+
to human maintainers scanning the thread:
62+
63+
- **Start every line that references an issue or PR with a Markdown list marker
64+
(`-` or `* `).** GitHub-flavored Markdown only autolinks `#NNNNN` inside a list,
65+
and those autolinks are colored — **purple = merged, red = closed, green = open**
66+
so the maintainer can see merge/close progress at a glance. A bare `#14813` at the
67+
start of a line does not autolink.
68+
- **Merging a PR that closes an issue also closes the issue's other open PRs**, so
69+
fold the duplicates into one autoclose statement rather than listing the winner
70+
alone:
71+
72+
```text
73+
* #14813 — 3x3 inverse returns the transpose → merge #14821
74+
(Closes #14813, Closes #14840, Closes #15045)
75+
```
76+
77+
Recommended shape:
78+
79+
```text
80+
## Confirmed bugs with an adequate open PR — merge
81+
* #<issue> — <one-line what/why> → merge #<pr> (Closes #<issue>, Closes #<dupe>, …)
82+
83+
## Not a bug / not merge-ready
84+
* #<issue> — <feature-request → relabel | needs cleanup | needs a human call>
85+
86+
## Summary — lines to add
87+
* Closes #<issue> → #<pr>
88+
```
89+
90+
### 5. When you must open your own PR
91+
92+
If no attached PR is adequate, open one — but let the contributors keep the credit
93+
where their work was close. Use autoclose keywords in the **commit message body**
94+
so the merge closes the issue *and* the superseded PRs:
95+
96+
```text
97+
Fixes #12233
98+
Fixes #12262
99+
Fixes #13635
100+
```
101+
102+
Follow the [`new-pull-request`](../new-pull-request/SKILL.md) skill for the
103+
mechanics (synced `master`, named branch, checked description box, untouched
104+
`uv.lock`).
105+
106+
## Tone
107+
108+
Be specific and kind. Name the exact PR and the exact reason, credit the
109+
contributor by handle, and offer runners-up detailed feedback so they learn — the
110+
point of the repo is that people come back and fix the next one.

.github/workflows/build.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- uses: actions/checkout@v7
13+
with:
14+
persist-credentials: false
1315
- uses: astral-sh/setup-uv@v7
1416
with:
1517
enable-cache: true
@@ -18,6 +20,12 @@ jobs:
1820
with:
1921
python-version-file: .python-version
2022
allow-prereleases: true
23+
# keras needs hdf5 on pre-release Python.
24+
- run: |
25+
if [ "$(python -c 'import sys; print(sys.version_info.releaselevel)')" != "final" ]; then
26+
sudo apt-get update -qq
27+
sudo apt-get install --yes libhdf5-dev
28+
fi
2129
- run: uv sync --group=test
2230
- name: Run tests
2331
# opencv-python is gated out on 3.14t (no cp314t wheel yet), so skip the

.github/workflows/devcontainer_ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v7
18+
with:
19+
persist-credentials: false
1820
- uses: devcontainers/ci@v0.3
1921
with:
2022
push: never

.github/workflows/directory_writer.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jobs:
99
- uses: actions/checkout@v7
1010
with:
1111
fetch-depth: 0
12+
persist-credentials: false
1213
- uses: actions/setup-python@v7
1314
with:
1415
python-version-file: .python-version
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Daily refresh of the Hacktoberfest 2026 open-PR cleanup tracker.
2+
# Ticks off any tracked pull request that has since been merged/closed, and
3+
# rewrites the "Automated statistics" section (open issue/PR counts + the top
4+
# three `awaiting reviews` directories). The job fails on purpose once
5+
# Hacktoberfest 2026 has begun (>= 2026-10-01), which is the signal to retire it.
6+
name: hacktoberfest_prep
7+
8+
on:
9+
push:
10+
paths:
11+
- ".github/workflows/hacktoberfest_prep.yml"
12+
- "scripts/hacktoberfest_prep_update.py"
13+
pull_request:
14+
paths:
15+
- ".github/workflows/hacktoberfest_prep.yml"
16+
- "scripts/hacktoberfest_prep_update.py"
17+
schedule:
18+
- cron: "50 11 * * *" # 11:50 UTC every day
19+
workflow_dispatch: # allow a manual run while testing
20+
21+
permissions:
22+
contents: write
23+
pull-requests: write
24+
25+
jobs:
26+
hacktoberfest-prep:
27+
# No point running on forks — this pushes to the repo's own docs file.
28+
if: github.repository == 'TheAlgorithms/Python'
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@v7
32+
with:
33+
persist-credentials: false
34+
- uses: actions/setup-python@v7
35+
with:
36+
python-version-file: .python-version
37+
allow-prereleases: true
38+
- name: Install dependencies
39+
run: python -m pip install --upgrade "httpx2>=2.0.1"
40+
- name: Update the tracker
41+
id: update
42+
env:
43+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
GITHUB_REPOSITORY: ${{ github.repository }}
45+
# Don't let the intentional post-Oct-1 failure stop the commit step;
46+
# capture the exit code and re-raise it after pushing any changes.
47+
run: |
48+
set +e
49+
python scripts/hacktoberfest_prep_update.py
50+
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
51+
# Dry run on push / pull_request: show the diff the script produced but
52+
# do NOT commit or push. This lets a PR prove the tracker still gathers
53+
# its data and rewrites docs/hacktober_2026_prep.md correctly without
54+
# leaving a permanent commit. Only the schedule/manual runs persist.
55+
- name: Show changes (dry run)
56+
if: github.event_name == 'push' || github.event_name == 'pull_request'
57+
run: |
58+
echo "Dry run (${{ github.event_name }}): showing git diff, not committing."
59+
git --no-pager diff -- docs/hacktober_2026_prep.md
60+
if git diff --quiet -- docs/hacktober_2026_prep.md; then
61+
echo "No changes to docs/hacktober_2026_prep.md."
62+
fi
63+
# `master` is a protected branch: direct pushes are rejected with
64+
# `GH006: Protected branch update failed ... Changes must be made through
65+
# a pull request`. So instead of committing straight to master, persist
66+
# the refreshed tracker on a single rolling branch and open — or, since
67+
# re-pushing the branch updates the existing PR in place, leave open — one
68+
# pull request. Uses the bundled `gh` CLI rather than a third-party
69+
# action (see zizmor's "superfluous actions" audit).
70+
- name: Open or update the tracker pull request
71+
if: github.event_name != 'push' && github.event_name != 'pull_request'
72+
env:
73+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74+
BRANCH: chore/hacktoberfest-2026-prep-refresh
75+
run: |
76+
set -euo pipefail
77+
if git diff --quiet -- docs/hacktober_2026_prep.md; then
78+
echo "No changes to docs/hacktober_2026_prep.md; nothing to persist."
79+
exit 0
80+
fi
81+
git config --global user.name "$GITHUB_ACTOR"
82+
git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
83+
# `actions/checkout` runs with `persist-credentials: false`, so git has
84+
# no token to authenticate the push below (it fails with
85+
# `fatal: could not read Username for 'https://github.com'`). Wire the
86+
# bundled `gh` in as git's credential helper so `git push` reuses
87+
# GH_TOKEN — no third-party action and no token baked into the remote URL.
88+
gh auth setup-git
89+
git switch -c "$BRANCH"
90+
git add docs/hacktober_2026_prep.md
91+
git commit -m "chore: refresh Hacktoberfest 2026 prep tracker"
92+
# Force-push so the rolling branch always carries just the latest
93+
# snapshot on top of master; this also updates any open PR in place.
94+
git push --force origin "$BRANCH"
95+
if [ -z "$(gh pr list --head "$BRANCH" --state open --json number --jq '.[].number')" ]; then
96+
gh pr create \
97+
--base master \
98+
--head "$BRANCH" \
99+
--title "chore: refresh Hacktoberfest 2026 prep tracker" \
100+
--body "Automated daily refresh of the Hacktoberfest 2026 open-PR cleanup tracker (\`docs/hacktober_2026_prep.md\`): ticks off any tracked pull request that has since been merged/closed and rewrites the **Automated statistics** section.
101+
102+
This PR is updated in place by the \`hacktoberfest_prep\` workflow, so it always reflects the latest scheduled run. Merge it whenever you want to capture the current snapshot."
103+
else
104+
echo "Open tracker PR already exists; force-push updated it in place."
105+
fi
106+
- name: Propagate the script's exit code
107+
env:
108+
UPDATE_EXIT_CODE: ${{ steps.update.outputs.exit_code }}
109+
run: exit ${UPDATE_EXIT_CODE}

0 commit comments

Comments
 (0)