コード例 #1
0
class ORSOutput(ORSSheets):
	"""A module to publish results tables, and restore default values to
	user input fields."""
	def __init__(self, ORSCalculatorInstance, xlInstance):
		self.ORS = ORSCalculatorInstance
		#self.xlInst = xlInstance
		self.Sheet = Sheet(xlInstance)
		self.InputSheet = "Input"
		self.CalculationSheet = "Calculation"
		self.StatsSheet = "Statistics"
		self.NetworkName = self.ORS.networknames[0]
		
		self.DateOrigin = pos(row=4, col=1) # The postion to place the fist date
	
	def Populate_Reliability_Stats(self):
		"""Write the 2015 determination statistics to a prebuilt table in excel.
		Used on the 'Statistics' sheet."""
		# Table origin is the top left
		ComComOrigin = pos(row=4, col=1)
		CalcOrigin = pos(row=4, col=9)
		
		# The row order of the values being calcualted by the ORSCalculator
		# TODO: The row text must match the values _get_stats() is expecting, we may need to introduce some aliases to make it more readable
		RowHeadings = [["UBV"], ["LIMIT"], ["TARGET"], ["COLLAR"], ["CAP"]]
		CalcRowValues = [self.ORS._get_stats(heading[0]) for heading in RowHeadings] # ORS calcualted values
		CCRowValues = [self.ORS._get_CC_stats(heading[0]) for heading in RowHeadings] # Com Com hard coded values
		
		# Work out how many columns we need to offset these SAIDI, SAIFI results
		NetworkOrder = ["ELIN", "OTPO", "TPCO"] # The order the networks are presented going across the table in excel
		try:
			Offset = NetworkOrder.index(self.NetworkName)
		except ValueError:
			print "%s is not a recognised network" % self.NetworkName
			Offset = 0 # Default option
		Offset *= 2
		
		# Table 1
		self.Sheet.setRange(self.StatsSheet, ComComOrigin.row, ComComOrigin.col, RowHeadings) # Write the row headings into the table
		ComComOrigin.col += 1 # Incriment the next column (i.e. don't overwrite row headings)
		row = ComComOrigin.row
		for rowValue in CalcRowValues:
			# The SAIDI/SAIFI values are written to excel in the order that they are returned by the ORSCalculator function
			self.Sheet.setRange(self.StatsSheet, row, ComComOrigin.col+Offset, [rowValue])
			row += 1

		# Table 2
		self.Sheet.setRange(self.StatsSheet, CalcOrigin.row, CalcOrigin.col, RowHeadings)
		CalcOrigin.col += 1 # Incriment the next column (i.e. don't overwrite row headings)
		row = CalcOrigin.row
		for rowValue in CCRowValues:
			# The SAIDI/SAIFI values are written to excel in the order that they are returned by the ORSCalculator function
			self.Sheet.setRange(self.StatsSheet, row, CalcOrigin.col+Offset, [rowValue])
			row += 1

	def Create_Summary_Table(self):
		"""Create a summary sheet in excel, delete it if it already exisits"""
		# Remove the sheet, if it exists, then re-add it -- Don't do this when adding multiple networks
		self.Sheet.rmvSheet(removeList=[self.OutputFileName])
		self.Sheet.addSheet(self.OutputFileName)

	def Summary_Table(self, suffix):
		"""Publish a summary of the year-to-date stats at the bottom of every sheet"""
		suffix = " " + suffix
		network = self.ORS.networknames[0]
		currentDate = datetime.datetime.now()
		RowHeadings = ["CAP", "TARGET", "COLLAR"] # The order the rows appear in the Excel spreadsheet
		TableHeadings = ["YTD Cap", "YTD Target", "YTD Collar", "YTD Total", "YTD Planned", "YTD Unplanned", "Projected Incentive/Penalty"]
		columns = [1, 2, 3, 4, 5]
		if network == "ELIN":
			RowOffset = 2
			ColOffset = 1
		elif network == "OTPO":
			RowOffset = 2 + 12
			ColOffset = len(self.IndexHeadings) * len(self.DataHeadings) + 1
		elif network == "TPCO":
			RowOffset = 2 + 2*12
			ColOffset = len(self.IndexHeadings) * len(self.DataHeadings) * (len(self.NetworkHeadings) - 1) + 1

		maxrow = self.Sheet.getMaxRow(self.CalculationSheet+suffix, 1, 4)
		self.Sheet.setRange("Summary", maxrow + RowOffset, 1, [[network]+TableHeadings]) # Write the heading data
		
		# Find the row that corrosponds to the current date
		Dates = self.Sheet.getRange(self.CalculationSheet+suffix, 4, 1, maxrow, 1)
		Dates = [self.Sheet.getDateTime(Date[0]) for Date in Dates] # Convert a 2D list of tuples to a 1D list
		try:
			index = Dates.index( datetime.datetime(currentDate.year, currentDate.month, currentDate.day) )
		except ValueError:
			index = len(Dates) - 1
				
		for param in self.IndexHeadings:
			# Read the entire row of data
			YTD_row = self.Sheet.getRange(self.CalculationSheet+suffix, index+4, 1, index+4, 
				self.Sheet.getMaxCol(self.CalculationSheet+suffix, 2, 3))[0]
			# Convert the row data to: CAP, TARGET, COLLAR, YTD Total, YTD Planned, YTD Unplanned
			#YTD_row[ColOffset : len(DataHeadings)+ColOffset+1]
			i = self.IndexHeadings.index(param)
			TableRow = [YTD_row[ColOffset], YTD_row[ColOffset+1], YTD_row[ColOffset+2], 
			   YTD_row[ColOffset+3] + YTD_row[ColOffset+4], YTD_row[ColOffset+3], 
					[0.5*CC_Revenue_At_Risk.get(network, 0)/(self.ORS._get_stats("CAP")[i] - self.ORS._get_stats("TARGET")[i])]]

			RowOffset += 1
			self.Sheet.setRange("Summary", maxrow + RowOffset, 1, [[param]+TableRow]) # Write the heading data
			ColOffset += len(self.DataHeadings)
		
		Table = []
		Table.append(["Revenue at risk", CC_Revenue_At_Risk.get(network, "No Revenue Found")]) 		# Revenue at Risk
		Table.append(["Total Number of ICPs", self.ORS._get_total_customers(Dates[index])]) 		# Total Number of ICPs
		Table.append(["Year to date figures as of", Dates[index]]) 		# Date
		self.Sheet.setRange("Summary", maxrow + RowOffset+1, 1, Table)

	def Generate_Values(self, enddate, startdate=None):
		"""
		Generate dictionary key value pairs for "Rob's" template - suitable for commercial team.

		@param enddate: Date to stop counting SAIDI and SAIFI for the YTD figures.
		@param startdate: Defaults to the 1/4/<1 year less than end>. Date to start counting SAIDI and SAIFI for YTD figures.
		@return: A dictionary of the keyword spesfic to the ORS instance currently being handled
		This functoin will work with date ranges larger than 1 year, but the CC_SAIDI_YTD/CC_SAIFI_YTD interpolations will
		be meainingless as these are intended to be scaled over 1 whole year starting on 1/4/n and ending on 31/3/n+1.
		"""
		if not startdate:
			year = self.ORS._get_fiscal_year(enddate) - 1 # Function returns the fiscal year (int) for the given date
			startdate = datetime.datetime(year, 4, 1)
		else:
			year = self.ORS._get_fiscal_year(startdate) - 1

		# Some checks... any future dates will be redfined as the present date
		assert startdate < enddate, "The end date is set before the startdate"
		now = datetime.datetime.now()
		if now < enddate:
			enddate = datetime.datetime(now.year, now.month, now.day)
			year = self.ORS._get_fiscal_year(enddate) - 1

		# Fixed sheet data
		name = self.Rename_Network(self.NetworkName) + "_"
		params = {}
		params[name+"DATE_END"] = enddate
		params[name+"CUST_NUM"] = self.ORS._get_total_customers(enddate)

		# Annual data
		Dates = self.Generate_Dates(startdate, enddate)
		Dates = [Date[0] for Date in Dates]
		SAIDI_, SAIFI_ = self._Calc_Rows(Dates, self.ORS) 		# (planned, unplanned, unplanned normed) for the given dates		
		params[name+"SAIDI_NORMED_OUT"] = np.sum(SAIDI_, 0)[2]
		params[name+"SAIFI_NORMED_OUT"] = np.sum(SAIFI_, 0)[2]
		params[name+"SAIDI_UNPLANNED"] = np.sum(SAIDI_, 0)[1]
		params[name+"SAIFI_UNPLANNED"] = np.sum(SAIFI_, 0)[1]
		params[name+"SAIDI_PLANNED"] = np.sum(SAIDI_, 0)[0]
		params[name+"SAIFI_PLANNED"] = np.sum(SAIFI_, 0)[0]
		params[name+"RAW_PLANNED"] = np.sum([self.ORS._get_num_faults(date, "planned") for date in Dates])
		params[name+"RAW_UNPLANNED"] = np.sum([self.ORS._get_num_faults(date, "unplanned") for date in Dates])
		params[name+"RAW_NUM_MAJOR_EVENTS_SAIDI"] = len(self.ORS.get_capped_days(Dates[0], Dates[-1])[0])
		params[name+"RAW_NUM_MAJOR_EVENTS_SAIFI"] = len(self.ORS.get_capped_days(Dates[0], Dates[-1])[1])

		# Monthly data (present month)
		Dates = self.Generate_Dates(datetime.datetime(enddate.year, enddate.month, 1), enddate)
		Dates = [Date[0] for Date in Dates]
		SAIDI_, SAIFI_ = self._Calc_Rows(Dates, self.ORS)		# (planned, unplanned, unplanned normed) for the given dates	
		params[name+"SAIDI_MONTH_NORMED_OUT"] = np.sum(SAIDI_, 0)[2]
		params[name+"SAIFI_MONTH_NORMED_OUT"] = np.sum(SAIFI_, 0)[2]
		params[name+"SAIDI_MONTH_UNPLANNED"] = np.sum(SAIDI_, 0)[1]
		params[name+"SAIFI_MONTH_UNPLANNED"] = np.sum(SAIFI_, 0)[1]
		params[name+"SAIDI_MONTH_PLANNED"] = np.sum(SAIDI_, 0)[0]
		params[name+"SAIFI_MONTH_PLANNED"] = np.sum(SAIFI_, 0)[0]
		params[name+"RAW_MONTH_PLANNED"] = np.sum([self.ORS._get_num_faults(date, "planned") for date in Dates])
		params[name+"RAW_MONTH_UNPLANNED"] = np.sum([self.ORS._get_num_faults(date, "unplanned") for date in Dates])
		params[name+"RAW_MONTH_NUM_MAJOR_EVENTS_SAIDI"] = len(self.ORS.get_capped_days(Dates[0], Dates[-1])[0])
		params[name+"RAW_MONTH_NUM_MAJOR_EVENTS_SAIFI"] = len(self.ORS.get_capped_days(Dates[0], Dates[-1])[1])

		# Com Com Interpolations (could use np.linspace)
		SAIDI_TARGET, SAIFI_TARGET = self.ORS._get_CC_stats("TARGET")
		num_days = (datetime.datetime(year+1, 3, 31) - datetime.datetime(year, 3, 31)).days
		x_days = (enddate - startdate).days
		SAIDI_M = SAIDI_TARGET/num_days
		SAIFI_M = SAIFI_TARGET/num_days
		params[name+"CC_SAIDI_YTD"] = SAIDI_M * (1 + x_days)
		params[name+"CC_SAIFI_YTD"] = SAIFI_M * (1 + x_days)
		params[name+"CC_SAIDI_TARGET"] = CC_Vals.get(self.NetworkName).get("SAIDI_TARGET")
		params[name+"CC_SAIFI_TARGET"] = CC_Vals.get(self.NetworkName).get("SAIFI_TARGET")
		params[name+"CC_SAIDI_CAP"]	= CC_Vals.get(self.NetworkName).get("SAIDI_CAP")
		params[name+"CC_SAIFI_CAP"]	= CC_Vals.get(self.NetworkName).get("SAIFI_CAP")
		params[name+"CC_SAIDI_COLLAR"] = CC_Vals.get(self.NetworkName).get("SAIDI_COLLAR")
		params[name+"CC_SAIFI_COLLAR"] = CC_Vals.get(self.NetworkName).get("SAIFI_COLLAR")
		params[name+"CC_REV_RISK"] = CC_Revenue_At_Risk.get(self.NetworkName) * 0.01
		return params
コード例 #2
0
class ORSOutput(ORSSheets):
    """A module to publish results tables, and restore default values to
	user input fields."""
    def __init__(self, ORSCalculatorInstance, xlInstance):
        self.ORS = ORSCalculatorInstance
        #self.xlInst = xlInstance
        self.Sheet = Sheet(xlInstance)
        self.InputSheet = "Input"
        self.CalculationSheet = "Calculation"
        self.StatsSheet = "Statistics"
        self.NetworkName = self.ORS.networknames[0]

        self.DateOrigin = pos(row=4,
                              col=1)  # The postion to place the fist date

    def Populate_Reliability_Stats(self):
        """Write the 2015 determination statistics to a prebuilt table in excel.
		Used on the 'Statistics' sheet."""
        # Table origin is the top left
        ComComOrigin = pos(row=4, col=1)
        CalcOrigin = pos(row=4, col=9)

        # The row order of the values being calcualted by the ORSCalculator
        # TODO: The row text must match the values _get_stats() is expecting, we may need to introduce some aliases to make it more readable
        RowHeadings = [["UBV"], ["LIMIT"], ["TARGET"], ["COLLAR"], ["CAP"]]
        CalcRowValues = [
            self.ORS._get_stats(heading[0]) for heading in RowHeadings
        ]  # ORS calcualted values
        CCRowValues = [
            self.ORS._get_CC_stats(heading[0]) for heading in RowHeadings
        ]  # Com Com hard coded values

        # Work out how many columns we need to offset these SAIDI, SAIFI results
        NetworkOrder = [
            "ELIN", "OTPO", "TPCO"
        ]  # The order the networks are presented going across the table in excel
        try:
            Offset = NetworkOrder.index(self.NetworkName)
        except ValueError:
            print "%s is not a recognised network" % self.NetworkName
            Offset = 0  # Default option
        Offset *= 2

        # Table 1
        self.Sheet.setRange(
            self.StatsSheet, ComComOrigin.row, ComComOrigin.col,
            RowHeadings)  # Write the row headings into the table
        ComComOrigin.col += 1  # Incriment the next column (i.e. don't overwrite row headings)
        row = ComComOrigin.row
        for rowValue in CalcRowValues:
            # The SAIDI/SAIFI values are written to excel in the order that they are returned by the ORSCalculator function
            self.Sheet.setRange(self.StatsSheet, row,
                                ComComOrigin.col + Offset, [rowValue])
            row += 1

        # Table 2
        self.Sheet.setRange(self.StatsSheet, CalcOrigin.row, CalcOrigin.col,
                            RowHeadings)
        CalcOrigin.col += 1  # Incriment the next column (i.e. don't overwrite row headings)
        row = CalcOrigin.row
        for rowValue in CCRowValues:
            # The SAIDI/SAIFI values are written to excel in the order that they are returned by the ORSCalculator function
            self.Sheet.setRange(self.StatsSheet, row, CalcOrigin.col + Offset,
                                [rowValue])
            row += 1

    def Create_Summary_Table(self):
        """Create a summary sheet in excel, delete it if it already exisits"""
        # Remove the sheet, if it exists, then re-add it -- Don't do this when adding multiple networks
        self.Sheet.rmvSheet(removeList=[self.OutputFileName])
        self.Sheet.addSheet(self.OutputFileName)

    def Summary_Table(self, suffix):
        """Publish a summary of the year-to-date stats at the bottom of every sheet"""
        suffix = " " + suffix
        network = self.ORS.networknames[0]
        currentDate = datetime.datetime.now()
        RowHeadings = ["CAP", "TARGET", "COLLAR"
                       ]  # The order the rows appear in the Excel spreadsheet
        TableHeadings = [
            "YTD Cap", "YTD Target", "YTD Collar", "YTD Total", "YTD Planned",
            "YTD Unplanned", "Projected Incentive/Penalty"
        ]
        columns = [1, 2, 3, 4, 5]
        if network == "ELIN":
            RowOffset = 2
            ColOffset = 1
        elif network == "OTPO":
            RowOffset = 2 + 12
            ColOffset = len(self.IndexHeadings) * len(self.DataHeadings) + 1
        elif network == "TPCO":
            RowOffset = 2 + 2 * 12
            ColOffset = len(self.IndexHeadings) * len(
                self.DataHeadings) * (len(self.NetworkHeadings) - 1) + 1

        maxrow = self.Sheet.getMaxRow(self.CalculationSheet + suffix, 1, 4)
        self.Sheet.setRange(
            "Summary", maxrow + RowOffset, 1,
            [[network] + TableHeadings])  # Write the heading data

        # Find the row that corrosponds to the current date
        Dates = self.Sheet.getRange(self.CalculationSheet + suffix, 4, 1,
                                    maxrow, 1)
        Dates = [self.Sheet.getDateTime(Date[0])
                 for Date in Dates]  # Convert a 2D list of tuples to a 1D list
        try:
            index = Dates.index(
                datetime.datetime(currentDate.year, currentDate.month,
                                  currentDate.day))
        except ValueError:
            index = len(Dates) - 1

        for param in self.IndexHeadings:
            # Read the entire row of data
            YTD_row = self.Sheet.getRange(
                self.CalculationSheet + suffix, index + 4, 1, index + 4,
                self.Sheet.getMaxCol(self.CalculationSheet + suffix, 2, 3))[0]
            # Convert the row data to: CAP, TARGET, COLLAR, YTD Total, YTD Planned, YTD Unplanned
            #YTD_row[ColOffset : len(DataHeadings)+ColOffset+1]
            i = self.IndexHeadings.index(param)
            TableRow = [
                YTD_row[ColOffset], YTD_row[ColOffset + 1],
                YTD_row[ColOffset + 2],
                YTD_row[ColOffset + 3] + YTD_row[ColOffset + 4],
                YTD_row[ColOffset + 3],
                [
                    0.5 * CC_Revenue_At_Risk.get(network, 0) /
                    (self.ORS._get_stats("CAP")[i] -
                     self.ORS._get_stats("TARGET")[i])
                ]
            ]

            RowOffset += 1
            self.Sheet.setRange("Summary", maxrow + RowOffset, 1,
                                [[param] + TableRow])  # Write the heading data
            ColOffset += len(self.DataHeadings)

        Table = []
        Table.append([
            "Revenue at risk",
            CC_Revenue_At_Risk.get(network, "No Revenue Found")
        ])  # Revenue at Risk
        Table.append([
            "Total Number of ICPs",
            self.ORS._get_total_customers(Dates[index])
        ])  # Total Number of ICPs
        Table.append(["Year to date figures as of", Dates[index]])  # Date
        self.Sheet.setRange("Summary", maxrow + RowOffset + 1, 1, Table)

    def Generate_Values(self, enddate, startdate=None):
        """
		Generate dictionary key value pairs for "Rob's" template - suitable for commercial team.

		@param enddate: Date to stop counting SAIDI and SAIFI for the YTD figures.
		@param startdate: Defaults to the 1/4/<1 year less than end>. Date to start counting SAIDI and SAIFI for YTD figures.
		@return: A dictionary of the keyword spesfic to the ORS instance currently being handled
		This functoin will work with date ranges larger than 1 year, but the CC_SAIDI_YTD/CC_SAIFI_YTD interpolations will
		be meainingless as these are intended to be scaled over 1 whole year starting on 1/4/n and ending on 31/3/n+1.
		"""
        if not startdate:
            year = self.ORS._get_fiscal_year(
                enddate
            ) - 1  # Function returns the fiscal year (int) for the given date
            startdate = datetime.datetime(year, 4, 1)
        else:
            year = self.ORS._get_fiscal_year(startdate) - 1

        # Some checks... any future dates will be redfined as the present date
        assert startdate < enddate, "The end date is set before the startdate"
        now = datetime.datetime.now()
        if now < enddate:
            enddate = datetime.datetime(now.year, now.month, now.day)
            year = self.ORS._get_fiscal_year(enddate) - 1

        # Fixed sheet data
        name = self.Rename_Network(self.NetworkName) + "_"
        params = {}
        params[name + "DATE_END"] = enddate
        params[name + "CUST_NUM"] = self.ORS._get_total_customers(enddate)

        # Annual data
        Dates = self.Generate_Dates(startdate, enddate)
        Dates = [Date[0] for Date in Dates]
        SAIDI_, SAIFI_ = self._Calc_Rows(
            Dates, self.ORS
        )  # (planned, unplanned, unplanned normed) for the given dates
        params[name + "SAIDI_NORMED_OUT"] = np.sum(SAIDI_, 0)[2]
        params[name + "SAIFI_NORMED_OUT"] = np.sum(SAIFI_, 0)[2]
        params[name + "SAIDI_UNPLANNED"] = np.sum(SAIDI_, 0)[1]
        params[name + "SAIFI_UNPLANNED"] = np.sum(SAIFI_, 0)[1]
        params[name + "SAIDI_PLANNED"] = np.sum(SAIDI_, 0)[0]
        params[name + "SAIFI_PLANNED"] = np.sum(SAIFI_, 0)[0]
        params[name + "RAW_PLANNED"] = np.sum(
            [self.ORS._get_num_faults(date, "planned") for date in Dates])
        params[name + "RAW_UNPLANNED"] = np.sum(
            [self.ORS._get_num_faults(date, "unplanned") for date in Dates])
        params[name + "RAW_NUM_MAJOR_EVENTS_SAIDI"] = len(
            self.ORS.get_capped_days(Dates[0], Dates[-1])[0])
        params[name + "RAW_NUM_MAJOR_EVENTS_SAIFI"] = len(
            self.ORS.get_capped_days(Dates[0], Dates[-1])[1])

        # Monthly data (present month)
        Dates = self.Generate_Dates(
            datetime.datetime(enddate.year, enddate.month, 1), enddate)
        Dates = [Date[0] for Date in Dates]
        SAIDI_, SAIFI_ = self._Calc_Rows(
            Dates, self.ORS
        )  # (planned, unplanned, unplanned normed) for the given dates
        params[name + "SAIDI_MONTH_NORMED_OUT"] = np.sum(SAIDI_, 0)[2]
        params[name + "SAIFI_MONTH_NORMED_OUT"] = np.sum(SAIFI_, 0)[2]
        params[name + "SAIDI_MONTH_UNPLANNED"] = np.sum(SAIDI_, 0)[1]
        params[name + "SAIFI_MONTH_UNPLANNED"] = np.sum(SAIFI_, 0)[1]
        params[name + "SAIDI_MONTH_PLANNED"] = np.sum(SAIDI_, 0)[0]
        params[name + "SAIFI_MONTH_PLANNED"] = np.sum(SAIFI_, 0)[0]
        params[name + "RAW_MONTH_PLANNED"] = np.sum(
            [self.ORS._get_num_faults(date, "planned") for date in Dates])
        params[name + "RAW_MONTH_UNPLANNED"] = np.sum(
            [self.ORS._get_num_faults(date, "unplanned") for date in Dates])
        params[name + "RAW_MONTH_NUM_MAJOR_EVENTS_SAIDI"] = len(
            self.ORS.get_capped_days(Dates[0], Dates[-1])[0])
        params[name + "RAW_MONTH_NUM_MAJOR_EVENTS_SAIFI"] = len(
            self.ORS.get_capped_days(Dates[0], Dates[-1])[1])

        # Com Com Interpolations (could use np.linspace)
        SAIDI_TARGET, SAIFI_TARGET = self.ORS._get_CC_stats("TARGET")
        num_days = (datetime.datetime(year + 1, 3, 31) -
                    datetime.datetime(year, 3, 31)).days
        x_days = (enddate - startdate).days
        SAIDI_M = SAIDI_TARGET / num_days
        SAIFI_M = SAIFI_TARGET / num_days
        params[name + "CC_SAIDI_YTD"] = SAIDI_M * (1 + x_days)
        params[name + "CC_SAIFI_YTD"] = SAIFI_M * (1 + x_days)
        params[name + "CC_SAIDI_TARGET"] = CC_Vals.get(
            self.NetworkName).get("SAIDI_TARGET")
        params[name + "CC_SAIFI_TARGET"] = CC_Vals.get(
            self.NetworkName).get("SAIFI_TARGET")
        params[name + "CC_SAIDI_CAP"] = CC_Vals.get(
            self.NetworkName).get("SAIDI_CAP")
        params[name + "CC_SAIFI_CAP"] = CC_Vals.get(
            self.NetworkName).get("SAIFI_CAP")
        params[name + "CC_SAIDI_COLLAR"] = CC_Vals.get(
            self.NetworkName).get("SAIDI_COLLAR")
        params[name + "CC_SAIFI_COLLAR"] = CC_Vals.get(
            self.NetworkName).get("SAIFI_COLLAR")
        params[name +
               "CC_REV_RISK"] = CC_Revenue_At_Risk.get(self.NetworkName) * 0.01
        return params
コード例 #3
0
class ParseORS(object):
	NetworkNames = ["ELIN", "TPCO", "OTPO", "LLNW"] # The order the network names appear in the input spreadsheet
	InputSheet = "Input" # The name of the Excel sheet used for user input
	Months = ["March (yr 0)", "April", "May", "June", "July", "August", "September", "October",
			"November", "December", "January", "February", "March (yr 1)"] # The months in a fiscal year

	def __init__(self, xlInstance):
		self.xlInst = xlInstance
		self.Sheet = Sheet(xlInstance)
		
		
		# Create some dictionaries to hold customer numbers
		
		self.Customer_Nums = {}
		for name in self.NetworkNames:
			self.Customer_Nums[name] = {}
		
		# Create a ordered list of network charts/tables to display
		self.StartDates = []

	def Read_Num_Cust(self):
		"""Read the average number of customers"""
		o = pos(row=3, col=1)
		Table = self.Sheet.getRange(self.InputSheet, o.row, o.col,
					self.Sheet.getMaxRow(self.InputSheet, o.col, o.row), 
					self.Sheet.getMaxCol(self.InputSheet, o.col, o. row))
		# Get the number of customers - fill up the dictionaries
		for row in Table:
			cell = row.__iter__()
			year = cell.next().year # Skip to column B
			cell.next() # Skip over column C
			for name in self.NetworkNames:
				self.Customer_Nums[name][year] = cell.next() # Get the value of the current cell and incriment the address pointer
		return self.Customer_Nums

	def _Read_Last_Date(self):
		"""Read the last date the user has input data for"""
		o = pos(row=3, col=1)
		# Read the last date in the yearly table
		FinalDate = self.Sheet.getCell(self.InputSheet, o.col, 
								 self.Sheet.getMaxCol(self.InputSheet, o.col, o. row))
		return self.Sheet.getDateTime(FinalDate)

	def Read_Num_Cust_Final(self):
		"""Read the number of customers in the final year only.
		This is data from the by month table."""
		o = pos(row=3, col=1)
		MonthlyICPs = {}
		# Read the last date in the yearly table
		FinalDate = self._Read_Last_Date()
		
		Table = self.Sheet.getRange(self.InputSheet, o.row, o.col,
					self.Sheet.getMaxRow(self.InputSheet, o.col, o.row), 
					self.Sheet.getMaxCol(self.InputSheet, o.col, o. row))
		
	def Read_Dates_To_Publish(self):
		"""Read the dates that require results to be outputted.
		Returns the date range expected by the ORS calcualtor."""
		o = pos(row=3, col=1)
		Table = self.Sheet.getRange(self.InputSheet, o.row, o.col,
					self.Sheet.getMaxRow(self.InputSheet, o.col, o.row), 
					self.Sheet.getMaxCol(self.InputSheet, o.col, o. row))
		# Get the number of customers - fill up the dictionaries
		for row in Table:
			if row[-1] == "Y" or row[-1] == "y":
				self.StartDates.append(datetime.datetime(row[0].year-1, 4, 1)) # Substract 1 from the end of fiscal year to get the start of the year
		if len(self.StartDates):
			return min(self.StartDates), datetime.datetime(max(self.StartDates).year+1, 3, 31) # Add 1 back to the year, so we get the end of fiscal year
		else:
			return None, None
	
	def Read_Last_Date(self):
		"""Read (get) the last date field"""
		o = pos(row=17, col=12)
		lastdate = self.Sheet.getCell(self.InputSheet, o.row, o.col)
		try:
			return self.Sheet.getDateTime(lastdate)
		except AttributeError:
			# The user entered an invalid date 
			return datetime.datetime.now()

	def Restore_Input_Default(self):
		"""Restore the default state of the table that has all the ICP counts for each network"""
		o = pos(row=3, col=1)
		OutputTable = []
		for year in CUST_NUMS.get(self.NetworkNames[0]):
			RowData = [datetime.datetime(year, 3, 31), year-1]
			for name in self.NetworkNames:
				RowData.append(CUST_NUMS.get(name).get(year))
			#RowData.append("Y") # The default option is to display the sheet
			OutputTable.append(RowData)
		# Sort the rows in the table so that we have the dates in cronological order
		OutputTable = sorted(OutputTable, key=lambda e: e[0], reverse=False)
		# Set the output range in excel
		self.Sheet.setRange(self.InputSheet, o.row-1, o.col+2, [self.NetworkNames])
		self.Sheet.setRange(self.InputSheet, o.row, o.col, OutputTable)

	def Set_Mean_ICPs(self, lastyear):
		"""Sets the mean (average) number of ICPS in the annual table from 
		records in the monthly table. The date 31/03/XXXX must appear in the 
		main annual data table, otherwise no updates will occur."""
		o_table1 = pos(row=3, col=1) # Top left cnr of annual table
		o_table2 = pos(row=3, col=11) # Top left cnr of the monthly table
		# Table Rows: [Month name, Year of months occurance, self.NetworkNames[]]

		# Find the average number of ICPs
		coloffset = 2 # Offset of ICP data from the left most column in the table
		maxrow = 15 # Last row in the table
		for network in self.NetworkNames:
			# Find the number of records in the monthly table
			lastrow = self.Sheet.getMaxRow(self.InputSheet, coloffset + o_table2.col, o_table2.row)
			if lastrow > maxrow:
				lastrow = o_table2.row
			# Compute the average number of ICPs (using the first and last row in the monthly table,
			# in the case of only a single month, then the first and last row are the same).
			avrg = (self.Sheet.getCell(self.InputSheet, lastrow, coloffset + o_table2.col) + \
			    self.Sheet.getCell(self.InputSheet, o_table2.row, coloffset + o_table2.col)) / 2

			# Place the average in the specified record
			# Input param replcaed the line below
			#lastyear = int(self.Sheet.getCell(self.InputSheet, o_table2.row, o_table2.col + 1)) + 1
			try:
				lastrow = self.Sheet.brief_search(self.InputSheet, "31/03/"+str(lastyear+1)).Row
				self.Sheet.setCell(self.InputSheet, lastrow, coloffset + o_table1.col, avrg)
			except:
				pass

			coloffset += 1

	def Restore_Table_2(self, lastyear=None):
		"""Builds the table for gathering ICP data by month"""
		o_table1 = pos(row=3, col=1) # Top left cnr of annual table
		o_table2 = pos(row=3, col=11) # Top left cnr of the monthly table

		# Get the row for the last date in the annual data table (table1)
		lastrow = self.Sheet.getMaxRow(self.InputSheet, o_table1.col, o_table1.row)
		if lastrow > 10000:
			lastrow = o_table1.row

		# If lastyear is None, then the last row in year in the last row of the
		# annual data table (table1) is used.
		if not lastyear:
			lastyear = self.Sheet.getDateTime(
					self.Sheet.getCell(self.InputSheet, lastrow, o_table1.col)).year

		# Build the two left most column of table 2 (Months names, Fiscal year)
		rowindex = 0
		# Iterate over an array of months (arranged in order for a fiscal year)
		for month in self.Months:
			fiscalyear = lastyear
			if self.Months.index("December") >= self.Months.index(month):
				# We are in first 3/4 of the year
				fiscalyear -= 1
			
			# Write each row in table2 (first two columns only), for example, "March (yr0), 2016"
			self.Sheet.setRange(self.InputSheet, o_table2.row+rowindex, o_table2.col, [(month, fiscalyear)])
			rowindex += 1

		# DON'T DO THIS! This will copy the last years average... we want the number of ICPs
		# as of the 31st March on the previous fiscal year instead...
		# Automatically copy the previous years data to record 0
		##lastrow -= 1 # Get the previous years data
		##if lastrow <= o_table1.row:
		##	lastrow = o_table1.row
		##previousrange= self.Sheet.getRange(self.InputSheet, lastrow, o_table1.col+2, lastrow, o_table1.col+5)
		##self.Sheet.setRange(self.InputSheet, o_table2.row, o_table2.col+2, previousrange)

	def Set_Year(self, year):
		"""Used to update the table labels at the end/start of a new fiscal year"""
		o_table1 = pos(row=3, col=1) # Top left cnr of annual table
		o_table2 = pos(row=3, col=11) # Top left cnr of the monthly table

		# Try and find the year in table1, otherwise create a new row(s)
		lastrow = self.Sheet.getMaxRow(self.InputSheet, o_table1.col, o_table1.row)
		if lastrow > 10000:
			lastrow = o_table1.row

		try:
			lastyear = self.Sheet.getDateTime(
				self.Sheet.getCell(self.InputSheet, lastrow, o_table1.col)).year
		except:
			lastyear = datetime.datetime.strptime(
					self.Sheet.getCell(self.InputSheet, lastrow, o_table1.col),
					"%d/%m/%Y").year

		# Change the labels on table 2 to match the selected year
		self.Restore_Table_2(year+1)

		while lastyear <= year:
			# We need to create some new rows in table1
			lastrow += 1
			lastyear += 1
			self.Sheet.setRange(self.InputSheet, lastrow, o_table1.col, [(datetime.datetime(lastyear, 3, 31), lastyear-1)])