< BACKMake Note | BookmarkCONTINUE >
152015024128143245168232148039199167010047123209178152124239215162147034164218028208152157

Code Examples

Listing 6.1 Benchmark Extension (File benchmarkmodule.c)
 1: #include "<Python.h>"
 2:
 3: static PyObject *
 4: benchmark_generate(PyObject *self, PyObject *args);
 5: {
 6:   int index, number_of_arguments;
 7:   PyObject *numberslist = NULL;
 8:   PyObject *check_value = NULL;
 9:   PyFloatObject *aux_float = NULL;
10:   double element_value;
11:   double minimum_value = 100;
12:   double maximum_value = 0;
13:   char *exist_check;
14:
15:   if (!PyArg_ParseTuple (args, "OO", &numberslist, &check_value))
16:      return NULL;
17:
18:   if (!PyList_Check(numberslist))
19:   {
20:     PyErr_SetString(PyExc_TypeError, "Invalid list of values !");
21:     return NULL;
22:   }
23:
24:   if (!PyFloat_Check(check_value))
25:   {
26:     PyErr_SetString(PyExc_TypeError, "Invalid checking value !");
27:     return NULL;
28:   }
29:
30:   number_of_arguments = PyList_Size(numberslist);
31:   exist_check = "No";
32:
33:   for (index=0; index<number_of_arguments; index++)
34:   {
35:      aux_float = (PyFloatObject *) PyList_GetItem(numberslist, index);
36:      if (!PyFloat_Check(aux_float))
37:      {
38:         PyErr_SetString(PyExc_TypeError, "Invalid list value !");
39:         return NULL;
40:      }
41:      element_value = PyFloat_AsDouble(aux_float);
42:      if (element_value < 0 )
43:      {
44:         PyErr_SetString(PyExc_TypeError, "The values cannot be less than 0
            !");
45:         return NULL;
46:      }
47:
48:      if (element_value > 100 )
49:      {
50:         PyErr_SetString(PyExc_TypeError,
                     "The values cannot be greater than 100 !");
51:         return NULL;
52:      }
53:
54:      if (element_value < minimum_value)
55:          minimum_value = element_value;
56:
57:      if (element_value > maximum_value)
58:          maximum_value = element_value;
59:
60:      if (element_value == PyFloat_AsDouble(check_value))
61:          exist_check = "Yes";
62:   }
63:   return Py_BuildValue("(ffs)", minimum_value, maximum_value,
                              exist_check );
64: }
65:
66: static PyMethodDef benchmark_methods[] = {
67:       {"generate", benchmark_generate, METH_VARARGS, "Minimum Value,
             Maximum Value"},
68:       {NULL, NULL}
69: };
70:
71: DL_EXPORT(void) initbenchmark()
72: {
73:     Py_InitModule("benchmark", benchmark_methods);
74: }

Line 9: PyFloatObject is a subtype of PyObject.

Line 18: Checks whether the first argument is a list.

Line 24: Checks whether the type of the second argument is a float.

Line 26: Raises a TypeError exception.

Line 30: Returns the list's length.

Line 60: PyFloat_AsDouble converts a Python Float into a C double.

Next, you can see a small interaction with this program. To execute it, we have to pass two arguments: The first one is a list of numbers, and the second one is a float number. This program returns the minimum and maximum values from the list, along with a logical test that informs whether the float number is part of the list.

					
Python 1.5.2 (#0, May 30 2000, 00:16:14) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import benchmark
>>> benchmark.generate([1.1],1.1)
(1.1, 1.1, 'Yes')
>>> benchmark.generate([1,2,3],4.5)
(1.0, 3.0, 'No')
>>>

				

Wrapping C Functions

By wrapping functions, you can use C code files, without changing them. Every time you feel the need to include a C source code file in your Python project, it is necessary to create a special module that wraps its functions, and to include a reference to the file in the python15.dsp.

The next example wraps the functions stored in the cfunctions.c file.

Listing 6.2 File: cfunctions.c
#include <stdio.h>

void display_info(char *user, char *domain, char *country) {

   if (country == "USA")
       printf("%s@%s\n", user, domain);
   else
       printf("%s@%s.%s\n", user, domain, country);
}

int calc_year (int f_year, int m_year, int l_year) {
   int result;
   result = ((l_year + m_year + f_year) / 3);
   return result;
}
Listing 6.3 File: wrappermodule.c
 1: #include "Python.h"
 2:
 3: extern void display_info(char *, char *, char *);
 4: extern int calc_year(int, int, int);
 5:
 6: static PyObject *wrapper_display_info(PyObject *self, PyObject *args,
                                              PyObject *kwargs)
 7: {
 8:    char *user = "None";
 9:    char *domain = "None";
10:    char *country = "None";
11:    static char *keywords[] = {"user","domain","country",NULL};
12:
13:    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", keywords,
             &user, &domain, &country)){
14:       return NULL;
15:    }
16:
17:    display_info(user, domain, country);
18:    return Py_BuildValue("");
19: }
20:
21: static PyObject *wrapper_calc_year(PyObject *self, PyObject *args) {
22:    int f_year, m_year, l_year, result;
23:    if (!PyArg_ParseTuple(args, "iii", &f_year, &m_year, &l_year)) {
24:        return NULL;
25:    }
26:    result = calc_year(f_year, m_year, l_year);
27:    return Py_BuildValue("i", result);
28: }
29:
30: static PyMethodDef wrappermethods[] = {
31:    {"display_info", wrapper_display_info, METH_VARARGS|METH_KEYWORDS},
32:    {"calc_year", wrapper_calc_year, METH_VARARGS},
33:    {NULL, NULL}
34: };
35:
36: void initwrapper() {
37:    Py_InitModule("wrapper", wrappermethods);
38: }

Lines 3 and 4: Identify which functions are external to this file.

Line 11: Creates a dictionary of keywords to be accepted by the function.

Line 13: PyArg_ParseTupleAndKeywords() parses the Python-level parameters by accepting a third "PyObject *" parameter.

Line 31: The METH_VARARGS|METH_KEYWORDS clause makes it clear that keyword elements are expected.

Next, you can see a small interaction with this program. The first function builds an email address based on the information provided. The other one calculates the average age of a family of three people based on the number of years that are passed to the function.

						
Python 1.5.2 (#0, May 30 2000, 00:56:46) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import wrapper
>>> wrapper.display_info("andre2530","aol.com","br")
andre2530@aol.com.br
>>> wrapper.calc_year(10, 30, 35)
25
>>>

					


Last updated on 1/30/2002
Python Developer's Handbook, © 2002 Sams Publishing

< BACKMake Note | BookmarkCONTINUE >

© 2002, O'Reilly & Associates, Inc.