⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cls_example.cpp

📁 orange源码 数据挖掘技术
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
    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 + -