Source code for pychemia.utils.computing

from __future__ import print_function, unicode_literals
from builtins import str
from numbers import Number
import gzip
import hashlib
import os
import sys
import zipfile


[docs]def deep_unicode(value): """ Recursively convert to unicode all string-like elements of a complex object. Use with care for objects that could not be converted properly to string This is safe for things like Atom names and symbols :param value: (unicode, list, dict) :return: (str, list, dict) The string, list or dictionary where all string-like elements are converted into strings :rtype : (str, list, dict) Examples: >>> deep_unicode(u'abc') u'abc' >>> deep_unicode([u'abc']) [u'abc'] >>> deep_unicode({u'abc': u'def'}) {u'abc': u'def'} >>> deep_unicode('abc') u'abc' """ if hasattr(value, 'decode'): value = value.decode() if isinstance(value, dict): ret = {} for key in value: ret[deep_unicode(key)] = deep_unicode(value[key]) return ret # This line is Python 2.7+ # return {unicode2string(key): unicode2string(value) for key, value in value.items()} elif isinstance(value, str): return value elif isinstance(value, Number): return value elif value is None: return None else: return value
[docs]def convert_color(s): """ Convert a string hexadecimal representation of a color into a tuple RBG where each element of the tuple is between 0.0 to 1.0 :param s: (str) :return: (tuple) With 3 floats representing the color in RGB :rtype : tuple Examples: >>> convert_color('FF5500') (1.0, 0.3333333333333333, 0.0) """ return float(int(s[:2], 16)) / 255, float(int(s[2:4], 16)) / 255, float(int(s[4:6], 16)) / 255
[docs]def get_int(value): """ Convert a string to an integer :param value: (str) :return: (int) Example: >>> get_int('3') 3 """ if value.isdigit(): return int(value) else: print("ERROR: The value '%s' should be an integer" % value) sys.exit(2)
[docs]def get_float(value): """ Convert a string to a float number :param value: (str) :return: (float) Example: >>> get_float('3.0') 3.0 """ try: ret = float(value) except ValueError: raise ValueError("Could not convert '%s' into a float number" % value) return ret
[docs]def hashfile(filename): """ Get the MD5 hash sum of a given file :param filename: (str) :return: (str) >>> import tempfile >>> a = tempfile.NamedTemporaryFile() >>> hashfile(a.name) 'd41d8cd98f00b204e9800998ecf8427e' >>> a = tempfile.NamedTemporaryFile('w') >>> tmp= a.file.write(128000*'GAF') >>> a.file.flush() >>> hashfile(a.name) '7b8a4f8a3ce222580765d577df78b782' """ blocksize = 65536 hasher = hashlib.md5() with open(filename, 'rb') as afile: buf = afile.read(blocksize) while len(buf) > 0: hasher.update(buf) buf = afile.read(blocksize) return hasher.hexdigest()
[docs]def read_file(filename): """ General function to open files even if they are compressed :param filename: :return: Example: >>> import tempfile >>> a = tempfile.NamedTemporaryFile() >>> read_file(a.name) '' """ if not os.path.exists(filename): raise ValueError('Could not open file: %s' % filename) if filename[-3:] == '.gz': rf = gzip.GzipFile(filename) elif filename[-4:] == '.zip': rf = zipfile.ZipFile(filename) else: rf = open(filename) return rf.read()
[docs]def only_ascii(string): """ Remove non-ascii characters, from monty :param string: :return: Example: >>> only_ascii(u'lmnopq') u'lmnopq' """ return "".join(x for x in string if ord(x) < 128)