Why do we create another variance variable after the function?


Why do we create another variance variable after the function?


In order to use the functions we just made, we need to give them values. We have the list, grades, to pass our other functions, but the function to calculate standard deviation expects a variance value to be provided, which we don’t have anywhere.
It may seem confusing because we do have a variable named variance inside of the grades_variance() and grades_std_deviation() functions, but those variables only exist inside of those functions. This is called scope of a variable, or where it is accessible.
Think of the stuff inside of functions as only being accessible inside of that function, which is why return is so useful.


Why do we create a variable outside of the scope of the functions this time?

All other functions we were tasked with creating handle everything within their scope. I understand the benefit of having the data accessible by calling a variable instead of the function. However, why haven’t we done that for all of the previous functions as well? I imagine that data is just as important to statistics.


I agree, but would put it the other way round:
We always called the helper functions inside the new function.
And we got our result by calling a function with grades as args.

Wouldn’t it be more logical to follow through with this pattern, giving std_dev scores as param and having it call our_variance = variance(scores), then return our_variance ** 0.5?


That’s what I thought…below is my code which gave the correct answer in the console:

grades = [100, 100, 90, 40, 80, 100, 85, 70, 90, 65, 90, 85, 50.5]

def print_grades(grades_input):
  for grade in grades_input:
    print grade

def grades_sum(scores):
  total = 0
  for score in scores: 
    total += score
  return total
def grades_average(grades_input):
  sum_of_grades = grades_sum(grades_input)
  average = sum_of_grades / float(len(grades_input))
  return average

def grades_variance(scores):
  average = grades_average(scores)
  variance = 0
  for score in scores:
    variance += (average - score) ** 2
  return variance / float(len(scores))
print grades_variance(grades)

def grades_std_deviation(var):
  variance = grades_variance(var)
  return variance ** 0.5

but an error term came up at the bottom of the editor that said ’ grades_std_deviation(8.2222222222) raised an error: ‘float’ object is not iterable’…so it must work for some lists but not others.

The final three lines are the most important. I thought I’d just give the whole thing for reference.

1 Like

It would work for all lists, it’s just Codecademy thinks you would input floats into the function because the input should be the variance instead of the list, and you can’t use a for loop on a float (you used a for loop in grades_variance), so because Codecademy inputted a float, the console threw an error saying ‘float object is not iterable’. Your definition is better, but the reason you got it wrong was Codecademy’s expectations.

:grinning: yay! :heart_eyes:

Why does “variance ** (1/2)” give a different 9and wrong) result than “variance ** 0.5” ?


“One divided by two” does not return 0.5 in python 2. Recall that unless you specify otherwise, division rounds to a whole number (integers instead of floats). I tried it out and found that it rounded 1 / 2 to 0, which would definitely not be the result you want.

If you put in 0.5 it treats the number as a float rather than an integer and it also doesn’t ask python to do an unnecessary additional division operation.