Repository: bokeh/bokeh

Issue:
Easy Range1d interface
This should work:

```
Range1d(0, 10)
```

as a shorthand for

```
Range1d(start=0, end=10)
```



Discussion:
@shughes-uk would you like to look at this? Basically just adding an `__init__` to `Range1d` that checks for _either_ exactly two positional args, or "start" and "end" in `kwargs`. If two positional args, store them as `"start"` and `"end"` in `kwargs`. In either case then call `super` with just `kwargs`.


Resolving patch:
diff --git a/bokeh/models/ranges.py b/bokeh/models/ranges.py
--- a/bokeh/models/ranges.py
+++ b/bokeh/models/ranges.py
@@ -1,7 +1,7 @@
 from __future__ import absolute_import
 
 from ..plot_object import PlotObject
-from ..properties import Any, Int, Float, Datetime, Instance, List, Either
+from ..properties import Int, Float, String, Datetime, Instance, List, Either
 from .sources import ColumnsRef
 
 class Range(PlotObject):
@@ -12,6 +12,17 @@ class Range1d(Range):
     start = Either(Float, Datetime, Int)
     end = Either(Float, Datetime, Int)
 
+    def __init__(self, *args, **kwargs):
+        if args and ('start' in kwargs or 'end' in kwargs):
+            raise ValueError("'start' and 'end' keywords cannot be used with positional arguments")
+        elif args and len(args) != 2:
+            raise ValueError('Only Range1d(start, end) acceptable when using positional arguments')
+        elif args:
+            kwargs['start'] = args[0]
+            kwargs['end'] = args[1]
+        super(Range1d, self).__init__(**kwargs)
+
+
 class DataRange(Range):
     sources = List(Instance(ColumnsRef))
 
@@ -23,4 +34,11 @@ class DataRange1d(DataRange):
 
 class FactorRange(Range):
     """ Represents a range in a categorical dimension """
-    factors = List(Any)
+    factors = Either(List(String), List(Int))
+
+    def __init__(self, *args, **kwargs):
+        if args and "factors" in kwargs:
+            raise ValueError("'factors' keyword cannot be used with positional arguments")
+        elif args:
+            kwargs['factors'] = list(args)
+        super(FactorRange, self).__init__(**kwargs)


Test patch:
diff --git a/bokeh/tests/test_models_ranges.py b/bokeh/tests/test_models_ranges.py
new file mode 100644
--- /dev/null
+++ b/bokeh/tests/test_models_ranges.py
@@ -0,0 +1,31 @@
+import unittest
+
+
+class TestRange1d(unittest.TestCase):
+
+    def setUp(self):
+        from bokeh.models.ranges import Range1d
+        self.range1d = Range1d
+
+    def test_init(self):
+        self.assertRaises(ValueError, self.range1d, 1, 2, start=1, end=2)
+        self.assertRaises(ValueError, self.range1d, 1, 2, 3)
+        range1d = self.range1d(1, 2)
+        range1d = self.range1d(start=1, end=2)
+
+class TestFactorRange(unittest.TestCase):
+
+    def setUp(self):
+        from bokeh.models.ranges import FactorRange
+        self.factorRange = FactorRange
+
+    def test_init(self):
+        self.assertRaises(ValueError, self.factorRange, [1, 2, 3], factors=[1, 2, 3])
+        self.assertRaises(ValueError, self.factorRange, [1, 2, 3, 4])
+        factorRange = self.factorRange(1, 2)
+        factorRange = self.factorRange(factors=[1, 2, 3, 4, 5])
+
+
+
+if __name__ == "__main__":
+    unittest.main()