Skip to content

Commit

Permalink
Merge pull request #1290 from martinholmer/revise-records-logic
Browse files Browse the repository at this point in the history
Move reading of records_variables.json file into Records class logic
  • Loading branch information
martinholmer authored Apr 14, 2017
2 parents 04010aa + 1bd8a0d commit cdb0fc4
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 39 deletions.
2 changes: 1 addition & 1 deletion taxcalc/behavior.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@
"value": [[0.0, 0.0, 0.0]],
"validations": {"max": 0.0}
}
}
}
80 changes: 45 additions & 35 deletions taxcalc/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,38 +98,8 @@ class instance: Records
WEIGHTS_PATH = os.path.join(CUR_PATH, WEIGHTS_FILENAME)
ADJUST_RATIOS_FILENAME = 'puf_ratios.csv'
ADJUST_RATIOS_PATH = os.path.join(CUR_PATH, ADJUST_RATIOS_FILENAME)
RECORDS_VARIABLES_FILENAME = 'records_variables.json'
RECORDS_VARIABLES_PATH = os.path.join(CUR_PATH, RECORDS_VARIABLES_FILENAME)

# Load metadata about all Records variables
if os.path.exists(RECORDS_VARIABLES_PATH):
with open(RECORDS_VARIABLES_PATH) as vfile:
VAR_INFO = json.load(vfile)
else:
VAR_INFO = read_egg_json(RECORDS_VARIABLES_FILENAME)

# Read variables
INTEGER_READ_VARS = \
set(k for k, v in VAR_INFO['in'].items() if v['format'] == 'int')
FLOAT_READ_VARS = \
set(k for k, v in VAR_INFO['in'].items() if v['format'] == 'float')
MUST_READ_VARS = \
set(k for k, v in VAR_INFO['in'].items() if v.get('required'))
USABLE_READ_VARS = INTEGER_READ_VARS | FLOAT_READ_VARS

# Calculated variables
BINARY_CALCULATED_VARS = \
set(k for k, v in VAR_INFO['out'].items() if v['format'] == 'binary')
INTEGER_CALCULATED_VARS = \
set(k for k, v in VAR_INFO['out'].items() if v['format'] == 'int')
FLOAT_CALCULATED_VARS = \
set(k for k, v in VAR_INFO['out'].items() if v['format'] == 'float')
CALCULATED_VARS = \
BINARY_CALCULATED_VARS | \
INTEGER_CALCULATED_VARS | \
FLOAT_CALCULATED_VARS

CHANGING_CALCULATED_VARS = FLOAT_CALCULATED_VARS
VAR_INFO_FILENAME = 'records_variables.json'
VAR_INFO_PATH = os.path.join(CUR_PATH, VAR_INFO_FILENAME)

def __init__(self,
data='puf.csv',
Expand Down Expand Up @@ -225,6 +195,44 @@ def set_current_year(self, new_current_year):
self._current_year = new_current_year
self.FLPDYR.fill(new_current_year)

@staticmethod
def read_var_info():
"""
Reads Records variables metadata from JSON file;
returns dictionary and specifies the static variable sets listed below.
"""
if os.path.exists(Records.VAR_INFO_PATH):
with open(Records.VAR_INFO_PATH) as vfile:
vardict = json.load(vfile)
else:
vardict = read_egg_json(Records.VAR_INFO_FILENAME)
Records.INTEGER_READ_VARS = set(k for k, v in vardict['read'].items()
if v['format'] == 'int')
FLOAT_READ_VARS = set(k for k, v in vardict['read'].items()
if v['format'] == 'float')
Records.MUST_READ_VARS = set(k for k, v in vardict['read'].items()
if v.get('required'))
Records.USABLE_READ_VARS = Records.INTEGER_READ_VARS | FLOAT_READ_VARS
INT_CALCULATED_VARS = set(k for k, v in vardict['calc'].items()
if v['format'] == 'int')
FLOAT_CALCULATED_VARS = set(k for k, v in vardict['calc'].items()
if v['format'] == 'float')
FIXED_CALCULATED_VARS = set(k for k, v in vardict['calc'].items()
if v['format'] == 'unchanging_float')
Records.CALCULATED_VARS = (INT_CALCULATED_VARS |
FLOAT_CALCULATED_VARS |
FIXED_CALCULATED_VARS)
Records.CHANGING_CALCULATED_VARS = FLOAT_CALCULATED_VARS
Records.INTEGER_VARS = Records.INTEGER_READ_VARS | INT_CALCULATED_VARS
return vardict

INTEGER_READ_VARS = None
MUST_READ_VARS = None
USABLE_READ_VARS = None
CALCULATED_VARS = None
CHANGING_CALCULATED_VARS = None
INTEGER_VARS = None

# --- begin private methods of Records class --- #

def _blowup(self, year):
Expand Down Expand Up @@ -340,6 +348,9 @@ def _read_data(self, data, exact_calcs):
Specifies _exact array depending on boolean value of exact_calcs.
"""
# pylint: disable=too-many-branches
if Records.INTEGER_VARS is None:
Records.read_var_info()
# read specified data
if isinstance(data, pd.DataFrame):
taxdf = data
elif isinstance(data, six.string_types):
Expand Down Expand Up @@ -373,9 +384,8 @@ def _read_data(self, data, exact_calcs):
# create other class variables that are set to all zeros
UNREAD_VARS = Records.USABLE_READ_VARS - READ_VARS
ZEROED_VARS = Records.CALCULATED_VARS | UNREAD_VARS
INT_VARS = Records.INTEGER_READ_VARS | Records.INTEGER_CALCULATED_VARS
for varname in ZEROED_VARS:
if varname in INT_VARS:
if varname in Records.INTEGER_VARS:
setattr(self, varname,
np.zeros(self.dim, dtype=np.int64))
else:
Expand All @@ -398,7 +408,7 @@ def _read_data(self, data, exact_calcs):

def zero_out_changing_calculated_vars(self):
"""
Set all CHANGING_CALCULATED_VARS to zero.
Set all Records.CHANGING_CALCULATED_VARS to zero.
"""
for varname in Records.CHANGING_CALCULATED_VARS:
var = getattr(self, varname)
Expand Down
6 changes: 3 additions & 3 deletions taxcalc/records_variables.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"in": {
"read": {
"DSI": {
"format": "int",
"description": "1 if claimed as dependent on another return; otherwise 0"
Expand Down Expand Up @@ -351,9 +351,9 @@
"description": ""
}
},
"out": {
"calc": {
"ID_Casualty_frt_in_pufcsv_year": {
"format": "binary",
"format": "unchanging_float",
"description": ""
},
"NIIT": {
Expand Down
1 change: 1 addition & 0 deletions taxcalc/validation/taxsim/simpletaxio.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ def _calc_object(self, exact_calcs,
calc: Calculator
"""
# create all-zeros dictionary and then list of all-zero dictionaries
Records.read_var_info()
zero_dict = {}
for varname in Records.USABLE_READ_VARS:
zero_dict[varname] = 0
Expand Down

0 comments on commit cdb0fc4

Please sign in to comment.