📄 cls_example.cpp
字号:
/*
This file is part of Orange.
Orange is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Orange is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Orange; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Authors: Janez Demsar, Blaz Zupan, 1996--2002
Contact: janez.demsar@fri.uni-lj.si
*/
#include "orange.hpp"
class TMLClassDefinition;
extern TMLClassDefinition MLDef_Domain;
extern TMLClassDefinition MLDef_Variable;
#include "vars.hpp"
#include "domain.hpp"
#include "examples.hpp"
#include "cls_value.hpp"
#include "cls_example.hpp"
#include "cls_orange.hpp"
#include "lib_kernel.hpp"
#include "converts.hpp"
#include "externs.px"
DATASTRUCTURE(Example, TPyExample, 0)
bool convertFromPythonExisting(PyObject *lst, TExample &example)
{
PDomain dom=example.domain;
if (PyOrExample_Check(lst)) {
const TExample &orex = PyExample_AS_ExampleReference(lst);
if (orex.domain != dom)
dom->convert(example, orex);
else
example = orex;
return true;
}
if (!PyList_Check(lst)) {
PyErr_Format(PyExc_TypeError, "invalid argument type (expected list, got '%s)", lst ? lst->ob_type->tp_name : "None");
return false;
}
if (int(dom->variables->size()) != PyList_Size(lst)) {
PyErr_Format(PyExc_IndexError, "invalid list size (%i items expected)", dom->variables->size());
return false;
}
int pos=0;
TExample::iterator ei(example.begin());
PITERATE(TVarList, vi, dom->variables) {
PyObject *li=PyList_GetItem(lst, pos++);
if (!li)
PYERROR(PyExc_SystemError, "can't read the list", false);
if (PyOrValue_Check(li))
if (PyValue_AS_Variable(li) ? (PyValue_AS_Variable(li) != *vi) : (PyValue_AS_Value(li).varType=!(*vi)->varType) ) {
PyErr_Format(PyExc_TypeError, "wrong value type for attribute no. %i (%s)", pos, (*vi)->name.c_str());
return false;
}
else
*(ei++)=PyValue_AS_Value(li);
else {
if (PyString_Check(li))
(*vi)->str2val(string(PyString_AsString(li)), *(ei++));
else if ((*vi)->varType==TValue::INTVAR) {
if (PyInt_Check(li))
*(ei++)=TValue(int(PyInt_AsLong(li)));
else {
PyErr_Format(PyExc_TypeError, "attribute no. %i (%s) is ordinal, string value expected", pos, (*vi)->name.c_str());
return false;
}
}
else if ((*vi)->varType==TValue::FLOATVAR) {
float f;
if (PyNumber_ToFloat(li, f))
*(ei++) = TValue(f);
else {
PyErr_Format(PyExc_TypeError, "attribute no. %i (%s) is continuous, float value expected", pos, (*vi)->name.c_str());
return false;
}
}
else
ei++;
}
}
return true;
}
bool convertFromPython(PyObject *lst, TExample &example, PDomain dom)
{ example=TExample(dom);
return convertFromPythonExisting(lst, example);
}
int cc_Example(PyObject *obj, void *ptr)
{ if (!PyOrExample_Check(obj))
return 0;
*(PExample *)(ptr) = PyExample_AS_Example(obj);
return 1;
}
int ccn_Example(PyObject *obj, void *ptr)
{ if (obj == Py_None) {
*(PExample *)(ptr) = PExample();
return 1;
}
else
return cc_Example(obj, ptr);
}
int ptr_Example(PyObject *obj, void *ptr)
{ if (!PyOrExample_Check(obj))
return 0;
*(TExample **)(ptr) = PyExample_AS_Example(obj).getUnwrappedPtr();
return 1;
}
int ptrn_Example(PyObject *obj, void *ptr)
{ if (obj == Py_None) {
*(TExample **)(ptr) = NULL;
return 1;
}
else
return ptr_Example(obj, ptr);
}
PyObject *Example_FromExample(PyTypeObject *type, PExample example, POrange lock)
{ TPyExample *self=PyObject_GC_New(TPyExample, type);
self->example.init();
self->lock.init();
self->example = example;
self->lock = lock;
PyObject_GC_Track(self);
return (PyObject *)self;
}
void Example_dealloc(TPyExample *self)
{ self->lock.~POrange();
self->example.~PExample();
/* Should not call tp_free if it is a reference
Destructor is also called by exit proc, not by wrapped */
if (PyObject_IsPointer(self)) {
PyObject_GC_UnTrack((PyObject *)self);
self->ob_type->tp_free((PyObject *)self);
}
}
int Example_traverse(TPyExample *self, visitproc visit, void *arg)
{ PVISIT(self->lock)
if (!self->lock) // don't visit if it's a reference!
PVISIT(self->example);
return 0;
}
int Example_clear(TPyExample *self)
{ self->lock=POrange();
self->example=PExample();
return 0;
}
bool readBoolFlag(PyObject *keywords, char *flag);
CONSTRUCTOR_KEYWORDS(Example, "filterMetas")
PyObject *Example_new(PyTypeObject *type, PyObject *args, PyObject *keywords) BASED_ON(ROOT, "(domain, [list of values])")
{ PyTRY
PyObject *list=PYNULL;
PDomain dom;
if (PyArg_ParseTuple(args, "O&|O", cc_Domain, &dom, &list)) {
if (list && PyOrExample_Check(list)) {
PExample ex = mlnew TExample(dom, PyExample_AS_Example(list).getReference(), readBoolFlag(keywords, "filterMetas"));
return Example_FromWrappedExample(ex);
}
PyObject *example = Example_FromDomain(dom);
if (list) {
if (PyList_Check(list) && PyList_Size(list) && PyOrExample_Check(PyList_GET_ITEM(list, 0))) {
TExampleList elist;
PyObject *iterator = PyObject_GetIter(list);
PyObject *item = PyIter_Next(iterator);
for(; item; item = PyIter_Next(iterator)) {
if (!PyOrExample_Check(item)) {
Py_DECREF(item);
break;
}
elist.push_back(PyExample_AS_Example(item));
Py_DECREF(item);
}
Py_DECREF(iterator);
if (item)
raiseError("invalid elements in list for example join");
else {
PExample ex = mlnew TExample(dom, PExampleList(elist));
return Example_FromWrappedExample(ex);
}
}
else if (!convertFromPythonExisting(list, PyExample_AS_ExampleReference(example))) {
Py_DECREF(example);
return PYNULL;
}
}
return example;
}
PyErr_Clear();
PExample example;
if (PyArg_ParseTuple(args, "O&", cc_Example, &example)) {
PExample ex = mlnew TExample(example.getReference());
return Example_FromWrappedExample(ex);
}
PYERROR(PyExc_TypeError, "domain and (optionally) list arguments accepted", PYNULL);
PyCATCH
}
int getMetaIdFromPy(PExample example, PyObject *index, PVariable &var)
{ if (PyInt_Check(index)) {
int idx=PyInt_AsLong(index);
var=example->domain->getMetaVar(idx, false); // it may also be NULL
return idx;
}
else if (PyString_Check(index)) {
TMetaDescriptor const *desc=example->domain->metas[string(PyString_AsString(index))];
if (!desc) {
PyErr_Format(PyExc_IndexError, "invalid meta variable name '%s'", PyString_AsString(index));
return 0;
}
var=desc->variable;
return desc->id;
}
else if (PyOrVariable_Check(index)) {
var = PyOrange_AsVariable(index);
int idx = example->domain->getMetaNum(var, false);
if (idx == ILLEGAL_INT)
PYERROR(PyExc_IndexError, "invalid meta variable", 0);
return idx;
}
PYERROR(PyExc_IndexError, "invalid meta variable", 0);
}
int weightIndex(const TExample &example, PyObject *pyindex)
{
if (pyindex == Py_None)
return 0;
if (PyInt_Check(pyindex))
return (int)PyInt_AsLong(pyindex);
PVariable var = varFromArg_byDomain(pyindex, example.domain);
if (!var)
PYERROR(PyExc_TypeError, "invalid arguments or unknown attribute", ILLEGAL_INT);
return example.domain->getVarNum(var);
}
PyObject *Example_reference(TPyExample *pex) PYARGS(METH_NOARGS, "unique reference (pointer to) the object")
{
return PyInt_FromLong(int(&PyExample_AS_ExampleReference(pex)));
}
PyObject *Example_getweight(TPyExample *pex, PyObject *pyindex) PYARGS(METH_O, "(id) -> weight; Returns example's weight")
{
PyTRY
const TExample &example = PyExample_AS_ExampleReference(pex);
int index = weightIndex(example, pyindex);
if (index == ILLEGAL_INT)
return PYNULL;
if (!index)
return PyFloat_FromDouble(1.0);
TValue val = example.getMeta(index);
if (val.isSpecial() || (val.varType!=TValue::FLOATVAR))
PYERROR(PyExc_TypeError, "invalid weight", PYNULL);
return PyFloat_FromDouble((double)val.floatV);
PyCATCH
}
PyObject *Example_setweight(TPyExample *pex, PyObject *args) PYARGS(METH_VARARGS, "(id[, weight]); Sets example's weight to given value")
{ PyTRY
PyObject *pyindex;
float weight = 1;
if (!PyArg_ParseTuple(args, "O|f:setweight", &pyindex, &weight))
return PYNULL;
TExample &example = PyExample_AS_ExampleReference(pex);
int index = weightIndex(example, pyindex);
if (index == ILLEGAL_INT)
return PYNULL;
if (index>0)
PYERROR(PyExc_IndexError, "Example.setweight: invalid weight id", PYNULL);
if (index)
example.setMeta(index, TValue(weight));
RETURN_NONE;
PyCATCH
}
PyObject *Example_removeweight(TPyExample *pex, PyObject *pyindex) PYARGS(METH_O, "(id); Removes examples's weight")
{ PyTRY
TExample &example = PyExample_AS_ExampleReference(pex);
int index = weightIndex(example, pyindex);
if (index == ILLEGAL_INT)
return PYNULL;
if (index>0)
PYERROR(PyExc_IndexError, "Example.setweight: invalid weight id", PYNULL);
if (index)
example.removeMeta(index);
RETURN_NONE;
PyCATCH
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -