HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonMinor

Algorithm to generate this alignment pattern locations table for QR codes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thislocationstablealignmentalgorithmgeneratecodesforpattern

Problem

I'm looking for a way to generate the following the series of numbers given the version number on the left. For example, given "2", generate [6, 18]. The series of numbers is from the alignment pattern locations for different versions of QR codes.

V2  6  18
 V3  6  22
 V4  6  26
 V5  6  30
 V6  6  34
 V7  6  22  38
 V8  6  24  42
 V9  6  26  46
V10  6  28  50
V11  6  30  54
V12  6  32  58
V13  6  34  62
V14  6  26  46  66
V15  6  26  48  70
V16  6  26  50  74
V17  6  30  54  78
V18  6  30  56  82
V19  6  30  58  86
V20  6  34  62  90
V21  6  28  50  72   94
V22  6  26  50  74   98
V23  6  30  54  78  102
V24  6  28  54  80  106
V25  6  32  58  84  110
V26  6  30  58  86  114
V27  6  34  62  90  118
V28  6  26  50  74   98  122
V29  6  30  54  78  102  126
V30  6  26  52  78  104  130
V31  6  30  56  82  108  134
V32  6  34  60  86  112  138
V33  6  30  58  86  114  142
V34  6  34  62  90  118  146
V35  6  30  54  78  102  126  150
V36  6  24  50  76  102  128  154
V37  6  28  54  80  106  132  158
V38  6  32  58  84  110  136  162
V39  6  26  54  82  110  138  166
V40  6  30  58  86  114  142  170


I've come up with the following Python code which generates the correct sequences, but contains an "exceptional" condition for V32, expressed in the if statement.

import math

def pattern(ver):
    w = 21 + ((ver - 1) * 4)       # Width
    h = 6                          # First item
    t = (w - 1) - 6                # Last item
    r = t - h                      # Distance between first and last
    n = math.ceil(r/28)            # Number of items in list - 1

    if (w == 145):
        intervals = 26             # Anomaly
    else:
        intervals = math.ceil(r/n) # Ceiling to nearest multiple of 2
        intervals = intervals + (intervals % 2)

    xs = [t]
    for m in (n-1) * [intervals]: xs.append(xs[-1] - m)
    xs.append(h)
    return list(reversed(xs))

for n in range(2, 41):
    print("Version {:2d}: {}".format(n, pattern(n)))


I'm lookin

Solution

I don't think such algorithm exists, because I looked quite hard and couldn't find it. It seems you have to follow the given table. Your formula approximates it pretty well. Too bad about the magic branch, but this shouldn't be a major concern anyway:
it's a small table that you only need to calculate once and can reuse later,
so any performance issues should be negligible in practice.

Coding style

The coding style can be improved.
Follow PEP8, the official coding style guide of Python,
for example, put 2 blank lines in front of top-level method definitions

Unnecessary parentheses

The parentheses around the multiplication are unnecessary here:

w = 21 + ((ver - 1) * 4)       # Width


It would be better to use more meaningful variable names,
for example no need to shorten version as ver.

Unnecessary parentheses here:

if (w == 145):


The augmented assignment operator +=

Instead of:

intervals = intervals + (intervals % 2)


This is better:

intervals += intervals % 2


Use one statement per line

Break the line after :, for example instead of:

for m in (n-1) * [intervals]: xs.append(xs[-1] - m)


Write like this:

for m in (n-1) * [intervals]: 
    xs.append(xs[-1] - m)


Avoid code in the global namespace

Move code out of the global namespace into methods, so instead of this:

for n in range(2, 41):
    print("Version {:2d}: {}".format(n, pattern(n)))


Do it this way:

def main():
    for n in range(2, 41):
        print("Version {:2d}: {}".format(n, pattern(n)))

if __name__ == '__main__':
    main()

Code Snippets

w = 21 + ((ver - 1) * 4)       # Width
if (w == 145):
intervals = intervals + (intervals % 2)
intervals += intervals % 2
for m in (n-1) * [intervals]: xs.append(xs[-1] - m)

Context

StackExchange Code Review Q#74925, answer score: 3

Revisions (0)

No revisions yet.