We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
VirtualEnv error with Windows + Vagrant
No idea where to even start with this one. Fresh clone with fresh vagrant box. 

Here's the weird part, at home my Windows 8.1 x64 computer experiences this problem but my Windows 7 x64 computer at work doesn't. This also happens to @abnor

```
vagrant@precise64:~/www.gittip.com$ make clean env
rm -rf env *.egg *.egg-info
find . -name \*.pyc -delete
"/usr/bin/python2.7"  "./vendor/virtualenv-1.9.1.py"\
                                --unzip-setuptools \
                                --prompt="[gittip] " \
                                --never-download \
                                --extra-search-dir=./vendor/ \
                                --distribute \
                                ./env/
Traceback (most recent call last):
  File "./vendor/virtualenv-1.9.1.py", line 2577, in <module>
    main()
  File "./vendor/virtualenv-1.9.1.py", line 979, in main
    no_pip=options.no_pip)
  File "./vendor/virtualenv-1.9.1.py", line 1081, in create_environment
    site_packages=site_packages, clear=clear))
  File "./vendor/virtualenv-1.9.1.py", line 1275, in install_python
    copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
  File "./vendor/virtualenv-1.9.1.py", line 437, in copyfile
    copyfileordir(src, dest)
  File "./vendor/virtualenv-1.9.1.py", line 412, in copyfileordir
    shutil.copytree(src, dest, True)
  File "/usr/lib/python2.7/shutil.py", line 206, in copytree
    raise Error, errors
shutil.Error: [('/usr/lib/python2.7/config/libpython2.7.so', './env/lib/python2.
7/config/libpython2.7.so', '[Errno 71] Protocol error')]
make: *** [env] Error 1
```

<bountysource-plugin>

---

Want to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/1846612-virtualenv-error-with-windows-vagrant?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github).
</bountysource-plugin>

fake_data generates 0.00 transfers that break positive constraint
Running fake_data may yield:

```
==> basebox: psycopg2.IntegrityError: new row for relation "transfers" violates check constraint "positive"
==> basebox: DETAIL:  Failing row contains (578395790, 2014-08-20 12:00:37+00, Dominicbdp, Katharina92q, 0.00, tip).
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gratipay/utils/fake_data.py`
Content:
```
1 from faker import Factory
2 from gratipay import wireup, MAX_TIP_SINGULAR, MIN_TIP
3 from gratipay.elsewhere import PLATFORMS
4 from gratipay.models.participant import Participant
5 
6 import datetime
7 import decimal
8 import random
9 import string
10 
11 
12 faker = Factory.create()
13 
14 
15 def _fake_thing(db, tablename, **kw):
16     column_names = []
17     column_value_placeholders = []
18     column_values = []
19 
20     for k,v in kw.items():
21         column_names.append(k)
22         column_value_placeholders.append("%s")
23         column_values.append(v)
24 
25     column_names = ", ".join(column_names)
26     column_value_placeholders = ", ".join(column_value_placeholders)
27 
28     db.run( "INSERT INTO {} ({}) VALUES ({})"
29             .format(tablename, column_names, column_value_placeholders)
30           , column_values
31            )
32     return kw
33 
34 
35 def fake_text_id(size=6, chars=string.ascii_lowercase + string.digits):
36     """Create a random text id.
37     """
38     return ''.join(random.choice(chars) for x in range(size))
39 
40 
41 def fake_balance(max_amount=100):
42     """Return a random amount between 0 and max_amount.
43     """
44     return random.random() * max_amount
45 
46 
47 def fake_int_id(nmax=2 ** 31 -1):
48     """Create a random int id.
49     """
50     return random.randint(0, nmax)
51 
52 
53 def fake_sentence(start=1, stop=100):
54     """Create a sentence of random length.
55     """
56     return faker.sentence(random.randrange(start,stop))
57 
58 
59 def fake_participant(db, number="singular", is_admin=False):
60     """Create a fake User.
61     """
62     username = faker.first_name() + fake_text_id(3)
63     _fake_thing( db
64                , "participants"
65                , id=fake_int_id()
66                , username=username
67                , username_lower=username.lower()
68                , statement=fake_sentence()
69                , ctime=faker.date_time_this_year()
70                , is_admin=is_admin
71                , balance=fake_balance()
72                , anonymous_giving=(random.randrange(5) == 0)
73                , anonymous_receiving=(random.randrange(5) == 0)
74                , goal=fake_balance()
75                , balanced_customer_href=faker.uri()
76                , last_ach_result=''
77                , is_suspicious=False
78                , last_bill_result=''  # Needed to not be suspicious
79                , claimed_time=faker.date_time_this_year()
80                , number=number
81                 )
82     #Call participant constructor to perform other DB initialization
83     return Participant.from_username(username)
84 
85 
86 
87 def fake_tip_amount():
88     amount = ((decimal.Decimal(random.random()) * (MAX_TIP_SINGULAR - MIN_TIP))
89             + MIN_TIP)
90 
91     decimal_amount = decimal.Decimal(amount).quantize(decimal.Decimal('.01'))
92 
93     return decimal_amount
94 
95 
96 def fake_tip(db, tipper, tippee):
97     """Create a fake tip.
98     """
99     return _fake_thing( db
100                , "tips"
101                , id=fake_int_id()
102                , ctime=faker.date_time_this_year()
103                , mtime=faker.date_time_this_month()
104                , tipper=tipper.username
105                , tippee=tippee.username
106                , amount=fake_tip_amount()
107                 )
108 
109 
110 def fake_elsewhere(db, participant, platform):
111     """Create a fake elsewhere.
112     """
113     _fake_thing( db
114                , "elsewhere"
115                , id=fake_int_id()
116                , platform=platform
117                , user_id=fake_text_id()
118                , user_name=participant.username
119                , is_locked=False
120                , participant=participant.username
121                , extra_info=None
122                 )
123 
124 
125 def fake_transfer(db, tipper, tippee):
126         return _fake_thing( db
127                , "transfers"
128                , id=fake_int_id()
129                , timestamp=faker.date_time_this_year()
130                , tipper=tipper.username
131                , tippee=tippee.username
132                , amount=fake_tip_amount()
133                , context='tip'
134                 )
135 
136 
137 def populate_db(db, num_participants=100, num_tips=200, num_teams=5, num_transfers=5000):
138     """Populate DB with fake data.
139     """
140     #Make the participants
141     participants = []
142     for i in xrange(num_participants):
143         participants.append(fake_participant(db))
144 
145     #Make the "Elsewhere's"
146     for p in participants:
147         #All participants get between 1 and 3 elsewheres
148         num_elsewheres = random.randint(1, 3)
149         for platform_name in random.sample(PLATFORMS, num_elsewheres):
150             fake_elsewhere(db, p, platform_name)
151 
152     #Make teams
153     for i in xrange(num_teams):
154         t = fake_participant(db, number="plural")
155         #Add 1 to 3 members to the team
156         members = random.sample(participants, random.randint(1, 3))
157         for p in members:
158             t.add_member(p)
159 
160     #Make the tips
161     tips = []
162     for i in xrange(num_tips):
163         tipper, tippee = random.sample(participants, 2)
164         tips.append(fake_tip(db, tipper, tippee))
165 
166 
167     #Make the transfers
168     transfers = []
169     for i in xrange(num_transfers):
170         tipper, tippee = random.sample(participants, 2)
171         transfers.append(fake_transfer(db, tipper, tippee))
172 
173 
174     #Make some paydays
175     #First determine the boundaries - min and max date
176     min_date = min(min(x['ctime'] for x in tips), \
177                    min(x['timestamp'] for x in transfers))
178     max_date = max(max(x['ctime'] for x in tips), \
179                    max(x['timestamp'] for x in transfers))
180     #iterate through min_date, max_date one week at a time
181     date = min_date
182     while date < max_date:
183         end_date = date + datetime.timedelta(days=7)
184         week_tips = filter(lambda x: date <= x['ctime'] <= end_date, tips)
185         week_transfers = filter(lambda x: date <= x['timestamp'] <= end_date, transfers)
186         week_participants = filter(lambda x: x.ctime.replace(tzinfo=None) <= end_date, participants)
187         actives=set()
188         tippers=set()
189         for xfers in week_tips, week_transfers:
190             actives.update(x['tipper'] for x in xfers)
191             actives.update(x['tippee'] for x in xfers)
192             tippers.update(x['tipper'] for x in xfers)
193         payday = {
194             'id': fake_int_id(),
195             'ts_start': date,
196             'ts_end': end_date,
197             'ntips': len(week_tips),
198             'ntransfers': len(week_transfers),
199             'nparticipants': len(week_participants),
200             'ntippers': len(tippers),
201             'nactive': len(actives),
202             'transfer_volume': sum(x['amount'] for x in week_transfers)
203         }
204         #Make ach_volume and charge_volume between 0 and 10% of transfer volume
205         def rand_part():
206             return decimal.Decimal(random.random()* 0.1)
207         payday['ach_volume']   = -1 * payday['transfer_volume'] * rand_part()
208         payday['charge_volume'] = payday['transfer_volume'] * rand_part()
209         _fake_thing(db, "paydays", **payday)
210         date = end_date
211 
212 
213 
214 def main():
215     populate_db(wireup.db(wireup.env()))
216 
217 if __name__ == '__main__':
218     main()
219
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gratipay/utils/fake_data.py b/gratipay/utils/fake_data.py
--- a/gratipay/utils/fake_data.py
+++ b/gratipay/utils/fake_data.py
@@ -89,7 +89,9 @@
             + MIN_TIP)
 
     decimal_amount = decimal.Decimal(amount).quantize(decimal.Decimal('.01'))
-
+    while decimal_amount == decimal.Decimal('0.00'):
+        # https://github.com/gratipay/gratipay.com/issues/2950
+        decimal_amount = fake_tip_amount() 
     return decimal_amount

{"golden_diff": "diff --git a/gratipay/utils/fake_data.py b/gratipay/utils/fake_data.py\n--- a/gratipay/utils/fake_data.py\n+++ b/gratipay/utils/fake_data.py\n@@ -89,7 +89,9 @@\n             + MIN_TIP)\n \n     decimal_amount = decimal.Decimal(amount).quantize(decimal.Decimal('.01'))\n-\n+    while decimal_amount == decimal.Decimal('0.00'):\n+        # https://github.com/gratipay/gratipay.com/issues/2950\n+        decimal_amount = fake_tip_amount() \n     return decimal_amount\n", "issue": "VirtualEnv error with Windows + Vagrant\nNo idea where to even start with this one. Fresh clone with fresh vagrant box. \n\nHere's the weird part, at home my Windows 8.1 x64 computer experiences this problem but my Windows 7 x64 computer at work doesn't. This also happens to @abnor\n\n```\nvagrant@precise64:~/www.gittip.com$ make clean env\nrm -rf env *.egg *.egg-info\nfind . -name \\*.pyc -delete\n\"/usr/bin/python2.7\"  \"./vendor/virtualenv-1.9.1.py\"\\\n                                --unzip-setuptools \\\n                                --prompt=\"[gittip] \" \\\n                                --never-download \\\n                                --extra-search-dir=./vendor/ \\\n                                --distribute \\\n                                ./env/\nTraceback (most recent call last):\n  File \"./vendor/virtualenv-1.9.1.py\", line 2577, in <module>\n    main()\n  File \"./vendor/virtualenv-1.9.1.py\", line 979, in main\n    no_pip=options.no_pip)\n  File \"./vendor/virtualenv-1.9.1.py\", line 1081, in create_environment\n    site_packages=site_packages, clear=clear))\n  File \"./vendor/virtualenv-1.9.1.py\", line 1275, in install_python\n    copyfile(join(stdlib_dir, fn), join(lib_dir, fn))\n  File \"./vendor/virtualenv-1.9.1.py\", line 437, in copyfile\n    copyfileordir(src, dest)\n  File \"./vendor/virtualenv-1.9.1.py\", line 412, in copyfileordir\n    shutil.copytree(src, dest, True)\n  File \"/usr/lib/python2.7/shutil.py\", line 206, in copytree\n    raise Error, errors\nshutil.Error: [('/usr/lib/python2.7/config/libpython2.7.so', './env/lib/python2.\n7/config/libpython2.7.so', '[Errno 71] Protocol error')]\nmake: *** [env] Error 1\n```\n\n<bountysource-plugin>\n\n---\n\nWant to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/1846612-virtualenv-error-with-windows-vagrant?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github).\n</bountysource-plugin>\n\nfake_data generates 0.00 transfers that break positive constraint\nRunning fake_data may yield:\n\n```\n==> basebox: psycopg2.IntegrityError: new row for relation \"transfers\" violates check constraint \"positive\"\n==> basebox: DETAIL:  Failing row contains (578395790, 2014-08-20 12:00:37+00, Dominicbdp, Katharina92q, 0.00, tip).\n```\n\n", "before_files": [{"content": "from faker import Factory\nfrom gratipay import wireup, MAX_TIP_SINGULAR, MIN_TIP\nfrom gratipay.elsewhere import PLATFORMS\nfrom gratipay.models.participant import Participant\n\nimport datetime\nimport decimal\nimport random\nimport string\n\n\nfaker = Factory.create()\n\n\ndef _fake_thing(db, tablename, **kw):\n    column_names = []\n    column_value_placeholders = []\n    column_values = []\n\n    for k,v in kw.items():\n        column_names.append(k)\n        column_value_placeholders.append(\"%s\")\n        column_values.append(v)\n\n    column_names = \", \".join(column_names)\n    column_value_placeholders = \", \".join(column_value_placeholders)\n\n    db.run( \"INSERT INTO {} ({}) VALUES ({})\"\n            .format(tablename, column_names, column_value_placeholders)\n          , column_values\n           )\n    return kw\n\n\ndef fake_text_id(size=6, chars=string.ascii_lowercase + string.digits):\n    \"\"\"Create a random text id.\n    \"\"\"\n    return ''.join(random.choice(chars) for x in range(size))\n\n\ndef fake_balance(max_amount=100):\n    \"\"\"Return a random amount between 0 and max_amount.\n    \"\"\"\n    return random.random() * max_amount\n\n\ndef fake_int_id(nmax=2 ** 31 -1):\n    \"\"\"Create a random int id.\n    \"\"\"\n    return random.randint(0, nmax)\n\n\ndef fake_sentence(start=1, stop=100):\n    \"\"\"Create a sentence of random length.\n    \"\"\"\n    return faker.sentence(random.randrange(start,stop))\n\n\ndef fake_participant(db, number=\"singular\", is_admin=False):\n    \"\"\"Create a fake User.\n    \"\"\"\n    username = faker.first_name() + fake_text_id(3)\n    _fake_thing( db\n               , \"participants\"\n               , id=fake_int_id()\n               , username=username\n               , username_lower=username.lower()\n               , statement=fake_sentence()\n               , ctime=faker.date_time_this_year()\n               , is_admin=is_admin\n               , balance=fake_balance()\n               , anonymous_giving=(random.randrange(5) == 0)\n               , anonymous_receiving=(random.randrange(5) == 0)\n               , goal=fake_balance()\n               , balanced_customer_href=faker.uri()\n               , last_ach_result=''\n               , is_suspicious=False\n               , last_bill_result=''  # Needed to not be suspicious\n               , claimed_time=faker.date_time_this_year()\n               , number=number\n                )\n    #Call participant constructor to perform other DB initialization\n    return Participant.from_username(username)\n\n\n\ndef fake_tip_amount():\n    amount = ((decimal.Decimal(random.random()) * (MAX_TIP_SINGULAR - MIN_TIP))\n            + MIN_TIP)\n\n    decimal_amount = decimal.Decimal(amount).quantize(decimal.Decimal('.01'))\n\n    return decimal_amount\n\n\ndef fake_tip(db, tipper, tippee):\n    \"\"\"Create a fake tip.\n    \"\"\"\n    return _fake_thing( db\n               , \"tips\"\n               , id=fake_int_id()\n               , ctime=faker.date_time_this_year()\n               , mtime=faker.date_time_this_month()\n               , tipper=tipper.username\n               , tippee=tippee.username\n               , amount=fake_tip_amount()\n                )\n\n\ndef fake_elsewhere(db, participant, platform):\n    \"\"\"Create a fake elsewhere.\n    \"\"\"\n    _fake_thing( db\n               , \"elsewhere\"\n               , id=fake_int_id()\n               , platform=platform\n               , user_id=fake_text_id()\n               , user_name=participant.username\n               , is_locked=False\n               , participant=participant.username\n               , extra_info=None\n                )\n\n\ndef fake_transfer(db, tipper, tippee):\n        return _fake_thing( db\n               , \"transfers\"\n               , id=fake_int_id()\n               , timestamp=faker.date_time_this_year()\n               , tipper=tipper.username\n               , tippee=tippee.username\n               , amount=fake_tip_amount()\n               , context='tip'\n                )\n\n\ndef populate_db(db, num_participants=100, num_tips=200, num_teams=5, num_transfers=5000):\n    \"\"\"Populate DB with fake data.\n    \"\"\"\n    #Make the participants\n    participants = []\n    for i in xrange(num_participants):\n        participants.append(fake_participant(db))\n\n    #Make the \"Elsewhere's\"\n    for p in participants:\n        #All participants get between 1 and 3 elsewheres\n        num_elsewheres = random.randint(1, 3)\n        for platform_name in random.sample(PLATFORMS, num_elsewheres):\n            fake_elsewhere(db, p, platform_name)\n\n    #Make teams\n    for i in xrange(num_teams):\n        t = fake_participant(db, number=\"plural\")\n        #Add 1 to 3 members to the team\n        members = random.sample(participants, random.randint(1, 3))\n        for p in members:\n            t.add_member(p)\n\n    #Make the tips\n    tips = []\n    for i in xrange(num_tips):\n        tipper, tippee = random.sample(participants, 2)\n        tips.append(fake_tip(db, tipper, tippee))\n\n\n    #Make the transfers\n    transfers = []\n    for i in xrange(num_transfers):\n        tipper, tippee = random.sample(participants, 2)\n        transfers.append(fake_transfer(db, tipper, tippee))\n\n\n    #Make some paydays\n    #First determine the boundaries - min and max date\n    min_date = min(min(x['ctime'] for x in tips), \\\n                   min(x['timestamp'] for x in transfers))\n    max_date = max(max(x['ctime'] for x in tips), \\\n                   max(x['timestamp'] for x in transfers))\n    #iterate through min_date, max_date one week at a time\n    date = min_date\n    while date < max_date:\n        end_date = date + datetime.timedelta(days=7)\n        week_tips = filter(lambda x: date <= x['ctime'] <= end_date, tips)\n        week_transfers = filter(lambda x: date <= x['timestamp'] <= end_date, transfers)\n        week_participants = filter(lambda x: x.ctime.replace(tzinfo=None) <= end_date, participants)\n        actives=set()\n        tippers=set()\n        for xfers in week_tips, week_transfers:\n            actives.update(x['tipper'] for x in xfers)\n            actives.update(x['tippee'] for x in xfers)\n            tippers.update(x['tipper'] for x in xfers)\n        payday = {\n            'id': fake_int_id(),\n            'ts_start': date,\n            'ts_end': end_date,\n            'ntips': len(week_tips),\n            'ntransfers': len(week_transfers),\n            'nparticipants': len(week_participants),\n            'ntippers': len(tippers),\n            'nactive': len(actives),\n            'transfer_volume': sum(x['amount'] for x in week_transfers)\n        }\n        #Make ach_volume and charge_volume between 0 and 10% of transfer volume\n        def rand_part():\n            return decimal.Decimal(random.random()* 0.1)\n        payday['ach_volume']   = -1 * payday['transfer_volume'] * rand_part()\n        payday['charge_volume'] = payday['transfer_volume'] * rand_part()\n        _fake_thing(db, \"paydays\", **payday)\n        date = end_date\n\n\n\ndef main():\n    populate_db(wireup.db(wireup.env()))\n\nif __name__ == '__main__':\n    main()\n", "path": "gratipay/utils/fake_data.py"}], "after_files": [{"content": "from faker import Factory\nfrom gratipay import wireup, MAX_TIP_SINGULAR, MIN_TIP\nfrom gratipay.elsewhere import PLATFORMS\nfrom gratipay.models.participant import Participant\n\nimport datetime\nimport decimal\nimport random\nimport string\n\n\nfaker = Factory.create()\n\n\ndef _fake_thing(db, tablename, **kw):\n    column_names = []\n    column_value_placeholders = []\n    column_values = []\n\n    for k,v in kw.items():\n        column_names.append(k)\n        column_value_placeholders.append(\"%s\")\n        column_values.append(v)\n\n    column_names = \", \".join(column_names)\n    column_value_placeholders = \", \".join(column_value_placeholders)\n\n    db.run( \"INSERT INTO {} ({}) VALUES ({})\"\n            .format(tablename, column_names, column_value_placeholders)\n          , column_values\n           )\n    return kw\n\n\ndef fake_text_id(size=6, chars=string.ascii_lowercase + string.digits):\n    \"\"\"Create a random text id.\n    \"\"\"\n    return ''.join(random.choice(chars) for x in range(size))\n\n\ndef fake_balance(max_amount=100):\n    \"\"\"Return a random amount between 0 and max_amount.\n    \"\"\"\n    return random.random() * max_amount\n\n\ndef fake_int_id(nmax=2 ** 31 -1):\n    \"\"\"Create a random int id.\n    \"\"\"\n    return random.randint(0, nmax)\n\n\ndef fake_sentence(start=1, stop=100):\n    \"\"\"Create a sentence of random length.\n    \"\"\"\n    return faker.sentence(random.randrange(start,stop))\n\n\ndef fake_participant(db, number=\"singular\", is_admin=False):\n    \"\"\"Create a fake User.\n    \"\"\"\n    username = faker.first_name() + fake_text_id(3)\n    _fake_thing( db\n               , \"participants\"\n               , id=fake_int_id()\n               , username=username\n               , username_lower=username.lower()\n               , statement=fake_sentence()\n               , ctime=faker.date_time_this_year()\n               , is_admin=is_admin\n               , balance=fake_balance()\n               , anonymous_giving=(random.randrange(5) == 0)\n               , anonymous_receiving=(random.randrange(5) == 0)\n               , goal=fake_balance()\n               , balanced_customer_href=faker.uri()\n               , last_ach_result=''\n               , is_suspicious=False\n               , last_bill_result=''  # Needed to not be suspicious\n               , claimed_time=faker.date_time_this_year()\n               , number=number\n                )\n    #Call participant constructor to perform other DB initialization\n    return Participant.from_username(username)\n\n\n\ndef fake_tip_amount():\n    amount = ((decimal.Decimal(random.random()) * (MAX_TIP_SINGULAR - MIN_TIP))\n            + MIN_TIP)\n\n    decimal_amount = decimal.Decimal(amount).quantize(decimal.Decimal('.01'))\n    while decimal_amount == decimal.Decimal('0.00'):\n        # https://github.com/gratipay/gratipay.com/issues/2950\n        decimal_amount = fake_tip_amount() \n    return decimal_amount\n\n\ndef fake_tip(db, tipper, tippee):\n    \"\"\"Create a fake tip.\n    \"\"\"\n    return _fake_thing( db\n               , \"tips\"\n               , id=fake_int_id()\n               , ctime=faker.date_time_this_year()\n               , mtime=faker.date_time_this_month()\n               , tipper=tipper.username\n               , tippee=tippee.username\n               , amount=fake_tip_amount()\n                )\n\n\ndef fake_elsewhere(db, participant, platform):\n    \"\"\"Create a fake elsewhere.\n    \"\"\"\n    _fake_thing( db\n               , \"elsewhere\"\n               , id=fake_int_id()\n               , platform=platform\n               , user_id=fake_text_id()\n               , user_name=participant.username\n               , is_locked=False\n               , participant=participant.username\n               , extra_info=None\n                )\n\n\ndef fake_transfer(db, tipper, tippee):\n        return _fake_thing( db\n               , \"transfers\"\n               , id=fake_int_id()\n               , timestamp=faker.date_time_this_year()\n               , tipper=tipper.username\n               , tippee=tippee.username\n               , amount=fake_tip_amount()\n               , context='tip'\n                )\n\n\ndef populate_db(db, num_participants=100, num_tips=200, num_teams=5, num_transfers=5000):\n    \"\"\"Populate DB with fake data.\n    \"\"\"\n    #Make the participants\n    participants = []\n    for i in xrange(num_participants):\n        participants.append(fake_participant(db))\n\n    #Make the \"Elsewhere's\"\n    for p in participants:\n        #All participants get between 1 and 3 elsewheres\n        num_elsewheres = random.randint(1, 3)\n        for platform_name in random.sample(PLATFORMS, num_elsewheres):\n            fake_elsewhere(db, p, platform_name)\n\n    #Make teams\n    for i in xrange(num_teams):\n        t = fake_participant(db, number=\"plural\")\n        #Add 1 to 3 members to the team\n        members = random.sample(participants, random.randint(1, 3))\n        for p in members:\n            t.add_member(p)\n\n    #Make the tips\n    tips = []\n    for i in xrange(num_tips):\n        tipper, tippee = random.sample(participants, 2)\n        tips.append(fake_tip(db, tipper, tippee))\n\n\n    #Make the transfers\n    transfers = []\n    for i in xrange(num_transfers):\n        tipper, tippee = random.sample(participants, 2)\n        transfers.append(fake_transfer(db, tipper, tippee))\n\n\n    #Make some paydays\n    #First determine the boundaries - min and max date\n    min_date = min(min(x['ctime'] for x in tips), \\\n                   min(x['timestamp'] for x in transfers))\n    max_date = max(max(x['ctime'] for x in tips), \\\n                   max(x['timestamp'] for x in transfers))\n    #iterate through min_date, max_date one week at a time\n    date = min_date\n    while date < max_date:\n        end_date = date + datetime.timedelta(days=7)\n        week_tips = filter(lambda x: date <= x['ctime'] <= end_date, tips)\n        week_transfers = filter(lambda x: date <= x['timestamp'] <= end_date, transfers)\n        week_participants = filter(lambda x: x.ctime.replace(tzinfo=None) <= end_date, participants)\n        actives=set()\n        tippers=set()\n        for xfers in week_tips, week_transfers:\n            actives.update(x['tipper'] for x in xfers)\n            actives.update(x['tippee'] for x in xfers)\n            tippers.update(x['tipper'] for x in xfers)\n        payday = {\n            'id': fake_int_id(),\n            'ts_start': date,\n            'ts_end': end_date,\n            'ntips': len(week_tips),\n            'ntransfers': len(week_transfers),\n            'nparticipants': len(week_participants),\n            'ntippers': len(tippers),\n            'nactive': len(actives),\n            'transfer_volume': sum(x['amount'] for x in week_transfers)\n        }\n        #Make ach_volume and charge_volume between 0 and 10% of transfer volume\n        def rand_part():\n            return decimal.Decimal(random.random()* 0.1)\n        payday['ach_volume']   = -1 * payday['transfer_volume'] * rand_part()\n        payday['charge_volume'] = payday['transfer_volume'] * rand_part()\n        _fake_thing(db, \"paydays\", **payday)\n        date = end_date\n\n\n\ndef main():\n    populate_db(wireup.db(wireup.env()))\n\nif __name__ == '__main__':\n    main()\n", "path": "gratipay/utils/fake_data.py"}]}