{ "info": { "author": "Greg Novak", "author_email": "greg.novak@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3" ], "description": "========\ngsn_util \n========\n\nLike many programmers, I have developed a toolbox of utilities that I\nlike to have close at hand. \n\nFor more information:\nhttp://pypi.python.org/pypi/gsn_util/\n\nFor the source code:\nhttp://launchpad.net/gsn-util\n\nInstallation\n============\n\nYou can use *any* of the following standard incantations:\n\n* pip gsn_util\n* easy_install gsn_util\n* python setup.py install \n\nIf you want to install in your home directory, you can add the --user\nflag to any of the above.\n\nUsage\n=====\n\nThere are many tidbits in this file. Most are self explanatory, some\nI think are rather clever, others lifted from other sources (always\nwith credits in the docstring). If a bit of code doesn't say \"this\nis from ...\" in the docstring, then I wrote it myself.\n\nA few of the highlights:\n\n* def memoize(f)\n\n For any function f, return a caching version of f. Thus if the\n function is called more than once with the same arguments, all calls\n (except for the first one) return the cached result instantly\n\n >>> long_running_function(1.1) # takes a long time\n >>> f = memoize(log_running_function)\n >>> f(2.2) # takes a long time, too\n >>> f(3.3) # Also takes a long time\n >>> f(2.2) # Instantaneous (using the previously cached result)\n\n* def forkify(f)\n\n Return a function that forks and calls f in separate process.\n\n I found this useful for long-running Python processes that handle a\n lot of data and eventually run out of memory. In spite of my best\n efforts at making sure no dangling references were hanging around,\n the most robust solution was to just fork and let the operating\n system handle de-allocation.\n\n So if memory_intensive_function() uses a lot of memory but\n produces small results, then this will prevent out-of-memory\n problems:\n\n >>> f = forkify(memory_intensive_function)\n >>> [f(ii) for ii in huge_list]\n\n Exceptions raised in the child process are caught and re-raised in\n the parent process.\n\n* class SnooperMixin(object):\n\n Snoop on how an object is being used.\n\n Suppose you pass an object into some function and want to know\n what properties of your object the function is using/depending on.\n Normally you do this:\n\n >>> obj = SomeObject() \n >>> opaque_function(obj)\n \n Instead you do the following. Note that there's no body to the\n definition of SnoopedObject.\n\n >>> class SnoopedObject(SnooperMixin, SomeObject): pass\n >>> obj = SnoopedObject()\n >>> opaque_function(obj)\n >>> obj.snoop\n set(['readlines', 'next'])\n\n So you know that opaque_function accessed/used the methods/data\n called readlines and next.\n\n This knowledge, of course, exposes the implementation details of\n opaque_function() and you probably shouldn't write code that\n depends on those details... On the other hand, such knowledge can\n be very illuminating.\n\n The name Mixin comes from the old CLOS (Common Lisp Object System)\n notion of an object that's not itself a fully specified, useful\n object, but is something that's added to other objects to given\n them specific functionality. \n\n* class DotDict(dict) \n\n Behaves like a dictionary, but allows dot access to read attributes.\n \n I use this as a container when I want the container to behave\n exactly like a dictionary, but get tired of typing foo['bar'] and\n want to just type foo.bar instead.\n\n Specifically, I use it to hold data from simulation snapshots. If\n my simulation has a field called \"density\", I'm sure not going to\n type sim['density'] every time I want to do anything. This object\n allows me to refer to it as sim.density instead.\n\n >>> foo = DotDict()\n >>> foo.density = read_from_file()\n >>> plot(foo.density)\n\n Accessing fields like a dict also works:\n\n >>> for kk in foo.keys(): ensure_no_nans(foo[kk])\n\n \"But that's not very object oriented, you should define a\n SimulationData object that has density as an attribute,\" you may\n say. Well.... that's what I've done. I want the SimulationData\n object to have the same things that dict objects have, the keys()\n function, for example. As long as you don't have a simulation data\n field that conflicts with the name of one of the dict methods, this\n causes no problem.\n\n* List manipulation, including: \n\n - ``def cross_set(*sets):``\n\n Given lists, generate all possibilities with the first element\n chosen from the first list, the second element chosen from the\n second, etc. Note that this handles an arbitrary number of sets\n from which to draw.\n \n >>> cross_set([1], [2,3]) \n [[1,2], [1,3]]\n\n - def combinations(lst, n):\n\n Generate all combinations of n items of lst\n \n >>> combinations([1,2,3], 2)\n [[1,2], [1,3], [2,3]]\n\n* Dict manipulation, including: \n\n - def map_dict_tree(f, d):\n\n Map an arbitrarily nested dict of dicts of dicts... The\n recursion stops when a non-dict value is encountered.\n \n >>> obj = dict(a=1, b=dict(c=2, d=dict(e=3, f=4)))\n >>> obj\n {'a': 1, 'b': {'c': 2, 'd': {'e': 3, 'f': 4}}}\n >>> map_dict_tree(lambda x: x+2, obj)\n {'a': 3, 'b': {'c': 4, 'd': {'e': 5, 'f': 6}}}\n \n* Convenient keyword argument list manipulation:\n\n - ``def given(*args):``\n\n Return True if all of the arguments are not None. \n\n Intended for use in argument lists where you can reasonably\n specify different combinations of parameters. Then you can write::\n\n def foo(a=None, b=None, c=None):\n if given(a,b): \n do something\n elif given(a,c): \n do something else\n\n\n - ``def pop_keys(d, *names):``\n\n Pull some keywords from dict d if they exist.\n \n I use this to help with argument processing when I have lots of\n keyword arguments floating around. The typical use is something like::\n\n def foo(**kw):\n kw1 = pop_keys('args', 'for', 'bar')\n bar(**kw1)\n other_function(**kw) # kw doesn't contain the popped keywords anymore\n \n Thus neither bar() nor other_function() get keyword arguments that\n they don't expect. In addition, if the caller *doesn't* specify\n an argument, it doesn't show up in the arg list for the calls to\n bar or other_function, so that the default values are used.\n\n - ``def dict_union(*ds, **kw):``\n\n Combine several dicts and keywords into one dict. I use this\n for argument processing where I want to set defaults in several\n places, sometimes overriding values. The common case is something\n like::\n \n values = dictUntion(global_defaults, local_defaults, key1=val1,\n key2=val2)\n\n where global_defaults and local_defaults are dicts where\n local_defaults overrides global_defaults, and key1 and key2\n override anything in either of the values.\n\n* Composition of function predicates:\n\n - ``def f_or(*fs)``\n - ``def f_and(*fs)``\n - ``def f_not(f)``\n\n The idea is to compose functions using logical operators to make\n compound predicates. Ie, you have functions blue(obj) and\n green(obj) that return True or False depending on whether the object\n is blue or green. You can write::\n\n blue_or_green = f_or(blue, green)\n if blue_or_green(obj): \n do something\n\n* Concise syntax for pickling objects:\n \n Pickling is great, but I do a lot of interactive data analysis, so I\n want syntax for object persistence that's one line and as few\n characters as possible.\n\n >>> can([1,2,3], 'file.dat')\n >>> obj = uncan('file.dat')\n\n* ``def timer(f, *a, **kw):``\n\n Provide reasonably reliable time estimates for a function.\n\n Runs the function once. If the run time is less than timer_tmin,\n run the function timer_factor more times. Repeat until timer_tmin\n is surpassed. If timer_verbose, print what's going on to stdout.\n\n >>> square = lambda x: x**2\n >>> timer(f, 5, timer_tmin=2.0, timer_factor=3, timer_verbose=True)\n\n* def import_graph(with_system=True, out_file=sys.stdout,\n excludes=None, exclude_regexps=None)\n \n Construct a graph of which python modules import which others,\n suitable for consumption by graphviz (http://www.graphviz.org). \n\n This just works on python files in the current directory. It's\n intended to be helpful if you want to reduce dependencies among\n python files in the current directory.\n\n >>> import_graph(out_file='imports.dot')\n # At the Unix shell prompt: \n [novak@thalia ~]$ dot -Tpng imports.dot > imports.png\n\nVersion Information\n===================\n\ngsn_util passes all tests with Python 2.5 through 2.7. \n\nWhen translated to Python 3 via the 2to3 script, gsn_util passes all\ntests on Python 3.1, 3.2, and 3.3. \n\nLicense\n=======\n\nThe code is released under the MIT license, so you should be able to\ndo whatever you want with it. \n\nIf you incorporate this code into a larger project, I would appreciate\nit if you send me a note at greg.novak@gmail.com", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/gsn_util/", "keywords": null, "license": "MIT (X11) License", "maintainer": null, "maintainer_email": null, "name": "gsn_util", "package_url": "https://pypi.org/project/gsn_util/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/gsn_util/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/gsn_util/" }, "release_url": "https://pypi.org/project/gsn_util/0.2.1/", "requires_dist": null, "requires_python": null, "summary": "Toolbox of general-purpose python code.", "version": "0.2.1" }, "last_serial": 792745, "releases": { "0.2.0": [ { "comment_text": "", "digests": { "md5": "1a68dc1119c6d0371599add4c570ebf1", "sha256": "a68ec60497270a94ea7ef314c6d701e963d1e610bf3f3c975430a12ebe75478a" }, "downloads": -1, "filename": "gsn_util-0.2.0.tar.gz", "has_sig": false, "md5_digest": "1a68dc1119c6d0371599add4c570ebf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20660, "upload_time": "2013-04-09T16:55:05", "url": "https://files.pythonhosted.org/packages/9c/c4/76791d59d5c3be2b70967333f3ba61b2bf299b2d0cc22293f280418addad/gsn_util-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "e3872520757c80ed79ac31df6fabebfd", "sha256": "7c9440a0e0812bc719734dc302dffce0477cf504ebdf0d3ffbf48fddc8b8ed3c" }, "downloads": -1, "filename": "gsn_util-0.2.1.tar.gz", "has_sig": false, "md5_digest": "e3872520757c80ed79ac31df6fabebfd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22183, "upload_time": "2013-04-27T18:30:08", "url": "https://files.pythonhosted.org/packages/f8/7a/363ea4b2e1fd3b9216f701a4047a96ea9b41c1620aab3f4f26de2bd17b65/gsn_util-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e3872520757c80ed79ac31df6fabebfd", "sha256": "7c9440a0e0812bc719734dc302dffce0477cf504ebdf0d3ffbf48fddc8b8ed3c" }, "downloads": -1, "filename": "gsn_util-0.2.1.tar.gz", "has_sig": false, "md5_digest": "e3872520757c80ed79ac31df6fabebfd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22183, "upload_time": "2013-04-27T18:30:08", "url": "https://files.pythonhosted.org/packages/f8/7a/363ea4b2e1fd3b9216f701a4047a96ea9b41c1620aab3f4f26de2bd17b65/gsn_util-0.2.1.tar.gz" } ] }