Package: pamda
PamdaPython wrapper for functional programming in object oriented structures.Inspired heavily byRamda.Documentation for Pamda Functionshttps://connor-makowski.github.io/pamda/pamda/pamda.htmlKey FeaturesSimplified functional programming for pythonCore Functions include:curryarbitrary methods and functionsthunkifyarbitrary methods and functionspipedata iteratively through n functionsList based path access and features for nested dictionariesSetupMake sure you have Python 3.9.x (or higher) installed on your system. You can download ithere.Installationpip install pamdaGetting StartedBasic Usagefrompamdaimportpamdadata={'a':{'b':1,'c':2}}# Example: Select data given a path and a dictionarypamda.path(['a','b'])(data)#=> 1# See documentation for all core pamda functions at# https://connor-makowski.github.io/pamda/pamda.htmlCurry Usagefrompamdaimportpamda# Define a function that you want to currydefmyFunction(a,b,c):return[a,b,c]# You can call pamda.curry as a function to curry your functionscurriedMyFn=pamda.curry(myFunction)# Inputs can now be passed in an async fashion# The function is evaluated when all inputs are addedx=curriedMyFn(1,2)x(3)#=> [1,2,3]x(4)#=> [1,2,4]# Each set of inputs returns a callable function# You can stack inputs on a single line for clean functional programmingcurriedMyFn(1,2)(3)#=> [1,2,3]For enforcing types, pamda relies ontype_enforcedbut curried objects do not play nice withtype_enforcedobjects. To fix this, there is a special curry function,curryType, that enables type_enforced annotations for your curried functions:>>>frompamdaimportpamda>>>>>># Pamda CurryTyped>>>@pamda.curryTyped...defadd(a:int,b:int):...returna+b...>>>add(1)(1)2>>>add(1)(1.5)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/home/conmak/development/personal/pamda/pamda/pamda_curry.py",line43,in__call__results=self.__fnExecute__(*new_args,**new_kwargs)File"/home/conmak/development/personal/pamda/venv/lib/python3.10/site-packages/type_enforced/enforcer.py",line90,in__call__self.__check_type__(assigned_vars.get(key),value,key)File"/home/conmak/development/personal/pamda/venv/lib/python3.10/site-packages/type_enforced/enforcer.py",line112,in__check_type__self.__exception__(File"/home/conmak/development/personal/pamda/venv/lib/python3.10/site-packages/type_enforced/enforcer.py",line34,in__exception__raiseTypeError(f"({self.__fn__.__qualname__}):{message}")TypeError:(add):Typemismatchfortypedvariable`b`.Expectedoneofthefollowing`[<class'int'>]` but got `<class 'float'>` instead.Thunkify Usagefrompamdaimportpamda# Define a function that you want to thunkify# thunkify can be called as a function or decorator@pamda.thunkifydefmyFunction(a,b,c):return[a,b,c]# The function is now curried and the evaluation is lazy# This means the function is not evaluated until calledx=myFunction(1,2)x(3)#=> <pamda.curry_obj object at 0x7fd514e4c820>x(3)()#=> [1,2,3]y=x(4)y()#=> [1,2,4]Thunkified functions can be executed asynchronously.frompamdaimportpamdaimporttime@pamda.thunkifydeftest(name,wait):print(f'{name}start')time.sleep(wait)print(f'{name}end')returnwaitasync_test_a=pamda.asyncRun(test('a',2))async_test_b=pamda.asyncRun(test('b',1))async_test_a.asyncWait()async_test_c=pamda.asyncRun(test('c',1))The above code would output:a start
b start
b end
a end
c start
c endPipefrompamdaimportpamdadefsquare(x):returnx**2defhalf(x):returnx/2defnegate(x):return-x# You can pipe data through multiple functions for clean functional programmingpamda.pipe([square,half,negate])(args=(6,),kwargs={})#=> -18Use pamda as a subclassfrompamdaimportpamdaclassmyClass(pamda):defmyFunction(self,a):returnself.inc(a)mc=myClass()mc.myFunction(2)#=> 3@mc.currydefaddUp(a,b):returna+baddUp(1)(2)#=> 3Pamda UtilsPamda also ships with a few helpful utilitiesCheck out the documentation here:https://connor-makowski.github.io/pamda/pamda_utils.html