Package: jacktrade
jacktradeJack of all trades, master of none- a collection of commonly used Python utilities. Install using:pip install jacktradeThe package consists of the following submodules:BenchmarkBuffersCollectionsFilesMulticorePicklerSysenvBenchmarkContains aCodeTimerclass which is used to elegantly and precisely time a piece of code:fromjacktradeimportCodeTimerfromtimeimportsleepwithCodeTimer()asct:# Enter code to time heresleep(0.1)# Simulates a piece of code# Prints: "Code execution took 100 ms."(ct.ns,ct.us,ct.ms,ct.s)# Access code duration in nano/micro/milli/seconds.ACodeTimerinstance can also be used as a decorator and store results of repeated function calls inside the list provided asresultsargument:fromjacktradeimportCodeTimerfromtimeimportsleepresults=[]# A list for storing timing results@CodeTimer(no_print=True,results=results)defsleep_ms(milliseconds:int):sleep(milliseconds/1000)sleep_ms(100)# Call wrapped functionsleep_ms(200)# Call againprint(int(results[0].ms))# Prints: "100"print(int(results[1].ms))# Prints: "200"BuffersContains aStringBuffersclass, whose purpose is to reduce the number of I/O operations
when writing to files. By speficyingbuffer_sizeparameter, the contents of the buffer
are automatically flushed to disk when the buffer fills up. The class handles any number
of simultaneously "open" files.fromjacktradeimportStringBuffersoutput_file="out.txt"buffers=StringBuffers(output_dir="text",buffer_size=3)buffers.add(output_file,"Hello")# Nothing is written outbuffers.add(output_file," world")# Nothing is written outbuffers.add(output_file,"!")# "Hello world!" is written to ./text/out.txtCollectionsContains utility functions for working with collections, namely dictionaries and iterables. Usage examples include:fromjacktradeimport*# Dict utilitiesdict_data={"a":1,"b":{"c":2}}flatten_dict(dict_data)# Returns: [1, 2]get_first_dict_item(dict_data)# Returns: ("a", 1)get_first_dict_key(dict_data)# Returns: "a"get_first_dict_value(dict_data)# Returns: 1# Iterable utilitieslist_data=[1,2,[3,4],5,6]flatten_list(list_data)# Returns: [1, 2, 3, 4, 5, 6]chunkify(list_data,chunk_size=2)# Yields: [1, 2], [[3, 4], 5], [6]limit_iterator(list_data,limit=3)# Yields: 1, 2, [3, 4]MasterDictis a wrapper class holding multiple dictionaries. It provides methods for simultaneously deleting keys from all underlying dictionaries, as well as clearing them. It is intended to hold caches and reliably empty them with a single method call.fromjacktradeimportMasterDictdicts=MasterDict(a={1:"1",2:"2"},b={1:"1",3:"3"},c={4:"4"})dicts.delete_keys(1,3)# Delete keys 1 and 3 from all dictionariesdicts.as_dict()# Returns:  {'a': {2: '2'}, 'b': {}, 'c': {4: '4'}}dicts.clear_all()# Clear all dictionariesdicts.as_dict()# Returns:  {'a': {}, 'b': {}, 'c': {}}BaseMappingis a generic base class used to createdictsubclasses which automatically map keys to values from a collection of objects of the same type. It is used like so:fromjacktradeimportBaseMappingclassNameAgeLookup(BaseMapping):"""Maps a person's name to its age if the person is over 18 years old."""def__init__(self,persons):super().__init__(items=persons,key_getter=lambdap:p["name"],value_getter=lambdap:p["age"],condition=lambdap:p["age"]>18,)mapping=NameAgeLookup([{"name":"Jack","age":15},{"name":"Mike","age":27},{"name":"Pete","age":39},])# Assertions passassertmapping=={"Mike":27,"Pete":39}assertmapping.invert()=={27:"Mike",39:"Pete"}Permutationsclass is used for parametrisation, returning all possible combinations of input parameters:fromjacktradeimportPermutationsp=Permutations(a=[1,2,3],b=["A","B"])p.args# Returns: [(1, "A"), (1, "B"), (2, "A"), (2, "B"), ...]p.kwargs# Returns: [{"a": 1, "b": "A"}, {"a": 1, "b": "B"}, ...]forkwargsinp:# yields:# {"a": 1, "b": "A"}# {"a": 1, "b": "B"}# ...FilesProvides utilities for working with files. Currently it contains only a single function for merging CSV files.fromjacktradeimportmerge_csv_files# Merges A.csv and B.csv into AB.csv without duplicating headersmerge_csv_files(["A.csv","B.csv"],"AB.csv")# Merges A.csv and B.csv into AB.csv verbatim, treating headers as datamerge_csv_files(["A.csv","B.csv"],"AB.csv",has_headers=False)MulticoreProvides an elegant and memory-efficient way to process data using multiple cores. The main advantage of usingdo_multicore_workfunction over manually usingconcurrent.futuresormultiprocessingmodules is that new jobs are only submitted for execution when a CPU core is available. This optimises CPU and RAM usage. Using the aforementioned modules directly, it is all too easy to inadvarently cause memory leaks and crash the interpreter (if not the whole system).Usage example (does not work in the interactive interpreter):fromjacktradeimportdo_multicore_workdefworker(first,second)->tuple:"""Receives two arguments and returns them as a tuple."""return(first,second)defworker_done_callback(future):"""Called whenever a worker process terminates and returns a result."""print(future.result())if__name__=="__main__":do_multicore_work(worker,args=[(1,2),(3,4),(5,6)],worker_done_callback=worker_done_callback)# Prints: (1, 2)\n(3, 4)\n(5, 6)\nPicklerThis tiny module contains two convenience functions for pickling and unpickling Python objects, making it possible to do so with a single function call (a feature missing frompicklemodule):fromjacktradeimportpickle_object,unpickle_objectpickle_object(obj:=[1,2,3],filename:="obj.pickle")# Pickles obj to obj.pickle fileassertunpickle_object(filename)==obj# Unpickle obj.pickle and test equality with objSysenvContains utilities for interacting with the operating system and the environment.fromjacktradeimportin_virtual_environment# Power managementsuspend()# Put the machine into standbyhibernate()# Hibernate the machinerestart()# Restart the machineshutdown()# Shut down the machine# Miscellaneousin_virtual_environment()# True if called inside venv, else False