C Numpy / C API的示例
/* dtlsmodule.c */
#include <math.h>
#include <stdio.h>
#include <Python.h>
#include "structmember.h"
#include <numpy/arrayobject.h>
/* ================================================================= MACROS */
#define QUOTE(s) # s /* turn s into string "s" */
#define NDIM_CHECK(a, expected_ndim, rt_error) \
if (PyArray_NDIM(a) != expected_ndim) { \
PyErr_Format(PyExc_ValueError, \
"%s array is %d-dimensional, but expected to be %d-dimensional", \
QUOTE(a), PyArray_NDIM(a), expected_ndim); \
return rt_error; \
}
#define DIM_CHECK(a, dim, expected_length, rt_error) \
if (dim > PyArray_NDIM(a)) { \
PyErr_Format(PyExc_ValueError, \
"%s array has no %d dimension (max dim. is %d)", \
QUOTE(a), dim, PyArray_NDIM(a)); \
return rt_error; \
} \
if (PyArray_DIM(a, dim) != expected_length) { \
PyErr_Format(PyExc_ValueError, \
"%s array has wrong %d-dimension=%d (expected %d)", \
QUOTE(a), dim, PyArray_DIM(a, dim), expected_length); \
return rt_error; \
}
#define TYPE_CHECK(a, tp, rt_error) \
if (PyArray_TYPE(a) != tp) { \
PyErr_Format(PyExc_TypeError, \
"%s array is not of correct type (%d)", QUOTE(a), tp); \
return rt_error; \
}
#define CALLABLE_CHECK(func, rt_error) \
if (!PyCallable_Check(func)) { \
PyErr_Format(PyExc_TypeError, \
"%s is not a callable function", QUOTE(func)); \
return rt_error; \
}
#define DIND1(a, i) *((double *) PyArray_GETPTR1(a, i))
#define DIND2(a, i, j) *((double *) PyArray_GETPTR2(a, i, j))
#define DIND3(a, i, j, k) *((double *) Py_Array_GETPTR3(a, i, j, k))
#define IIND1(a, i) *((int *) PyArray_GETPTR1(a, i))
#define IIND2(a, i, j) *((int *) PyArray_GETPTR2(a, i, j))
#define IIND3(a, i, j, k) *((int *) Py_Array_GETPTR3(a, i, j, k))
#define DEF_PYARRAY_GETTER(funcname, selftype, valname) \
static PyObject * \
funcname(selftype *self, void *closure) \
{ \
Py_INCREF(self->valname); \
return PyArray_Return(self->valname); \
}
#define DEF_PYARRAY_SETTER(funcname, selftype, valname, arraydim) \
static int \
funcname(selftype *self, PyObject *value, void *closure) \
{ \
if (value == NULL) { \
PyErr_SetString( PyExc_TypeError, \
"Cannot delete the last attribute"); \
return -1; \
} \
if ( PyArray_Check(value) != 1 ){ \
PyErr_Format( PyExc_ValueError, \
"value is not of type numpy array"); \
return -1; \
} \
if ( PyArray_NDIM(value) != arraydim ){ \
PyErr_Format( PyExc_ValueError, \
"value array's dimension %d != arraydim", \
PyArray_NDIM(value)); \
return -1; \
} \
if ( PyArray_TYPE(value) != NPY_DOUBLE ){ \
PyErr_Format( PyExc_ValueError, \
"value array is not of type 'Python float'"); \
return -1; \
} \
Py_DECREF(self->valname); \
Py_INCREF(value); \
self->valname = (PyArrayObject *) value; \
return 0; \
}
/* ========================================================== DTLSys struct */
typedef struct {
PyObject_HEAD
PyArrayObject *wt;
PyArrayObject *bs;
PyArrayObject *xt;
} DTLSys;
/* ============================================================ Declaration */
static void DTLSys_dealloc(DTLSys* self);
static PyObject * DTLSys_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static int DTLSys_init(DTLSys *self, PyObject *args, PyObject *kwds);
static PyMemberDef DTLSys_members[] = {
{NULL} /* Sentinel */
};
static PyObject * DTLSys_get_wt(DTLSys *self, void *closure);
static int DTLSys_set_wt(DTLSys *self, PyObject *value, void *closure);
static PyObject * DTLSys_get_bs(DTLSys *self, void *closure);
static int DTLSys_set_bs(DTLSys *self, PyObject *value, void *closure);
static PyObject * DTLSys_get_xt(DTLSys *self, void *closure);
static int DTLSys_set_xt(DTLSys *self, PyObject *value, void *closure);
static PyGetSetDef DTLSys_getseters[] = {
{"wt", (getter)DTLSys_get_wt, (setter)DTLSys_set_wt, "Matrix", NULL},
{"bs", (getter)DTLSys_get_bs, (setter)DTLSys_set_bs, "Vector", NULL},
{"xt", (getter)DTLSys_get_xt, (setter)DTLSys_set_xt, "Vector time sequence", NULL},
{NULL} /* Sentinel */
};
static int _DTLSys_check_sys_conf(DTLSys *self);
static PyObject * DTLSys_check_sys_conf(DTLSys *self);
static PyObject * DTLSys_make_tms(DTLSys *self, PyObject *args);
static PyMethodDef DTLSys_methods[] = {
{"check_sys_conf", (PyCFunction)DTLSys_check_sys_conf, METH_NOARGS, "Check if system config is correct"},
{"make_tms", (PyCFunction)DTLSys_make_tms, METH_VARARGS, "Make TiMe Series"},
{NULL} /* Sentinel */
};
static PyTypeObject DTLSysType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"dtls.DTLSys", /*tp_name*/
sizeof(DTLSys), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)DTLSys_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"DTLSys objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
DTLSys_methods, /* tp_methods */
DTLSys_members, /* tp_members */
DTLSys_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)DTLSys_init, /* tp_init */
0, /* tp_alloc */
DTLSys_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initdtls(void)
{
PyObject* m;
if (PyType_Ready(&DTLSysType) < 0){ return; }
m = Py_InitModule3("dtls", module_methods,
"Example module that creates an extension type.");
if (m == NULL){ return; }
Py_INCREF(&DTLSysType);
PyModule_AddObject(m, "DTLSys", (PyObject *)&DTLSysType);
import_array(); /* required NumPy initialization */
}
/* ================================================================= Define */
static void
DTLSys_dealloc(DTLSys* self)
{
Py_XDECREF(self->wt);
Py_XDECREF(self->bs);
Py_XDECREF(self->xt);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
DTLSys_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
DTLSys *self;
npy_intp wt_dims[2] = {0,0};
npy_intp bs_dims[1] = {0};
npy_intp xt_dims[2] = {0,0};
self = (DTLSys *)type->tp_alloc(type, 0);
if (self != NULL) {
self->wt = (PyArrayObject *) PyArray_SimpleNew(2, wt_dims, NPY_DOUBLE);
if (self->wt == NULL){ Py_DECREF(self); return NULL; }
self->bs = (PyArrayObject *) PyArray_SimpleNew(1, bs_dims, NPY_DOUBLE);
if (self->bs == NULL){ Py_DECREF(self); return NULL; }
self->xt = (PyArrayObject *) PyArray_SimpleNew(2, xt_dims, NPY_DOUBLE);
if (self->xt == NULL){ Py_DECREF(self); return NULL; }
}
return (PyObject *)self;
}
static int
DTLSys_init(DTLSys *self, PyObject *args, PyObject *kwds)
{
PyArrayObject *wt, *bs, *tmp;
int t_max;
npy_intp xt_dims[2] = {0,0};
if ( !PyArg_ParseTuple( args, "O!O!i:DTLSys.init",
&PyArray_Type, &wt,
&PyArray_Type, &bs,
&t_max)
) {
return -1; /* PyArg_ParseTuple has raised an exception */
}
if ( wt==NULL || bs==NULL ) {
printf("getting args failed\n"); return -1;
}
if ( t_max < 0 ) {
printf("t_max (3rd arg) must be positive int\n"); return -1;
}
xt_dims[0] = PyArray_DIM(wt,0);
xt_dims[1] = t_max;
self->xt = (PyArrayObject *) PyArray_SimpleNew(2, xt_dims, NPY_DOUBLE);
if (self->xt == NULL){
printf("creating %dx%d array failed\n", (int)xt_dims[0], (int)xt_dims[1]);
return -1;
}
tmp = self->wt; Py_INCREF(wt); self->wt = wt; Py_DECREF(tmp);
tmp = self->bs; Py_INCREF(bs); self->bs = bs; Py_DECREF(tmp);
if( _DTLSys_check_sys_conf(self) != 0 ){
PyErr_Clear();
printf("DTLSys config is not correct!\n");
}
return 0;
}
DEF_PYARRAY_GETTER( DTLSys_get_wt, DTLSys, wt )
DEF_PYARRAY_SETTER( DTLSys_set_wt, DTLSys, wt, 2 )
DEF_PYARRAY_GETTER( DTLSys_get_bs, DTLSys, bs )
DEF_PYARRAY_SETTER( DTLSys_set_bs, DTLSys, bs, 1 )
DEF_PYARRAY_GETTER( DTLSys_get_xt, DTLSys, xt )
DEF_PYARRAY_SETTER( DTLSys_set_xt, DTLSys, xt, 2 )
static int
_DTLSys_check_sys_conf(DTLSys *self)
{
int vecsize;
NDIM_CHECK(self->wt, 2, -1); TYPE_CHECK(self->wt, NPY_DOUBLE, -1);
NDIM_CHECK(self->bs, 1, -1); TYPE_CHECK(self->bs, NPY_DOUBLE, -1);
vecsize = PyArray_DIM(self->wt,0);
if (vecsize != PyArray_DIM(self->wt,1) ) {
PyErr_Format( PyExc_ValueError, "self.wt must be square");
return -1;
}
if (vecsize != PyArray_DIM(self->bs,0) ) {
PyErr_Format( PyExc_ValueError, "self.bs and self.wt[0] must be same shape");
return -1;
}
if (vecsize != PyArray_DIM(self->xt,0) ) {
PyErr_Format( PyExc_ValueError, "self.xt[,0] and self.wt[0] must be same shape");
return -1;
}
return 0;
}
static PyObject *
DTLSys_check_sys_conf(DTLSys *self)
{
if( _DTLSys_check_sys_conf(self) != 0 ){
PyErr_Clear();
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
}
static PyObject *
DTLSys_make_tms(DTLSys *self, PyObject *args)
{
int vecsize, t_max, i, j, t;
if( _DTLSys_check_sys_conf(self) != 0 ){
return NULL;
}
vecsize = PyArray_DIM(self->wt,0);
t_max = PyArray_DIM(self->xt,1);
for (t = 1; t < t_max; t++) {
for (i = 0; i < vecsize; i++) {
DIND2(self->xt,i,t) = DIND1(self->bs,i);
for (j = 0; j < vecsize; j++) {
DIND2(self->xt,i,t) += DIND2(self->wt,i,j) * DIND2(self->xt,j,t-1);
}
}
}
return Py_BuildValue(""); /* return None */
}
/*
# setup.py
# build command : python setup.py build build_ext --inplace
from numpy.distutils.core import setup, Extension
import os, numpy
name = 'dtls'
sources = ['dtlsmodule.c']
include_dirs = [
numpy.get_include()
]
setup( name = name,
include_dirs = include_dirs,
ext_modules = [Extension(name, sources)]
)
*/
/*
# test code
import scipy, pylab
import dtls
t_max = 200
rot = 5.0 * 2.0 * scipy.pi / t_max
wt = scipy.array([
[ scipy.cos(rot), scipy.sin(rot) ],
[ -scipy.sin(rot), scipy.cos(rot) ]
])
wt *= 0.99
bs = scipy.array([0.,0.])
a=dtls.DTLSys( wt, bs, t_max )
a.xt[0,0] = 0
a.xt[1,0] = 1
a.make_tms()
pylab.clf()
pylab.plot(a.xt[0],a.xt[1], 'o-')
# Check calculation
print (scipy.dot( a.wt, a.xt[:,0] ) + a.bs) - a.xt[:,1]
*/
C 用于python扩展模块的C API
==> sonmodule.h <==
typedef struct {
PyObject_HEAD
PyObject *str;
int num;
} Son;
#define MAKE_SON_NEW(self, type, rt_error) \
(self) = (Son *)(type)->tp_alloc((type), 0); \
if ((self) == rt_error) { return rt_error; } \
\
(self)->str = PyString_FromString(""); \
if ((self)->str == rt_error) { \
Py_DECREF((self)); \
return rt_error; \
} \
\
(self)->num = 0
#ifdef __SON_MODULE
/* ---------- inclue form sonmodule.c ---------- */
static PyTypeObject SonType;
#else
/* ---------- inclue form othere module to use api ---------- */
/* store all api here */
void **Son_API;
/* set alias for easy call */
#define SonType (*(PyTypeObject *)Son_API[0])
#define Son_info (*(PyObject *(*) (Son *))Son_API[1])
static int _import_son(void)
{
PyObject *son = PyImport_ImportModule("son");
PyObject *c_api = NULL;
if (son == NULL){ return -1; }
/* load c api */
c_api = PyObject_GetAttrString(son, "_Son_API");
if (c_api == NULL) {Py_DECREF(son); return -1;}
if (PyCObject_Check(c_api)) {
Son_API = (void **)PyCObject_AsVoidPtr(c_api);
}
Py_DECREF(c_api);
Py_DECREF(son);
if (Son_API == NULL) return -1;
return 0;
}
#define import_son() \
{ \
if (_import_son() < 0) { \
PyErr_Print(); \
PyErr_SetString( PyExc_ImportError, \
"son failed to import"); \
return; \
} \
}
#endif
/* __SONMODULE */
==> sonmodule.c <==
#include <Python.h>
#include "structmember.h"
#define __SON_MODULE
#include "sonmodule.h"
#undef __SON_MODULE
static void
Son_dealloc(Son* self)
{
Py_XDECREF(self->str);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
Son_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
Son *self;
MAKE_SON_NEW(self, type, NULL);
return (PyObject *)self;
}
static int
Son_init(Son *self, PyObject *args, PyObject *kwds)
{
PyObject *str=NULL, *tmp;
static char *kwlist[] = {"str", "num", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|Si", kwlist,
&str,
&self->num)){
return -1;
}
if (str) {
tmp = self->str;
Py_INCREF(str);
self->str = str;
Py_DECREF(tmp);
}
return 0;
}
static PyMemberDef Son_members[] = {
{"num", T_INT, offsetof(Son, num), 0, "Sone num"},
{NULL} /* Sentinel */
};
static PyObject *
Son_getstr(Son *self, void *closure)
{
Py_INCREF(self->str);
return self->str;
}
static int
Son_setstr(Son *self, PyObject *value, void *closure)
{
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete the str attribute");
return -1;
}
if (! PyString_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"The str attribute value must be a string");
return -1;
}
Py_DECREF(self->str);
Py_INCREF(value);
self->str = value;
return 0;
}
static PyGetSetDef Son_getseters[] = {
{"str", (getter)Son_getstr, (setter)Son_setstr, "str", NULL},
{NULL} /* Sentinel */
};
static PyObject *
Son_info(Son *self)
{
PyObject *dic = PyDict_New();
if (dic == NULL) {
printf("creating dict failed\n");
return NULL;
}
Py_INCREF(self->str);
PyDict_SetItemString(dic, "str", self->str);
PyDict_SetItemString(dic, "num", PyLong_FromLong( self->num ));
return dic;
}
static PyMethodDef Son_methods[] = {
{"info", (PyCFunction)Son_info, METH_NOARGS, "return info dic"},
{NULL} /* Sentinel */
};
static PyTypeObject SonType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"son.Son", /*tp_name*/
sizeof(Son), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Son_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Son objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Son_methods, /* tp_methods */
Son_members, /* tp_members */
Son_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Son_init, /* tp_init */
0, /* tp_alloc */
Son_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
};
/* ---------- insert object into api array ---------- */
void *Son_API[] = {
(void *) &SonType,
(void *) Son_info,
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initson(void)
{
PyObject *m, *d;
PyObject *c_api;
if (PyType_Ready(&SonType) < 0){ return; }
m = Py_InitModule3("son", module_methods,
"Son Class");
if (m == NULL){ goto err; }
Py_INCREF(&SonType);
PyModule_AddObject(m, "Son", (PyObject *)&SonType);
/* ----- set api to module ----- */
d = PyModule_GetDict(m);
if (!d){ goto err; }
c_api = PyCObject_FromVoidPtr((void *)Son_API, NULL);
if (c_api == NULL){ goto err; }
PyDict_SetItemString(d, "_Son_API", c_api);
Py_DECREF(c_api);
return;
err:
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError,
"cannot load son module.");
}
return;
}
==> fathermodule.c <==
#include <Python.h>
#include "structmember.h"
#include "sonmodule.h"
typedef struct {
PyObject_HEAD
Son *son;
} Father;
static void
Father_dealloc(Father* self)
{
Py_XDECREF(self->son);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
Father_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
Father *self;
self = (Father *)type->tp_alloc(type, 0);
if (self == NULL) { return NULL; }
MAKE_SON_NEW(self->son, &SonType, NULL);
return (PyObject *)self;
}
static int
Father_init(Father *self, PyObject *args, PyObject *kwds)
{
return 0;
}
static PyMemberDef Father_members[] = {
{NULL} /* Sentinel */
};
static PyObject *
Father_getson(Father *self, void *closure)
{
Py_INCREF(self->son);
return (PyObject *)self->son;
}
static int
Father_setson(Father *self, PyObject *value, void *closure)
{
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete the son attribute");
return -1;
}
if (! PyObject_TypeCheck(value, &SonType)) {/* SonType is from Son_API! */
PyErr_SetString(PyExc_TypeError,
"The str attribute value must be a Son");
return -1;
}
Py_DECREF(self->son);
Py_INCREF(value);
self->son = (Son *)value;
return 0;
}
static PyGetSetDef Father_getseters[] = {
{"son", (getter)Father_getson, (setter)Father_setson, "son", NULL},
{NULL} /* Sentinel */
};
static PyObject *
Father_info(Father *self)
{
PyObject *dic = PyDict_New();
if (dic == NULL) {
printf("creating dict failed\n");
return NULL;
}
PyDict_SetItemString(dic, "son",
Son_info(self->son));/* Son_info is from Son_API! */
return dic;
}
static PyMethodDef Father_methods[] = {
{"info", (PyCFunction)Father_info, METH_NOARGS, "return info dic"},
{NULL} /* Sentinel */
};
static PyTypeObject FatherType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"father.Father", /*tp_name*/
sizeof(Father), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Father_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Father objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Father_methods, /* tp_methods */
Father_members, /* tp_members */
Father_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Father_init, /* tp_init */
0, /* tp_alloc */
Father_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initfather(void)
{
PyObject* m;
if (PyType_Ready(&FatherType) < 0){ return; }
m = Py_InitModule3("father", module_methods,
"Father Class");
if (m == NULL){ return; }
Py_INCREF(&FatherType);
PyModule_AddObject(m, "Father", (PyObject *)&FatherType);
import_son();
}
==> setup.py <==
# python setup.py build build_ext --inplace
import sys
import os
from distutils.core import setup, Extension
son_module = Extension(
'son',
define_macros = [],
include_dirs = [],
libraries = [],
library_dirs = [],
extra_compile_args = [],
sources = ['sonmodule.c'])
father_module = Extension(
'father',
define_macros = [],
include_dirs = [],
libraries = [],
library_dirs = [],
extra_compile_args = [],
sources = ['fathermodule.c'])
setup(
name = 'storage',
version = '1.0',
description = '',
ext_modules = [son_module, father_module] )
==> test.txt <==
>>> import son
>>> sn = son.Son()
>>> import father
>>> fr = father.Father()
>>> sn.num = 12
>>> sn.str = "son str"
>>> sn.info()
{'num': 12L, 'str': 'son str'}
>>> fr.son
<son.Son object at 0xb7cd5070>
>>> fr.son.info()
{'num': 0L, 'str': ''}
>>> fr.info()
{'son': {'num': 0L, 'str': ''}}
>>> fr.son = sn
>>> fr.info()
{'son': {'num': 12L, 'str': 'son str'}}
C 在目录上操作
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
//coded by cobra90nj
int main(int argc, char **argv) {
struct dirent *drs;
struct stat buf;
DIR *dir;
if (argc == 1) {
dir = opendir(".");
}
else {
dir = opendir(argv[1]);
}
while ((drs = readdir(dir)) != NULL) {
stat(drs->d_name, &buf);
printf("\033[0;20;31m Nome File: %s\n Ultima modifica: %s\n Dimensione file: %d B \n", drs->d_name, ctime(&(buf.st_mtime)), buf.st_size);
}
closedir(dir);
}
C C #define宏使用预处理器中的连接运算符生成注释
#define _AT_ ;/ ## /
C 心跳
#include <avr/io.h>
#include <util/delay.h>
// Some macros that make the code more readable
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_input(portdir,pin) portdir &= ~(1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
#define LON 1
#define LOF 0
#define LED_COUNT 12
uint8_t led_table[] =
{
LOF, PB0, PB1,
LOF, PB1, PB0,
LOF, PB0, PB2,
LOF, PB2, PB0,
LOF, PB0, PB4,
LOF, PB4, PB0,
LOF, PB1, PB2,
LOF, PB2, PB1,
LOF, PB1, PB4,
LOF, PB4, PB1,
LOF, PB2, PB4,
LOF, PB4, PB2
};
void clear_leds()
{
set_input(DDRB, PB0);
set_input(DDRB, PB1);
set_input(DDRB, PB2);
set_input(DDRB, PB4);
}
void set_led(uint8_t index, uint8_t state)
{
uint8_t i = (index * 3);
uint8_t s = led_table[i];
uint8_t p1 = led_table[i + 1];
uint8_t p2 = led_table[i + 2];
set_output(DDRB, p1);
set_output(DDRB, p2);
if(state == LON)
{
output_low(PORTB, p1);
output_high(PORTB, p2);
}
else
{
output_low(PORTB, p1);
output_low(PORTB, p2);
}
}
void delay_10us(uint8_t us)
{
uint8_t delay_count = F_CPU / 2000000;
volatile uint8_t i;
while (us != 0) {
for (i=0; i != delay_count; i++);
us--;
}
}
void do_pwm_fade(uint8_t index, uint8_t start_duty, uint8_t end_duty, uint8_t rate)
{
uint8_t duty;
uint8_t j;
duty = start_duty;
while (duty != end_duty)
{
for (j = 0; j < rate; j++)
{
set_led(index, LON);
delay_10us(duty);
set_led(index, LOF);
delay_10us(255-duty);
}
if (start_duty < end_duty)
duty++;
else
duty--;
}
}
int main(void)
{
// initialize the direction of the B port to be outputs
// on the 3 pins that have LEDs connected
while(1)
{
for(int i=0; i < LED_COUNT; i++)
{
clear_leds();
do_pwm_fade(i, 0, 255, 1);
do_pwm_fade(i, 255, 0, 1);
}
}
}
C Makefile para SRGP
CC = gcc
GCCFLAGS = -fpcc-struct-return
CFLAGS = -g
INCLUDE = -I/usr/include/srgp
LDLIBS = -lsrgp -lX11 -lm
LDFLAGS = -L/usr/lib
$(PROG):
$(CC) $(GCCFLAGS) $(INCLUDE) $(CFLAGS) $(PROG).c $(LDFLAGS) $(LDLIBS) -o $(PROG)
C tetris.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL/SDL.h>
#include <SDL/SDL_gfx.h>
#include "io.c"
#define WAIT_TIME 700 //miliseconds
#define PIECE_SIZE 5 //in blocks
#define MAP_HEIGHT 20 // in blocks
#define MAP_WIDTH 10 // in blocks
#define MAP_POSITION 320 //px
#define BLOCK_SIZE 16 //px
#define MAP_LINE_WIDTH 5 //px
int current_x = 0, current_y = 0;
int piece [PIECE_SIZE] [PIECE_SIZE] = {0};
int map [MAP_WIDTH] [MAP_HEIGHT] = {0};
#define TYPES 2
int pieces [ TYPES ][PIECE_SIZE][PIECE_SIZE] = {
{
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 1, 2, 1, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 0, 0}
}, {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 1, 2, 1, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 0}
}
};
int i, j; /* VaeRY BAD. */
int screen_height = get_screen_height(); /* BAD. */
unsigned long time_1;
unsigned long time_2;
/* ----------------------- IS_GAME_OVER ---------------------------------- */
/* If the first line has blocks, then, game over. */
int is_game_over()
{
for ( i = 0; i < MAP_WIDTH; i++ )
if ( map[i][0] )
return 1;
return 0;
}
/* ----------------------- STORE_PIECE ----------------------------------- */
/* Store each !=0 block of the piece into the board. */
void store_piece ()
{
int i1, i2, j1, j2;
for ( i1 = current_x, i2 = 0; i1 < current_x + PIECE_SIZE; i1++, i2++)
for ( j1 = current_y, j2 = 0; j1 < current_y + PIECE_SIZE; j1++, j2++)
if ( piece[j2][i2] )
map[i1][j1] = 1;
}
/* ----------------------- DELETE_LINE ----------------------------------- */
/* Delete a line of the board by moving all above lines down */
/* pY: Vertical position in blocks of the line to delete */
void delete_line (int y)
{
for ( j = y; j > 0; j--)
for ( i = 0; i < MAP_WIDTH; i++)
map[i][j] = map[i][j-1];
}
/* ----------------------- DELETE_POSSIBLE_LINES ------------------------- */
/* Delete all the lines that should be removed. */
void delete_possible_lines ()
{
for ( j = 0; j < MAP_HEIGHT; j++) {
for ( i = 0; i < MAP_WIDTH; i++ ) {
if (map[i][j] != 1)
break;
i++;
}
if ( i == MAP_WIDTH )
DeleteLine(j);
}
}
/* ----------------------- IS_POSSIBLE_MOVEMENT -------------------------- */
int is_possible_movement ( )
{
int i1, i2, j1, j2;
for ( i1 = current_x, i2 = 0; i1 < current_x + PIECE_SIZE; i1++, i2++)
for ( j1 = current_y, j2 = 0; j1 < current_y + PIECE_SIZE; j1++, j2++) {
/* Check limits */
if ( i1 < 0 || i1 > MAP_WIDTH - 1 || j1 > MAP_HEIGHT - 1 )
if ( piece[j2][i2] )
return 0;
/* Check collisions with a block already stored in the map. */
if (j1 >= 0)
if ( piece[j2][i2] && !map[i1][j1] )
return 0;
}
return 1; /* No collision. Movement IS possible. */
}
/* ------------------------ ROTATE_PIECE --------------------------------- */
void rotate_piece ()
{
int piece_2 [PIECE_SIZE] [PIECE_SIZE] = {0};
for ( i = 0; i < PIECE_SIZE; i++ )
for ( j = 0; j < PIECE_SIZE; j++ )
piece_2[i][j] = piece[i][j];
for ( i = 0; i < PIECE_SIZE; i++ )
for ( j = 0; j < PIECE_SIZE; j++ )
piece[i][j] = piece_2[j][i];
}
/* ------------------------ CREATE_NEW_PIECE ----------------------------- */
void create_new_piece()
{
for( i = 0; i < PIECE_SIZE; i++ )
for( j = 0; j < PIECE_SIZE; j++ )
piece[i][j] = pieces [rand(TYPES)] [i] [j];
/* ADD function that puts piece in right position. */
current_y = 0; /* TODO */
current_x = MAP_WIDTH / 2;
/* may be some rotation...*/
/* + generate next(). later. */
}
/* ------------------------ DRAW_SHADOW ---------------------------------- */
void draw_shadow()
{
/* TODO. 2 */
}
/* ------------------------ DRAW_NEXT_PIECE ------------------------------ */
void draw_next_piece()
{
/* TODO. 1 */
}
/* ------------------------ ADD_RUBBISH_TO_MAP --------------------------- */
void add_rubbish_to_map()
{
/* TODO. later. */
}
/* ----------------------- DRAW_PIECE ------------------------------------ */
void draw_piece ()
{
color piece_color; /* Color of the block. */
/* Obtain the position in pixel in the screen of the block we want to draw. */
int mPixelsY = (screen_height - (BLOCK_SIZE * MAP_HEIGHT)) + (current_y * BLOCK_SIZE);
int mPixelsX = ( MAP_POSITION - (BLOCK_SIZE * (MAP_WIDTH / 2)) ) + (current_x * BLOCK_SIZE);
/* Travel the matrix of blocks of the piece and draw the blocks that are filled. */
for ( i = 0; i < PIECE_SIZE; i++ )
for ( j = 0; j < PIECE_SIZE; j++ ) {
switch ( piece[j][i] ) {
case 1: piece_color = GREEN; break; /* For each block (except the pivot). */
case 2: piece_color = BLUE; break; /* For the pivot. */
default: piece_color = YELLOW;break;
}
if ( piece[j][i] )
draw_rectangle (
mPixelsX + i * BLOCK_SIZE,
mPixelsY + j * BLOCK_SIZE,
(mPixelsX + i * BLOCK_SIZE) + BLOCK_SIZE - 1,
(mPixelsY + j * BLOCK_SIZE) + BLOCK_SIZE - 1,
piece_color );
}
}
/* ----------------------- DRAW_MAP -------------------------------------- */
void draw_map ()
{
/* Calculate the limits of the board in pixels. */
int X1 = MAP_POSITION - (BLOCK_SIZE * (MAP_WIDTH / 2)) - 1;
int X2 = MAP_POSITION + (BLOCK_SIZE * (MAP_WIDTH / 2));
int Y = screen_height - (BLOCK_SIZE * MAP_HEIGHT);
/* Rectangles that delimits the board. */
draw_rectangle ( X1 - BOARD_LINE_WIDTH, Y, X1, screen_height - 1, BLUE);
draw_rectangle ( X2, Y, X2 + BOARD_LINE_WIDTH, screen_height - 1, BLUE);
/* Drawing the blocks that are already stored in the board. */
X1++;
for ( i = 0; i < MAP_WIDTH; i++ )
for ( j = 0; j < MAP_HEIGHT; j++ )
if ( map(i, j) )
draw_rectangle (
X1 + i * BLOCK_SIZE,
Y + j * BLOCK_SIZE,
(X1 + i * BLOCK_SIZE) + BLOCK_SIZE - 1,
(Y + j * BLOCK_SIZE) + BLOCK_SIZE - 1,
RED );
}
/* ----------------------- MAIN ------------------------------------------ */
int main()
{
add_rubbish_to_map(); /* TODO */
create_new_piece(); /* First piece. */
/* Get the actual clock milliseconds. */
time_1 = SDL_GetTicks();
/* ----- Main Loop --------------------------------------------------------- */
while ( !is_key_down(SDLK_ESCAPE) ) {
/* ----- Draw -------------------------------------------------------------- */
clear_screen ();
draw_map ();
draw_piece ();
draw_next_piece (); /* LATER. */
draw_shadow (); /* TODO */
update_screen (); /* Put the graphic context in the screen. */
/* ----- Input ------------------------------------------------------------- */
int key = poll_key();
switch (key) {
case (SDLK_RIGHT):
current_x++;
if ( !is_possible_movement() )
current_x--;
break;
case (SDLK_LEFT):
current_x--;
if ( ! )
current_x++;
break;
#if 0
case (SDLK_DOWN):
current_y++;
if ( !is_possible_movement() )
current_y--;
break;
#endif
case (SDLK_DOWN):
/* Check collision from up to down. */
while ( is_possible_movement() )
current_y++;
current_y--;
store_piece ();
delete_possible_lines ();
if ( is_game_over()) {
puts( "GAME OVER" );
get_key();
exit(0);
}
create_new_piece();
break;
case (SDLK_UP):
rotate_piece();
if ( !is_possible_movement() ) {
/* Stupid hack... =( */
rotate_piece();
rotate_piece();
rotate_piece();
}
break;
default:
puts( "Suka. <, >, A, V." );
break;
}
/* ----- Vertical movement ------------------------------------------------- */
time_2 = SDL_GetTicks();
if ( (time_2 - time_1) > WAIT_TIME ) {
current_y++;
if ( !is_game_over() ) {
store_piece ();
delete_possible_lines ();
if ( is_game_over() ) {
puts( "GAME OVER" );
get_key();
exit(0);
}
create_new_piece();
}
time_1 = SDL_GetTicks();
}
} /* while ( !is_key_down(SDLK_ESCAPE) ) */
return 0;
}
C 分析文字
#include <stdio.h>
#include <malloc.h>
int main() {
const int l_block = 1024;
FILE* input_text_file;
long n = 0, i = 0, j = 0;
int meet_comma = 0;
long file_lengh;
char* buffer;
int num_block;
input_text_file = fopen( "../../additional_files/en.txt", "r" );
if ( !input_text_file ) {
puts( "Can't open file!" );
return 1;
}
fseek( input_text_file, 0, SEEK_END );
file_lengh = ftell( input_text_file );
buffer = (char*) malloc( (file_lengh + 1) * sizeof(char) );
num_block = file_lengh / l_block;
fseek( input_text_file, 0, SEEK_SET );
fread( buffer, l_block, num_block + 1, input_text_file );
buffer[file_lengh] = '\0';
/* ----------------------------- PROCESSING ------------------------------ */
while( buffer[i]) {
switch ( buffer[i] ) {
case ',':
meet_comma = 1;
break;
case '.':
case '!':
case '?':
if ( !meet_comma ) /* ЕÑли запÑтой небыло. */
for ( j = n; j <= i; j++ )
putchar( buffer[j] );
meet_comma = 0;
n = i + 1;
break;
default: break;
}
i++;
}
/* ------------------------------------------------------------------------- */
fclose ( input_text_file );
free(buffer);
puts("");
return 0;
}
C 从文件中加载或保存一块内存
void*loadfile(const char*const s){
FILE*f=fopen(s,"rb");
if(f){
fseek(f,0,SEEK_END);
{
const int ml=ftell(f);
if(ml){
char*m=malloc(ml);
if(m){
rewind(f);
fread(m,1,ml,f);
fclose(f);
return m;
}
}
}
}
return 0;
}
int savefile(const char*const s,const void*const m,const int ml){
FILE*f=fopen(s,"wb");
if(f){
int ok=fwrite(m,1,ml,f)==ml;
fclose(f);
return ok;
}
return 0;
}
C RSA
/* rsa.c */
#include <gmp.h>
#include <stdio.h>
#include <assert.h>
/* проверÑет, ÑвлÑетÑÑ Ð»Ð¸ чиÑло проÑтым. ЕÑли нет, то делает таковым. */
/* ПроÑтоÌе чиÑÐ»Ð¾Ì Ñто натуральное чиÑло,
которое имеет ровно 2 различных Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ (только 1 и Ñамоё ÑебÑ). */
void check_for_prime(mpz_ptr p)
{
int forprimep = mpz_probab_prime_p (p, 50);
while (forprimep == 0) {
mpz_add_ui (p, p, 1);
forprimep = mpz_probab_prime_p (p, 50);
};
}
const int SIZE = 512; /* Размер ключей. */
/* -------------------------------- MAIN --------------------------------- */
int main (int argc, char* argv[])
{
mpz_t p, q;
/* Ð˜Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ€Ð°Ð½Ð´Ð¾Ð¼Ð° */
gmp_randstate_t state;
gmp_randinit_default(state);
/* 1. ГенерируетÑÑ Ñлучайные проÑтые чиÑла p и q */
mpz_init2(p,SIZE);
mpz_urandomb(p, state, SIZE);
check_for_prime(p);
mpz_init2(q,SIZE);
mpz_urandomb(q, state, SIZE);
check_for_prime(q);
puts("p = ");
mpz_out_str (stdout, 10, p);
puts("\nq = ");
mpz_out_str (stdout, 10, q);
/* 2. ВычиÑлÑетÑÑ Ð¸Ñ… произведение n = pq */
mpz_t n;
mpz_init(n);
mpz_mul(n,p,q);
puts("\nn = ");
mpz_out_str (stdout, 10, n);
/* 3. ВычиÑлÑетÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ функции Ðйлера от чиÑла n.
Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ðйлера ( phi(n), где n — натуральное чиÑло )
равна количеÑтву натуральных чиÑел, не больших n и взаимно проÑÑ‚Ñ‹Ñ… Ñ Ð½Ð¸Ð¼. */
mpz_t fi;
mpz_init(fi);
mpz_t p_m, q_m;
mpz_init(p_m);
mpz_init(q_m);
mpz_sub_ui(p_m, p, 1);
mpz_sub_ui(q_m, q, 1);
mpz_mul(fi, p_m, q_m);
puts("\nfi = ");
mpz_out_str (stdout, 10, fi);
/* 4. ВыбираетÑÑ Ñ†ÐµÐ»Ð¾Ðµ чиÑло e, взаимно проÑтое Ñо значением функции fi
Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¹ раÑÑ‚Ñ‘Ñ‚ Ñ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸ÐµÐ¼ количеÑтва ненулевых
битов в двоичном предÑтавлении открытой ÑкÑпоненты e.
Чтобы увеличить ÑкороÑÑ‚ÑŒ шифрованиÑ, значение e
чаÑто выбирают равным 17, 257 или 65537 — проÑтым чиÑлам,
двоичное предÑтавление которых Ñодержит лишь две единицы:
17 = 0x11, 257 = 0x101, 65537 = 0x10001 (проÑтые чиÑла Ферма). */
int possible_values[] = {
17, 257, 65537
};
mpz_t e;
mpz_init(e);
mpz_t gcd;
mpz_init(gcd);
int i = 0;
for (; i < 3; ++i)
{
mpz_set_ui(e,possible_values[i]);
mpz_gcd(gcd, e, fi);
int compgcd = mpz_cmp_ui(gcd, 1);
if (compgcd == 0)
break;
}
assert(i != 3); /* выбор был Ñделан */
puts("\ne = ");
mpz_out_str (stdout, 10, e);
/* 5. ВычиÑлÑетÑÑ Ñ‡Ð¸Ñло d мультипликативное обратное к чиÑлу e по модулю fi */
mpz_t d;
mpz_init(d);
mpz_invert(d, e, fi);
puts("\nd = ");
mpz_out_str (stdout, 10, d);
/* Пара P = (e,n) публикуетÑÑ Ð² качеÑтве открытого ключа RSA */
/* Пара S = (d,n) играет роль Ñекретного ключа RSA */
/* ------------------------------------------------------------------------- */
/* Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ. (Ð’Ñе переменные имеют приÑтавку 's_') */
/* Открытый текÑÑ‚ */
/* Ð’ качеÑтве текÑта возьмем рандомное чиÑло. Так или иначе, текÑÑ‚
необходимо привеÑти к какому-то чиÑлу */
mpz_t s_M;
mpz_init2(s_M,SIZE / 2);
mpz_urandomb(s_M, state, SIZE / 2);
puts("\ns_M = ");
mpz_out_str (stdout, 10, s_M);
/* Создаем цифровую подпиÑÑŒ sigma Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñвоего Ñекретного ключа S */
mpz_t s_sigma;
mpz_init(s_sigma);
mpz_powm(s_sigma, s_M, d, n);
puts("\ns_sigma = ");
mpz_out_str (stdout, 10, s_sigma);
/* ПроверÑем подлинноÑÑ‚ÑŒ подпиÑи (Pa должно равнÑÑ‚ÑŒÑÑ M) */
mpz_t s_Pa;
mpz_init(s_Pa);
mpz_powm(s_Pa, s_sigma, e, n);
puts("\ns_Pa = ");
mpz_out_str (stdout, 10, s_Pa);
int compgcd = mpz_cmp(s_M, s_Pa);
if (compgcd == 0) {
puts("\ns_M == s_Pa");
}
else {
puts("\ns_M != s_Pa");
}
/* ------------------------------------------------------------------------- */
/* Шифрование. */
mpz_t M;
mpz_init2 (M,SIZE / 2);
// mpz_urandomb (M, state, SIZE / 2);
mpz_set_ui(M, 11);
puts ("\nM = ");
mpz_out_str (stdout, 10, M);
/* Шифрование. */
mpz_t Pa;
mpz_init (Pa);
mpz_powm (Pa, M, e, n);
puts ("\nPa = ");
mpz_out_str (stdout, 10, Pa);
/* Дешифрование. */
mpz_t Sa;
mpz_init (Sa);
mpz_powm(Sa, Pa, d, n);
puts("\nSa = ");
mpz_out_str (stdout, 10, Sa);
/* Проверка. */
if (mpz_cmp(M, Sa) == 0) {
puts("\nM == Sa");
}
else {
puts("\nM != Sa");
}
/* ------------------------------------------------------------------------- */
/* Text encription. */
int i = 0;
mpz_t text [32];
mpz_t Pa_2 [32];
char text_M[] = "some text.";
puts("");
puts("initial text:");
puts (text_M);
puts("");
puts("codes:");
for ( i=0; text_M [i] != '\0'; i++ ) {
mpz_init ( Pa_2[i] );
mpz_init ( text[i] );
mpz_set_ui ( text[i], text_M[i] );
mpz_powm ( Pa_2[i], text[i], e, n );
mpz_out_str ( stdout, 10, Pa_2[i] );
puts ("");
}
/* ------------------*/
mpz_t Sa_2[32];
puts("");
puts("result text:");
for ( i=0; text_M [i] != '\0'; i++ ) {
mpz_init ( Sa_2[i] );
mpz_powm ( Sa_2[i], Pa_2[i], d, n );
putchar ( (char)mpz_get_si(Sa_2[i]) );
}
/* ------------------*/
return 0;
}