Changeset 3997:6fa178887403 in orange


Ignore:
Timestamp:
07/19/07 13:14:17 (7 years ago)
Author:
janezd <janez.demsar@…>
Branch:
default
Convert:
5d7c71d60a72584df6df25d63a7b7918cc400869
Message:
  • two attributes with the same name and type loaded from different files are now the same attribute
  • values of discrete attribtues loaded from files are now sorted alphabetically
  • attributes are constructed in scripts are different attributes, but there is a function getExisting, which returns an existing attribute, if it's there
  • pickling bugs, which caused the above changes, are presumably fixed
  • user-specified flags for loaders (dontCheckStored etc) are now treated inconsistently and have unknown effects
  • DomainDepots still exist
Location:
source/orange
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • source/orange/assistant.cpp

    r708 r3997  
    141141 
    142142  TDomainDepot::TAttributeDescription classDescription(getLine(str), TValue::INTVAR); 
    143   classDescription.values = mlnew TStringList; 
    144143  for(int noval = atoi(getLine(str).c_str()); noval; noval--) 
    145     classDescription.values->push_back(getLine(str)); 
     144    classDescription.addValue(getLine(str)); 
    146145 
    147146  TDomainDepot::TAttributeDescriptions attributeDescriptions; 
     
    153152  while(noAttr--) { 
    154153    attributeDescriptions.push_back(TDomainDepot::TAttributeDescription(getLine(str), TValue::INTVAR)); 
    155     PStringList values = mlnew TStringList(); 
    156     attributeDescriptions.back().values = values; 
     154    TDomainDepot::TAttributeDescription &desc = attributeDescriptions.back(); 
    157155 
    158156      int nvalues = atoi(getLine(str).c_str()); 
    159157      if (nvalues>0) { 
    160158      while(nvalues--) 
    161         values->push_back(getLine(str).c_str()); 
     159        desc.addValue(getLine(str)); 
    162160    } 
    163161      else if (nvalues<0) { 
     
    167165        (*ri)->push_back(atof(getLine(str).c_str())); 
    168166        sprintf(buf, "v%i", (*ri)->size()); 
    169         values->push_back(buf); 
     167        desc.addValue(buf); 
    170168        } 
    171169      sprintf(buf, "v%i", (*ri)->size()+1); 
    172       values->push_back(buf); 
     170      desc.addValue(buf); 
    173171    } 
    174172    else 
  • source/orange/basket.cpp

    r3451 r3997  
    108108      id = getMetaID(); 
    109109      // Variable is created solely to hold the name 
    110       domain->metas.push_back(TMetaDescriptor(id, mlnew TFloatVariable(atom), true)); 
     110      TFloatVariable *var = (TFloatVariable *)TVariable::getExisting(atom, TValue::FLOATVAR); 
     111      if (!var) 
     112        var = mlnew TFloatVariable(atom); 
     113      domain->metas.push_back(TMetaDescriptor(id, var, true)); 
    111114 
    112115      // store to global cache, if allowed and if not already there 
  • source/orange/c45inter.cpp

    r2659 r3997  
    8383    ::raiseError("empty or invalid names file"); 
    8484 
    85   PStringList classValues = mlnew TStringList; 
    86   for(vector<string>::iterator ai(atoms.begin()), ei(atoms.end()); ai!=ei; )  
    87     classValues->push_back(*(ai++));  
    88  
    8985  TDomainDepot::TAttributeDescriptions attributeDescriptions; 
    90  
     86  TDomainDepot::TAttributeDescription classDescription("y", TValue::INTVAR); 
     87 
     88  for(vector<string>::iterator ai(atoms.begin()), ei(atoms.end()); ai!=ei; ai++) 
     89    classDescription.addValue(*ai); 
     90   
    9191  do { 
    9292    while(!feof(fei.file) && !readC45Atom(fei, atoms)); 
     
    110110      else { 
    111111        attributeDescriptions.push_back(TDomainDepot::TAttributeDescription(name, TValue::INTVAR)); 
    112         PStringList values = mlnew TStringList; 
    113         attributeDescriptions.back().values = values; 
     112        TDomainDepot::TAttributeDescription &desc = attributeDescriptions.back(); 
    114113        while(ai!=atoms.end()) 
    115           values->push_back(*(ai++)); 
     114          desc.addValue(*ai++); 
    116115      } 
    117116    } 
     
    121120    ::raiseError("names file contains no variables but class variable"); 
    122121 
    123   attributeDescriptions.push_back(TDomainDepot::TAttributeDescription("y", TValue::INTVAR)); 
    124   attributeDescriptions.back().values = classValues; 
     122  attributeDescriptions.push_back(classDescription); 
    125123  skip->push_back(false); 
    126124 
  • source/orange/cls_orange.cpp

    r3623 r3997  
    460460 
    461461 
     462/* Never tested!  
     463int unpackOrangeDictionary(PyObject *self, PyObject *dict) 
     464{ 
     465  PyObject *d_key, *d_value; 
     466  int i = 0; 
     467  while (PyDict_Next(dict, &i, &d_key, &d_value)) { 
     468      if (Orange_setAttrLow(self, d_key, d_value, false) == -1) 
     469        return -1; 
     470    } 
     471  return 0; 
     472} 
     473*/ 
    462474 
    463475ORANGE_API PyObject *Orange__reduce__(PyObject *self, PyObject *, PyObject *) 
  • source/orange/cls_orange.hpp

    r2700 r3997  
    3838 
    3939ORANGE_API PyObject *packOrangeDictionary(PyObject *self); 
     40/* Never tested!  
     41ORANGE_API int unpackOrangeDictionary(PyObject *self, PyObject *dict); 
     42*/ 
    4043ORANGE_API PyObject *Orange__reduce__(PyObject *self, PyObject *, PyObject *); 
    4144 
  • source/orange/domaindepot.cpp

    r3316 r3997  
    171171 
    172172 
     173TDomainDepot::TAttributeDescription::TAttributeDescription(PVariable pvar) 
     174: preparedVar(pvar) 
     175{} 
     176 
     177 
     178void TDomainDepot::TAttributeDescription::addValue(const string &s) 
     179{ 
     180  fixedOrderValues.push_back(s); 
     181  values.insert(s); 
     182} 
     183 
    173184TDomainDepot::~TDomainDepot() 
    174185{ 
     
    188199} 
    189200 
    190                    
     201 
     202  
     203inline bool checkValueOrder(PVariable var, const TDomainDepot::TAttributeDescription &desc) 
     204{ 
     205  return    desc.varType != TValue::INTVAR 
     206         || dynamic_cast<TEnumVariable &>(var.getReference()).checkValuesOrder(desc.fixedOrderValues); 
     207} 
     208 
     209void augmentVariableValues(PVariable var, const TDomainDepot::TAttributeDescription &desc) 
     210{ 
     211  if (desc.varType != TValue::INTVAR) 
     212    return; 
     213     
     214  TEnumVariable &evar = dynamic_cast<TEnumVariable &>(var.getReference()); 
     215  const_ITERATE(TStringList, fvi, desc.fixedOrderValues) 
     216    evar.addValue(*fvi); 
     217  vector<string> sorted; 
     218  TEnumVariable::presortValues(desc.values, sorted); 
     219  const_ITERATE(vector<string>, ssi, sorted) 
     220    evar.addValue(*ssi); 
     221} 
     222 
     223 
    191224bool TDomainDepot::checkDomain(const TDomain *domain,  
    192225                               const TAttributeDescriptions *attributes, bool hasClass, 
     
    203236  // check the names and types of attributes 
    204237  TVarList::const_iterator vi(domain->variables->begin()); 
    205   const_PITERATE(TAttributeDescriptions, ai, attributes) 
     238  TAttributeDescriptions::const_iterator ai(attributes->begin()), ae(attributes->end()); 
     239  for(; ai != ae; ai++, vi++) 
    206240    if (    ((*ai).name != (*vi)->name) 
    207241         || ((*ai).varType>0) && ((*ai).varType != (*vi)->varType) 
    208242         || (((*ai).varType==PYTHONVAR) && !pythonDeclarationMatches((*ai).typeDeclaration, *vi)) 
     243         || !checkValueOrder(*vi, *ai) 
    209244       ) 
    210245      return false; 
    211     else 
    212       vi++; 
    213246 
    214247  // check the meta attributes if they exist 
    215   if (metas) 
    216     const_PITERATE(TAttributeDescriptions, mi, metas) { 
     248  TAttributeDescriptions::const_iterator mi, me; 
     249  if (metas) { 
     250    for(mi = metas->begin(), me = metas->end(); mi != me; mi++) { 
    217251      PVariable var = domain->getMetaVar((*mi).name, false); 
    218252      if (    !var 
    219253           || (((*mi).varType > 0) && ((*mi).varType != var->varType)) 
    220254           || (((*mi).varType==PYTHONVAR) && !pythonDeclarationMatches((*mi).typeDeclaration, var)) 
     255           || !checkValueOrder(var, *mi) 
    221256         ) 
    222257        return false; 
     
    224259        *(metaIDs++) = domain->getMetaNum((*mi).name, false); 
    225260    } 
    226  
     261  } 
     262 
     263  for(ai = attributes->begin(), vi = domain->variables->begin(); ai != ae; ai++, vi++) 
     264    augmentVariableValues(*vi, *ai); 
     265  for(mi = metas->begin(); mi != me; mi++) 
     266    if (mi->varType == TValue::INTVAR) 
     267      augmentVariableValues(domain->getMetaVar((*mi).name), *mi); 
     268       
    227269  return true; 
    228270} 
    229271 
    230272 
    231 PDomain TDomainDepot::prepareDomain(const TAttributeDescriptions *attributes, bool hasClass, 
    232                                     const TAttributeDescriptions *metas, PVarList knownVars, 
     273PDomain TDomainDepot::prepareDomain(TAttributeDescriptions *attributes, bool hasClass, 
     274                                    TAttributeDescriptions *metas, PVarList knownVars, 
    233275                                    const TMetaVector *knownMetas, 
    234276                                    const bool dontStore, const bool dontCheckStored, 
     
    245287  TVarList attrList; 
    246288  int foo; 
    247   const_PITERATE(TAttributeDescriptions, ai, attributes) { 
     289  PITERATE(TAttributeDescriptions, ai, attributes) { 
    248290    PVariable newvar = makeVariable(*ai, foo, knownVars, knownMetas, false, false); 
    249291    if ((*ai).ordered) 
     
    263305 
    264306  if (metas) 
    265     const_PITERATE(TAttributeDescriptions, mi, metas) { 
     307    PITERATE(TAttributeDescriptions, mi, metas) { 
    266308      int id; 
    267309      PVariable var = makeVariable(*mi, id, knownVars, knownMetas, false, true); 
     
    338380} 
    339381 
    340 PVariable TDomainDepot::createVariable(const TAttributeDescription &desc) 
    341 { 
     382PVariable TDomainDepot::createVariable(TAttributeDescription &desc) 
     383{ 
     384  TVariable *existing = TVariable::getExisting(desc.name, desc.varType, &desc.fixedOrderValues, &desc.values); 
     385  if (existing) 
     386    return existing; 
     387 
     388   
    342389  switch (desc.varType) { 
    343390    case TValue::INTVAR: { 
    344       TEnumVariable *evar = mlnew TEnumVariable(desc.name, desc.values ? desc.values : PStringList(mlnew TStringList())); 
    345       if (desc.ordered) 
    346         evar->ordered = true; 
    347       return evar; 
     391      TStringList *values = mlnew TStringList(desc.fixedOrderValues); 
     392      PVariable var = mlnew TEnumVariable(desc.name, values); 
     393      augmentVariableValues(var, desc); 
     394      return var; 
    348395    } 
    349396 
     
    365412 
    366413 
    367 PVariable TDomainDepot::makeVariable(const TAttributeDescription &desc, int &id, PVarList knownVars, const TMetaVector *metas, bool dontCreateNew, bool preferMetas) 
     414PVariable TDomainDepot::makeVariable(TAttributeDescription &desc, int &id, PVarList knownVars, const TMetaVector *metas, bool dontCreateNew, bool preferMetas) 
    368415{  
     416  PVariable var; 
     417   
    369418  if (!preferMetas && knownVars) 
    370419    const_PITERATE(TVarList, vi, knownVars) 
     
    375424             ) 
    376425          && ((desc.varType!=PYTHONVAR) || pythonDeclarationMatches(desc.typeDeclaration, *vi)) 
     426          && checkValueOrder(*vi, desc) 
    377427         ) { 
    378428        id = 0; 
    379         return *vi; 
     429        var = *vi; 
    380430      } 
    381431 
    382   if (metas) 
     432  if (!var && metas) 
    383433    const_PITERATE(TMetaVector, mi, metas) 
    384434      if (   ((*mi).variable->name == desc.name) 
     
    388438             ) 
    389439          && ((desc.varType!=PYTHONVAR) || pythonDeclarationMatches(desc.typeDeclaration, (*mi).variable)) 
     440          && checkValueOrder((*mi).variable, desc) 
    390441         ) { 
    391442        id = (*mi).id; 
    392         return (*mi).variable; 
     443        var = (*mi).variable; 
    393444      } 
    394445 
    395   if (preferMetas && knownVars) 
     446  if (!var && preferMetas && knownVars) 
    396447    const_PITERATE(TVarList, vi, knownVars) 
    397448      if (   ((*vi)->name==desc.name) 
     
    401452             ) 
    402453          && ((desc.varType!=PYTHONVAR) || pythonDeclarationMatches(desc.typeDeclaration, *vi)) 
     454          && checkValueOrder(*vi, desc) 
    403455         ) { 
    404456        id = 0; 
    405         return *vi; 
     457        var = *vi; 
    406458      } 
     459 
     460  if (var) {   
     461    augmentVariableValues(var, desc); 
     462    return var; 
     463  } 
    407464   
    408465  id = 0; 
    409  
    410466  return dontCreateNew ? PVariable() : createVariable(desc); 
    411467} 
  • source/orange/domaindepot.hpp

    r2637 r3997  
    4949  class TAttributeDescription { 
    5050  public: 
     51    PVariable preparedVar; 
     52     
    5153    string name; 
    5254    int varType; 
    5355    string typeDeclaration; 
    5456    bool ordered; 
    55     PStringList values; // not always used, but often comes handy... 
    56  
     57    TStringList fixedOrderValues; // these have a fixed order 
     58    set<string> values; // all values, sorted alpabetically 
     59    vector<string> DCs; 
     60     
    5761    TAttributeDescription(const string &, const int &, const string &, bool = false); 
    5862    TAttributeDescription(const string &, const int &); 
     63    TAttributeDescription(PVariable); 
     64     
     65    void addValue(const string &s); 
    5966  }; 
    6067 
     
    6673                          const TAttributeDescriptions *metas, int *metaIDs = NULL); 
    6774 
    68   PDomain prepareDomain(const TAttributeDescriptions *attributes, bool hasClass, 
    69                         const TAttributeDescriptions *metas, PVarList knownVars, const TMetaVector *knownMetas, 
     75  PDomain prepareDomain(TAttributeDescriptions *attributes, bool hasClass, 
     76                        TAttributeDescriptions *metas, PVarList knownVars, const TMetaVector *knownMetas, 
    7077                        const bool dontStore, const bool dontCheckStored, 
    7178                        bool *domainIsNew = NULL, int *metaIDs = NULL); 
     
    7481 
    7582  /* Creates a variable with given name and type. */ 
    76   static PVariable createVariable(const TAttributeDescription &); 
     83  static PVariable createVariable(TAttributeDescription &); 
    7784  static PVariable createVariable_Python(const string &typeDeclaration, const string &name); 
    7885 
     
    8188     the id is set as well; if not, id is set to 0. If the variable is not found, 
    8289     a new one is created unless dontCreateNew is set to false. */ 
    83   static PVariable makeVariable(const TAttributeDescription &, int &id, PVarList knownVars, const TMetaVector * = NULL, bool dontCreateNew = false, bool preferMetas = false); 
     90  static PVariable makeVariable(TAttributeDescription &, int &id, PVarList knownVars, const TMetaVector * = NULL, bool dontCreateNew = false, bool preferMetas = false); 
    8491 
    8592 
  • source/orange/lib_kernel.cpp

    r3407 r3997  
    222222C_NAMED(FloatVariable, Variable, "([name=, startValue=, endValue=, stepValue=, distributed=, getValueFrom=])") 
    223223 
     224PyObject *Variable_getExisting(PyObject *, PyObject *args) PYARGS(METH_VARARGS | METH_STATIC, "(name, type[, fixedOrderValues[, otherValues]]) -> Variable | None") 
     225{ 
     226  PyTRY 
     227    char *varName; 
     228    int varType; 
     229    PStringList values; 
     230    PStringList unorderedValues_asList; 
     231     
     232    if (!PyArg_ParseTuple(args, "si|O&O&:Variable.getExisting", &varName, &varType, ccn_StringList, &values, ccn_StringList, &unorderedValues_asList)) 
     233      return NULL; 
     234     
     235    set<string> unorderedValues; 
     236    if (unorderedValues_asList) 
     237      unorderedValues.insert(unorderedValues_asList->begin(), unorderedValues_asList->end()); 
     238       
     239    PVariable var = TVariable::getExisting(varName, varType, values.getUnwrappedPtr(), &unorderedValues); 
     240    return WrapOrange(var); 
     241  PyCATCH 
     242} 
     243 
    224244 
    225245#include "stringvars.hpp" 
     
    381401 
    382402 
     403PyObject *EnumVariable__reduce__(PyObject *self) 
     404{ 
     405    PyTRY 
     406        return Py_BuildValue("O(ON)", getExportedFunction("__pickleLoaderEnumVariable"), self->ob_type, packOrangeDictionary(self)); 
     407    PyCATCH 
     408} 
     409 
     410 
     411PyObject *__pickleLoaderEnumVariable(PyObject *, PyObject *args) PYARGS(METH_VARARGS, "(type, dictionary)") 
     412{ 
     413  PyTRY 
     414    PyTypeObject *type; 
     415    PyObject *dict; 
     416      if (!PyArg_ParseTuple(args, "OO:__pickleLoaderCostMatrix", &type, &dict)) 
     417          return NULL; 
     418 
     419    char *name = NULL; 
     420    TStringList *values = NULL; 
     421     
     422    PyObject *pyname = PyDict_GetItemString(dict, "name"); 
     423    if (pyname) 
     424      name = PyString_AsString(pyname); 
     425 
     426    PyObject *pyvalues = PyDict_GetItemString(dict, "values"); 
     427    if (pyvalues) 
     428      values = PyOrange_AsStringList((TPyOrange *)pyvalues).getUnwrappedPtr(); 
     429       
     430    TVariable *var = TVariable::getExisting(name, TValue::INTVAR, values, NULL); 
     431    PVariable pvar = var; 
     432    if (!var) { 
     433      TEnumVariable *evar = new TEnumVariable(name ? name : ""); 
     434      pvar = evar; 
     435      if (values) 
     436        const_PITERATE(TStringList, vi, values) 
     437          evar->addValue(*vi); 
     438    } 
     439     
     440    PyObject *pyvar = WrapOrange(pvar); 
     441 
     442    PyObject *d_key, *d_value; 
     443    int i = 0; 
     444    while (PyDict_Next(dict, &i, &d_key, &d_value)) { 
     445      if (   strcmp("values", PyString_AsString(d_key)) 
     446          && Orange_setattrLow((TPyOrange *)pyvar, d_key, d_value, false) < 0 
     447         ) { 
     448          Py_DECREF(pyvar); 
     449          return NULL; 
     450        } 
     451    } 
     452  
     453    return pyvar; 
     454    PyCATCH 
     455} 
    383456 
    384457PyObject *EnumVariable_getitem_sq(PyObject *self, int index) 
  • source/orange/retisinter.cpp

    r708 r3997  
    131131    if (type=="discrete") { 
    132132      attributeDescriptions.push_back(TDomainDepot::TAttributeDescription(name, TValue::INTVAR)); 
    133       PStringList values = mlnew TStringList; 
    134       attributeDescriptions.back().values = values; 
     133      TDomainDepot::TAttributeDescription &desc = attributeDescriptions.back(); 
    135134      int noVals = atoi(getLine(str).c_str()); 
    136135      while(noVals--) 
    137         values->push_back(getLine(str).c_str()); 
     136        desc.addValue(getLine(str).c_str()); 
    138137    } 
    139138    else if (type=="continuous") { 
  • source/orange/tabdelim.cpp

    r3451 r3997  
    4444 
    4545TDomainDepot TTabDelimExampleGenerator::domainDepot_tab; 
    46 TDomainDepot TTabDelimExampleGenerator::domainDepot_txt; 
    4746 
    4847 
     
    315314  char *isNotTab = mayBeTabFile(stem); 
    316315 
     316  TDomainDepot::TAttributeDescriptions descriptions; 
     317   
    317318  if (autoDetect) { 
    318319    if (!isNotTab) 
    319320      raiseWarning("'%s' is being loaded as .txt, but could be .tab file", stem.c_str()); 
    320     else 
    321       mldelete isNotTab; 
    322  
    323     return domainWithDetection(stem, sourceVars, sourceMetas, sourceDomain, dontCheckStored, noCodedDiscrete, noClass); 
    324   } 
    325  
     321    readTxtHeader(stem, descriptions); 
     322  } 
    326323  else { 
    327     if (isNotTab) { 
     324    if (isNotTab) 
    328325      raiseWarning("'%s' is being loaded as .tab, but looks more like .txt file\n(%s)", stem.c_str(), isNotTab); 
    329       mldelete isNotTab; 
    330     } 
    331  
    332     return domainWithoutDetection(stem, sourceVars, sourceMetas, sourceDomain, dontCheckStored); 
    333   } 
    334 } 
    335  
    336   
     326    readTabHeader(stem, descriptions); 
     327  } 
     328 
     329  if (isNotTab) 
     330    mldelete isNotTab; 
     331 
     332  scanAttributeValues(stem, descriptions); 
     333   
     334  TIntList::iterator ati(attributeTypes->begin()); 
     335  TDomainDepot::TAttributeDescriptions attributeDescriptions, metaDescriptions; 
     336  int ind = 0, lastRegular = -1; 
     337 
     338  for(TDomainDepot::TAttributeDescriptions::iterator adi(descriptions.begin()), ade(descriptions.end()); adi != ade; adi++, ati++, ind++) { 
     339    if (!*ati) 
     340      continue; 
     341       
     342    if (adi->varType == -1) { 
     343      int autoType = detectAttributeType(*adi, noCodedDiscrete); 
     344       
     345      if (autoType == 3) { 
     346        raiseWarning("cannot determine type for attribute '%s'; the attribute will be ignored", adi->name.c_str()); 
     347        *ati = 0; 
     348        continue; 
     349      } 
     350 
     351      adi->varType = autoType == 1 ? TValue::FLOATVAR : TValue::INTVAR; 
     352    } 
     353     
     354    if (*ati == 1) 
     355      metaDescriptions.push_back(*adi); 
     356       
     357    else if ((classPos != ind) && (basketPos != ind)) { 
     358      attributeDescriptions.push_back(*adi); 
     359      lastRegular = ind; 
     360    } 
     361  } 
     362   
     363  if (classPos > -1) 
     364    attributeDescriptions.push_back(descriptions[classPos]); 
     365  else if (autoDetect && !noClass) 
     366    classPos = lastRegular; 
     367     
     368  if (basketPos >= 0) 
     369    basketFeeder = mlnew TBasketFeeder(sourceDomain, dontCheckStored, false); 
     370     
     371  if (sourceDomain) { 
     372    if (!domainDepot_tab.checkDomain(sourceDomain.AS(TDomain), &attributeDescriptions, classPos >= 0, NULL)) 
     373      raiseError("given domain does not match the file"); 
     374 
     375    if (basketFeeder) 
     376      basketFeeder->domain = sourceDomain; 
     377    return sourceDomain; 
     378  } 
     379 
     380  int *metaIDs = mlnew int[metaDescriptions.size()]; 
     381  PDomain newDomain = domainDepot_tab.prepareDomain(&attributeDescriptions, classPos>-1, &metaDescriptions, sourceVars, sourceMetas, false, dontCheckStored, NULL, metaIDs); 
     382 
     383  int *mid = metaIDs; 
     384  PITERATE(TIntList, ii, attributeTypes) 
     385    if (*ii == 1) 
     386      *ii = *(mid++); 
     387 
     388  mldelete metaIDs; 
     389 
     390  if (basketFeeder) 
     391    basketFeeder->domain = newDomain; 
     392 
     393  return newDomain; 
     394} 
     395 
     396 
     397 
     398int TTabDelimExampleGenerator::detectAttributeType(TDomainDepot::TAttributeDescription &desc, const bool noCodedDiscrete) 
     399{ 
     400  char numTest[64]; 
     401 
     402  int status = 3;  //  3 - not encountered any values, 2 - can be coded discrete, 1 - can be float, 0 - must be nominal 
     403  ITERATE(set<string>, vli, desc.values) { 
     404 
     405    if (vli->length() > 63) 
     406      return 0; 
     407     
     408    const char *ceni = vli->c_str(); 
     409    if (   !*ceni 
     410        || !ceni[1] && ((*ceni=='?') || (*ceni=='.') || (*ceni=='~') || (*ceni=='*') || (*ceni=='-')) 
     411        || (*vli == "NA") || (DC && (*vli == DC)) || (DK && (*vli == DK))) 
     412      continue; 
     413     
     414    if (status == 3) 
     415      status = 2; 
     416 
     417    if ((status == 2) && (ceni[1] || (*ceni<'0') || (*ceni>'9'))) 
     418      status = noCodedDiscrete ? 2 : 1; 
     419       
     420    if (status == 1) { 
     421      strcpy(numTest, ceni); 
     422      for(char *sc = numTest; *sc; sc++) 
     423        if (*sc == ',') 
     424          *sc = '.'; 
     425 
     426      char *eptr; 
     427      strtod(numTest, &eptr); 
     428      while (*eptr==32) 
     429        eptr++; 
     430      if (*eptr) 
     431        return 0; 
     432    } 
     433  } 
     434   
     435  return status; 
     436} 
     437 
     438 
     439 
    337440 
    338441/* These are the rules for determining the attribute types. 
     
    345448      respectively. 
    346449      D, C and S mean discrete, continuous and string attributes. 
     450 
     451 
     452!!! NOT TRUE: 
    347453 
    348454   2. By knownVars. 
     
    363469*/ 
    364470 
    365 class TSearchWarranty  
    366 { public: 
    367   int posInFile, posInDomain, suspectedType; 
    368   // suspectedType can be 3 (never seen it yet), 2 (can even be coded discrete), 1 (can be float); 
    369   //   if it's found that it cannot be float, it can only be discrete, so the warranty is removed 
    370   TSearchWarranty(const int &pif, const int &pid) 
    371   : posInFile(pif), posInDomain(pid), suspectedType(3) 
    372   {} 
    373 }; 
    374  
    375 PDomain TTabDelimExampleGenerator::domainWithDetection(const string &stem, PVarList sourceVars, TMetaVector *sourceMetas, PDomain sourceDomain, bool dontCheckStored, bool noCodedDiscrete, bool noClass) 
     471 
     472void TTabDelimExampleGenerator::scanAttributeValues(const string &stem, TDomainDepot::TAttributeDescriptions &desc) 
     473{ 
     474  TFileExampleIteratorData fei(stem); 
     475 
     476  vector<string> atoms; 
     477  vector<string>::const_iterator ai, ae; 
     478  TDomainDepot::TAttributeDescriptions::iterator di, db(desc.begin()), de(desc.end()); 
     479  TIntList::const_iterator ati, atb(attributeTypes->begin()); 
     480 
     481  for (int i = headerLines; !feof(fei.file) && i--; ) 
     482    while(!feof(fei.file) && (readTabAtom(fei, atoms, true, csv) == -1)); 
     483 
     484  while (!feof(fei.file)) { 
     485    if (readTabAtom(fei, atoms, true, csv) <= 0) 
     486      continue; 
     487     
     488    for(di = db, ati = atb, ai = atoms.begin(), ae = atoms.end(); (di != de) && (ai != ae); di++, ai++, ati++) { 
     489      if (!*atb) 
     490        continue; 
     491         
     492      const char *ceni = ai->c_str(); 
     493      if (   !*ceni 
     494          || !ceni[1] && ((*ceni=='?') || (*ceni=='.') || (*ceni=='~') || (*ceni=='*') || (*ceni=='-')) 
     495          || (*ai == "NA") || (DC && (*ai == DC)) || (DK && (*ai == DK))) 
     496         continue; 
     497 
     498      di->values.insert(*ai); 
     499    } 
     500  } 
     501} 
     502 
     503 
     504void TTabDelimExampleGenerator::readTxtHeader(const string &stem, TDomainDepot::TAttributeDescriptions &descs) 
    376505{  
    377   headerLines = 1; 
    378  
    379506  TFileExampleIteratorData fei(stem); 
    380    
     507 
    381508  vector<string> varNames; 
    382   // read the next non-comment line 
    383509  while(!feof(fei.file) && (readTabAtom(fei, varNames, true, csv)==-1)); 
    384510  if (varNames.empty()) 
    385     ::raiseError("unexpected end of file '%s'", fei.filename.c_str()); 
    386  
    387   TDomainDepot::TAttributeDescriptions attributeDescriptions, metas; 
     511    ::raiseError("unexpected end of file '%s' while searching for attribute names", fei.filename.c_str()); 
     512 
     513  headerLines = 1; 
    388514  classPos = -1; 
    389515  basketPos = -1; 
    390   int classType = -1; 
    391   int lastRegular = -1; 
    392  
    393  
    394   list<TSearchWarranty> searchWarranties; 
    395  
    396   /**** Parse the header row */ 
    397    
    398   ITERATE(vector<string>, ni, varNames) { 
     516  attributeTypes = mlnew TIntList(varNames.size(), -1); 
     517  TIntList::iterator attributeType(attributeTypes->begin()); 
     518  vector<string>::const_iterator ni(varNames.begin()), ne(varNames.end()); 
     519  int ind = 0; 
     520   
     521  for(; ni != ne; ni++, ind++, attributeType++) { 
    399522    /* Parses the header line 
    400523       - sets *ni to a real name (without prefix) 
     
    404527       - to attributeTypes, appends -1 for ordinary atributes, 1 for metas and 0 for ignored or baskets*/ 
    405528    int varType = -1; // varType, or -1 for unnown, -2 for basket 
    406     attributeTypes->push_back(-1); 
    407     int &attributeType = attributeTypes->back(); 
    408529 
    409530    const char *cptr = (*ni).c_str(); 
    410     if (*cptr && (cptr[1]=='#')) { 
    411       if (*cptr == 'm') 
    412         attributeType = 1; 
    413       else if (*cptr == 'i') 
    414         attributeType = 0; 
     531    if (*cptr && (cptr[1]=='#') || (cptr[2] == '#')) { 
     532      if (*cptr == 'm') { 
     533        *attributeType = 1; 
     534        cptr++; 
     535      } 
     536      else if (*cptr == 'i') { 
     537        *attributeType = 0; 
     538        cptr++; 
     539      } 
    415540      else if (*cptr == 'c') { 
    416541        if (classPos>-1) 
    417542          ::raiseError("more than one attribute marked as class"); 
    418543        else 
    419           classPos = ni-varNames.begin(); 
    420       } 
    421  
    422       else if (*cptr == 'D') 
     544          classPos = ind; 
     545        cptr++; 
     546      } 
     547       
     548      // we may have encountered a m, i or c, so cptr points to the second character, 
     549      // or it can still point to the first  
     550      if (*cptr == 'D') { 
    423551        varType = TValue::INTVAR; 
    424       else if (*cptr == 'C') 
     552        cptr++; 
     553      } 
     554      else if (*cptr == 'C') { 
    425555        varType = TValue::FLOATVAR; 
    426       else if (*cptr == 'S') 
     556        cptr++; 
     557      } 
     558      else if (*cptr == 'S') { 
    427559        varType = STRINGVAR; 
     560        cptr++; 
     561      } 
    428562      else if (*cptr == 'B') { 
    429           varType = -2; 
    430           attributeType = 0; 
    431           if (basketPos > -1) 
    432             ::raiseError("more than one basket attribute"); 
    433           else 
    434             basketPos = ni - varNames.begin(); 
    435       } 
    436       else 
     563        varType = -2; 
     564        if ((*attributeType != -1) || (classPos == ind)) 
     565          ::raiseError("flag 'B' is incompatible with 'i', 'm' and 'c'"); 
     566        *attributeType = 0; 
     567        if (basketPos > -1) 
     568          ::raiseError("more than one basket attribute"); 
     569        else 
     570          basketPos = ind; 
     571        cptr++; 
     572      } 
     573      
     574      if (*cptr != '#')      
    437575        ::raiseError("unrecognized flags in attribute name '%s'", cptr); 
    438  
    439       *ni = string(cptr+2); 
    440     } 
    441  
    442     else if (*cptr && cptr[1] && (cptr[2]=='#')) { 
    443       bool beenWarned = false; 
    444       if (*cptr == 'm') 
    445         attributeType = 1; 
    446       else if (*cptr == 'i') 
    447         attributeType = 0; 
    448       else if (*cptr == 'c') { 
    449         if (classPos>-1) 
    450           ::raiseError("more than one attribute marked as class"); 
    451         else 
    452           classPos = ni-varNames.begin(); 
    453       } 
    454       else 
    455         ::raiseError("unrecognized flags in attribute name '%s'", cptr); 
    456  
    457576      cptr++; 
    458       if (*cptr == 'D') 
    459         varType = TValue::INTVAR; 
    460       else if (*cptr == 'C') 
    461         varType = TValue::FLOATVAR; 
    462       else if (*cptr == 'S') 
    463         varType = STRINGVAR; 
    464       else if (*cptr == 'B') { 
    465         if (attributeType) { // basket can be ignored, too 
    466           varType = -2; 
    467           attributeType = 0;  // this is ugly, but baskets are a patch anyway: if not ignored by 'i' flag, it's ignored by 'basket' 
    468           if (basketPos > -1) 
    469             ::raiseError("there can only be one basket attribute"); 
    470           else 
    471             basketPos = ni - varNames.begin(); 
    472         } 
    473       } 
    474       else 
    475         ::raiseError("unrecognized flags in attribute name '%s'", cptr); 
    476  
    477       // remove the prefix (we have already increased cptr once) 
    478       *ni = string(cptr+2); 
    479     } 
    480  
    481     /* If the attribute is not to be ignored, we attempt to either find its descriptor 
    482        among the known attributes or create a new attribute if the type is given. 
    483        For ordinary attributes, the descriptor (or PVariable()) is pushed to the list of 'variables'. 
    484        For meta attributes, a meta descriptor is pushed to 'metas'. If the attribute was used as 
    485        meta-attribute in some of known domains, the id is reused; otherwise a new id is created. 
    486        If the descriptor was nor found nor created, a warranty is issued. 
    487     */ 
    488        
    489     if ((classPos == ni-varNames.begin())) { 
    490       classType = varType; 
    491     } 
    492     else { 
    493       if (attributeType == 1) { 
    494         metas.push_back(TDomainDepot::TAttributeDescription(*ni, varType)); 
    495         if (varType==-1) 
    496           searchWarranties.push_back(TSearchWarranty(ni-varNames.begin(), -(signed int)(metas.size()))); 
    497       } 
    498       else if (attributeType) { 
    499         lastRegular = ni-varNames.begin(); 
    500         attributeDescriptions.push_back(TDomainDepot::TAttributeDescription(*ni, varType)); 
    501         if (varType==-1) 
    502           searchWarranties.push_back(TSearchWarranty(ni-varNames.begin(), attributeType==-2 ? -1 : attributeDescriptions.size()-1)); 
    503       } 
    504     } 
    505   } 
    506  
    507   if (classPos > -1) { 
    508     attributeDescriptions.push_back(TDomainDepot::TAttributeDescription(varNames[classPos], classType)); 
    509     if (classType<0) 
    510       searchWarranties.push_back(TSearchWarranty(classPos, attributeDescriptions.size()-1)); 
    511   } 
    512   else { 
    513     if (!noClass) 
    514       classPos = lastRegular; 
    515   } 
    516  
    517   if (!searchWarranties.empty()) { 
    518     vector<string> atoms; 
    519     char numTest[64]; 
    520     while (!feof(fei.file) && !searchWarranties.empty()) { 
    521       // seek to the next line non-empty non-comment line 
    522       if (readTabAtom(fei, atoms, true, csv) <= 0) 
    523         continue; 
    524      
    525       for(list<TSearchWarranty>::iterator wi(searchWarranties.begin()); wi != searchWarranties.end(); ) { 
    526         if ((*wi).posInFile >= atoms.size()) { 
    527           wi++; 
    528           continue; 
    529 //          raiseError("line %i too short", fei.line); 
    530         } 
    531  
    532         const string &atom = atoms[(*wi).posInFile]; 
    533  
    534         // only discrete attributes can have values longer than 63 characters 
    535         if (atom.length()>63) { 
    536           if ((*wi).posInDomain<0) 
    537             metas[-(*wi).posInDomain - 1].varType = TValue::INTVAR; 
    538           else 
    539             attributeDescriptions[(*wi).posInDomain].varType = TValue::INTVAR; 
    540           wi = searchWarranties.erase(wi); 
    541           continue; 
    542         } 
    543  
    544         const char *ceni = atom.c_str(); 
    545         if (   !*ceni 
    546             || !ceni[1] && ((*ceni=='?') || (*ceni=='.') || (*ceni=='~') || (*ceni=='*') || (*ceni=='-')) 
    547             || (atom == "NA") || (DC && (atom == DC)) || (DK && (atom == DK))) { 
    548           wi++; 
    549           continue; 
    550         } 
    551  
    552         // we have encountered some value 
    553         if ((*wi).suspectedType == 3)  
    554           (*wi).suspectedType = 2; 
    555  
    556         // If the attribute is a digit, it can be anything 
    557         if ((!ceni[1]) && (*ceni>='0') && (*ceni<='9')) { 
    558           wi++; 
    559           continue; 
    560         } 
    561  
    562         // If it is longer than one character, it cannot be a coded discrete 
    563         if (ceni[1]) 
    564           (*wi).suspectedType = 1; 
    565  
    566         // Convert commas into dots 
    567         strcpy(numTest, ceni); 
    568         for(char *sc = numTest; *sc; sc++) 
    569           if (*sc == ',') 
    570             *sc = '.'; 
    571  
    572         // If the attribute cannot be converted into a number, it is enum 
    573         char *eptr; 
    574         strtod(numTest, &eptr); 
    575         while (*eptr==32) 
    576           eptr++; 
    577         if (*eptr) { 
    578           if ((*wi).posInDomain<0) 
    579             metas[-(*wi).posInDomain - 1].varType = TValue::INTVAR; 
    580           else 
    581             attributeDescriptions[(*wi).posInDomain].varType = TValue::INTVAR; 
    582           wi = searchWarranties.erase(wi); 
    583           continue; 
    584         } 
    585          
    586         wi++; 
    587       } 
    588     } 
    589  
    590  
    591     ITERATE(list<TSearchWarranty>, wi, searchWarranties) { 
    592       const string &name = varNames[(*wi).posInFile]; 
    593       if ((*wi).suspectedType == 3) 
    594         raiseWarning("cannot determine type for attribute '%s'; the attribute will be ignored", name.c_str()); 
    595  
    596       int type = (*wi).suspectedType == 2 && !noCodedDiscrete ? TValue::INTVAR : TValue::FLOATVAR; 
    597       if ((*wi).posInDomain<0) 
    598         metas[-(*wi).posInDomain - 1].varType = type; 
    599       else 
    600         attributeDescriptions[(*wi).posInDomain].varType = type; 
    601     } 
    602  
    603     for(int i = 0; i < attributeDescriptions.size(); ) 
    604       if (attributeDescriptions[i].varType == -1) 
    605         attributeDescriptions.erase(attributeDescriptions.begin() + i); 
    606       else 
    607         i++; 
    608   } 
    609  
    610  
    611   if (basketPos >= 0) 
    612     basketFeeder = mlnew TBasketFeeder(sourceDomain, dontCheckStored, false); 
    613      
    614   if (sourceDomain) { 
    615     if (!domainDepot_txt.checkDomain(sourceDomain.AS(TDomain), &attributeDescriptions, classPos>-1, NULL)) 
    616       raiseError("given domain does not match the file"); 
    617     else { 
    618       if (basketFeeder) 
    619         basketFeeder->domain = sourceDomain; 
    620       return sourceDomain; 
    621     } 
    622   } 
    623  
    624   int *metaIDs = mlnew int[metas.size()]; 
    625   PDomain newDomain = domainDepot_txt.prepareDomain(&attributeDescriptions, classPos>-1, &metas, sourceVars, sourceMetas, false, dontCheckStored, NULL, metaIDs); 
    626  
    627   int *mid = metaIDs; 
    628   PITERATE(TIntList, ii, attributeTypes) 
    629     if (*ii == 1) 
    630       *ii = *(mid++); 
    631  
    632   mldelete metaIDs; 
    633  
    634   if (basketFeeder) 
    635     basketFeeder->domain = newDomain; 
    636  
    637   return newDomain; 
    638 } 
    639  
    640  
    641 PDomain TTabDelimExampleGenerator::domainWithoutDetection(const string &stem, PVarList sourceVars, TMetaVector *sourceMetas, PDomain sourceDomain, bool dontCheckStored) 
     577    } 
     578 
     579    descs.push_back(TDomainDepot::TAttributeDescription(cptr, varType)); 
     580  } 
     581} 
     582 
     583 
     584 
     585void TTabDelimExampleGenerator::readTabHeader(const string &stem, TDomainDepot::TAttributeDescriptions &descs) 
    642586{ 
     587  classPos = -1; 
     588  basketPos = -1; 
     589  headerLines = 3; 
     590 
    643591  TFileExampleIteratorData fei(stem); 
    644592   
     
    662610    varFlags.push_back(""); 
    663611 
    664   TDomainDepot::TAttributeDescriptions attributeDescriptions, metas; 
    665   TDomainDepot::TAttributeDescription classDescription("", 0); 
    666   classPos = -1; 
    667   basketPos = -1; 
    668   headerLines = 3; 
    669  
    670612  attributeTypes = mlnew TIntList(varNames.size(), -1); 
    671613 
     
    673615  vector<string>::iterator ti(varTypes.begin()); 
    674616  vector<string>::iterator fi(varFlags.begin()), fe(varFlags.end()); 
    675   TIntList::iterator ati(attributeTypes->begin()); 
    676   for(; vni!=vne; fi++, vni++, ti++, ati++) { 
    677     TDomainDepot::TAttributeDescription *attributeDescription = NULL; 
     617  TIntList::iterator attributeType(attributeTypes->begin()); 
     618  int ind = 0; 
     619   
     620  for(; vni!=vne; fi++, vni++, ti++, attributeType++, ind++) { 
     621   
     622    descs.push_back(TDomainDepot::TAttributeDescription(*vni, 0)); 
     623    TDomainDepot::TAttributeDescription &desc = descs.back(); 
     624 
    678625    bool ordered = false; 
     626    vector<string> thisDCs; 
    679627 
    680628    if (fi!=fe) { 
     
    682630 
    683631      if (args.direct.size()) { 
     632       
    684633        if (args.direct.size()>1) 
    685634          ::raiseError("invalid flags for attribute '%s'", (*vni).c_str()); 
     635           
    686636        string direct = args.direct.front(); 
    687637        if ((direct=="s") || (direct=="skip") || (direct=="i") || (direct=="ignore")) 
    688           *ati = 0; 
    689         else if ((direct=="c") || (direct=="class")) 
    690           if (classPos==-1) { 
    691             classPos = vni - varNames.begin(); 
    692             classDescription.name = *vni; 
    693             attributeDescription = &classDescription; 
    694           } 
    695           else  
     638          *attributeType = 0; 
     639 
     640        else if ((direct=="c") || (direct=="class")) { 
     641          if (classPos != -1) 
    696642            ::raiseError("multiple attributes are specified as class attribute ('%s' and '%s')", (*vni).c_str(), (*vni).c_str()); 
     643          classPos = ind; 
     644        } 
     645         
    697646        else if ((direct=="m") || (direct=="meta")) 
    698           *ati = 1; 
    699       } 
    700  
    701       if (args.exists("dc")) { 
    702         const int ind = vni-varNames.begin(); 
    703         ITERATE(TMultiStringParameters, mi, args.options) 
    704           if ((*mi).first == "dc") { 
    705             while (DCs.size() <= ind) 
    706               DCs.push_back(vector<string>()); 
    707             DCs.at(ind).push_back((*mi).second); 
    708           } 
    709       } 
     647          *attributeType = 1; 
     648      } 
     649 
     650      ITERATE(TMultiStringParameters, mi, args.options) 
     651        if ((*mi).first == "dc") 
     652          thisDCs.push_back((*mi).second); 
    710653 
    711654      ordered = args.exists("ordered"); 
    712655    } 
    713  
    714     if (!*ati) 
    715       continue; 
    716656 
    717657    if (!strcmp((*ti).c_str(), "basket")) { 
    718658      if (basketPos > -1) 
    719659        ::raiseError("multiple basket attributes are defined"); 
    720       basketPos = vni - varNames.begin(); 
    721       *ati = 0; 
     660      if (ordered || (classPos == ind) || (*attributeType != -1)) 
     661        ::raiseError("'basket' flag is incompatible with other flags"); 
     662      basketPos = ind; 
     663      *attributeType = 0; 
     664    } 
     665 
     666    if (!*attributeType) 
    722667      continue; 
    723     } 
    724  
    725     if (!attributeDescription) {// this can only be defined if the attribute is a class attribute 
    726       if (*ati==1) { 
    727         metas.push_back(TDomainDepot::TAttributeDescription(*vni, -1, *ti, ordered)); 
    728         attributeDescription = &metas.back(); 
    729       } 
    730       else { 
    731         attributeDescriptions.push_back(TDomainDepot::TAttributeDescription(*vni, -1, *ti, ordered)); 
    732         attributeDescription = &attributeDescriptions.back(); 
    733       } 
    734     } 
    735     else 
    736       attributeDescription->ordered = ordered; 
    737668 
    738669    if (!(*ti).length()) 
     
    743674      if (!(tid->matchRoot ? strncmp(tid->identifier, (*ti).c_str(), tid->matchRoot) 
    744675                           : strcmp(tid->identifier, (*ti).c_str()))) { 
    745         attributeDescription->varType = tid->varType; 
     676        desc.varType = tid->varType; 
    746677        break; 
    747678      } 
     679       
    748680    if (!tid->identifier) { 
    749       attributeDescription->varType = TValue::INTVAR; 
    750       attributeDescription->values = mlnew TStringList; 
     681      desc.varType = TValue::INTVAR; 
    751682 
    752683      string vals; 
    753       ITERATE(string, ci, *ti) 
     684      ITERATE(string, ci, *ti) { 
    754685        if (*ci==' ') { 
    755686          if (vals.length()) 
    756             attributeDescription->values->push_back(vals); 
     687            desc.addValue(vals); 
    757688          vals=""; 
    758689        } 
     
    765696            vals += *ci; 
    766697        } 
     698      } 
    767699 
    768700      if (vals.length()) 
    769         attributeDescription->values->push_back(vals); 
    770     } 
    771   } 
    772  
    773   if (classPos > -1) 
    774     attributeDescriptions.push_back(classDescription); 
    775  
    776   if (basketPos >= 0) 
    777     basketFeeder = mlnew TBasketFeeder(sourceDomain, dontCheckStored, false); 
    778      
    779   if (sourceDomain) { 
    780     if (!domainDepot_tab.checkDomain(sourceDomain.AS(TDomain), &attributeDescriptions, classPos >= 0, NULL)) 
    781       raiseError("given domain does not match the file"); 
    782     else { 
    783       if (basketFeeder) 
    784         basketFeeder->domain = sourceDomain; 
    785       return sourceDomain; 
    786     } 
    787   } 
    788  
    789   int *metaIDs = mlnew int[metas.size()]; 
    790   PDomain newDomain = domainDepot_tab.prepareDomain(&attributeDescriptions, classPos>=0, &metas, sourceVars, sourceMetas, false, dontCheckStored, NULL, metaIDs); 
    791  
    792   int *mid = metaIDs; 
    793   PITERATE(TIntList, ii, attributeTypes) 
    794     if (*ii == 1) 
    795       *ii = *(mid++); 
    796  
    797   mldelete metaIDs; 
    798  
    799   if (basketFeeder) 
    800     basketFeeder->domain = newDomain; 
    801  
    802   return newDomain; 
     701        desc.addValue(vals); 
     702    } 
     703  } 
    803704} 
    804705 
  • source/orange/tabdelim.hpp

    r2775 r3997  
    100100  char *mayBeTabFile(const string &stem); 
    101101  PDomain readDomain(const string &stem, const bool autoDetect, PVarList sourceVars, TMetaVector *sourceMetas, PDomain sourceDomain, bool dontCheckStored, bool dontStore, bool noCodedDiscrete, bool noClass); 
    102   PDomain domainWithDetection(const string &stem, PVarList sourceVars, TMetaVector *sourceMetas, PDomain sourceDomain, bool dontCheckStored, bool noCodedDiscrete, bool noClass); 
    103   PDomain domainWithoutDetection(const string &stem, PVarList sourceVars, TMetaVector *sourceMetas, PDomain sourceDomain, bool dontCheckStored); 
    104  
     102  void readTxtHeader(const string &stem, TDomainDepot::TAttributeDescriptions &); 
     103  void readTabHeader(const string &stem, TDomainDepot::TAttributeDescriptions &); 
     104  int detectAttributeType(TDomainDepot::TAttributeDescription &desc, bool noCodedDiscrete); 
     105  void scanAttributeValues(const string &stem, TDomainDepot::TAttributeDescriptions &desc); 
    105106private: 
    106107  static TDomainDepot domainDepot_tab; 
    107   static TDomainDepot domainDepot_txt; 
    108108}; 
    109109 
  • source/orange/vars.hpp

    r2794 r3997  
    2525 
    2626#include <string> 
     27#include <list> 
     28#include <set> 
    2729#include "orvector.hpp" 
    2830 
     
    7274 
    7375public: 
    74   TVariable(const int &avarType=TValue::NONE, const bool &ordered = false); 
     76  static list<TVariable *> allVariables; 
     77 
     78  void *operator new(size_t s) throw(bad_alloc) 
     79  { 
     80    void *t = ::operator new(s); 
     81    TVariable::allVariables.push_back((TVariable *)t); 
     82    return t; 
     83  } 
     84 
     85  void operator delete(void *t) 
     86  { 
     87    /* When the program shuts down, it may happen that the list is destroyed before 
     88       the variables. We do nothing in this case. */ 
     89    if (allVariables.size()) 
     90      allVariables.remove((TVariable *)t); 
     91       
     92    ::operator delete(t); 
     93  } 
     94 
     95  static TVariable *getExisting(const string &name, const int &varType, TStringList *fixedOrderValues = NULL, set<string> *values = NULL); 
     96   
     97  TVariable(const int &avarType = TValue::NONE, const bool &ordered = false); 
    7598  TVariable(const string &aname, const int &avarType=TValue::NONE, const bool &ordered = false); 
    7699 
     
    132155  virtual bool str2val_try(const string &valname, TValue &valu); 
    133156  virtual void str2val_add(const string &valname, TValue &valu); 
     157 
     158  bool checkValuesOrder(const TStringList &refValues); 
     159  static void presortValues(const set<string> &unsorted, vector<string> &sorted); 
    134160 
    135161private: 
Note: See TracChangeset for help on using the changeset viewer.