From 19981848832a68b2ff97faea178365537b422404 Mon Sep 17 00:00:00 2001 From: katanasovski Date: Mon, 11 Apr 2022 10:32:44 +0200 Subject: [PATCH 1/5] Change reading for mastery_model --- .../commands/fix_exercise_complete.py | 15 ++------ .../management/commands/handling_function.py | 36 +++++++++++++++++++ .../management/commands/mark_incomplete.py | 6 ++++ 3 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 contentcuration/contentcuration/management/commands/handling_function.py diff --git a/contentcuration/contentcuration/management/commands/fix_exercise_complete.py b/contentcuration/contentcuration/management/commands/fix_exercise_complete.py index b2e465cb13..8af0b935c8 100644 --- a/contentcuration/contentcuration/management/commands/fix_exercise_complete.py +++ b/contentcuration/contentcuration/management/commands/fix_exercise_complete.py @@ -5,6 +5,7 @@ from django.db.models import Q from le_utils.constants import content_kinds from le_utils.constants import exercises +from handling_function import handling_mastery_competition_criteria from contentcuration.models import ContentNode from contentcuration.models import License @@ -23,19 +24,7 @@ def handle(self, *args, **options): reset_time = time.time() - mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE)\ - .filter(Q(extra_fields__has_key='mastery_model')).order_by().count() - - i = 0 - - while i < mastery_model_exercise_count: - chunk_time = time.time() - update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE)\ - .filter(Q(extra_fields__has_key='mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] - ContentNode.objects.filter(pk__in=update_ids).update(complete=True) - logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) - i += CHUNKSIZE - + i = handling_mastery_competition_criteria() logging.info('Marked all mastery_modeled exercises as complete=True (finished in {})'.format(time.time() - reset_time)) # Mark invalid titles diff --git a/contentcuration/contentcuration/management/commands/handling_function.py b/contentcuration/contentcuration/management/commands/handling_function.py new file mode 100644 index 0000000000..fd94e4fb13 --- /dev/null +++ b/contentcuration/contentcuration/management/commands/handling_function.py @@ -0,0 +1,36 @@ +from contentcuration.models import ContentNode +from le_utils.constants import content_kinds +import time +import logging as logmodule +from django.db.models import Q + +logging = logmodule.getLogger('command') +CHUNKSIZE = 10000 + + +def handling_mastery_competition_criteria(): + mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='mastery_model')).order_by().count() + + i = 0 + + while i < mastery_model_exercise_count: + chunk_time = time.time() + update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] + ContentNode.objects.filter(pk__in=update_ids).update(complete=True) + logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) + i += CHUNKSIZE + + mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='option.completion_criteria.mastery_model')).order_by().count() + + while i < mastery_model_exercise_count: + chunk_time = time.time() + update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='option.completion_criteria.mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] + ContentNode.objects.filter(pk__in=update_ids).update(complete=True) + logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) + i += CHUNKSIZE + + return i diff --git a/contentcuration/contentcuration/management/commands/mark_incomplete.py b/contentcuration/contentcuration/management/commands/mark_incomplete.py index 95b4702834..cac9f93ad1 100644 --- a/contentcuration/contentcuration/management/commands/mark_incomplete.py +++ b/contentcuration/contentcuration/management/commands/mark_incomplete.py @@ -118,6 +118,12 @@ def handle(self, *args, **options): logging.info('Marking mastery_model less exercises...') count = ContentNode.objects.exclude(complete=False).filter(kind_id=content_kinds.EXERCISE).filter(~Q(extra_fields__has_key='mastery_model')) \ .order_by().update(complete=False) + + logging.info('Marked {} mastery_model less exercises(finished in {})'.format(count, time.time() - exercisestart)) + + count = ContentNode.objects.exclude(complete=False).filter(kind_id=content_kinds.EXERCISE).filter(~Q(extra_fields__has_key='option.completion_criteria.mastery_model')) \ + .order_by().update(complete=False) + logging.info('Marked {} mastery_model less exercises(finished in {})'.format(count, time.time() - exercisestart)) exercisestart = time.time() From d312d30470b5524a9fe1dae523c88939bcdbe02c Mon Sep 17 00:00:00 2001 From: katanasovski Date: Mon, 11 Apr 2022 10:37:29 +0200 Subject: [PATCH 2/5] Change reading for mastery_model --- contentcuration/contentcuration/utils/publish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contentcuration/contentcuration/utils/publish.py b/contentcuration/contentcuration/utils/publish.py index bb200e018d..2bc262fba2 100644 --- a/contentcuration/contentcuration/utils/publish.py +++ b/contentcuration/contentcuration/utils/publish.py @@ -403,7 +403,7 @@ def process_assessment_metadata(ccnode, kolibrinode): randomize = exercise_data.get('randomize') if exercise_data.get('randomize') is not None else True assessment_item_ids = [a.assessment_id for a in assessment_items] - mastery_model = {'type': exercise_data.get('mastery_model') or exercises.M_OF_N} + mastery_model = {'type': exercise_data.get('mastery_model') or exercises.M_OF_N or exercise_data.get('option.completion_criteria.mastery_model')} if mastery_model['type'] == exercises.M_OF_N: mastery_model.update({'n': exercise_data.get('n') or min(5, assessment_items.count()) or 1}) mastery_model.update({'m': exercise_data.get('m') or min(5, assessment_items.count()) or 1}) From 2efc3439af48b2bb1d30a13f035be1ce7b9c0bed Mon Sep 17 00:00:00 2001 From: katanasovski Date: Tue, 26 Apr 2022 09:52:45 +0200 Subject: [PATCH 3/5] Fixes, changed mastery models. --- .../commands/fix_exercise_complete.py | 27 ++++++++++++-- .../management/commands/handling_function.py | 36 ------------------- .../management/commands/mark_incomplete.py | 2 +- .../contentcuration/utils/publish.py | 10 +++++- 4 files changed, 34 insertions(+), 41 deletions(-) delete mode 100644 contentcuration/contentcuration/management/commands/handling_function.py diff --git a/contentcuration/contentcuration/management/commands/fix_exercise_complete.py b/contentcuration/contentcuration/management/commands/fix_exercise_complete.py index 8af0b935c8..74b3438302 100644 --- a/contentcuration/contentcuration/management/commands/fix_exercise_complete.py +++ b/contentcuration/contentcuration/management/commands/fix_exercise_complete.py @@ -5,7 +5,6 @@ from django.db.models import Q from le_utils.constants import content_kinds from le_utils.constants import exercises -from handling_function import handling_mastery_competition_criteria from contentcuration.models import ContentNode from contentcuration.models import License @@ -21,10 +20,32 @@ class Command(BaseCommand): def handle(self, *args, **options): start = time.time() - reset_time = time.time() - i = handling_mastery_competition_criteria() + mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='mastery_model')).order_by().count() + + i = 0 + + while i < mastery_model_exercise_count: + chunk_time = time.time() + update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] + ContentNode.objects.filter(pk__in=update_ids).update(complete=True) + logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) + i += CHUNKSIZE + + mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='option.completion_criteria.mastery_model')).order_by().count() + + while i < mastery_model_exercise_count: + chunk_time = time.time() + update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ + .filter(Q(extra_fields__has_key='option.completion_criteria.mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] + ContentNode.objects.filter(pk__in=update_ids).update(complete=True) + logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) + i += CHUNKSIZE + logging.info('Marked all mastery_modeled exercises as complete=True (finished in {})'.format(time.time() - reset_time)) # Mark invalid titles diff --git a/contentcuration/contentcuration/management/commands/handling_function.py b/contentcuration/contentcuration/management/commands/handling_function.py deleted file mode 100644 index fd94e4fb13..0000000000 --- a/contentcuration/contentcuration/management/commands/handling_function.py +++ /dev/null @@ -1,36 +0,0 @@ -from contentcuration.models import ContentNode -from le_utils.constants import content_kinds -import time -import logging as logmodule -from django.db.models import Q - -logging = logmodule.getLogger('command') -CHUNKSIZE = 10000 - - -def handling_mastery_competition_criteria(): - mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ - .filter(Q(extra_fields__has_key='mastery_model')).order_by().count() - - i = 0 - - while i < mastery_model_exercise_count: - chunk_time = time.time() - update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ - .filter(Q(extra_fields__has_key='mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] - ContentNode.objects.filter(pk__in=update_ids).update(complete=True) - logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) - i += CHUNKSIZE - - mastery_model_exercise_count = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ - .filter(Q(extra_fields__has_key='option.completion_criteria.mastery_model')).order_by().count() - - while i < mastery_model_exercise_count: - chunk_time = time.time() - update_ids = ContentNode.objects.filter(kind_id=content_kinds.EXERCISE) \ - .filter(Q(extra_fields__has_key='option.completion_criteria.mastery_model')).order_by("id").values_list("id", flat=True)[i: i + CHUNKSIZE] - ContentNode.objects.filter(pk__in=update_ids).update(complete=True) - logging.info('Marked {} nodes as complete=True in {} seconds'.format(CHUNKSIZE, time.time() - chunk_time)) - i += CHUNKSIZE - - return i diff --git a/contentcuration/contentcuration/management/commands/mark_incomplete.py b/contentcuration/contentcuration/management/commands/mark_incomplete.py index cac9f93ad1..0e058b4e95 100644 --- a/contentcuration/contentcuration/management/commands/mark_incomplete.py +++ b/contentcuration/contentcuration/management/commands/mark_incomplete.py @@ -121,7 +121,7 @@ def handle(self, *args, **options): logging.info('Marked {} mastery_model less exercises(finished in {})'.format(count, time.time() - exercisestart)) - count = ContentNode.objects.exclude(complete=False).filter(kind_id=content_kinds.EXERCISE).filter(~Q(extra_fields__has_key='option.completion_criteria.mastery_model')) \ + count = ContentNode.objects.exclude(complete=False).filter(kind_id=content_kinds.EXERCISE).filter(~Q(extra_fields__has_key='mastery_model') & ~Q(extra_fields__has_key='option.completion_criteria.mastery_model')) \ .order_by().update(complete=False) logging.info('Marked {} mastery_model less exercises(finished in {})'.format(count, time.time() - exercisestart)) diff --git a/contentcuration/contentcuration/utils/publish.py b/contentcuration/contentcuration/utils/publish.py index 2bc262fba2..3615b4bb27 100644 --- a/contentcuration/contentcuration/utils/publish.py +++ b/contentcuration/contentcuration/utils/publish.py @@ -403,7 +403,15 @@ def process_assessment_metadata(ccnode, kolibrinode): randomize = exercise_data.get('randomize') if exercise_data.get('randomize') is not None else True assessment_item_ids = [a.assessment_id for a in assessment_items] - mastery_model = {'type': exercise_data.get('mastery_model') or exercises.M_OF_N or exercise_data.get('option.completion_criteria.mastery_model')} + exercise_data_type = "" + if exercise_data.get('mastery_model'): + exercise_data_type = exercise_data.get('mastery_model') + if exercises.M_OF_N: + exercise_data_type = exercises.M_OF_N + if exercise_data.get('option') or exercise_data.get('option').get('completion_criteria') or exercise_data.get('option').get('completion_criteria').get('mastery_model'): + exercise_data_type = exercise_data.get('option').get('completion_criteria').get('mastery_model') + + mastery_model = {'type': exercise_data_type} if mastery_model['type'] == exercises.M_OF_N: mastery_model.update({'n': exercise_data.get('n') or min(5, assessment_items.count()) or 1}) mastery_model.update({'m': exercise_data.get('m') or min(5, assessment_items.count()) or 1}) From dad846a77cf0337b0705ee972abb45cc94726865 Mon Sep 17 00:00:00 2001 From: katanasovski Date: Thu, 12 May 2022 11:18:04 +0200 Subject: [PATCH 4/5] Fix mastery model --- contentcuration/contentcuration/utils/publish.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contentcuration/contentcuration/utils/publish.py b/contentcuration/contentcuration/utils/publish.py index 3615b4bb27..f478fd3aa2 100644 --- a/contentcuration/contentcuration/utils/publish.py +++ b/contentcuration/contentcuration/utils/publish.py @@ -406,12 +406,10 @@ def process_assessment_metadata(ccnode, kolibrinode): exercise_data_type = "" if exercise_data.get('mastery_model'): exercise_data_type = exercise_data.get('mastery_model') - if exercises.M_OF_N: - exercise_data_type = exercises.M_OF_N if exercise_data.get('option') or exercise_data.get('option').get('completion_criteria') or exercise_data.get('option').get('completion_criteria').get('mastery_model'): exercise_data_type = exercise_data.get('option').get('completion_criteria').get('mastery_model') - mastery_model = {'type': exercise_data_type} + mastery_model = {'type': exercise_data_type or exercises.M_OF_N} if mastery_model['type'] == exercises.M_OF_N: mastery_model.update({'n': exercise_data.get('n') or min(5, assessment_items.count()) or 1}) mastery_model.update({'m': exercise_data.get('m') or min(5, assessment_items.count()) or 1}) From 6927ef0f845f9bfbd125d5e10662e0e8be1cc820 Mon Sep 17 00:00:00 2001 From: katanasovski Date: Tue, 17 May 2022 15:34:47 +0200 Subject: [PATCH 5/5] Change "or" to "and" --- contentcuration/contentcuration/utils/publish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contentcuration/contentcuration/utils/publish.py b/contentcuration/contentcuration/utils/publish.py index f478fd3aa2..9e31dd5220 100644 --- a/contentcuration/contentcuration/utils/publish.py +++ b/contentcuration/contentcuration/utils/publish.py @@ -406,7 +406,7 @@ def process_assessment_metadata(ccnode, kolibrinode): exercise_data_type = "" if exercise_data.get('mastery_model'): exercise_data_type = exercise_data.get('mastery_model') - if exercise_data.get('option') or exercise_data.get('option').get('completion_criteria') or exercise_data.get('option').get('completion_criteria').get('mastery_model'): + if exercise_data.get('option') and exercise_data.get('option').get('completion_criteria') and exercise_data.get('option').get('completion_criteria').get('mastery_model'): exercise_data_type = exercise_data.get('option').get('completion_criteria').get('mastery_model') mastery_model = {'type': exercise_data_type or exercises.M_OF_N}