-5
\$\begingroup\$

Is there a way to make my code more concise?

Given 3 int values, a b c, return their sum. However, if one of the values is 13 then it does not count towards the sum and values to its right do not count. So for example, if b is 13, then both b and c do not count.

lucky_sum(1, 2, 3) → 6 
lucky_sum(1, 2, 13) → 3 
lucky_sum(1, 13, 3) → 1
def lucky_sum(a, b, c):
    illegal = 13
    if a  == illegal:
        return 0
    elif b == illegal:
        return a 
    elif c == illegal:
        return a + b
    else: 
        return a + b + c
\$\endgroup\$
8
\$\begingroup\$

Your code is OK for a simple case with 3 values. If you had more values, it would quickly go out of hand. Essentially, you want to sum values until you find an "illegal" value. We can implement this in terms of itertools.takewhile:

import itertools


def lucky_sum(a, b, c):
    """
    >>> lucky_sum(1, 2, 3)
    6
    >>> lucky_sum(1, 2, 13)
    3
    >>> lucky_sum(1, 13, 3)
    1
    >>> lucky_sum(13, 1, 3)
    0
    """
    illegal = 13

    return sum(itertools.takewhile(lambda x: x != illegal, [a, b, c]))

This can be easily extended to support a more general case with arbitrary number of arguments by replacing a, b, c with *args:

def lucky_sum(*args):
    # ...
    return sum(itertools.takewhile(lambda x: x != illegal, args))

doctests

Please include doctests like I did in this answer and also in my previous answers to your recent questions. If your script is in a file named lucky_sum.py, then you can run the doctests with:

python -m doctest lucky_sum.py

This is very handy. Covered with doctests, you can freely rewrite your implementation and easily verify it still works or not.

If you include doctests in your questions, you make the reviewer's job a lot easier. It would also show that you're learning from answers.

\$\endgroup\$
  • \$\begingroup\$ so all I need to include doctests is to run a program with this line: python -m doctest lucky_sum.py ? \$\endgroup\$ – noob81 Jul 26 '15 at 14:56
  • \$\begingroup\$ Exactly. It will output nothing if all tests pass. Otherwise it will print a detailed report about each failed test. \$\endgroup\$ – janos Jul 26 '15 at 15:04
  • \$\begingroup\$ I included your tests in the file's docstring but doctest outputs nothing... how do you choose which tests you run or do you just choose some values randomly? \$\endgroup\$ – noob81 Jul 26 '15 at 15:27
  • \$\begingroup\$ It runs all tests in the file. Empty output is normal. Change a value in the doctest to make it incorrect, and run again. It will print errors \$\endgroup\$ – janos Jul 26 '15 at 15:29
  • 3
    \$\begingroup\$ @noob That problem - test coverage - is a fundamental consideration in all testing, not just doctests. As you might imagine, complete coverage of all possible failure modes can be nontrivial. \$\endgroup\$ – lvc Jul 26 '15 at 15:53

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.