2

I'm currently doing the following to create and execute a simple python calculation, using DLR:

ScriptRuntime runtime = Python.CreateRuntime();
ScriptEngine engine = runtime.GetEngine("py");

MemoryStream ms = new MemoryStream();
runtime.IO.SetOutput(ms, new StreamWriter(ms));

ScriptSource ss = engine.CreateScriptSourceFromString("print 1+1", SourceCodeKind.InteractiveCode);

CompiledCode cc = ss.Compile();
cc.Execute();

int length = (int)ms.Length;
Byte[] bytes = new Byte[length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(bytes, 0, (int)ms.Length);
string result = Encoding.GetEncoding("utf-8").GetString(bytes, 0, (int)ms.Length);

Console.WriteLine(result);

Which prints '2' to the console, but;

I want to get the result of 1 + 1 without having to print it (as that seems to be a costly operation). Anything I assign the result of cc.Execute() to is null. Is there any other way I can get the resulting variables from Execute()?

I am also trying to find a way to pass in parameters, i.e. so the result is arg1 + arg2 and have no idea how to do that; the only other overload for Execute takes ScriptScope as a parameter, and I've never used python before. Can anyone help?

[Edit] The answer to both questions: (Desco's accepted as pointed me in the right direction)

ScriptEngine py = Python.CreateEngine();
ScriptScope pys = py.CreateScope();

ScriptSource src = py.CreateScriptSourceFromString("a+b");
CompiledCode compiled = src.Compile();

pys.SetVariable("a", 1);
pys.SetVariable("b", 1);
var result = compiled.Execute(pys);

Console.WriteLine(result);

2 Answers 2

6

You can either evaluate expression in Python and return its result (1) or assign value to some variable in scope and later pick it (2):

    var py = Python.CreateEngine();

    // 1
    var value = py.Execute("1+1");
    Console.WriteLine(value);

    // 2
    var scriptScope = py.CreateScope();
    py.Execute("a = 1 + 1", scriptScope);
    var value2 = scriptScope.GetVariable("a");
    Console.WriteLine(value2);
Sign up to request clarification or add additional context in comments.

Comments

3

You definitely don't have to print it. I'd expect there to be a way of just evaluating an expression, but if not there are alternatives.

For example, in a dynamic graphing demo I wrote a long time ago (and unfortunately no longer have the code for) I created a function, using the python:

def f(x):
    return x * x

and then got f out of the script scope like this:

Func<double, double> function;
if (!scope.TryGetVariable<Func<double, double>>("f", out function))
{
    // Error handling here
}
double step = (maxInputX - minInputX) / 100;
for (int i = 0; i < 101; i++)
{
    values[i] = function(minInputX + step * i);
}

You could do something similar if you want to evaluate the expression multiple times, or just assign the result to a variable if you only need to evaluate it once.

2 Comments

The example link is broken
@Aron: Yup, unfortunately I think that was in the 2nd edition, and I lost the code when updating the site. (I've a suspicion that it didn't work fully with later versions of the DLR, but it's a long time ago.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.