Skip to content

Commit

Permalink
Fix #24
Browse files Browse the repository at this point in the history
  • Loading branch information
invisibleroads committed Dec 12, 2016
1 parent 6fd6131 commit dcbe9a3
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
36 changes: 23 additions & 13 deletions infrastructure_planning/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,22 +255,32 @@ def get_table_from_variables(ls, g, keys):
return DataFrame(rows, columns=keys).set_index('name')


def interpolate_values(source_table, target_column, target_value):
def interpolate_values(source_table, source_column, target_value):
t = source_table
assert len(t) > 0
assert len(t) == len(set(t[target_column]))
# Get indices of two rows nearest to target value
difference = t[target_column] - target_value
sorted_indices = difference.abs().argsort()
index0 = sorted_indices[0]
index1 = sorted_indices[1] if len(sorted_indices) > 1 else index0
# Compute fraction of difference in target column
source_values = t[source_column]
minimum_source_value = source_values.min()
maximum_source_value = source_values.max()
message_template = 'source_column (%s) values must be %%s' % source_column
assert len(t) > 0, 'table must have at least one row'
assert len(t) == len(set(source_values)), message_template % 'unique'
assert minimum_source_value >= 0, message_template % 'positive'
if len(t) == 1:
return t.ix[t.index[0]]
if target_value <= minimum_source_value:
return t.ix[source_values.argmin()]
if target_value >= maximum_source_value:
return t.ix[source_values.argmax()]
# Get two rows nearest to target value
sorted_indices = (source_values - target_value).abs().argsort()
row0 = t.ix[sorted_indices[0]]
row1 = t.ix[sorted_indices[1]]
# Compute fraction of interpolation
fraction = divide_safely(
t[target_column].ix[index0],
t[target_column].ix[index1],
ExpectedPositive(target_column))
target_value - row0[source_column],
row1[source_column] - row0[source_column],
ExpectedPositive(message_template % 'unique and positive'))
# Interpolate
return t.ix[index0] + (t.ix[index1] - t.ix[index0]) * fraction
return row0 + (row1 - row0) * fraction


def rename_keys(value_by_key, prefix='', suffix=''):
Expand Down
11 changes: 9 additions & 2 deletions missions/ProductionCountdown-20161212.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ It is important to keep the project alive while it still has users.
# Objectives

1. Sort goals.
2. Update model.
2. Fix bugs.
3. Update model.

# Log

Expand All @@ -30,10 +31,16 @@ It is important to keep the project alive while it still has users.
_ Rename standard_output.log to stdout.log
_ Rename standard_error.log to stderr.log
_ Get default parameters for tanzania training
+ Check that everything still works

# Tasks
20161212-1100 - 20161212-1200: 1 hour

I found a serious bug in the way that values are being interpolated in `interpolate_values`.

Use parameters from minimum capacity if actual is less than minimum

# Tasks

Consider total population and % connected to compute unconnected household count
Grow population using total population
Size capacity using unconnected household count
Expand Down
25 changes: 25 additions & 0 deletions tests/test_macros.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest
from infrastructure_planning.macros import interpolate_values
from pandas import DataFrame


SOURCE_TABLE = DataFrame([
[2, 200],
[6, 600],
], columns=[
'x', 'y',
])


@pytest.mark.parametrize('x, y', [
(0, 200),
(1, 200),
(2, 200),
(3, 300),
(4, 400),
(5, 500),
(6, 600),
(7, 600),
])
def test_interpolate_values(x, y):
assert interpolate_values(SOURCE_TABLE, 'x', x)['y'] == y

0 comments on commit dcbe9a3

Please sign in to comment.