Changeset 11697:49d2a5f5db16 in orange


Ignore:
Timestamp:
09/12/13 19:39:21 (7 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Check the values of discrete features in Orange.data.Table constructor.

(references #1322)

Location:
source/orange
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • source/orange/cls_example.cpp

    r11662 r11697  
    8888      if (li == Py_None) { 
    8989        *(ei++) = (*vi)->DK(); 
    90       } 
    91          
    92       else if (PyString_Check(li)) 
     90      } else if (PyString_Check(li)) { 
    9391          (*vi)->str2val(string(PyString_AsString(li)), *(ei++)); 
    94  
    95       else if ((*vi)->varType==TValue::INTVAR) { 
    96         if (PyInt_Check(li)) 
    97           *(ei++)=TValue(int(PyInt_AsLong(li))); 
    98         else { 
    99           PyErr_Format(PyExc_TypeError, "attribute no. %i (%s) is ordinal, string value expected", pos, (*vi)->get_name().c_str()); 
     92      } else if ((*vi)->varType==TValue::INTVAR) { 
     93        if (PyInt_Check(li)) { 
     94          TEnumVariable * enumvar = dynamic_cast<TEnumVariable *>(vi->getUnwrappedPtr()); 
     95          int value = int(PyInt_AsLong(li)); 
     96          if (value < 0 || value >= enumvar->noOfValues()) { 
     97            PyErr_Format(PyExc_ValueError, 
     98                         "value index %i out of range (0 - %i) at attribute no %i (%s)", 
     99                         value, enumvar->noOfValues() - 1, pos, enumvar->get_name().c_str()); 
     100            return false; 
     101          } 
     102          *(ei++) = TValue(value); 
     103        } else { 
     104          PyErr_Format(PyExc_TypeError, "attribute no. %i (%s) is ordinal, string or int value expected", pos, (*vi)->get_name().c_str()); 
    100105          return false; 
    101106        } 
  • source/orange/lib_kernel.cpp

    r11625 r11697  
    29342934 
    29352935 
     2936 
     2937template<typename T> 
     2938int to_int_value(T & value) { 
     2939    return (int)value; 
     2940} 
     2941 
     2942 
     2943template<> 
     2944int to_int_value<float>(float & value) { 
     2945    return (int)floor(0.5 + value); 
     2946} 
     2947 
     2948 
     2949template<> 
     2950int to_int_value<double>(double & value) { 
     2951    return (int)floor(0.5 + value); 
     2952} 
     2953 
     2954 
     2955template<typename T> 
     2956void init_value(TValue & target, TVariable & variable, T & value, bool masked=false) { 
     2957    if (variable.varType == TValue::INTVAR) { 
     2958        TEnumVariable * enumvar = dynamic_cast<TEnumVariable *>(&variable); 
     2959        int ivalue = to_int_value(value); 
     2960        if (enumvar) { 
     2961            if (!masked && (ivalue < 0 || ivalue >= enumvar->noOfValues())) { 
     2962                PyErr_Format(PyExc_ValueError, "Invalid value for a Discrete variable."); 
     2963                throw pyexception(); 
     2964            } 
     2965        } 
     2966        intValInit(target, ivalue, masked ? valueDK : valueRegular); 
     2967    } else { 
     2968        floatValInit(target, (float)value,  masked ? valueDK : valueRegular); 
     2969    } 
     2970} 
     2971 
     2972 
     2973template<typename T> 
     2974void copy_strided_buffer_to_example( 
     2975        TExample & example, 
     2976        char * buffer, Py_ssize_t stride, 
     2977        char * mask_buffer, Py_ssize_t mask_stride) { 
     2978    PDomain domain = example.domain; 
     2979    PVarList vars = domain->variables, class_vars = domain->classVars; 
     2980    TVarList::iterator var_iter = vars->begin(); 
     2981    TValue * value_iter = example.begin(); 
     2982    int pos = 0; 
     2983 
     2984    // copy variables part 
     2985    for (; var_iter != vars->end(); 
     2986            var_iter++, value_iter++, pos++) { 
     2987        init_value(*value_iter, var_iter->getReference(), 
     2988                   *((T *) buffer), mask_buffer && (*mask_buffer)); 
     2989 
     2990        buffer += stride; 
     2991        if (mask_buffer) { 
     2992            mask_buffer += mask_stride; 
     2993        } 
     2994    } 
     2995 
     2996    // copy class vars part 
     2997    for (var_iter = class_vars->begin(); 
     2998            var_iter != class_vars->end(); 
     2999            var_iter++, value_iter++, pos++) { 
     3000        init_value(*value_iter, var_iter->getReference(), 
     3001                   *((T *) buffer), mask_buffer && (*mask_buffer)); 
     3002 
     3003        buffer += stride; 
     3004        if (mask_buffer) { 
     3005        mask_buffer += mask_stride; 
     3006        } 
     3007    } 
     3008} 
     3009 
     3010 
    29363011TExampleTable *readListOfExamples(PyObject *args, PDomain domain, bool filterMetas) 
    29373012{ 
     
    29393014 
    29403015  if (isSomeNumeric_wPrecheck(args)) { 
    2941     array = (PyArrayObject *)(args); 
    2942   } 
    2943   else if (isSomeMaskedNumeric_wPrecheck(args)) { 
    2944     array = (PyArrayObject *)(args); 
     3016    array = (PyArrayObject *)args; 
     3017  } else if (isSomeMaskedNumeric_wPrecheck(args)) { 
     3018    array = (PyArrayObject *)args; 
    29453019    mask = (PyArrayObject *)PyObject_GetAttrString(args, "mask"); 
    29463020    if (!mask) { 
    29473021        PyErr_Clear(); 
    2948     } 
    2949     else if (!isSomeNumeric_wPrecheck((PyObject *)mask)) { 
     3022    } else if (!isSomeNumeric_wPrecheck((PyObject *)mask)) { 
    29503023      Py_DECREF((PyObject *)mask); 
    29513024      mask = NULL; 
     
    30073080      const int &strideMaskCol = mask ? mask->strides[1] : strideCol; 
    30083081 
    3009       TVarList::const_iterator const vb(variables->begin()); 
    3010       TVarList::const_iterator const ve(variables->end()); 
    3011       TVarList::const_iterator const cb(domain->classVars->begin()); 
    3012       TVarList::const_iterator const ce(domain->classVars->end()); 
    3013  
    30143082      try { 
    30153083        TExample::iterator ei; 
     
    30173085        char *maskRowPtr = mask ? mask->data : array->data; 
    30183086 
    3019         for(int row = 0, rowe = array->dimensions[0]; row < rowe; row++, rowPtr += strideRow, maskRowPtr += strideMaskRow) { 
    3020           char *elPtr = rowPtr; 
    3021           char *maskPtr = maskRowPtr; 
     3087        for (int row = 0, rowe = array->dimensions[0]; 
     3088             row < rowe; 
     3089             row++, rowPtr += strideRow, maskRowPtr += strideMaskRow) { 
    30223090          TExample *nex = mlnew TExample(domain); 
    3023  
    3024           #define ARRAYTYPE(TYPE) \ 
    3025             for(ei = nex->begin(), vi = vb; vi!=ve; vi++, ei++, elPtr += strideCol, maskPtr += strideMaskCol) \ 
    3026               if ((*vi)->varType == TValue::INTVAR) \ 
    3027                 intValInit(*ei, *(TYPE *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); \ 
    3028               else \ 
    3029                 floatValInit(*ei, *(TYPE *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); \ 
    3030             for(vi = cb; vi!=ce; vi++, ei++, elPtr += strideCol, maskPtr += strideMaskCol) \ 
    3031               if ((*vi)->varType == TValue::INTVAR) \ 
    3032                 intValInit(*ei, *(TYPE *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); \ 
    3033               else \ 
    3034                 floatValInit(*ei, *(TYPE *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); \ 
    3035             break; 
     3091          char * maskPtr = mask ? maskRowPtr : NULL; 
     3092 
     3093          #define COPY_BUFFER(TYPE) \ 
     3094                  copy_strided_buffer_to_example<TYPE>(*nex, rowPtr, strideCol, maskPtr, strideMaskCol); \ 
     3095                  break; 
    30363096 
    30373097          switch (arrayType) { 
    30383098            case 'c': 
    3039             case 'b': ARRAYTYPE(char) 
    3040             case 'B': ARRAYTYPE(unsigned char) 
    3041             case 'h': ARRAYTYPE(short) 
    3042             case 'H': ARRAYTYPE(unsigned short) 
    3043             case 'i': ARRAYTYPE(int) 
    3044             case 'I': ARRAYTYPE(unsigned int) 
    3045             case 'l': ARRAYTYPE(long) 
    3046             case 'L': ARRAYTYPE(unsigned long) 
    3047  
    3048             case 'f': 
    3049               for(ei = nex->begin(), vi = vb; vi!=ve; vi++, ei++, elPtr += strideCol, maskPtr += strideMaskCol) 
    3050                 if ((*vi)->varType == TValue::INTVAR) 
    3051                   intValInit(*ei, int(floor(0.5 + *(float *)elPtr)), mask && !*maskPtr ? valueDK : valueRegular); 
    3052                 else 
    3053                   floatValInit(*ei, *(float *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); 
    3054               for(vi = cb; vi!=ce; vi++, ei++, elPtr += strideCol, maskPtr += strideMaskCol) 
    3055                 if ((*vi)->varType == TValue::INTVAR) 
    3056                   intValInit(*ei, int(floor(0.5 + *(float *)elPtr)), mask && !*maskPtr ? valueDK : valueRegular); 
    3057                 else 
    3058                   floatValInit(*ei, *(float *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); 
    3059               break; 
    3060  
    3061             case 'd': 
    3062               for(ei = nex->begin(), vi = variables->begin(); vi!=ve; vi++, ei++, elPtr += strideCol, maskPtr += strideMaskCol) 
    3063                 if ((*vi)->varType == TValue::INTVAR) 
    3064                   intValInit(*ei, int(floor(0.5 + *(double *)elPtr)), mask && !*maskPtr ? valueDK : valueRegular); 
    3065                 else 
    3066                   floatValInit(*ei, *(double *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); 
    3067               for(vi = cb; vi!=ce; vi++, ei++, elPtr += strideCol, maskPtr += strideMaskCol) 
    3068                 if ((*vi)->varType == TValue::INTVAR) 
    3069                   intValInit(*ei, int(floor(0.5 + *(double *)elPtr)), mask && !*maskPtr ? valueDK : valueRegular); 
    3070                 else 
    3071                   floatValInit(*ei, *(double *)elPtr, mask && !*maskPtr ? valueDK : valueRegular); 
    3072               break; 
    3073  
     3099            case 'b': COPY_BUFFER(char) 
     3100            case 'B': COPY_BUFFER(unsigned char) 
     3101            case 'h': COPY_BUFFER(short) 
     3102            case 'H': COPY_BUFFER(unsigned short) 
     3103            case 'i': COPY_BUFFER(int) 
     3104            case 'I': COPY_BUFFER(unsigned int) 
     3105            case 'l': COPY_BUFFER(long) 
     3106            case 'L': COPY_BUFFER(unsigned long) 
     3107            case 'f': COPY_BUFFER(float) 
     3108            case 'd': COPY_BUFFER(double) 
    30743109          } 
    30753110 
    3076           #undef ARRAYTYPE 
     3111          #undef COPY_BUFFER 
    30773112 
    30783113          table->addExample(nex); 
Note: See TracChangeset for help on using the changeset viewer.