From 0c24ce9ac696da94ff9f6d95354022e4b163c2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Dachary?= Date: Tue, 16 Aug 2022 01:40:38 +1000 Subject: [PATCH] implementation of the revenue sharing model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Loïc Dachary --- share.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 share.py diff --git a/share.py b/share.py new file mode 100644 index 0000000..9c7a01d --- /dev/null +++ b/share.py @@ -0,0 +1,35 @@ +# py.test-3 --log-cli-level=DEBUG -v -k test_share_income share.py + +EXPENSE = 1 + +# +# For a given income, return a list of the members who will not be paid in full +# and how much will remain in their expense balance. +# +# See https://forum.hostea.org/t/decision-revenue-sharing-model/92 +# +def share_income(income, members): + if income <= 0: + return members + if income < len(members): + share = 1 + count = income + else: + share = min(int(income / len(members)), min(members, key=lambda m: m[EXPENSE])[EXPENSE]) + count = len(members) + remaining = [] + for i in range(count): + m = members[i] + m[EXPENSE] -= share + if m[EXPENSE] > 0: + remaining.append(m) + remaining.extend(members[count:]) + return share_income(income - share * count, remaining) + +def test_share_income(): + assert share_income(1, [['a', 1], ['b', 1]]) == [['b', 1]] + assert share_income(5, [['a', 10], ['b', 2]]) == [['a', 7]] + assert share_income(5, [['a', 2], ['b', 10], ['c', 1]]) == [['b', 8]] + assert share_income(5, [['a', 2], ['b', 10], ['c', 1], ['d', 40]]) == [['b', 9], ['d', 39]] + assert share_income(5, [['a', 2], ['b', 10], ['c', 1], ['d', 40], ['e', 3]]) == [['a', 1], ['b', 9], ['d', 39], ['e', 2]] + assert share_income(5, [['a', 2], ['b', 10], ['c', 1], ['d', 40], ['e', 3], ['f', 1]]) == [['a', 1], ['b', 9], ['d', 39], ['e', 2], ['f', 1]]