Преглед изворни кода

add `reduce` and `partial`

blueloveTH пре 1 година
родитељ
комит
8ca0e0168c
4 измењених фајлова са 67 додато и 11 уклоњено
  1. 16 0
      docs/modules/functools.md
  2. 0 0
      include/pocketpy/_generated.h
  3. 26 11
      python/functools.py
  4. 25 0
      tests/88_functools.py

+ 16 - 0
docs/modules/functools.md

@@ -0,0 +1,16 @@
+---
+icon: package
+label: functools
+---
+
+### `functools.cache`
+
+A decorator that caches a function's return value each time it is called. If called later with the same arguments, the cached value is returned, and not re-evaluated.
+
+### `functools.reduce(function, sequence, initial=...)`
+
+Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, `functools.reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])` calculates `((((1+2)+3)+4)+5)`. The left argument, `x`, is the accumulated value and the right argument, `y`, is the update value from the sequence. If the optional `initial` is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
+
+### `functools.partial(f, *args, **kwargs)`
+
+Return a new partial object which when called will behave like `f` called with the positional arguments `args` and keyword arguments `kwargs`. If more arguments are supplied to the call, they are appended to `args`. If additional keyword arguments are supplied, they extend and override `kwargs`.

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
include/pocketpy/_generated.h


+ 26 - 11
python/functools.py

@@ -1,13 +1,3 @@
-# def cache(f):
-#     def wrapper(*args):
-#         if not hasattr(f, '__cache__'):
-#             f.__cache__ = {}
-#         key = args
-#         if key not in f.__cache__:
-#             f.__cache__[key] = f(*args)
-#         return f.__cache__[key]
-#     return wrapper
-
 class cache:
 class cache:
     def __init__(self, f):
     def __init__(self, f):
         self.f = f
         self.f = f
@@ -16,4 +6,29 @@ class cache:
     def __call__(self, *args):
     def __call__(self, *args):
         if args not in self.cache:
         if args not in self.cache:
             self.cache[args] = self.f(*args)
             self.cache[args] = self.f(*args)
-        return self.cache[args]
+        return self.cache[args]
+    
+def reduce(function, sequence, initial=...):
+    it = iter(sequence)
+    if initial is ...:
+        value = next(it)
+        if value is StopIteration:
+            raise TypeError("reduce() of empty iterable with no initial value")
+    else:
+        value = initial
+    for element in it:
+        value = function(value, element)
+    return value
+
+class partial:
+    def __init__(self, f, *args, **kwargs):
+        self.f = f
+        if not callable(f):
+            raise TypeError("the first argument must be callable")
+        self.args = args
+        self.kwargs = kwargs
+
+    def __call__(self, *args, **kwargs):
+        kwargs.update(self.kwargs)
+        return self.f(*self.args, *args, **kwargs)
+

+ 25 - 0
tests/88_functools.py

@@ -0,0 +1,25 @@
+# test reduce
+
+from functools import reduce, partial
+
+# test reduce
+assert reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]) == 15
+assert reduce(lambda x, y: x * y, [1, 2, 3, 4, 5]) == 120
+assert reduce(lambda x, y: x * y, [1, 2, 3, 4, 5], 10) == 1200
+
+# test partial
+def add(a, b):
+    return a + b
+
+add_1 = partial(add, 1)
+
+assert add_1(2) == 3
+assert add_1(3) == 4
+
+def sub(a, b=1):
+    return a - b
+
+sub_10 = partial(sub, b=10)
+assert sub_10(20) == 10
+assert sub_10(30) == 20
+

Неке датотеке нису приказане због велике количине промена