content: ############################################################
  '''
      testForks.py
      Written by: Brian O'Dell, Spetember 2017
  
      A program to run each program a 500 times per thread count.
      Then uses the data collected to make graphs and tables that
      are useful to evaluate the programs running time.
  '''
  ############################################################
  
  from subprocess import *
  from numba import jit
  import numpy as np
  import csv as csv
  import pandas as pd
  from pandas.plotting import table
  import matplotlib.pyplot as plt
  
  '''
      Call the C program multiple times with variable arguments to gather data
      The name of the executable should exist before running
  '''
  @jit
  def doCount(name):
      j = 0
      while (j < 1025):
          for i in range(0,501):
              call([name,"-t",str(j), "-w"])
          if (j == 0):
              j = 1
  
          else:
              j = 2*j;
  
  '''
      Turn the data into something meaningful.
      Takes all the data gets the average and standard deviation for each
      number of threads. Then plots a graph based on it. Also, makes
      a csv with the avg and stddev
  '''
  @jit
  def exportData(name):
      DF = pd.read_csv("data/"+name+".csv")
      f = {'ExecTime':['mean','std']}
  
      #group by the number of threads in the csv and
      #apply the mean and standard deviation functions to the groups
      avgDF = DF.groupby('NumThreads').agg(f)
      avgTable = DF.groupby('NumThreads', as_index=False).agg(f)
  
      #When the data csv was saved we used 0 to indicate serial execution
      #this was so the rows would be in numerical order instead of Alphabetical
      #Now rename index 0 to Serial to be an accurate representation
      indexList = avgDF.index.tolist()
      indexList[0] = 'Serial'
      avgDF.index = indexList
  
      #make the bar chart and set the axes
      avgPlot = avgDF.plot(kind='bar',
                   title=('Run Times Using '+ name), legend='False', figsize=(15,8))
      avgPlot.set_xlabel("Number of Forks")
      avgPlot.set_ylabel("Run Time (seconds)")
  
      #put the data values on top of the bars for clarity
      avgPlot.legend(['mean','std deviation'])
      for p in avgPlot.patches:
          avgPlot.annotate((str(p.get_height())[:6]),
                    (p.get_x()-.01, p.get_height()), fontsize=9)
  
      #save the files we need
      plt.savefig('data/'+name+'Graph.png')
      avgTable.to_csv('data/'+name+'Table.csv', index=False, encoding='utf-8')
  
  
  def main():
      doCount("./forkedSemaphor")
      doCount("./forkedPrivateCount")
      doCount("./forkedPrivateCount32")
      exportData("forkedSemaphor")
      exportData("forkedPrivateCount")
      exportData("forkedPrivateCount32")
  
  if __name__ == '__main__':
      main()
  