[reportlab-users] code128.py

Robin Becker robin at reportlab.com
Tue Jan 5 09:06:41 EST 2016


Hi Klaas,

for some reason I assumed we always start in b, but perhaps I'm being stupid 
since as you suggest we can immediately switch to C.

I think you are suggesting that in the special case that

       l[startpos-1]=='START_X'

we know that START_X TO_C will be reduced so we can add one to the saving.

I believe a sequence like this

'START_B b TO_A a TO_B xf1 1 2 3 4 b STOP' (12)

can occur and it is not improved by the current scheme

effectively we seem to ignore the start character entirely.

This should be reduced to

'START_B b TO_A a TO_C xf1 12 34 TO_B b STOP' (11)

I propose one more complication to try and capture this; we add to savings if we 
start the C sequence right after a start and then combine the start and TO_C if 
that condition works.


my new test program looks like this

#######################################################
from string import digits
starts = ['START_B','TO_A','TO_B']
def _trailingDigitsToC(self, l):
     # Optimization: trailing digits -> set C double-digits

     i = 0
     nl = []
     while i < len(l):
         startpos = i
         rl = []
         savings = -1 # the TO_C costs one character
         while i < len(l):
             if l[i] in starts:
                 j = i
                 break
             elif l[i] == '\xf1':
                 rl.append(l[i])
                 i += 1
                 continue
             elif len(l[i]) == 1 and l[i] in digits \
              and len(l[i+1]) == 1 and l[i+1] in digits:
                 rl.append(l[i] + l[i+1])
                 i += 2
                 savings += 1
                 continue
             else:
                 break

         ta = not (l[i]=='STOP' or j==i)
         xs = savings>=0 and (startpos and nl[-1] in starts)
         if savings+int(xs) > int(ta):
             if xs:
                 toc = nl[-1][:-1]+'C'
                 del nl[-1]
             else:
                 toc = 'TO_C'
             nl += [toc]+rl
             if ta:
                 nl.append('TO'+l[j][-2:])
             nl.append(l[i])
         else:
             nl += l[startpos:i+1]
         i += 1
     return nl

for x,l in enumerate((
         'START_B b b b b 1 2 3 4 5 6 b b b STOP',
         'START_B b b b b 1 2 3 4 5 b b b STOP',
         'START_B b b b b 1 2 3 4 b b b STOP',
         'START_B b b b b 1 2 3 b b b STOP',
         'START_B b b b b 1 2 b b b STOP',
         'START_B b b b b 1 b b b STOP',
         'START_B b b b b 1 2 3 4 5 6 TO_A a a STOP',
         'START_B b b b b 1 2 3 4 TO_A a a STOP',
         'START_B b b b b 1 2 3 TO_A a a STOP',
         'START_B b b b b 1 2 TO_A a a STOP',
         'START_B b b b b 1 TO_A a a STOP',
         'START_B b b b b 1 2 3 4 5 6 STOP',
         'START_B b b b b 1 2 3 4 5 STOP',
         'START_B b b b b 1 2 3 4 STOP',
         'START_B b b b b 1 2 3 STOP',
         'START_B b b b b 1 2 STOP',
         'START_B b b b b 1 STOP',
         'START_B \xf1 1 2 3 4 b STOP',
         'START_B b TO_A a TO_B \xf1 1 2 3 4 b STOP',
         'START_B b TO_A a TO_B 1 2 STOP',
         'START_B b TO_A a TO_B 1 2 3 b STOP',
         'START_B b TO_A a TO_B 1 2 3 4 b STOP',
         )):
     l = l.split()
     lo = _trailingDigitsToC(None, l)
     print '%2d: %s(%d) --> %s(%d)' % (x,' '.join(l),len(l),' '.join(lo),len(lo))
#######################################################

On 05/01/2016 00:13, Klaas Feenstra wrote:
> Robin, I made a little modification and I think this is now working
> correctly.
>
> def _trailingDigitsToC(self, l):
>          # Optimization: trailing digits -> set C double-digits
>
>          i = 0
>          nl = []
>          while i < len(l):
>                  startpos = i
>                  rl = []
>                  savings = -1 # the TO_C costs one character
>                  while i < len(l):
>                          if l[i] in (['START_B','TO_A','TO_B']):
>                                  j = i
>                                  break
>                          elif l[i] == '\xf1':
>                                  rl.append(l[i])
>                                  i += 1
>                                  continue
>                          elif len(l[i]) == 1 and l[i] in digits \
>                           and len(l[i+1]) == 1 and l[i+1] in digits:
>                                  rl.append(l[i] + l[i+1])
>                                  i += 2
>                                  savings += 1
>                                  continue
>                          else:
>                                  break
>
>                  ta = not (l[i]=='STOP' or j==i)
>                  if savings > int(ta) or savings > (startpos-1): #In case of
> starting with C
>                          nl += ['TO_C']+rl
>                          if ta:
>                                  nl.append('TO'+l[j][-2:])
>                          nl.append(l[i])
>                  else:
>                          nl += l[startpos:i+1]
>                  i += 1
>          return nl
>
> On Tue, Jan 5, 2016 at 12:21 AM, Klaas Feenstra <klaas at feenstra.es> wrote:
>
>> Hi Robin,
>>
>> Yes, your code is working better, but is also not correct. Try the next:
>> 'START_B xf1 1 2 3 4 b STOP' (8)
>> should be
>> 'START_B TO_C xf1 12 34 TO_B b STOP' (8), but in the function encode
>>
>>          # Finally, replace START_X,TO_Y with START_Y
>>          if l[1] in tos:
>>              l[:2] = ['START_' + l[1][-1]]
>>
>> this will be transformed to
>> 'START_C xf1 12 34 TO_B b STOP' (7)
.........

-- 
Robin Becker


More information about the reportlab-users mailing list