How to define a variable in a function when calling the function? - python

When I run my code I get “NameError: name ‘mean’ is not defined”. I get this error when I try to call my function “calculateVariance(mean, nums)”. I can not seem to figure out how I can define ‘mean’ without having to changing my “calculateVariance(mean, nums)” function.. if that makes sense..
Here is the code:
import math
import matplotlib.pyplot as plt
def readFile(file_name):
with open('data_1.txt', 'r') as DataOne:
nums = DataOne.read()
print(nums)
return nums
def calculateMean(nums):
sumOfNums = 0
for i in range(len(nums)):
sumOfNums += i
mean = sumOfNums//len(nums)
print("The mean is : ", mean)
return mean
def calculateVariance(mean, nums):
squaredDifferences = 0
for number in nums:
difference =mean - number
squaredDiff = difference ** 2
squaredDifferences += squaredDiff
variance = squaredDifferences // (len(nums)-1)
print(" The variance is : ", variance)
return variance
def calculateSD(variance):
square_root = math.sqrt(number)
StandDev = square_root(variance)
print("Standard Deviation is : ", StandDev)
return StandDev
def showHistogram(nums):
num_bins = 10
plt.hist(listOfNums, num_bins)
plt.show()
nums = readFile('data_1.txt')
calculateMean(nums)
calculateVariance(mean, nums)
calculateSD(variance)

When you are calling the function which returns mean, you are not actually saving it. Therefore it cannot be used when calling a different function.
Try saving it as mean_result or similar to use for later (avoiding naming clashes).

You should store mean result from function calculateMean(nums) in a variable. You need to do it for another function as well.
import math
import matplotlib.pyplot as plt
def readFile(file_name):
with open('data_1.txt', 'r') as DataOne:
nums = DataOne.readlines()
print(nums)
return nums
def calculateMean(nums):
sumOfNums = 0
for i in range(len(nums)):
sumOfNums += i
mean = sumOfNums//len(nums)
print("The mean is : ", mean)
return mean
def calculateVariance(mean, nums):
squaredDifferences = 0
for number in nums:
if number != '':
difference = mean - int(number.replace('\n', ''))
squaredDiff = difference ** 2
squaredDifferences += squaredDiff
variance = squaredDifferences // (len(nums)-1)
print(" The variance is : ", variance)
return variance
def calculateSD(variance):
square_root = math.sqrt(number)
StandDev = math.sqrt(variance)
print("Standard Deviation is : ", StandDev)
return StandDev
def showHistogram(nums):
num_bins = 10
plt.hist(listOfNums, num_bins)
plt.show()
nums = readFile('data_1.txt')
mean = calculateMean(nums)
variance = calculateVariance(mean, nums)
stdev = calculateSD(variance)

Related

Python: defining a function with mean and standard deviation calculation

I am trying to calculate mean and the population standard deviation without using stats module...and my code will be
total = 0
sum3 = 0
def stats():
global total
for numbers in range(0,len(my_list)):
total = total + my_list[numbers]
mean = total / len(my_list)
print(mean)
for numbers in range(0,len(my_list)):
global sum3
sum3 = sum3 + (my_list[numbers] - mean)**2
sum21 = sum3 / len(my_list)
standard_dev = sum21**(1/2)
print(standard_dev)
my_list1 = input()
my_list = my_list1.split()
print(my_list)
stats()
also help me to assign a list of numbers to int.....thank u
Try this code. The stats methods have not been used here.
Only python methods have been used to speed up the functions.
def mean(my_list):
sum = sum(my_list)
return sum/len(my_list)
def standard_deviation(my_list):
mean = mean(my_list)
temp = 0
for item in my_list:
temp = temp + ((item - mean) ** 2)
return (temp/len(my_list))**0.5
This seems like a nice place to use list comprehension for brevity's sake.
def mean(l):
return sum(l) / len(l)
def stdev(l):
# Get the mean of the list
m = mean(l)
# Subtract the mean from each item and square the result
# Take the mean from the resulting list
m_of_sqrd = mean([(i-m)**2 for i in l])
# Return the root
return m_of_sqrd ** 0.5
inp = input()
values = [int(item) for item in inp.split()]
print(mean(values))
print(stdev(values))

Turn 2 integers in to 1

I have a method that is retrieving a couple of random numbers. I then want to combine randoma and randomb to be one number
For example if randoma = 2 and randomb = 150, I want it to return 2150
I am unsure how to do so. The #'s are where my unknown return statement would be.
def display()
total = setnums()
print("total = " + total)
def setnums():
randoma = random.randint(1, 5)
randomb = random.randint(100,1000)
return ########
In Python 3.6 and newer:
int(f'{randoma}{randomb}')
In Python older than 3.6:
int(str(randoma) + str(randomb))
Convert them to strings and concatenate them.
return int(str(randoma) + str(randomb))
int(str(randoma) + str(randomb))
If you want to do it using simple mathematic without converting to string
from math import floor, log10, pow
from random import randint
def display():
total = setnums()
print(total)
def setnums():
randoma = randint(1, 5)
randomb = randint(100,1000)
print(randoma)
print(randomb)
numberOfDigitsInFirstRandNumber = floor(log10(randomb))
numberOfDigitsInSecondRandNumber = floor(log10(randomb))
totalDigitCount = numberOfDigitsInFirstRandNumber + numberOfDigitsInSecondRandNumber
multiplyingFactor = pow(10, totalDigitCount - 1)
return (randoma * multiplyingFactor ) + randomb
display()
Basically what you do is to sum the number of digits in both numbers, subtract one from it and raise 10 to the power of the result, then multiple the first random number by the result and add it to the second random number.
you can try it out from here https://repl.it/repls/StainedRashArchive
TL;DR:
In Python >= 3.6 use f-strings:
return int(f'{randoma}{randomb}')
In Python < 3.6 use the + Operator:
int(str(randoma) + str(randomb))
Keep it simple, readable, and test in your own environment which option suits you best.
Given the following function:
def setnums():
randoma = random.randint(1, 5)
randomb = random.randint(100, 1000)
r = ##
return int(r)
Execution time in python3.6:
r = f"{randoma}{randomb}"
2.870281131
r = "%s%s" % (randoma, randomb)
2.9696586189999996
r = str(randoma) + str(randomb)
3.084615994999999
r = "".join((str(randoma), str(randomb)))
3.1661511100000013
def setnums():
randoma = str(random.randint(1, 5))
randomb = str(random.randint(100, 1000))
randoma += randomb
return int(randoma)
3.0611202350000006
Execution time in python2.7:
r = "%s%s" % (randoma, randomb)
2.46315312386
r = str(randoma) + str(randomb)
2.56769394875
r = "".join((str(randoma), str(randomb)))
2.68126797676
def setnums():
randoma = str(random.randint(1, 5))
randomb = str(random.randint(100, 1000))
randoma += randomb
return int(randoma)
2.53426408768
Literal String Interpolation (PEP 498).
Splitting, Concatenating, and Joining Strings in Python
Use the 'str' function to convert randoma and randomb to strings, concatenate by using '=', then convert the concatenated string to integer by using the 'int' function.

Which data structure to store inputted numbers?

Which data structure is best for calculating average of inputted numbers ?
I used an array, but it feels clumsy.
Is there a more standard way to do this?
import os
def getGrades():
g = input("How many tests?")
numGrades = int(g)
grades = []*numGrades
for x in range(numGrades):
t = int(input("Enter Grade #" + str(x+1) + ": "))
grades.append(t)
avgGrades(grades)
def avgGrades(a):
total = 0
count = 0
for t in a:
total = total + t
count = count + 1
avg = total / count
print (f"average is: {avg}")
getGrades()
There is a statistics module which you can use:
import statistics
def get_grades_avg():
g = input("How many tests?")
num_grades = int(g)
grades = [] * num_grades
for x in range(num_grades):
grades.append(int(input("Enter Grade #" + str(x + 1) + ": ")))
return statistics.mean(grades)
avg = get_grades_avg()
print('avg: {}'.format(avg))
Using Python list is well. Maybe trying some built-in functions for getting average grade would be more easily.
Assume grades is a list store some grade.
sum(grades) / len(grades)
You can use something like this:
def average_factory():
count_numbers = 0
sum_numbers = 0
def wrapper(number):
nonlocal count_numbers
nonlocal sum_numbers
sum_numbers += number
count_numbers += 1
return sum_numbers / count_numbers
return wrapper
def get_number(message):
str_number = input(message)
try:
return int(str_number)
except (ValueError, TypeError):
print('Invalid number, please try again')
return get_number(message)
def get_average_of_all_tests():
count_tests = get_number('How many tests? ')
get_average = average_factory()
average = 0
for test_number in range(1, count_tests + 1):
number = get_number('Enter Grade #{test_number}: '.format(test_number=test_number))
average = get_average(number)
return average
Yes this solution seems a little complex with average factory. But I think storing all value just for calculating average is not so good idea. Storing only count and sum of grades is better.
If you have any question about solution feel free to ask me about it.
numpy or scipy offer good facilities for this.
store your numbers in an numpy.array([]).
To obtain your mean, numpy.mean(<yourarray>)
Your code would look like:
import numpy
import os
def getGrades():
g = input("How many tests?")
numGrades = int(g)
grades = []*numGrades
for x in range(numGrades):
t = int(input("Enter Grade #" + str(x+1) + ": "))
grades.append(t)
yourArray = numpy.array(grades)
return numpy.mean(yourArray)

Copy float values from within lists of lists

I do apologize if I'm not looking in the right places, but I cannot for the life of me figure out how to get a value from say
list[[1,2,3][4,5,6.01]] , list[1][2] integrated into code as anything but a list.
import random
fruits = [
['mango',7],
['apple',4],
['kiwi',6],
['grape',12],
['pear',3]
]
#Finding Probability
def setup():
fsum = 0;
prob = 0;
i = 0
#Finding the sum
while i < len(fruits):
fsum += fruits[i][1]
i += 1
i = 0
#Calculating Probability
while i < len(fruits):
prob = [fruits[i][1] / fsum]
fruits[i].append(prob)
i += 1
print(fsum)
print(fruits)
setup()
def pick(x):
rand = random.random()
index = 0
while rand > 0:
#How do I get the value of the float in the list from the next line
#(fruits[index][2])
#to be stored in a variable that I can plug into this.
#rand = rand - (var)
index+=1
pick (fruits)
Any feedback would be greatly appreciated.
Your problem is this line:
prob = [fruits[i][1] / fsum]
You are defining prob to be a list with one value, just eliminate the unnecessary list, e.g.:
prob = fruits[i][1] / fsum
Then fruits[index][2] will be the probability.
You should consider replacing your while loops with for loops, e.g.:
while i < len(fruits):
fsum += fruits[i][1]
i += 1
i = 0
Is equivalent to:
for fruit in fruits:
fsum += fruit[1]
Which could be be accomplished with a generator expression:
fsum = sum(fruit[1] for fruit in fruits)
But if what you are looking to do is just pick the fruit based on the relative weights (fruits[i][1]) then there is an easier way to do this in Py3.6, without the setup(), e.g.:
def pick(fruits):
items, weights = zip(*fruits)
return random.choices(items, weights)[0]
Prior to Py3.6 you could do:
def pick(fruits):
return random.choice([f for fruit in fruits for f in [fruit[0]]*fruit[1]])
Just access the first item of the list/array, using the index access and the index 0:
var = fruits[index][2][0]

How to create a proper histogram in python with only one value

I wrote a function aveMean(die, numRolls, numTrials) which requires the following:
Blockquote
die, a Die
numRolls, numTrials, are positive ints
Calculates the expected mean value of the longest run of a number over numTrials runs of numRolls rolls.
Calls makeHistogram to produce a histogram of the longest runs for all the trials. There should be 10 bins in the histogram
Choose appropriate labels for the x and y axes.
Returns the mean calculated
Blockquote
Everything works fine, except:
the list has just one item
the items in the list are equal
or the numRolls are limited to one roll
This is how it should look like
You see that in 1.-3. there is always a little extra bar (barely visible) on the left side. How can I get rid of it? I read something about this is due to Python 3, but I didn't find out a solution.
Thanks!
P.S. I edited the code how to call the histogram and also the function that uses the call to create the histogram:
def getMeanAndStd(X):
mean = sum(X)/float(len(X))
tot = 0.0
for x in X:
tot += (x - mean)**2
std = (tot/len(X))**0.5
return mean, std
class Die(object):
def __init__(self, valList):
""" valList is not empty """
self.possibleVals = valList[:]
def roll(self):
return random.choice(self.possibleVals)
def makeHistogram(values, numBins, xLabel, yLabel, title=None):
pylab.hist(values, numBins)
pylab.xlabel(xLabel)
pylab.ylabel(yLabel)
if(title != None): pylab.title(title)
pylab.show()
def aveMean(die, numRolls, numTrials):
tries = die
testList, res = [], []
for i in range(numTrials):
count, tempCount, testList = 1, 1, []
for i in range(numRolls):
testList.append(tries.roll())
for i in range(1, numRolls):
if testList[i-1] == testList[i]:
count +=1
else:
if count > tempCount:
tempCount = count
count = 1
else:
count = 1
res.append(tempCount)
mean, std = getMeanAndStd(res)
makeHistogram(res, 10, 'Quantity of Consecutive Numbers', 'Consecutive Number per Run')
return round(mean, 3)
The Error Message I get is: Unsuccessfully called makeHistogram
def getAverage(die, numRolls, numTrials):
"""
- die, a Die
- numRolls, numTrials, are positive ints
- Calculates the expected mean value of the longest run of a number
over numTrials runs of numRolls rolls
- Calls makeHistogram to produce a histogram of the longest runs for all
the trials. There should be 10 bins in the histogram
- Choose appropriate labels for the x and y axes.
- Returns the mean calculated
"""
tries = die
testList, res = [], []
for i in range(numTrials):
count, tempCount, testList = 1, 1, []
for i in range(numRolls):
testList.append(tries.roll())
for i in range(1, numRolls):
if testList[i-1] == testList[i]:
count +=1
else:
count = 1
if count > tempCount:
tempCount = count
if count > tempCount:
tempCount = count
res.append(tempCount)
mean, std = getMeanAndStd(res)
makeHistogram(res, 10, 'Quantity of Consecutive Numbers', 'Consecutive Number per Run')
return round(mean, 3)

Categories

Resources