1
\$\begingroup\$

I want to ask how to improve this code. Is it well-written or should anything be changed? Please let me know. And is it a bad thing to use arguments to store some info, such as the argument value here?

Here's the problem:

Write a recursive function that will receive an array of integers as an argument and as a result will check whether the sum of the array elements after the ith element is equal to the ith element itself. If all elements meet the condition, the function returns 1, otherwise it returns 0.

Test cases

nums([16,8,4,2,1,1]) # 1 first element is 16, we skip it and then  
# 8+4+2+1+1 = 16
nums([256,128,64,32,14,7,7]) # 0 first element 256, 128 + 64 + 32 + 14 + 7 + 7 its not 256 so we return 0
def list_of_numbers(nums, value=0, index=1):
    if index == len(nums):
        if value == nums[0]:
            return 1
        else:
            return 0
    else:
        return list_of_numbers(nums, value + nums[index], index + 1)

print(list_of_numbers([16, 8, 4, 2, 1, 1]))  # 1
print(list_of_numbers([256, 128, 64, 32, 14, 7, 7]))  # 0
\$\endgroup\$
3
  • \$\begingroup\$ The identifier list_of_numbers is not helpful. And there's no """docstring""". Tell us what it does, not what it accepts. We can always choose to express that later with a signature of def list_of_numbers(nums: list[int], value: int = 0, index:int = 1) -> int: if we'd like. \$\endgroup\$
    – J_H
    Jun 11, 2023 at 20:52
  • 1
    \$\begingroup\$ Judging by your problem statement and your example inputs, my assumption would be that the key test – namely, that nums[i] == sum(nums[i+1:]) – must be true for all values of i (other than the last). But your implementation only verifies that condition for i = 0. For example, it returns 1 for this input: [3, 1, 1, 1]. Please clarify. \$\endgroup\$
    – FMc
    Jun 11, 2023 at 23:44
  • \$\begingroup\$ [3, 1, 1, 1] this testcase as you give to me it should return one why because we take the first element and then from second element in array we sum to the end for example first element = 3 , and remaining elements are 1 + 1 +1 = 3 and it should return 1 if the remaining elements are not equal to the first element return 0 \$\endgroup\$
    – mcccuklev
    Jun 12, 2023 at 12:22

1 Answer 1

1
\$\begingroup\$

At least in most situations, if you mean true-false, don't return one-zero. The former is more explicit, readable, and communicative. And since bool is a subclass of int, the more explicit return values are still usable in numeric contexts.

Handle empty sequences. Your code blows up if given an empty sequence. It should either return None or raise an explicit ValueError.

Naming: functions do things. Although functions are things (they are objects), their primary purpose is to do things. As a result, their names usually involve verbs or verb-like operations. Your function name lacks that: it has no verb, implies no operation, and tells us nothing about what the function does (it's actually just an elaboration of the variable nums). Granted, this function is not easy to name (I tried my best below), but even an imperfect name conveying something about the function's behavior is better than a bland, noun-oriented name.

Naming: when feasible, be specific. The nums and index names are clear enough, but what is value? Rather than using a generic term like that, select something more explicit, such as total.

Consider processing the sequence in reverse order. The function is supposed to recurse over the sequence to compute a sum and then, at the end, return whether that sum equals the first number in the sequence. In that context, it seems a bit more intuitive to go in reverse order, eliminating the need to check len(nums) repeatedly. Just stop when you hit the index of zero.

Consider using a second function to handle the recursion. The optional arguments in your current implementation are not really part of the function's intended API. A common technique in recursive scenarios like this is to have two functions: (1) a top-level function for users to call, and (2) a secondary function to handle the recursion. The first function can handle any validations (for example, checking for empty sequences) and then make the appropriate call to bootstrap the recursion. The second function can be an inner function (as illustrated below) or another top-level function (use the latter if you ever need to call the recursive function separately, for example, for testing purposes).

def first_equals_sum_of_rest(nums):

    def check_seq(i, total):
        n = nums[i]
        if i == 0:
            return n == total
        else:
            return check_seq(i - 1, total + n)

    if nums:
        return check_seq(len(nums) - 1, 0)
    else:
        return None

Consider generalizing the recursive behavior. This programming exercise can be decomposed into two parts: (1) a simple equality check against the first number, and (2) computing a sum recursively. Why not make the sum computation a first-class citizen?

def first_equals_sum_of_rest(nums):
    if nums:
        return nums[0] == recursive_sum(nums, i = 1)
    else:
        return None

def recursive_sum(nums, i = 0, stop = None, total = 0):
    stop = len(nums) if stop is None else stop
    if i == stop:
        return total
    else:
        return recursive_sum(nums, i + 1, stop, total + nums[i])
\$\endgroup\$
1
  • \$\begingroup\$ Thank you a lot this was a question from university which said return 1 if its correct or 0 False \$\endgroup\$
    – mcccuklev
    Jun 12, 2023 at 19:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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