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

Gray out fields based on data-source selection #842

Merged
merged 18 commits into from
Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ Go
[here](https://github.com/OpenSourcePolicyCenter/PolicyBrain/pulls?q=is%3Apr+is%3Aclosed)
for a complete commit history.

Release 1.5.0 on 2018-03-13
----------------------------
**Major Changes**
- None

**Minor Changes**
- [#842](https://github.com/OpenSourcePolicyCenter/PolicyBrain/pull/842/)[Gray out fields based on data-source selection] - Hank Doupe and Sean Wang

**Bug Fixes**
- None

Release 1.4.4 on 2018-03-08
----------------------------
**Major Changes**
Expand Down
11 changes: 6 additions & 5 deletions deploy/taxbrain_server/celery_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,17 @@ def dropq_task(year_n, user_mods, first_budget_year, use_puf_not_cps=True, use_f


@celery_app.task
def dropq_task_async(year, user_mods, first_budget_year):
print('dropq_task_async', year, user_mods, first_budget_year)
def dropq_task_async(year, user_mods, first_budget_year, use_puf_not_cps=True):
print('dropq_task_async', year, user_mods, first_budget_year, use_puf_not_cps)
return dropq_task(year, user_mods, first_budget_year,
use_puf_not_cps=True, use_full_sample=True)
use_puf_not_cps=use_puf_not_cps, use_full_sample=True)


@celery_app.task
def dropq_task_small_async(year, user_mods, first_budget_year):
def dropq_task_small_async(year, user_mods, first_budget_year, use_puf_not_cps=True):
print('dropq_task_small_async', year, user_mods, first_budget_year, use_puf_not_cps)
return dropq_task(year, user_mods, first_budget_year,
use_puf_not_cps=True, use_full_sample=False)
use_puf_not_cps=use_puf_not_cps, use_full_sample=False)


@celery_app.task
Expand Down
25 changes: 23 additions & 2 deletions deploy/taxbrain_server/flask_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,23 @@ def dropq_endpoint(dropq_task):
year_n = request.form['year']
user_mods = json.loads(request.form['user_mods'])
first_budget_year = None if 'first_budget_year' not in request.form else request.form['first_budget_year']
use_puf_not_cps = None if 'use_puf_not_cps' not in request.form else request.form['use_puf_not_cps']
else:
year_n = request.args.get('year', '')
first_budget_year = None

year_n = int(year_n)
# use_puf_not_cps passed as string. If for some reason it is not supplied
# we default to True i.e. using the PUF file
if use_puf_not_cps in ('True', 'true') or use_puf_not_cps is None:
use_puf_not_cps = True
else:
use_puf_not_cps = False
print("year_n", year_n)
print("user_mods", user_mods)
print("first_budget_year", first_budget_year)
raw_results = dropq_task.delay(year_n, user_mods, first_budget_year)
print("use_puf_not_cps", use_puf_not_cps)
raw_results = dropq_task.delay(year_n, user_mods, first_budget_year, use_puf_not_cps)
RUNNING_JOBS[raw_results.id] = raw_results
length = client.llen(queue_name) + 1
results = {'job_id':str(raw_results), 'qlength':length}
Expand Down Expand Up @@ -115,7 +123,20 @@ def elastic_endpoint():
elast_params = json.loads(request.form['gdp_elasticity'])
first_budget_year = request.form['first_budget_year']
print("elast params", elast_params, " user_mods: ", user_mods)
raw_results = elasticity_gdp_task_async.delay(year_n, user_mods, first_budget_year, elast_params)
use_puf_not_cps = request.form['use_puf_not_cps']
# use_puf_not_cps passed as string. If for some reason it is not supplied
# we default to True i.e. using the PUF file
if use_puf_not_cps in ('True', 'true') or use_puf_not_cps is None:
use_puf_not_cps = True
else:
use_puf_not_cps = False
raw_results = elasticity_gdp_task_async.delay(
year_n,
user_mods,
first_budget_year,
elast_params,
use_puf_not_cps=use_puf_not_cps
)
RUNNING_JOBS[raw_results.id] = raw_results
length = client.llen(queue_name) + 1
results = {'job_id': str(raw_results), 'qlength': length}
Expand Down
6 changes: 3 additions & 3 deletions webapp/apps/dynamic/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def bool_like(x):

class DynamicElasticityInputsModelForm(ModelForm):

def __init__(self, first_year, *args, **kwargs):
def __init__(self, first_year, use_puf_not_cps, *args, **kwargs):
self._first_year = int(first_year)
self._default_params = default_elasticity_parameters(self._first_year)
# Defaults are set in the Meta, but we need to swap
Expand Down Expand Up @@ -217,7 +217,7 @@ class Meta:

class DynamicBehavioralInputsModelForm(PolicyBrainForm, ModelForm):

def __init__(self, first_year, *args, **kwargs):
def __init__(self, first_year, use_puf_not_cps, *args, **kwargs):
if first_year is None:
first_year = START_YEAR
self._first_year = int(first_year)
Expand Down Expand Up @@ -275,7 +275,7 @@ class Meta:

class DynamicInputsModelForm(ModelForm):

def __init__(self, first_year, *args, **kwargs):
def __init__(self, first_year, use_puf_not_cps, *args, **kwargs):
self._first_year = int(first_year)
self._default_params = default_parameters(self._first_year)
# Defaults are set in the Meta, but we need to swap
Expand Down
15 changes: 5 additions & 10 deletions webapp/apps/dynamic/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@

from ..taxbrain.models import (CommaSeparatedField, SeparatedValuesField,
TaxSaveInputs, OutputUrl)
from ..taxbrain.behaviors import Resultable, Fieldable
from ..taxbrain.behaviors import Resultable, Fieldable, DataSourceable
from ..taxbrain import helpers as taxbrain_helpers
from ..taxbrain import param_formatters

import datetime


class DynamicSaveInputs(models.Model):
class DynamicSaveInputs(DataSourceable, models.Model):
"""
This model contains all the parameters for the dynamic tax model and the tax
result.
Expand All @@ -43,8 +43,6 @@ class DynamicSaveInputs(models.Model):

# Starting Year of the reform calculation
first_year = models.IntegerField(default=None, null=True)
# data source for model
data_source = models.CharField(default="PUF", blank=True, null=True, max_length=20)
# Result
tax_result = JSONField(default=None, blank=True, null=True)
# Creation DateTime
Expand All @@ -62,7 +60,8 @@ class Meta:
)


class DynamicBehaviorSaveInputs(Fieldable, Resultable, models.Model):
class DynamicBehaviorSaveInputs(DataSourceable, Fieldable, Resultable,
models.Model):
"""
This model contains all the parameters for the dynamic behavioral tax
model and the tax result.
Expand All @@ -87,8 +86,6 @@ class DynamicBehaviorSaveInputs(Fieldable, Resultable, models.Model):

# Starting Year of the reform calculation
first_year = models.IntegerField(default=None, null=True)
# data source for model
data_source = models.CharField(default="PUF", blank=True, null=True, max_length=20)

# Result
tax_result = JSONField(default=None, blank=True, null=True)
Expand Down Expand Up @@ -151,7 +148,7 @@ class Meta:
)


class DynamicElasticitySaveInputs(models.Model):
class DynamicElasticitySaveInputs(DataSourceable, models.Model):
"""
This model contains all the parameters for the dynamic elasticity
wrt GDP dynamic macro model and tax result
Expand All @@ -166,8 +163,6 @@ class DynamicElasticitySaveInputs(models.Model):

# Starting Year of the reform calculation
first_year = models.IntegerField(default=None, null=True)
# data source for model
data_source = models.CharField(default="PUF", blank=True, null=True, max_length=20)
# Result
tax_result = JSONField(default=None, blank=True, null=True)
# Creation DateTime
Expand Down
42 changes: 31 additions & 11 deletions webapp/apps/dynamic/tests/test_behavioral.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import taxcalc
from taxcalc import Policy

from .utils import do_behavioral_sim, START_YEAR
from .utils import do_dynamic_sim, START_YEAR
from ...test_assets.utils import (check_posted_params, do_micro_sim,
get_post_data, get_file_post_data)

Expand Down Expand Up @@ -44,26 +44,25 @@ def test_behavioral_edit(self):

# Do the partial equilibrium simulation based on the third microsim
pe_reform = {u'BE_inc': [u'-0.4']}
pe_response = do_behavioral_sim(self.client, micro3, pe_reform)
pe_response = do_dynamic_sim(self.client, 'behavioral', micro3, pe_reform)
orig_micro_model_num = micro3.url[-2:-1]

# Now edit this partial equilibrium sim
# Go to behavioral input page
behavior_num = pe_response.url[pe_response.url[:-1].rfind('/')+1:-1]
dynamic_behavior_edit = '/dynamic/behavioral/edit/{0}?start_year={1}'.format(behavior_num, START_YEAR)
#Redirect first
dynamic_behavior_edit = '/dynamic/behavioral/edit/{0}/?start_year={1}'.format(behavior_num, START_YEAR)
# load page
response = self.client.get(dynamic_behavior_edit)
self.assertEqual(response.status_code, 301)
#Now load the page
rep2 = self.client.get(response.url)
page = rep2.content
self.assertEqual(response.status_code, 200)
page = response.content
# Read the page to find the linked microsim. It should be the third
# microsim above
idx = page.find('dynamic/behavioral')
idx_ms_num_start = idx + 19
idx_ms_num_end = idx_ms_num_start + page[idx_ms_num_start:].find('/')
microsim_model_num = page[idx_ms_num_start:idx_ms_num_end]
assert microsim_model_num == orig_micro_model_num
microsim_url = page[idx:idx_ms_num_end]
assert 'dynamic/behavioral/{0}'.format(microsim_model_num) == microsim_url

def test_behavioral_reform_with_wildcard(self):
# Do the microsim
Expand All @@ -75,7 +74,7 @@ def test_behavioral_reform_with_wildcard(self):

# Do the partial equilibrium simulation based on the microsim
pe_reform = {u'BE_sub': [u'0.25']}
pe_response = do_behavioral_sim(self.client, micro1, pe_reform)
pe_response = do_dynamic_sim(self.client, 'behavioral', micro1, pe_reform)
orig_micro_model_num = micro1.url[-2:-1]
from webapp.apps.dynamic import views
post = views.dropq_compute.last_posted
Expand All @@ -85,6 +84,27 @@ def test_behavioral_reform_with_wildcard(self):
assert user_mods["policy"]["2020"][u'_SS_Earnings_c'][0] == 15000.0
assert user_mods["behavior"]["2016"]["_BE_sub"][0] == 0.25

def test_behavioral_reform_cps(self):
# Do the microsim
start_year = u'2016'
data = get_post_data(start_year)
data[u'SS_Earnings_c'] = [u'*,*,*,*,15000']
data['data_source'] = 'CPS'

micro1 = do_micro_sim(self.client, data)["response"]

# Do the partial equilibrium simulation based on the microsim
pe_reform = {u'BE_sub': [u'0.25']}
pe_response = do_dynamic_sim(self.client, 'behavioral', micro1, pe_reform)
orig_micro_model_num = micro1.url[-2:-1]
from webapp.apps.dynamic import views
post = views.dropq_compute.last_posted
# Verify that partial equilibrium job submitted with proper
# SS_Earnings_c with wildcards filled in properly
user_mods = json.loads(post['user_mods'])
assert user_mods["policy"]["2020"][u'_SS_Earnings_c'][0] == 15000.0
assert user_mods["behavior"]["2016"]["_BE_sub"][0] == 0.25
assert post['use_puf_not_cps'] == False

def test_behavioral_reform_from_file(self):
# Do the microsim from file
Expand All @@ -94,7 +114,7 @@ def test_behavioral_reform_from_file(self):

# Do the partial equilibrium simulation based on the microsim
be_reform = {u'BE_sub': [u'0.25']}
be_response = do_behavioral_sim(self.client, micro1, be_reform)
be_response = do_dynamic_sim(self.client, 'behavioral', micro1, be_reform)
orig_micro_model_num = micro1.url[-2:-1]
from webapp.apps.dynamic import views
post = views.dropq_compute.last_posted
Expand Down
43 changes: 32 additions & 11 deletions webapp/apps/dynamic/tests/test_elasticity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import mock
import os
import json
import sys
# os.environ["NUM_BUDGET_YEARS"] = '2'

from ...taxbrain.models import TaxSaveInputs
Expand All @@ -13,7 +14,7 @@
import taxcalc
from taxcalc import Policy

from .utils import do_elasticity_sim, START_YEAR
from .utils import do_dynamic_sim, START_YEAR
from ...test_assets.utils import (check_posted_params, do_micro_sim,
get_post_data, get_file_post_data)

Expand All @@ -29,7 +30,6 @@ def setUp(self):
self.client = Client()

def test_elasticity_edit(self):
import sys
from webapp.apps.taxbrain import views
webapp_views = sys.modules['webapp.apps.taxbrain.views']
webapp_views.dropq_compute = MockCompute()
Expand All @@ -55,26 +55,47 @@ def test_elasticity_edit(self):

# Do the elasticity of GDP simulation based on the third microsim
egdp_reform = {u'elastic_gdp': [u'0.4']}
egdp_response = do_elasticity_sim(self.client, micro3, egdp_reform)
egdp_response = do_dynamic_sim(self.client, 'macro', micro3, egdp_reform)
orig_micro_model_num = micro3.url[-2:-1]

# Now edit this elasticity of gdp sim
# Go to macro input page
egdp_num = egdp_response.url[egdp_response.url[:-1].rfind('/')+1:-1]
dynamic_macro_edit = '/dynamic/macro/edit/{0}?start_year={1}'.format(egdp_num, START_YEAR)
#Redirect first
dynamic_macro_edit = '/dynamic/macro/edit/{0}/?start_year={1}'.format(egdp_num, START_YEAR)
# get edit page.
response = self.client.get(dynamic_macro_edit)
self.assertEqual(response.status_code, 301)
#Now load the page
rep2 = self.client.get(response.url)
page = rep2.content
self.assertEqual(response.status_code, 200)
page = response.content
# Read the page to find the linked microsim. It should be the third
# microsim above
idx = page.find('dynamic/macro')
idx_ms_num_start = idx + 14
idx_ms_num_end = idx_ms_num_start + page[idx_ms_num_start:].find('/')
microsim_model_num = page[idx_ms_num_start:idx_ms_num_end]
assert microsim_model_num == orig_micro_model_num
microsim_url = page[idx:idx_ms_num_end]
assert 'dynamic/macro/{0}'.format(microsim_model_num) == microsim_url

def test_elasticity_cps(self):
# Do the microsim
start_year = u'2016'
data = get_post_data(start_year)
data[u'II_em'] = [u'4333']
data['data_source'] = ['CPS']

micro1 = do_micro_sim(self.client, data)

from webapp.apps.dynamic import views
dynamic_views = sys.modules['webapp.apps.dynamic.views']
dynamic_views.dropq_compute = ElasticMockCompute(num_times_to_wait=1)

# Do the elasticity of GDP simulation based on the third microsim
egdp_reform = {u'elastic_gdp': [u'0.4']}
egdp_response = do_dynamic_sim(self.client,'macro', micro1['response'],
egdp_reform)
from webapp.apps.dynamic import views
post = views.dropq_compute.last_posted

assert post['use_puf_not_cps'] == False

@pytest.mark.xfail
def test_elasticity_reform_from_file(self):
Expand All @@ -97,7 +118,7 @@ def test_elasticity_reform_from_file(self):

# Do the partial equilibrium simulation based on the microsim
el_reform = {u'elastic_gdp': [u'0.4']}
el_response = do_elasticity_sim(self.client, micro1, el_reform)
el_response = do_dynamic_sim(self.client, 'macro', micro1, el_reform)
orig_micro_model_num = micro1.url[-2:-1]
from webapp.apps.dynamic import views
post = views.dropq_compute.last_posted
Expand Down
13 changes: 12 additions & 1 deletion webapp/apps/dynamic/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ class TaxBrainDynamicFieldsTest(TaxBrainFieldsTest, TestCase):
def test_set_fields(self):
start_year = 2017
fields = self.test_coverage_behavioral_gui_fields.copy()
fields["first_year"] = start_year
fields['first_year'] = start_year
self.parse_fields(start_year, fields,
Form=DynamicBehavioralInputsModelForm)

def test_data_source_puf(self):
start_year = 2017
fields = self.test_coverage_behavioral_gui_fields.copy()
fields['first_year'] = start_year
fields['data_source'] = 'PUF'
model = self.parse_fields(start_year, fields,
Form=DynamicBehavioralInputsModelForm,
use_puf_not_cps=True)

assert model.use_puf_not_cps