Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New package version requirements #1351

Merged
merged 11 commits into from
May 9, 2017
Merged
10 changes: 4 additions & 6 deletions conda.recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,17 @@ requirements:
- pytest
- setuptools
- python
- mock
- numpy ==1.11.2
- pandas <=0.18.0
- numpy >=1.11.2
- pandas >=0.18.0
- numba
- toolz
- six
run:
- pytest
- setuptools
- python
- mock
- numpy ==1.11.2
- pandas <=0.18.0
- numpy >=1.11.2
- pandas >=0.18.0
- numba
- toolz
- six
Expand Down
11 changes: 5 additions & 6 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ name: taxcalc-dev
dependencies:
- pytest
- setuptools
- numpy =1.11.2
- pandas =0.18.0
- numpy >=1.11.2
- pandas >=0.18.0
- numba
- bokeh =0.12.3
- toolz
- six
- ipython
- ipython-notebook
- bokeh >=0.12.3
- mock
- pep8
- pylint
- mock
- coverage
- pip:
- pytest-pep8
32 changes: 15 additions & 17 deletions taxcalc/behavior.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,8 @@ def response(calc_x, calc_y):
new_ltcg = calc_x.records.p23250 * exp_term
ltcg_chg = new_ltcg - calc_x.records.p23250
# calculate charitable giving effect
no_charity_response = \
calc_y.behavior.BE_charity.tolist() == \
[0.0, 0.0, 0.0]
no_charity_response = (calc_y.behavior.BE_charity.tolist() ==
[0.0, 0.0, 0.0])
if no_charity_response:
c_charity_chg = np.zeros(calc_x.records.dim)
nc_charity_chg = np.zeros(calc_x.records.dim)
Expand Down Expand Up @@ -299,23 +298,22 @@ def _update_ordinary_income(taxinc_change, calc):
calc.records.c04470)
agi_m_ided = agi - ided
# assume behv response only for filing units with positive agi_m_ided
delta_income = np.where(agi_m_ided > 0., taxinc_change, 0.)
pos = np.array(agi_m_ided > 0., dtype=bool)
delta_income = np.where(pos, taxinc_change, 0.)
# allocate delta_income into three parts
delta_wage = np.where(agi_m_ided > 0.,
delta_income * calc.records.e00200 / agi_m_ided,
0.)
other_income = agi - calc.records.e00200
delta_oinc = np.where(agi_m_ided > 0.,
delta_income * other_income / agi_m_ided,
0.)
delta_ided = np.where(agi_m_ided > 0.,
delta_income * ided / agi_m_ided,
0.)
winc = calc.records.e00200
delta_winc = np.zeros_like(agi)
delta_winc[pos] = delta_income[pos] * winc[pos] / agi_m_ided[pos]
oinc = agi - winc
delta_oinc = np.zeros_like(agi)
delta_oinc[pos] = delta_income[pos] * oinc[pos] / agi_m_ided[pos]
delta_ided = np.zeros_like(agi)
delta_ided[pos] = delta_income[pos] * ided[pos] / agi_m_ided[pos]
# confirm that the three parts are consistent with delta_income
assert np.allclose(delta_income, delta_wage + delta_oinc - delta_ided)
assert np.allclose(delta_income, delta_winc + delta_oinc - delta_ided)
# add the three parts to different calc.records variables
calc.records.e00200 = calc.records.e00200 + delta_wage
calc.records.e00200p = calc.records.e00200p + delta_wage
calc.records.e00200 = calc.records.e00200 + delta_winc
calc.records.e00200p = calc.records.e00200p + delta_winc
calc.records.e00300 = calc.records.e00300 + delta_oinc
calc.records.e19200 = calc.records.e19200 + delta_ided
return calc
Expand Down
13 changes: 11 additions & 2 deletions taxcalc/cli/install_local_taxcalc_package
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/bin/bash
# USAGE: ./install_local_taxcalc_package
# ACTION: (1) uninstalls any installed taxcalc package (conda uninstall)
# (2) builds local taxcalc=0.0.0 package (conda build)
# (3) installs local taxcalc=0.0.0 package (conda install)
# (2) executes "conda install conda-build" (if necessary)
# (3) builds local taxcalc=0.0.0 package (conda build)
# (4) installs local taxcalc=0.0.0 package (conda install)
# NOTE: for those with experience working with compiled languages,
# building a local conda package is analogous to compiling an executable

Expand All @@ -14,6 +15,14 @@ if [ $? -eq 1 ]; then
./uninstall_taxcalc_package
fi

# install conda-build package if not present
conda list build | awk '$1~/conda-build/{rc=1}END{exit(rc)}'
if [ $? -eq 0 ]; then
echo "==> Installing conda-build package"
conda install conda-build --yes 2>&1 > /dev/null
echo "==> Continue building taxcalc package"
fi

# build taxcalc conda package
cd ../../conda.recipe/
conda build --python 2.7 . 2>&1 | awk '$1~/BUILD/||$1~/TEST/'
Expand Down
7 changes: 5 additions & 2 deletions taxcalc/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import os

import numpy
import pandas
import pytest

from taxcalc import Records


# convert all numpy warnings into errors so they can be detected in tests
numpy.seterr(all='raise')


@pytest.fixture(scope='session')
def tests_path():
return os.path.abspath(os.path.dirname(__file__))
Expand Down
2 changes: 2 additions & 0 deletions taxcalc/tests/test_behavior.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ def test_incorrect_Behavior_instantiation():
behv = Behavior(behavior_dict=bad_behv_dict)
with pytest.raises(ValueError):
behv = Behavior(num_years=0)
with pytest.raises(FloatingPointError):
np.divide(1., 0.)


def test_correct_but_not_recommended_Behavior_instantiation():
Expand Down
21 changes: 11 additions & 10 deletions taxcalc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ def atr_graph_data(calc1, calc2,

min_avginc : float
specifies the minimum average expanded income for a percentile to
be included in the graph data
be included in the graph data; value must be positive

Returns
-------
Expand Down Expand Up @@ -962,6 +962,8 @@ def atr_graph_data(calc1, calc2,
msg = ('atr_measure="{}" is neither '
'"itax" nor "ptax" nor "combined"')
raise ValueError(msg.format(atr_measure))
# . . check min_avginc value
assert min_avginc > 0.
# calculate taxes and expanded income
calc1.calc_all()
calc2.calc_all()
Expand Down Expand Up @@ -994,19 +996,18 @@ def atr_graph_data(calc1, calc2,
avginc_series = gdfx.apply(weighted_mean, 'expanded_income')
avgtax1_series = gdfx.apply(weighted_mean, 'tax1')
avgtax2_series = gdfx.apply(weighted_mean, 'tax2')
# compute average tax rates by income percentile
# pylint: disable=no-member
# (above pylint comment eliminates bogus np.divide warnings)
atr1_series = np.divide(avgtax1_series, avginc_series)
atr2_series = np.divide(avgtax2_series, avginc_series)
# compute average tax rates for each included income percentile
included = np.array(avginc_series >= min_avginc, dtype=bool)
atr1_series = np.zeros_like(avginc_series)
atr1_series[included] = avgtax1_series[included] / avginc_series[included]
atr2_series = np.zeros_like(avginc_series)
atr2_series[included] = avgtax2_series[included] / avginc_series[included]
# construct DataFrame containing the two atr?_series
lines = pd.DataFrame()
lines['avginc'] = avginc_series
lines['base'] = atr1_series
lines['reform'] = atr2_series
# drop percentiles with average income below the specified minimum
lines = lines[lines['avginc'] >= min_avginc]
lines.drop('avginc', axis=1, inplace=True)
# include only percentiles with average income no less than min_avginc
lines = lines[included]
# construct dictionary containing plot lines and auto-generated labels
data = dict()
data['lines'] = lines
Expand Down