2
\$\begingroup\$

Add 2 strings representing 2 doubles, return the sum of the 2 doubles in string format. Please review my code. Is there a cleaner way of writing the code where we have to add the 2 doubles digit by digit?

for example, s1 is '9.9' and s2 is '8.8', we need to return '18.7'. The requirement is that we cannot pad zeros for cases like adding '9.9' and '7.899'. In another word, we cannot change the input into '9.900' (i.e: with padded 0's) and '7.899'.

we have to add the two input digit by digit. For example, if s1 = '9.9' and s2 = '7.899', then we need to do 8+9 (the digit after the decimal point in s1 and s2), 9+7 (the two digits before the decimal points in s1 and s2). In another words, please do not use internal libraries to convert the two numbers into float and add them together.

def addDoubles(s1, s2):
    s1Split = s1.find('.')
    s2Split = s2.find('.')
    s1Post = ''
    s2Post = ''
    if s1Split != -1:
        s1Post = s1[s1Split+1:]
    if s2Split != -1:
        s2Post = s2[s2Split+1:] 
    s1PostLen = len(s1Post)
    s2PostLen = len(s2Post)
    s1PostLonger = s2PostLonger = False
    postLenDiff = 0  
    if s1PostLen > s2PostLen:
        #s2Post = s2Post + '0'*(s1PostLen-s2PostLen)
        s1PostLonger = True 
        postLenDiff = s1PostLen - s2PostLen
    elif s1PostLen < s2PostLen:
        #s1Post = s1Post + '0'*(s2PostLen-s1PostLen)
        s2PostLonger = True
        postLenDiff = s2PostLen - s1PostLen
    if s1Split != -1:
        s1New = s1[:s1Split] + s1Post 
    else:
        s1New = s1
    if s2Split != -1:
        s2New = s2[:s2Split] + s2Post 
    else:
        s2New = s2
    postSum = helper(s1New, s2New, postLenDiff, s1PostLonger, s2PostLonger)
    print('s2PostLonger =', s2PostLonger)
    if s1PostLonger or (s1PostLonger == s2PostLonger == False and s1Post != ''):
        postSum = postSum[:-s1PostLen] + '.' + postSum[-s1PostLen:]
    elif s2PostLonger:
        postSum = postSum[:-s2PostLen] + '.' + postSum[-s2PostLen:]
    return postSum

def helper(one, two, postLenDiff, s1PostLonger, s2PostLonger):
    oneIdx = len(one)-1
    twoIdx = len(two)-1
    curSum = 0 
    res = ''
    if s1PostLonger:
        res = one[-postLenDiff:]
        oneIdx = oneIdx - postLenDiff
    elif s2PostLonger:
        res = two[-postLenDiff:]
        twoIdx = twoIdx - postLenDiff
    while oneIdx >= 0 or twoIdx >= 0 or curSum>0:
        if oneIdx >= 0:
            curSum += int(one[oneIdx])
            oneIdx -= 1 
        if twoIdx >= 0:
            curSum += int(two[twoIdx]) 
            twoIdx -= 1
        res = str(curSum%10) + res 
        curSum //= 10
    return res
\$\endgroup\$
5
  • 1
    \$\begingroup\$ What do you mean by digit by digit? Two digits ≥ 5 cannot be added like that. \$\endgroup\$
    – Alex Povel
    May 8 '20 at 7:30
  • \$\begingroup\$ Would you show us an example input and your expected output? There is a lot of code here for something that sounds simple based just on your stated requirements. \$\endgroup\$
    – Preston
    May 8 '20 at 10:08
  • 1
    \$\begingroup\$ Thank you for the input. I've edited the code requirement to specify what I want. \$\endgroup\$
    – Jin Huang
    May 8 '20 at 13:42
  • \$\begingroup\$ You said when you add '9.9' and '7.899', you start with the '9' + '8'. What about the '99' at the end? Do you drop it and get '17.7'? Or do you expect to get '17.799' ? \$\endgroup\$
    – RootTwo
    May 8 '20 at 23:26
  • \$\begingroup\$ hi, I expect to get '17.799'. the '99' is concatenated to the result. \$\endgroup\$
    – Jin Huang
    May 9 '20 at 0:05
1
\$\begingroup\$

If your need is truly

Add 2 strings representing 2 doubles, return the sum of the 2 doubles in string format.

then it is as easy as

def add_strings(x, y):
    return str(float(x) + float(y))

a = add_strings("2.3", "4.5")

print(a)
print(type(a))

which gives

6.8
<class 'str'>

Note that returning a numerical string is a strange and mostly not required operation in the Python world. The function should return without the str call, and the conversion to string will either be implicit (like print can do it) or explicit by the user of that function. If you hand the returned string into a new function that does, say, multiplication, and that function has to convert string to float again... you see the unnecessary chain there.

Other than that, your code can benefit from sticking to the PEP 8 Style Guide. Most of all, in this case, having all variables in snake_case can save you from hearing "PEP 8"-comments again. In res = '', you could issue res = "", since those quotes are impossible to mistake. '' can look like ".

\$\endgroup\$
3
  • \$\begingroup\$ Hi, how do I make the code cleaner if I cannot just directly convert the input into float and add them together? Thank you so much for your input. I've edited my original post to make clear what I want. Can you please take a look? \$\endgroup\$
    – Jin Huang
    May 8 '20 at 13:45
  • \$\begingroup\$ Your edit sounds like quite the other-worldly requirement. Converting to float is not an "internal library"... I guess technically, it is, but it is so much a very core language feature that forbidding it is very strange. And I still do not understand your "digit by digit" requirement. How do you handle addition of two digits greater equal 5 (or rather, how would you want to)? If this is a task from some teacher, please reassure you understood correctly. Lastly, please provide a more elaborate input/output sample. \$\endgroup\$
    – Alex Povel
    May 8 '20 at 16:14
  • \$\begingroup\$ Hi, when both of the 2 digits are greater than 5, there is a "carry" of 1 to the next digits summation. so when I add "1.6" + "1.5" I do '6'+'5' = '11' and there is a 'carry' of '1' in the summation of '1'+'1'. so I do '1' + '1' + '1' = 3. I get a result of '3.1' \$\endgroup\$
    – Jin Huang
    May 9 '20 at 0:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.