def GenerateProjectReport(): outfile = open("./DssProjectReport.txt", 'w') outfile.write("Project | Type | Sessions | Not Enabled | Observers | Complete | Incomplete | Avail / Rem Hrs | Obs Hrs | Blackout | Backup | Receivers\n") count = 0 open_projects = sorted(Project.objects.filter(complete = False) , lambda x, y: cmp(x.pcode, y.pcode)) for p in open_projects: for typ in get_type(p): if count % 5 == 0: outfile.write("-------------------------------------------------------------------------------------------------------------------------------------------\n") count += 1 outfile.write( "%s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s\n" % \ (p.pcode.ljust(11) , typ.center(8) , str(len(p.sesshun_set.all())).center(8) , str(len(get_sessions(p, typ, False))).center(11) , str(len(p.get_observers())).center(9) , str(len([s for s in p.sesshun_set.all() \ if s.status.complete == True])).center(8) , str(len(get_sessions(p, typ))).center(10) , "".join([str(get_rem_schedulable_hours(p, typ)), " / ", str(get_rem_hours(p,typ))]).rjust(16) , str(get_obs_hours(p,typ)).center(7) , "Yes".center(8) if any([len(o.user.blackout_set.all()) == 0 for o in p.get_observers()]) else " " , "Yes".center(6) if any([s.status.backup for s in p.sesshun_set.all()]) else " " , get_rcvrs(p, typ) ) ) semester = Semester.getCurrentSemester() SEMESTER_HOURS = (semester.end() - semester.start()).days * 24. semester_hrs_left = (semester.end() - datetime.today()).days * 24. outfile.write("\nTotal hours in this semester = %.1f"% SEMESTER_HOURS) outfile.write("\nTotal hours left this semester = %.1f\n" % \ semester_hrs_left) ta = TimeAccounting() hours = sum([ta.getTimeLeft(p) for p in open_projects]) remainingRatio = float(hours / semester_hrs_left * 100.) if semester_hrs_left != 0 else 0.0 outfile.write("\nSum of all incomplete projects' hours remaining = %.1f" % hours) outfile.write("\nHours remaining / Trimester Hours = %.1f%%" % (hours / SEMESTER_HOURS * 100.)) outfile.write("\nHours remaining / Trimester Hours Left = %.1f%%\n" % remainingRatio) hours = sum([ta.getProjectSchedulableTotalTime(p) for p in open_projects]) schedulableRatio = float(hours / semester_hrs_left * 100.) if semester_hrs_left != 0 else 0.0 outfile.write("\nSum of all schedulable time = %.1f" % \ hours) outfile.write("\nSchedulable time / Trimester Hours = %.1f%%" % (hours / SEMESTER_HOURS * 100.)) outfile.write("\nSchedulable time / Trimester Hours Left = %.1f%%\n" % schedulableRatio) outfile.close()
def GenerateProjectTimeAccountingReport(pcode): project = Project.objects.get(pcode = pcode) if project is None: print "cannot find project: ", pcode return ta = TimeAccounting() ta.report(project, "%sTimeAccounting.txt" % pcode)
def report(pcode, start, end): try: project = Project.objects.get(pcode = pcode) except Project.DoesNotExist: print "cannot find project: ", pcode return startDate = datetime.strptime(start, '%m-%d-%Y') e = datetime.strptime(end, '%m-%d-%Y') endDate = datetime(e.year, e.month, e.day, 23, 59, 59) ta = TimeAccounting() ta.reportDateRange(project, startDate, endDate)
def report(cat, start, end): try: ot = Observing_Type.objects.get(type = cat) except Observing_Type.DoesNotExist: print "cannot find science category: ", cat return startDate = datetime.strptime(start, '%m-%d-%Y') e = datetime.strptime(end, '%m-%d-%Y') endDate = datetime(e.year, e.month, e.day, 23, 59, 59) #sessions = Sesshun.objects.filter(observing_type = ot) sessions = Sesshun.objects.filter(frequency__gte = 18) #sessions = [s for s in Sesshun.objects.all() if any( [r in s.rcvrs_specified() for r in ('K', 'Ka', 'Q', 'MBA', 'KFPA', 'W')])] ta = TimeAccounting() ta.reportObservingTypeDateRange(cat, sessions, startDate, endDate)
def get_rem_schedulable_hours(project, typ): ta = TimeAccounting() return sum([ta.getTimeLeft(s) for s in get_sessions(project, typ) \ if s.schedulable() and project.has_sanctioned_observers()])
def get_rem_hours(project, typ): ta = TimeAccounting() return sum([ta.getTimeLeft(s) for s in get_sessions(project, typ)])
def get_obs_hours(project, typ): ta = TimeAccounting() return sum([ta.getTime("observed", s) for s in get_sessions(project, typ)])
def GenerateReport(start): outfile = open("./DssSessionReport.txt", 'w') scs = [1, 13, 5, 3, 6, 4, 10, 11, 6, 6, 6, 6, 5, 15] scss = " %s" * len(scs) hdrFormat = "\n\n\t " + scss dataFormat = "\n\t " + scss semesters = sorted(Semester.objects.all() , lambda x,y:cmp(x.semester,y.semester)) ta = TimeAccounting() for s in semesters: projects = sorted([p for p in s.project_set.all() if not p.complete] , lambda x,y:cmp(x.pcode, y.pcode)) if projects: outfile.write("\n\n") outfile.write("=" * 100) outfile.write("\n\nTrimester: %s\n" %s.semester) outfile.write("-" * 14) for p in projects: outfile.write("\n\n\t%s, %s, PI: %s, Rem/Tot: %.1f/%.1f" % \ (p.pcode , p.name[:50] , p.principal_investigator().last_name if p.principal_investigator() else "None" , ta.getTimeLeft(p) , ta.getProjectTotalTime(p))) outfile.write(hdrFormat % \ (ljust("", scs[0]) , ljust("name", scs[1]) , center("orgID", scs[2]) , center("sch", scs[3]) , center("obs", scs[4]) , ljust("type", scs[5]) , center("RA", scs[6]) , center("Dec", scs[7]) , center("rem", scs[8]) , center("tot", scs[9]) , rjust("min", scs[10]) , rjust("max", scs[11]) , rjust("btwn", scs[12]) , ljust("rcvrs", scs[13]))) sessions = sorted(p.sesshun_set.all() , lambda x,y:cmp(x.name, y.name)) for s in sessions: target = s.getTarget() outfile.write(dataFormat % \ (ljust(bl(s.status.complete), scs[0]) , ljust(s.name, scs[1]) , rjust(s.original_id, scs[2]) , center(scheduable(s), scs[3]) , center(s.observing_type.type[:6], scs[4]) , center(s.session_type.type[0], scs[5]) , ljust(target.get_horizontal(), scs[6]) , ljust(target.get_vertical(), scs[7]) , rjust(ta.getTimeLeft(s), scs[8]) , rjust(s.allotment.total_time, scs[9]) , rjust(s.min_duration, scs[10]) , rjust(s.max_duration, scs[11]) , rjust(s.time_between, scs[12]) , ljust("".join(s.rcvrs_specified()), scs[13]) )) if p != projects[-1]: outfile.write("\n\t" + ("-" * 96))
def __init__(self, quiet = False, filename = None): self.ta = TimeAccounting() self.lines = "" self.quiet = quiet self.filename = filename
class DBReporter: """ This class is responsible for reporting on the state of the database. It provides statistical summarries, as well as alerts on any potential issues. Right now it is currently used to report on newly projects transferred from Carl's system, w/ a format similar to Carl's for cross checking purposes. Using the revision system, one can view how the old 'report' method used to try and replicate Carl's report exactly, but this is no longer used. """ def __init__(self, quiet = False, filename = None): self.ta = TimeAccounting() self.lines = "" self.quiet = quiet self.filename = filename def add(self, lines): if not self.quiet: print lines self.lines += lines def printLines(self): if not self.quiet: print self.lines if self.filename: f = file(self.filename, 'w') f.writelines(self.lines) f.close() def reportProjectSummaryBySemester(self, semester = None): if semester is None: projs = Project.objects.order_by("pcode").all() else: projs = Project.objects.filter(semester__semester = semester ).order_by("pcode") self.reportProjectSummary(projs) def reportProjectSummaryByPcode(self, pcodes): projs = [] for pcode in pcodes: ps = Project.objects.filter(pcode = pcode) projs.extend(ps) self.reportProjectSummary(projs) def reportProjectSummary(self, projs): # *** General Info *** # gather stats on projects - how many, how many of what type, total hrs .. numProjs = len(projs) totalProjHrs = sum([self.ta.getProjectTotalTime(p) for p in projs]) self.add("\n*** Projects ***\n") self.add("Total # of Projects: %d, Total Hrs: %5.2f\n\n" % (numProjs, totalProjHrs)) semesters = Semester.objects.all().order_by('semester') proj_types = Project_Type.objects.all() projSems = self.binProject(projs, semesters, "semester") self.printInfo(projSems, "Projects by Semester: ", "Semester") projTypes = self.binProject(projs, proj_types, "project_type") self.printInfo(projTypes, "Projects by Type: ", "Type") projThesis = self.binProject(projs, [True, False], "thesis") self.printInfo(projThesis, "Projects by Thesis: ", "Thesis") # project summary: for each project, how many sess, hrs, etc. self.add("\n") self.add("Project Summary (modeled from Carl's report): \n") header = ["Name", "#", "Hrs", "Original IDs"] cols = [10, 5, 6, 50] self.printData(header, cols, True) for p in projs: ss = p.sesshun_set.all() hrs = self.ta.getProjSessionsTotalTime(p) ssIds = ["%s" % s.original_id for s in ss] ssIds.sort() ssIdStrs = " ".join(ssIds) data = [p.pcode, str(len(ss)), "%5.2f" % hrs, ssIdStrs] self.printData(data, cols) self.add("\n") self.printLines() def binWindow(self, windows, bins, attrib): r = {} for bin in bins: binW = [w for w in windows if w.__getattribute__(attrib) == bin] r[str(bin)] = (len(binW), 0) # Hrs is N/A return r def binProject(self, projs, bins, attrib): r = {} for bin in bins: binProj = [p for p in projs if p.__getattribute__(attrib) == bin] binProjHrs = sum([self.ta.getProjectTotalTime(p) for p in binProj]) r[str(bin)] = (len(binProj), binProjHrs) return r def binSesshun(self, sess, bins, attribs, attribFnc = False): r = {} # attributes can be "attrib", or "attrib.attrib" parts = attribs.split(".") for bin in bins: if len(parts) == 1: attrib = parts[0] # for one attrib, we must support difference between a member # var and a method if attribFnc: binSess = [s for s in sess if s.__getattribute__(attrib)() == bin] else: binSess = [s for s in sess if s.__getattribute__(attrib) == bin] elif len(parts) == 2: # in this case, we don't support methods a1, a2 = parts binSess = [s for s in sess \ if s.__getattribute__(a1).__getattribute__(a2) == bin] else: raise "binSesshun only supports <= 2 attributes" binSessHrs = sum([s.allotment.total_time for s in binSess]) r[str(bin)] = (len(binSess), binSessHrs) return r def binSesshunNumTargets(self, sess): nums = {} nums['0'] = (len([s for s in sess if s.target_set.all() == []]) , 0) nums['1'] = (len([s for s in sess if len(s.target_set.all()) == 1]), 0) nums['>1'] = (len([s for s in sess if len(s.target_set.all()) > 1]) , 0) return nums def binSesshunNumCadences(self, ss): nums = {} nums['0'] = (len([s for s in ss if len(s.cadence_set.all()) == 0]), 0) nums['1'] = (len([s for s in ss if len(s.cadence_set.all()) == 1]), 0) nums['>1'] = (len([s for s in ss if len(s.cadence_set.all()) > 1]) , 0) return nums def printInfo(self, info, title, header): # the first col should have a width to accomodate the biggest thing keys = info.keys() keys.sort() maxKeys = max(keys, key=len) col1 = len(max([header, maxKeys], key=len)) cols = [col1, 5, 10] self.add("\n" + title + "\n") self.printData([header, "#", "Hrs"], cols, True) for k in keys: self.add(" ".join([k[0:cols[0]].rjust(cols[0]), \ str(info[k][0])[0:cols[1]].rjust(cols[1]), \ str(info[k][1])[0:cols[2]].rjust(cols[2])]) + "\n") def printData(self, data, cols, header = False): self.add(" ".join([h[0:c].rjust(c) for h, c in zip(data, cols)]) + "\n") if header: self.add(("-" * (sum(cols) + len(cols))) + "\n") def reportProjectDetails(self, projects, pcodes): self.add("Project Details for projects: %s\n" % (", ".join(pcodes))) projs = [p for p in projects if p.pcode in pcodes] for proj in projs: self.projectDetails(proj) def projectDetails(self, project): self.add("Project %s:\n" % project.pcode) for a in project.allotments.all(): self.add("Allotment: %s\n" % a) for s in project.sesshun_set.all(): self.add(" Session name : %s, vpkey : %d, hrs : %5.2f\n" % \ (s.name, s.original_id, s.allotment.total_time)) for p in s.period_set.all(): self.add(" Period %s for %5.2f Hrs\n" % (p.start, p.duration))