Python sum of number in array, ignoring sections of specific numbers

Question:

I am very new to Python and have been going through multiple tutorials to get better.

I have straggled with one difficult problem and found a solution. But it feels, works very newbie like. I think that I have tailored it to answer the specific question.

So the question is:

SUMMER OF ’69: Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 9 (every 6 will be followed by at least one 9). Return 0 for no numbers.

summer_69([1, 3, 5]) --> 9
summer_69([4, 5, 6, 7, 8, 9]) --> 9
summer_69([2, 1, 6, 9, 11]) --> 14

My code to solve this is:

def summer_69(arr):
    list1 = arr
    summ = int()
    for i in range(0, len(arr)):
        if 6 in list1:
            listOfRange = range(list1.index(6), list1.index(9) + 1)
            for index in listOfRange:
                    print(listOfRange)
                    arr[index] = 0
            if 6 != arr[i]:
                summ += arr[i]
            else:
                continue
        else:
            summ += arr[i]
    return summ

It is a very basic problem and I am very alerted that I have struggled with something like this already.

Asked By: Klim Yadrintsev

||

Answers:

Here’s how I’d do it, as a first cut:

def summer_69(series):
  in_summer = False
  cur_sum = 0
  for v in series:
    if in_summer:
      if v == 9:
        in_summer = False
    else:
      if v == 6:
        in_summer = True
      else:
        cur_sum += v
  return cur_sum
Answered By: Sean Suchter

Here’s a version that uses a more reusable pythonic idiom, a generator function, and is a little more compact (at the slight cost of an extra comparison):

def yield_non_summer(series):
  in_summer = False
  def stateful_summer_predicate(v):
    nonlocal in_summer
    if in_summer and v == 9:
      in_summer = False
      return True  # 9 is still in summer
    elif not in_summer and v == 6:
      in_summer = True
    return in_summer
  return (v for v in series if not stateful_summer_predicate(v))

def summer_69(series):
  return sum(yield_non_summer(series))

Or, in fewer lines:

def yield_non_summer(series):
  in_summer = False
  def stateful_summer_predicate(v):
    nonlocal in_summer
    in_summer = (in_summer or v == 6) and v != 9
    return in_summer
  return (v for v in series if not stateful_summer_predicate(v))

def summer_69(series):
  return sum(yield_non_summer(series))
Answered By: Sean Suchter

Something like this:

def summer_69(lst):
  """Return the sum of the numbers in the array, 
     except ignore sections of numbers starting with a 6 and extending to the next 9 
     (every 6 will be followed by at least one 9). Return 0 for no numbers
  """
  if not lst:
    return 0
  else:
    _sum = 0
    active = True
    for x in lst:
      if active: 
        if x != 6:
          _sum += x
        else:
          active = False
      else:
        if x == 9:
          active = True
    return _sum

print(summer_69([1, 3, 5]))
print(summer_69([4, 5, 6, 7, 8, 9]))
print(summer_69([2, 1, 6, 9, 11]))

output

9
9
14
Answered By: balderman
def summer_69(arr):
    if 6 in arr:
        c=arr[arr.index(6):arr.index(9)+1]
        for i in c:
            arr.remove(i)
        print(arr)
        return sum(arr)
    else:
        return sum(arr)

summer_69([1,2,3,4,5,6,7,8,9,10,11,12])
Answered By: pramod

This will work:

def summer_69(arr):
    total = 0
    add = True
    for num in arr:
        while add:
            if num != 6:
                total += num
                break
            else:
                add = False
        while not add:
            if num != 9:
                break
            else:
                add = True
                break
    return total
Answered By: user13432631
def summer_69(arr):
sum = 0
Flag = False
if 6 not in arr:
    for num in arr:
        sum = sum + num
    return sum
else:
    for num in arr:
        if num != 6 and Flag == False:
            sum = sum + num                
        elif num == 6:
            Flag = True
            continue
        elif Flag == True and num != 9:
            continue
        elif num == 9:
            Flag = False
    return sum
Answered By: jiju

A simple approach is to make a filter and sum the results.

Code

def filter_substring(seq, start, end):
    """Yield values outside a given substring."""
    release = True

    for x in seq:

        if x == start:
            release = False
        elif x == end:
            release = True
        elif release:
            yield x


def summer(seq):
    """Return the sum of certain values."""
    return sum(filter_substring(seq, 6, 9))

Demo

assert 0 == summer([])
assert 6 == summer([1, 2, 3])
assert 6 == summer([1, 2, 3, 6, 8, 7, 9])
assert 9 == summer([1, 3, 5])
assert 8 == summer([3, 5, 6, 7, 8, 9])
assert 15 == summer([2, 1, 6, 9, 12])
assert 16 == summer([2, 1, 6, 9, 1, 6, 6, 120, 9, 9, 12])


Details

filter_substring()+

This is a generator function. It iterates the input sequence and only yields a value if the conditions are appropriate, i.e. when the release remains True.

>>> list(filter_substring("abcde", "c", "d"))
['a', 'b', 'e']
>>> list(filter_substring([0, 1, 2, 3, 10], 1, 3))
[0, 10]

summer()

Here we simply sum whatever filter_range() yields.

+Note: a substring is a contiguous subsequence; this may or may not include strings in Python.

Answered By: pylang
def summer_69(arr):
    a = 0
    for nums in arr: 
        if nums == 6:
            for items in arr[arr.index(6):]:
                a = a+ items
                if items == 9:
                    break
    return sum(arr)-a
Answered By: Mohit Sinha
def summer_69(arr):
        x = arr.count(6)
        y = arr.count(9)
        # to decide number of iteration required for loop
        z = min(x,y)
        k = 0
        while k < (z) :
            m = arr.index(6)
            n = arr.index(9)
            del arr[m:(n+1)]
            k = k + 1
        print(arr)
        return sum(arr)
Answered By: Ramakanth Joshi

This will work for summer_69 problem as well for filtering substring

def filter_substring(seq, start, end):
flag = False
for char in seq:
    if char == start:
        flag = True
        continue
    elif flag:
        if char == end:
            flag = False 
        else:
            continue
    else:
        yield char

def summer_69(seq, start, end):
    return sum(filter_substring(seq, start, end))

def print_substring(string, start, end):
    return list(filter_substring(string, start, end))

Example ::

seq = [4, 5, 9, 6, 2, 9, 5, 6, 1, 9, 2]
print(summer_69(seq, start=6, end=9))


string = "abcdef"
print(print_substring(string, start='c', end='e'))
Answered By: mann

Will work with indexes:

def summer_69(arr):
    y = []
    for x in arr:
        if 6 in arr:
            a = arr.index(6)
            b = arr.index(9)
            del arr[a:b+1]
            y = arr
        elif arr == []:
            return "0"
        else:
            return sum(arr)
    return sum(y)
print(summer_69([]))                                                          #0
print(summer_69([1, 3, 5]))                                                   #9
print(summer_69([4, 5, 6, 7, 8, 9]))                                          #9
print(summer_69([2, 1, 6, 9, 11]))                                            #14
print(summer_69([2, 1, 6, 9, 6, 11, 25, 36, 11, 9, 4, 6, 4, 6, 3, 9, 15]))    #22
Answered By: Alex

This is the probably best answer if you are a newbie. I have simplified it as much as i can. you only need to know enumerate, function, for loops , tuple unpacking,if/else statements and break function.So lets go straight to the answer.

def myfunc(a):
mylist=[]
sum1 = 0
for b,c in enumerate(a):
    if c==6:
       for d in  a[:b]:
           mylist.append(d)
for e,f in enumerate(a):
    if f==9:
       for j in a[e+1:]:
           mylist.append(j)
for y in a:
    if y==6:
      break
    else:
       mylist.append(y)
for k in mylist:
    sum1 = sum1+k
print(sum1)

myfunc([1,3,5])

Answered By: Coder119872

Replace

list1.index(9)+1 
by 
list1.index(9,list1.index(6)+1)+1

in line 6.
This will start searching for a 9 after 6.

Answered By: Avinash Ranjan

For those interested, here is my solution for this problem:

def summer_69(arr):
    skate = arr
    guitar = []
    for i in range(len(arr)):
        if 6 in arr:
            guitar = skate[skate.index(6):skate.index(9)+1]
            return abs(sum(skate) - sum(guitar))
        else:
            return sum(skate)
Answered By: phrbittencourt

Short O(n) solution using an iterator and the in operator to search for (and thereby skip to) the 9 following each 6:

def summer_69(lst):
    it = iter(lst)
    return sum(x for x in it
               if x != 6 or 9 not in it)

Less dense version:

def summer_69(lst):
    it = iter(lst)
    total = 0
    for x in it:
        if x == 6:
            9 in it
        else:
            total += x
    return total

Correctness check (random test cases) and benchmark (with [1] * 5000 + [6, 9] * 2500) along with the accepted answer’s solution (which takes O(n2)):

30 out of 30 tests correct

303045 us  303714 us  304335 us  306007 us  309986 us  summer_69_Accepted
   444 us     446 us     464 us     478 us     527 us  summer_69_Kelly1
   442 us     448 us     453 us     465 us     500 us  summer_69_Kelly2

Code (Try it online!):

from timeit import repeat

def summer_69_Accepted(lst):
    copyoflist = lst[:] # makes shallow copy of list
    while True:
        if 6 not in copyoflist:
            return sum(copyoflist)

        indexof6 = copyoflist.index(6)
        indexof9 = copyoflist.index(9, indexof6+1) # begin search for 9 after 6
        del copyoflist[indexof6:indexof9+1] 

def summer_69_Kelly1(lst):
    it = iter(lst)
    return sum(x for x in it
               if x != 6 or 9 not in it)

def summer_69_Kelly2(lst):
    it = iter(lst)
    total = 0
    for x in it:
        if x == 6:
            9 in it
        else:
            total += x
    return total

funcs = summer_69_Accepted, summer_69_Kelly1, summer_69_Kelly2

from random import randrange, choices

def testcase():
    def others():
        return choices([0, 1, 2, 3, 4, 5, 7, 8], k=randrange(10))
    lst = others()
    for _ in range(10):
        lst += [6, *others(), 9, *others()]
    return lst

tests = correct = 0
for _ in range(10):
    lst = testcase()
    expect = funcs[0](lst.copy())
    for func in funcs:
        result = func(lst.copy())
        correct += result == expect
        tests += 1
print(correct, 'out of', tests, 'tests correct')
print()

lst = [1] * 5000 + [6, 9] * 2500
for func in funcs:
    times = repeat(lambda: func(lst), number=1)
    print(*('%6d us ' % (t * 1e6) for t in sorted(times)), func.__name__)
Answered By: Kelly Bundy

This is taken from a Udemy course.

Here is the official answer . . .

def summer_69(arr):
total = 0
add = True
for num in arr:
    while add:
        if num != 6:
            total += num
            break
        else:
            add = False
    while not add:
        if num != 9:
            break
        else:
            add = True
            break
return total

Jose Periera has this on Python ‘zero to hero’ course.

Answered By: Leigh Chambers

My own particular approach was this . . .

def summer_69(arr):

#first find out if 6 or 9 are in the list

if 6 in arr and 9 in arr:

#Then create a variable that stores the index location of the number 6 
#and the number 9

        sixer = arr.index(6)
        niner = arr.index(9)

#now return the sum of the array minus the sum of the values between 
#index of 6 and index of 9 inclusive (hence the plus 1)
#This way will ignore the case of a 9 appearring before a 6 too.

        return sum(arr) - sum(arr[sixer:niner+1])

#Otherwise just return the sum of the array.

else:
    return sum(arr)

Happy to accept criticism here. I’m learning Python myself and I’m undergoing an Msc in computer science and hoping to apply for jobs in the field soon, so your comments will help me 🙂

Answered By: Leigh Chambers

My approach was to sum the whole list and the part of the list that we want to ignore and subtract them at the end.

def summer_69(arr):
result=0
reduction =0
for i in range(0,len(arr)):
    result+=arr[i]
    if arr[i] == 6:
        temp = arr[arr.index(6):arr.index(9)+1]
        reduction = sum(temp)
return result - reduction
def summer69(a):
    for z in a:
        if z==6 and 9 in a:
           x=a.index(6)
           y=a.index(9)
           del a[x:y+1]
           t= sum(a)
        else:
           t=sum(a)
    return t

Will always prefer short , clear and easy understandable solution.

Answered By: Yogesh sahu
def summer_69(arr):
if 9 in arr :
    sum = 0 
    y = arr.index(9)
    for i , l in enumerate(arr):
        if l == 6:
            del arr[i:y+1]
    for i in range(len(arr)):
        sum = sum + arr[i]
    return sum
elif 9 not in arr:
    sum = 0
    for i in range(len(arr)):
        sum = sum + arr[i]
    return sum 
Answered By: Yahia Naeem

def summer_69(mylist):

if 6 in mylist:        
    return sum(mylist) - sum(mylist[mylist.index(6):mylist.index(9)+1])
else:
    return sum(mylist)
Answered By: Shakhlyn

def summer_69(arr):

returner = []

if 6 and 9 in arr:        
    
    a = arr.index(6)    
    b = arr.index(9)
    
    if a < b:
        
        seq = arr[a:(b+1)]

        for i in arr:    
            if i not in seq:
                returner.append(i)
        return (sum(returner))
    
    elif a > b:
        
        seq = arr[b:(a+1)]

        for i in arr:    
            if i not in seq:
                returner.append(i)
        return (sum(returner))

elif 6 in arr:
    
    a = arr.index(6)
    seq = arr[a:]
    for i in arr:    
        if i not in slicer:
            returner.append(i)
    return(sum(returner))

elif 9 in arr:
    a = arr.index(9)
    seq = arr[a:]
    for i in arr:    
        if i not in slicer:
            returner.append(i)
    return(sum(returner))

elif arr == []:
    return 0

else:
    return (sum(arr))
Answered By: i-nergiz

Just learning Python too and this was what I came up with for it:

def myfunc(arr):
 ignore_list = []
 newlist = []
 for i,v in enumerate(arr):
     if v >= 6 and v <= 9:
         ignore_list.append(i)
     if i in ignore_list:
         newlist.append(0)
     else:
         newlist.append(v)

 return sum(newlist)
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.