2010-12-07 5 views
1

Poursuivant sur ma question précédente au Executing a C program in python?; ce qui renvoie un de C pour obtenir des données utilisables en Python ??Que devrait retourner C à Python call()?

Actuellement, mon programme retourne ceci:

int main (int argc, char *argv[]) 
{ 
    spa_data spa; //declare the SPA structure 
    int result; 
    float min, sec; 

    //enter required input values into SPA structure 

    spa.year   = 2003; 
    spa.month   = 10; 
    spa.day   = 17; 
    spa.hour   = 12; 
    spa.minute  = 30; 
    spa.second  = 30; 
    spa.timezone  = -7.0; 
    spa.delta_t  = 67; 
    spa.longitude  = -105.1786; 
    spa.latitude  = 39.742476; 
    spa.elevation  = 1830.14; 
    spa.pressure  = 820; 
    spa.temperature = 11; 
    spa.slope   = 30; 
    spa.azm_rotation = -10; 
    spa.atmos_refract = 0.5667; 
    spa.function  = SPA_ALL; 

    //call the SPA calculate function and pass the SPA structure 

    result = spa_calculate(&spa); 

    if (result == 0) //check for SPA errors 
    { 
     //display the results inside the SPA structure 

     printf("Julian Day: %.6f\n",spa.jd); 
     printf("L:    %.6e degrees\n",spa.l); 
     printf("B:    %.6e degrees\n",spa.b); 
     printf("R:    %.6f AU\n",spa.r); 
     printf("H:    %.6f degrees\n",spa.h); 
     printf("Delta Psi:  %.6e degrees\n",spa.del_psi); 
     printf("Delta Epsilon: %.6e degrees\n",spa.del_epsilon); 
     printf("Epsilon:  %.6f degrees\n",spa.epsilon); 
     printf("Zenith:  %.6f degrees\n",spa.zenith); 
     printf("Azimuth:  %.6f degrees\n",spa.azimuth); 
     printf("Incidence:  %.6f degrees\n",spa.incidence); 

     min = 60.0*(spa.sunrise - (int)(spa.sunrise)); 
     sec = 60.0*(min - (int)min); 
     printf("Sunrise:  %02d:%02d:%02d Local Time\n", (int)(spa.sunrise), (int)min, (int)sec); 

     min = 60.0*(spa.sunset - (int)(spa.sunset)); 
     sec = 60.0*(min - (int)min); 
     printf("Sunset:  %02d:%02d:%02d Local Time\n", (int)(spa.sunset), (int)min, (int)sec); 

    } else printf("SPA Error Code: %d\n", result); 

    return 0; 
} 

J'ai lu quelques articles sur struct et Pythons'pack, mais je ne pouvais pas comprendre tout à fait encore, alors peut-être quelqu'un peut pointer la bonne direction.

+0

Après avoir regardé le code C, il serait probablement assez facile de générer un module en l'utilisant, sans avoir à l'appeler du tout. –

+0

Merci pour votre réponse; Pouvez-vous développer sur ce sujet? –

Répondre

2

Le moyen le plus simple de retourner des données à Python serait de les imprimer dans un format raisonnable. Celui que vous avez décent, mais un simple CSV serait un peu plus facile.

Ensuite, vous allez utiliser subprocess.Popen:

p = subprocess.Popen(["./spa", "args", "to", "spa"], stdout=subprocess.PIPE) 
(stdout, stderr) = p.communicate() 
data = parse_output(stdout.read()) 

Et, par exemple, si la sortie était CSV:

printf("%.6f, %.6e, %.6e, %.6f, %.6f, %.6e, %.6e, %.6f, %.6f, %.6f, %.6f\n", 
     spa.jd, spa.l, spa.b, spa.r, spa.h, spa.del_psi, spa.del_epsilon, spa.epsilon, 
     spa.zenith, spa.azimuth, spa.incidenc) 

Alors parse_output pourrait être écrit:

def parse_output(datastr): 
    return [ float(value.strip()) for value in datastr.split(",") 

maintenant , cela fait un tas d'hypothèses ... Plus précisément:

  • que vous avez affaire à un nombre assez restreint de données (Popen.communicate() stocke la sortie dans la mémoire avant de le retourner à votre programme)
  • que vous ne serez pas trop souvent appelez ./spa (générant un processus est très, très lent)

Mais si cela vous convient, cela fonctionnera pour vous.

+0

Merci! Cela a vraiment fonctionné instantanément! @edit: Pour l'instant, cela m'a vraiment aidé. Jusqu'à ce jour, je n'avais jamais utilisé C, donc je vais m'inquiéter des performances et de l'utilisation de la mémoire plus tard;) Encore une fois, merci! –

+0

Heureux que je pourrais aider :) Aussi, c'est l'esprit avec la performance et l'utilisation de la mémoire! –