Skip to content

Commit 571a9a3

Browse files
committed
Merge branch 'release/0.3'
2 parents 5167072 + e95422b commit 571a9a3

6 files changed

Lines changed: 505 additions & 357 deletions

File tree

.travis.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,20 @@ install:
1515
- conda update -q conda
1616
- conda info -a
1717
- |
18-
conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip numpy pandas pytest matplotlib scipy statsmodels
18+
conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip numpy pandas pytest matplotlib scipy statsmodels pytables
1919
- source activate test-environment
2020
- conda list
21-
- pip install https://github.com/UDST/orca/archive/master.zip
22-
- pip install https://github.com/pksohn/urbansim/archive/python3.zip
23-
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then pip install pandana; else
24-
pip install https://github.com/UDST/osmnet/archive/python3-support.zip &&
25-
pip install https://github.com/UDST/pandana/archive/python3-support.zip; fi
21+
- pip install pycodestyle
22+
- pip install orca
23+
- pip install https://github.com/udst/urbansim/archive/master.zip
24+
- pip install osmnet pandana
2625
- pip install .
2726
- cd .. && git clone git@github.com:urbansim/urbansim_parcels.git
2827
- pip install ./urbansim_parcels
28+
- cd "$TRAVIS_BUILD_DIR"
2929

3030
script:
31-
- cd "$TRAVIS_BUILD_DIR" && py.test
32-
- cd ../urbansim_parcels/sf_example && python simulate.py
31+
- pycodestyle developer
32+
- py.test
33+
- cd ../urbansim_parcels/sf_example && python simulate.py
34+
- cd ../sd_example && python Simulation.py

developer/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.2.0'
1+
__version__ = '0.3.0'

developer/develop.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def to_yaml(self, str_or_buffer=None):
153153
logger.debug('serializing Developer model to YAML')
154154
return utils.convert_to_yaml(self.to_dict, str_or_buffer)
155155

156-
def pick(self, profit_to_prob_func=None):
156+
def pick(self, profit_to_prob_func=None, custom_selection_func=None):
157157
"""
158158
Choose the buildings from the list that are feasible to build in
159159
order to match the specified demand.
@@ -166,6 +166,11 @@ def pick(self, profit_to_prob_func=None):
166166
a function which takes the feasibility dataframe and returns
167167
a series of probabilities. If no function is passed, the behavior
168168
of this method will not change
169+
custom_selection_func: func
170+
User passed function that decides how to select buildings for
171+
development after probabilities are calculated. Must have
172+
parameters (self, df, p) and return a numpy array of buildings to
173+
build (i.e. df.index.values)
169174
170175
Returns
171176
-------
@@ -174,26 +179,28 @@ def pick(self, profit_to_prob_func=None):
174179
DataFrame of buildings to add. These buildings are rows from the
175180
DataFrame that is returned from feasibility.
176181
"""
182+
df = self.feasibility
183+
empty_warn = "WARNING THERE ARE NO FEASIBLE BUILDINGS TO CHOOSE FROM"
177184

178-
if len(self.feasibility) == 0:
179-
# no feasible buildings, might as well bail
185+
if len(df) == 0 or df.empty:
186+
print(empty_warn)
180187
return
181188

182189
# Get DataFrame of potential buildings from SqFtProForma steps
183190
df = self._get_dataframe_of_buildings()
184191
df = self._remove_infeasible_buildings(df)
185192
df = self._calculate_net_units(df)
186193

187-
if len(df) == 0:
188-
print("WARNING THERE ARE NO FEASIBLE BUILDING TO CHOOSE FROM")
194+
if len(df) == 0 or df.empty:
195+
print(empty_warn)
189196
return
190197

191198
print("Sum of net units that are profitable: {:,}".format(
192199
int(df.net_units.sum())))
193200

194201
# Generate development probabilities and pick buildings to build
195202
p, df = self._calculate_probabilities(df, profit_to_prob_func)
196-
build_idx = self._buildings_to_build(df, p)
203+
build_idx = self._select_buildings(df, p, custom_selection_func)
197204

198205
# Drop built buildings from self.feasibility attribute if desired
199206
self._drop_built_buildings(build_idx)
@@ -295,6 +302,8 @@ def _remove_infeasible_buildings(self, df):
295302
-------
296303
df : DataFrame
297304
"""
305+
if len(df) == 0 or df.empty:
306+
return df
298307

299308
df = df[df.max_profit_far > 0]
300309
self.ave_unit_size[
@@ -326,6 +335,8 @@ def _calculate_net_units(self, df):
326335
-------
327336
df : DataFrame
328337
"""
338+
if len(df) == 0 or df.empty:
339+
return df
329340

330341
if self.residential:
331342
df['net_units'] = df.residential_units - df.current_units
@@ -362,7 +373,7 @@ def _calculate_probabilities(df, profit_to_prob_func):
362373
p = df.max_profit_per_size.values / df.max_profit_per_size.sum()
363374
return p, df
364375

365-
def _buildings_to_build(self, df, p):
376+
def _select_buildings(self, df, p, custom_selection_func):
366377
"""
367378
Helper method to pick(). Selects buildings to build based on
368379
development probabilities.
@@ -373,6 +384,11 @@ def _buildings_to_build(self, df, p):
373384
DataFrame of buildings from _calculate_probabilities method
374385
p : Series
375386
Probabilities from _calculate_probabilities method
387+
custom_selection_func: func
388+
User passed function that decides how to select buildings for
389+
development after probabilities are calculated. Must have
390+
parameters (self, df, p) and return a numpy array of buildings to
391+
build (i.e. df.index.values)
376392
377393
Returns
378394
-------
@@ -381,7 +397,9 @@ def _buildings_to_build(self, df, p):
381397
382398
"""
383399

384-
if df.net_units.sum() < self.target_units:
400+
if custom_selection_func is not None:
401+
build_idx = custom_selection_func(self, df, p)
402+
elif df.net_units.sum() < self.target_units:
385403
print("WARNING THERE WERE NOT ENOUGH PROFITABLE UNITS TO",
386404
"MATCH DEMAND")
387405
build_idx = df.index.values
@@ -442,7 +460,11 @@ def _prepare_new_buildings(self, df, build_idx):
442460
"""
443461

444462
new_df = df.loc[build_idx]
445-
new_df.index.name = "parcel_id"
463+
464+
drop = True
465+
if 'parcel_id' not in df.columns:
466+
new_df.index.name = "parcel_id"
467+
drop = False
446468

447469
if self.year is not None:
448470
new_df["year_built"] = self.year
@@ -453,4 +475,4 @@ def _prepare_new_buildings(self, df, build_idx):
453475

454476
new_df["stories"] = new_df.stories.apply(np.ceil)
455477

456-
return new_df.reset_index()
478+
return new_df.reset_index(drop=drop)

0 commit comments

Comments
 (0)