Skip to main content
use better names
Source Link
mkrieger1
  • 1.7k
  • 1
  • 14
  • 26

The documentation string you provided at the top of the module would better be placed in the function, and the examples should be formatted as doctests so that they can automatically be checked.

The control flow can be simplified and manual handling of indexes eliminated if you iterate directly over the input list, maintain a deque for the currently considered subsequence, and use an inner while loop for discarding numbers.

from collections import deque

def sum_targetcontains_subsequence_sum(numbers, target):
    '''Given a sequence of positive integers `numbers` and an integer `target`,
    return whether there is a continuous sub-sequence of `numbers` that sums up
    to exactly `target`.

    >>> sum_targetcontains_subsequence_sum([23, 5, 4, 7, 2, 11], 20)  # 7 + 2 + 11 = 20
    True
    >>> sum_targetcontains_subsequence_sum([1, 3, 5, 23, 2], 8)       # 3 + 5 = 8
    True
    >>> sum_targetcontains_subsequence_sum([1, 3, 5, 23, 2], 7)
    False
    '''
    subsequence = deque()
    current_sumtotal = 0

    for number in numbers:
        if current_sumtotal < target:
            subsequence.append(number)
            current_sumtotal += number
        while current_sumtotal > target and subsequence:
            current_sumtotal -= subsequence.popleft()
        if current_sumtotal == target:
            return True

    return False

The original name sum_target suggests that the function returns a number when it actually returns a boolean value (it is a predicate). Such functions tend to have names like "has", "is", "contains", etc. While I'm still not quite happy with it, the name contains_subsequence_sum is a better fit.

The documentation string you provided at the top of the module would better be placed in the function, and the examples should be formatted as doctests so that they can automatically be checked.

The control flow can be simplified and manual handling of indexes eliminated if you iterate directly over the input list, maintain a deque for the currently considered subsequence, and use an inner while loop for discarding numbers.

from collections import deque

def sum_target(numbers, target):
    '''Given a sequence of positive integers `numbers` and an integer `target`,
    return whether there is a continuous sub-sequence of `numbers` that sums up
    to exactly `target`.

    >>> sum_target([23, 5, 4, 7, 2, 11], 20)  # 7 + 2 + 11 = 20
    True
    >>> sum_target([1, 3, 5, 23, 2], 8)       # 3 + 5 = 8
    True
    >>> sum_target([1, 3, 5, 23, 2], 7)
    False
    '''
    subsequence = deque()
    current_sum = 0

    for number in numbers:
        if current_sum < target:
            subsequence.append(number)
            current_sum += number
        while current_sum > target and subsequence:
            current_sum -= subsequence.popleft()
        if current_sum == target:
            return True

    return False

The documentation string you provided at the top of the module would better be placed in the function, and the examples should be formatted as doctests so that they can automatically be checked.

The control flow can be simplified and manual handling of indexes eliminated if you iterate directly over the input list, maintain a deque for the currently considered subsequence, and use an inner while loop for discarding numbers.

from collections import deque

def contains_subsequence_sum(numbers, target):
    '''Given a sequence of positive integers `numbers` and an integer `target`,
    return whether there is a continuous sub-sequence of `numbers` that sums up
    to exactly `target`.

    >>> contains_subsequence_sum([23, 5, 4, 7, 2, 11], 20)  # 7 + 2 + 11 = 20
    True
    >>> contains_subsequence_sum([1, 3, 5, 23, 2], 8)       # 3 + 5 = 8
    True
    >>> contains_subsequence_sum([1, 3, 5, 23, 2], 7)
    False
    '''
    subsequence = deque()
    total = 0

    for number in numbers:
        if total < target:
            subsequence.append(number)
            total += number
        while total > target and subsequence:
            total -= subsequence.popleft()
        if total == target:
            return True

    return False

The original name sum_target suggests that the function returns a number when it actually returns a boolean value (it is a predicate). Such functions tend to have names like "has", "is", "contains", etc. While I'm still not quite happy with it, the name contains_subsequence_sum is a better fit.

Source Link
mkrieger1
  • 1.7k
  • 1
  • 14
  • 26

The documentation string you provided at the top of the module would better be placed in the function, and the examples should be formatted as doctests so that they can automatically be checked.

The control flow can be simplified and manual handling of indexes eliminated if you iterate directly over the input list, maintain a deque for the currently considered subsequence, and use an inner while loop for discarding numbers.

from collections import deque

def sum_target(numbers, target):
    '''Given a sequence of positive integers `numbers` and an integer `target`,
    return whether there is a continuous sub-sequence of `numbers` that sums up
    to exactly `target`.

    >>> sum_target([23, 5, 4, 7, 2, 11], 20)  # 7 + 2 + 11 = 20
    True
    >>> sum_target([1, 3, 5, 23, 2], 8)       # 3 + 5 = 8
    True
    >>> sum_target([1, 3, 5, 23, 2], 7)
    False
    '''
    subsequence = deque()
    current_sum = 0

    for number in numbers:
        if current_sum < target:
            subsequence.append(number)
            current_sum += number
        while current_sum > target and subsequence:
            current_sum -= subsequence.popleft()
        if current_sum == target:
            return True

    return False