From 54539bd1f01a1bc7ee5886d0734b9bd0a2fbb212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Nguy=C3=AAn=20Hoang?= Date: Thu, 2 May 2024 09:51:13 +0200 Subject: [PATCH 1/4] [front] feat: update Sergei's info (#1964) Co-authored-by: Gresille&Siffle <39056254+GresilleSiffle@users.noreply.github.com> --- frontend/public/locales/en/translation.json | 2 +- frontend/public/locales/fr/translation.json | 2 +- frontend/public/people/Sergei.jpg | Bin 0 -> 63513 bytes frontend/public/people/sergia.jpg | Bin 53213 -> 0 bytes frontend/src/pages/about/About.tsx | 6 +++--- 5 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 frontend/public/people/Sergei.jpg delete mode 100644 frontend/public/people/sergia.jpg diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index 6aa5101e67..c627af098a 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -644,7 +644,7 @@ "roleSecretary": "Secretary", "significantContributors": "Significant Contributors", "weThankOurContributors": "We are extremely thankful to many significant contributor who are or have been very impactful for the project.", - "sergiaDescription": "Sergia was among the few people who decided to start building Tournesol. She took over most of the engineering effort and developed the backend, the algorithms and the front-end of the first version of the platform.", + "sergeiDescription": "Sergei was among the few people who decided to start building Tournesol. He took over most of the engineering effort and developed the back end, the algorithms and the front end of the first version of the platform.", "sigmikeDescription": "Michael is a volunteer open source contributor who contributes impactful features on our backend, frontend and extension.", "weThankOurPartners": "We thank our partners", "partnershipWithEpfl": "Partnership with EPFL", diff --git a/frontend/public/locales/fr/translation.json b/frontend/public/locales/fr/translation.json index eb41d93429..a836ebad92 100644 --- a/frontend/public/locales/fr/translation.json +++ b/frontend/public/locales/fr/translation.json @@ -653,7 +653,7 @@ "roleSecretary": "Secrétaire", "significantContributors": "Contributeur·rices important·es", "weThankOurContributors": "Nous sommes extrêmement reconnaissant envers les contributrices et contributeurs qui ont eu un très grand impact sur le projet.", - "sergiaDescription": "Sergia était une des quelques personnes qui ont décidé de développer le projet Tournesol. Elle a au début assumé la majorité des efforts de developpement pour le backend, les algorithmes et le frontend de la première vesion de la plateforme.", + "sergeiDescription": "Sergei était une des quelques personnes qui ont décidé de développer le projet Tournesol. Il a au début assumé la majorité des efforts de developpement pour le back end, les algorithmes et le front end de la première vesion de la plateforme.", "sigmikeDescription": "Michael contribue volontairement au développement open source de beaucoup d'aspects du project comme le site web et l'extension navigateur.", "weThankOurPartners": "Nous remercions nos partenaires", "partnershipWithEpfl": "Partenariat avec l'EPFL", diff --git a/frontend/public/people/Sergei.jpg b/frontend/public/people/Sergei.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a04171c53e41d751ef0eaabf744780bc0d2406a3 GIT binary patch literal 63513 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 TtAo;z4C~UYx`MoeLm&Uy40pI~ literal 0 HcmV?d00001 diff --git a/frontend/public/people/sergia.jpg b/frontend/public/people/sergia.jpg deleted file mode 100644 index ce2016c1e0dfd08c8a9bbaf08a5c55b6b546c507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53213 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 uqtsq`Hw-bqs=Y$HP$ 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 diff --git a/frontend/src/pages/about/About.tsx b/frontend/src/pages/about/About.tsx index 052efb4f0c..97b5802e84 100644 --- a/frontend/src/pages/about/About.tsx +++ b/frontend/src/pages/about/About.tsx @@ -338,9 +338,9 @@ const AboutPage = () => { From 9ad2f333ade91016f7245b9475128b8f88967f8d Mon Sep 17 00:00:00 2001 From: Gresille & Siffle <39056254+GresilleSiffle@users.noreply.github.com> Date: Thu, 2 May 2024 11:09:29 +0200 Subject: [PATCH 2/4] [front] feat: update sergei website (#1965) --- frontend/src/pages/about/About.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/about/About.tsx b/frontend/src/pages/about/About.tsx index 97b5802e84..331a878b6b 100644 --- a/frontend/src/pages/about/About.tsx +++ b/frontend/src/pages/about/About.tsx @@ -341,7 +341,7 @@ const AboutPage = () => { name="Sergei" image="/people/Sergei.jpg" description={t('about.sergeiDescription')} - website="https://sergia.ch" + website="https://linkedin.com/in/sergeivolodin" /> From f92145b04d891cb878a99aba7595ec70a6a87b13 Mon Sep 17 00:00:00 2001 From: Gresille & Siffle <39056254+GresilleSiffle@users.noreply.github.com> Date: Thu, 2 May 2024 16:58:48 +0200 Subject: [PATCH 3/4] [back][front] feat: support patching score and score max of criteria (#1947) Co-authored-by: Adrien Matissart --- backend/ml/inputs.py | 6 +- backend/ml/mehestan/parameters.py | 3 +- backend/tournesol/lib/public_dataset.py | 12 +- .../commands/load_public_dataset.py | 1 + ...parisoncriteriascore_score_max_and_more.py | 29 ++ backend/tournesol/models/comparisons.py | 22 +- backend/tournesol/resources/export_readme.txt | 13 +- backend/tournesol/serializers/comparison.py | 32 ++- .../tournesol/serializers/inconsistencies.py | 1 + .../tournesol/tests/factories/comparison.py | 1 + .../tournesol/tests/test_api_comparison.py | 262 +++++++++++++++++- .../tests/test_api_inconsistencies.py | 1 + backend/tournesol/tests/test_exports.py | 6 +- .../test_model_comparisoncriteriascore.py | 98 +++++++ backend/tournesol/utils/constants.py | 3 - backend/tournesol/views/comparison.py | 15 +- backend/tournesol/views/exports.py | 2 +- backend/tournesol/views/inconsistencies.py | 48 ++-- frontend/scripts/openapi.yaml | 81 +++++- .../comparisons/ComparisonSliders.tsx | 28 +- .../features/comparisons/CriteriaSlider.tsx | 19 +- solidago/src/solidago/pipeline/inputs.py | 6 +- .../pipeline/legacy2023/individual_scores.py | 14 +- .../generalized_bradley_terry.py | 52 ++-- 24 files changed, 643 insertions(+), 112 deletions(-) create mode 100644 backend/tournesol/migrations/0061_comparisoncriteriascore_score_max_and_more.py create mode 100644 backend/tournesol/tests/test_model_comparisoncriteriascore.py diff --git a/backend/ml/inputs.py b/backend/ml/inputs.py index 2842bc037e..9f8272378f 100644 --- a/backend/ml/inputs.py +++ b/backend/ml/inputs.py @@ -70,6 +70,7 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame: values = scores_queryset.values( "score", + "score_max", "criteria", "weight", entity_a=F("comparison__entity_1_id"), @@ -78,7 +79,9 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame: ) if len(values) > 0: dtf = pd.DataFrame(values) - return dtf[["user_id", "entity_a", "entity_b", "criteria", "score", "weight"]] + return dtf[ + ["user_id", "entity_a", "entity_b", "criteria", "score", "score_max", "weight"] + ] return pd.DataFrame( columns=[ @@ -87,6 +90,7 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame: "entity_b", "criteria", "score", + "score_max", "weight", ] ) diff --git a/backend/ml/mehestan/parameters.py b/backend/ml/mehestan/parameters.py index 3215d2bcf5..e31e6de255 100644 --- a/backend/ml/mehestan/parameters.py +++ b/backend/ml/mehestan/parameters.py @@ -1,8 +1,7 @@ from solidago.pipeline.legacy2023.parameters import PipelineParameters -from tournesol.utils.constants import COMPARISON_MAX, MEHESTAN_MAX_SCALED_SCORE +from tournesol.utils.constants import MEHESTAN_MAX_SCALED_SCORE class MehestanParameters(PipelineParameters): - r_max = COMPARISON_MAX max_squashed_score = MEHESTAN_MAX_SCALED_SCORE diff --git a/backend/tournesol/lib/public_dataset.py b/backend/tournesol/lib/public_dataset.py index 43d0b58338..8612436d52 100644 --- a/backend/tournesol/lib/public_dataset.py +++ b/backend/tournesol/lib/public_dataset.py @@ -54,6 +54,7 @@ def get_comparisons_data(poll_name: str, until_: datetime) -> QuerySet: comparisoncriteriascore.criteria, comparisoncriteriascore.weight, comparisoncriteriascore.score, + comparisoncriteriascore.score_max, DATE(DATE_TRUNC('week', datetime_add)) AS week_date FROM tournesol_comparison @@ -283,7 +284,15 @@ def write_comparisons_file( # If we want this function to be generic, the specific video_a and video_b # columns should be renamed entity_a and entity_b. - fieldnames = ["public_username", "video_a", "video_b", "criteria", "score", "week_date"] + fieldnames = [ + "public_username", + "video_a", + "video_b", + "criteria", + "score", + "score_max", + "week_date" + ] writer = csv.DictWriter(write_target, fieldnames=fieldnames) writer.writeheader() writer.writerows( @@ -293,6 +302,7 @@ def write_comparisons_file( "video_b": comparison.uid_b.split(UID_DELIMITER)[1], "criteria": comparison.criteria, "score": int(round(comparison.score)), + "score_max": comparison.score_max, "week_date": comparison.week_date, } for comparison in get_comparisons_data(poll_name, until_).iterator() diff --git a/backend/tournesol/management/commands/load_public_dataset.py b/backend/tournesol/management/commands/load_public_dataset.py index 28b81377e4..b6e40aba2f 100644 --- a/backend/tournesol/management/commands/load_public_dataset.py +++ b/backend/tournesol/management/commands/load_public_dataset.py @@ -110,6 +110,7 @@ def handle(self, *args, **options): comparison=comparison, criteria=values["criteria"], score=values["score"], + score_max=values["score_max"], ) nb_comparisons += 1 print(f"Created {nb_comparisons} comparisons") diff --git a/backend/tournesol/migrations/0061_comparisoncriteriascore_score_max_and_more.py b/backend/tournesol/migrations/0061_comparisoncriteriascore_score_max_and_more.py new file mode 100644 index 0000000000..d3843c14dc --- /dev/null +++ b/backend/tournesol/migrations/0061_comparisoncriteriascore_score_max_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.11 on 2024-05-02 09:05 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tournesol", "0060_remove_entity_tournesol_score"), + ] + + operations = [ + migrations.AddField( + model_name="comparisoncriteriascore", + name="score_max", + field=models.IntegerField( + default=10, + help_text="The absolute value of the maximum score.", + validators=[django.core.validators.MinValueValidator(1)], + ), + preserve_default=False, + ), + migrations.AlterField( + model_name="comparisoncriteriascore", + name="score", + field=models.FloatField(help_text="Score for the given comparison"), + ), + ] diff --git a/backend/tournesol/models/comparisons.py b/backend/tournesol/models/comparisons.py index a9466cc5b0..f111ca18b7 100644 --- a/backend/tournesol/models/comparisons.py +++ b/backend/tournesol/models/comparisons.py @@ -5,12 +5,11 @@ import uuid import computed_property -from django.core.validators import MaxValueValidator, MinValueValidator +from django.core.validators import MinValueValidator from django.db import models from django.db.models import F, ObjectDoesNotExist, Q from core.models import User -from tournesol.utils.constants import COMPARISON_MAX from .poll import Poll @@ -129,7 +128,10 @@ class ComparisonCriteriaScore(models.Model): ) score = models.FloatField( help_text="Score for the given comparison", - validators=[MinValueValidator(-COMPARISON_MAX), MaxValueValidator(COMPARISON_MAX)], + ) + score_max = models.IntegerField( + help_text="The absolute value of the maximum score.", + validators=[MinValueValidator(1)], ) # TODO: ask Lê if weights should be in a certain range (maybe always > 0) # and add validation if required @@ -144,3 +146,17 @@ class Meta: def __str__(self): return f"{self.comparison}/{self.criteria}/{self.score}" + + def save(self, *args, **kwargs): + if self.score_max is None: + raise TypeError("The value of score_max cannot be None.") + + if self.score_max <= 0: + raise ValueError("The value of score_max must be greater than or equal to 1.") + + if abs(self.score) > self.score_max: + raise ValueError( + f"The absolute value of the score {self.score} given to the criterion " + f"{self.criteria} can't be greater than the value of score_max {self.score_max}." + ) + return super().save(*args, **kwargs) diff --git a/backend/tournesol/resources/export_readme.txt b/backend/tournesol/resources/export_readme.txt index 52f56e4bbc..adcfd8b3c3 100644 --- a/backend/tournesol/resources/export_readme.txt +++ b/backend/tournesol/resources/export_readme.txt @@ -70,10 +70,15 @@ List of columns: - score: - The score is an integer between -10 and +10. Negative values indicate that - the user considers the video_a better, and positive values indicate that - they prefer the video_b. A score of 0 or close to 0 means that they find the - two videos similar. + The score is an integer in the range [-score_max, +score_max]. Negative + values indicate that the user considers the video_a better, and positive + values indicate that they prefer the video_b. A score of 0 or close to 0 + means that they find the two videos similar. + +- score_max: + + The absolute value of the minimum and maximum score. 10 means the user could + have given a score between -10 and +10 for the criterion. - week_date: diff --git a/backend/tournesol/serializers/comparison.py b/backend/tournesol/serializers/comparison.py index 20da7474da..89559414de 100644 --- a/backend/tournesol/serializers/comparison.py +++ b/backend/tournesol/serializers/comparison.py @@ -11,7 +11,7 @@ class ComparisonCriteriaScoreSerializer(ModelSerializer): class Meta: model = ComparisonCriteriaScore - fields = ["criteria", "score", "weight"] + fields = ["criteria", "score", "score_max", "weight"] def validate_criteria(self, value): current_poll = self.context["poll"] @@ -37,11 +37,15 @@ def reverse_criteria_scores(self, criteria_scores): def validate_criteria_scores(self, value): current_poll = self.context["poll"] - missing_criterias = set(current_poll.required_criterias_list) - set( - score["criteria"] for score in value - ) - if missing_criterias: - raise ValidationError(f"Missing required criteria: {','.join(missing_criterias)}") + partial_update = self.context.get("partial_update") + + if not partial_update: + missing_criterias = set(current_poll.required_criterias_list) - set( + score["criteria"] for score in value + ) + if missing_criterias: + raise ValidationError(f"Missing required criteria: {','.join(missing_criterias)}") + return value @@ -193,9 +197,19 @@ def update(self, instance, validated_data): instance.duration_ms = validated_data.get("duration_ms") instance.save() - instance.criteria_scores.all().delete() - for criteria_score in validated_data.pop("criteria_scores"): - instance.criteria_scores.create(**criteria_score) + partial_update = self.context.get("partial_update") + + if partial_update: + for criteria_score in validated_data.pop("criteria_scores"): + instance.criteria_scores.update_or_create( + criteria=criteria_score["criteria"], + defaults={**criteria_score} + ) + else: + instance.criteria_scores.all().delete() + + for criteria_score in validated_data.pop("criteria_scores"): + instance.criteria_scores.create(**criteria_score) return instance diff --git a/backend/tournesol/serializers/inconsistencies.py b/backend/tournesol/serializers/inconsistencies.py index 5423d16c85..a42fb0135e 100644 --- a/backend/tournesol/serializers/inconsistencies.py +++ b/backend/tournesol/serializers/inconsistencies.py @@ -56,6 +56,7 @@ class ScoreInconsistencySerializer(Serializer): entity_1_rating = serializers.FloatField() entity_2_rating = serializers.FloatField() comparison_score = serializers.FloatField() + comparison_score_max = serializers.IntegerField() expected_comparison_score = serializers.FloatField() diff --git a/backend/tournesol/tests/factories/comparison.py b/backend/tournesol/tests/factories/comparison.py index 821da6163f..4181651439 100644 --- a/backend/tournesol/tests/factories/comparison.py +++ b/backend/tournesol/tests/factories/comparison.py @@ -31,3 +31,4 @@ class Meta: comparison = factory.SubFactory(ComparisonFactory) criteria = "better_habits" score = fuzzy.FuzzyDecimal(-10, 10) + score_max = 10 diff --git a/backend/tournesol/tests/test_api_comparison.py b/backend/tournesol/tests/test_api_comparison.py index 7b9ffb2d69..7d41307066 100644 --- a/backend/tournesol/tests/test_api_comparison.py +++ b/backend/tournesol/tests/test_api_comparison.py @@ -13,6 +13,7 @@ from core.utils.time import time_ago, time_ahead from tournesol.models import ( Comparison, + ComparisonCriteriaScore, ContributorRatingCriteriaScore, Entity, EntityCriteriaScore, @@ -54,7 +55,9 @@ class ComparisonApiTestCase(TestCase): non_existing_comparison = { "entity_a": {"uid": _uid_01}, "entity_b": {"uid": _uid_03}, - "criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}], + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ], "duration_ms": 103, } @@ -144,7 +147,12 @@ def _compare(self, uid_1, uid_2): "entity_a": {"uid": uid_1}, "entity_b": {"uid": uid_2}, "criteria_scores": [ - {"criteria": "largely_recommended", "score": 10, "weight": 10} + { + "criteria": "largely_recommended", + "score": 10, + "score_max": 10, + "weight": 10, + } ], "duration_ms": 103, }, @@ -752,7 +760,11 @@ def test_anonymous_cant_update(self): self._uid_01, self._uid_02, ), - {"criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}]}, + { + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ] + }, format="json", ) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) @@ -768,7 +780,11 @@ def test_authenticated_cant_update_non_existing_poll(self): "/users/me/comparisons/{}/{}/{}/".format( non_existing_poll, self._uid_01, self._uid_02 ), - {"criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}]}, + { + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ] + }, format="json", ) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) @@ -809,7 +825,11 @@ def test_authenticated_can_update(self): self._uid_03, self._uid_04, ), - {"criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}]}, + { + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ] + }, format="json", ) @@ -831,6 +851,216 @@ def test_authenticated_can_update(self): self.assertEqual(comp2["entity_a"]["uid"], comparison2.entity_1.uid) self.assertEqual(comp2["entity_b"]["uid"], comparison2.entity_2.uid) + def test_anonymous_cant_patch(self): + score = ComparisonCriteriaScore.objects.create( + comparison=self.comparisons[0], + criteria="largely_recommended", + score=8, + score_max=10, + ) + + response = self.client.patch( + "{}/{}/{}/".format( + self.comparisons_base_url, + self._uid_01, + self._uid_02, + ), + data={ + "criteria_scores": [ + { + "criteria": "largely_recommended", + "score": 2, + "score_max": 2, + } + ] + }, + format="json", + ) + + score.refresh_from_db() + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + self.assertEqual(score.score, 8) + self.assertEqual(score.score_max, 10) + + def test_authenticated_can_patch(self): + """ + An authenticated user can patch the score and the score_max of the + main criterion. + """ + self.client.force_authenticate(user=self.user) + self.comparisons[0].criteria_scores.all().delete() + + ComparisonCriteriaScore.objects.create( + comparison=self.comparisons[0], + criteria="largely_recommended", + score=8, + score_max=10, + ) + + response = self.client.patch( + "{}/{}/{}/".format( + self.comparisons_base_url, + self._uid_01, + self._uid_02, + ), + data={ + "criteria_scores": [ + { + "criteria": "largely_recommended", + "score": 2, + "score_max": 2, + } + ] + }, + format="json", + ) + + criteria_scores = response.data["criteria_scores"] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertListEqual( + criteria_scores, + [ + {"criteria": "largely_recommended", "score": 2.0, "score_max": 2, "weight": 1.0}, + ], + ) + + def test_authenticated_can_patch_optional(self): + """ + An authenticated user can patch the score and the score_max of an + optional criterion. + """ + self.client.force_authenticate(user=self.user) + self.comparisons[0].criteria_scores.all().delete() + + optional = "pedagogy" + ComparisonCriteriaScore.objects.create( + comparison=self.comparisons[0], + criteria="largely_recommended", + score=1, + score_max=10, + ) + ComparisonCriteriaScore.objects.create( + comparison=self.comparisons[0], + criteria="reliability", + score=2, + score_max=10, + ) + + # A new criterion can be added, without erasing all existing criteria. + response = self.client.patch( + "{}/{}/{}/".format( + self.comparisons_base_url, + self._uid_01, + self._uid_02, + ), + data={ + "criteria_scores": [ + { + "criteria": optional, + "score": 3, + "score_max": 8, + } + ] + }, + format="json", + ) + + criteria_scores = response.data["criteria_scores"] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertListEqual( + criteria_scores, + [ + {"criteria": "largely_recommended", "score": 1.0, "score_max": 10, "weight": 1.0}, + {"criteria": "reliability", "score": 2.0, "score_max": 10, "weight": 1.0}, + {"criteria": "pedagogy", "score": 3.0, "score_max": 8, "weight": 1.0}, + ], + ) + + # An existing criterion can be updated, without affecting all existing criteria. + response = self.client.patch( + "{}/{}/{}/".format( + self.comparisons_base_url, + self._uid_01, + self._uid_02, + ), + data={ + "criteria_scores": [ + { + "criteria": optional, + "score": 4, + } + ] + }, + format="json", + ) + + criteria_scores = response.data["criteria_scores"] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertListEqual( + criteria_scores, + [ + {"criteria": "largely_recommended", "score": 1.0, "score_max": 10, "weight": 1.0}, + {"criteria": "reliability", "score": 2.0, "score_max": 10, "weight": 1.0}, + {"criteria": "pedagogy", "score": 4.0, "score_max": 8, "weight": 1.0}, + ], + ) + + def test_authenticated_can_patch_several(self): + """ + An authenticated user can patch the score and the score_max of several + criteria at a time. + """ + self.client.force_authenticate(user=self.user) + self.comparisons[0].criteria_scores.all().delete() + + ComparisonCriteriaScore.objects.create( + comparison=self.comparisons[0], + criteria="largely_recommended", + score=1, + score_max=10, + ) + ComparisonCriteriaScore.objects.create( + comparison=self.comparisons[0], + criteria="reliability", + score=2, + score_max=10, + ) + + # A new criterion can be added, without erasing all existing criteria. + response = self.client.patch( + "{}/{}/{}/".format( + self.comparisons_base_url, + self._uid_01, + self._uid_02, + ), + data={ + "criteria_scores": [ + { + "criteria": "reliability", + "score": 4, + "score_max": 8, + }, + { + "criteria": "pedagogy", + "score": 5, + "score_max": 9, + }, + ] + }, + format="json", + ) + + criteria_scores = response.data["criteria_scores"] + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertListEqual( + criteria_scores, + [ + {"criteria": "largely_recommended", "score": 1.0, "score_max": 10, "weight": 1.0}, + {"criteria": "reliability", "score": 4.0, "score_max": 8, "weight": 1.0}, + {"criteria": "pedagogy", "score": 5.0, "score_max": 9, "weight": 1.0}, + ], + ) + def test_anonymous_cant_delete(self): """ An anonymous user can't delete a comparison. @@ -919,7 +1149,9 @@ def test_n_ratings_from_video(self): data1 = { "entity_a": {"uid": self._uid_05}, "entity_b": {"uid": self._uid_06}, - "criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}], + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ], "duration_ms": 103, } response = self.client.post( @@ -932,7 +1164,9 @@ def test_n_ratings_from_video(self): data2 = { "entity_a": {"uid": self._uid_05}, "entity_b": {"uid": self._uid_07}, - "criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}], + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ], "duration_ms": 103, } response = self.client.post( @@ -947,7 +1181,9 @@ def test_n_ratings_from_video(self): data3 = { "entity_a": {"uid": self._uid_05}, "entity_b": {"uid": self._uid_06}, - "criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}], + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ], "duration_ms": 103, } response = self.client.post( @@ -986,7 +1222,9 @@ def test_metadata_refresh_on_comparison_creation(self, mock_get_video_metadata): data = { "entity_a": {"uid": self._uid_01}, "entity_b": {"uid": self._uid_02}, - "criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}], + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ], } response = self.client.post(self.comparisons_base_url, data, format="json") self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.json()) @@ -997,7 +1235,9 @@ def test_metadata_refresh_on_comparison_creation(self, mock_get_video_metadata): data = { "entity_a": {"uid": self._uid_01}, "entity_b": {"uid": self._uid_03}, - "criteria_scores": [{"criteria": "largely_recommended", "score": 10, "weight": 10}], + "criteria_scores": [ + {"criteria": "largely_recommended", "score": 10, "score_max": 10, "weight": 10} + ], } response = self.client.post(self.comparisons_base_url, data, format="json") @@ -1097,7 +1337,7 @@ def test_update_individual_scores_after_new_comparison(self): data={ "entity_a": {"uid": self.entities[0].uid}, "entity_b": {"uid": self.entities[2].uid}, - "criteria_scores": [{"criteria": "criteria1", "score": 3}], + "criteria_scores": [{"criteria": "criteria1", "score": 3, "score_max": 10}], }, format="json", ) diff --git a/backend/tournesol/tests/test_api_inconsistencies.py b/backend/tournesol/tests/test_api_inconsistencies.py index 562758cff5..d4abf5e946 100644 --- a/backend/tournesol/tests/test_api_inconsistencies.py +++ b/backend/tournesol/tests/test_api_inconsistencies.py @@ -405,6 +405,7 @@ def test_response_format(self): self.assertEqual(results["entity_1_rating"], rating_1_score) self.assertEqual(results["entity_2_rating"], rating_2_score) self.assertEqual(results["comparison_score"], comparison_score) + self.assertEqual(results["comparison_score_max"], 10) self.assertGreater(results["expected_comparison_score"], 0) self.assertLess(results["expected_comparison_score"], 1) diff --git a/backend/tournesol/tests/test_exports.py b/backend/tournesol/tests/test_exports.py index 8e0c0d18e6..19b425e5da 100644 --- a/backend/tournesol/tests/test_exports.py +++ b/backend/tournesol/tests/test_exports.py @@ -57,7 +57,7 @@ def setUp(self) -> None: entity_2=self.video2, ) ComparisonCriteriaScore.objects.create( - comparison=self.comparison, score=5, criteria="largely_recommended" + comparison=self.comparison, score=5, score_max=10, criteria="largely_recommended" ) self.user_without_comparisons = UserFactory(username="user_without_comparisons") @@ -138,7 +138,7 @@ def add_comparison(self, user, is_public=True): entity_2=video2, ) ComparisonCriteriaScoreFactory( - comparison=comparison, score=5, criteria="largely_recommended" + comparison=comparison, score=5, score_max=10, criteria="largely_recommended" ) def parse_zipped_csv(self, response: requests.models.Response, filename: str) -> Dict[str, str]: @@ -549,7 +549,7 @@ def test_use_public_export_as_ml_input(self): self.assertEqual(len(comparisons_df), 1) self.assertEqual( list(comparisons_df.columns), - ["user_id", "entity_a", "entity_b", "criteria", "score", "weight"], + ["user_id", "entity_a", "entity_b", "criteria", "score", "score_max", "weight"], ) self.assertEqual(len(rating_properties), 2) diff --git a/backend/tournesol/tests/test_model_comparisoncriteriascore.py b/backend/tournesol/tests/test_model_comparisoncriteriascore.py new file mode 100644 index 0000000000..36c287cc8e --- /dev/null +++ b/backend/tournesol/tests/test_model_comparisoncriteriascore.py @@ -0,0 +1,98 @@ +""" +All test cases of the `ComparisonCriteriaScore` model. +""" + +from django.core.exceptions import ValidationError +from django.test import TestCase + +from core.tests.factories.user import UserFactory +from tournesol.models import ComparisonCriteriaScore +from tournesol.tests.factories.comparison import ComparisonFactory +from tournesol.tests.factories.poll import PollWithCriteriasFactory + + +class ComparisonCriteriaScoreTestCase(TestCase): + """ + TestCase of the `ComparisonCriteriaScore` model. + """ + + _user = "username" + + def setUp(self): + self.poll = PollWithCriteriasFactory() + self.user = UserFactory(username=self._user) + self.comparison = ComparisonFactory(poll=self.poll, user=self.user) + + def test_validators_score_max(self): + score = ComparisonCriteriaScore( + comparison=self.comparison, + criteria=self.poll.main_criteria, + score=0, + score_max=0, + ) + + # score_max cannot be zero. + with self.assertRaises(ValidationError): + score.clean_fields() + + score.score_max = -1 + # score_max cannot be negative. + with self.assertRaises(ValidationError): + score.clean_fields() + + score.score_max = 1 + score.clean_fields() + + def test_save_validate_score(self): + score = ComparisonCriteriaScore( + comparison=self.comparison, + criteria=self.poll.main_criteria, + score=11, + score_max=10, + ) + + # The score cannot be greater than score_max. + with self.assertRaises(ValueError): + score.save() + + score.score = -11 + # The absolute value of the score cannot be greater than score_max. + with self.assertRaises(ValueError): + score.save() + + # The score can be zero. + score.score = 0 + score.save() + + # The score can be equal to the score_max. + score.score = score.score_max + score.save() + + # The absolute value of the score can be lesser than score_max. + score.score = -1 + score.save() + + def test_save_validate_score_max(self): + score = ComparisonCriteriaScore( + comparison=self.comparison, + criteria=self.poll.main_criteria, + score=5, + score_max=None, + ) + + # score_max cannot be None. + with self.assertRaises(TypeError): + score.save() + + score.score_max = 0 + # score_max cannot be zero. + with self.assertRaises(ValueError): + score.save() + + score.score_max = -10 + # score_max cannot be negative. + with self.assertRaises(ValueError): + score.save() + + score.score_max = 10 + score.save() diff --git a/backend/tournesol/utils/constants.py b/backend/tournesol/utils/constants.py index 22b0bfe76f..057e4574cc 100644 --- a/backend/tournesol/utils/constants.py +++ b/backend/tournesol/utils/constants.py @@ -14,9 +14,6 @@ # Maximal entity score after poll scaling is applied MEHESTAN_MAX_SCALED_SCORE = 100.0 -# Maximal absolute value for a comparison [-10, 10] -COMPARISON_MAX = 10.0 - # Default weight for a criteria in the recommendations # FIXME: the default weight used by the front end is 50, not 10 CRITERIA_DEFAULT_WEIGHT = 10 diff --git a/backend/tournesol/views/comparison.py b/backend/tournesol/views/comparison.py index 9cd601420b..a2453bb5ea 100644 --- a/backend/tournesol/views/comparison.py +++ b/backend/tournesol/views/comparison.py @@ -197,15 +197,16 @@ def get_serializer_class(self): their immutability and thus prevent the falsification of comparisons by uid swap. """ - if self.request.method == "PUT": + if self.request.method in ["PATCH", "PUT"]: return self.UPDATE_SERIALIZER return self.DEFAULT_SERIALIZER def get_serializer_context(self): - context = super().get_serializer_context() - context["reverse"] = self.currently_reversed - return context + ctx = super().get_serializer_context() + ctx["reverse"] = self.currently_reversed + ctx["partial_update"] = self.request.method == 'PATCH' + return ctx def perform_update(self, serializer): super().perform_update(serializer) @@ -223,6 +224,12 @@ def get(self, request, *args, **kwargs): """Retrieve a comparison made by the logged user, in the given poll.""" return self.retrieve(request, *args, **kwargs) + def patch(self, request, *args, **kwargs): + """Partially update a comparison made by the logged user, in the given poll.""" + if not self.poll_from_url.active: + raise InactivePollError + return self.partial_update(request, *args, **kwargs) + def put(self, request, *args, **kwargs): """Update a comparison made by the logged user, in the given poll""" if not self.poll_from_url.active: diff --git a/backend/tournesol/views/exports.py b/backend/tournesol/views/exports.py index c4309e74a0..c0ec4a85a4 100644 --- a/backend/tournesol/views/exports.py +++ b/backend/tournesol/views/exports.py @@ -33,7 +33,7 @@ def write_logged_user_comparisons_file(request, write_target): Comparisons from all polls are included. """ - fieldnames = ["video_a", "video_b", "criteria", "weight", "score"] + fieldnames = ["video_a", "video_b", "criteria", "weight", "score", "score_max"] writer = csv.DictWriter(write_target, fieldnames=fieldnames) writer.writeheader() comparisons = ( diff --git a/backend/tournesol/views/inconsistencies.py b/backend/tournesol/views/inconsistencies.py index a8f5d27803..de652b813d 100755 --- a/backend/tournesol/views/inconsistencies.py +++ b/backend/tournesol/views/inconsistencies.py @@ -13,7 +13,6 @@ ScoreInconsistenciesFilterSerializer, ScoreInconsistenciesSerializer, ) -from tournesol.utils.constants import COMPARISON_MAX from tournesol.views.mixins.poll import PollScopedViewMixin @@ -214,6 +213,7 @@ def get(self, request, *args, **kwargs): "comparison__entity_2__uid", "criteria", "score", + "score_max", ) ) @@ -229,16 +229,18 @@ def get(self, request, *args, **kwargs): ) ) - response = self._list_inconsistent_comparisons(contributor_comparisons_criteria, - ratings, - filters["inconsistency_threshold"], - poll.criterias_list) + response = self._list_inconsistent_comparisons( + contributor_comparisons_criteria, + ratings, + filters["inconsistency_threshold"], + poll.criterias_list, + ) return Response(ScoreInconsistenciesSerializer(response).data) @staticmethod def _list_inconsistent_comparisons( # pylint: disable=too-many-locals - criteria_comparisons: list, + criteria_comparisons: list[dict], criteria_ratings: list, threshold: float, criteria_list: list @@ -265,6 +267,7 @@ def _list_inconsistent_comparisons( # pylint: disable=too-many-locals entity_2 = comparison_criteria["comparison__entity_2__uid"] criteria = comparison_criteria["criteria"] comparison_score = comparison_criteria["score"] + comparison_score_max = comparison_criteria["score_max"] try: rating_1 = ratings_map[(entity_1, criteria)] @@ -278,6 +281,7 @@ def _list_inconsistent_comparisons( # pylint: disable=too-many-locals rating_1["score"], rating_2["score"], comparison_score, + comparison_score_max, uncertainty, ) @@ -296,6 +300,7 @@ def _list_inconsistent_comparisons( # pylint: disable=too-many-locals "entity_1_rating": rating_1["score"], "entity_2_rating": rating_2["score"], "comparison_score": comparison_score, + "comparison_score_max": comparison_score_max, "expected_comparison_score": ideal_comparison_score, } ) @@ -322,10 +327,13 @@ def _list_inconsistent_comparisons( # pylint: disable=too-many-locals return response @staticmethod - def _calculate_inconsistency(entity_1_calculated_rating, - entity_2_calculated_rating, - comparison_score, - uncertainty) -> float: + def _calculate_inconsistency( + entity_1_calculated_rating, + entity_2_calculated_rating, + comparison_score, + comparison_score_max, + uncertainty, + ) -> tuple[float, float]: """ Calculate the inconsistency between the comparison criteria score and the general rating of the entity. @@ -361,18 +369,20 @@ def _calculate_inconsistency(entity_1_calculated_rating, base_rating_difference = entity_2_calculated_rating - entity_1_calculated_rating - def inconsistency_calculation(rating_diff): - return abs(comparison_score - COMPARISON_MAX * rating_diff / sqrt(rating_diff**2 + 1)) + def inconsistency_calculation(rating_diff) -> float: + return abs( + comparison_score - comparison_score_max * rating_diff / sqrt(rating_diff**2 + 1) + ) min_rating_difference = base_rating_difference - uncertainty max_rating_difference = base_rating_difference + uncertainty - if comparison_score <= -COMPARISON_MAX: + if comparison_score <= -comparison_score_max: min_inconsistency = inconsistency_calculation(min_rating_difference) - elif comparison_score >= COMPARISON_MAX: + elif comparison_score >= comparison_score_max: min_inconsistency = inconsistency_calculation(max_rating_difference) else: - root = comparison_score / sqrt(COMPARISON_MAX ** 2 - comparison_score ** 2) + root = comparison_score / sqrt(comparison_score_max**2 - comparison_score**2) if max_rating_difference < root: # The inconsistency is decreasing with the rating_difference min_inconsistency = inconsistency_calculation(max_rating_difference) @@ -381,12 +391,12 @@ def inconsistency_calculation(rating_diff): min_inconsistency = inconsistency_calculation(min_rating_difference) else: # The root is a possible value for the rating_difference - min_inconsistency = 0 + min_inconsistency = 0.0 # Comparison imprecision of 0.5, because comparisons scores are on integers, not floats inconsistency = max(min_inconsistency - 0.5, 0) - - expected_comparison_score = \ - COMPARISON_MAX * base_rating_difference / sqrt(base_rating_difference**2 + 1) + expected_comparison_score = ( + comparison_score_max * base_rating_difference / sqrt(base_rating_difference**2 + 1) + ) return inconsistency, expected_comparison_score diff --git a/frontend/scripts/openapi.yaml b/frontend/scripts/openapi.yaml index 4fe106875c..5b8a22030b 100644 --- a/frontend/scripts/openapi.yaml +++ b/frontend/scripts/openapi.yaml @@ -1383,6 +1383,49 @@ paths: schema: $ref: '#/components/schemas/ComparisonUpdate' description: '' + patch: + operationId: users_me_comparisons_partial_update + description: Partially update a comparison made by the logged user, in the given + poll. + parameters: + - in: path + name: poll_name + schema: + type: string + required: true + - in: path + name: uid_a + schema: + type: string + required: true + - in: path + name: uid_b + schema: + type: string + required: true + tags: + - users + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchedComparisonUpdateRequest' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/PatchedComparisonUpdateRequest' + multipart/form-data: + schema: + $ref: '#/components/schemas/PatchedComparisonUpdateRequest' + security: + - oauth2: + - read write groups + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ComparisonUpdate' + description: '' delete: operationId: users_me_comparisons_destroy description: Delete a comparison made by the logged user, in the given poll @@ -2746,9 +2789,12 @@ components: score: type: number format: double - maximum: 10.0 - minimum: -10.0 description: Score for the given comparison + score_max: + type: integer + maximum: 2147483647 + minimum: 1 + description: The absolute value of the maximum score. weight: type: number format: double @@ -2756,6 +2802,7 @@ components: required: - criteria - score + - score_max ComparisonCriteriaScoreRequest: type: object properties: @@ -2767,9 +2814,12 @@ components: score: type: number format: double - maximum: 10.0 - minimum: -10.0 description: Score for the given comparison + score_max: + type: integer + maximum: 2147483647 + minimum: 1 + description: The absolute value of the maximum score. weight: type: number format: double @@ -2777,6 +2827,7 @@ components: required: - criteria - score + - score_max ComparisonRequest: type: object description: |- @@ -3842,6 +3893,25 @@ components: type: array items: $ref: '#/components/schemas/VideoSerializerWithCriteria' + PatchedComparisonUpdateRequest: + type: object + description: |- + A comparison serializer used only for updates. + + Given the context determined by the view, it will represent or save the + comparison in the reverse order. + + Use `ComparisonSerializer` for all other operations. + properties: + criteria_scores: + type: array + items: + $ref: '#/components/schemas/ComparisonCriteriaScoreRequest' + duration_ms: + type: number + format: double + nullable: true + description: Time it took to rate the videos (in milliseconds) PatchedContributorRatingRequest: type: object properties: @@ -4364,11 +4434,14 @@ components: comparison_score: type: number format: double + comparison_score_max: + type: integer expected_comparison_score: type: number format: double required: - comparison_score + - comparison_score_max - criteria - entity_1_rating - entity_1_uid diff --git a/frontend/src/features/comparisons/ComparisonSliders.tsx b/frontend/src/features/comparisons/ComparisonSliders.tsx index 12a3ae126d..1866bdaaea 100644 --- a/frontend/src/features/comparisons/ComparisonSliders.tsx +++ b/frontend/src/features/comparisons/ComparisonSliders.tsx @@ -22,7 +22,7 @@ import { resetPendingRatings, } from 'src/utils/comparison/pending'; import { CriteriaValuesType } from 'src/utils/types'; -import CriteriaSlider from './CriteriaSlider'; +import CriteriaSlider, { SLIDER_SCORE_MAX } from './CriteriaSlider'; const useStyles = makeStyles(() => ({ root: { @@ -96,7 +96,11 @@ const ComparisonSliders = ({ entity_b: { uid: uidB }, criteria_scores: criterias .filter((c) => !c.optional || critAlwaysDisplayed?.includes(c.name)) - .map((c) => ({ criteria: c.name, score: pendingRatings[c.name] || 0 })), + .map((c) => ({ + criteria: c.name, + score: pendingRatings[c.name] || 0, + score_max: SLIDER_SCORE_MAX, + })), }; }; @@ -154,7 +158,11 @@ const ComparisonSliders = ({ } }; - const handleSliderChange = (criteria: string, score: number | undefined) => { + const handleSliderChange = ( + criteria: string, + score: number | undefined, + scoreMax: number + ) => { const cs = comparison.criteria_scores.find((c) => c.criteria === criteria); if (score === undefined) { comparison.criteria_scores = comparison.criteria_scores.filter( @@ -163,8 +171,14 @@ const ComparisonSliders = ({ } else if (cs) { if (cs.score == score) return; cs.score = score; + cs.score_max = scoreMax; } else { - comparison.criteria_scores.push({ criteria, score, weight: 1 }); + comparison.criteria_scores.push({ + criteria, + score, + score_max: scoreMax, + weight: 1, + }); } clearPendingRating(pollName, uidA, uidB, criteria); @@ -181,7 +195,11 @@ const ComparisonSliders = ({ .map((c) => c.name); optionalCriteriasKeys.forEach((criteria) => - handleSliderChange(criteria, showOptionalCriterias ? undefined : 0) + handleSliderChange( + criteria, + showOptionalCriterias ? undefined : 0, + SLIDER_SCORE_MAX + ) ); }; diff --git a/frontend/src/features/comparisons/CriteriaSlider.tsx b/frontend/src/features/comparisons/CriteriaSlider.tsx index a7afb66c06..b13137c26e 100644 --- a/frontend/src/features/comparisons/CriteriaSlider.tsx +++ b/frontend/src/features/comparisons/CriteriaSlider.tsx @@ -18,8 +18,9 @@ import { CriteriaIcon, InternalLink } from 'src/components'; import { getCriteriaTooltips } from 'src/utils/constants'; import { RouteID } from 'src/utils/types'; -const SLIDER_MIN_STEP = -10; -const SLIDER_MAX_STEP = 10; +export const SLIDER_SCORE_MAX = 10; +const SLIDER_MIN_STEP = -SLIDER_SCORE_MAX; +const SLIDER_MAX_STEP = +SLIDER_SCORE_MAX; const SLIDER_STEP = 1; const useStyles = makeStyles(() => ({ @@ -125,7 +126,11 @@ const CriteriaSlider = ({ criteriaLabel: string; criteriaValue: number | undefined; disabled?: boolean; - handleSliderChange: (criteria: string, value: number | undefined) => void; + handleSliderChange: ( + criteria: string, + value: number | undefined, + valueMax: number + ) => void; }) => { const { t } = useTranslation(); const classes = useStyles(); @@ -187,7 +192,11 @@ const CriteriaSlider = ({ disabled={disabled} checked={criteriaValue !== undefined} onChange={(e: React.ChangeEvent) => - handleSliderChange(criteria, e.target.checked ? 0 : undefined) + handleSliderChange( + criteria, + e.target.checked ? 0 : undefined, + SLIDER_SCORE_MAX + ) } color="secondary" sx={{ @@ -224,7 +233,7 @@ const CriteriaSlider = ({ track={false} disabled={disabled || criteriaValue === undefined} onChange={(_: Event, score: number | number[]) => - handleSliderChange(criteria, score as number) + handleSliderChange(criteria, score as number, SLIDER_SCORE_MAX) } /> diff --git a/solidago/src/solidago/pipeline/inputs.py b/solidago/src/solidago/pipeline/inputs.py index 2d644bfa7a..686323c37a 100644 --- a/solidago/src/solidago/pipeline/inputs.py +++ b/solidago/src/solidago/pipeline/inputs.py @@ -29,6 +29,7 @@ def get_comparisons( * `entity_b`: int or str * `criteria`: str * `score`: float + * `score_max`: int * `weight`: float """ raise NotImplementedError @@ -105,7 +106,10 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame: if user_id is not None: dtf = dtf[dtf.user_id == user_id] dtf["weight"] = 1 - return dtf[["user_id", "entity_a", "entity_b", "criteria", "score", "weight"]] + if "score_max" not in dtf: + # For compatibility with older datasets + dtf["score_max"] = 10 + return dtf[["user_id", "entity_a", "entity_b", "criteria", "score", "score_max", "weight"]] @cached_property def ratings_properties(self): diff --git a/solidago/src/solidago/pipeline/legacy2023/individual_scores.py b/solidago/src/solidago/pipeline/legacy2023/individual_scores.py index 92952ea470..333e987a01 100644 --- a/solidago/src/solidago/pipeline/legacy2023/individual_scores.py +++ b/solidago/src/solidago/pipeline/legacy2023/individual_scores.py @@ -5,6 +5,7 @@ from solidago.pipeline import TournesolInput from .parameters import PipelineParameters + def get_individual_scores( input: TournesolInput, criteria: str, @@ -12,6 +13,14 @@ def get_individual_scores( single_user_id: Optional[int] = None, ) -> pd.DataFrame: comparisons_df = input.get_comparisons(criteria=criteria, user_id=single_user_id) + # Legacy pipeline assumes all comparisons use the same 'score_max' + score_max_series = comparisons_df.pop("score_max") + if score_max_series.nunique() > 1: + raise RuntimeError( + "Legacy pipeline does not support multiple 'score_max' in comparisons. " + f"Found {dict(score_max_series.value_counts())}" + ) + initial_contributor_scores = input.get_individual_scores( criteria=criteria, user_id=single_user_id ) @@ -19,15 +28,14 @@ def get_individual_scores( initial_contributor_scores = initial_contributor_scores.groupby("user_id") individual_scores = [] - for (user_id, user_comparisons) in comparisons_df.groupby("user_id"): + for user_id, user_comparisons in comparisons_df.groupby("user_id"): if initial_contributor_scores is None: initial_entity_scores = None else: try: contributor_score_df = initial_contributor_scores.get_group(user_id) initial_entity_scores = pd.Series( - data=contributor_score_df.raw_score, - index=contributor_score_df.entity + data=contributor_score_df.raw_score, index=contributor_score_df.entity ) except KeyError: initial_entity_scores = None diff --git a/solidago/src/solidago/preference_learning/generalized_bradley_terry.py b/solidago/src/solidago/preference_learning/generalized_bradley_terry.py index 5b97f3bb19..3e2cc9596e 100644 --- a/solidago/src/solidago/preference_learning/generalized_bradley_terry.py +++ b/solidago/src/solidago/preference_learning/generalized_bradley_terry.py @@ -216,18 +216,18 @@ def hessian_diagonal_element( score_diff = solution[coordinate] - solution[coordinate_bis] result += self.cumulant_generating_function_second_derivative(score_diff) return result - - + + class UniformGBT(GeneralizedBradleyTerry): + def __init__( - self, - prior_std_dev: float=7, - comparison_max: float=10, - convergence_error: float=1e-5, - cumulant_generating_function_error: float=1e-5, + self, + prior_std_dev: float = 7, + convergence_error: float = 1e-5, + cumulant_generating_function_error: float = 1e-5, ): """ - + Parameters ---------- initialization: dict[int, float] @@ -236,22 +236,10 @@ def __init__( tolerated error """ super().__init__(prior_std_dev, convergence_error) - self.comparison_max = comparison_max self.cumulant_generating_function_error = cumulant_generating_function_error - + @cached_property def cumulant_generating_function_derivative(self) -> Callable[[npt.NDArray], npt.NDArray]: - """ For. - - Parameters - ---------- - score_diff: float - Score difference - - Returns - ------- - out: float - """ tolerance = self.cumulant_generating_function_error @njit @@ -259,38 +247,36 @@ def f(score_diff: npt.NDArray): return np.where( np.abs(score_diff) < tolerance, score_diff / 3, - 1/ np.tanh(score_diff) - 1 / score_diff + 1 / np.tanh(score_diff) - 1 / score_diff, ) + return f - def cumulant_generating_function_second_derivative(self, score_diff: float) -> float: - """ We estimate uncertainty by the flatness of the negative log likelihood, + """We estimate uncertainty by the flatness of the negative log likelihood, which is directly given by the second derivative of the cumulant generating function. - + Parameters ---------- score_diff: float Score difference - + Returns ------- out: float """ if np.abs(score_diff) < self.cumulant_generating_function_error: - return (1/3) - (score_diff**2 / 15) - return 1 - (1 / np.tanh(score_diff)**2) + (1 / score_diff**2) - + return (1 / 3) - (score_diff**2 / 15) + return 1 - (1 / np.tanh(score_diff) ** 2) + (1 / score_diff**2) + def to_json(self): return type(self).__name__, dict( prior_std_dev=self.prior_std_dev, - comparison_max=self.comparison_max, convergence_error=self.convergence_error, cumulant_generating_function_error=self.cumulant_generating_function_error, ) - + def __str__(self): - prop_names = ["prior_std_dev", "convergence_error", "comparison_max", - "cumulant_generating_function_error"] + prop_names = ["prior_std_dev", "convergence_error", "cumulant_generating_function_error"] prop = ", ".join([f"{p}={getattr(self, p)}" for p in prop_names]) return f"{type(self).__name__}({prop})" From ce94b0b10749db8e82c51cfa8358299fc67db8a5 Mon Sep 17 00:00:00 2001 From: Adrien Matissart Date: Mon, 6 May 2024 09:40:50 +0200 Subject: [PATCH 4/4] [back] chore: clarity instructions about secret key configuration (#1967) --- backend/dev-env/settings-tournesol.yaml | 5 ++++ backend/documentation/settings-tournesol.yaml | 17 +++++++++--- backend/settings/settings.py | 26 +++++++------------ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/backend/dev-env/settings-tournesol.yaml b/backend/dev-env/settings-tournesol.yaml index 109405c7a9..c39d3b6081 100644 --- a/backend/dev-env/settings-tournesol.yaml +++ b/backend/dev-env/settings-tournesol.yaml @@ -1,3 +1,8 @@ +# This configuration file is intended for development environment only +# (see instructions in /dev-env/README.md). +# Find more information regarding the configuration and a detailed example +# in /backend/documentation/settings-tournesol.yaml + DEBUG: True SECRET_KEY: g&*0o49mk(t&*vvdsfsdgfsdgsgesqdg5n*e7ars&$qz*lpi^s$k* ALLOWED_HOSTS: diff --git a/backend/documentation/settings-tournesol.yaml b/backend/documentation/settings-tournesol.yaml index 30c0c819f8..fbcabc6354 100644 --- a/backend/documentation/settings-tournesol.yaml +++ b/backend/documentation/settings-tournesol.yaml @@ -1,7 +1,16 @@ +# This file is an example settings file for Tournesol backend. +# It should NOT be deployed as is. +# Follow the instructions below to adapt the configuration +# and generate secret values. + # to be set to False in production DEBUG: True -# to be changed in production + +# TO BE CHANGED IN PRODUCTION +# Can be generated (for example) with the command below: +# `openssl rand -base64 48` SECRET_KEY: g&*0o49mk(t&*vvdsfsdgfsdgsgesqdg5n*e7ars&$qz*lpi^s$k* + # to be set to the actual hosts on which the API in served in production ALLOWED_HOSTS: - localhost @@ -35,8 +44,10 @@ LOGIN_URL: /admin/login OIDC_ENABLED: true # to be set to the actual IDP URI in production OIDC_ISS_ENDPOINT: http://localhost:8000/o -# test key generated with the command below (change it in production) -# openssl genrsa 4096 + +# TO BE CHANGED IN PRODUCTION +# The key can be generated with the command below: +# `openssl genrsa 4096` OIDC_RSA_PRIVATE_KEY: | -----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEAx0m1CHyJjkjCQW3f9pRDXHDWkmJtEGTPLqoxug8TRi6baRKs diff --git a/backend/settings/settings.py b/backend/settings/settings.py index 5507df2a42..7994ac0a56 100644 --- a/backend/settings/settings.py +++ b/backend/settings/settings.py @@ -27,17 +27,20 @@ with open(SETTINGS_FILE, "r") as f: server_settings = yaml.full_load(f) except FileNotFoundError: - print("No local settings.") - pass + print("WARNING: no local settings.") -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ + +# For guidelines related to settings in production +# see https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # SECURITY WARNING # Do not commit any secret used in staging or production. -SECRET_KEY = server_settings.get( - "SECRET_KEY", "django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1" -) +if "SECRET_KEY" in server_settings: + SECRET_KEY = server_settings["SECRET_KEY"] +else: + print("WARNING: using default secret key, as none was found in local settings.") + # The default key generated by Django is only be used for testing purposes. + SECRET_KEY = "django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1" # nosec B105 # SECURITY WARNING # Don't set DEBUG to True in staging or production. @@ -209,13 +212,6 @@ }, } -DRF_RECAPTCHA_PUBLIC_KEY = server_settings.get( - "DRF_RECAPTCHA_PUBLIC_KEY", "dsfsdfdsfsdfsdfsdf" -) -DRF_RECAPTCHA_SECRET_KEY = server_settings.get( - "DRF_RECAPTCHA_SECRET_KEY", "dsfsdfdsfsdf" -) - # Password validation # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators @@ -327,8 +323,6 @@ 'entertaining_relaxing', ] -# maximal weight to assign to a rating for a particular feature, see #41 -MAX_FEATURE_WEIGHT = 8 SPECTACULAR_SETTINGS = { # Split data components into 2 distinct schemas for request and response.