Repository: gratipay/gratipay.com

Issue:
Show how many total fundees and the donation amount they're in for.
As a reciever of money I'd like to know how diversified my $13/wk is so that I know how volatile my income is likely to be.

How I see this working is a Histogram similar to:

 $1 [---]  1
 $3 []
 $6 []
$12 [---]  1
$24 []

which shows that I have 2 funders, one in for $1 and one in for $12.



Discussion:

Resolving patch:
diff --git a/gittip/__init__.py b/gittip/__init__.py
--- a/gittip/__init__.py
+++ b/gittip/__init__.py
@@ -215,6 +215,17 @@ def get_tips_and_total(tipper, for_payday=False, db=None):
     return tips, total
 
 
+def get_histogram_of_giving(user):
+    SQL = """
+    SELECT amount, count(amount) num_contributing FROM tips t WHERE
+    tippee=%s GROUP BY (amount)
+    """
+    results = dict()
+    for amount_dict in db.fetchall(SQL, (user,)):
+        results[amount_dict['amount']] = amount_dict['num_contributing']
+    return results
+
+
 # canonizer
 # =========
 # This is an Aspen hook to ensure that requests are served on a certain root


Test patch:
diff --git a/tests/test_stats.py b/tests/test_stats.py
--- a/tests/test_stats.py
+++ b/tests/test_stats.py
@@ -1,7 +1,9 @@
 from datetime import datetime
+from decimal import Decimal
 
 from mock import patch
 
+import gittip
 from gittip.billing.payday import Payday
 from gittip import testing
 from gittip import wireup
@@ -21,6 +23,59 @@ def test_commaize_commaizes_and_obeys_decimal_places():
     assert actual == "1,000.0000", actual
 
 
+class HistogramOfGivingTests(testing.GittipBaseDBTest):
+    def setUp(self):
+        super(HistogramOfGivingTests, self).setUp()
+
+        user_ids = [x[1] for x in testing.GITHUB_USERS]
+        prices = (0, 1, 3, 6, 12, 24)
+        donation_map = {
+            'lgtest': {
+                'lglocktest': 1,
+                'gittip-test-0': 3,
+                'gittip-test-1': 6,
+                'gittip-test-2': 0,
+                },
+            'lglocktest': {
+                'lgtest': 3,
+                'gittip-test-0': 6,
+                'gittip-test-1': 6,
+                'gittip-test-2': 3,
+                },
+            'gittip-test-0': {
+                'lgtest': 12,
+                },
+            'gittip-test-1': {
+                'lgtest': 3,
+                },
+            'gittip-test-2': {
+                'lgtest': 6,
+                },
+            'gittip-test-3': {
+                },
+        }
+        for tipper, donation in donation_map.iteritems():
+            for tippee, amount in donation.iteritems():
+                self.db.execute(
+                    "INSERT INTO tips (ctime, tipper, tippee, amount) " \
+                    "VALUES (now(), %s, %s, %s);",
+                    (tipper, tippee, amount))
+
+    def test_histogram(self):
+        expected = {
+            Decimal('3.00'): 2,
+            Decimal('6.00'): 1,
+            Decimal('12.00'):1
+        }
+        actual = gittip.get_histogram_of_giving('lgtest')
+        self.assertEqual(expected, actual)
+
+    def test_histogram_no_tips(self):
+        expected = {}
+        actual = gittip.get_histogram_of_giving('gittip-test-3')
+        self.assertEqual(expected, actual)
+
+
 # rendering
 
 class TestStatsPage(testing.GittipBaseTest):