Find a number in a another number - python

How can I find if a number is in another number and it's location in python?
Example: finding if 58 is in 45896 and its location?
Output: True and 2 Place
PS: Is there a way without invoking strings. Just with number?

>>> x=str(45896)
>>> str(58) in x
True
>>> x.index(str('58')) + 1
2

Since you're asking for a method where the values are not converted to strings.
Beware, I've not tested this for all possible cases. So you may be able to find bugs. If and when you do, please let me know so I can fix this.
def find_length(num):
# If number is 0, return the length as 1.
if num == 0:
return 1
length = 0
# Loop over the number by dividing it by 10
# and incrementing the length counter.
while num != 0:
length += 1
num /= 10
return length
def find_inside(num1, num2):
# Trivial case, when the numbers are same.
if num1 == num2:
return (True, 1)
len_n2 = find_length(num2)
place = find_length(num1)
# Iterate over the numbers, extracting the last
# n digits everytime, where n is length of num2
# Keep dividing the original number by 10 and
# decrementing place everytime.
while num1 != 0:
if num2 == (num1 % (10 ** len_n2)):
return (True, place - len_n2 + 1)
num1 /= 10
place -= 1
return (False, -1)
Some test cases (Trivial):
>>> find_inside(10, 0)
(True, 2)
>>> find_inside(3456, 98)
(False, -1)
>>> find_inside(4589678, 58)
(True, 2)
>>> find_inside(10, 1)
(True, 1)

Another way using re:
re.search('58','45896').start()+1

One liner:
>>> x=45896
>>> y=58
>>> str(x).index(str(y))+1 if str(y) in str(x) else -1
2
>>>
Alternative (uses str(...) only for length!):
x=45896
y=58
yLength = len(str(y)) #you need the size!
t = 10**yLength
found = "false"
position = 0
while x > 0:
position = position +1
if(x%t == y):
found = "true"
break
x = x/10
print found
print str(position - 1)
NOTE: You can get the size easily without using str(...), but I will leave you to write that code.

If you want work without strings you will like this approach:
import math
original = 45896
find = 58
org_dgt = int(math.log10(original))+1
fnd_dgt = int(math.log10(find))+1
count = 1
found = False
while not found:
curr_dgt = org_dgt-fnd_dgt
if curr_dgt < 0:
break
if int((original%(10**org_dgt))/(10**(curr_dgt))) == find:
found = True
break
org_dgt -= 1
count += 1
if found:
print count
else:
print 'Not Found'

Related

Unable to get solution correct for submission

It is a sample problem for practice (here), and is not getting accepted due to it giving 'wrong answer'. It is compiling fine, but might be for different test inputs failing on submission.
I just request comment for the same, as hope that the issue must be small.
The problem statement is:
The program should accept first line of input as no. of strings, s.t. it is less than 10. And the next lines should contain one string each of length less than 100 characters. Need find occurrence of "gfg" in the strings.
If no occurrence is found, -1 should be returned.
#code
t = int(input())
if t > 10 or t<0:
exit()
arr = [[0] for i in range(t)]
total = [[-1] for i in range(t)]
for i in range(t):
arr[i] = [k for k in input().split()[:1]]
for j in arr[i]:
total[i] = j.count("gfg")
if total[i]==0: total[i]=-1
print (total[i])
t = int(input())
if t not in range(10):
exit()
else:
pass
total = []
for i in range(t):
line = input()[:100]
if line.count("gfg") == 0:
total.append(-1)
else:
total.append(line.count("gfg"))
print('\n'.join(map(str, total)))
SOLUTION FOR YOUR TASK:
t = int(input())
total = []
for i in range(1, t + 1):
line = input()
if len(line)<=100:
count = 0
for i in range(0, len(line) - 3 + 1):
if line[i:i + 3] == "gfg":
count += 1
if count != 0:
total.append(count)
else:
total.append(-1)
for i in total:
print (i)
NOTE: your submitting was failing because of special cases
For example:
in string gfgfg, your substring "gfg" occurres 2 times, and in that case you can't use the string count() method
how you can see ,here line[i:i + 3] I am moving index by index and checking next 3 values (because your substing "gfg" have length 3)
You are erasing the value of total[i] each time you iterate in the last loop :
>>> for j in arr[i]:
>>> total[i] = j.count("gfg")
>>> if total[i]==0:
>>> total[i]=-1
>>> print (total[i])
Do you want to count the occurences in each word or in the whole sentence ? Because then you just have to write :
>>> for i in range(t):
>>> n_occ = input().count("gfg")
>>> if n_occ != 0:
>>> total[i] = n_occ
If there's no occurence you don't have to do anything because the value in total is -1 already.
Also, write:
>>> total = [-1]*t
not:
>>> total = [[-1] for i in range(t)]

Find the numbers in string and Sum them using list comprehension [sum only 1-9] [duplicate]

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
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.
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
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
One liner
sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
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)))
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
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.
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
#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))
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}'

Python: Find longest binary gap in binary representation of an integer number

I would like to know if my implementation is efficient.
I have tried to find the simplest and low complex solution to that problem using python.
def count_gap(x):
"""
Perform Find the longest sequence of zeros between ones "gap" in binary representation of an integer
Parameters
----------
x : int
input integer value
Returns
----------
max_gap : int
the maximum gap length
"""
try:
# Convert int to binary
b = "{0:b}".format(x)
# Iterate from right to lift
# Start detecting gaps after fist "one"
for i,j in enumerate(b[::-1]):
if int(j) == 1:
max_gap = max([len(i) for i in b[::-1][i:].split('1') if i])
break
except ValueError:
print("Oops! no gap found")
max_gap = 0
return max_gap
let me know your opinion.
I do realize that brevity does not mean readability nor efficiency.
However, ability to spell out solution in spoken language and implement it in Python in no time constitutes efficient use of my time.
For binary gap: hey, lets convert int into binary, strip trailing zeros, split at '1' to list, then find longest element in list and get this element lenght.
def binary_gap(N):
return len(max(format(N, 'b').strip('0').split('1')))
Your implementation converts the integer to a base two string then visits each character in the string. Instead, you could just visit each bit in the integer using << and &. Doing so will avoid visiting each bit twice (first to convert it to a string, then to check if if it's a "1" or not in the resulting string). It will also avoid allocating memory for the string and then for each substring you inspect.
You can inspect each bit of the integer by visiting 1 << 0, 1 << 1, ..., 1 << (x.bit_length).
For example:
def max_gap(x):
max_gap_length = 0
current_gap_length = 0
for i in range(x.bit_length()):
if x & (1 << i):
# Set, any gap is over.
if current_gap_length > max_gap_length:
max_gap_length = current_gap_length
current_gap_length = 0
else:
# Not set, the gap widens.
current_gap_length += 1
# Gap might end at the end.
if current_gap_length > max_gap_length:
max_gap_length = current_gap_length
return max_gap_length
def max_gap(N):
xs = bin(N)[2:].strip('0').split('1')
return max([len(x) for x in xs])
Explanation:
Both leading and trailing zeros are redundant with binary gap finding
as they are not bounded by two 1's (left and right respectively)
So step 1 striping zeros left and right
Then splitting by 1's yields all sequences of 0'z
Solution: The maximum length of 0's sub-strings
As suggested in the comments, itertools.groupby is efficient in grouping elements of an iterable like a string. You could approach it like this:
from itertools import groupby
def count_gap(x):
b = "{0:b}".format(x)
return max(len(list(v)) for k, v in groupby(b.strip("0")) if k == "0")
number = 123456
print(count_gap(number))
First we strip all zeroes from the ends, because a gap has to have on both ends a one. Then itertools.groupby groups ones and zeros and we extract the key (i.e. "0" or "1") together with a group (i.e. if we convert it into a list, it looks like "0000" or "11"). Next we collect the length for every group v, if k is zero. And from this we determine the largest number, i.e. the longest gap of zeroes amidst the ones.
I think the accepted answer dose not work when the input number is 32 (100000). Here is my solution:
def solution(N):
res = 0
st = -1
for i in range(N.bit_length()):
if N & (1 << i):
if st != -1:
res = max(res, i - st - 1)
st = i
return res
def solution(N):
# write your code in Python 3.6
count = 0
gap_list=[]
bin_var = format(N,"b")
for bit in bin_var:
if (bit =="1"):
gap_list.append(count)
count =0
else:
count +=1
return max(gap_list)
Here is my solution:
def solution(N):
num = binary = format(N, "06b")
char = str(num)
find=False
result, conteur=0, 0
for c in char:
if c=='1' and not find:
find = True
if find and c=='0':
conteur+=1
if c=='1':
if result<conteur:
result=conteur
conteur=0
return result
this also works:
def binary_gap(n):
max_gap = 0
current_gap = 0
# Skip the tailing zero(s)
while n > 0 and n % 2 == 0:
n //= 2
while n > 0:
remainder = n % 2
if remainder == 0:
# Inside a gap
current_gap += 1
else:
# Gap ends
if current_gap != 0:
max_gap = max(current_gap, max_gap)
current_gap = 0
n //= 2
return max_gap
Old question, but I would solve it using generators.
from itertools import dropwhile
# a generator that returns binary
# representation of the input
def getBinary(N):
while N:
yield N%2
N //= 2
def longestGap(N):
longestGap = 0
currentGap = 0
# we want to discard the initial 0's in the binary
# representation of the input
for i in dropwhile(lambda x: not x, getBinary(N)):
if i:
# a new gap is found. Compare to the maximum
longestGap = max(currentGap, longestGap)
currentGap = 0
else:
# extend the previous gap or start a new one
currentGap+=1
return longestGap
Can be done using strip() and split() function :
Steps:
Convert to binary (Remove first two characters )
Convert int to string
Remove the trailing and starting 0 and 1 respectively
Split with 1 from the string to find the subsequences of strings
Find the length of the longest substring
Second strip('1') is not mandatory but it will decrease the cases to be checked and will improve the time complexity
Worst case T
def solution(N):
return len(max(bin(N)[2:].strip('0').strip('1').split('1')))
Solution using bit shift operator (100%). Basically the complexity is O(N).
def solution(N):
# write your code in Python 3.6
meet_one = False
count = 0
keep = []
while N:
if meet_one and N & 1 == 0:
count+=1
if N & 1:
meet_one = True
keep.append(count)
count = 0
N >>=1
return max(keep)
def solution(N):
# write your code in Python 3.6
iterable_N = "{0:b}".format(N)
max_gap = 0
gap_positions = []
for index, item in enumerate(iterable_N):
if item == "1":
if len(gap_positions) > 0:
if (index - gap_positions[-1]) > max_gap:
max_gap = index - gap_positions[-1]
gap_positions.append(index)
max_gap -= 1
return max_gap if max_gap >= 0 else 0
this also works:
def solution(N):
bin_num = str(bin(N)[2:])
list1 = bin_num.split('1')
max_gap =0
if bin_num.endswith('0'):
len1 = len(list1) - 1
else:
len1 = len(list1)
if len1 != 0:
for i in range(len1):
if max_gap < len(list1[i]):
max_gap = len(list1[i])
return max_gap
def solution(number):
bits = [int(digit) for digit in bin(number)[2:]]
occurences = [i for i, bit in enumerate(bits) if(bit==1)]
res = [occurences[counter+1]-a-1 for counter, a in enumerate(occurences) if(counter+1 < len(occurences))]
if(not res):
print("Gap: 0")
else:
print("Gap: ", max(res))
number = 1042
solution(number)
This works
def solution(number):
# convert number to binary then strip trailing zeroes
binary = ("{0:b}".format(number)).strip("0")
longest_gap = 0
current_gap = 0
for c in binary:
if c is "0":
current_gap = current_gap + 1
else:
current_gap = 0
if current_gap > longest_gap:
longest_gap = current_gap
return longest_gap
def max_gap(N):
bin = '{0:b}'.format(N)
binary_gap = []
bin_list = [bin[i:i+1] for i in range(0, len(bin), 1)]
for i in range(len(bin_list)):
if (bin_list[i] == '1'):
# print(i)
# print(bin_list[i])
# print(binary_gap)
gap = []
for j in range(len(bin_list[i+1:])):
# print(j)
# print(bin_list[j])
if(bin_list[i+j+1]=='1'):
binary_gap.append(j)
# print(j)
# print(bin_list[j])
# print(binary_gap)
break
elif(bin_list[i+j+1]=='0'):
# print(i+j+1)
# print(bin_list[j])
# print(binary_gap)
continue
else:
# print(i+j+1)
# print(bin_list[i+j])
# print(binary_gap)
break
else:
# print(i)
# print(bin_list[i])
# print(binary_gap)
binary_gap.append(0)
return max(binary_gap)
pass
def find(s, ch):
return [i for i, ltr in enumerate(s) if ltr == ch]
def solution(N):
get_bin = lambda x: format(x, 'b')
binary_num = get_bin(N)
print(binary_num)
binary_str = str(binary_num)
list_1s = find(binary_str,'1')
diffmax = 0
for i in range(len(list_1s)-1):
if len(list_1s)<1:
diffmax = 0
break
else:
diff = list_1s[i+1] - list_1s[i] - 1
if diff > diffmax:
diffmax = diff
return diffmax
pass
def solution(N: int) -> int:
binary = bin(N)[2:]
longest_gap = 0
gap = 0
for char in binary:
if char == '0':
gap += 1
else:
if gap > longest_gap:
longest_gap = gap
gap = 0
return longest_gap
Here's a solution using iterators and generators that will handle edge cases such as the binary gap for the number 32 (100000) being 0 and the binary gap for 0 being 0. It doesn't create a list, instead relying on iterating and processing elements of the bit string one step at a time for a memory efficient solution.
def solution(N):
def counter(n):
count = 0
preceeding_one = False
for x in reversed(bin(n).lstrip('0b')):
x = int(x)
if x == 1:
count = 0
preceeding_one = True
yield count
if preceeding_one and x == 0:
count += 1
yield count
yield count
return(max(counter(N)))
Here is one more that seems to be easy to understand.
def count_gap(x):
binary_str = list(bin(x)[2:].strip('0'))
max_gap = 0
n = len(binary_str)
pivot_point = 0
for i in range(pivot_point, n):
zeros = 0
for j in range(i + 1, n):
if binary_str[j] == '0':
zeros += 1
else:
pivot_point = j
break
max_gap = max(max_gap, zeros)
return max_gap
This is really old, I know. But here's mine:
def solution(N):
gap_list = [len(gap) for gap in bin(N)[2:].strip("0").split("1") if gap != ""]
return max(gap_list) if gap_list else 0
Here is another efficient solution. Hope it may helps you. You just need to pass any number in function and it will return longest Binary gap.
def LongestBinaryGap(num):
n = int(num/2)
bin_arr = []
for i in range(0,n):
if i == 0:
n1 = int(num/2)
bin_arr.append(num%2)
else:
bin_arr.append(n1%2)
n1 = int(n1/2)
if n1 == 0:
break
print(bin_arr)
result = ""
count = 0
count_arr = []
for i in bin_arr:
if result == "found":
if i == 0:
count += 1
else:
if count > 0:
count_arr.append(count)
count = 0
if i == 1:
result = 'found'
else:
pass
if len(count_arr) == 0:
return 0
else:
return max(count_arr)
print(LongestBinaryGap(1130)) # Here you can pass any number.
My code in python 3.6 scores 100
Get the binary Number .. Get the positions of 1
get the abs differennce between 1.. sort it
S = bin(num).replace("0b", "")
res = [int(x) for x in str(S)]
print(res)
if res.count(1) < 2 or res.count(0) < 1:
print("its has no binary gap")
else:
positionof1 = [i for i,x in enumerate(res) if x==1]
print(positionof1)
differnce = [abs(j-i) for i,j in zip(positionof1, positionof1[1:])]
differnce[:] = [differnce - 1 for differnce in differnce]
differnce.sort()
print(differnce[-1])
def solution(N):
return len(max(bin(N).strip('0').split('1')[1:]))
def solution(N):
maksimum = 0
zeros_list = str(N).split('1')
if zeros_list[-1] != "" :
zeros_list.pop()
for item in zeros_list :
if len(item) > maksimum :
maksimum = len(item)
return(maksimum)
def solution(N):
# Convert the number to bin
br = bin(N).split('b')[1]
sunya=[]
groupvalues=[]
for i in br:
count = i
if int(count) == 1:
groupvalues.append(len(sunya))
sunya=[]
if int(count) == 0:
sunya.append('count')
return max(groupvalues)
def solution(N):
bin_num = str(bin(N)[2:])
bin_num = bin_num.rstrip('0')
bin_num = bin_num.lstrip('0')
list1 = bin_num.split('1')
max_gap = 0
for i in range(len(list1)):
if len(list1[i]) > max_gap:
max_gap = len(list1[i])
return (max_gap)

Python : parasitic number

In general, a positive natural number that can be multiplied by n
by moving the rightmost digit to the front of the number is called an n
-parasitic number. Here n is itself a single-digit positive natural number. For example: 4×128205=512820
4×128205=512820
so 128205 is a 4-parasitic number. Natural numbers with leading zeros are not allowed. So even though
4×025641=102564
4×025641=102564
the number 025641 is not 4-parasitic.
Assignment: write a function parasitic that takes a natural number. In case the given natural number is n-parasitic, the function must return the value n. Otherwise, the function must return the value 0.
My code (last definition parastic(number)) is not working for some cases for example: parasitic(142857)
n = 5 while with my code I return 0.
def rotateLeft(number):
"""
>>> rotateLeft(717948)
179487
>>> rotateLeft(142857)
428571
>>> rotateLeft(105263157894736842)
52631578947368421
"""
k = str(number)
letter = k[:1]
numb = k[1:]
resultaat = str(numb) + str(letter)
return int(resultaat)
def rotateRight(number):
"""
>>> rotateRight(179487)
717948
>>> rotateRight(428571)
142857
>>> rotateRight(52631578947368421)
15263157894736842
"""
k = str(number)
letter = k[-1]
numb = k[:-1]
resultaat = str(letter) + str(numb)
return int(resultaat)
def parasitic(number):
"""
>>> parasitic(179487)
4
>>> parasitic(142857)
5
>>> parasitic(105263157894736842)
2
>>> parasitic(1234)
0
"""
count = 0
getal = count * number
while getal != rotateLeft(number):
count += 1
getal = count * number
if getal == rotateLeft(number):
break
return (count)
else:
return 0
While using a while loop may improve your grasp of python, this can be solved rather simply using the % operator.
def rotateRight(number):
"""
>>> rotateRight(179487)
717948
>>> rotateRight(428571)
142857
>>> rotateRight(52631578947368421)
15263157894736842
"""
k = str(number)
return int(k[-1] + k[:-1])
def parasitic(number):
rotated = rotateRight(number)
if not rotated % number:
return rotated // number
else:
return 0
This tests to see if number is divisible by the number obtained by a right-rotation, and, if so, returns the divisor (the // operator rounds the result to the nearest integer, but we already know the result must be an integer)
I have written a function that seems to do the job for your examples!
It uses concatenation of string slices and compares this against the num. I think a trick is that n can only ever be between 2 and 11 for this to work as otherwise the shift by 1 at the end would never make the original number.
Here's the code:
def parasitic(num):
for n in range(2, 11):
res = n * num
if str(num)[-1] + str(num)[:-1] == str(res):
return n
return False
Testing:
>>> parasitic(128205)
4
>>> parasitic(142857)
5
>>> parasitic(105263157894736842)
2
>>> parasitic(35)
False
Your issue (having removed break, which is the first issue as it ends before it can return anything):
if getal==rotateLeft(number):
return count
else:
return 0
I think you intended a while-else loop, but you ended up with "if the first result doesn't work, return 0". You need to change indentation so the else lines up the the while (so if no result is found, return 0), not the if. You will also have to add a limit of what to check, or if there is no result it will go on forever.
while getal != rotateLeft(number):
count += 1
getal = count * number
if getal == rotateLeft(number):
return (count)
else:
return 0
If your number is parasitic, the while loop will eventually stop even without you put break in it. I would suggest not to use while loop with this current conditon, since this will be infinity-loop if the number is not parasitic.
But I may show that your code would work if you remove the return in else condition. And also you may want to add both condition of rotateLeft and rotateRight :
def parasitic(number):
count = 0;
getal = count * number;
while getal != rotateLeft(number) and getal != rotateRight(number) :
count += 1
getal = int(count * number)
if getal == rotateLeft(number) or getal == rotateRight(number) :
print(count); print(getal);
return (count)
else:
pass
Hope this helps.
if getal == rotateLeft(number):
break
return (count)
Since break leaves the loop, you cannot ever reach the return statement; your code would simply fall off the end of the function, and return None.
Also, your double-check of getal == rotateLeft(number) signals poor loop design; you should be able to test this once at the top of the loop, without making a second check within.
REPAIR
You have to handle two cases:
If you find a multiplier that matches the rotation, return that multiplier.
If all valid multipliers fail, then you return 0.
So (a) how many multipliers do you try before you give up?
(b) where do you put the two different return statements to handle those cases?

Sum of digits in a string

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
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.
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
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
One liner
sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
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)))
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
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.
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
#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))
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}'

Categories