# W_rapper is a super simple python wrapper for W
# Andrei Perhinschi - September 2010

# W_rapper records all of the reccomendations made by
# W into a file placed within a directory called results/
# created in the current directory. W_rapper needs to be
# run from the root directory of W with write privileges

# We can now run up to 4 projects against one dataset in one go

# Usage: python W_wrapper.py [dataset] [test project] [test project]
#							 [test project] [test project] 
#							 [times to run W] [sets of runs]
# Example: python W_wrapper.py nasa93 ground

#!/usr/bin/python

import os, sys, time, math

def normalize(list):
	
	L = [1+(x-min(list))*(100-1)/(max(list)-min(list)) for x in list]
	return [ int(x) for x in L]

def median(aList):
	size = len(aList)
	if size % 2 == 1:
		return aList[(size - 1)/2]
	else:
		return (aList[size/2 - 1] + aList[size/2] ) / 2

# this checks for the correct number of command line
# arguments but does nothing to make sure they are valid

# bash w nasa93 ground 5 1; bash w nasa93 flight 5 1; bash w nasa93 osp 5 1

if len(sys.argv) == 8:
	
	total_runs = int(sys.argv[6])
	super_runs = int(sys.argv[7])
	projects = [sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]]
	args = 4
elif len(sys.argv) == 7:
	
	total_runs = int(sys.argv[5])
	super_runs = int(sys.argv[6])
	projects = [sys.argv[2], sys.argv[3], sys.argv[4]]
	args = 3
elif len(sys.argv) == 6:
	
	total_runs = int(sys.argv[4])
	super_runs = int(sys.argv[5])
	projects = [sys.argv[2], sys.argv[3]]
	args = 2
elif len(sys.argv) == 5:
	
	total_runs = int(sys.argv[3])
	super_runs = int(sys.argv[4])
	projects = [sys.argv[2]]
	args = 1
else:
	
	print "Error: Wrong number of arguments"
	print "Usage: python W_wrapper.py <dataset> <test project(s)> <times to run W> <sets of runs>\n"
	exit()
	
# initial variables
#com1 = "bash w %s %s %d %d" % (sys.argv[1], sys.argv[2], total_runs, super_runs)
com = "bash w %s" % (sys.argv[1])
params = []
for q in projects:
	params.append("%s %s %d %d" % (com, q, total_runs, super_runs))
	
#print "PARAMS: %s\n" % (params)
projectcoms = ';'.join(params)
pronames = ''.join(sys.argv[2:len(sys.argv)-2])
command = projectcoms
print command + "\n"

zerovar = 0
run = 1
supRun = 1
results = 0
suffix1 = "Reduction Summary-----------"
suffix2 = "Recommendations------------"
stat = ""
percent = ""
stats = []
percents = []
sums = []
lists = []
now_read = str(time.asctime())
now_num = str(time.time())
filename = "results2/"+ sys.argv[1] + "_" + pronames + "_x%d" % (total_runs) + "(10-30).txt"
header = "W RESULTS FILE\n\n" + \
		"Creation date: " + now_read + "\n" + \
		"Test project(s): " + ', '.join(projects) + "\n" + \
		"Dataset: " + sys.argv[1] + "\n" + \
		"W was run %d " % (total_runs) + "times\n" + \
		"We did this %d " % (super_runs) + "times\n\n"

# setting up output directory
try:
	
	os.mkdir ("results2")
	print "Results directory created under current directory\n"
except OSError:
	
	print "Results directory already exists\n"


# output file handler
try:
	
	out = open(filename, "w")
	out.write(header)
except IOError:
	
	print "Error: You lack permission to write files here\n"
	exit()

# set the limit of this while loop to 
# however many times you want to run W
while supRun <= super_runs:
	while run <= total_runs:

		demo = os.popen(command)
		lines = demo.readlines()
		
		for line in lines:
		
			# true if recommended values are on next line
			if line.find(suffix1) >= 0:	 	
				# set sentinel var and move on to the line we want
				results = 1
				continue
			if line.find(suffix2) >= 0:	 	
				# Kill sentinel var
				results = 0
				continue
			
			# when this evaluates true, the previous loop will have
			# ran once and made sure the line we are on now is the
			# one containing W's recommendations
			if results == 1:
				
				# print W output to stdout and file
				stat = line.split(':', 1)
				percent = stat[1].split('%', 1)
				stat = stat[0].strip()
				percent = percent[0].strip()
				percent = int(percent)
				if run == 1:
					stats.append(stat)
				percents.append(percent)
		run += 1
	i = 0
	itBy = len(stats)
	tmp = []
	for aClass in stats:
		j = i
		aSum = 0
		while (j < len(percents)):
			aSum += percents[j]
			tmp.append(percents[j])
			j += itBy
		sums.append(aSum)
		tmp.sort()
		tmp = normalize(tmp)
		lists.append(tmp)
		tmp = []
		i += 1
	i = 0
	for aSum in sums:
		sums[i] = aSum / (run -1)
		i += 1
	i = 0
	
	for aClass in stats:
		f = zerovar
		goal_project = aClass.split(" ", 1)
		tmpList = lists[i]
		tmpMin = min(tmpList)
		tmpMax = max(tmpList)
		tmpQ1 = median(tmpList[0:(len(tmpList)/2)])
		tmpQ3 = median(tmpList[(len(tmpList)/2):len(tmpList)])
		tmpSpr = tmpQ3 - tmpQ1
		med = median(tmpList)
		
		hline = ""
		hlpstr = r"\%"
		
		if i % 2 == 0:
			if goal_project[0] == "effort":
				hline = "\\hline"
				zerovar += 1
			tmpStr2 = "%s & %s & %d%s & %d%s & \\boxplot {%d}{%d}{%d}{%d}{%d}\\\\%s" % (goal_project[0], projects[f], med, hlpstr, tmpSpr, hlpstr, tmpQ1, (med-tmpQ1), med, (tmpQ3-med), tmpQ3, hline)
			print tmpStr2
			out.write(tmpStr2)
			out.write("\n")
		i += 1
	stats = []
	percents = []
	sums = []
	lists = []
	tmp = []
	supRun += 1
	run = 1
out.close()
