1. Jonathan Eunice
  2. intensional

Commits

Jonathan Eunice  committed ff358ad

updated

  • Participants
  • Parent commits edb5327
  • Branches default

Comments (0)

Files changed (4)

File README.rst

View file
 ``for`` loop.
 
 Once you know what you're looking for, intensional sets are *everywhere*.
-
 Python doesn't represent them directly, but regular expressions, many list
 comprehensions, and all manner of testing and filtering operations are really
 faces of the intensional set concept. Many functions test whether something
 that pass the test.
 
 Many such tests have a temporal aspect--they determine whether a value is a
-member at the time of the test. In the future, the answer may change, if
-conditions change. Others are invariant over time. ``%%734`` will never be a
+member *right now*. The answer may change in the future, if
+conditions change. Others tests are invariant over time. ``%%734`` will never be a
 valid Python identifier, no matter how many times it's tested--unless the rules
-of the overall Python universe change.
+of the overall Python universe change, that is.
 
 Intensional sets are part and parcel of all programming, even if they're not
-called by that name or explictly manifested. ``intensional`` helps Python
-prograims represent intensional sets directly. 
+explicitly represented or called by that name.``intensional`` helps Python
+programs represent intensional sets directly. This provides several interesting
+improvements:
+
+  * A nicer way to use regular expressions
+  * A ``switch`` statement (actually, function) for Python
+
 
 Usage
 =====
 
 Instead of::
 
+    import re
+    
     match = re.search(r'(pattern\w*)', some_string)
     if match:
         print match.group(1)
 
 You can do an *en passant* test::
 
+    from intensional import Re
+    
     if some_string in Re(r'(pattern\w*)'):
         print _[1]
         
 Note this turns the sense of the matching around, asking "is a given string *in*
-this pattern?" The ``Re`` pattern is an intensionally defined set--namely, the
+the set of items this pattern describes?" The ``Re`` pattern is an intensionally defined set--namely, the
 set of all strings matching the pattern. This makes excellent sene in cases where
 you have a clear intent for the match--for example, determining "is the given string
 within the set of *all legitimate commands*?"

File intensional.py

View file
     __metaclass__ = MementoMetaclass
     
     
-# need to complete more of the set functions like union, difference, etc
+# Any = Union, Every = Intersection
+# might want to complete more of the set functions like symmetric difference, discard, etc
+
 
 
 class ReMatch(orderedstuf):
                     return False
         return True
 
-   
+class ButNot(IntensionalSet):
+    """
+    An item is in a ButNot if it's in the primary set and not the exclusion.
+    """
+    
+    def __init__(self, items, exclusion):
+        self.items = items
+        self.exclusion = exclusion
+
+    def __contains__(self, item):
+        if item == self.items or item in self.items:
+            if item != self.exclusion and item not in self.exclusion:
+                return True
+        return False
+
 class Test(IntensionalSet):
     
     def __init__(self, expr, *args, **kwargs):
             raise ValueError('expr needs to be string or callable')
         
     def __contains__(self, item):
-        return self.func(item, *self.args, **self.kwargs)
+        try:
+            return self.func(item, *self.args, **self.kwargs)
+        except StandardError:
+            return False
+        
+        # NB failure to run test => fails test
+        # might silently hide syntax errors and such
+        # do we want a mode or mechanism to make such errors into Warnings?

File setup.py

View file
 
 setup(
     name='intensional',
-    version=verno("0.01"),
+    version=verno("0.012"),
     author='Jonathan Eunice',
     author_email='jonathan.eunice@gmail.com',
     description='Intensional sets in Python',

File test/test.py

View file
     assert 2 in ext
     assert 33 not in ext
     print ext
+    a2 = Any(12, Test('x.startswith("k")'))
+    assert 12 in a2
+    assert "kaboom" in a2
+    assert "laboom" not in a2
+    assert 33 not in a2
+    
+def test_Every():
+    e = Every(1)
+    assert 1 in e
+    assert 4 not in e
+    e2 = Every(Test('x > 12'), Test('x > 33'))
+    assert 44 in e2
+    assert 55 in e2
+    assert 0 not in e2
+    assert 18 not in e2
+    
+    e3 = Every(Test('x.startswith("r")'), Test('len(x) <= 5'))
+    
+    assert 'roger' in e3
+    assert 'roof'  in e3
+    assert 'roofer' not in e3
+    
+    # diffent way of stating e3
+    e3a = Every(Test('x.startswith("r") and len(x) <= 5'))
+
+    assert 'roger' in e3a
+    assert 'roof'  in e3a
+    assert 'roofer' not in e3a
+
+    # yet another way of stating e3
+    e3b = Test('x.startswith("r") and len(x) <= 5')
+
+    assert 'roger' in e3b
+    assert 'roof'  in e3b
+    assert 'roofer' not in e3b
+    
+    # any way to link to Python all and any?
+
+def test_ButNot():
+
+    a2 = Any(12, Test('x.startswith("k")'))
+    assert 12 in a2
+    assert "kaboom" in a2
+    assert "laboom" not in a2
+    assert 33 not in a2
+    
+    bn = ButNot(a2, Any(12, 'kookoo'))
+    assert 'kookoo' in a2
+    assert 'kookoo' not in bn
+    assert 'kaboom' in bn
+    assert 'laboom' not in bn
+    assert 12 in a2
+    assert 12 not in bn
+    
     
 def test_Test():
     mytest = Test('x.startswith("a")')