Skip to content
Related Articles

Related Articles

Save Article
Improve Article
Save Article
Like Article

Issues with using C code in Python | Set 2

  • Last Updated : 20 Mar, 2019

Prerequisite: Issues with using C code in Python | Set 1

The DoubleArrayType class can handle the situation of Python having different forms like array, numpy array, list, tuple. In this class, a single method from_param() is defined. This method takes a single parameter and narrow it down to a compatible ctypes object (a pointer to a ctypes.c_double, in the example).

 Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.  

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning - Basic Level Course

In the code below, the typename of the parameter is extracted and used to dispatch to a more specialized method. For example, if a list is passed, the typename is list and a method from_list() is invoked. For lists and tuples, the from_list() method performs a conversion to a ctypes array object.

Code #1 :

nums = [1, 2, 3]
a = (ctypes.c_double * len(nums))(*nums)
print ("a : ", a)
print ("\na[0] : ", a[0])
print ("\na[1] : ", a[1])
print ("\na[2] : ", a[2])

Output :

a : <__main__.c_double_Array_3 object at 0x10069cd40>

a[0] : 1.0

a[1] : 2.0

a[2] : 3.0

The from_array() method extracts the underlying memory pointer and casts it to a ctypes pointer object for array objects.

Code #2 :

import array
arr = array.array('d', [1, 2, 3])
print ("arr : ", arr)
ptr_ = a.buffer_info()
print ("\nptr :", ptr)
print ("\n", ctypes.cast(ptr, ctypes.POINTER(ctypes.c_double)))

Output :

arr : array('d', [1.0, 2.0, 3.0])

ptr : 4298687200

<__main__.LP_c_double object at 0x10069cd40> 

The from_ndarray() shows comparable conversion code for numpy arrays. By defining the DoubleArrayType class and using it in the type signature of avg(), the function can accept a variety of different array-like inputs.

Code #3 :

# libraries
import sample
import array
import numpy
print("Average of list : ", sample.avg([1, 2, 3]))
print("\nAverage of tuple : ", sample.avg((1, 2, 3)))
print(\nAverage of array : ", sample.avg(array.array('d', [1, 2, 3])))
print(\nAverage of numpy array : ", sample.avg(numpy.array([1.0, 2.0, 3.0])))

Output :

Average of list : 2.0

Average of tuple : 2.0 

Average of array : 2.0

Average of numpy array : 2.0

To work with a simple C structure, simply define a class that contains the appropriate fields and types as shown in the code below. After defining, the class in type signatures as well as in code that needs to instantiate and work with the structures, can be used.

Code #4 :

class Point(ctypes.Structure):
    _fields_ = [('x', ctypes.c_double),
                ('y', ctypes.c_double)]
point1 = sample.Point(1, 2)
point2 = sample.Point(4, 5)
print ("pt1 x : ", point1.x)
print ("\npt1 y : ", point1.y)
print ("\nDistance between pt1 and pt2 : ",
           sample.distance(point1, point2))

Output :

pt1 x : 1.0

pt1 y : 2.0

Distance between pt1 and pt2 : 4.242640687119285

My Personal Notes arrow_drop_up
Recommended Articles
Page :