-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong behavior in float values using IronPython in a C# application #841
Comments
How are you passing the parameters from .NET to Python? It's hard to tell what your doing from the description above. An example to reproduce the issue would be helpful... |
Hi, thanks for your quick answer. Let me write some example of the code here, limited as by my company's IT policies ( I'm trying to include screenshots but is not possible for some reason) //Create the Runtime
public RuntimeProvider()
{
// set the callback to log errors.
var options = new Dictionary<string, object>();
options["Debug"] = false;
// Creates execution engine
this.myEngine = Python.CreateEngine(options);
// This is for debugging Python code
// this.myEngine.SetTrace(this.OnTraceback);
this.myScope = this.myEngine.CreateScope();
}
// Load the script
public void LoadScript(string scriptSource, bool sameScope, bool sourceIsFileName)
{
this.ScriptScope = this.RuntimeProvider.CreateScope();
ScriptSource source;
source = this.RuntimeProvider.Engine.CreateScriptSourceFromString(scriptSource);
ScriptSources.Add(source);
var compiled = source.Compile();
this.myExecutions.Add(compiled.Execute(this.ScriptScope));
}
// Proxy
private TcoAlgorithmProxy LoadAlgorithmInstance(string algorithmCode, string algorithmDescriptionBuilder)
{
var scriptLoader = new ScriptLoader();
var pythonInstance = this.LoadAlgorithm(algorithmCode, algorithmDescriptionBuilder, scriptLoader);
// Creates the proxy to comunicate the code with the other application domain
// This proxy is neccesary because the object that you want to sent to the other domain must intherit from MarshalByRefObject
var algorithm = new AlgorithmProxy(pythonInstance, scriptLoader.RuntimeProvider.Engine);
return algorithm;
}
// Call function
protected override double? GetValue(IClusterableFeature anomaly)
{
var ffsLoss = this.FfsAssessement.GetMaxIliFfsLoss(anomaly, lineType.Value, inBend.Value, pipeGrade.Value, anomaly.AddTolerance);
return ffsLoss.Value;
}
// Specific function call in python
public double GetMaxIliFfsLoss(
string lineType,
double wallThicknessInMeter,
double designFactor,
bool inBend,
string pofDefectClass,
double lengthInMeter,
double widthInMeter,
double depthPercentage,
double designPressureInMpa,
string pipeGrade,
double outerDiameterInMeter,
bool addTolerance)
{
return this.GetValue(
() => this.myPythonAlgorithmInstance.GetMaxIliFfsLoss(
lineType,
wallThicknessInMeter,
designFactor,
inBend,
wallThicknessInMeter.ToString("R"),
lengthInMeter,
widthInMeter,
depthPercentage,
designPressureInMpa,
pipeGrade,
outerDiameterInMeter,
addTolerance)); And finally the simplified code in Python that is being executed: def GetMaxIliFfsLoss(self,
lineType,
wallThicknessInMeter,
designFactor,
inBend,
pofDefectClass,
lengthInMeter,
widthInMeter,
depthPercentage,
designPressureInMpa,
pipeGrade,
outerDiameterInMeter,
addTolerance):
if not isinstance(wallThicknessInMeter, float):
culture = CultureInfo.CurrentCulture
number = 0.00950000
numberStr = number.ToString(culture.NumberFormat)
raise Exception("WT: " + str(wallThicknessInMeter), lineType,
type(wallThicknessInMeter),
"Float Number: ",
number,
"Float Number String",
numberStr,
"Convert From String To Float",
Double.Parse("0.0095"),
"Culture Number Format",
culture.NumberFormat,
designFactor,
inBend,
pofDefectClass,
float(pofDefectClass),
lengthInMeter,
widthInMeter,
depthPercentage,
addTolerance,
designPressureInMpa,
pipeGrade,
outerDiameterInMeter) And just using that RaiseError to print in the .NET Exception the values we identified the change to that very small numbers, not the desired ones. |
It's interesting that |
As we are iterating over several calls to the python functions, the code works well in the first ones but after that starts to fail and we could never have a full execution of the algorithm. The specific version of IronPython is 2.7.9. The solution is build in .NET framework 4.7.2. Seems also related with the Microsoft.Scripting 1.2.2.0. Thanks! |
Description
We are running a sandbox in a .NET windows application (.NET framework 4.7.2 and IronPython 2.7).
Once we call the execution of the specific script, they returned to us a DivisionByZero exception, because a normal decimal value we are sending from .NET are being converted to a very small number (1.03e-311), that causes the Zero Division issue.
Steps to Reproduce
Error returned:
"An error occured while executing the underlying Python script (Traceback (most recent call last): :: File "", line 98, in GetTheFailureMode :: File "", line 699, in GetMaxFfsLoss :: File "", line 2043, in GetMaxHoopLoss :: File "", line 2197, in GetHoopMsop :: ZeroDivisionError: Attempted to divide by zero.)"
Parameters from .NET:
"
addToIerance = true
depthPercentage = 7
designFactor = 0.72
designPressureInMpa = 14.1
inBend = false
lengthInMeter = 0.0689999999999884
lineType = "Hybrid"
outerDiameterInMeter = 0.1683
pipeGrade = "X60"
pofDefectCIass = "General"
wallThicknessInMeter = 0.0095
widthInMeter = 0.038
"
Values recovered in Python just calling the method:
"
An error occured while executing the underlying Python script (Traceback (most recent call last): :: File "", line 148, in GetMaxIliFfsLoss :: Exception: (
'WT: 6.95238308496e-310',
'Hybrid', <type 'float'>,
'Float Number: ', 1.034294700449062e-311,
'Float Number String', '0.0095',
'Convert From String To Float', 1.034294700449062e-311,
'Culture Number Format', <System.Globalization.NumberFormatInfo object at 0x000000000000002B [System.Globalization.NumberFormatInfo]>, 1.0343456283479938e-311,
False,
'0.0095',
1.034294700449062e-311,
1.0353302339822869e-311,
1.034294700449062e-311,
1.0334119502000876e-311,
True,
1.0338363493581819e-311,
'X60',
1.0349533679427365e-311))
"
Culture info:
NumberFormat
CurrencyDecimaIDigits = 2
CurrencyDecimalSeparator = "."
CurrencyGroupSeparator = ","
Expected behavior: Do not convert the normal float parameters to very small numbers.
Actual behavior: The float values are converted to a very small numbers that causes a Zero Division Exception.
Versions
IronPython 2.7
.NET Framework 4.7.2
The text was updated successfully, but these errors were encountered: