-1

I am working through John Guttag's 'Introduction to Computation and Programming Using Python' and encountered an exercise to create a function that returns the sum of decimal digits in a string. I have been able to implement this for single-digit int > 0. Do point out if my code is somehow inefficient or if it could be made more pythonic.

I want to take this further than simply summing single digits in the str (combination of characters, not just digits, without delimiters between 'numbers' to be summed).

If a 'number' is defined as a sequence of digits without intervening non-digit characters (other than . to represent floats), how can the function be extended to recognise and sum multiple-digit numbers, negative numbers like -5 and floats like 1.23?

Here is my code:

def sumDigits(s):
    """Assumes s an str
    Returns sum of digits in s"""

    w= []
    for i in range(len(s)):
        try:
            w.append(int(s[i]))
        except ValueError:
            w.extend('')

    sum = 0
    for x in w:
        sum += x
    print('sumDigits is:', sum)

sumDigits(str(input('Enter sequence:')))
Aja
  • 3
  • 2
  • 2
    If input is '123', what's the expected result? And what if '1.23' and '-1.23'? – Waket Zheng Oct 09 '22 at 15:17
  • 1
    if you separate the numbers by a delimiter, i.e. " " or "," or ", " then it is easy. Any other way: it depends – Tom McLean Oct 09 '22 at 15:21
  • I have edited the question to define more clearly what constitutes a number to be summed. So, for the str input 'a1B2c500d3.4e..5-6' the function would return: 505.4, i.e., the value of 1+2+500+3.4+5+-6. This is in contrast to what my code would return: 26, i.e., the value of 1+2+5+0+0+3+4+5+6. – Aja Oct 09 '22 at 15:34
  • 1
    Welcome to Stack Overflow. "How can the function be extended to recognise and sum multiple-digit numbers, negative numbers like -5 and floats like 1.23?" **Did you try the existing code**? When I try it, the result from an input of `-5` is `5`, and the result for `1.23` is `6`. I think these answers are correct. Aren't they? I think the existing code *should be expected* to work already. Don't you? (Hint: where the code says `try:` and `except ValueError:`, what do you think is the purpose of that part?) – Karl Knechtel Oct 09 '22 at 15:53
  • 1
    "So, for the str input 'a1B2c500d3.4e..5-6' the function would return: 505.4, i.e., the value of 1+2+500+3.4+5+-6." This expectation does not make any sense. The assignment says to "sum the decimal digits in a string". `500` is **not a "decimal digit"**, and neither is `3.4`. "This is in contrast to what my code would return: 26, i.e., the value of 1+2+5+0+0+3+4+5+6." According to *what you described the book as saying*, that is exactly what **should** happen. I think the question here has more to do with understanding the task description than it does with actually writing code. – Karl Knechtel Oct 09 '22 at 15:56

3 Answers3

2

Your script can be re-written as:

def sum_string(s):
    return sum(int(c) for c in s if c.isnumeric())

Examples:

sum_string("111") -> 3
sum_string("11abcd1") -> 3

For the second half of your question, it depends on how your input is formatted as your numbers are no longer represented by single characters.

If the digits are separated a delimiter, you can do:

def can_convert_float(s):
   try:
      float(s)
   except ValueError:
      return False
   return True


def sum_string(s, delimiter=" "):
    return sum(float(x) for x in s.split(delimiter) if can_convert_float(x))

Examples:

sum_string("1 -2 a 2.5") -> 1.5
Tom McLean
  • 5,583
  • 1
  • 11
  • 36
0

if integer > 0 then num = sum([int(x) for x in inp_str.split() if x.isdigit()])

Dmitry Erohin
  • 137
  • 1
  • 5
0

A prefered method would be to use regular expressions, but if you are using for loops, then something like this is a good approach.

This method collects allowable digits and converts them into floats when a space occurs. There are string formats that might break this tho, so you would need to consider edge cases or other characters...

def sumDigits(s):
    """Assumes s an str
    Returns sum of digits in s"""

    w= []
    num = ''
    allowables = ['0','1','2','3','4','5','6','7','8','9', '.']
    for i in s:
        if i in allowables:
            num = num + i
        elif i ==" ":
            w.append(float(num))
            num = ''            
        else:
            print('not a space')
    w.append(float(num))    

    return w, sum(w)

sumDigits(str(input('Enter sequence:')))

D.L
  • 4,339
  • 5
  • 22
  • 45