Commits

Janez Demšar  committed d374411

Added property 'name' that resolves to an attribute name, if it exists,
otherwise it returns the class name with the first letter in lowercase and
without the suffix 'Learner', 'Classifier' or 'Discretization'.

  • Participants
  • Parent commits 25c41cd

Comments (0)

Files changed (2)

File Orange/testing/unit/tests/test_name.py

+import orange
+import Orange
+import unittest
+
+class TestName(unittest.TestCase):
+    def test_Learner(self):
+        b = orange.BayesLearner()
+        self.assertEqual(b.name, "bayes")
+        b.name = "foo"
+        self.assertEqual(b.name, "foo")
+        b.name = "BayesLearner"
+        self.assertEqual(b.name, "BayesLearner")
+        b.name = "x.BayesLearner"
+        self.assertEqual(b.name, "x.BayesLearner")
+        b.name = ""
+        self.assertEqual(b.name, "")
+
+    def test_class(self):
+        class MyBla(orange.BayesLearner):
+            pass
+        b = MyBla()
+        self.assertEqual(b.name, "myBla")
+        b.name = "foo"
+        self.assertEqual(b.name, "foo")
+
+    def test_classLearner(self):
+        class MyBlaLearner(orange.BayesLearner):
+            pass
+        b = MyBlaLearner()
+        self.assertEqual(b.name, "myBla")
+
+    def test_class_short(self):
+        class A(orange.BayesLearner):
+            pass
+        b = A()
+        self.assertEqual(b.name, "a")
+        b.name = "foo"
+        self.assertEqual(b.name, "foo")
+
+    def test_Discretizer(self):
+        b = orange.EquiDistDiscretizer()
+        # The class is renamed internally
+        # "Discretizer" is removed and E is changed to e
+        self.assertEqual(b.name, "equalWidth")
+
+    def test_Classifier(self):
+        b = orange.TreeClassifier()
+        self.assertEqual(b.name, "tree")
+
+    def test_Orange(self):
+        b = Orange.classification.bayes.NaiveLearner()
+        self.assertEqual(b.name, "naive")
+
+    def test_static_name(self):
+        # Tests that class attributes work and are left
+        # (stripping off 'Learner' and lower cases are
+        # applied only to class names
+        class NaiveLearner(orange.BayesLearner):
+            name = "BayesLearner"
+        b = NaiveLearner()
+        self.assertEqual(b.name, "BayesLearner")
+
+
+if __name__ == "__main__":
+    unittest.main()

File source/orange/cls_orange.cpp

       {}
     }
  
-    if (!strcmp(name, "name") || !strcmp(name, "shortDescription") || !strcmp(name, "description"))
-      return PyString_FromString("");
-
     PyErr_Format(PyExc_AttributeError, "'%s' has no attribute '%s'", self->ob_type->tp_name, name);
     return PYNULL;
   PyCATCH;
 }
 
 
+char const *genericNames[] = {"Classifier", "Learner", "Discretizer", NULL};
+
+PyObject *Orange_get_name(TPyOrange *self)
+{
+  PyTRY
+    PyObject *pyname = Orange_getattr1(self, "name");
+    if (!pyname) { 
+      PyErr_Clear();
+      if (self->orange_dict) {
+        pyname = PyDict_GetItemString(self->orange_dict, "name");
+        Py_XINCREF(pyname);
+      }
+    }
+    if (pyname) {
+      if (PyString_Check(pyname)) {
+        return pyname;
+      }
+      PyObject *pystr = PyObject_Repr(pyname);
+      Py_DECREF(pyname);
+      return pystr;
+    }
+
+    char const *tp_name = self->ob_type->tp_name;
+    char const *dotp = tp_name + strlen(tp_name);
+    while((dotp != tp_name) && (*dotp != '.')) {
+      dotp--;
+    }
+	if (*dotp == '.') {
+	  dotp++;
+	}
+	if (*dotp == '_') {
+	  dotp++;
+	}
+    char *name = (char *)malloc(strlen(dotp) + 1);
+    strcpy(name, dotp);
+
+	const int lenname = strlen(name);
+	char *nameend = name + lenname;
+    for(char const *const *gen = genericNames; *gen; gen++) {
+		if (strlen(*gen) < lenname) {
+		    char *cap = nameend - strlen(*gen);
+		    if (!strcmp(cap, *gen)) {
+              *cap = 0;
+              break;
+			}
+		}
+	}
+    if ((*name >= 'A') && (*name <= 'Z')) {
+      *name ^= 32;
+      }
+    return PyString_FromString(name);
+  PyCATCH
+}
+
+
+
+int Orange_set_name(TPyOrange *self, PyObject *arg)
+{
+  PyTRY
+    int res = Orange_setattr1(self, "name", arg);
+    if (res == 1) {
+        res = Orange_setattrDictionary(self, "name", arg, false);
+    }
+    return res;
+  PyCATCH_1
+}
+
+
 int Orange_nonzero(PyObject *self)
 { PyTRY
     if (self->ob_type->tp_as_sequence && self->ob_type->tp_as_sequence->sq_length)