-1

I'm attempting to write a function which takes a list and sums all the numbers in the list, except it ignores sections of the list starting with a list and extending to a 7, but continues to sum after the 7. Here is my code:

def sum67(nums):
   i = 0
   sum = 0
   while i < len(nums):
      k = 0
      if nums[i] != 0:
         sum += nums[i]
         i += 1
      if nums[i] == 6:
         for j in range(i + 1, len(nums)):
            if nums[j] != 7:
               k += 1
            if nums[j] == 7:
               k += 2
               i += k

Test cases show that 6 and proceeding numbers up until and including 7 are ignored while other numbers are added to the sum, and numbers after the 7 are also added to the sum (as was intended), but for some reason any 7 after the first 7 after a 6 is not summed - this is not what I want and I'm not sure why it's happening. Any suggestions?

Test case results:

[1, 2, 2 Expected: 5. My result: 5 (OK)

[1, 2, 2, 6, 99, 99, 7] Expected: 5. My result: 5 (OK)  
[1, 1, 6, 7, 2] Expected: 4 My result: 4 (Chill)    
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7] Expected: 2    My result: 1 (Not chill)    
[1, 6, 2, 6, 2, 7, 1, 6, 99, 99, 7] Expected: 2 My result: 1    (Not chill) 
[2, 7, 6, 2, 6, 7, 2, 7] Expected: 18 My result: 9 (Not chill)

`

3 Answers3

1
def sum67(nums):
    # flag to know if we are summing
    active = True
    tot = 0
    for n in nums:
        # if we hit a 6 -> deactivate summing
        if n == 6:
             active = False
        if active:
             tot += n
        # if we hit a seven -> reactivate summing
        if n == 7 and not active: 
             active = True
    return tot
user1620443
  • 784
  • 3
  • 14
  • 1
    The correct test is `n == 6` and not `n is 6`. It is an implementation dependend detail that it works for small integers. – VPfB Oct 28 '17 at 06:15
0

The posted code is completely broken. For example for a list without any 6, i will be out of bounds of the list when reaching the nums[i] == 6 condition on the last element.

You need to completely rethink the conditions inside the loop. Here's one approach that will work. If the current number is 6, then skip until you see a 7, without adding to the sum. Otherwise add to the sum. After performing either of these two actions (skipping numbers or adding to the sum), increment i.

def sum67(nums):
    i = 0
    total = 0
    while i < len(nums):
        if nums[i] == 6:
            for i in range(i + 1, len(nums)):
                if nums[i] == 7:
                    break
        else:
            total += nums[i]

        i += 1

    return total
janos
  • 120,954
  • 29
  • 226
  • 236
0

Here is an intermediate alternative for learning new Python techniques:

import itertools as it


def span_sum(iterable, start=6, end=7):
    """Return the sum of values found between start and end integers."""
    iterable = iter(iterable)
    flag = [True]
    result = []

    while flag:
        result.extend(list(it.takewhile(lambda x: x!=start, iterable)))
        flag = list(it.dropwhile(lambda x: x!=end, iterable))
        iterable = iter(flag)
        next(iterable, [])
    return sum(result)

# Tests
f = span_sum
assert f([1, 2, 2]) == 5
assert f([1, 2, 2, 6, 99, 99, 7] ) == 5
assert f([1, 6, 2, 2, 7, 1, 6, 99, 99, 7]) == 2
assert f([1, 6, 2, 6, 2, 7, 1, 6, 99, 99, 7]) == 2
assert f([2, 7, 6, 2, 6, 7, 2, 7]) == 18

In principle, this function filters the input, collecting values into a result that meet your condition and drops the rest, then the sum is returned. In particular you can observe the following techniques:

pylang
  • 40,867
  • 14
  • 129
  • 121