Home > Net >  How to streamline code with a for statement
How to streamline code with a for statement

Time:04-25

I am trying to find the number of students enrolled by teacher. The code below produces the result I want. However, the code seems to be inefficiently long. I tried to simplify the code by using a "for" functiib, but couldn't solve it, so I posted a question to the experts for help.

The number registered in SPECIAL CLASS must be obtained separately.

The register condition is student with 1 entered in the day field.

monthly_kwargs = {
    'jan': Count('student_id', filter=Q(register_date__gte='2022-01-01', register_date__lte='2022-01-31')),
    'feb': Count('student_id', filter=Q(register_date__gte='2022-02-01', register_date__lte='2022-02-28')),
    'mar': Count('student_id', filter=Q(register_date__gte='2022-03-01', register_date__lte='2022-03-31')),
    'apr': Count('student_id', filter=Q(register_date__gte='2022-04-01', register_date__lte='2022-04-30')),
    'may': Count('student_id', filter=Q(register_date__gte='2022-05-01', register_date__lte='2022-05-31')),
    'jun': Count('student_id', filter=Q(register_date__gte='2022-06-01', register_date__lte='2022-06-30')),
    'jul': Count('student_id', filter=Q(register_date__gte='2022-07-01', register_date__lte='2022-07-31')),
    'aug': Count('student_id', filter=Q(register_date__gte='2022-08-01', register_date__lte='2022-08-31')),
    'sept': Count('student_id', filter=Q(register_date__gte='2022-09-01', register_date__lte='2022-09-30')),
    'oct': Count('student_id', filter=Q(register_date__gte='2022-10-01', register_date__lte='2022-10-31')),
    'nov': Count('student_id', filter=Q(register_date__gte='2022-11-01', register_date__lte='2022-11-30')),
    'dec': Count('student_id', filter=Q(register_date__gte='2022-12-01', register_date__lte='2022-12-31')),
    'total': Count('student_id', filter=Q(register_date__year=today.year)),
    'SPECIAL_jan': Count('student_id', filter=Q(register_date__gte='2022-01-01', register_date__lte='2022-01-31', student__class__id__in=SPECIAL)),
    'SPECIAL_feb': Count('student_id', filter=Q(register_date__gte='2022-02-01', register_date__lte='2022-02-28', student__class__id__in=SPECIAL)),
    'SPECIAL_mar': Count('student_id', filter=Q(register_date__gte='2022-03-01', register_date__lte='2022-03-31', student__class__id__in=SPECIAL)),
    'SPECIAL_apr': Count('student_id', filter=Q(register_date__gte='2022-04-01', register_date__lte='2022-04-30', student__class__id__in=SPECIAL)),
    'SPECIAL_may': Count('student_id', filter=Q(register_date__gte='2022-05-01', register_date__lte='2022-05-31', student__class__id__in=SPECIAL)),
    'SPECIAL_jun': Count('student_id', filter=Q(register_date__gte='2022-06-01', register_date__lte='2022-06-30', student__class__id__in=SPECIAL)),
    'SPECIAL_jul': Count('student_id', filter=Q(register_date__gte='2022-07-01', register_date__lte='2022-07-31', student__class__id__in=SPECIAL)),
    'SPECIAL_aug': Count('student_id', filter=Q(register_date__gte='2022-08-01', register_date__lte='2022-08-31', student__class__id__in=SPECIAL)),
    'SPECIAL_sept': Count('student_id', filter=Q(register_date__gte='2022-09-01', register_date__lte='2022-09-30', student__class__id__in=SPECIAL)),
    'SPECIAL_oct': Count('student_id', filter=Q(register_date__gte='2022-10-01', register_date__lte='2022-10-31', student__class__id__in=SPECIAL)),
    'SPECIAL_nov': Count('student_id', filter=Q(register_date__gte='2022-11-01', register_date__lte='2022-11-30', student__class__id__in=SPECIAL)),
    'SPECIAL_dec': Count('student_id', filter=Q(register_date__gte='2022-12-01', register_date__lte='2022-12-31', student__class__id__in=SPECIAL)),
    'SPECIAL_total': Count('student_id', filter=Q(register_date__year=today.year, student__class__id__in=SPECIAL))
}
value_list_args = ['teacher__first_name', 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sept', 'oct', 'nov', 'dec', 'total',
                   'SPECIAL_jan', 'SPECIA_feb', 'SPECIA_mar', 'SPECIA_apr', 'SPECIA_may', 'SPECIA_jun', 'SPECIA_jul', 'SPECIA_aug', 'SPECIA_sept', 'SPECIA_oct', 'SPECIA_nov', 'SPECIA_dec', 'SPECIA_total']

monthly_enroll = DayCheck.objects.filter(Q(day='1', register_date__year=today.year)) \
            .values('teacher__first_name').distinct() \
            .order_by('teacher__first_name') \
            .annotate(**monthly_kwargs) \
            .values_list(*value_list_args) \
            .order_by('teacher__first_name')

monthly_enroll_list = [];
for i in monthly_enroll:
    inside_list = []
    for j in i:
        inside_list.append(j)
    monthly_enroll_list.append(inside_list[0:27])

CodePudding user response:

This code seems like it may have been adapted from JavaScript, given the number of dot operators dangling off of DayCheck. Nevertheless, here are some ideas:

  • If the order of items in monthly_kwargs doesn't matter, then you can loop over months to save some lines (though I'm not sure it's actually clearer or easier to read that way.
  • The monthly_enroll_list can be turned into a very concise list comprehension, so that's good!
from datetime import datetime, timedelta

monthly_kwargs = {}
for i in range(1, 13):
    gte = datetime(2022, i, 1)
    lte = datetime(2022   i // 12, (i   1) % 12, 1) - timedelta(1)
    mo = f'{gte:%b}'.lower()
    monthly_kwargs[mo] = Count('student_id', filter=Q(
        register_date__gte=f'{gte:%Y-%m-%d}',
        register_date__lte=f'{lte:%Y-%m-%d}'
    ))
    monthly_kwargs['SPECTIAL_'   mo] = Count('student_id', filter=Q(
        register_date__gte=f'{gte:%Y-%m-%d}',
        register_date__lte=f'{lte:%Y-%m-%d}', student__class__id__in=SPECIAL
    ))
monthly_kwargs['total'] = Count('student_id', filter=Q(
    register_date__year=today.year
))
monthly_kwargs['SPECIAL_total'] = Count('student_id', filter=Q(
    register_date__year=today.year, student__class__id__in=SPECIAL
))
value_list_args = [
    'teacher__first_name', 'jan', 'feb', 'mar', 'apr', 'may',
    'jun', 'jul', 'aug', 'sept', 'oct', 'nov', 'dec', 'total',
    'SPECIAL_jan', 'SPECIA_feb', 'SPECIA_mar', 'SPECIA_apr', 'SPECIA_may',
    'SPECIA_jun', 'SPECIA_jul', 'SPECIA_aug', 'SPECIA_sept', 'SPECIA_oct',
    'SPECIA_nov', 'SPECIA_dec', 'SPECIA_total'
]
monthly_enroll = DayCheck.objects\
    .filter(Q(day='1', register_date__year=today.year))\
    .values('teacher__first_name').distinct().order_by('teacher__first_name')\
    .annotate(**monthly_kwargs).values_list(*value_list_args)\
    .order_by('teacher__first_name')

monthly_enroll_list = [list(i)[0:27] for i in monthly_enroll]
  • Related