Files
ProjectEulerPython/Benchmark.py

175 lines
5.8 KiB
Python

#ProjectEulerPython/Bechmark.py
#Matthew Ellison
# Created: 07-19-20
#Modified: 07-19-20
#This is the driver function for the Java version of the ProjectEuler project
"""
Copyright (C) 2020 Matthew Ellison
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from Problems.Problem import Problem
from ProblemSelection import ProblemSelection
from Stopwatch import Stopwatch
class Benchmark:
class BenchmarkOptions:
runSpecific = 1
runAllShort = 2
runAll = 3
exit = 4
size = 5
__tooLong = [3, 5, 10, 12, 14, 15, 23, 24, 25, 27, 30, 67]
#The driver function for the benchmark selection
@staticmethod
def benchmarkMenu():
Benchmark.printMenu()
selection = Benchmark.getMenuSelection()
if(selection == Benchmark.BenchmarkOptions.runSpecific):
Benchmark.runSpecific()
elif(selection == Benchmark.BenchmarkOptions.runAllShort):
Benchmark.runAllShort()
elif(selection == Benchmark.BenchmarkOptions.runAll):
Benchmark.runAll()
#Print the benchmark menu
@staticmethod
def printMenu():
print("1. Run a specific problem")
print("2. Run all problems that have a reasonably short run time")
print("3. Run all problems")
print("4. Exit the menu")
print()
#Returns a valid menu option
@staticmethod
def getMenuSelection() -> int:
selection = int(input(""))
while(not Benchmark.isValidMenu(selection)):
print("that is an invalid option!\nPress Enter to continue")
Benchmark.printMenu()
selection = int(input(""))
return selection
#Determines if a value is a valid menu option. Helper for getBechmarkMenuSelection
@staticmethod
def isValidMenu(selection: int):
if((selection > 0) and (selection < (Benchmark.BenchmarkOptions.size))):
return True
else:
return False
#Determines which problem user wants to run and runs it
@staticmethod
def runSpecific():
#Ask which problem the user wants to run
problemNumber = ProblemSelection.getProblemNumber()
#Ask how many times to run the problem
timesToRun = Benchmark.getNumberOfTimesToRun()
#Get the problem and print its description
problem = ProblemSelection.getProblem(problemNumber)
print(str(problemNumber) + ". " + problem.getDescription())
#Run the problem the specific number of times
totalTime = Benchmark.runProblem(problem, timesToRun)
#Print the results
print(Benchmark.getBenchmarkResults(problem, totalTime, timesToRun))
#Runs all problems except a few that are specified because of run length
@staticmethod
def runAllShort():
#Ask how many times to run the problems
timesToRun = Benchmark.getNumberOfTimesToRun()
#Run through all valid problem numbers, skipping a few that are in the tooLong list
for cnt in range(1, len(ProblemSelection.problemNumbers)):
problemNumber = ProblemSelection.problemNumbers[cnt]
#If the problem number is contained in the list of problems that take too long skip it
if problemNumber in Benchmark.__tooLong:
continue
#Get the problem and print its description
problem = ProblemSelection.getProblem(problemNumber)
print(str(problemNumber) + ". " + problem.getDescription())
#Run each problem the specified number of times
totalTime = Benchmark.runProblem(problem, timesToRun)
#Print the results
print(Benchmark.getBenchmarkResults(problem, totalTime, timesToRun))
#Runs all problems
@staticmethod
def runAll():
#Ask how many times to run the problem
timesToRun = Benchmark.getNumberOfTimesToRun()
#Run through all valid problem numbers, skipping a few that are in the tooLong list
for cnt in range(1, len(ProblemSelection.problemNumbers)):
problemNumber = ProblemSelection.problemNumbers[cnt]
#Get the problem and print its description
problem = ProblemSelection.getProblem(problemNumber)
print(str(problemNumber) + ". " + problem.getDescription())
#Run each problem the specified number of times
totalTime = Benchmark.runProblem(problem, timesToRun)
#Print the results
print(Benchmark.getBenchmarkResults(problem, totalTime, timesToRun))
#Asks how many times a problem is supposed to run and returns the value
@staticmethod
def getNumberOfTimesToRun() -> int:
numOfTimesToRun = int(input("How many times do you want to run this problem? "))
while(numOfTimesToRun < 1):
print("That is an invalid number!")
numOfTimesToRun = int(input("How many times do you want to run this problem? "))
return numOfTimesToRun
#Runs the problem the given number of times
@staticmethod
def runProblem(problem: Problem, timesToRun: int) -> float:
totalTime = 0.0
print("Solving", end='')
for cnt in range(0, timesToRun):
print('.', end = '', flush = True)
#Reset the data so you are actually count the run time an additional time
problem.reset()
#Solve the problem
problem.solve()
#Get the time data
totalTime += problem.getTimer().getNanoseconds()
return totalTime
#Prints the benchmark results of a problem
@staticmethod
def getBenchmarkResults(problem: Problem, totalTime: float, timesRun: int) -> str:
#Calculate the average run time of the problem
totalTime /= timesRun
timeResults = Stopwatch.getStr(totalTime)
#Tally the results
results = "\n\n" + problem.getResult() + "\nIt took an average of " + str(timeResults) + " to run this problem through " + str(timesRun) + " iterations\n\n"
return results