1

I want to integrate code python (hierarchical clustering algorithm) with code C#.

(The idea of ​​the project is to divide similar people and put them into classes using the algorithm. We use language c# (asp.net) and want a method to link the algorithm to the code.)

closed as off-topic by gnat, maple_shaft Jan 22 at 13:31

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking for assistance in explaining, writing or debugging code are off-topic here. These can be asked on Stack Overflow if they include the desired behavior, a specific problem or error, and the shortest code necessary to reproduce it in the question (see Minimal, Complete, and Verifiable Example)." – gnat, maple_shaft
If this question can be reworded to fit the rules in the help center, please edit the question.

  • IronPython is worth considering, assuming your Python code works with it. It then allows you to bundle that Python code directly in your .NET app. – David Arno Jan 22 at 12:16
  • 1
    @DavidArno Unlikely. Hierarchical clustering is probably the one from scikit-learn and that lib does not work with IronPython. Imo that'S the problem of IronPython: It works for the language, but does not capture the bazillion of packages. And without them, python looses a lot – Christian Sauer Jan 22 at 12:18
7

Ok, we have done this. I would advise you to use a microservice architecture: e.g. your code calls a Python Rest Service which computes the data and returns the result. Or if the operation is long (which clustering is most of the time) use a message queue as broker between the two services.

You can directly call python code from C# using the library http://pythonnet.github.io/. When it works, it works amazingly well. If not, you are in a world of hurt - most especially it sometimes fails to load (deterministig at least, but fun to diagnose). Furthermore, due to python GIL, you are restricted to one Python process. Also, marshalling data between Python and C# is nontrivial and leads to interesting debugging sessions, e.g. trying to poke into the insides of an IENumerable in Python...

Overall, the microservice pattern is easier to build, to reason about,to debug and to build. Only drawback is that you have now 2 or 3 moving parts, which can be a deal breaker.

  • Did you investigate the feasibility of IronPython at the time? – John Go-Soco Jan 22 at 12:15
  • 1
    @JohnGo-Soco yes, we did. We used the whole shebang to drive a data science application, so access to numpy, pandas, scipy, scikit-learn etc. was very important. And not all of these libs where supported at the time. I do not think that this has improved, IronPython looks pretty dead to me – Christian Sauer Jan 22 at 12:16
  • I figured that'd be the case. – John Go-Soco Jan 22 at 12:18
1

This article may prove insightful: https://code.msdn.microsoft.com/windowsdesktop/C-and-Python-interprocess-171378ee

It basically details that you write a python script which uses command-line arguments and prints a return value. Your C# code then calls this script with the required arguments and gets the value back from it.

using System; 
using System.IO; 
using System.Diagnostics; 

namespace CallPython 
{ 
    /// <summary> 
    /// Used to show simple C# and Python interprocess communication 
    /// Author      : Ozcan ILIKHAN 
    /// Created     : 02/26/2015 
    /// Last Update : 04/30/2015 
    /// </summary> 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            // full path of python interpreter 
            string python = @"C:\Continuum\Anaconda\python.exe"; 

            // python app to call 
            string myPythonApp = "sum.py"; 

            // dummy parameters to send Python script 
            int x = 2; 
            int y = 5; 

            // Create new process start info 
            ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python); 

            // make sure we can read the output from stdout 
            myProcessStartInfo.UseShellExecute = false; 
            myProcessStartInfo.RedirectStandardOutput = true; 

            // start python app with 3 arguments  
            // 1st arguments is pointer to itself,  
            // 2nd and 3rd are actual arguments we want to send 
            myProcessStartInfo.Arguments = myPythonApp + " " + x + " " + y; 

            Process myProcess = new Process(); 
            // assign start information to the process 
            myProcess.StartInfo = myProcessStartInfo; 

            Console.WriteLine("Calling Python script with arguments {0} and {1}", x,y); 
            // start the process 
            myProcess.Start(); 

            // Read the standard output of the app we called.  
            // in order to avoid deadlock we will read output first 
            // and then wait for process terminate: 
            StreamReader myStreamReader = myProcess.StandardOutput; 
            string myString = myStreamReader.ReadLine(); 

            /*if you need to read multiple lines, you might use: 
                string myString = myStreamReader.ReadToEnd() */           

            // wait exit signal from the app we called and then close it. 
            myProcess.WaitForExit(); 
            myProcess.Close(); 

            // write the output we got from python app 
            Console.WriteLine("Value received from script: " + myString); 

        } 
    } 
} 
  • You would definitely add the "-u" command line parameter otherwise python buffers it's output, which can be annoying. Also "-m" might be required when you use a module. Also, I dislike this approach. It works, but is not really stable or scalable, especially in a web context. A clustering algorithm takes a lot of memory, so starting a few of them gets funny fast – Christian Sauer Jan 22 at 13:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.