changeset 5:dbbf5344868c

add utlities for casting data
author Jeff Hammel <k0scist@gmail.com>
date Sun, 10 Dec 2017 11:51:39 -0800
parents 9575c4a925c1
children 244c29f46554
files lemuriformes/cast.py
diffstat 1 files changed, 105 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemuriformes/cast.py	Sun Dec 10 11:51:39 2017 -0800
@@ -0,0 +1,105 @@
+"""
+methods for casting data
+"""
+
+import datetime
+from collections import OrderedDict
+
+
+try:
+    # python2
+    string = (str, unicode)
+except NameError:
+    # python3
+    string = (str,)
+
+def isstring(f):
+    return isinstance(f, string)
+
+# types we expect to encounter
+types = OrderedDict([('int', int),
+                     ('float', float),
+                     ('str', str)])
+
+
+def keyvalue(_string, separator='='):
+    """
+    cast `_string` to [`key`, `value`] split on `separator`
+    """
+
+    if separator not in _string:
+        raise AssertionError("Separator '{}' not in '{}'".format(separator,
+                                                                 _string))
+    return _string.split(separator, 1)
+
+
+def string_to_bool(string):
+    """cast a string to a `bool`"""
+    return {'true': True,
+            'false': False}.get(string.lower())
+
+
+def unify(item, codec='utf-8'):
+    """cast item to unicode carefully if a string;  otherwise, return it"""
+
+    if not isinstance(item, string):
+        return item
+    return item.encode(codec, 'ignore')
+
+
+def datetime_handler(x):
+    """handler for JSON serialization"""
+
+    # Ref
+    # https://stackoverflow.com/questions/35869985/datetime-datetime-is-not-json-serializable
+    if isinstance(x, datetime.datetime):
+        return x.isoformat()
+
+    # go through the normal types for type casting
+    # (and hope nothing "weird" happens")
+    for _type in types.values():
+        try:
+            return str(_type(x))
+        except ValueError:
+            continue
+
+    # worst case scenario
+    raise TypeError("Unknown type: {x}".format(x=x))
+
+
+def isiterable(obj):
+    """determines if `obj` is iterable"""
+
+    try:
+        iter(obj)
+        return True
+    except TypeError:
+        return False
+
+
+def iterable(obj):
+    """make an iterable out of `obj`"""
+    return obj if isiterable(obj) else (obj,)
+
+
+def infer(strings, types=types.values()):
+    """
+    inferrred the type of a bunch of strings
+    """
+    for _type in types:
+        for s in strings:
+            try:
+                _type(s)
+            except ValueError:
+                break
+        else:
+            return _type
+
+
+def cast(strings, types=types.values()):
+    """
+    cast `strings` to `types` based on inference
+    """
+
+    _type = infer(strings, types=types)
+    return [_type(s) for s in strings]