Julia G
Julia G

Reputation: 23

Why are these functions the same, but output a different value?

I wrote a function to calculate the mean of a list, and excluding the zeroes, the mean_val() is the function that should output 5.2200932159502855, but instead it outputs 6.525116519937857 even though its the same formula.

The mean_val2 function has the correct output: 5.2200932159502855 but this function doesn't exclude zeroes.

How do I make the mean_val() output 5.2200932159502855 while also excluding the zeroes from the list while also keeping it in this for loop format?

Here is the code + testing code:

val = [4, 3, 5, 0, 9, 3, 6, 0, 14, 15]
val1 = [4, 3, 5, 9, 3, 6, 14, 15]


def mean_val2(val1):    
    sum = 0
    for i in val1:
        print(i)
        sum += 1 / i  
        output = len(val1)/sum
    return output  
        
           
                
def mean_val(val): 
    sum = 0
    for i in val:
        if i != 0:  
            print(i)
            sum += 1 / i
            output2 = len(val)/sum  
    return output2
            
       
        
mean_out2 = mean_val2(val1) # 5.2200932159502855  correct output 
mean_out = mean_val(val) # 6.525116519937857
print (mean_out, mean_out2)

Upvotes: 2

Views: 111

Answers (2)

PythonProgrammi
PythonProgrammi

Reputation: 23463

I'd use one function for both lists:

val = [4, 3, 5, 0, 9, 3, 6, 0, 14, 15]
val1 = [4, 3, 5, 9, 3, 6, 14, 15]

            
def mean_val(val=[]) -> float: 
    sum_rec = 0
    zeros = 0
    for i in val:
        if i != 0:  
            print(i)
            sum_rec += 1 / i
        else:
            zeros += 1
    output2 = (len(val) - zeros) / sum_rec
    return output2
            
               
mean_out2 = mean_val(val1) # 5.2200932159502855  correct output 
mean_out = mean_val(val) # 5.2200932159502855  correct output
print (mean_out, mean_out2)

Upvotes: 0

Henry Ecker
Henry Ecker

Reputation: 35696

The len of val and val1 are different.

len(val) is 10.

len(val1) is 8

When you divide len/sum you will get a different result.

You could add a counter to keep track of the length of the elements you do process:

val = [4, 3, 5, 0, 9, 3, 6, 0, 14, 15]
val1 = [4, 3, 5, 9, 3, 6, 14, 15]


def mean_val2(val1_param):
    total = 0
    for i in val1_param:
        total += 1 / i
    output = len(val1_param) / total
    return output


def mean_val(val_param):
    total = 0
    non_zero_length = 0
    for i in val_param:
        if i != 0:
            total += 1 / i
            non_zero_length += 1
    output2 = non_zero_length / total
    return output2


mean_out2 = mean_val2(val1)
mean_out = mean_val(val)
print(mean_out, mean_out2)
print(mean_out == mean_out2)

Output:

5.2200932159502855 5.2200932159502855
True

General notes:

  1. You shouldn't use variable name sum as it shadows the name of the built-in function sum. I changed it to total in the modified code.
  2. Your function arguments should not have the same name as your lists defined in global scope. I added a _param suffix, but a more meaningful variable name would be better.

You could also reuse your functions. Instead of doing similar processing in both, you could instead filter out the 0s in your list and pass that to your mean_val2 function

def mean_val(val_param):
    return mean_val2([i for i in val_param if i != 0])


def mean_val2(val1_param):
    total = 0
    for i in val1_param:
        total += 1 / i
    output = len(val1_param) / total
    return output

As Comprehension:

def mean_val(lst):
    # Filter Out 0 Elements From List
    return mean_val2([i for i in lst if i != 0])


def mean_val2(lst):
    # Process List with No Zeros
    return len(lst) / sum([1 / i for i in lst])

Upvotes: 5

Related Questions