1
\$\begingroup\$

I have created a database using Django. I have a small statistics page as shown below. Can I improve this code?

View file

def statistics(request):
        """ Return the number of categories (Category is based on first 
        three-letter character, say Cry in the example) in the database 
        and its corresponding count.

        The holotype is a protein name that ends in 1. Example: Cry1Aa1
        A holotype is a single protein name used to name the lower rank based on identity. 
        Cry1Aa2 is named based on the identity to Cry1Aa1
        """
    category_count = {}
    category_holotype_count = {}
    category_prefixes = []
    total_holotype = 0

    categories = \
        PesticidalProteinDatabase.objects.order_by(
            'name').values_list('name', flat=True).distinct()
    for category in categories:
        cat = category[:3]
        if category[-1] == '1' and not category[-2].isdigit():
            total_holotype += 1
            count = category_holotype_count.get(cat, 0)
            count += 1
            category_holotype_count[cat] = count

    category_count['Holotype'] = [total_holotype] * 2

    for category in categories:
        prefix = category[0:3]
        if prefix not in category_prefixes:
            category_prefixes.append(prefix)

    for category in category_prefixes:
        count = PesticidalProteinDatabase.objects.filter(
            name__istartswith=category).count()
        category_count[category] = [
            count, category_holotype_count.get(category, 0)]

    prefix_count_dictionary = {}
    for prefix in category_prefixes:
        prefix_count_dictionary[prefix] = category_count[prefix][0]

    prefix_count_dictionary.pop('Holotype', None)

    context = \
        {'category_prefixes': category_prefixes,
         'category_count': category_count}

    return render(request, 'database/statistics.html', context)

Urls file

    path('statistics/', views.statistics,
         name='statistics'),

Sample HTML file

<b>General Statistics</b>

        <table class="table table-bordered table-hover">
            <thead>
                <tr>
                    <th>No</th>
                    <th>Category</th>
                    <th>Total Count</th>
                    <th>Holotype Count</th>
                </tr>

           {% for key,value in category_count.items %}

                    <tr>
                        <td> {{ forloop.counter }} </td>
                        <td> {{ key }} </td>
                        <td> {{ value.0 }} </td>
                        <td> {{ value.1 }} </td>
                    </tr>
           {% endfor %}
            <thead>
        <table>

Display page

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Please show more of your code, including what produces request. \$\endgroup\$
    – Reinderien
    Commented May 27, 2020 at 17:37

1 Answer 1

1
\$\begingroup\$

The first for loop can be simplified a lot by using collections.Counter. The generation of the distinct category_prefixes using a set and the final category_count dictionary using a dictionary comprehension:

db = PesticidalProteinDatabase
categories = db.objects.order_by('name').values_list('name', flat=True).distinct()
holotype_counts = Counter(category[:3] for category in categories
                          if category[-1] == '1' and not category[-2].isdigit())

category_prefixes = sorted({category[:3] for category in categories})
category_count = {cat: [db.objects.filter(name__istartswith=cat).count(), 
                        holotype_counts[cat]]
                  for cat in category_prefixes}
category_count['Holotype'] = [sum(holotype_counts.values())] * 2

Note that PesticidalProteinDatabase is not a name following Python's official style-guide, PEP8, which recommends using lower_case for variables and functions and PascalCase only for classes (not instances of classes).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.