Пример #1
0
def test_arg_validation():
    with pytest.raises(ValueError):
        TaxBrain(2018, 2020)
    with pytest.raises(AssertionError):
        TaxBrain("2018", "2020", use_cps=True)
    with pytest.raises(AssertionError):
        TaxBrain(TaxBrain.LAST_BUDGET_YEAR,
                 TaxBrain.FIRST_BUDGET_YEAR,
                 use_cps=True)
    with pytest.raises(AssertionError):
        TaxBrain(TaxBrain.FIRST_BUDGET_YEAR - 1, 2018, use_cps=True)
    with pytest.raises(AssertionError):
        TaxBrain(2018, TaxBrain.LAST_BUDGET_YEAR + 1, use_cps=True)
Пример #2
0
def cli_core(startyear, endyear, data, usecps, reform, behavior, assump,
             baseline, outdir, name, make_report, author):
    """
    Core logic for the CLI
    """
    tb = TaxBrain(start_year=startyear,
                  end_year=endyear,
                  microdata=data,
                  use_cps=usecps,
                  reform=reform,
                  behavior=behavior,
                  assump=assump,
                  base_policy=baseline,
                  verbose=True)
    tb.run()

    # create outputs
    dirname = name
    if not dirname:
        dirname = f"TaxBrain Analysis {datetime.today().date()}"
    outputpath = Path(outdir, dirname)
    outputpath.mkdir()
    # create output tables
    aggregate = tb.weighted_totals("combined")
    aggregate.to_csv(Path(outputpath, "aggregate_tax_liability.csv"))
    for year in range(startyear, endyear + 1):
        yeardir = Path(outputpath, str(year))
        yeardir.mkdir()
        make_tables(tb, year, yeardir)

    if make_report:
        report(tb, name=name, outdir=outputpath, author=author)
Пример #3
0
def cli_core(startyear, endyear, data, usecps, reform, behavior, assump,
             baseline, outdir, name, make_report, author):
    """
    Core logic for the CLI

    Parameters
    ----------
    startyear: int
        year to start analysis
    endyear: int
        last year for analysis
    data: str or Pandas DataFrame
        path to or DataFrame with data for Tax-Calculator
    usecps: bool
        whether to use the CPS or (if False) the PUF-based file
    reform: dict
        parameter changes for reform run in Tax-Calculator
    behavior: dict
        behavioral assumptions for Behavioral-Responses
    assump: dict
        consumption assumptions
    base_policy: dict
        parameter changes (relative to current law baseline) for baseline
        policy
    verbose: bool
        indicator for printing of output

    Returns
    -------
    None
        reports saved to disk at path specified by outdir
    """
    tb = TaxBrain(start_year=startyear,
                  end_year=endyear,
                  microdata=data,
                  use_cps=usecps,
                  reform=reform,
                  behavior=behavior,
                  assump=assump,
                  base_policy=baseline,
                  verbose=True)
    tb.run()

    # create outputs
    dirname = name
    if not dirname:
        dirname = f"TaxBrain Analysis {datetime.today().date()}"
    outputpath = Path(outdir, dirname)
    outputpath.mkdir(exist_ok=True)
    # create output tables
    aggregate = tb.weighted_totals("combined")
    aggregate.to_csv(Path(outputpath, "aggregate_tax_liability.csv"))
    for year in range(startyear, endyear + 1):
        yeardir = Path(outputpath, str(year))
        yeardir.mkdir(exist_ok=True)
        make_tables(tb, year, yeardir)

    if make_report:
        report(tb, name=name, outdir=outputpath, author=author)
Пример #4
0
def test_user_input(reform_json_str, assump_json_str):
    valid_reform = {"II_rt7": {2019: 0.40}}
    # Test valid reform dictionary with No assumption
    TaxBrain(2018, 2020, use_cps=True, reform=valid_reform)
    TaxBrain(2018, 2020, use_cps=True, reform=reform_json_str)
    invalid_assump = {"consumption": {}}
    # Test valid reform and assumptions dictionary
    valid_assump = {
        "consumption": {},
        "growdiff_baseline": {},
        "growdiff_response": {}
    }
    TaxBrain(2018, 2019, use_cps=True, assump=valid_assump)
    TaxBrain(2018,
             2019,
             use_cps=True,
             reform=reform_json_str,
             assump=assump_json_str)
    tb = TaxBrain(2018,
                  2019,
                  use_cps=True,
                  reform=valid_reform,
                  assump=valid_assump)
    required_param_keys = {
        "policy", "consumption", "growdiff_baseline", "growdiff_response",
        "behavior", "base_policy"
    }
    assert set(tb.params.keys()) == required_param_keys
    with pytest.raises(ValueError):
        TaxBrain(2018, 2020, use_cps=True, assump=invalid_assump)
    invalid_assump = {
        "consumption": {},
        "growdiff_baseline": {},
        "growdiff_response": {},
        "invalid": {}
    }
    with pytest.raises(ValueError):
        TaxBrain(2018, 2020, use_cps=True, assump=invalid_assump)
    with pytest.raises(TypeError):
        TaxBrain(2018, 2020, use_cps=True, reform=True)
    with pytest.raises(TypeError):
        TaxBrain(2018, 2020, use_cps=True, assump=True)
Пример #5
0
def test_stacked_run():
    # reforms to use
    payroll_json = """{"SS_Earnings_thd": {"2021": 400000}}"""
    CG_rate_json = """{
        "CG_brk3": {"2021": [1000000, 1000000, 1000000, 1000000, 1000000]},
        "CG_rt4": {"2021": 0.396}
    }"""
    reform_dict = {
        "Payroll Threshold Increase": payroll_json,
        "Capital Gains Tax Changes": CG_rate_json
    }
    tb = TaxBrain(2021, 2022, reform=reform_dict, stacked=True, use_cps=True)
    tb.run()
    # check that there is a stacked table now
    assert isinstance(tb.stacked_table, pd.DataFrame)
Пример #6
0
def tb_dynamic(reform_json_str):
    return TaxBrain(2018, 2019, use_cps=True, reform=reform_json_str,
                    behavior={"sub": 0.25})
Пример #7
0
def tb_static(reform_json_str):
    return TaxBrain(2018, 2019, use_cps=True, reform=reform_json_str)
Пример #8
0
def test_baseline_policy():
    base = {"II_em": {2019: 0}}
    reform = {"II_em": {2025: 2000}}

    tb = TaxBrain(2018, 2019, use_cps=True, reform=reform, base_policy=base)
    tb.run()
Пример #9
0
def run_model(meta_params_dict, adjustment):
    """
    Runs TaxBrain
    """
    # update meta parameters
    meta_params = MetaParameters()
    meta_params.adjust(meta_params_dict)
    # convert COMP user inputs to format accepted by tax-calculator
    policy_mods = convert_adj(adjustment["policy"], meta_params.year.tolist())
    behavior_mods = convert_behavior_adj(adjustment["behavior"])
    user_mods = {"policy": policy_mods, "behavior": behavior_mods}
    start_year = int(meta_params.year)
    use_cps = meta_params.data_source == "CPS"
    if meta_params.data_source == "PUF":
        puf_df = retrieve_puf(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
        if puf_df is not None:
            if not isinstance(puf_df, pd.DataFrame):
                raise TypeError("'puf_df' must be a Pandas DataFrame.")
            fuzz = True
            use_cps = False
            sampling_frac = 0.05
            sampling_seed = 2222
            full_sample = puf_df
        else:
            # Access keys are not available. Default to the CPS.
            print("Defaulting to the CPS")
            meta_params.adjust({"data_source": "CPS"})
    if meta_params.data_source == "CPS":
        fuzz = False
        use_cps = True
        input_path = os.path.join(TCDIR, "cps.csv.gz")
        # full_sample = read_egg_csv(cpspath)  # pragma: no cover
        sampling_frac = 0.03
        sampling_seed = 180
        full_sample = pd.read_csv(input_path)

    if meta_params.use_full_sample:
        sample = full_sample
        end_year = min(start_year + 10, TaxBrain.LAST_BUDGET_YEAR)
    else:
        sample = full_sample.sample(frac=sampling_frac,
                                    random_state=sampling_seed)
        end_year = start_year

    tb = TaxBrain(start_year,
                  end_year,
                  microdata=sample,
                  use_cps=use_cps,
                  reform=policy_mods,
                  behavior=behavior_mods)
    tb.run()

    # Collect results for each year
    delayed_list = []
    for year in range(start_year, end_year + 1):
        print('delaying for', year)
        delay = delayed(nth_year_results)(tb, year, user_mods, fuzz)
        delayed_list.append(delay)
    results = compute(*delayed_list)

    # process results to get them ready for display
    # create aggregate plot
    agg_plot = aggregate_plot(tb)
    all_to_process = defaultdict(list)
    for result in results:
        for key, value in result.items():
            all_to_process[key] += value
    results, downloadable = postprocess(all_to_process)
    agg_output, table_output = create_layout(results, start_year, end_year)
    model_versions_str = ""
    for model, version in TaxBrain.VERSIONS.items():
        model_versions_str += f"{model}: {version}\n"
    comp_outputs = {
        "renderable": [agg_plot, agg_output, table_output],
        "model_version": model_versions_str,
        "downloadable": downloadable
    }
    return comp_outputs
Пример #10
0
from taxbrain import TaxBrain

reform_url = "https://raw.githubusercontent.com/PSLmodels/Tax-Calculator/master/taxcalc/reforms/Larson2019.json"

# run static analysis

tb_static = TaxBrain(2019, 2028, use_cps=True, reform=reform_url)
tb_static.run()
static_table = tb_static.weighted_totals("c00100")
print("Tax Liability by Year\n")
print("Static Results")
print(static_table)

# run dynamic analysis

tb_dynamic = TaxBrain(2019,
                      2028,
                      use_cps=True,
                      reform=reform_url,
                      behavior={"sub": 0.25})
tb_dynamic.run()
dynamic_table = tb_dynamic.weighted_totals("c00100")
print("Dynamic Results")
print(dynamic_table)

# produce a differences table

diff = tb_static.differences_table(2019, "weighted_deciles", "combined")
print("\nDifferences Table for 2019")
print(diff)
Пример #11
0
def run_tbi_model(start_year,
                  data_source,
                  use_full_sample,
                  user_mods,
                  puf_df=None):
    """
    Run TBI using the taxbrain API
    """
    tbi_path = os.path.abspath(os.path.dirname(__file__))
    tcpath = inspect.getfile(Records)
    tcdir = os.path.dirname(tcpath)
    # use taxbrain
    if data_source == "PUF":
        if not isinstance(puf_df, pd.DataFrame):
            raise TypeError("'puf_df' must be a Pandas DataFrame.")
        fuzz = True
        use_cps = False
        sampling_frac = 0.05
        sampling_seed = 2222
        full_sample = puf_df
    else:
        fuzz = False
        use_cps = True
        input_path = os.path.join(tbi_path, '..', 'cps.csv.gz')
        if not os.path.isfile(input_path):
            # otherwise read from taxcalc package "egg"
            input_path = os.path.join(tcdir, "cps.csv.gz")
            # full_sample = read_egg_csv(cpspath)  # pragma: no cover
        sampling_frac = 0.03
        sampling_seed = 180
        full_sample = pd.read_csv(input_path)

    if use_full_sample:
        sample = full_sample
        end_year = min(start_year + 10, TaxBrain.LAST_BUDGET_YEAR)
    else:
        sample = full_sample.sample(frac=sampling_frac,
                                    random_state=sampling_seed)
        end_year = start_year

    tb = TaxBrain(start_year,
                  end_year,
                  microdata=sample,
                  use_cps=use_cps,
                  reform=user_mods["policy"],
                  behavior=user_mods["behavior"])
    tb.run()

    # Collect results for each year
    delayed_list = []
    for year in range(start_year, end_year + 1):
        print('delaying for', year)
        delay = delayed(nth_year_results)(tb, year, user_mods, fuzz)
        delayed_list.append(delay)
    results = compute(*delayed_list)

    all_to_process = defaultdict(list)
    for result in results:
        for key, value in result.items():
            all_to_process[key] += value
    results = postprocess(all_to_process)
    return results