Skip to main content

A small clone of ramda

Project description

python_ramda

This is a repo try to copy https://github.com/ramda/ramda in python.

linting: pylint PyPI version Python Versions codecov

install

For whom wants to use this package.

> pip install python-ramda
> pip install python-ramda -U # get the latest

Usage

>>> from ramda import curry
>>> def sum(a, b, c): return a + b + c
>>> curry(sum)(1)(2, 3)
6
>>> import ramda as R # similar to ramda syntax
>>> def sum(a, b, c): return a + b + c
>>> R.curry(sum)(1)(2, 3)
6

Doc

Because the usage of python_ramda is almostly same to ramda, so we don't create any extra doc.

If you feel any behaviour is different from what is should be in ramda, please check below CheckList for more details.

Contribute

For whom wants to contribute to this repo.

$ pip install -U pylint
# see: https://pre-commit.com/ for more details
$ pre-commit install # please install hooks first

Checkout new branch from main branch directly and create PR.

CheckList

Functions supported now.

  • 0.1.2 __
  • 0.1.2 add
# different from ramda
R.add(None, None) # float('nan)
R.add(date(1,2,3), date(1,2,3)) # float('nan)
  • addIndex
  • 0.1.2 adjust
  • 0.1.2 all
    • Transducer part is not fully tested.
  • allPass
  • 0.1.2 always
  • 0.1.2 And (and is a keyword in python)
  • andThen
  • 0.1.2 any
  • anyPass
  • ap
  • aperture
  • 0.1.2 append
  • apply
  • applySpec
  • applyTo
  • ascend
  • assoc
  • assocPath
  • 0.2.0 binary
  • bind
  • both
  • call
  • chain
  • clamp
  • 0.1.2 clone

we are simply using python copy module So with no specific reason, we suggest you to use python origin copy module as your first choice.

class Obj:
  def __init__(self, x):
    self.value = x
obj = Obj(42)
clone = R.clone(obj)
obj == clone # False, obj and clone have different references
isinstance(clone, Obj) # True

class Obj:
  def __init__(self, x):
    self.value = x

  def __eq__(self, other):
    return self.value == other.value
obj = Obj(42)
clone = R.clone(obj)
obj == clone # True, if Obj override __eq__ function
isinstance(clone, Obj) # True
  • collectBy
  • 0.1.2 comparator
  • complement
  • 0.1.2 compose
  • composeWith
  • 0.1.2 concat
  • cond
  • construct
  • constructN
  • 0.1.4 converge
  • count
  • 0.1.2 countBy
  • 0.1.2 curry
  • 0.1.2 curryN
  • dec
  • defaultTo
  • descend
  • 0.1.2 difference
  • 0.1.2 differenceWith
  • dissoc
  • dissocPath
  • 0.1.2 divide
  • 0.1.2 drop
  • dropLast
  • dropLastWhile
  • dropRepeats
  • dropRepeatsWith
  • dropWhile
  • either
  • 0.1.2 empty
# We don't support empty object in python
class Obj:
  def __init__(self, value):
    self.value = value
o = Obj(42)
o == R.empty(o) # True, we will return the original cloned object

What we support for now:

  1. dict()
  2. set()
  3. list()
  4. str()
  5. any instance with empty() method
  6. any instance with 'fantasy-land/empty' property
  • endsWith
  • eqBy
  • 0.1.2 eqProps
# works for both dict and object
class Obj:
  def __init__(self, v):
    self.v = v
obj1 = Obj(1)
obj2 = Obj(1)
R.eqProps('v', obj1, obj2) # True
R.eqProps('v', {'v': 1}, {'v': 1}) # True
  • 0.1.2 equals
R.equals(float('nan'), float('nan')) # True
  • evolve
  • 0.1.2 F
  • 0.1.2 filter
  • 0.1.2 find
  • 0.1.4 findIndex
  • 0.1.4 findLast
  • 0.1.4 findLastIndex
  • 0.1.2 flatten
  • 0.1.2 flip
  • 0.1.4 forEach
  • forEachObjIndexed
  • fromPairs
  • 0.1.2 groupBy
  • groupWith
  • 0.1.2 gt
  • 0.1.2 gte
  • has
  • hasIn
  • hasPath
  • 0.1.2 head
  • identical
  • 0.1.2 identity
  • ifElse
  • inc
  • includes
  • indexBy
  • 0.1.2 indexOf
  • init
  • innerJoin
  • insert
  • insertAll
  • 0.1.2 intersection
  • intersperse
  • 0.1.2 into
  • invert
  • invertObj
  • 0.1.2 invoker
  • is
  • 0.1.2 isEmpty
class Obj:
  pass
# Any custom object will be treated as non-empty
R.isEmpty(Obj()) # False
R.isEmpty(None) # False
  • isNil
  • 0.1.2 join
  • 0.1.4 juxt
  • 0.1.2 keys
# When using R.keys(obj) and obj is a class instance, we use obj.__dict__ as keys.
class A:
  c = 'not included'
  def __init__(self):
    self.a = 1
    self.b = 2
a = A()
R.keys(a) # ['a', 'b']
# keys include super class attributes
class A:
  def __init__(self, a):
    self.a = a

class B(A):
  def __init__(self, a, b):
    super().__init__(a)
    self.b = b

class C(A):
  def __init__(self, c):
    self.c = c

a = A(1)
b = B(2, 3)
c = C(4)
R.keys(a) # ['a']
R.keys(b) # ['a', 'b']
R.keys(c) # ['c'], because c does not call super().__init__()

# For normal dict
R.keys({'a': 1, 'b': 2}) # ['a', 'b']
  • 0.2.0 keysIn

Different from keys, keysIn will return all attributes of the object, including super class attributes and class static variables.

class A:
  a_static = 1
  def __init__(self):
    self.a = 1
class B(A):
  b_static = 2
  def __init__(self, b):
    super().__init__()
    self.b = b

R.keysIn(A()) # ['a_static', 'a']
R.keysIn(B(2)) # ['a_static', 'a', 'b_static', 'b']

# For normal dict
R.keysIn({'a': 1, 'b': 2}) # ['a', 'b']
  • 0.1.4 last
  • 0.1.2 lastIndexOf
  • length
  • lens
  • lensIndex
  • lensPath
  • lensProp
  • lift
  • liftN
  • 0.1.2 lt
  • 0.1.2 lte
  • 0.1.2 map
  • mapAccum
  • mapAccumRight
  • mapObjIndexed
  • 0.1.2 match
  • mathMod
  • 0.1.2 Max (max is a keyword in python)

If R.Max(a, b) a and b are with different types, we will compare with str(a) and str(b).

R.Max('A', None) # None, 'A' < 'None'
  • maxBy
  • mean
  • median
  • memoizeWith
  • mergeAll
  • mergeDeepLeft
  • mergeDeepRight
  • mergeDeepWith
  • mergeDeepWithKey
  • mergeLeft
  • mergeRight
  • mergeWith
  • mergeWithKey
  • 0.1.2 Min (min is a keyword in python)

If R.Min(a, b) a and b are with different types, we will compare with str(a) and str(b).

R.Min('A', None) # 'A', 'A' < 'None'
  • minBy
  • modify
  • modifyPath
  • 0.1.4 modulo

Python modulo on negative numbers has different behavior than JS.

5 % -3 # -1
5 % -3 // 2
  • move
  • 0.1.2 multiply
  • 0.2.0 nAry
  • negate
  • none
  • 0.1.2 not
  • 0.1.2 nth
  • nthArg
  • o
  • 0.1.2 objOf
  • of
  • 0.1.2 omit

we support both dict type and object type.

class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj = Obj(1, 2)
R.omit(['v1'], obj) # {'v2': 2}
R.omit(['v1', 'v3'], obj) # {'v2': 2}
  • on
  • 0.1.2 once
  • 0.1.2 or
  • otherwise
  • over
  • pair
  • partial
  • partialObject
  • partialRight
  • 0.1.4 partition
  • 0.1.2 path
  • pathEq
  • pathOr
  • 0.1.2 paths
  • pathSatisfies
  • 0.1.2 pick
  • 0.1.2 pickAll

both pick and pickAll support both dict and object type.

class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj = Obj(1, 2)
R.pick(['v1'], obj) # {'v1': 1}
R.pickAll(['v1', 'v3'], obj) # {'v1': 1, 'v3': None}
  • pickBy
  • 0.1.2 pipe
  • pipeWith
  • 0.1.2 pluck
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj1 = Obj(1, 2)
obj2 = Obj(3, 4)
R.pluck('v1', [obj1, obj2]) # [1, 3]
  • 0.1.2 prepend
  • 0.1.2 product
  • 0.1.2 project
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj1 = Obj(1, 2)
obj2 = Obj(3, 4)
R.project(['v1'], [obj1, obj2]) # [{'v1': 1}, {'v1': 3}]
  • promap
  • 0.1.2 prop
  • 0.1.2 propEq
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj1 = Obj(1, 2)
R.propEq(1, 'v1', obj1) # True
R.propEq(2, 'v2', obj1) # True
R.propEq(1, 'v2', obj1) # False

R.propEq(1, 'v1', {'v1': 1}) # True
  • propIs
  • propOr
  • 0.1.2 props
  • propSatisfies
  • 0.1.2 range
  • 0.1.2 reduce
  • 0.1.2 reduceBy
  • 0.1.2 reduced
  • 0.1.2 reduceRight
  • reduceWhile
  • 0.1.2 reject
  • remove
  • 0.1.4 repeat
  • replace
  • 0.1.2 reverse
  • scan
  • sequence
  • set
  • 0.1.2 slice
R.slice(1, 3, ['a', 'b', 'c', 'd']) # ['b', 'c']
R.slice(1, None, ['a', 'b', 'c', 'd']) # ['b', 'c', 'd']
  • 0.1.2 sort
  • 0.1.2 sortBy
  • sortWith
  • 0.1.2 split
  • splitAt
  • splitEvery
  • splitWhen
  • splitWhenever
  • startsWith
  • 0.1.2 subtract
# different from ramda
R.subtract(None, None) # float('nan)
R.subtract(date(1,2,3), date(1,2,3)) # float('nan)
  • 0.1.2 sum
  • symmetricDifference
  • symmetricDifferenceWith
  • 0.1.2 T
  • 0.1.2 tail
  • 0.1.2 take
  • takeLast
  • takeLastWhile
  • 0.1.2 takeWhile
  • 0.1.2 tap
  • test
  • thunkify
  • 0.1.4 times
  • toLower
  • toPairs
  • toPairsIn
  • 0.1.2 toString

Partially supported

  1. String type, supported
  2. for others, just use str(x) instead
  • toUpper
  • transduce
  • transpose
  • traverse
  • trim
  • tryCatch
  • type
  • unapply
  • 0.2.0 unary
  • uncurryN
  • unfold
  • 0.1.2 union
  • 0.1.2 unionWith
  • 0.1.2 uniq
  • 0.1.2 uniqBy
  • 0.1.2 uniqWith
  • unless
  • unnest
  • until
  • unwind
  • update
  • 0.1.2 useWith
  • 0.1.2 values
# works for both dict and object
class Obj:
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
obj = Obj(1, 2)
R.values(obj) # [1, 2]
R.values({'a': 1, 'b': 2}) # [1, 2]
  • 0.2.0 valuesIn

Use R.keysIn to get the keys of an object.

  • view
  • when
  • 0.1.4 where

spec(first param) is prefer to be a dict.

method where supports both dict and object as second param.

class Obj:
  def __init__(self, x, y):
    self.x = x
    self.y = y

spec = {'x': R.equals(1)}
R.where(spec, {'x': 1, 'y': 2}) # True
R.where(spec, Obj(1, 2)) # True
  • whereAny
  • whereEq
  • without
  • xor
  • 0.1.2 xprod
  • 0.1.2 zip
  • zipObj
  • 0.1.2 zipWith

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_ramda-0.2.0.tar.gz (60.2 kB view details)

Uploaded Source

Built Distribution

python_ramda-0.2.0-py3-none-any.whl (132.2 kB view details)

Uploaded Python 3

File details

Details for the file python_ramda-0.2.0.tar.gz.

File metadata

  • Download URL: python_ramda-0.2.0.tar.gz
  • Upload date:
  • Size: 60.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.4

File hashes

Hashes for python_ramda-0.2.0.tar.gz
Algorithm Hash digest
SHA256 82b9a4ea7e743f02df30832e3ae8b4eb3e14ccde2d28850a1689d4393240ff0e
MD5 24ea77899057c387c71cc10fe2c9a58d
BLAKE2b-256 ae0a2f68c2727bd335084e2bf12fee35a2c878f85b20fac8ab5fd26855caaa76

See more details on using hashes here.

File details

Details for the file python_ramda-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: python_ramda-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 132.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.4

File hashes

Hashes for python_ramda-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c33f520bf46b2365fda4fccb43754cbc0e6815b06644ee19eb0cc6ea53592c6
MD5 2793d08acbb7df10cb2ce536eda8d891
BLAKE2b-256 b1fb6bbc54293af809592a021c7a6d5b79f19ab32a9680fc198c4323daf09282

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page