There was some confusion with the code I had posted in my previous version of this question and there was some good advice from @Oscar Smith.
The explanation is the same; please give improvements for speed in this new version:
#!/usr/bin/python
import numpy as np
import time
chosenNum = 429
numRuns = 10000
numCapturedTanks = 7
numGuessN = []
guesses = []
percentErrors = []
STDarray = []
start_time = time.time()
STDtimes = []
def getAverageStdTime(timetaken): # gets the average time it took to calculate standard deviations
STDtimes.append(timetaken)
if (len(STDtimes) == numRuns):
print ("Average List of Standard Devations Generation Time: " + str(round(np.mean(STDtimes),2)) + " seconds")
def createListOfStandardDeviations(start,end):
for y in range(start,int(end)):
tankSerialNumbersSimulated = np.random.randint(1, y + 1, size=numCapturedTanks) #from Oscar Smith
simulatedSTD = np.std(tankSerialNumbersSimulated)
STDarray.append(simulatedSTD)
def getAllGuesses():
print ("Your guesses are: " + str(guesses))
def getAvgPercentError():
numCorrect = 0
closestNumber = 0
for x in range(len(guesses) - 1):
percentError = '%.2f' % round(((np.abs(guesses[x] - chosenNum))/float(chosenNum) * 100), 2)
percentErrors.append(float(percentError))
if(guesses[x] == chosenNum):
numCorrect = numCorrect + 1
else:
closestNumber = min(guesses, key=lambda x:abs(x-chosenNum))
averagePercentError = np.mean(percentErrors)
print ("The average Percent Error is: " + str(round(averagePercentError,2)) + "%")
getAccuracy(numCorrect,closestNumber)
def getAccuracy(amountCorrect,closestNumberToActual):
if (amountCorrect > 0):
print ("You got the correct number " + str(amountCorrect) + " out of " + str(len(guesses)) + " times.")
else:
print ("Your closest number was: " + str(closestNumberToActual))
getmode(guesses)
def getmode(inplist):
dictofcounts = {}
listofcounts = []
for i in inplist:
countofi = inplist.count(i) # count items for each item in list
listofcounts.append(countofi) # add counts to list
dictofcounts[i]=countofi # add counts and item in dict to get later
maxcount = max(listofcounts) # get max count of items
if maxcount ==1:
print ("There is no mode for this dataset, values occur only once")
else:
modelist = [] # if more than one mode, add to list to print out
for key, item in dictofcounts.items():
if item ==maxcount: # get item from original list with most counts
modelist.append(str(key))
print ("Most guessed number(s):",' and '.join(modelist))
return modelist
def getNumGuessed(givenSTD,maxNumber):
minStd = min(STDarray, key=lambda x:abs(x-givenSTD)) #finds closest standard deviation to the given standard deviation
for (z,this_std) in enumerate(STDarray):
if(minStd == this_std): #find closest number to original standard deviation
numGuessed = z + maxNumber
return numGuessed
def main():
print ("reached main")
for runsRan in range(numRuns):
tankSerialNumbers = np.random.randint(1, chosenNum + 1, size=numCapturedTanks) #from Oscar Smith
NumSTD = np.std(tankSerialNumbers)
highestTankSerial = np.mean(tankSerialNumbers) + 3*NumSTD
maxNum = np.amax(tankSerialNumbers)
print ("Tank Serial Numbers Generated")
print ("Standard Deviation and Range Calculated")
ListOfStandardDeviationsStartTime = time.time()
for _ in range(100):
del STDarray[:]
if (maxNum - highestTankSerial < 0):
createListOfStandardDeviations(maxNum,highestTankSerial)
else:
createListOfStandardDeviations(highestTankSerial,maxNum)
numGuessN.append(getNumGuessed(NumSTD,maxNum))
print ("Initial List of Standard Deviations Generated")
print ("List of Standard Devations Generation took " + str(round(time.time() - ListOfStandardDeviationsStartTime,2)) + " seconds")
guess = int(np.mean(numGuessN))
print ("Guess Generated " + str(runsRan + 1))
getAverageStdTime(float(time.time() - ListOfStandardDeviationsStartTime))
guesses.append(guess)
getAllGuesses()
getAvgPercentError()
main()
print ("My program took " + str(round((time.time() - start_time)/float(60),2)) + " minutes to run")
Currently, the runtime is approximately 7.26 minutes for 1,000 runs. I want to get it to run 10,000 times and at this rate, it would take too long.