8000 n:n matching rounds <> grants by owocki · Pull Request #7522 · gitcoinco/web · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

n:n matching rounds <> grants #7522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions app/grants/clr.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,37 +468,39 @@ def predict_clr(save_to_db=False, from_date=None, clr_round=None, network='mainn

if save_to_db:
_grant = Grant.objects.get(pk=grant.pk)
_grant.clr_prediction_curve = list(zip(potential_donations, potential_clr))
base = _grant.clr_prediction_curve[0][1]
clr_prediction_curve = list(zip(potential_donations, potential_clr))
base = clr_prediction_curve[0][1]
_grant.last_clr_calc_date = timezone.now()
_grant.next_clr_calc_date = timezone.now() + timezone.timedelta(minutes=20)

can_estimate = True if base or _grant.clr_prediction_curve[1][1] or _grant.clr_prediction_curve[2][1] or _grant.clr_prediction_curve[3][1] else False
can_estimate = True if base or clr_prediction_curve[1][1] or clr_prediction_curve[2][1] or clr_prediction_curve[3][1] else False

if can_estimate :
_grant.clr_prediction_curve = [[ele[0], ele[1], ele[1] - base] for ele in _grant.clr_prediction_curve ]
clr_prediction_curve = [[ele[0], ele[1], ele[1] - base] for ele in clr_prediction_curve ]
else:
_grant.clr_prediction_curve = [[0.0, 0.0, 0.0] for x in range(0, 6)]
clr_prediction_curve = [[0.0, 0.0, 0.0] for x in range(0, 6)]

JSONStore.objects.create(
created_on=from_date,
view='clr_contribution',
key=f'{grant.id}',
data=_grant.clr_prediction_curve,
data=clr_prediction_curve,
)
clr_round.record_clr_prediction_curve(_grant, clr_prediction_curve)

try:
if _grant.clr_prediction_curve[0][1]:
if clr_prediction_curve[0][1]:
Stat.objects.create(
created_on=from_date,
key=_grant.title[0:43] + "_match",
val=_grant.clr_prediction_curve[0][1],
val=clr_prediction_curve[0][1],
)
max_twitter_followers = max(_grant.twitter_handle_1_follower_count, _grant.twitter_handle_2_follower_count)
if max_twitter_followers:
Stat.objects.create(
created_on=from_date,
key=_grant.title[0:43] + "_admt1",
val=int(100 * _grant.clr_prediction_curve[0][1]/max_twitter_followers),
val=int(100 * clr_prediction_curve[0][1]/max_twitter_followers),
)

if _grant.positive_round_contributor_count:
Expand Down
40 changes: 40 additions & 0 deletions app/grants/migrations/0088_auto_20200924_0425.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Django 2.2.4 on 2020-09-24 04:25

import django.contrib.postgres.fields
from django.db import migrations, models
import django.db.models.deletion
import economy.models


class Migration(migrations.Migration):

dependencies = [
('grants', '0087_grantstat'),
]

operations = [
migrations.RemoveField(
model_name='grant',
name='backup_clr_prediction_curve',
),
migrations.AlterField(
model_name='grantstat',
name='grant',
field=models.ForeignKey(help_text='Grant to add stats for this grant', on_delete=django.db.models.deletion.CASCADE, related_name='stats', to='grants.Grant'),
),
migrations.CreateModel(
name='GrantCLRCalculation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_on', models.DateTimeField(db_index=True, default=economy.models.get_time)),
('modified_on', models.DateTimeField(default=economy.models.get_time)),
('latest', models.BooleanField(db_index=True, default=False, help_text='Is this calc the latest?')),
('clr_prediction_curve', django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(), size=2), blank=True, default=list, help_text='5 point curve to predict CLR donations.', size=None)),
('grant', models.ForeignKey(help_text='The grant', on_delete=django.db.models.deletion.CASCADE, related_name='clr_calculations', to='grants.Grant')),
('grantclr', models.ForeignKey(help_text='The grant CLR Round', on_delete=django.db.models.deletion.CASCADE, related_name='clr_calculations', to='grants.GrantCLR')),
],
options={
'abstract': False,
},
),
]
86 changes: 73 additions & 13 deletions app/grants/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ def __str__(self):
def grants(self):
return Grant.objects.filter(**self.grant_filters)

def record_clr_prediction_curve(self, grant, clr_prediction_curve):
for obj in self.clr_calculations.filter(grant=grant):
obj.latest = False
obj.save()

GrantCLRCalculation.objects.create(
grantclr=self,
grant=grant,
clr_prediction_curve=clr_prediction_curve,
latest=True,
)


class Grant(SuperModel):
"""Define the structure of a Grant."""
Expand Down Expand Up @@ -316,18 +328,6 @@ class Meta:
max_digits=20,
help_text=_('The fundingamount across all rounds with phantom funding'),
)
# TODO-CROSS-GRANT: [{round: fk1, value: time}]
clr_prediction_curve = ArrayField(
ArrayField(
models.FloatField(),
size=2,
), blank=True, default=list, help_text=_('5 point curve to predict CLR donations.'))
# TODO: REMOVE
backup_clr_prediction_curve = ArrayField(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh nice nice i like

ArrayField(
models.FloatField(),
size=2,
), blank=True, default=list, help_text=_('backup 5 point curve to predict CLR donations - used to store a secondary backup of the clr prediction curve, in the case a new identity mechanism is used'))
activeSubscriptions = ArrayField(models.CharField(max_length=200), blank=True, default=list)
hidden = models.BooleanField(default=False, help_text=_('Hide the grant from the /grants page?'), db_index=True)
weighted_shuffle = models.PositiveIntegerField(blank=True, null=True)
Expand Down Expand Up @@ -375,6 +375,12 @@ class Meta:

funding_info = models.CharField(default='', blank=True, null=True, max_length=255, help_text=_('Is this grant VC funded?'))

clr_prediction_curve = ArrayField(
ArrayField(
models.FloatField(),
size=2,
), blank=True, default=list, help_text=_('5 point curve to predict CLR donations.'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ This works for now -> but curious if you've given any thought on what the this would be the total accumulated match irrespective of chains / would we wanna move this to a table by itself which has
grant_fk | clr_round_fk | clr_prediction_curve which would store finer details ?

Grant A is part of Zcash Tech & Eth Tech
clr_prediction_curve -> would be a property which show the total prediction match across all active rounds/chains

and the new table would would have 2 entries in fk table
grant_fk | clr_round_fk | clr_prediction_curve with clr_prediction_curve for both Zcash & EthTech

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the this would be the total accumulated match irrespective of chains / would we wanna move this to a table by itself which

not sure i totally understand the question (typo in the middle?) but the GrantCLRCalculation basically hadnles this i think

i think if we want to extend the match estimates to only look at one (or a subset of) of curves, the existing FK structure handles that. i dont see a strong reason to store it in the grant-level one


weighted_risk_score = models.DecimalField(
default=0,
decimal_places=4,
Expand All @@ -396,6 +402,32 @@ class Meta:
# Grant Query Set used as manager.
objects = GrantQuerySet.as_manager()

def __str__(self):
"""Return the string representation of a Grant."""
return f"id: {self.pk}, active: {self.active}, title: {self.title}, type: {self.grant_type}"

@property
def calc_clr_round_nums(self):
roudn_nums = [ele for ele in self.in_active_clrs.values_list('round_num', flat=True)]
return ", ".join(roudn_nums)

@property
def calc_clr_prediction_curve(self):
# [amount_donated, match amount, bonus_from_match_amount ], etc..
# [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]
_clr_prediction_curve = []
for insert_clr_calc in self.clr_calculations.filter(latest=True).order_by('-created_on'):
insert_clr_calc = insert_clr_calc.clr_prediction_curve
if not _clr_prediction_curve:
_clr_prediction_curve = insert_clr_calc
else:
for j in [1,2]:
for i in [0,1,2,3,4,5]:
# add the 1 and 2 index of each clr prediction cuve
_clr_prediction_curve[i][j] += insert_clr_calc[i][j]
return _clr_prediction_curve


def __str__(self):
"""Return the string representation of a Grant."""
return f"id: {self.pk}, active: {self.active}, title: {self.title}, type: {self.grant_type}"
Expand Down Expand Up @@ -1087,8 +1119,18 @@ def successful_contribution(self, tx_id):

@receiver(pre_save, sender=Grant, dispatch_uid="psave_grant")
def psave_grant(sender, instance, **kwargs):
# TODO: move to grant task
instance.clr_prediction_curve = instance.calc_clr_prediction_curve
instance.clr_round_num = instance.calc_clr_round_nums

# todo: move to grant task
active_clr_rounds = GrantCLR.objects.filter(is_active=True)
for clr_round in active_clr_rounds:
if clr_round.grants.filter(pk=instance.pk).exists():
instance.in_active_clrs.add(clr_round)

from grants.tasks import update_grant_metadata
if instance.modified_on < (timezone.now() - timezone.timedelta(minutes=5)):
from grants.tasks import update_grant_metadata
update_grant_metadata.delay(instance.pk)

class DonationQuerySet(models.QuerySet):
Expand Down Expand Up @@ -1824,3 +1866,21 @@ class GrantStat(SuperModel):

def __str__(self):
return f'{self.snapshot_type} {self.created_on} for {self.grant.title}'


class GrantCLRCalculation(SuperModel):

latest = models.BooleanField(default=False, db_index=True, help_text="Is this calc the latest?")
grant = models.ForeignKey(Grant, on_delete=models.CASCADE, related_name='clr_calculations',
help_text=_('The grant'))
grantclr = models.ForeignKey(GrantCLR, on_delete=models.CASCADE, related_name='clr_calculations',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@owocki why do both of these have the same related name ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bc they are both clr_calculations, just reference from a diff spot.

help_text=_('The grant CLR Round'))

clr_prediction_curve = ArrayField(
ArrayField(
models.FloatField(),
size=2,
), blank=True, default=list, help_text=_('5 point curve to predict CLR donations.'))

def __str__(self):
return f'{self.created_on} for g:{self.grant.pk} / gclr:{self.grantclr.pk} : {self.clr_prediction_curve}'
3 changes: 1 addition & 2 deletions app/grants/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ def add_grant_to_active_clrs(grant):

active_clr_rounds = GrantCLR.objects.filter(is_active=True)
for clr_round in active_clr_rounds:
grants_in_clr = Grant.objects.filter(**clr_round.grant_filters)
if grants_in_clr.filter(pk=grant.pk).count():
if clr_round.grants.filter(pk=grant.pk).exists():
grant.in_active_clrs.add(clr_round)
grant.save()
4 changes: 1 addition & 3 deletions app/grants/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1136,10 +1136,8 @@ def grant_details(request, grant_id, grant_slug):

if clr_round:
is_clr_active = True
clr_round_num = clr_round.round_num
else:
is_clr_active = False
clr_round_num = 'LAST'

is_clr_active = True if clr_round else False
title = grant.title + " | Grants"
Expand Down Expand Up @@ -1169,7 +1167,7 @@ def grant_details(request, grant_id, grant_slug):
'activity_count': activity_count,
'contributors': contributors,
'clr_active': is_clr_active,
'round_num': clr_round_num,
'round_num': grant.clr_round_num,
'is_team_member': is_team_member,
'voucher_fundings': voucher_fundings,
'is_unsubscribed_from_updates_from_this_grant': is_unsubscribed_from_updates_from_this_grant,
Expand Down
0