barissozudogru/swe-bench-mini huggingface dataset:
Repository: quixbugs (difficulty: medium)

Issue:
levenshtein(source, target) computes the Levenshtein edit distance between two strings via recursion. It returns values that are too large: e.g. levenshtein('kitten', 'sitting') returns 7 instead of 3, and levenshtein('electron', 'neutron') returns more than 3. When the leading characters of source and target are equal, no edit is needed, so that case must not contribute to the distance.

Source files:
levenshtein.py: def levenshtein(source, target):
    if source == '' or target == '':
        return len(source) or len(target)

    elif source[0] == target[0]:
        return 1 + levenshtein(source[1:], target[1:])

    else:
        return 1 + min(
            levenshtein(source,     target[1:]),
            levenshtein(source[1:], target[1:]),
            levenshtein(source[1:], target)
        )


Test files:
test_levenshtein.py: from levenshtein import levenshtein

# Real QuixBugs json_testcases/levenshtein.json data, inlined for self-containment.
CASES = [
    (["electron", "neutron"], 3),
    (["kitten", "sitting"], 3),
    (["rosettacode", "raisethysword"], 8),
    (["abcdefg", "gabcdef"], 2),
    (["", ""], 0),
    (["hello", "olleh"], 4),
]


def test_levenshtein():
    for args, expected in CASES:
        assert levenshtein(*args) == expected


Patch:
--- a/levenshtein.py
+++ b/levenshtein.py
@@ -3,7 +3,7 @@
         return len(source) or len(target)
 
     elif source[0] == target[0]:
-        return 1 + levenshtein(source[1:], target[1:])
+        return levenshtein(source[1:], target[1:])
 
     else:
         return 1 + min(
Repository: quixbugs (difficulty: medium)

Issue:
bitcount(n) is supposed to return the number of 1-bits in the binary representation of a nonnegative integer n. Instead, the function hangs forever for any n > 0. For example, bitcount(127) never returns. The loop is meant to clear the lowest set bit on each iteration (Brian Kernighan's algorithm) but instead keeps producing nonzero values, so the while loop never terminates.

Source files:
bitcount.py: def bitcount(n):
    count = 0
    while n:
        n ^= n - 1
        count += 1
    return count


Test files:
test_bitcount.py: import multiprocessing as mp

from bitcount import bitcount

# Real QuixBugs json_testcases/bitcount.json data, inlined for self-containment.
CASES = [
    ([127], 7),
    ([128], 1),
    ([3005], 9),
    ([13], 3),
    ([14], 3),
    ([27], 4),
    ([834], 4),
    ([254], 7),
    ([256], 1),
]


def _run(args, q):
    q.put(bitcount(*args))


def _call_with_timeout(args, timeout=4.0):
    # The buggy version (n ^= n - 1) never terminates; run in a child
    # process so we can fail deterministically instead of hanging.
    ctx = mp.get_context("spawn")
    q = ctx.Queue()
    p = ctx.Process(target=_run, args=(args, q))
    p.start()
    p.join(timeout)
    if p.is_alive():
        p.terminate()
        p.join()
        raise AssertionError(f"bitcount{tuple(args)} did not terminate (infinite loop)")
    return q.get_nowait()


def test_bitcount():
    for args, expected in CASES:
        assert _call_with_timeout(args) == expected


Patch:
--- a/bitcount.py
+++ b/bitcount.py
@@ -1,6 +1,6 @@
 def bitcount(n):
     count = 0
     while n:
-        n ^= n - 1
+        n &= n - 1
         count += 1
     return count
Repository: toolz (difficulty: medium)

Issue:
take_nth(n, seq) is supposed to yield every nth item starting from the first one. take_nth(2, [10, 20, 30, 40, 50]) should give [10, 30, 50], but it currently returns [20, 40] -- the whole result is shifted, starting from the second element and dropping the first. The stride is correct; the starting offset is wrong.

Source files:
itertoolz.py: """A slice of toolz.itertoolz.

Vendored verbatim from toolz 1.1.0 (itertoolz.take_nth), BSD-3-Clause.
"""
import itertools


def take_nth(n, seq):
    """ Every nth item in seq

    >>> list(take_nth(2, [10, 20, 30, 40, 50]))
    [10, 30, 50]
    """
    return itertools.islice(seq, 1, None, n)


Test files:
test_itertoolz.py: """Slice of toolz 1.1.0 test_itertoolz.py (take_nth)."""
from itertoolz import take_nth


def test_take_nth():
    assert list(take_nth(2, [10, 20, 30, 40, 50])) == [10, 30, 50]
    assert list(take_nth(3, range(10))) == [0, 3, 6, 9]
    assert list(take_nth(1, [1, 2, 3])) == [1, 2, 3]


Patch:
--- a/itertoolz.py
+++ b/itertoolz.py
@@ -11,4 +11,4 @@
     >>> list(take_nth(2, [10, 20, 30, 40, 50]))
     [10, 30, 50]
     """
-    return itertools.islice(seq, 1, None, n)
+    return itertools.islice(seq, 0, None, n)
Repository: classickit (difficulty: medium)

Issue:
find_first_in_sorted is documented to return the index of the first occurrence of x in a sorted list, but with duplicates it returns some other occurrence. Observed: find_first_in_sorted([1, 2, 2, 2, 3], 2) returns 2, expected 1. find_first_in_sorted([5, 5, 5, 5, 5, 5, 5], 5) returns 3, expected 0. find_first_in_sorted([0, 1, 1, 1, 1, 1, 2], 1) returns 3, expected 1. Even the two-element case is wrong: find_first_in_sorted([2, 2], 2) returns 1, expected 0. Inputs without duplicates behave: absent values give -1, the empty list gives -1, and hits at the first or last position of a duplicate-free list come back with the right index. The returned index always does hold x, so the search apparently stops at whatever middle element happens to equal x instead of continuing toward the leftmost copy.

Source files:
core.py: """Binary search helpers for sorted sequences.

find_first_in_sorted(arr, x) returns the index of the FIRST occurrence of
x in the sorted list arr, or -1 if x is not present. With duplicates the
smallest index holding x must be returned: for arr = [1, 2, 2, 2, 3] and
x = 2 the answer is 1, never 2 or 3. The empty list contains nothing, so
the result is -1 for any x.
"""


def find_first_in_sorted(arr, x):
    """Return the smallest i with arr[i] == x, or -1 if x is absent."""
    lo, hi = 0, len(arr)
    while lo < hi:
        mid = (lo + hi) // 2
        if arr[mid] == x:
            return mid
        if arr[mid] < x:
            lo = mid + 1
        else:
            hi = mid
    return -1


Test files:
test_core.py: import random

from core import find_first_in_sorted


def first_index(arr, x):
    """Stdlib reference: leftmost index of x, or -1 when absent."""
    return arr.index(x) if x in arr else -1


def test_pinned_duplicates():
    assert find_first_in_sorted([1, 2, 2, 2, 3], 2) == 1
    assert find_first_in_sorted([5, 5, 5, 5, 5, 5, 5], 5) == 0
    assert find_first_in_sorted([0, 1, 1, 1, 1, 1, 2], 1) == 1
    assert find_first_in_sorted([2, 2], 2) == 0


def test_edges_and_bounds():
    assert find_first_in_sorted([], 7) == -1
    assert find_first_in_sorted([1, 3], 2) == -1
    assert find_first_in_sorted([1, 2, 3], 0) == -1
    assert find_first_in_sorted([1, 2, 3], 4) == -1
    assert find_first_in_sorted([1, 2, 3], 1) == 0
    assert find_first_in_sorted([1, 2, 3], 3) == 2
    assert find_first_in_sorted([7, 7, 7, 7, 7, 7], 7) == 0
    assert find_first_in_sorted([4], 4) == 0
    assert find_first_in_sorted([4], 5) == -1


def test_random_property_vs_list_index():
    rng = random.Random(20210)
    for _ in range(400):
        n = rng.randint(0, 30)
        arr = sorted(rng.randrange(6) for _ in range(n))
        x = rng.randint(-1, 6)
        assert find_first_in_sorted(arr, x) == first_index(arr, x)


Patch:
--- a/core.py
+++ b/core.py
@@ -13,10 +13,10 @@
     lo, hi = 0, len(arr)
     while lo < hi:
         mid = (lo + hi) // 2
-        if arr[mid] == x:
-            return mid
         if arr[mid] < x:
             lo = mid + 1
         else:
             hi = mid
+    if lo < len(arr) and arr[lo] == x:
+        return lo
     return -1
Repository: classickit (difficulty: medium)

Issue:
Fenwick.prefix_sum drops the element at its own index: the sum comes back exclusive of position i even though the docstring says positions 0 through i inclusive. Observed: t = Fenwick(5); t.update(0, 5); t.prefix_sum(0) returns 0, expected 5. After additionally doing t.update(2, 3), t.prefix_sum(2) returns 5, expected 8, while t.prefix_sum(1) returns 5 as expected. It looks like prefix_sum(i) actually returns the sum of the first i elements, i.e. positions 0 through i - 1, so prefix_sum(0) is always 0 no matter what was added at index 0. Updates themselves land at the right positions, and negative deltas must keep working (update is documented to accept them).

Source files:
core.py: """Fenwick tree (binary indexed tree) with a 0-indexed public API.

Fenwick(n) creates a tree over n elements, all initially 0, indexed 0
through n - 1. update(i, delta) adds delta (possibly negative) to the
element at index i. prefix_sum(i) returns the sum of the elements 0
through i INCLUSIVE: immediately after Fenwick(3).update(0, 5),
prefix_sum(0) must already be 5. Internally the tree array is 1-indexed,
as is conventional for Fenwick trees; only the public API is 0-indexed.
"""


class Fenwick:
    """Point updates and inclusive prefix sums in O(log n)."""

    def __init__(self, n):
        self.n = n
        self.tree = [0] * (n + 1)

    def update(self, i, delta):
        """Add delta to the element at 0-indexed position i."""
        j = i + 1
        while j <= self.n:
            self.tree[j] += delta
            j += j & (-j)

    def prefix_sum(self, i):
        """Return the sum of the elements at positions 0..i inclusive."""
        j = i
        total = 0
        while j > 0:
            total += self.tree[j]
            j -= j & (-j)
        return total


Test files:
test_core.py: import random

from core import Fenwick


def test_pinned_trace():
    t = Fenwick(5)
    t.update(0, 5)
    assert t.prefix_sum(0) == 5
    t.update(2, 3)
    assert t.prefix_sum(0) == 5
    assert t.prefix_sum(1) == 5
    assert t.prefix_sum(2) == 8
    assert t.prefix_sum(4) == 8
    t.update(2, -4)
    assert t.prefix_sum(2) == 4
    assert t.prefix_sum(4) == 4
    single = Fenwick(1)
    single.update(0, 7)
    assert single.prefix_sum(0) == 7


def test_random_ops_vs_plain_list():
    rng = random.Random(20270)
    total_ops = 0
    for _ in range(40):
        n = rng.randint(1, 50)
        tree = Fenwick(n)
        plain = [0] * n
        for _ in range(rng.randint(10, 20)):
            total_ops += 1
            i = rng.randrange(n)
            if rng.random() < 0.5:
                delta = rng.randint(-9, 9)
                tree.update(i, delta)
                plain[i] += delta
            else:
                assert tree.prefix_sum(i) == sum(plain[: i + 1])
    assert total_ops >= 300


Patch:
--- a/core.py
+++ b/core.py
@@ -25,7 +25,7 @@
 
     def prefix_sum(self, i):
         """Return the sum of the elements at positions 0..i inclusive."""
-        j = i
+        j = i + 1
         total = 0
         while j > 0:
             total += self.tree[j]