Exemplo n.º 1
0
    def __init__(self,
                 gfactors=None,
                 start_year=JSON_START_YEAR,
                 num_years=DEFAULT_NUM_YEARS):
        super(Policy, self).__init__()

        if gfactors is None:
            self._gfactors = GrowFactors()
        elif isinstance(gfactors, GrowFactors):
            self._gfactors = gfactors
        else:
            raise ValueError('gfactors is not None or a GrowFactors instance')

        # read default parameters
        self._vals = self._params_dict_from_json_file()

        if start_year < Policy.JSON_START_YEAR:
            raise ValueError('start_year cannot be less than JSON_START_YEAR')
        if num_years < 1:
            raise ValueError('num_years cannot be less than one')

        syr = start_year
        lyr = start_year + num_years - 1
        self._inflation_rates = self._gfactors.price_inflation_rates(syr, lyr)
        self._apply_clp_cpi_offset(self._vals['_cpi_offset'], num_years)
        self._wage_growth_rates = self._gfactors.wage_growth_rates(syr, lyr)

        self.initialize(start_year, num_years)

        self.parameter_warnings = ''
        self.parameter_errors = ''
        self._ignore_errors = False
Exemplo n.º 2
0
 def cps_constructor(data=None,
                     gfactors=GrowFactors(),
                     exact_calculations=False):
     """
     Static method returns a Records object instantiated with CPS
     input data.  This works in a analogous way to Records(), which
     returns a Records object instantiated with PUF input data.
     This is a convenience method that eliminates the need to
     specify all the details of the CPS input data just as the
     default values of the arguments of the Records class constructor
     eliminate the need to specify all the details of the PUF input
     data.
     """
     if data is None:
         data = os.path.join(Records.CODE_PATH, 'cps.csv.gz')
     if gfactors is None:
         weights = None
     else:
         weights = os.path.join(Records.CODE_PATH,
                                Records.CPS_WEIGHTS_FILENAME)
     return Records(data=data,
                    start_year=Records.CPSCSV_YEAR,
                    gfactors=gfactors,
                    weights=weights,
                    adjust_ratios=Records.CPS_RATIOS_FILENAME,
                    exact_calculations=exact_calculations)
Exemplo n.º 3
0
    def set_rates(self):
        """Initialize taxcalc indexing data."""
        cpi_vals = [
            vo["value"] for
            vo in self._data["parameter_indexing_CPI_offset"]["value"]
        ]
        # extend parameter_indexing_CPI_offset values through budget window
        # if they have not been extended already.
        cpi_vals = cpi_vals + cpi_vals[-1:] * (
            self.end_year - self.start_year + 1 - len(cpi_vals)
        )
        cpi_offset = {
            (self.start_year + ix): val
            for ix, val in enumerate(cpi_vals)
        }

        self._gfactors = GrowFactors()

        self._inflation_rates = [
            np.round(rate + cpi_offset[self.start_year + ix], 4)
            for ix, rate in enumerate(
                self._gfactors.price_inflation_rates(
                    self.start_year, self.end_year
                )
            )
        ]

        self._wage_growth_rates = self._gfactors.wage_growth_rates(
            self.start_year, self.end_year
        )
 def __init__(self,
              data=CIT_DATA_FILENAME,
              data_type='cross-section',
              gfactors=GrowFactors(),
              weights=CIT_WEIGHTS_FILENAME,
              panel_blowup=CIT_BLOWFACTORS_FILENAME,
              start_year=CITCSV_YEAR):
     # pylint: disable=too-many-arguments,too-many-locals
     self.__data_year = start_year
     # read specified data
     if data_type == 'cross-section':
         self.data_type = data_type
     elif data_type == 'panel':
         self.data_type = data_type
         self.blowfactors_path = panel_blowup
     else:
         raise ValueError('data_type is not cross-section or panel')
     self._read_data(data)
     # handle grow factors
     is_correct_type = isinstance(gfactors, GrowFactors)
     if gfactors is not None and not is_correct_type:
         msg = 'gfactors is neither None nor a GrowFactors instance'
         raise ValueError(msg)
     self.gfactors = gfactors
     # read sample weights
     self.WT = None
     self._read_weights(weights)
     # weights must be same size as tax record data
     if self.WT.size > 0 and self.array_length != len(self.WT.index):
         # scale-up sub-sample weights by year-specific factor
         sum_full_weights = self.WT.sum()
         self.WT = self.WT.iloc[self.__index[:len(self.WT.index)]]
         sum_sub_weights = self.WT.sum()
         factor = sum_full_weights / sum_sub_weights
         self.WT *= factor
     # specify current_year and ASSESSMENT_YEAR values
     if isinstance(start_year, int):
         self.__current_year = start_year
         self.ASSESSMENT_YEAR.fill(start_year)
     else:
         msg = 'start_year is not an integer'
         raise ValueError(msg)
     # construct sample weights for current_year
     if self.WT.size > 0:
         wt_colname = 'WT{}'.format(self.current_year)
         if wt_colname in self.WT.columns:
             if len(self.WT[wt_colname]) == self.array_length:
                 self.weight = self.WT[wt_colname]
             else:
                 self.weight = (np.ones(self.array_length) *
                                sum(self.WT[wt_colname]) /
                                len(self.WT[wt_colname]))
Exemplo n.º 5
0
 def __init__(self, gfactors=None, only_reading_defaults=False, **kwargs):
     # put JSON contents of DEFAULTS_FILE_NAME into self._vals dictionary
     super().__init__()
     # handle gfactors argument
     if gfactors is None:
         self._gfactors = GrowFactors()
     elif isinstance(gfactors, GrowFactors):
         self._gfactors = gfactors
     else:
         raise ValueError('gfactors is not None or a GrowFactors instance')
     # read default parameters and initialize
     syr = Policy.JSON_START_YEAR
     lyr = Policy.LAST_BUDGET_YEAR
     nyrs = Policy.DEFAULT_NUM_YEARS
     self._inflation_rates = None
     self._wage_growth_rates = None
     self.initialize(syr, nyrs, Policy.LAST_KNOWN_YEAR,
                     Policy.REMOVED_PARAMS, Policy.REDEFINED_PARAMS,
                     Policy.WAGE_INDEXED_PARAMS, **kwargs)
Exemplo n.º 6
0
 def with_suffix(gdict, growdiff_baseline_dict, growdiff_response_dict):
     """
     Return param_base:year dictionary having only suffix parameters.
     """
     if bool(growdiff_baseline_dict) or bool(growdiff_response_dict):
         gdiff_baseline = GrowDiff()
         gdiff_baseline.update_growdiff(growdiff_baseline_dict)
         gdiff_response = GrowDiff()
         gdiff_response.update_growdiff(growdiff_response_dict)
         growfactors = GrowFactors()
         gdiff_baseline.apply_to(growfactors)
         gdiff_response.apply_to(growfactors)
     else:
         gdiff_baseline = None
         gdiff_response = None
         growfactors = None
     pol = Policy(gfactors=growfactors)
     pol.ignore_reform_errors()
     odict = dict()
     for param in gdict.keys():
         odict[param] = dict()
         for year in sorted(gdict[param].keys()):
             odict[param][year] = dict()
             for suffix in gdict[param][year].keys():
                 plist = getattr(pol, param).tolist()
                 dvals = plist[int(year) - Policy.JSON_START_YEAR]
                 odict[param][year] = [dvals]
                 idx = Policy.JSON_REFORM_SUFFIXES[suffix]
                 odict[param][year][0][idx] = gdict[param][year][suffix]
                 udict = {int(year): {param: odict[param][year]}}
                 pol.implement_reform(udict,
                                      print_warnings=False,
                                      raise_errors=False)
     del gdiff_baseline
     del gdiff_response
     del growfactors
     del pol
     return odict
 def __init__(self,
              data=PIT_DATA_FILENAME,
              gfactors=GrowFactors(),
              weights=PIT_WEIGHTS_FILENAME,
              start_year=PITCSV_YEAR):
     # pylint: disable=too-many-arguments,too-many-locals
     self.__data_year = start_year
     # read specified data
     self._read_data(data)
     # handle grow factors
     is_correct_type = isinstance(gfactors, GrowFactors)
     if gfactors is not None and not is_correct_type:
         msg = 'gfactors is neither None nor a GrowFactors instance'
         raise ValueError(msg)
     self.gfactors = gfactors
     # read sample weights
     self.WT = None
     self._read_weights(weights)
     # weights must be same size as tax record data
     if self.WT.size > 0 and self.array_length != len(self.WT.index):
         # scale-up sub-sample weights by year-specific factor
         sum_full_weights = self.WT.sum()
         self.WT = self.WT.iloc[self.__index]
         sum_sub_weights = self.WT.sum()
         factor = sum_full_weights / sum_sub_weights
         self.WT *= factor
     # specify current_year and AYEAR values
     if isinstance(start_year, int):
         self.__current_year = start_year
         self.AYEAR.fill(start_year)
     else:
         msg = 'start_year is not an integer'
         raise ValueError(msg)
     # construct sample weights for current_year
     if self.WT.size > 0:
         wt_colname = 'WT{}'.format(self.current_year)
         if wt_colname in self.WT.columns:
             self.weight = self.WT[wt_colname]
Exemplo n.º 8
0
    def __init__(self, gfactors=None):
        super(Policy, self).__init__()

        if gfactors is None:
            self._gfactors = GrowFactors()
        elif isinstance(gfactors, GrowFactors):
            self._gfactors = gfactors
        else:
            raise ValueError('gfactors is not None or a GrowFactors instance')

        # read default parameters and initialize
        self._vals = self._params_dict_from_json_file()
        syr = Policy.JSON_START_YEAR
        lyr = Policy.LAST_BUDGET_YEAR
        nyrs = Policy.DEFAULT_NUM_YEARS
        self._inflation_rates = self._gfactors.price_inflation_rates(syr, lyr)
        self._apply_clp_cpi_offset(self._vals['_cpi_offset'], nyrs)
        self._wage_growth_rates = self._gfactors.wage_growth_rates(syr, lyr)
        self.initialize(syr, nyrs)

        self.parameter_warnings = ''
        self.parameter_errors = ''
        self._ignore_errors = False
Exemplo n.º 9
0
 def __init__(self,
              data='puf.csv',
              exact_calculations=False,
              gfactors=GrowFactors(),
              weights=PUF_WEIGHTS_FILENAME,
              adjust_ratios=PUF_RATIOS_FILENAME,
              start_year=PUFCSV_YEAR):
     # pylint: disable=too-many-arguments,too-many-locals
     self.__data_year = start_year
     # read specified data
     self._read_data(data, exact_calculations)
     # check that three sets of split-earnings variables have valid values
     msg = 'expression "{0} == {0}p + {0}s" is not true for every record'
     tol = 0.020001  # handles "%.2f" rounding errors
     if not np.allclose(self.e00200, (self.e00200p + self.e00200s),
                        rtol=0.0, atol=tol):
         raise ValueError(msg.format('e00200'))
     if not np.allclose(self.e00900, (self.e00900p + self.e00900s),
                        rtol=0.0, atol=tol):
         raise ValueError(msg.format('e00900'))
     if not np.allclose(self.e02100, (self.e02100p + self.e02100s),
                        rtol=0.0, atol=tol):
         raise ValueError(msg.format('e02100'))
     # check that ordinary dividends are no less than qualified dividends
     other_dividends = np.maximum(0., self.e00600 - self.e00650)
     if not np.allclose(self.e00600, self.e00650 + other_dividends,
                        rtol=0.0, atol=tol):
         msg = 'expression "e00600 >= e00650" is not true for every record'
         raise ValueError(msg)
     del other_dividends
     # check that total pension income is no less than taxable pension inc
     nontaxable_pensions = np.maximum(0., self.e01500 - self.e01700)
     if not np.allclose(self.e01500, self.e01700 + nontaxable_pensions,
                        rtol=0.0, atol=tol):
         msg = 'expression "e01500 >= e01700" is not true for every record'
         raise ValueError(msg)
     del nontaxable_pensions
     # handle grow factors
     is_correct_type = isinstance(gfactors, GrowFactors)
     if gfactors is not None and not is_correct_type:
         msg = 'gfactors is neither None nor a GrowFactors instance'
         raise ValueError(msg)
     self.gfactors = gfactors
     # read sample weights
     self.WT = None
     self._read_weights(weights)
     self.ADJ = None
     self._read_ratios(adjust_ratios)
     # weights must be same size as tax record data
     if self.WT.size > 0 and self.array_length != len(self.WT.index):
         # scale-up sub-sample weights by year-specific factor
         sum_full_weights = self.WT.sum()
         self.WT = self.WT.iloc[self.__index]
         sum_sub_weights = self.WT.sum()
         factor = sum_full_weights / sum_sub_weights
         self.WT *= factor
     # specify current_year and FLPDYR values
     if isinstance(start_year, int):
         self.__current_year = start_year
         self.FLPDYR.fill(start_year)
     else:
         msg = 'start_year is not an integer'
         raise ValueError(msg)
     # construct sample weights for current_year
     if self.WT.size > 0:
         wt_colname = 'WT{}'.format(self.current_year)
         if wt_colname in self.WT.columns:
             self.s006 = self.WT[wt_colname] * 0.01
     # specify that variable values do not include behavioral responses
     self.behavioral_responses_are_included = False
Exemplo n.º 10
0
    def init(self, input_data, tax_year, baseline, reform, assump,
             growdiff_growmodel, aging_input_data, exact_calculations):
        """
        TaxCalcIO class post-constructor method that completes initialization.

        Parameters
        ----------
        First five are same as the first five of the TaxCalcIO constructor:
            input_data, tax_year, baseline, reform, assump.

        growdiff_growmodel: GrowDiff object or None
            growdiff_growmodel GrowDiff object is used only in the
            TaxCalcIO.growmodel_analysis method.

        aging_input_data: boolean
            whether or not to extrapolate Records data from data year to
            tax_year.

        exact_calculations: boolean
            specifies whether or not exact tax calculations are done without
            any smoothing of "stair-step" provisions in the tax law.
        """
        # pylint: disable=too-many-arguments,too-many-locals
        # pylint: disable=too-many-statements,too-many-branches
        self.errmsg = ''
        # get policy parameter dictionary from --baseline file
        basedict = Calculator.read_json_param_objects(baseline, None)
        # get assumption sub-dictionaries
        paramdict = Calculator.read_json_param_objects(None, assump)
        # get policy parameter dictionaries from --reform file(s)
        policydicts = list()
        if self.specified_reform:
            reforms = reform.split('+')
            for ref in reforms:
                pdict = Calculator.read_json_param_objects(ref, None)
                policydicts.append(pdict['policy'])
            paramdict['policy'] = policydicts[0]
        # remember parameters for reform documentation
        self.param_dict = paramdict
        self.policy_dicts = policydicts
        # create Behavior object
        beh = Behavior()
        try:
            beh.update_behavior(paramdict['behavior'])
        except ValueError as valerr_msg:
            self.errmsg += valerr_msg.__str__()
        self.behavior_has_any_response = beh.has_any_response()
        # create gdiff_baseline object
        gdiff_baseline = GrowDiff()
        try:
            gdiff_baseline.update_growdiff(paramdict['growdiff_baseline'])
        except ValueError as valerr_msg:
            self.errmsg += valerr_msg.__str__()
        # create GrowFactors base object that incorporates gdiff_baseline
        gfactors_base = GrowFactors()
        gdiff_baseline.apply_to(gfactors_base)
        # specify gdiff_response object
        gdiff_response = GrowDiff()
        try:
            gdiff_response.update_growdiff(paramdict['growdiff_response'])
        except ValueError as valerr_msg:
            self.errmsg += valerr_msg.__str__()
        # create GrowFactors ref object that has all gdiff objects applied
        gfactors_ref = GrowFactors()
        gdiff_baseline.apply_to(gfactors_ref)
        gdiff_response.apply_to(gfactors_ref)
        if growdiff_growmodel:
            growdiff_growmodel.apply_to(gfactors_ref)
        # create Policy objects:
        # ... the baseline Policy object
        base = Policy(gfactors=gfactors_base)
        try:
            base.implement_reform(basedict['policy'],
                                  print_warnings=False,
                                  raise_errors=False)
            self.errmsg += base.parameter_errors
        except ValueError as valerr_msg:
            self.errmsg += valerr_msg.__str__()
        # ... the reform Policy object
        if self.specified_reform:
            pol = Policy(gfactors=gfactors_ref)
            for poldict in policydicts:
                try:
                    pol.implement_reform(poldict,
                                         print_warnings=False,
                                         raise_errors=False)
                    self.errmsg += pol.parameter_errors
                except ValueError as valerr_msg:
                    self.errmsg += valerr_msg.__str__()
        else:
            pol = Policy(gfactors=gfactors_base)
        # create Consumption object
        con = Consumption()
        try:
            con.update_consumption(paramdict['consumption'])
        except ValueError as valerr_msg:
            self.errmsg += valerr_msg.__str__()
        # create GrowModel object
        self.growmodel = GrowModel()
        try:
            self.growmodel.update_growmodel(paramdict['growmodel'])
        except ValueError as valerr_msg:
            self.errmsg += valerr_msg.__str__()
        # check for valid tax_year value
        if tax_year < pol.start_year:
            msg = 'tax_year {} less than policy.start_year {}'
            msg = msg.format(tax_year, pol.start_year)
            self.errmsg += 'ERROR: {}\n'.format(msg)
        if tax_year > pol.end_year:
            msg = 'tax_year {} greater than policy.end_year {}'
            msg = msg.format(tax_year, pol.end_year)
            self.errmsg += 'ERROR: {}\n'.format(msg)
        # any errors imply cannot proceed with calculations
        if self.errmsg:
            return
        # set policy to tax_year
        pol.set_year(tax_year)
        base.set_year(tax_year)
        # read input file contents into Records objects
        if aging_input_data:
            if self.cps_input_data:
                recs = Records.cps_constructor(
                    gfactors=gfactors_ref,
                    exact_calculations=exact_calculations)
                recs_base = Records.cps_constructor(
                    gfactors=gfactors_base,
                    exact_calculations=exact_calculations)
            else:  # if not cps_input_data but aging_input_data
                recs = Records(data=input_data,
                               gfactors=gfactors_ref,
                               exact_calculations=exact_calculations)
                recs_base = Records(data=input_data,
                                    gfactors=gfactors_base,
                                    exact_calculations=exact_calculations)
        else:  # input_data are raw data that are not being aged
            recs = Records(data=input_data,
                           gfactors=None,
                           exact_calculations=exact_calculations,
                           weights=None,
                           adjust_ratios=None,
                           start_year=tax_year)
            recs_base = copy.deepcopy(recs)
        if tax_year < recs.data_year:
            msg = 'tax_year {} less than records.data_year {}'
            msg = msg.format(tax_year, recs.data_year)
            self.errmsg += 'ERROR: {}\n'.format(msg)
        # create Calculator objects
        self.calc = Calculator(policy=pol,
                               records=recs,
                               verbose=True,
                               consumption=con,
                               behavior=beh,
                               sync_years=aging_input_data)
        self.calc_base = Calculator(policy=base,
                                    records=recs_base,
                                    verbose=False,
                                    consumption=con,
                                    sync_years=aging_input_data)
Exemplo n.º 11
0
 def __init__(self,
              data='puf.csv',
              start_year=PUFCSV_YEAR,
              gfactors=GrowFactors(),
              weights=PUF_WEIGHTS_FILENAME,
              adjust_ratios=PUF_RATIOS_FILENAME,
              exact_calculations=False):
     # pylint: disable=no-member,too-many-branches
     if isinstance(weights, str):
         weights = os.path.join(Records.CODE_PATH, weights)
     super().__init__(data, start_year, gfactors, weights)
     if data is None:
         return  # because there are no data
     # read adjustment ratios
     self.ADJ = None
     self._read_ratios(adjust_ratios)
     # specify exact value based on exact_calculations
     self.exact[:] = np.where(exact_calculations is True, 1, 0)
     # specify FLPDYR value based on start_year
     self.FLPDYR.fill(start_year)
     # check for valid MARS values
     if not np.all(np.logical_and(np.greater_equal(self.MARS, 1),
                                  np.less_equal(self.MARS, 5))):
         raise ValueError('not all MARS values in [1,5] range')
     # create variables derived from MARS, which is in MUST_READ_VARS
     self.num[:] = np.where(self.MARS == 2, 2, 1)
     self.sep[:] = np.where(self.MARS == 3, 2, 1)
     # check for valid EIC values
     if not np.all(np.logical_and(np.greater_equal(self.EIC, 0),
                                  np.less_equal(self.EIC, 3))):
         raise ValueError('not all EIC values in [0,3] range')
     # check that three sets of split-earnings variables have valid values
     msg = 'expression "{0} == {0}p + {0}s" is not true for every record'
     tol = 0.020001  # handles "%.2f" rounding errors
     if not np.allclose(self.e00200, (self.e00200p + self.e00200s),
                        rtol=0.0, atol=tol):
         raise ValueError(msg.format('e00200'))
     if not np.allclose(self.e00900, (self.e00900p + self.e00900s),
                        rtol=0.0, atol=tol):
         raise ValueError(msg.format('e00900'))
     if not np.allclose(self.e02100, (self.e02100p + self.e02100s),
                        rtol=0.0, atol=tol):
         raise ValueError(msg.format('e02100'))
     # check that spouse income variables have valid values
     nospouse = self.MARS != 2
     zeros = np.zeros_like(self.MARS[nospouse])
     msg = '{} is not always zero for non-married filing unit'
     if not np.allclose(self.e00200s[nospouse], zeros):
         raise ValueError(msg.format('e00200s'))
     if not np.allclose(self.e00900s[nospouse], zeros):
         raise ValueError(msg.format('e00900s'))
     if not np.allclose(self.e02100s[nospouse], zeros):
         raise ValueError(msg.format('e02100s'))
     if not np.allclose(self.k1bx14s[nospouse], zeros):
         raise ValueError(msg.format('k1bx14s'))
     # check that ordinary dividends are no less than qualified dividends
     other_dividends = np.maximum(0., self.e00600 - self.e00650)
     if not np.allclose(self.e00600, self.e00650 + other_dividends,
                        rtol=0.0, atol=tol):
         msg = 'expression "e00600 >= e00650" is not true for every record'
         raise ValueError(msg)
     del other_dividends
     # check that total pension income is no less than taxable pension inc
     nontaxable_pensions = np.maximum(0., self.e01500 - self.e01700)
     if not np.allclose(self.e01500, self.e01700 + nontaxable_pensions,
                        rtol=0.0, atol=tol):
         msg = 'expression "e01500 >= e01700" is not true for every record'
         raise ValueError(msg)
     del nontaxable_pensions
     # check that PT_SSTB_income has valid value
     if not np.all(np.logical_and(np.greater_equal(self.PT_SSTB_income, 0),
                                  np.less_equal(self.PT_SSTB_income, 1))):
         raise ValueError('not all PT_SSTB_income values are 0 or 1')
def generate_policy_revenues():
    from taxcalc.growfactors import GrowFactors
    from taxcalc.policy import Policy
    from taxcalc.records import Records
    from taxcalc.gstrecords import GSTRecords
    from taxcalc.corprecords import CorpRecords
    from taxcalc.parameters import ParametersBase
    from taxcalc.calculator import Calculator
    

    """
    for num in range(1, num_reforms):
        block_selected_dict[num]['selected_item']= block_widget_dict[num][1].get()
        block_selected_dict[num]['selected_value']= block_widget_dict[num][3].get()
        block_selected_dict[num]['selected_year']= block_widget_dict[num][2].get()
    print(block_selected_dict)
    """
    f = open('reform.json')
    block_selected_dict = json.load(f)
    print("block_selected_dict from json",block_selected_dict)
    #print(block_selected_dict)
    # create Records object containing pit.csv and pit_weights.csv input data
    #print("growfactors filename ", growfactors_filename)
    #recs = Records(data=data_filename, weights=weights_filename, gfactors=GrowFactors(growfactors_filename=growfactors_filename))
    #recs = Records(data=data_filename, weights=weights_filename, gfactors=GrowFactors(growfactors_filename=growfactors_filename))

    #recs.increment_year1(3.0)
    
    #grecs = GSTRecords()
    f = open('global_vars.json')
    vars = json.load(f)
        
    print("data_filename: ", vars['cit_data_filename'])
    print("weights_filename: ", vars['cit_weights_filename'])
    print("growfactors_filename: ", vars['GROWFACTORS_FILENAME'])
    print("policy_filename: ", vars['DEFAULTS_FILENAME'])
    # create CorpRecords object using cross-section data
    #crecs1 = CorpRecords(data='cit_cross.csv', weights='cit_cross_wgts1.csv')
    crecs1 = CorpRecords(data=vars['cit_data_filename'], weights=vars['cit_weights_filename'], gfactors=GrowFactors(growfactors_filename=vars['GROWFACTORS_FILENAME']))
    #crecs1 = CorpRecords(data=vars['cit_weights_filename'], weights=vars['cit_weights_filename'])

    # Note: weights argument is optional
    assert isinstance(crecs1, CorpRecords)
    assert crecs1.current_year == 2017
    
    # create Policy object containing current-law policy
    pol = Policy(DEFAULTS_FILENAME=vars['DEFAULTS_FILENAME'])
    
    # specify Calculator objects for current-law policy
    #calc1 = Calculator(policy=pol, records=recs, corprecords=crecs1,
    #                   gstrecords=grecs, verbose=False)
    calc1 = Calculator(policy=pol, corprecords=crecs1, verbose=False)    
    #calc1.increment_year1(3.8)
    assert isinstance(calc1, Calculator)
    assert calc1.current_year == 2017

    np.seterr(divide='ignore', invalid='ignore')
    
    pol2 = Policy(DEFAULTS_FILENAME=vars['DEFAULTS_FILENAME'])
    
    years, reform=read_reform_dict(block_selected_dict)
    print("reform dictionary: ",reform) 
    #reform = Calculator.read_json_param_objects('app01_reform.json', None)
    pol2.implement_reform(reform['policy'])
    
    #calc2 = Calculator(policy=pol2, records=recs, corprecords=crecs1,
    #                   gstrecords=grecs, verbose=False)
    calc2 = Calculator(policy=pol2, corprecords=crecs1, verbose=False)
    pit_adjustment_factor={}
    revenue_dict_cit={}
    revenue_amount_dict = {}

    calc1.calc_all()
        
           
    for year in range(2019, 2024):
        cols = []
        calc1.advance_to_year(year)       
        calc2.advance_to_year(year)
        # NOTE: calc1 now contains a PRIVATE COPY of pol and a PRIVATE COPY of recs,
        #       so we can continue to use pol and recs in this script without any
        #       concern about side effects from Calculator method calls on calc1.

        # Produce DataFrame of results using the calculator
        
        # First run the calculator for the corporate income tax
        calc1.calc_all()
        
        print("***** Year ", year)
        weighted_citax1 = calc1.weighted_total_cit('citax')                
        citax_collection_billions1 = weighted_citax1/10**9       
        citax_collection_str1 = '{0:.2f}'.format(citax_collection_billions1)
              
        print("The CIT Collection in billions is: ", citax_collection_billions1)
 
        # Produce DataFrame of results using cross-section
        calc2.calc_all()
       
        weighted_citax2 = calc2.weighted_total_cit('citax')                
        citax_collection_billions2 = weighted_citax2/10**9    
        citax_collection_str2 = '{0:.2f}'.format(citax_collection_billions2)
        # This is the difference in the collection due to the reform
        # This amount will now be allocated to dividends of PIT
        citax_diff_collection_billions2 = (citax_collection_billions2-citax_collection_billions1)
        citax_diff_collection_str2 = '{0:.2f}'.format(citax_diff_collection_billions2)
              
        print("The CIT Collection after reform billions is: ", citax_collection_billions2)

        print("The difference in CIT Collection in billions is: ", citax_diff_collection_billions2)

        # Process of allocation of difference in CIT profits to PIT 
        # in the form of Dividends
        # Dividends in this case is reported as Income from Other Sources
        # TOTAL_INCOME_OS in the PIT form
        
        # First get the unadjusted amounts
        
        # Now calculate the adjusted amounts
        # contribution to PIT Dividends
        proportion_change_dividend = (weighted_citax1 - weighted_citax2)/weighted_citax1       
        new_dividend_proportion_of_old = (1 + proportion_change_dividend)
        pit_adjustment_factor[year]=new_dividend_proportion_of_old
        # Store Results
        revenue_dict_cit[year]={}
        revenue_dict_cit[year]['current_law']=citax_collection_str1
        revenue_dict_cit[year]['reform']=citax_collection_str2      
        revenue_dict_cit[year]['difference']=citax_diff_collection_str2
        
    print(revenue_dict_cit)
    
    print("new_dividend_proportion_of_old ", pit_adjustment_factor)     

    # now update pit.csv with this proportion
    # start a new round of simulation for pit
    recs = Records(data=vars['pit_data_filename'], weights=vars['pit_weights_filename'], gfactors=GrowFactors(growfactors_filename=vars['GROWFACTORS_FILENAME']))
    
    # create Policy object containing current-law policy
    pol = Policy(DEFAULTS_FILENAME=vars['DEFAULTS_FILENAME'])
    
    # specify Calculator objects for current-law policy
    #calc1 = Calculator(policy=pol, records=recs, corprecords=crecs1,
    #                   gstrecords=grecs, verbose=False)
    calc1 = Calculator(policy=pol, records=recs, verbose=False)    
    #calc1.increment_year1(3.8)
    assert isinstance(calc1, Calculator)
    assert calc1.current_year == 2017

    np.seterr(divide='ignore', invalid='ignore')
    
    pol2 = Policy(DEFAULTS_FILENAME=vars['DEFAULTS_FILENAME'])
    
    #years, reform=read_reform_dict(block_selected_dict)
    #print("reform dictionary: ", reform) 
    #reform = Calculator.read_json_param_objects('app01_reform.json', None)
    pol2.implement_reform(reform['policy'])
    
    #calc2 = Calculator(policy=pol2, records=recs, corprecords=crecs1,
    #                   gstrecords=grecs, verbose=False)

    calc2 = Calculator(policy=pol2, records=recs, verbose=False)
        
    total_revenue_text={}
    reform_revenue_text={}
    revenue_dict_pit={}
    revenue_amount_dict = {}
    num = 1
    first_time = True
    i=1
    j=0
    #rows = []
    
    window = tk.Toplevel()
    window.geometry("800x400+140+140")
    display_table(window, revenue_dict_cit, revenue_dict_pit, header=True)

    #for year in range(years[0], years[-1]+1):            
    for year in range(2019, 2024):
        cols = []
        calc1.advance_to_year(year)       
        calc2.advance_to_year(year)
        # NOTE: calc1 now contains a PRIVATE COPY of pol and a PRIVATE COPY of recs,
        #       so we can continue to use pol and recs in this script without any
        #       concern about side effects from Calculator method calls on calc1.

        # Produce DataFrame of results using the calculator
        
        # First run the calculator for the corporate income tax
        calc1.calc_all()
        
        weighted_pitax1 = calc1.weighted_total_pit('pitax')                
        pitax_collection_billions1 = weighted_pitax1/10**9        
        pitax_collection_str1 = '{0:.2f}'.format(pitax_collection_billions1)
        
        print('\n\n\n')
        print(f'TAX COLLECTION FOR THE YEAR - {year} \n')   
        print("The PIT Collection in billions is: ", pitax_collection_billions1)       
        #total_revenue_text[year] = "PIT COLLECTION UNDER CURRENT LAW FOR THE YEAR - " + str(year)+" : "+str(pitax_collection_str1)+" bill"

        # Produce DataFrame of results using cross-section
        calc2.calc_all()
       
        
        weighted_pitax2 = calc2.weighted_total_pit('pitax')
        pitax_collection_billions2 = weighted_pitax2/10**9        
        pitax_collection_str2 = '{0:.2f}'.format(pitax_collection_billions2)
        pitax_diff_collection_billions2 = (pitax_collection_billions2-pitax_collection_billions1)        
        pitax_diff_collection_str2 = '{0:.2f}'.format(pitax_diff_collection_billions2)
        
        # Now calculate the adjusted amounts
        # contribution to PIT Dividends

        print("Total Income from Other Sources (bill) no adjustment is ", calc2.weighted_total_pit('TOTAL_INCOME_OS')/10**9 )       
        calc2.adjust_pit(pit_adjustment_factor[year])
        print("Total Income from Other Sources (bill) after adjustment is ", calc2.weighted_total_pit('TOTAL_INCOME_OS')/10**9 )
        
        calc2.calc_all()
        
        weighted_pitax3 = calc2.weighted_total_pit('pitax')     
        pitax_collection_billions3 = weighted_pitax3/10**9        
        pitax_collection_str3 = '{0:.2f}'.format(pitax_collection_billions3)

        pitax_diff_collection_billions3 = (pitax_collection_billions3-pitax_collection_billions1)        
        pitax_diff_collection_str3 = '{0:.2f}'.format(pitax_diff_collection_billions3)

        pitax_diff_collection_billions4 = (pitax_collection_billions3-pitax_collection_billions2)        
        pitax_diff_collection_str4 = '{0:.2f}'.format(pitax_diff_collection_billions4)
        
        #save the results
        revenue_dict_pit[year]={}
        revenue_dict_pit[year]['current_law']=pitax_collection_str1
        revenue_dict_pit[year]['reform']={}
        revenue_dict_pit[year]['reform']['unadjusted']=pitax_collection_str2
        revenue_dict_pit[year]['reform']['adjusted']=pitax_collection_str3
        revenue_dict_pit[year]['difference']=pitax_diff_collection_str3
        
        print('\n\n\n')       
        print(f'TAX COLLECTION FOR THE YEAR UNDER REFORM - {year} \n')       
        print("The PIT Collection in billions is: ", pitax_collection_billions2)
        print("The difference in PIT Collection in billions is: ", pitax_diff_collection_billions2)
        print('****AFTER ADJUSTMENT \n\n\n')
        print('TAX COLLECTION FOR THE YEAR UNDER REFORM WITH ADJUSTMENT \n')       
        print("The PIT Collection in billions after adjusting for the impact of CIT is: ", pitax_collection_billions3)        
        print("The difference in PIT Collection in billions after adjusting for the impact of CIT is: ", pitax_diff_collection_billions3)

        print("The impact of adjustment is: ", pitax_diff_collection_billions4)
        
        display_table(window, revenue_dict_cit, revenue_dict_pit, year=year, row=i)
        i=i+1
        #reverse the adjustment to obtain baseline
        calc2.adjust_pit(1/pit_adjustment_factor[year])
   
    display_table(window, revenue_dict_cit, revenue_dict_pit, footer=i)

    
    
    """
Exemplo n.º 13
0
    def adjust_with_indexing(self, params_or_path, **kwargs):
        """
        Adjust parameter values with the following indexing logic:

        1. If "parameter_indexing_CPI_offset" is adjusted, first set
           parameter_indexing_CPI_offset to zero before implementing the
           adjusted parameter_indexing_CPI_offset to avoid stacking
           adjustments. Then, revert all values of indexed parameters to
           the 'known' values:

            a. The current values of parameters that are being adjusted are
               deleted after the first year in which
               parameter_indexing_CPI_offset is adjusted.
            b. The current values of parameters that are not being adjusted
               (i.e. are not in params) are deleted after the last known year,
               with the exception of parameters that revert to their pre-TCJA
               values in 2026. Instead, these (2026) parameter values are
               recalculated using the new inflation rates.

            After the 'unknown' values have been deleted, the last known value
            is extrapolated through the budget window. If there are indexed
            parameters in the adjustment, they will be included in the final
            adjustment call (unless their indexed status is changed).

        2. If the "indexed" status is updated for any parameter:

            a. If a parameter has values that are being adjusted before
               the indexed status is adjusted, update those parameters first.
            b. Extend the values of that parameter to the year in which
               the status is changed.
            c. Change the indexed status for the parameter.
            d. Update parameter values in adjustment that are adjusted after
               the year in which the indexed status changes.
            e. Using the new "-indexed" status, extend the values of that
               parameter through the remaining years or until the -indexed
               status changes again.

        3. Update all parameters that are not indexing related, i.e. they are
           not "parameter_indexing_CPI_offset" or do not end with "-indexed".

        4. Return parsed adjustment with all adjustments, including "-indexed"
           parameters.

        Notable side-effects:

        - All values of a parameter whose indexed status is adjusted are
          wiped out after the year in which the value is adjusted for the
          same hard-coding reason.
        """
        # Temporarily turn off extra ops during the intermediary adjustments
        # so that expensive and unnecessary operations are not run.
        label_to_extend = self.label_to_extend
        array_first = self.array_first
        self.array_first = False
        self._gfactors = GrowFactors()

        params = self.read_params(params_or_path)

        # Check if parameter_indexing_CPI_offset is adjusted. If so, reset
        # values of all indexed parameters after year where
        # parameter_indexing_CPI_offset is changed. If
        # parameter_indexing_CPI_offset is changed multiple times, then
        # reset values after the first year in which the
        # parameter_indexing_CPI_offset is changed.
        needs_reset = []
        if params.get("parameter_indexing_CPI_offset") is not None:
            # Update parameter_indexing_CPI_offset with new value.
            cpi_adj = super().adjust(
                {
                    "parameter_indexing_CPI_offset":
                    params["parameter_indexing_CPI_offset"]
                }, **kwargs)
            # turn off extend now that parameter_indexing_CPI_offset
            # has been updated.
            self.label_to_extend = None
            # Get first year in which parameter_indexing_CPI_offset
            # is changed.
            cpi_min_year = min(cpi_adj["parameter_indexing_CPI_offset"],
                               key=lambda vo: vo["year"])

            rate_adjustment_vals = (
                self.sel["parameter_indexing_CPI_offset"]["year"] >=
                cpi_min_year["year"])
            # "Undo" any existing parameter_indexing_CPI_offset for
            # years after parameter_indexing_CPI_offset has
            # been updated.
            self._inflation_rates = self._inflation_rates[:cpi_min_year[
                "year"] - self.start_year] + self._gfactors.price_inflation_rates(
                    cpi_min_year["year"], self.LAST_BUDGET_YEAR)

            # Then apply new parameter_indexing_CPI_offset values to
            # inflation rates
            for cpi_vo in rate_adjustment_vals:
                self._inflation_rates[cpi_vo["year"] -
                                      self.start_year] += cpi_vo["value"]
            # 1. Delete all unknown values.
            # 1.a For revision, these are years specified after cpi_min_year.
            to_delete = {}
            for param in params:
                if (param == "parameter_indexing_CPI_offset"
                        or param in self._wage_indexed):
                    continue
                if param.endswith("-indexed"):
                    param = param.split("-indexed")[0]
                if self._data[param].get("indexed", False):
                    to_delete[param] = (self.sel[param]["year"] >
                                        cpi_min_year["year"])
                    needs_reset.append(param)
            self.delete(to_delete, **kwargs)

            # 1.b For all others, these are years after last_known_year.
            last_known_year = max(cpi_min_year["year"], self._last_known_year)
            # calculate 2026 value, using new inflation rates, for parameters
            # that revert to their pre-TCJA values.
            long_params = [
                'II_brk7', 'II_brk6', 'II_brk5', 'II_brk4', 'II_brk3',
                'II_brk2', 'II_brk1', 'PT_brk7', 'PT_brk6', 'PT_brk5',
                'PT_brk4', 'PT_brk3', 'PT_brk2', 'PT_brk1',
                'PT_qbid_taxinc_thd', 'ALD_BusinessLosses_c', 'STD', 'II_em',
                'II_em_ps', 'AMT_em', 'AMT_em_ps', 'AMT_em_pe', 'ID_ps',
                'ID_AllTaxes_c'
            ]
            final_ifactor = 1.0
            pyear = 2017  # prior year before TCJA first implemented
            fyear = 2026  # final year in which parameter values revert to
            # pre-TCJA values
            # construct final-year inflation factor from prior year
            # NOTE: pvalue[t+1] = pvalue[t] * ( 1 + irate[t] )
            for year in range(pyear, fyear):
                final_ifactor *= 1 + \
                    self._inflation_rates[year - self.start_year]

            long_param_vals = defaultdict(list)
            # compute final year parameter value
            for param in long_params:
                # only revert param in 2026 if it's not in revision
                if params.get(param) is None:
                    # grab param values from 2017
                    vos = self.sel[param]["year"] == pyear
                    # use final_ifactor to inflate from 2017 to 2026
                    for vo in vos:
                        long_param_vals[param].append(
                            # Create new dict to avoid modifying the original
                            dict(
                                vo,
                                value=min(
                                    9e99, round(vo["value"] * final_ifactor,
                                                0)),
                                year=fyear,
                            ))
                    needs_reset.append(param)
            super().adjust(long_param_vals, **kwargs)

            to_delete = {}
            for param in self._data:
                if (param in params or param == "parameter_indexing_CPI_offset"
                        or param in self._wage_indexed):
                    continue
                if self._data[param].get("indexed", False):
                    to_delete[param] = self.sel[param]["_auto"] == True  # noqa
                    needs_reset.append(param)

            self.delete(to_delete, **kwargs)

            self.extend(label="year")

        # 2. Handle -indexed parameters.
        self.label_to_extend = None
        index_affected = set([])
        for param, values in params.items():
            if param.endswith("-indexed"):
                base_param = param.split("-indexed")[0]
                if not self._data[base_param].get("indexable", None):
                    msg = f"Parameter {base_param} is not indexable."
                    raise pt.ValidationError({"errors": {
                        base_param: msg
                    }},
                                             labels=None)
                index_affected |= {param, base_param}
                indexed_changes = {}
                if isinstance(values, bool):
                    indexed_changes[self.start_year] = values
                elif isinstance(values, list):
                    for vo in values:
                        indexed_changes[vo.get("year",
                                               self.start_year)] = vo["value"]
                else:
                    msg = ("Index adjustment parameter must be a boolean or "
                           "list.")
                    raise pt.ValidationError({"errors": {
                        base_param: msg
                    }},
                                             labels=None)
                # 2.a Adjust values less than first year in which index status
                # was changed.
                if base_param in params:
                    min_index_change_year = min(indexed_changes.keys())
                    vos = self.sel[params[base_param]]["year"].lt(
                        min_index_change_year, strict=False)

                    if len(list(vos)):
                        min_adj_year = min(vos,
                                           key=lambda vo: vo["year"])["year"]
                        self.delete({
                            base_param:
                            self.sel[base_param]["year"] > min_adj_year  # noqa
                        })
                        super().adjust({base_param: vos}, **kwargs)
                        self.extend(
                            params=[base_param],
                            label="year",
                            label_values=list(
                                range(self.start_year, min_index_change_year)),
                        )

                for year in sorted(indexed_changes):
                    indexed_val = indexed_changes[year]
                    # Get and delete all default values after year where
                    # indexed status changed.
                    self.delete(
                        {base_param: self.sel[base_param]["year"] > year})

                    # 2.b Extend values for this parameter to the year where
                    # the indexed status changes.
                    if year > self.start_year:
                        self.extend(
                            params=[base_param],
                            label="year",
                            label_values=list(range(self.start_year,
                                                    year + 1)),
                        )

                    # 2.c Set indexed status.
                    self._data[base_param]["indexed"] = indexed_val

                    # 2.d Adjust with values greater than or equal to current
                    # year in params
                    if base_param in params:
                        vos = self.sel[params[base_param]]["year"].gte(
                            year, strict=False)
                        super().adjust({base_param: vos}, **kwargs)

                    # 2.e Extend values through remaining years.
                    self.extend(params=[base_param], label="year")

                needs_reset.append(base_param)
        # Re-instate ops.
        self.label_to_extend = label_to_extend
        self.array_first = array_first
        self.set_state()

        # Filter out "-indexed" params.
        nonindexed_params = {
            param: val
            for param, val in params.items() if param not in index_affected
        }

        # 3. Do adjustment for all non-indexing related parameters.
        adj = super().adjust(nonindexed_params, **kwargs)

        # 4. Add indexing params back for return to user.
        adj.update({
            param: val
            for param, val in params.items() if param in index_affected
        })
        return adj
def generate_revenues():
    from taxcalc.growfactors import GrowFactors
    from taxcalc.policy import Policy
    from taxcalc.records import Records
    from taxcalc.gstrecords import GSTRecords
    from taxcalc.corprecords import CorpRecords
    from taxcalc.parameters import ParametersBase
    from taxcalc.calculator import Calculator
    """
    for num in range(1, num_reforms):
        block_selected_dict[num]['selected_item']= block_widget_dict[num][1].get()
        block_selected_dict[num]['selected_value']= block_widget_dict[num][3].get()
        block_selected_dict[num]['selected_year']= block_widget_dict[num][2].get()
    print(block_selected_dict)
    """
    f = open('reform.json')
    block_selected_dict = json.load(f)
    print("block_selected_dict from json", block_selected_dict)
    #print(block_selected_dict)
    # create Records object containing pit.csv and pit_weights.csv input data
    #print("growfactors filename ", growfactors_filename)
    #recs = Records(data=data_filename, weights=weights_filename, gfactors=GrowFactors(growfactors_filename=growfactors_filename))
    #recs = Records(data=data_filename, weights=weights_filename, gfactors=GrowFactors(growfactors_filename=growfactors_filename))

    #recs.increment_year1(3.0)

    #grecs = GSTRecords()
    f = open('global_vars.json')
    vars = json.load(f)

    print("data_filename: ", vars['cit_data_filename'])
    print("weights_filename: ", vars['cit_weights_filename'])
    print("growfactors_filename: ", vars['GROWFACTORS_FILENAME'])
    print("policy_filename: ", vars['DEFAULTS_FILENAME'])
    # create CorpRecords object using cross-section data
    #crecs1 = CorpRecords(data='cit_cross.csv', weights='cit_cross_wgts1.csv')
    crecs1 = CorpRecords(
        data=vars['cit_data_filename'],
        weights=vars['cit_weights_filename'],
        gfactors=GrowFactors(
            growfactors_filename=vars['GROWFACTORS_FILENAME']))
    #crecs1 = CorpRecords(data=vars['cit_weights_filename'], weights=vars['cit_weights_filename'])

    # Note: weights argument is optional
    assert isinstance(crecs1, CorpRecords)
    assert crecs1.current_year == 2017

    # create Policy object containing current-law policy
    pol = Policy(DEFAULTS_FILENAME=vars['DEFAULTS_FILENAME'])

    # specify Calculator objects for current-law policy
    #calc1 = Calculator(policy=pol, records=recs, corprecords=crecs1,
    #                   gstrecords=grecs, verbose=False)
    calc1 = Calculator(policy=pol, corprecords=crecs1, verbose=False)
    #calc1.increment_year1(3.8)
    assert isinstance(calc1, Calculator)
    assert calc1.current_year == 2017

    np.seterr(divide='ignore', invalid='ignore')

    calc1.calc_all()
    revenue_dict_cit = {}

    for year in range(2019, 2024):
        cols = []
        calc1.advance_to_year(year)

        # NOTE: calc1 now contains a PRIVATE COPY of pol and a PRIVATE COPY of recs,
        #       so we can continue to use pol and recs in this script without any
        #       concern about side effects from Calculator method calls on calc1.

        # Produce DataFrame of results using the calculator

        # First run the calculator for the corporate income tax
        calc1.calc_all()

        print("***** Year ", year)
        weighted_citax1 = calc1.weighted_total_cit('citax')
        citax_collection_billions1 = weighted_citax1 / 10**9
        citax_collection_str1 = '{0:.2f}'.format(citax_collection_billions1)

        print("The CIT Collection in billions is: ",
              citax_collection_billions1)

        # Store Results
        revenue_dict_cit[year] = {}
        revenue_dict_cit[year]['current_law'] = citax_collection_str1

    # start a new round of simulation for pit
    recs = Records(data=vars['pit_data_filename'],
                   weights=vars['pit_weights_filename'],
                   gfactors=GrowFactors(
                       growfactors_filename=vars['GROWFACTORS_FILENAME']))

    # create Policy object containing current-law policy
    pol = Policy(DEFAULTS_FILENAME=vars['DEFAULTS_FILENAME'])

    # specify Calculator objects for current-law policy
    #calc1 = Calculator(policy=pol, records=recs, corprecords=crecs1,
    #                   gstrecords=grecs, verbose=False)
    calc1 = Calculator(policy=pol, records=recs, verbose=False)
    #calc1.increment_year1(3.8)
    assert isinstance(calc1, Calculator)
    assert calc1.current_year == 2017

    np.seterr(divide='ignore', invalid='ignore')

    total_revenue_text = {}
    reform_revenue_text = {}
    revenue_dict_pit = {}
    revenue_amount_dict = {}
    num = 1
    first_time = True
    i = 1
    j = 0
    #rows = []

    window = tk.Toplevel()
    window.geometry("800x400+140+140")
    display_table(window, revenue_dict_cit, revenue_dict_pit, header=True)

    #for year in range(years[0], years[-1]+1):
    for year in range(2019, 2024):
        cols = []
        calc1.advance_to_year(year)

        # NOTE: calc1 now contains a PRIVATE COPY of pol and a PRIVATE COPY of recs,
        #       so we can continue to use pol and recs in this script without any
        #       concern about side effects from Calculator method calls on calc1.

        # Produce DataFrame of results using the calculator

        # First run the calculator for the corporate income tax
        calc1.calc_all()

        weighted_pitax1 = calc1.weighted_total_pit('pitax')
        pitax_collection_billions1 = weighted_pitax1 / 10**9
        pitax_collection_str1 = '{0:.2f}'.format(pitax_collection_billions1)

        print('\n\n\n')
        print(f'TAX COLLECTION FOR THE YEAR - {year} \n')
        print("The PIT Collection in billions is: ",
              pitax_collection_billions1)
        #total_revenue_text[year] = "PIT COLLECTION UNDER CURRENT LAW FOR THE YEAR - " + str(year)+" : "+str(pitax_collection_str1)+" bill"

        #save the results
        revenue_dict_pit[year] = {}
        revenue_dict_pit[year]['current_law'] = pitax_collection_str1

        display_table(window,
                      revenue_dict_cit,
                      revenue_dict_pit,
                      year=year,
                      row=i)
        i = i + 1

    display_table(window, revenue_dict_cit, revenue_dict_pit, footer=i)
    """