Skip to content

Commit f28286c

Browse files
committed
Fixes for number comparison issues.
1 parent fb1fe1f commit f28286c

File tree

17 files changed

+243
-158
lines changed

17 files changed

+243
-158
lines changed

TNMStagingCSharp/TNMStagingCSharp/Src/DecisionEngine/DecisionEngine.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ public static int findMatchingTableRow(ITable table, Dictionary<String, String>
139139

140140
//========================================================================================================================
141141
// Tests that a value is contained in a list of ranges; if the list of ranges is missing or empty, then all values will match to it
142-
// @param values a List of StringRange objects
142+
// @param values a List of Range objects
143143
// @param value a value to look for
144144
// @param context the context will be used to do key lookups when values are in the format of {{var}}
145-
// @return return true if the value is contained in the List of StringRange objects
145+
// @return return true if the value is contained in the List of Range objects
146146
//========================================================================================================================
147-
public static bool testMatch(List<StringRange> values, String value, Dictionary<String, String> context)
147+
public static bool testMatch(List<Range> values, String value, Dictionary<String, String> context)
148148
{
149149
if (values == null)
150150
{

TNMStagingCSharp/TNMStagingCSharp/Src/DecisionEngine/StringRange.cs renamed to TNMStagingCSharp/TNMStagingCSharp/Src/DecisionEngine/Range.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace TNMStagingCSharp.Src.DecisionEngine
88
{
9-
public abstract class StringRange
9+
public abstract class Range
1010
{
1111
//========================================================================================================================
1212
// Returns true of the passed value is contained in the range

TNMStagingCSharp/TNMStagingCSharp/Src/DecisionEngine/TableRow.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ public interface ITableRow
1313
//========================================================================================================================
1414
// A list of values from the input column represented by the passed key
1515
// @param key the field name of the column
16-
// @return a List of StringRange objects
16+
// @return a List of Range objects
1717
//========================================================================================================================
18-
List<StringRange> getColumnInput(String key);
18+
List<Range> getColumnInput(String key);
1919

2020
//========================================================================================================================
2121
// A list of endpoints on the row

TNMStagingCSharp/TNMStagingCSharp/Src/Staging/Entities/StagingStringRange.cs renamed to TNMStagingCSharp/TNMStagingCSharp/Src/Staging/Entities/StagingRange.cs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace TNMStagingCSharp.Src.Staging.Entities
77
{
8-
public class StagingStringRange : DecisionEngine.StringRange
8+
public class StagingRange : DecisionEngine.Range
99
{
1010
private String _low;
1111
private String _high;
@@ -14,14 +14,15 @@ public class StagingStringRange : DecisionEngine.StringRange
1414
private bool bHighIsRefContextValue;
1515

1616
// Construct a string range that matches any string
17-
public StagingStringRange()
17+
public StagingRange()
1818
{
19+
1920
}
2021

2122
// Construct a string range with a low and high bound
2223
// @param low low value
2324
// @param high high value
24-
public StagingStringRange(String low, String high)
25+
public StagingRange(String low, String high)
2526
{
2627
if (low == null || high == null)
2728
throw new System.InvalidOperationException("Invalid range");
@@ -33,6 +34,14 @@ public StagingStringRange(String low, String high)
3334
bHighIsRefContextValue = DecisionEngine.DecisionEngineFuncs.isReferenceVariable(high);
3435
}
3536

37+
// Return true if the string can converted into a number
38+
public static bool isNumeric(String value)
39+
{
40+
//return NumberUtils.isParsable(value);
41+
float number;
42+
return (float.TryParse(value, out number));
43+
}
44+
3645
public override String getLow()
3746
{
3847
return _low;
@@ -50,9 +59,14 @@ public bool matchesAll()
5059
return _low == null && _high == null;
5160
}
5261

62+
63+
// Returns true if the value is contained in the range. Note that the low and high values will be replaced with context if
64+
// they are specified that way. There are two ways in which the values are compared.
65+
// 1. If the low and high values are different and are both "numeric", then the value will be compared using floats.
66+
// 2. Otherwise it will be compared using String but the strings must be the same length othersize the method will always return false.
5367
public override bool contains(String value, Dictionary<String, String> context)
5468
{
55-
if (_low == null && _high == null)
69+
if (matchesAll())
5670
return true;
5771

5872
// make null values match the same as if they were blank
@@ -67,6 +81,42 @@ public override bool contains(String value, Dictionary<String, String> context)
6781
if (bHighIsRefContextValue)
6882
high = DecisionEngine.DecisionEngineFuncs.translateValue(_high, context);
6983

84+
// if input, low and high values represent decimal numbers then do a float comparison
85+
86+
if (!low.Equals(high))
87+
{
88+
float fConverted, fLow, fHigh;
89+
bool bValueConv = float.TryParse(value, out fConverted);
90+
bool bLowConv = float.TryParse(low, out fLow);
91+
bool bHighConv = float.TryParse(high, out fHigh);
92+
93+
if ((bLowConv) && (bHighConv))
94+
{
95+
if (!bValueConv) return false;
96+
97+
return (fConverted >= fLow) && (fConverted <= fHigh);
98+
}
99+
100+
}
101+
102+
103+
/*
104+
if (!low.Equals(high) && isNumeric(low) && isNumeric(high))
105+
{
106+
if (!isNumeric(value)) return false;
107+
108+
float fConverted, fLow, fHigh;
109+
float.TryParse(value, out fConverted);
110+
float.TryParse(low, out fLow);
111+
float.TryParse(high, out fHigh);
112+
113+
return (fConverted >= fLow) && (fConverted <= fHigh);
114+
115+
//float converted = NumberUtils.createFloat(value);
116+
//return (converted >= NumberUtils.createFloat(low)) && (converted <= NumberUtils.createFloat(high));
117+
}
118+
*/
119+
70120
// if the context value(s) failed or the low and high values are different length, return false
71121
if (low.Length != high.Length || low.Length != value.Length)
72122
return false;

TNMStagingCSharp/TNMStagingCSharp/Src/Staging/Entities/StagingTableRow.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ public class StagingTableRow: ITableRow
1414
{
1515

1616
[JsonProperty("inputs")]
17-
[JsonConverter(typeof(CustomDictionaryConverter<String, List<StagingStringRange>>))]
18-
private Dictionary<String, List<StringRange>> _inputs = new Dictionary<String, List<StringRange>>(20);
17+
[JsonConverter(typeof(CustomDictionaryConverter<String, List<StagingRange>>))]
18+
private Dictionary<String, List<Range>> _inputs = new Dictionary<String, List<Range>>(20);
1919
[JsonProperty("endpoint")]
2020
[JsonConverter(typeof(CustomListConverter<StagingEndpoint>))]
2121
private List<IEndpoint> _endpoints = new List<IEndpoint>(20);
2222

2323
private int iNumInputs = 0;
2424
private String[] arrKeys;
25-
private List<StringRange>[] arrValues;
25+
private List<Range>[] arrValues;
2626

27-
public List<StringRange> getColumnInput(String key)
27+
public List<Range> getColumnInput(String key)
2828
{
2929
for (int i = 0; i < iNumInputs; i++)
3030
{
@@ -37,31 +37,31 @@ public void ConvertColumnInput()
3737
{
3838
iNumInputs = _inputs.Count;
3939
arrKeys = new String[iNumInputs];
40-
arrValues = new List<StringRange>[iNumInputs];
40+
arrValues = new List<Range>[iNumInputs];
4141

4242
int iIndex = 0;
43-
foreach (KeyValuePair<String, List<StringRange>> entry in _inputs)
43+
foreach (KeyValuePair<String, List<Range>> entry in _inputs)
4444
{
4545
arrKeys[iIndex] = entry.Key;
4646
arrValues[iIndex] = entry.Value;
4747
iIndex++;
4848
}
4949
}
5050

51-
public Dictionary<String, List<StringRange>> getInputs()
51+
public Dictionary<String, List<Range>> getInputs()
5252
{
5353
return _inputs;
5454
}
5555

56-
public void setInputs(Dictionary<String, List<StringRange>> inputs)
56+
public void setInputs(Dictionary<String, List<Range>> inputs)
5757
{
5858
_inputs = inputs;
5959
}
6060

6161
// Add a single columns input list
6262
// @param key key
6363
// @param range range
64-
public void addInput(String key, List<StringRange> range)
64+
public void addInput(String key, List<Range> range)
6565
{
6666
_inputs[key] = range;
6767
}

TNMStagingCSharp/TNMStagingCSharp/Src/Staging/StagingDataProvider.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public abstract class StagingDataProvider : IDataProvider
1919
public static readonly String PRIMARY_SITE_TABLE = "primary_site";
2020
public static readonly String HISTOLOGY_TABLE = "histology";
2121

22-
private static Entities.StagingStringRange _MATCH_ALL_ENDPOINT = new Entities.StagingStringRange();
22+
private static Entities.StagingRange _MATCH_ALL_ENDPOINT = new Entities.StagingRange();
2323

2424
private ConcurrentDictionary<String, List<StagingSchema>> mLookupMemoryDict;
2525
private int miLookupMemoryDictCount;
@@ -148,13 +148,13 @@ public static StagingTable initTable(StagingTable table)
148148
{
149149
case ColumnType.INPUT:
150150
// if there are no ranges in the list, that means the cell was "blank" and is not needed in the table row
151-
List<StringRange> ranges = splitValues(cellValue);
151+
List<Range> ranges = splitValues(cellValue);
152152
if (!(ranges.Count == 0))
153153
{
154154
tableRowEntity.addInput(col.getKey(), ranges);
155155

156156
// if there are key references used (values that reference other inputs) like {{key}}, then add them to the extra inputs list
157-
foreach (StagingStringRange range in ranges)
157+
foreach (StagingRange range in ranges)
158158
{
159159
if (DecisionEngineFuncs.isReferenceVariable(range.getLow()))
160160
extraInputs.Add(DecisionEngineFuncs.trimBraces(range.getLow()));
@@ -267,12 +267,12 @@ public static StagingEndpoint parseEndpoint(String endpoint)
267267
return new StagingEndpoint(type, value);
268268
}
269269

270-
// Parses a string in having lists of ranges into a List of StringRange objects
270+
// Parses a string in having lists of ranges into a List of Range objects
271271
// @param values String representing sets value ranges
272272
// @return a parsed list of string Range objects
273-
public static List<StringRange> splitValues(String values)
273+
public static List<Range> splitValues(String values)
274274
{
275-
List<StringRange> convertedRanges = new List<StringRange>();
275+
List<Range> convertedRanges = new List<Range>();
276276

277277
if (values != null)
278278
{
@@ -296,12 +296,12 @@ public static List<StringRange> splitValues(String values)
296296
{
297297
// don't worry about length differences if one of the parts is a context variable
298298
if (parts[0].Trim().Length != parts[1].Trim().Length && !DecisionEngineFuncs.isReferenceVariable(parts[0].Trim()) && !DecisionEngineFuncs.isReferenceVariable(parts[1].Trim()))
299-
convertedRanges.Add(new StagingStringRange(range.Trim(), range.Trim()));
299+
convertedRanges.Add(new StagingRange(range.Trim(), range.Trim()));
300300
else
301-
convertedRanges.Add(new StagingStringRange(parts[0].Trim(), parts[1].Trim()));
301+
convertedRanges.Add(new StagingRange(parts[0].Trim(), parts[1].Trim()));
302302
}
303303
else
304-
convertedRanges.Add(new StagingStringRange(range.Trim(), range.Trim()));
304+
convertedRanges.Add(new StagingRange(range.Trim(), range.Trim()));
305305
}
306306
}
307307
}
@@ -484,7 +484,7 @@ private HashSet<String> getAllInputValues(String tableId)
484484

485485
foreach (StagingTableRow row in table.getTableRows())
486486
{
487-
foreach (StagingStringRange range in row.getColumnInput(inputKey))
487+
foreach (StagingRange range in row.getColumnInput(inputKey))
488488
{
489489
if (range.getLow() != null)
490490
{

TNMStagingCSharp/TNMStagingCSharp/TNMStagingCSharp.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
<Compile Include="Src\DecisionEngine\Mapping.cs" />
8484
<Compile Include="Src\DecisionEngine\Output.cs" />
8585
<Compile Include="Src\DecisionEngine\Result.cs" />
86-
<Compile Include="Src\DecisionEngine\StringRange.cs" />
86+
<Compile Include="Src\DecisionEngine\Range.cs" />
8787
<Compile Include="Src\DecisionEngine\Table.cs" />
8888
<Compile Include="Src\DecisionEngine\TablePath.cs" />
8989
<Compile Include="Src\DecisionEngine\TableRow.cs" />
@@ -101,7 +101,7 @@
101101
<Compile Include="Src\Staging\Entities\StagingSchema.cs" />
102102
<Compile Include="Src\Staging\Entities\StagingSchemaInput.cs" />
103103
<Compile Include="Src\Staging\Entities\StagingSchemaOutput.cs" />
104-
<Compile Include="Src\Staging\Entities\StagingStringRange.cs" />
104+
<Compile Include="Src\Staging\Entities\StagingRange.cs" />
105105
<Compile Include="Src\Staging\Entities\StagingTable.cs" />
106106
<Compile Include="Src\Staging\Entities\StagingTablePath.cs" />
107107
<Compile Include="Src\Staging\Entities\StagingTableRow.cs" />

TNMStagingCSharp/TNMStaging_UnitTestApp/Src/DecisionEngine/Basic/BasicDataProvider.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class BasicDataProvider : IDataProvider
1313
{
1414

1515
private static String _MATCH_ALL_STRING = "*";
16-
private static BasicStringRange _MATCH_ALL_ENDPOINT = new BasicStringRange();
16+
private static BasicRange _MATCH_ALL_ENDPOINT = new BasicRange();
1717
private Dictionary<String, BasicTable> _tables = new Dictionary<String, BasicTable>();
1818
private Dictionary<String, BasicDefinition> _definitions = new Dictionary<String, BasicDefinition>();
1919

@@ -93,13 +93,13 @@ public void initTable(BasicTable table)
9393
{
9494
case ColumnType.INPUT:
9595
// if there are no ranges in the list, that means the cell was "blank" and is not needed in the table row
96-
List<BasicStringRange> ranges = splitValues(cellValue);
96+
List<BasicRange> ranges = splitValues(cellValue);
9797
if (!(ranges.Count == 0))
9898
{
9999
tableRowEntity.addInput(col.getKey(), ranges);
100100

101101
// if there are key references used (values that reference other inputs) like {{key}}, then add them to the extra inputs list
102-
foreach (BasicStringRange range in ranges)
102+
foreach (BasicRange range in ranges)
103103
{
104104
if (DecisionEngineFuncs.isReferenceVariable(range.getLow()))
105105
extraInputs.Add(DecisionEngineFuncs.trimBraces(range.getLow()));
@@ -181,7 +181,7 @@ public BasicEndpoint parseEndpoint(String endpoint)
181181
}
182182

183183
/**
184-
* Parses a string of values into a List of StringRange entities. The values can contain ranges and multiple values. Some examples might be:
184+
* Parses a string of values into a List of Range entities. The values can contain ranges and multiple values. Some examples might be:
185185
* <p>
186186
* 10
187187
* 10-14
@@ -192,9 +192,9 @@ public BasicEndpoint parseEndpoint(String endpoint)
192192
* @param values a string of values
193193
* @return a List of BasicStringRange objects
194194
*/
195-
protected List<BasicStringRange> splitValues(String values)
195+
protected List<BasicRange> splitValues(String values)
196196
{
197-
List<BasicStringRange> convertedRanges = new List<BasicStringRange>();
197+
List<BasicRange> convertedRanges = new List<BasicRange>();
198198

199199
if (values != null)
200200
{
@@ -214,16 +214,16 @@ protected List<BasicStringRange> splitValues(String values)
214214
// may need to revisit this issue later.
215215
String[] parts = range.Split("-".ToCharArray());
216216
if (parts.Length == 1)
217-
convertedRanges.Add(new BasicStringRange(parts[0].Trim(), parts[0].Trim()));
217+
convertedRanges.Add(new BasicRange(parts[0].Trim(), parts[0].Trim()));
218218
else if (parts.Length == 2)
219219
{
220220
if (parts[0].Trim().Length != parts[1].Trim().Length)
221-
convertedRanges.Add(new BasicStringRange(range.Trim(), range.Trim()));
221+
convertedRanges.Add(new BasicRange(range.Trim(), range.Trim()));
222222
else
223-
convertedRanges.Add(new BasicStringRange(parts[0].Trim(), parts[1].Trim()));
223+
convertedRanges.Add(new BasicRange(parts[0].Trim(), parts[1].Trim()));
224224
}
225225
else
226-
convertedRanges.Add(new BasicStringRange(range.Trim(), range.Trim()));
226+
convertedRanges.Add(new BasicRange(range.Trim(), range.Trim()));
227227
}
228228
}
229229
}

TNMStagingCSharp/TNMStaging_UnitTestApp/Src/DecisionEngine/Basic/BasicStringRange.cs renamed to TNMStagingCSharp/TNMStaging_UnitTestApp/Src/DecisionEngine/Basic/BasicRange.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace TNMStaging_UnitTestApp.Src.DecisionEngine.Basic
88
{
9-
public class BasicStringRange : StringRange
9+
public class BasicRange : Range
1010
{
1111

1212
private String _low;
@@ -16,7 +16,7 @@ public class BasicStringRange : StringRange
1616
/**
1717
* Construct a BasicString range that matches any string
1818
*/
19-
public BasicStringRange()
19+
public BasicRange()
2020
{
2121
_usesContext = false;
2222
}
@@ -26,7 +26,7 @@ public BasicStringRange()
2626
* @param low low value
2727
* @param high high value
2828
*/
29-
public BasicStringRange(String low, String high)
29+
public BasicRange(String low, String high)
3030
{
3131
if (low == null || high == null)
3232
throw new InvalidOperationException("Invalid range");

0 commit comments

Comments
 (0)