From 3ba3b6a9afceacb86ce75024c9736a55228c4c3f Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 09:51:14 -0800 Subject: [PATCH 01/43] Modify Travis build to temporarily clone feature branch of parcel model --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e5a904d..cb7bdfc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ install: - pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install urbansim pandana -- git clone git@github.com:urbansim/urbansim_parcels.git +- git clone -b refactor_developer git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: From ff6fc1cd79474a25e8b4db61b854184181cff0a1 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 14:44:13 -0800 Subject: [PATCH 02/43] Annotations --- developer/developer.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/developer/developer.py b/developer/developer.py index d3618b2..2fcd874 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -77,6 +77,9 @@ class Developer(object): """ + # TODO remove agents, buildings, supply_fname, target_vacancy + # TODO remove remove_developed_buildings, unplace_agents + # TODO rename form forms def __init__(self, feasibility, form, agents, buildings, supply_fname, parcel_size, ave_unit_size, current_units, year=None, target_vacancy=0.1, bldg_sqft_per_job=400.0, @@ -107,6 +110,7 @@ def __init__(self, feasibility, form, agents, buildings, self.remove_developed_buildings = remove_developed_buildings self.unplace_agents = unplace_agents + # TODO just take in target units self.target_units = ( self.num_units_to_build or self.compute_units_to_build(len(agents), @@ -131,6 +135,8 @@ def from_yaml(cls, feasibility, form, agents, buildings, """ cfg = utils.yaml_to_dict(yaml_str, str_or_buffer) + # TODO remove agents, buildings, supply_fname, target_vacancy + # TODO remove remove_developed_buildings, unplace_agents model = cls( feasibility, form, agents, buildings, cfg['supply_fname'], @@ -152,6 +158,8 @@ def to_dict(self): """ + # TODO remove supply_fname, target_vacancy + # TODO remove remove_developed_buildings, unplace_agents attributes = ['supply_fname', 'target_vacancy', 'bldg_sqft_per_job', 'min_unit_size', 'max_parcel_size', 'drop_after_build', 'residential', 'num_units_to_build', @@ -240,6 +248,7 @@ def keep_form_with_max_profit(self, forms=None): df = df.reset_index(level=1) return df + # TODO move to urbansim_parcels utils.py @staticmethod def compute_units_to_build(num_agents, num_units, target_vacancy): """ @@ -271,6 +280,7 @@ def compute_units_to_build(num_agents, num_units, target_vacancy): target_units) return target_units + # TODO Add target_units to parameters def pick(self, profit_to_prob_func=None): """ Choose the buildings from the list that are feasible to build in From 4837a518faad623872d108ab471ac319e1d0e399 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 14:46:14 -0800 Subject: [PATCH 03/43] Rename form -> forms in Developer class --- developer/developer.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 2fcd874..228e276 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -79,8 +79,7 @@ class Developer(object): # TODO remove agents, buildings, supply_fname, target_vacancy # TODO remove remove_developed_buildings, unplace_agents - # TODO rename form forms - def __init__(self, feasibility, form, agents, buildings, + def __init__(self, feasibility, forms, agents, buildings, supply_fname, parcel_size, ave_unit_size, current_units, year=None, target_vacancy=0.1, bldg_sqft_per_job=400.0, min_unit_size=400, max_parcel_size=2000000, @@ -92,7 +91,7 @@ def __init__(self, feasibility, form, agents, buildings, feasibility = pd.concat(feasibility.values(), keys=feasibility.keys(), axis=1) self.feasibility = feasibility - self.form = form + self.forms = forms self.agents = agents self.buildings = buildings self.supply_fname = supply_fname @@ -118,7 +117,7 @@ def __init__(self, feasibility, form, agents, buildings, self.target_vacancy)) @classmethod - def from_yaml(cls, feasibility, form, agents, buildings, + def from_yaml(cls, feasibility, forms, agents, buildings, parcel_size, ave_unit_size, current_units, year=None, yaml_str=None, str_or_buffer=None): """ @@ -138,7 +137,7 @@ def from_yaml(cls, feasibility, form, agents, buildings, # TODO remove agents, buildings, supply_fname, target_vacancy # TODO remove remove_developed_buildings, unplace_agents model = cls( - feasibility, form, agents, + feasibility, forms, agents, buildings, cfg['supply_fname'], parcel_size, ave_unit_size, current_units, year, cfg['target_vacancy'], cfg['bldg_sqft_per_job'], @@ -307,12 +306,12 @@ def pick(self, profit_to_prob_func=None): # no feasible buildings, might as well bail return - if self.form is None: + if self.forms is None: df = self.feasibility - elif isinstance(self.form, list): - df = self.keep_form_with_max_profit(self.form) + elif isinstance(self.forms, list): + df = self.keep_form_with_max_profit(self.forms) else: - df = self.feasibility[self.form] + df = self.feasibility[self.forms] # feasible buildings only for this building type df = df[df.max_profit_far > 0] @@ -378,9 +377,9 @@ def pick(self, profit_to_prob_func=None): if self.year is not None: new_df["year_built"] = self.year - if not isinstance(self.form, list): + if not isinstance(self.forms, list): # form gets set only if forms is a list - new_df["form"] = self.form + new_df["form"] = self.forms new_df["stories"] = new_df.stories.apply(np.ceil) From 2bf4227ea587ccf7b23d31a1943fbae025c4fac5 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 14:49:24 -0800 Subject: [PATCH 04/43] Revise unit tests to take forms argument --- developer/tests/test_developer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index 95c8a96..b9771ac 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -42,7 +42,7 @@ def base_args(feasibility): @pytest.fixture def res(base_args): args = base_args.copy() - args.update({'form': 'residential', + args.update({'forms': 'residential', 'supply_fname': 'residential_units'}) return args @@ -50,7 +50,7 @@ def res(base_args): @pytest.fixture def nonres(base_args): args = base_args.copy() - args.update({'form': 'office', + args.update({'forms': 'office', 'supply_fname': 'job_spaces'}) return args From d0c6d5087d0a911b1dda8d8f341157f8506be727 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 16:52:08 -0800 Subject: [PATCH 05/43] Remove parameters related to calculating target_units from Developer object * Add target_units to Developer constructor method * Remove agents, buildings, supply_fname, and target_vacancy * Revise unit tests * Reconcile difference in unit tests from urbansim to this repo --- developer/developer.py | 43 ++++++----------- developer/tests/test_developer.py | 78 ++++++++++--------------------- 2 files changed, 39 insertions(+), 82 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 228e276..a854784 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -77,12 +77,11 @@ class Developer(object): """ - # TODO remove agents, buildings, supply_fname, target_vacancy # TODO remove remove_developed_buildings, unplace_agents - def __init__(self, feasibility, forms, agents, buildings, - supply_fname, parcel_size, ave_unit_size, current_units, - year=None, target_vacancy=0.1, bldg_sqft_per_job=400.0, - min_unit_size=400, max_parcel_size=2000000, + def __init__(self, feasibility, forms, target_units, + parcel_size, ave_unit_size, current_units, + year=None, bldg_sqft_per_job=400.0, + min_unit_size=400, max_parcel_size=200000, drop_after_build=True, residential=True, num_units_to_build=None, remove_developed_buildings=True, unplace_agents=['households', 'jobs']): @@ -92,14 +91,11 @@ def __init__(self, feasibility, forms, agents, buildings, keys=feasibility.keys(), axis=1) self.feasibility = feasibility self.forms = forms - self.agents = agents - self.buildings = buildings - self.supply_fname = supply_fname + self.target_units = target_units self.parcel_size = parcel_size self.ave_unit_size = ave_unit_size self.current_units = current_units self.year = year - self.target_vacancy = target_vacancy self.bldg_sqft_per_job = bldg_sqft_per_job self.min_unit_size = min_unit_size self.max_parcel_size = max_parcel_size @@ -109,15 +105,8 @@ def __init__(self, feasibility, forms, agents, buildings, self.remove_developed_buildings = remove_developed_buildings self.unplace_agents = unplace_agents - # TODO just take in target units - self.target_units = ( - self.num_units_to_build or - self.compute_units_to_build(len(agents), - buildings[supply_fname].sum(), - self.target_vacancy)) - @classmethod - def from_yaml(cls, feasibility, forms, agents, buildings, + def from_yaml(cls, feasibility, forms, target_units, parcel_size, ave_unit_size, current_units, year=None, yaml_str=None, str_or_buffer=None): """ @@ -134,13 +123,11 @@ def from_yaml(cls, feasibility, forms, agents, buildings, """ cfg = utils.yaml_to_dict(yaml_str, str_or_buffer) - # TODO remove agents, buildings, supply_fname, target_vacancy # TODO remove remove_developed_buildings, unplace_agents model = cls( - feasibility, forms, agents, - buildings, cfg['supply_fname'], - parcel_size, ave_unit_size, current_units, year, - cfg['target_vacancy'], cfg['bldg_sqft_per_job'], + feasibility, forms, target_units, + parcel_size, ave_unit_size, current_units, + year, cfg['bldg_sqft_per_job'], cfg['min_unit_size'], cfg['max_parcel_size'], cfg['drop_after_build'], cfg['residential'], cfg['num_units_to_build'], cfg['remove_developed_buildings'], @@ -156,13 +143,12 @@ def to_dict(self): Return a dict representation of a SqftProForma instance. """ - - # TODO remove supply_fname, target_vacancy # TODO remove remove_developed_buildings, unplace_agents - attributes = ['supply_fname', 'target_vacancy', 'bldg_sqft_per_job', - 'min_unit_size', 'max_parcel_size', 'drop_after_build', - 'residential', 'num_units_to_build', - 'remove_developed_buildings', 'unplace_agents'] + attributes = ['bldg_sqft_per_job', + 'min_unit_size', 'max_parcel_size', + 'drop_after_build', 'residential', + 'num_units_to_build', 'remove_developed_buildings', + 'unplace_agents'] results = {} for attribute in attributes: @@ -279,7 +265,6 @@ def compute_units_to_build(num_agents, num_units, target_vacancy): target_units) return target_units - # TODO Add target_units to parameters def pick(self, profit_to_prob_func=None): """ Choose the buildings from the list that are feasible to build in diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index b9771ac..37a5a49 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -42,72 +42,46 @@ def base_args(feasibility): @pytest.fixture def res(base_args): args = base_args.copy() - args.update({'forms': 'residential', - 'supply_fname': 'residential_units'}) + args.update({'forms': 'residential'}) return args @pytest.fixture def nonres(base_args): args = base_args.copy() - args.update({'forms': 'office', - 'supply_fname': 'job_spaces'}) + args.update({'forms': 'office'}) return args -@pytest.fixture -def res_10(res): - households = pd.DataFrame(index=range(90)) - buildings = pd.DataFrame( - {'residential_units': [30, 30, 30]}, - index=range(3) - ) - args = res.copy() - args.update({'agents': households, 'buildings': buildings}) - return args - - -@pytest.fixture -def res_1000(res): - households = pd.DataFrame(index=range(9000)) - buildings = pd.DataFrame( - {'residential_units': [3000, 3000, 3000]}, - index=range(3) - ) - args = res.copy() - args.update({'agents': households, 'buildings': buildings}) - return args - - -def test_res_developer_10(res_10): - dev = developer.Developer(**res_10) +def test_res_developer(res): + dev = developer.Developer(target_units=10, **res) bldgs = dev.pick() - assert dev.target_units == 10 assert len(bldgs) == 1 + assert len(dev.feasibility) == 2 - -def test_res_developer_1000(res_1000): - dev = developer.Developer(**res_1000) - + dev = developer.Developer(target_units=1000, **res) bldgs = dev.pick() - assert dev.target_units == 1000 assert len(bldgs) == 3 - -def test_res_developer_none(res_10): - dev = developer.Developer(residential=False, **res_10) - + dev = developer.Developer(target_units=2, residential=False, **res) bldgs = dev.pick() assert bldgs is None -def test_developer_dict_roundtrip(res_10): - dev1 = developer.Developer(**res_10) +@pytest.fixture +def res10(res): + args = res.copy() + args.update({'target_units': 10}) + return args + + +def test_developer_dict_roundtrip(res10): + dev1 = developer.Developer(**res10) config1 = dev1.to_dict next_args = config1.copy() - next_args.update(res_10) + next_args.update(res10) dev2 = developer.Developer(**next_args) config2 = dev2.to_dict @@ -115,36 +89,34 @@ def test_developer_dict_roundtrip(res_10): assert config1 == config2 -def test_developer_yaml_roundtrip(res_10): +def test_developer_yaml_roundtrip(res10): if os.path.exists('test_dev_config.yaml'): os.remove('test_dev_config.yaml') - dev = developer.Developer(**res_10) + dev = developer.Developer(**res10) with open('test_dev_config.yaml', 'wb') as yaml_file: dev.to_yaml(yaml_file) yaml_string = dev.to_yaml() - res_10.pop('supply_fname', None) - dev_from_yaml_file = developer.Developer.from_yaml( - str_or_buffer='test_dev_config.yaml', **res_10) + str_or_buffer='test_dev_config.yaml', **res10) assert dev.to_dict == dev_from_yaml_file.to_dict dev_from_yaml_string = developer.Developer.from_yaml( - yaml_str=yaml_string, **res_10) + yaml_str=yaml_string, **res10) assert dev.to_dict == dev_from_yaml_string.to_dict os.remove('test_dev_config.yaml') -def test_developer_compute_units_to_build(res_10): - dev = developer.Developer(**res_10) +def test_developer_compute_units_to_build(res10): + dev = developer.Developer(**res10) to_build = dev.compute_units_to_build(30, 30, .1) assert int(to_build) == 3 -def test_developer_compute_forms_max_profit(res_10): - dev = developer.Developer(**res_10) +def test_developer_compute_forms_max_profit(res10): + dev = developer.Developer(**res10) dev.keep_form_with_max_profit() From 483c7495f94ecd5feca73841f728df06abf6dc43 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 17:14:18 -0800 Subject: [PATCH 06/43] Delete compute_units_to_build method (move to parcel model) --- developer/developer.py | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index a854784..7b5d253 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -233,38 +233,6 @@ def keep_form_with_max_profit(self, forms=None): df = df.reset_index(level=1) return df - # TODO move to urbansim_parcels utils.py - @staticmethod - def compute_units_to_build(num_agents, num_units, target_vacancy): - """ - Compute number of units to build to match target vacancy. - - Parameters - ---------- - num_agents : int - number of agents that need units in the region - num_units : int - number of units in buildings - target_vacancy : float (0-1.0) - target vacancy rate - - Returns - ------- - number_of_units : int - the number of units that need to be built - """ - print "Number of agents: {:,}".format(num_agents) - print "Number of agent spaces: {:,}".format(int(num_units)) - assert target_vacancy < 1.0 - target_units = int(max( - (num_agents / (1 - target_vacancy) - num_units), 0)) - print "Current vacancy = {:.2f}".format(1 - num_agents / - float(num_units)) - print "Target vacancy = {:.2f}, target of new units = {:,}".format( - target_vacancy, - target_units) - return target_units - def pick(self, profit_to_prob_func=None): """ Choose the buildings from the list that are feasible to build in From de9430100b01aa5b46533d545108177f0b81a906 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 17:33:28 -0800 Subject: [PATCH 07/43] Remove test for compute_units function moved to parcel model --- developer/tests/test_developer.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index 37a5a49..e0fda60 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -109,12 +109,6 @@ def test_developer_yaml_roundtrip(res10): os.remove('test_dev_config.yaml') -def test_developer_compute_units_to_build(res10): - dev = developer.Developer(**res10) - to_build = dev.compute_units_to_build(30, 30, .1) - assert int(to_build) == 3 - - def test_developer_compute_forms_max_profit(res10): dev = developer.Developer(**res10) dev.keep_form_with_max_profit() From d2d3dca721e0ec32ccad252ddf409cfd2bcb8302 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 17:44:10 -0800 Subject: [PATCH 08/43] Remove Developer.merge() static method (move to parcel model) --- developer/developer.py | 38 ------------------------------- developer/tests/test_developer.py | 8 ------- 2 files changed, 46 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 7b5d253..44aca44 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -338,41 +338,3 @@ def pick(self, profit_to_prob_func=None): return new_df.reset_index() - # TODO Move this into parcel model - @staticmethod - def merge(old_df, new_df, return_index=False): - """ - Merge two dataframes of buildings. The old dataframe is - usually the buildings dataset and the new dataframe is a modified - (by the user) version of what is returned by the pick method. - - Parameters - ---------- - old_df : dataframe - Current set of buildings - new_df : dataframe - New buildings to add, usually comes from this module - return_index : bool - If return_index is true, this method will return the new - index of new_df (which changes in order to create a unique - index after the merge) - - Returns - ------- - df : dataframe - Combined DataFrame of buildings, makes sure indexes don't overlap - index : pd.Index - If and only if return_index is True, return the new index for the - new_df dataframe (which changes in order to create a unique index - after the merge) - """ - maxind = np.max(old_df.index.values) - new_df = new_df.reset_index(drop=True) - new_df.index = new_df.index + maxind + 1 - concat_df = pd.concat([old_df, new_df], verify_integrity=True) - concat_df.index.name = 'building_id' - - if return_index: - return concat_df, new_df.index - - return concat_df diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index e0fda60..8583410 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -112,11 +112,3 @@ def test_developer_yaml_roundtrip(res10): def test_developer_compute_forms_max_profit(res10): dev = developer.Developer(**res10) dev.keep_form_with_max_profit() - - -def test_developer_merge(): - df1 = pd.DataFrame({'test': [1]}, index=[1]) - df2 = pd.DataFrame({'test': [1]}, index=[1]) - dev = developer.Developer.merge(df1, df2) - # make sure index is unique - assert dev.index.values[1] == 2 From f367e3037413ffab53dda296521bd6a190d168ee Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 17:46:17 -0800 Subject: [PATCH 09/43] Fix docstrings for Developer class --- developer/developer.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 44aca44..bbccd9d 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -17,19 +17,12 @@ class Developer(object): ---------- feasibility : DataFrame or dict Results from SqftProForma lookup method - form : string or list + forms : string or list One or more of the building forms from the pro forma specification - e.g. "residential" or "mixedresidential" - these are configuration parameters passed previously to the pro forma. If more than one form is passed the forms compete with each other (based on profitability) for which one gets built in order to meet demand. - agents : DataFrame Wrapper - Used to compute the current demand for units/floorspace in the area - buildings : DataFrame Wrapper - Used to compute the current supply of units/floorspace in the area - supply_fname : string - Identifies the column in buildings which indicates the supply of - units/floorspace parcel_size : series The size of the parcels. This was passed to feasibility as well, but should be passed here as well. Index should be parcel_ids. @@ -45,8 +38,6 @@ class Developer(object): year : int The year of the simulation - will be assigned to 'year_built' on the new buildings - target_vacancy : float - The target vacancy rate - used to determine how much to build bldg_sqft_per_job : float (default 400.0) The average square feet per job for this building form. min_unit_size : float From 0428329db54f4d7a55595b05f5e9e643f6204212 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 17:59:02 -0800 Subject: [PATCH 10/43] Remove final two params from Developer --- developer/developer.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index bbccd9d..dd912f8 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -59,23 +59,15 @@ class Developer(object): computing it internally by using the length of agents adn the sum of the relevant supply columin - this trusts the caller to know how to compute this. - remove_developed_buildings : optional - Remove all buildings on the parcels which are being developed on - unplace_agents : list of strings - For all tables in the list, will look for field building_id and set - it to -1 for buildings which are removed - only executed if - remove_developed_buildings is true """ - # TODO remove remove_developed_buildings, unplace_agents def __init__(self, feasibility, forms, target_units, parcel_size, ave_unit_size, current_units, year=None, bldg_sqft_per_job=400.0, min_unit_size=400, max_parcel_size=200000, drop_after_build=True, residential=True, - num_units_to_build=None, remove_developed_buildings=True, - unplace_agents=['households', 'jobs']): + num_units_to_build=None): if isinstance(feasibility, dict): feasibility = pd.concat(feasibility.values(), @@ -93,8 +85,6 @@ def __init__(self, feasibility, forms, target_units, self.drop_after_build = drop_after_build self.residential = residential self.num_units_to_build = num_units_to_build - self.remove_developed_buildings = remove_developed_buildings - self.unplace_agents = unplace_agents @classmethod def from_yaml(cls, feasibility, forms, target_units, @@ -114,15 +104,13 @@ def from_yaml(cls, feasibility, forms, target_units, """ cfg = utils.yaml_to_dict(yaml_str, str_or_buffer) - # TODO remove remove_developed_buildings, unplace_agents model = cls( feasibility, forms, target_units, parcel_size, ave_unit_size, current_units, year, cfg['bldg_sqft_per_job'], cfg['min_unit_size'], cfg['max_parcel_size'], cfg['drop_after_build'], cfg['residential'], - cfg['num_units_to_build'], cfg['remove_developed_buildings'], - cfg['unplace_agents'] + cfg['num_units_to_build'] ) logger.debug('loaded Developer model from YAML') @@ -134,12 +122,10 @@ def to_dict(self): Return a dict representation of a SqftProForma instance. """ - # TODO remove remove_developed_buildings, unplace_agents attributes = ['bldg_sqft_per_job', 'min_unit_size', 'max_parcel_size', 'drop_after_build', 'residential', - 'num_units_to_build', 'remove_developed_buildings', - 'unplace_agents'] + 'num_units_to_build'] results = {} for attribute in attributes: From ee32e0bd905776d795bc8d129c06d0590040f5f8 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 7 Mar 2017 18:04:26 -0800 Subject: [PATCH 11/43] Remove num_units_to_build from yaml config in Developer class --- developer/developer.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index dd912f8..a2448b2 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -109,8 +109,7 @@ def from_yaml(cls, feasibility, forms, target_units, parcel_size, ave_unit_size, current_units, year, cfg['bldg_sqft_per_job'], cfg['min_unit_size'], cfg['max_parcel_size'], - cfg['drop_after_build'], cfg['residential'], - cfg['num_units_to_build'] + cfg['drop_after_build'], cfg['residential'] ) logger.debug('loaded Developer model from YAML') @@ -124,8 +123,7 @@ def to_dict(self): """ attributes = ['bldg_sqft_per_job', 'min_unit_size', 'max_parcel_size', - 'drop_after_build', 'residential', - 'num_units_to_build'] + 'drop_after_build', 'residential'] results = {} for attribute in attributes: From ad76a6c5cde6896d5dbbffad759af504024af2ef Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Thu, 9 Mar 2017 16:29:12 -0800 Subject: [PATCH 12/43] Point Travis build back to master branch of urbansim_parcels --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cb7bdfc..e5a904d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ install: - pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install urbansim pandana -- git clone -b refactor_developer git@github.com:urbansim/urbansim_parcels.git +- git clone git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: From e51b55b6af40c16a2bbd71e1fe49c87bf3f3a7e8 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Thu, 9 Mar 2017 16:32:55 -0800 Subject: [PATCH 13/43] Add _feasibility_from_from method --- developer/developer.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index a2448b2..44d4f5a 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -208,6 +208,16 @@ def keep_form_with_max_profit(self, forms=None): df = df.reset_index(level=1) return df + def _feasibility_from_form(self): + + if self.forms is None: + df = self.feasibility + elif isinstance(self.forms, list): + df = self.keep_form_with_max_profit(self.forms) + else: + df = self.feasibility[self.forms] + return df + def pick(self, profit_to_prob_func=None): """ Choose the buildings from the list that are feasible to build in @@ -234,12 +244,7 @@ def pick(self, profit_to_prob_func=None): # no feasible buildings, might as well bail return - if self.forms is None: - df = self.feasibility - elif isinstance(self.forms, list): - df = self.keep_form_with_max_profit(self.forms) - else: - df = self.feasibility[self.forms] + df = self._feasibility_from_form() # feasible buildings only for this building type df = df[df.max_profit_far > 0] From 9bdf6f9f0a71588b84e8e8b59531ec546060c15f Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Thu, 9 Mar 2017 16:45:30 -0800 Subject: [PATCH 14/43] Continue to split up pick() into helper methods --- developer/developer.py | 91 +++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 44d4f5a..99df141 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -208,7 +208,7 @@ def keep_form_with_max_profit(self, forms=None): df = df.reset_index(level=1) return df - def _feasibility_from_form(self): + def _get_dataframe_of_buildings(self): if self.forms is None: df = self.feasibility @@ -218,35 +218,8 @@ def _feasibility_from_form(self): df = self.feasibility[self.forms] return df - def pick(self, profit_to_prob_func=None): - """ - Choose the buildings from the list that are feasible to build in - order to match the specified demand. + def _remove_infeasible_buildings(self, df): - Parameters - ---------- - profit_to_prob_func: function - As there are so many ways to turn the development feasibility - into a probability to select it for building, the user may pass - a function which takes the feasibility dataframe and returns - a series of probabilities. If no function is passed, the behavior - of this method will not change - - Returns - ------- - None if there are no feasible buildings - new_buildings : dataframe - DataFrame of buildings to add. These buildings are rows from the - DataFrame that is returned from feasibility. - """ - - if len(self.feasibility) == 0: - # no feasible buildings, might as well bail - return - - df = self._feasibility_from_form() - - # feasible buildings only for this building type df = df[df.max_profit_far > 0] self.ave_unit_size[ self.ave_unit_size < self.min_unit_size @@ -261,25 +234,27 @@ def pick(self, profit_to_prob_func=None): df['job_spaces'] = (df.non_residential_sqft / self.bldg_sqft_per_job).round() + return df + + def _calculate_net_units(self, df): + if self.residential: df['net_units'] = df.residential_units - df.current_units else: df['net_units'] = df.job_spaces - df.current_units - df = df[df.net_units > 0] - - if len(df) == 0: - print "WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM" - return + return df[df.net_units > 0] - # print "Describe of net units\n", df.net_units.describe() - print "Sum of net units that are profitable: {:,}".\ - format(int(df.net_units.sum())) + @staticmethod + def _calculate_probabilities(df, profit_to_prob_func): if profit_to_prob_func: p = profit_to_prob_func(df) else: df['max_profit_per_size'] = df.max_profit / df.parcel_size p = df.max_profit_per_size.values / df.max_profit_per_size.sum() + return p, df + + def _buildings_to_build(self, df, p): if df.net_units.sum() < self.target_units: print "WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO " \ @@ -301,6 +276,48 @@ def pick(self, profit_to_prob_func=None): side="left")) + 1 build_idx = choices[:ind] + return build_idx + + def pick(self, profit_to_prob_func=None): + """ + Choose the buildings from the list that are feasible to build in + order to match the specified demand. + + Parameters + ---------- + profit_to_prob_func: function + As there are so many ways to turn the development feasibility + into a probability to select it for building, the user may pass + a function which takes the feasibility dataframe and returns + a series of probabilities. If no function is passed, the behavior + of this method will not change + + Returns + ------- + None if there are no feasible buildings + new_buildings : dataframe + DataFrame of buildings to add. These buildings are rows from the + DataFrame that is returned from feasibility. + """ + + if len(self.feasibility) == 0: + # no feasible buildings, might as well bail + return + + df = self._get_dataframe_of_buildings() + df = self._remove_infeasible_buildings(df) + df = self._calculate_net_units(df) + + if len(df) == 0: + print "WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM" + return + + print "Sum of net units that are profitable: {:,}".\ + format(int(df.net_units.sum())) + + p, df = self._calculate_probabilities(df, profit_to_prob_func) + build_idx = self._buildings_to_build(df, p) + if self.drop_after_build: self.feasibility = self.feasibility.drop(build_idx) From 2e1bf497ea47e58cc2e609a8b8e7cf54198671e7 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Thu, 9 Mar 2017 16:51:59 -0800 Subject: [PATCH 15/43] Finish refactoring of pick() method --- developer/developer.py | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 99df141..1b44a26 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -278,6 +278,27 @@ def _buildings_to_build(self, df, p): return build_idx + def _drop_built_buildings(self, build_idx): + + if self.drop_after_build: + self.feasibility = self.feasibility.drop(build_idx) + + def _prepare_new_buildings(self, df, build_idx): + + new_df = df.loc[build_idx] + new_df.index.name = "parcel_id" + + if self.year is not None: + new_df["year_built"] = self.year + + if not isinstance(self.forms, list): + # form gets set only if forms is a list + new_df["form"] = self.forms + + new_df["stories"] = new_df.stories.apply(np.ceil) + + return new_df.reset_index() + def pick(self, profit_to_prob_func=None): """ Choose the buildings from the list that are feasible to build in @@ -304,6 +325,7 @@ def pick(self, profit_to_prob_func=None): # no feasible buildings, might as well bail return + # Get DataFrame of potential buildings from SqFtProForma steps df = self._get_dataframe_of_buildings() df = self._remove_infeasible_buildings(df) df = self._calculate_net_units(df) @@ -315,23 +337,16 @@ def pick(self, profit_to_prob_func=None): print "Sum of net units that are profitable: {:,}".\ format(int(df.net_units.sum())) + # Generate development probabilities and pick buildings to build p, df = self._calculate_probabilities(df, profit_to_prob_func) build_idx = self._buildings_to_build(df, p) - if self.drop_after_build: - self.feasibility = self.feasibility.drop(build_idx) - - new_df = df.loc[build_idx] - new_df.index.name = "parcel_id" - - if self.year is not None: - new_df["year_built"] = self.year + # Drop built buildings from self.feasibility attribute if desired + self._drop_built_buildings(build_idx) - if not isinstance(self.forms, list): - # form gets set only if forms is a list - new_df["form"] = self.forms + # Prep DataFrame of new buildings + new_df = self._prepare_new_buildings(df, build_idx) - new_df["stories"] = new_df.stories.apply(np.ceil) + return new_df - return new_df.reset_index() From e9cb1b3ba4bfb9c39d8f996bebba3d72550103dc Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Thu, 9 Mar 2017 16:57:05 -0800 Subject: [PATCH 16/43] Order Developer methods in a more readable way --- developer/developer.py | 122 ++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/developer/developer.py b/developer/developer.py index 1b44a26..93d936f 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -152,6 +152,66 @@ def to_yaml(self, str_or_buffer=None): logger.debug('serializing Developer model to YAML') return utils.convert_to_yaml(self.to_dict, str_or_buffer) + def pick(self, profit_to_prob_func=None): + """ + Choose the buildings from the list that are feasible to build in + order to match the specified demand. + + Parameters + ---------- + profit_to_prob_func: function + As there are so many ways to turn the development feasibility + into a probability to select it for building, the user may pass + a function which takes the feasibility dataframe and returns + a series of probabilities. If no function is passed, the behavior + of this method will not change + + Returns + ------- + None if there are no feasible buildings + new_buildings : dataframe + DataFrame of buildings to add. These buildings are rows from the + DataFrame that is returned from feasibility. + """ + + if len(self.feasibility) == 0: + # no feasible buildings, might as well bail + return + + # Get DataFrame of potential buildings from SqFtProForma steps + df = self._get_dataframe_of_buildings() + df = self._remove_infeasible_buildings(df) + df = self._calculate_net_units(df) + + if len(df) == 0: + print "WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM" + return + + print "Sum of net units that are profitable: {:,}".\ + format(int(df.net_units.sum())) + + # Generate development probabilities and pick buildings to build + p, df = self._calculate_probabilities(df, profit_to_prob_func) + build_idx = self._buildings_to_build(df, p) + + # Drop built buildings from self.feasibility attribute if desired + self._drop_built_buildings(build_idx) + + # Prep DataFrame of new buildings + new_df = self._prepare_new_buildings(df, build_idx) + + return new_df + + def _get_dataframe_of_buildings(self): + + if self.forms is None: + df = self.feasibility + elif isinstance(self.forms, list): + df = self.keep_form_with_max_profit(self.forms) + else: + df = self.feasibility[self.forms] + return df + @staticmethod def _max_form(f, colname): """ @@ -208,16 +268,6 @@ def keep_form_with_max_profit(self, forms=None): df = df.reset_index(level=1) return df - def _get_dataframe_of_buildings(self): - - if self.forms is None: - df = self.feasibility - elif isinstance(self.forms, list): - df = self.keep_form_with_max_profit(self.forms) - else: - df = self.feasibility[self.forms] - return df - def _remove_infeasible_buildings(self, df): df = df[df.max_profit_far > 0] @@ -298,55 +348,3 @@ def _prepare_new_buildings(self, df, build_idx): new_df["stories"] = new_df.stories.apply(np.ceil) return new_df.reset_index() - - def pick(self, profit_to_prob_func=None): - """ - Choose the buildings from the list that are feasible to build in - order to match the specified demand. - - Parameters - ---------- - profit_to_prob_func: function - As there are so many ways to turn the development feasibility - into a probability to select it for building, the user may pass - a function which takes the feasibility dataframe and returns - a series of probabilities. If no function is passed, the behavior - of this method will not change - - Returns - ------- - None if there are no feasible buildings - new_buildings : dataframe - DataFrame of buildings to add. These buildings are rows from the - DataFrame that is returned from feasibility. - """ - - if len(self.feasibility) == 0: - # no feasible buildings, might as well bail - return - - # Get DataFrame of potential buildings from SqFtProForma steps - df = self._get_dataframe_of_buildings() - df = self._remove_infeasible_buildings(df) - df = self._calculate_net_units(df) - - if len(df) == 0: - print "WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM" - return - - print "Sum of net units that are profitable: {:,}".\ - format(int(df.net_units.sum())) - - # Generate development probabilities and pick buildings to build - p, df = self._calculate_probabilities(df, profit_to_prob_func) - build_idx = self._buildings_to_build(df, p) - - # Drop built buildings from self.feasibility attribute if desired - self._drop_built_buildings(build_idx) - - # Prep DataFrame of new buildings - new_df = self._prepare_new_buildings(df, build_idx) - - return new_df - - From 2d9e2377b99a2cd8233337d6fd2d0b2b86633e3c Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Mon, 13 Mar 2017 14:26:53 -0700 Subject: [PATCH 17/43] Add docstrings to helper methods for pick() --- developer/developer.py | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/developer/developer.py b/developer/developer.py index 93d936f..ce01930 100644 --- a/developer/developer.py +++ b/developer/developer.py @@ -203,6 +203,14 @@ def pick(self, profit_to_prob_func=None): return new_df def _get_dataframe_of_buildings(self): + """ + Helper method to pick(). Returns a DataFrame of buildings from + self.feasibility based on what type is passed to self.forms + + Returns + ------- + df : DataFrame + """ if self.forms is None: df = self.feasibility @@ -269,6 +277,23 @@ def keep_form_with_max_profit(self, forms=None): return df def _remove_infeasible_buildings(self, df): + """ + Helper method to pick(). Removes buildings from the DataFrame if: + - max_profit_far is 0 or less + - parcel_size is larger than max_parcel_size + + Also calculates useful DataFrame columns from object attributes + for later calculations. + + Parameters + ---------- + df : DataFrame + DataFrame of buildings from _get_dataframe_of_buildings() + + Returns + ------- + df : DataFrame + """ df = df[df.max_profit_far > 0] self.ave_unit_size[ @@ -287,6 +312,19 @@ def _remove_infeasible_buildings(self, df): return df def _calculate_net_units(self, df): + """ + Helper method to pick(). Calculates the net_units column, + and removes buildings that have net_units of 0 or less. + + Parameters + ---------- + df : DataFrame + DataFrame of buildings from _remove_infeasible_buildings() + + Returns + ------- + df : DataFrame + """ if self.residential: df['net_units'] = df.residential_units - df.current_units @@ -296,6 +334,25 @@ def _calculate_net_units(self, df): @staticmethod def _calculate_probabilities(df, profit_to_prob_func): + """ + Helper method to pick(). Calculates development probabilities based on + a preset rule, or an optional function passed to the constructor. + + Parameters + ---------- + df : DataFrame + DataFrame of buildings, prepared via _get_dataframe_of_buildings, + _remove_infeasible_buildings, and _calculate_net_units methods + profit_to_prob_func : function, optional + Function to calculate development probabilities for each building + + Returns + ------- + p : Series + Series of development probability for each building + df : DataFrame + DataFrame of buildings + """ if profit_to_prob_func: p = profit_to_prob_func(df) @@ -305,6 +362,23 @@ def _calculate_probabilities(df, profit_to_prob_func): return p, df def _buildings_to_build(self, df, p): + """ + Helper method to pick(). Selects buildings to build based on + development probabilities. + + Parameters + ---------- + df : DataFrame + DataFrame of buildings from _calculate_probabilities method + p : Series + Probabilities from _calculate_probabilities method + + Returns + ------- + build_idx : ndarray + Index of buildings selected for development + + """ if df.net_units.sum() < self.target_units: print "WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO " \ @@ -329,11 +403,42 @@ def _buildings_to_build(self, df, p): return build_idx def _drop_built_buildings(self, build_idx): + """ + Helper method to pick(). Drops built buildings from the + self.feasibility attribute DataFrame. + + Parameters + ---------- + build_idx : Array-like + Index of buildings selected for development, from + _buildings_to_build method + + Returns + ------- + None + """ if self.drop_after_build: self.feasibility = self.feasibility.drop(build_idx) def _prepare_new_buildings(self, df, build_idx): + """ + Helper method to pick(). Brings parcel_id into a column and applies + other compatibility fixes before returning to parcel model + + Parameters + ---------- + df : DataFrame + DataFrame of buildings from the _calculate_probabilities method + build_idx : Array-like + Index of buildings selected for development, from + _buildings_to_build method + + Returns + ------- + new_df : DataFrame + + """ new_df = df.loc[build_idx] new_df.index.name = "parcel_id" From 1a6751a72f37bb9f03436f56716bbde082658932 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 14 Mar 2017 09:44:02 -0700 Subject: [PATCH 18/43] Add failing unit test for reading optional parameters from YAML --- developer/tests/test_sqftproforma.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index fae2a35..90f507a 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -75,6 +75,31 @@ def test_sqftproforma_to_yaml(): os.remove('test_sqftproforma_config.yaml') +def test_sqftproforma_to_yaml_defaults(): + # Make sure that optional parameters to the SqFtProForma constructor + # are being read from config + + if os.path.exists('test_sqftproforma_config.yaml'): + os.remove('test_sqftproforma_config.yaml') + + settings = sqpf.SqFtProForma.get_defaults() + settings['residential_to_yearly'] = False + settings['forms_to_test'] = 'residential' + settings['only_built'] = False + settings['pass_through'] = ['some_column'] + settings['simple_zoning'] = True + settings['parcel_filter'] = 'some_expression' + + pf_from_settings = sqpf.SqFtProForma(**settings) + pf_from_settings.to_yaml('test_sqftproforma_config.yaml') + + pf_from_yaml = sqpf.SqFtProForma.from_yaml('test_sqftproforma_config.yaml') + + assert pf_from_yaml.to_dict == settings + + os.remove('test_sqftproforma_config.yaml') + + def test_sqftproforma_defaults(simple_dev_inputs): pf = sqpf.SqFtProForma.from_defaults() From 728ba518b13e4a97794f4fcbd5aa1035361094ef Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 14 Mar 2017 09:55:49 -0700 Subject: [PATCH 19/43] Fix failing test to fail on assertion --- developer/tests/test_sqftproforma.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index 90f507a..5b848c0 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -93,7 +93,8 @@ def test_sqftproforma_to_yaml_defaults(): pf_from_settings = sqpf.SqFtProForma(**settings) pf_from_settings.to_yaml('test_sqftproforma_config.yaml') - pf_from_yaml = sqpf.SqFtProForma.from_yaml('test_sqftproforma_config.yaml') + pf_from_yaml = sqpf.SqFtProForma.from_yaml( + str_or_buffer='test_sqftproforma_config.yaml') assert pf_from_yaml.to_dict == settings From b95db728e96145de187f4189a0c1d95c46f96f0a Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 14 Mar 2017 11:40:30 -0700 Subject: [PATCH 20/43] Fix failing test to get the correct assertion --- developer/tests/test_sqftproforma.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index 5b848c0..e083b51 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -96,7 +96,7 @@ def test_sqftproforma_to_yaml_defaults(): pf_from_yaml = sqpf.SqFtProForma.from_yaml( str_or_buffer='test_sqftproforma_config.yaml') - assert pf_from_yaml.to_dict == settings + assert pf_from_yaml.to_dict == pf_from_settings.to_dict os.remove('test_sqftproforma_config.yaml') From 15003c789131ff491134e4cdd78ddfc964fbc184 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 14 Mar 2017 11:41:31 -0700 Subject: [PATCH 21/43] Fix pro forma from_yaml to get optional parameters --- developer/sqftproforma.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/developer/sqftproforma.py b/developer/sqftproforma.py index 4c77677..95f8611 100644 --- a/developer/sqftproforma.py +++ b/developer/sqftproforma.py @@ -272,7 +272,13 @@ def from_yaml(cls, yaml_str=None, str_or_buffer=None): cfg['parking_configs'], cfg['costs'], cfg['heights_for_costs'], cfg['parking_sqft_d'], cfg['parking_cost_d'], cfg['height_per_story'], cfg['max_retail_height'], - cfg['max_industrial_height'] + cfg['max_industrial_height'], + cfg.get('residential_to_yearly', True), + cfg.get('forms_to_test', None), + cfg.get('only_built', True), + cfg.get('pass_through', None), + cfg.get('simple_zoning', False), + cfg.get('parcel_filter', None) ) logger.debug('loaded SqftProForma model from YAML') From 7890845bcff84bdcfe648dbc3498ecce19d79a42 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 12:04:48 -0700 Subject: [PATCH 22/43] Fix imports, change developer.py to develop.py --- developer/{developer.py => develop.py} | 2 +- developer/sqftproforma.py | 4 ++-- developer/tests/test_developer.py | 22 +++++++++++----------- developer/tests/test_sqftproforma.py | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) rename developer/{developer.py => develop.py} (99%) diff --git a/developer/developer.py b/developer/develop.py similarity index 99% rename from developer/developer.py rename to developer/develop.py index ce01930..c0e83c3 100644 --- a/developer/developer.py +++ b/developer/develop.py @@ -1,6 +1,6 @@ import pandas as pd import numpy as np -import utils +import developer.utils as utils import logging logger = logging.getLogger(__name__) diff --git a/developer/sqftproforma.py b/developer/sqftproforma.py index 95f8611..701c094 100644 --- a/developer/sqftproforma.py +++ b/developer/sqftproforma.py @@ -1,8 +1,8 @@ import numpy as np import pandas as pd import logging -import utils -from utils import columnize +import developer.utils as utils +from developer.utils import columnize logger = logging.getLogger(__name__) diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index 8583410..f51010a 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -2,8 +2,8 @@ import pytest import os -from .. import sqftproforma as sqpf -from .. import developer +from developer import sqftproforma as sqpf +from developer import develop @pytest.fixture @@ -55,16 +55,16 @@ def nonres(base_args): def test_res_developer(res): - dev = developer.Developer(target_units=10, **res) + dev = develop.Developer(target_units=10, **res) bldgs = dev.pick() assert len(bldgs) == 1 assert len(dev.feasibility) == 2 - dev = developer.Developer(target_units=1000, **res) + dev = develop.Developer(target_units=1000, **res) bldgs = dev.pick() assert len(bldgs) == 3 - dev = developer.Developer(target_units=2, residential=False, **res) + dev = develop.Developer(target_units=2, residential=False, **res) bldgs = dev.pick() assert bldgs is None @@ -77,13 +77,13 @@ def res10(res): def test_developer_dict_roundtrip(res10): - dev1 = developer.Developer(**res10) + dev1 = develop.Developer(**res10) config1 = dev1.to_dict next_args = config1.copy() next_args.update(res10) - dev2 = developer.Developer(**next_args) + dev2 = develop.Developer(**next_args) config2 = dev2.to_dict assert config1 == config2 @@ -93,16 +93,16 @@ def test_developer_yaml_roundtrip(res10): if os.path.exists('test_dev_config.yaml'): os.remove('test_dev_config.yaml') - dev = developer.Developer(**res10) + dev = develop.Developer(**res10) with open('test_dev_config.yaml', 'wb') as yaml_file: dev.to_yaml(yaml_file) yaml_string = dev.to_yaml() - dev_from_yaml_file = developer.Developer.from_yaml( + dev_from_yaml_file = develop.Developer.from_yaml( str_or_buffer='test_dev_config.yaml', **res10) assert dev.to_dict == dev_from_yaml_file.to_dict - dev_from_yaml_string = developer.Developer.from_yaml( + dev_from_yaml_string = develop.Developer.from_yaml( yaml_str=yaml_string, **res10) assert dev.to_dict == dev_from_yaml_string.to_dict @@ -110,5 +110,5 @@ def test_developer_yaml_roundtrip(res10): def test_developer_compute_forms_max_profit(res10): - dev = developer.Developer(**res10) + dev = develop.Developer(**res10) dev.keep_form_with_max_profit() diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index e083b51..d61a44c 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from .. import sqftproforma as sqpf +from developer import sqftproforma as sqpf @pytest.fixture From e6335a0248df2edaa697a050f7a6ecef457a8e9b Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 12:07:08 -0700 Subject: [PATCH 23/43] Fix print statements --- developer/develop.py | 11 ++++++----- developer/sqftproforma.py | 1 + developer/tests/test_sqftproforma.py | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/developer/develop.py b/developer/develop.py index c0e83c3..7480313 100644 --- a/developer/develop.py +++ b/developer/develop.py @@ -1,3 +1,4 @@ +from __future__ import print_function, division import pandas as pd import numpy as np import developer.utils as utils @@ -184,11 +185,11 @@ def pick(self, profit_to_prob_func=None): df = self._calculate_net_units(df) if len(df) == 0: - print "WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM" + print("WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM") return - print "Sum of net units that are profitable: {:,}".\ - format(int(df.net_units.sum())) + print("Sum of net units that are profitable: {:,}". + format(int(df.net_units.sum()))) # Generate development probabilities and pick buildings to build p, df = self._calculate_probabilities(df, profit_to_prob_func) @@ -381,8 +382,8 @@ def _buildings_to_build(self, df, p): """ if df.net_units.sum() < self.target_units: - print "WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO " \ - "MATCH DEMAND" + print("WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO" + "MATCH DEMAND") build_idx = df.index.values elif self.target_units <= 0: build_idx = [] diff --git a/developer/sqftproforma.py b/developer/sqftproforma.py index 701c094..ae93e55 100644 --- a/developer/sqftproforma.py +++ b/developer/sqftproforma.py @@ -1,3 +1,4 @@ +from __future__ import print_function, division import numpy as np import pandas as pd import logging diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index d61a44c..dc8b33c 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -1,3 +1,4 @@ +from __future__ import print_function, division import os import pandas as pd From 10132d22f559c36a8dfb32ee79a4eb2f541e866e Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 12:17:38 -0700 Subject: [PATCH 24/43] Fix dict.iteritems() - replace with dict.items() --- developer/sqftproforma.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/developer/sqftproforma.py b/developer/sqftproforma.py index ae93e55..5143394 100644 --- a/developer/sqftproforma.py +++ b/developer/sqftproforma.py @@ -193,23 +193,23 @@ def check_is_reasonable(self): fars = pd.Series(self.fars) assert len(fars[fars > 20]) == 0 assert len(fars[fars <= 0]) == 0 - for k, v in self.forms.iteritems(): + for k, v in self.forms.items(): assert isinstance(v, dict) - for k2, v2 in self.forms[k].iteritems(): + for k2, v2 in self.forms[k].items(): assert isinstance(k2, str) assert isinstance(v2, float) - for k2, v2 in self.forms[k].iteritems(): + for k2, v2 in self.forms[k].items(): assert isinstance(k2, str) assert isinstance(v2, float) - for k, v in self.parking_rates.iteritems(): + for k, v in self.parking_rates.items(): assert isinstance(k, str) assert k in self.uses assert 0 <= v < 5 - for k, v in self.parking_sqft_d.iteritems(): + for k, v in self.parking_sqft_d.items(): assert isinstance(k, str) assert k in self.parking_configs assert 50 <= v <= 1000 - for k, v in self.parking_sqft_d.iteritems(): + for k, v in self.parking_sqft_d.items(): assert isinstance(k, str) assert k in self.parking_cost_d assert 10 <= v <= 300 @@ -218,7 +218,7 @@ def check_is_reasonable(self): if np.isinf(v): continue assert 0 <= v <= 1000 - for k, v in self.costs.iteritems(): + for k, v in self.costs.items(): assert isinstance(k, str) assert k in self.uses for i in v: @@ -235,7 +235,7 @@ def _convert_types(self): [self.parking_rates[use] for use in self.uses]) self.res_ratios = {} assert len(self.uses) == len(self.residential_uses) - for k, v in self.forms.iteritems(): + for k, v in self.forms.items(): self.forms[k] = np.array( [self.forms[k].get(use, 0.0) for use in self.uses]) # normalize if not already From 5d55b94ce78a24e9b0a62d8bd31e545b6cb9b966 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 12:25:14 -0700 Subject: [PATCH 25/43] Fix dict.keys().sort() -> list(dict.keys()).sort() --- developer/sqftproforma.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/developer/sqftproforma.py b/developer/sqftproforma.py index 5143394..d6c6174 100644 --- a/developer/sqftproforma.py +++ b/developer/sqftproforma.py @@ -543,7 +543,7 @@ def _debug_output(self): import matplotlib.pyplot as plt df_d = self.reference_dict - keys = df_d.keys() + keys = list(df_d.keys()) keys.sort() for key in keys: logger.debug("\n" + str(key) + "\n") @@ -552,7 +552,7 @@ def _debug_output(self): logger.debug("\n" + str(key) + "\n") logger.debug(self.get_ave_cost_sqft(form, "surface")) - keys = self.forms.keys() + keys = list(self.forms.keys()) keys.sort() cnt = 1 share = None @@ -628,7 +628,7 @@ def _generate_reference(self): """ # get all the building forms we can use - keys = self.forms.keys() + keys = list(self.forms.keys()) keys.sort() df_d = {} for name in keys: From 33df321ed6b2d4a0aad83e9fe1d260c64387193a Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 12:39:24 -0700 Subject: [PATCH 26/43] Fix binary writes in test modules --- developer/tests/test_developer.py | 2 +- developer/tests/test_sqftproforma.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index f51010a..184999d 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -94,7 +94,7 @@ def test_developer_yaml_roundtrip(res10): os.remove('test_dev_config.yaml') dev = develop.Developer(**res10) - with open('test_dev_config.yaml', 'wb') as yaml_file: + with open('test_dev_config.yaml', 'w') as yaml_file: dev.to_yaml(yaml_file) yaml_string = dev.to_yaml() diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index dc8b33c..40f7007 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -61,7 +61,7 @@ def test_sqftproforma_to_yaml(): os.remove('test_sqftproforma_config.yaml') pf = sqpf.SqFtProForma.from_defaults() - with open('test_sqftproforma_config.yaml', 'wb') as yaml_file: + with open('test_sqftproforma_config.yaml', 'w') as yaml_file: pf.to_yaml(yaml_file) yaml_string = pf.to_yaml() From a203d0e90e64fe136cd17a4ac04e66862ebea4c7 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 13:32:33 -0700 Subject: [PATCH 27/43] Update Travis build with Python 3.5 and 3.6 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index e5a904d..992c960 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: python sudo: false python: - '2.7' +- '3.5' +- '3.6' install: - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh From 18523bd98bb3c8b6927e274c47b92e57d0e9b596 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 13:34:14 -0700 Subject: [PATCH 28/43] Travis: remove numpy version number, include condition for pandana installation --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 992c960..b1903df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,12 +16,13 @@ install: - conda update -q conda - conda info -a - | - conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip numpy=1.11 pandas pytest matplotlib scipy statsmodels + conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip numpy pandas pytest matplotlib scipy statsmodels - source activate test-environment - conda list - pip install . - pip install https://github.com/UDST/orca/archive/master.zip -- pip install urbansim pandana +- pip install urbansim +- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; pip install pandana - git clone git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels From 7f1456fb16be5e08820b4d99442cf76ccc16747d Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 13:41:37 -0700 Subject: [PATCH 29/43] Fix bash syntax in Travis config, fix print statements --- .travis.yml | 4 +++- developer/develop.py | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1903df..5bc9595 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,9 @@ install: - pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install urbansim -- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; pip install pandana +- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then + pip install pandana; + fi - git clone git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels diff --git a/developer/develop.py b/developer/develop.py index 7480313..a64ca0a 100644 --- a/developer/develop.py +++ b/developer/develop.py @@ -188,8 +188,8 @@ def pick(self, profit_to_prob_func=None): print("WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM") return - print("Sum of net units that are profitable: {:,}". - format(int(df.net_units.sum()))) + print("Sum of net units that are profitable: {:,}".format( + int(df.net_units.sum()))) # Generate development probabilities and pick buildings to build p, df = self._calculate_probabilities(df, profit_to_prob_func) @@ -382,7 +382,7 @@ def _buildings_to_build(self, df, p): """ if df.net_units.sum() < self.target_units: - print("WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO" + print("WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO", "MATCH DEMAND") build_idx = df.index.values elif self.target_units <= 0: From ad553c2024b6b7550ccdc2b854b7273824fb4dcc Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 14:36:34 -0700 Subject: [PATCH 30/43] Travis: only run simulate.py if python version 2.7 --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5bc9595..5bd058b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,4 +30,6 @@ install: script: - py.test -- cd urbansim_parcels/sf_example; python simulate.py \ No newline at end of file +- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then + cd urbansim_parcels/sf_example; python simulate.py; + fi \ No newline at end of file From acf68f4012e1e0cad81476001250eed8e44acf97 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 14:46:47 -0700 Subject: [PATCH 31/43] Travis: fix bash syntax, fix py.test call to be local to developer repo --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5bd058b..afc2a51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ install: - pip install ./urbansim_parcels script: -- py.test +- cd "$TRAVIS_BUILD_DIR" && py.test - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - cd urbansim_parcels/sf_example; python simulate.py; + cd urbansim_parcels/sf_example && python simulate.py; fi \ No newline at end of file From 1317d1f3d0a742fd137de01e04bf3915c6626310 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 14:57:56 -0700 Subject: [PATCH 32/43] Change where urbansim_parcels is being cloned in Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index afc2a51..56fe84f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ install: - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; fi -- git clone git@github.com:urbansim/urbansim_parcels.git +- cd .. && git clone git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: From cb93f5a534df93833e9af9398da0cf233515ce8a Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 15:15:27 -0700 Subject: [PATCH 33/43] Fix bash syntax for simulate.py, change urbansim installation to py3 fork --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56fe84f..22ae3ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ install: - conda list - pip install . - pip install https://github.com/UDST/orca/archive/master.zip -- pip install urbansim +- pip install https://github.com/pksohn/urbansim/archive/python3.zip - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; fi @@ -31,5 +31,5 @@ install: script: - cd "$TRAVIS_BUILD_DIR" && py.test - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - cd urbansim_parcels/sf_example && python simulate.py; + cd ../urbansim_parcels/sf_example && python simulate.py; fi \ No newline at end of file From 014b98c0c8bc589aaf31b7c2447305f10d91aee6 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 17 Mar 2017 15:20:42 -0700 Subject: [PATCH 34/43] Travis fix - get python3 branch of urbansim_parcels --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 22ae3ef..14bfcfc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ install: - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; fi -- cd .. && git clone git@github.com:urbansim/urbansim_parcels.git +- cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: From 1eeccd6c2bca32672063695c111cbeed46b489e1 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Mon, 20 Mar 2017 11:40:48 -0700 Subject: [PATCH 35/43] Travis file syntax --- .travis.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14bfcfc..6db6570 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,14 +22,11 @@ install: - pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install https://github.com/pksohn/urbansim/archive/python3.zip -- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - pip install pandana; - fi +- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; fi - cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: - cd "$TRAVIS_BUILD_DIR" && py.test - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - cd ../urbansim_parcels/sf_example && python simulate.py; - fi \ No newline at end of file + cd ../urbansim_parcels/sf_example && python simulate.py; fi \ No newline at end of file From abe304edef6f9c180ef956b45a6b0e653a247f40 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 21 Mar 2017 10:03:02 -0700 Subject: [PATCH 36/43] Add absolute_imports from __future__ imports --- developer/develop.py | 2 +- developer/sqftproforma.py | 2 +- developer/tests/test_developer.py | 1 + developer/tests/test_sqftproforma.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/developer/develop.py b/developer/develop.py index a64ca0a..d68c88c 100644 --- a/developer/develop.py +++ b/developer/develop.py @@ -1,4 +1,4 @@ -from __future__ import print_function, division +from __future__ import print_function, division, absolute_import import pandas as pd import numpy as np import developer.utils as utils diff --git a/developer/sqftproforma.py b/developer/sqftproforma.py index d6c6174..469b1b4 100644 --- a/developer/sqftproforma.py +++ b/developer/sqftproforma.py @@ -1,4 +1,4 @@ -from __future__ import print_function, division +from __future__ import print_function, division, absolute_import import numpy as np import pandas as pd import logging diff --git a/developer/tests/test_developer.py b/developer/tests/test_developer.py index 184999d..d35e1e1 100644 --- a/developer/tests/test_developer.py +++ b/developer/tests/test_developer.py @@ -1,3 +1,4 @@ +from __future__ import print_function, division, absolute_import import pandas as pd import pytest import os diff --git a/developer/tests/test_sqftproforma.py b/developer/tests/test_sqftproforma.py index 40f7007..6d00758 100644 --- a/developer/tests/test_sqftproforma.py +++ b/developer/tests/test_sqftproforma.py @@ -1,4 +1,4 @@ -from __future__ import print_function, division +from __future__ import print_function, division, absolute_import import os import pandas as pd From fd764884c9ba0d3811ef5f5c3abb59443bd233d8 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 21 Mar 2017 13:50:40 -0700 Subject: [PATCH 37/43] Add pandana installation and simulate.py to Travis build for 3.5 and 3.6 --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6db6570..80107ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,11 +22,10 @@ install: - pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install https://github.com/pksohn/urbansim/archive/python3.zip -- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; fi +- pip install https://github.com/UDST/pandana/archive/python3-support.zip - cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: - cd "$TRAVIS_BUILD_DIR" && py.test -- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - cd ../urbansim_parcels/sf_example && python simulate.py; fi \ No newline at end of file +- cd ../urbansim_parcels/sf_example && python simulate.py \ No newline at end of file From ad8336f654b7c7b8cc5ad9fc857039558e0c14a5 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 21 Mar 2017 13:53:30 -0700 Subject: [PATCH 38/43] Add python3 compatible osmnet installation --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 80107ca..efcca67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ install: - pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install https://github.com/pksohn/urbansim/archive/python3.zip +- pip install https://github.com/UDST/osmnet/archive/python3-support.zip - pip install https://github.com/UDST/pandana/archive/python3-support.zip - cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels From 6e9e1867589dadeff036d7df33f137337464da9e Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 21 Mar 2017 14:00:55 -0700 Subject: [PATCH 39/43] Change order of installation in Travis build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index efcca67..e89e268 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,11 +19,11 @@ install: conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip numpy pandas pytest matplotlib scipy statsmodels - source activate test-environment - conda list -- pip install . - pip install https://github.com/UDST/orca/archive/master.zip - pip install https://github.com/pksohn/urbansim/archive/python3.zip - pip install https://github.com/UDST/osmnet/archive/python3-support.zip - pip install https://github.com/UDST/pandana/archive/python3-support.zip +- pip install . - cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels From 41b1e86a46f962c24540330fcc4ac5224d6ecf01 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Tue, 21 Mar 2017 14:31:10 -0700 Subject: [PATCH 40/43] pip install Pandana if 2.7 --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e89e268..5861fe3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,9 @@ install: - conda list - pip install https://github.com/UDST/orca/archive/master.zip - pip install https://github.com/pksohn/urbansim/archive/python3.zip -- pip install https://github.com/UDST/osmnet/archive/python3-support.zip -- pip install https://github.com/UDST/pandana/archive/python3-support.zip +- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; else + pip install https://github.com/UDST/osmnet/archive/python3-support.zip && + pip install https://github.com/UDST/pandana/archive/python3-support.zip; fi - pip install . - cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels From 763c336ac7e33a033f198a6acfa3291f3ff65906 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 24 Mar 2017 17:16:05 -0700 Subject: [PATCH 41/43] Point to master branch of urbansim_parcels in Travis build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5861fe3..0a15b42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ install: pip install https://github.com/UDST/osmnet/archive/python3-support.zip && pip install https://github.com/UDST/pandana/archive/python3-support.zip; fi - pip install . -- cd .. && git clone -b python3 git@github.com:urbansim/urbansim_parcels.git +- cd .. && git clone git@github.com:urbansim/urbansim_parcels.git - pip install ./urbansim_parcels script: From 85aa25f6a23ffb3daf2795883d1af4592bf42136 Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Fri, 24 Mar 2017 17:16:44 -0700 Subject: [PATCH 42/43] Remove python 3.6 from builds --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0a15b42..7d95f9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ sudo: false python: - '2.7' - '3.5' -- '3.6' install: - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh From f5d53c9017d71c9cf727d0c7c5ae5dc52e7c8fbe Mon Sep 17 00:00:00 2001 From: Paul Sohn Date: Wed, 29 Mar 2017 11:47:49 -0700 Subject: [PATCH 43/43] Bump version numbers --- developer/__init__.py | 1 + setup.py | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/developer/__init__.py b/developer/__init__.py index e69de29..7fd229a 100644 --- a/developer/__init__.py +++ b/developer/__init__.py @@ -0,0 +1 @@ +__version__ = '0.2.0' diff --git a/setup.py b/setup.py index 9659b56..472f57e 100644 --- a/setup.py +++ b/setup.py @@ -9,17 +9,13 @@ setup( name='developer', - version='0.1dev', + version='0.2.0', description='Urbansim developer model', author='UrbanSim Inc.', author_email='info@urbansim.com', url='https://github.com/urbansim/developer', classifiers=[ - 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5' ], packages=find_packages(exclude=['*.tests']),