12

if i just read my sum_digits function here, it makes sense in my head but it seems to be producing wrong results. Any tip?

def is_a_digit(s):
''' (str) -> bool

Precondition: len(s) == 1

Return True iff s is a string containing a single digit character (between
'0' and '9' inclusive).

>>> is_a_digit('7')
True
>>> is_a_digit('b')
False
'''

return '0' <= s and s <= '9'

def sum_digits(digit):
    b = 0
    for a in digit:
        if is_a_digit(a) == True:
            b = int(a)
            b += 1

    return b

For the function sum_digits, if i input sum_digits('hihello153john'), it should produce 9

Óscar López
  • 232,561
  • 37
  • 312
  • 386
user1864828
  • 349
  • 1
  • 3
  • 10

10 Answers10

29

Notice that you can easily solve this problem using built-in functions. This is a more idiomatic and efficient solution:

def sum_digits(digit):
    return sum(int(x) for x in digit if x.isdigit())

print(sum_digits('hihello153john'))
=> 9

In particular, be aware that the is_a_digit() method already exists for string types, it's called isdigit().

And the whole loop in the sum_digits() function can be expressed more concisely using a generator expression as a parameter for the sum() built-in function, as shown above.

Haseeb Mir
  • 928
  • 1
  • 13
  • 22
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • @HaseeBMir of course if doesn't work... in ideone you need to explicitly print the result. There is nothing wrong with my implementation, it'll work in any real interpreter, you just forgot to add a `print()`. Kindly remove your downvote, the problem is with _your_ code, not mine. – Óscar López May 07 '21 at 23:58
  • @HaseeBMir you shouldn't test other people's code in ideone, use a real interpreter, otherwise you'll get incorrect results. – Óscar López May 08 '21 at 00:01
  • ideone is most accurate coding editor out there – Haseeb Mir May 08 '21 at 00:11
  • You should write full code then for all compilers and interpreters. – Haseeb Mir May 08 '21 at 06:26
  • @HaseeBMir why don't you take a look at all the other million Python answers that are in this site? if you have free time in your hands you can start adding a `print()` to literally all of them, because according to you they are "all wrong" and should work "on all compilers and interpreters" and "ideone is the most accurate editor" xD – Óscar López May 08 '21 at 09:02
  • Okay no worries i removed downvote now i use main compiled languages not interpreted so I think its fine for python language. Cheers – Haseeb Mir May 08 '21 at 12:07
9

You're resetting the value of b on each iteration, if a is a digit.

Perhaps you want:

b += int(a)

Instead of:

b = int(a)
b += 1
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • wow that works! could you explain why mine didnt work though? – user1864828 Jan 27 '13 at 17:34
  • 2
    The line `b = int(a)` sets the value of `b` to be the integer value of the digit character. Then you add one to it. In your example, the last digit is `3`, so you set `b` to `3` and then add `1`, getting `4`. Instead, you want to increment `b` by each digit's value. – Alex Reynolds Jan 27 '13 at 17:35
5

Another way of using built in functions, is using the reduce function:

>>> numeric = lambda x: int(x) if x.isdigit() else 0
>>> reduce(lambda x, y: x + numeric(y), 'hihello153john', 0)
9
grooveplex
  • 2,492
  • 4
  • 28
  • 30
JCash
  • 312
  • 1
  • 3
  • 10
1

One liner

sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
Cam
  • 14,930
  • 16
  • 77
  • 128
shantanoo
  • 3,617
  • 1
  • 24
  • 37
1

I would like to propose a different solution using regx that covers two scenarios:

1.
Input = 'abcd45def05'
Output = 45 + 05 = 50

import re
print(sum(int(x) for x in re.findall(r'[0-9]+', my_str)))

Notice the '+' for one or more occurrences

2.
Input = 'abcd45def05'
Output = 4 + 5 + 0 + 5 = 14

import re
print(sum(int(x) for x in re.findall(r'[0-9]', my_str)))
Santosh Pillai
  • 8,169
  • 1
  • 31
  • 27
1

Another way of doing it:

def digit_sum(n):
  new_n = str(n)
  sum = 0
  for i in new_n:
    sum += int(i)
  return sum
0

An equivalent for your code, using list comprehensions:

def sum_digits(your_string):
    return sum(int(x) for x in your_string if '0' <= x <= '9')

It will run faster then a "for" version, and saves a lot of code.

kaspersky
  • 3,959
  • 4
  • 33
  • 50
0

Just a variation to @oscar's answer, if we need the sum to be single digit,

def sum_digits(digit):
    s = sum(int(x) for x in str(digit) if x.isdigit())
    if len(str(s)) > 1:
        return sum_digits(s)
    else:
        return s
Babu
  • 2,548
  • 3
  • 30
  • 47
0
#if string =he15ll15oo10
#sum of number =15+15+10=40

def sum_of_all_Number(s):
    num = 0
    sum = 0

    for i in s:
        if i.isdigit():
            num = num * 10 + int(i)
        else:
            sum = sum + num
            num = 0
    return sum+num

#if string =he15ll15oo10
#sum of digit=1+5+1+5+1+0=13

def sum_of_Digit(s):
    sum = 0

    for i in s:
        if i.isdigit():
             sum= sum + int(i)

    return sum

s = input("Enter any String ")

print("Sum of Number =", sum_of_all_Number(s))
print("Sum Of Digit =", sum_of_Digit(s))
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Sanjay Rai
  • 27
  • 3
0

simply turn the input to integer by int(a) ---> using a.isdigit to make sure the input not None ('') , if the input none make it 0 and return sum of the inputs in a string simply

def sum_str(a, b):
    a = int(a) if a.isdigit() else 0
    b = int(b) if b.isdigit() else 0
    return f'{a+b}'
Not Bedo
  • 11
  • 2
  • Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Feb 13 '23 at 18:52