Category: Python

Validating GRids: A Python GRid check digit calculator

June 27, 2012

A Global Resource Identifier, or GRid, is used in the music industry to uniquely identify digital data such as sound recordings. Like barcodes, the last digit is a check digit to verify that the preceding digits were correct.

Calculating the check digit for a GRid is a little more of an obscure need than barcodes, but this Python code snippet will save whomever needs to do it in Python a bunch of time!

def calculate_grid_check_digit(grid):
    """
    Assumes `grid` is 17 characters long
    and missing the check digit.
    """
    def _mod_36(i):
        """
        A modified modulus function is used
        by the algorithm.
        """
        m = i % 36
        return 36 if m == 0 else m

    grid = grid.upper()
    lookup_values = ['0','1','2','3','4','5','6','7','8','9',
                     'A','B','C','D','E','F','G','H','I','J',
                     'K','L','M','N','O','P','Q','R','S','T',
                     'U','V','W','X','Y','Z']
    p_list = [36]
    s_list = []
    
    for j, c in enumerate(grid):
        c_val = lookup_values.index(c)
        s_list.append(p_list[j]%37+int(c_val))
        p_list.append(_mod_36(s_list[j]) * 2)
    
    i = 0
    while 1:
        if _mod_36(p_list[-1]%37 + i) == 1:
            break;
        i += 1
    return lookup_values[i]

You can read more on GRids at the International Federation of the Phonographic Industry website and access their online GRid validator. (Don't view the JavaScript source though, for the code is terrible!)

Categories: Programming, Python

View Comments


Validating barcodes

June 1, 2012

Here is some Python to validate barcodes (tested with EAN-13s). Someone should find it useful.

get_check_digit() will generate the valid check digit for the first part of a barcode. While is_valid_barcode() will check the final digit of a barcode against the generated check digit.

import math

def get_check_digit(b):
    """
    Returns the check digit for a barcode.
    
    It is assumed that the check digit is missing from the input.
    """
    sum = 0
    for x, c in enumerate(b[::-1]):
        if (x + 1) % 2:
            sum += int(c) * 3
        else:
            sum += int(c)
    return str(int(math.ceil(sum / 10.0) * 10) - sum)

def is_valid_barcode(b):
    """
    Checks the last digit of a barcode matches the calculated 
    check digit.
    """
    return get_check_digit(b[0:-1]) == b[-1]

test_data = (
    # Valid barcodes
    ('9771473968012', True),
    ('0123456789012', True),
    ('1234567890128', True),
    # Invalid barcodes
    ('9771473968011', False),
    ('0123456789019', False),
    ('1234567890127', False),
)

for t in test_data:
    print t[1] == is_valid_barcode(t[0])

Categories: Programming, Python

View Comments


A nicer way of using the Django 1.2 messages framework

May 11, 2010

Update: Someone asked me "why?" recently, claiming you could just order messages in the view. It slipped my mind that the whole point of this solution is that it's usable in any template without extra work, so you can render the messages out in your base template and then forget about it.


In Django versions prior to 1.2 adding user feedback messages was cumbersome. In your view you'd use a snippet like this request.user.message_set.create(message='My message.').

to add a message to be retrieved and displayed to the user in the template. Messages were also attached to the current user and had no severity level.

Version 1.2 brings an easy to use messages framework. Adding a new message becomes as simple as messages.success(request, 'Your details have been updated.') or messages.warning(request, 'Your password expires in one week.'). Built-in levels are debug, info, success, warning and error, and adding your own is easy.

To retrieve the messages in the template you need to make sure your view renders the template with the current request as the context_instance like so:

def my_view(request):
    # ...
    return render_to_response('my_template.html',
    	my_dict,
        context_instance=RequestContext(request))

And them spit them out in the template like this:

{% if messages %}
  <ul>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
  </ul>
{% endif %}

This is where I think the framework falls down. All your info, success, warning and error messages are in the same list. Whilst you can check the tag/level and include it as a CSS class for the <li> you can't get around that it's still the same list. It's quite common to see success and warning messages styled differently in <div>s with red and green backgrounds, and as far as I can tell there's no way of doing this with the framework without hackery.

To counter this I wrote a template tag that accepts the messages instance and separates all the messages out into separate <ul>s ordered by level so I can style up something like this.

Example messages screenshot

The template tag is included in full below and you are free to use it as you wish. (Working example project on Github.)

from django import template
register = template.Library()

class MessagesNode(template.Node):
    """ Outputs grouped Django Messages Framework messages in separate
        lists sorted by level. """
    
    def __init__(self, messages):
        self.messages = messages
        
    def render(self, context):
        try:
            messages = context[self.messages]
            
            # Make a dictionary of messages grouped by tag, sorted by level.
            grouped = {}
            for m in messages:
                # Add message
                if (m.level, m.tags) in grouped:
                    grouped[(m.level, m.tags)].append(m.message)
                else:
                    grouped[(m.level, m.tags)] = [m.message]

            # Create a list of messages for each tag.
            out_str = ''
            for level, tag in sorted(grouped.iterkeys()):
                out_str += '<div> class="messages %s">\n<ul">' % tag
                for m in grouped[(level, tag)]:
                    out_str += '<li>%s</li>' % (m)
                out_str += '</ul>\n</div>\n'
                
            return out_str
            
        except KeyError:
            return ''
        
@register.tag(name='render_messages')
def render_messages(parser, token):
    parts = token.split_contents()
    if len(parts) != 2:
        raise template.TemplateSyntaxError("%r tag requires a single argument"
                                           % token.contents.split()[0])
    return MessagesNode(parts[1])

Calling the tag form your template is then done like this:

{% load messages %}
...
{% render_messages messages %}

Easy!

This gives you a separate list, in a <div>, for each tag/level in the messages object (see below) so you're free to style them all differently.

<div class="messages success">
  <ul>
    <li>This is a success message.</li>
  </ul>
</div>
<div class="messages error">
  <ul>
    <li>This is an error message.</li>
    <li>This is another error message.</li>
  </ul>
</div>

Visit Github for an example site using all the code, with sample CSS and images ready to drop into your own projects.

Categories: Django, Programming, Python

View Comments


About me

Hi, I'm Ben Tappin.

I make stuff, mainly for the web. You can read more about me.

And you can hire me for freelance work.