Re: Barcode Vocalization Application

From: Alan Dechert <adechert_at_earthlink_dot_net>
Date: Mon Oct 06 2003 - 12:33:16 CDT

Skip,

> Further to that point, if written in Python, others (like myself) who were
> solicited in comp.lang.python could assist. I have little enough time as
it
> is (witness the lack of progress on the website - I'm still offline except
> for time spent at my day job). ....
>
I understand. I (we) appreciate wherever and whenever you can contribute to
finishing a piece of the project.

> I'm not going to spend time learning the
> dBase scripting language or locating and installing tools to use it.
>
Nor should anyone expect you to or ask you to do so. David has expertise in
xBase. I worked on the dBASE product at Borland (my name is on the credits
list of the dBASE 5.0 product I used for the bva app).

I am anxious to get the demo done. My choices for this component looked
like this:

1) Spend another two months trying to get someone else to do it (probably in
Python).
2) Spend one afternoon and do it myself in dBASE.
3) Spend several days figuring out how to do it in Python, and do it myself.

I hope you will forgive me for choosing the most expeditious route. I admit
that a real programmer in my position would have chosen option (3).
Nonetheless, I may need to consider that more carefully. Jan didn't know
Python but he jumped in there and learned it enough to do the PrintBallot
function (3 cheers for Jan!). I'm not looking for a career as a Python
programmer at this point. In fact, I'm not looking for a career as any kind
of programmer. But, maybe it wouldn't hurt to learn some both as a career
fallback and to help get the demo done more directly.

> (Maybe there's someone who knows both who can translate?)
>
David discussed this some. Here are a few more clues:

Jan did the revert function in Python like so:

def revert(key, num):
    keydigits = list(key)
    numdigits = list(num)
    for i in range(len(numdigits)):
        numdigits[i] = str((int(numdigits[i]) - int(keydigits[i % 4])) % 10)
    return string.join(numdigits, "")

here's the revert function I did in dBASE
********************
function revert
********************
parameters key, num

declare keydigits[4]
declare numdigits[len(num)]
for i = 1 to 4
   keydigits[i] = substr(key,i,1)
next
for i = 1 to len(num)
   numdigits[i] = substr(num,i,1)
next
for i = 1 to len(num)
   numdigits[i] = str(mod(val(numdigits[i]) -
val(keydigits[iif(mod(i,4)=0,4,mod(i,4))]),10),1)
next
retval = ""
for i = 1 to len(num)
   retval = retval + numdigits[i]
next
return retval

So I guess the list() function in Python makes an array out of the
characters in the "key" variable. In dBASE, I had to declare the array. I
guess the percent sign is like the mod function in dBASE although I don't
quite understand it. dBASE can't handle a zero subscript so I had to work
around that. According to what David said in a previous previous post,
Python doesn't have iif (called immediate if) -- this is a compact form of
if-then-else.

Beyond that, the bva application is trivial. Except for the code I wrote to
work with the long integer (which you don't have to worry about in Python)
and the revert function (which Jan already did), there less than 70 lines of
code left (I condensed it some since I posted it on SourceForge).

I've copied the dBASE code below. I made it shorter by using 2-dimensional
arrays. I assume Python has such a thing? So the first line here defines
an array with 11 rows and 4 columns (actually I just noticed something
stupid: I made an array 8x5 for the county commissioner race but never used
the 5th column).

the StringOfSelections variable is a 116 digit long string of zeros and ones
where it's all zeros except for the ones which represent items on the ballot
that were selected by the voter. This long binary number is obtained by
converting the decimal number you get from the ballot that Jan's function
prints (input scanned from the barcode).

The program needs to do basically one thing: create a list of wav files
corresponding to the votes.

To accomplish this, two things must be done:

1) Locate the position of the "1"s in the StringOfSelections (if you find a
"1" in the 33rd position, then you include sel033.wav in the list).

2) For each race, determine if there were no selections made. If no
selections made, for example in the 4th contest, include np04.wav in the
list.

Then all we have to do is issue a command to a wav file player to play the
list. As published, it just runs a player called wav.exe. But I have
already changed that to accept any variety of players and have it working
well with Windows Media Player (7.1). It could work just as well with the
media player in OS/2. There is no need to get it working with many wav file
players since this is just for the demo. Acually, it will probably only be
used with one OS for the demo. We may need more flexibility built in to the
production system -- not something we need to worry about right now.

On the slowest machine I have (200 mhz Pentium), it takes about two-tenths
of one second from the time the data is entered (barcode scanned) to where
the list is written out -- this includes the long integer work-around. So
there is no conceivable performance advantage to using some other language.
There may be some other advantage of using Python, but bascally bva is done.
I'd prefer to use the time on another component rather than re-doing this
one. The only way re-doing bva would be productive, imo, is that if I
re-wrote it myself in Python, I'd be better able to help with other
components -- especially the blind-accessible ballot application.

** first eleven contests
declare first11[11,4]
nwavs = 0
positiondata = "018 098 173 203 234 273 304 343 372 392 412"

for n = 1 to 11
   first11[n,2] = val(substr(positiondata, n * 4 - 3,2))
   first11[n,3] = val(substr(positiondata, n * 4 - 1,1))
   first11[n,1] = at("1",
substr(stringofselections,first11[n,2],first11[n,3]))
   if first11[n,1] = 0
      first11[n,4] = "np" + iif(n < 10, "0" + str(n,1),str(n,2)) + ".wav"
   else
      if first11[n,1] + first11[n,2] < 11
         first11[n,4] = "sel00" + str(first11[n,1] + first11[n,2]-1,1) +
".wav"
      else
         first11[n,4] = "sel0" + str(first11[n,1] + first11[n,2]-1,2) +
".wav"
      endif
   endif
   nwavs = nwavs + 1
   wavs[n] = first11[n,4]
next

** twelveth contest
if "1" $ substr(StringOfSelections,43,10)
   char = rtrim(ltrim(str(at("1", substr(stringofselections,43,10))+42,2)))
   char = "0" + char
   wavs[12] = "sel&char" + ".wav"
   nwavs = nwavs + 1
   cat2 = at("1", substr(stringofselections,43,10),2)
   if cat2 > 0
      char = "0" + rtrim(ltrim(str(cat2 + 42)))
      wavs[13] = "sel&char" + ".wav"
      nwavs = nwavs + 1
      cat3 = at("1", substr(stringofselections,43,10),3)
      if cat3 > 0
         char = "0" + rtrim(ltrim(str(cat3 + 42)))
         wavs[14] = "sel&char" + ".wav"
         nwavs = nwavs + 1
      endif
   endif
else
   wavs[12] = "np12.wav"
   nwavs = nwavs + 1
endif
checkno = nwavs

** thirteenth contest
declare commiss[8,5]
for n = 1 to 8
   commiss[n,2] = 45 + (8 * n)
   commiss[n,3] = 52 + (8 * n)
   commiss[n,1] = at("1", substr(stringofselections,commiss[n,2],8))
   if commiss[n,1] = 0
      commiss[n,4] = " "
   else
      if commiss[n,1] + commiss[n,2] < 101
         commiss[n,4] = "sel0" + str(commiss[n,1] + commiss[n,2]-1,2) +
".wav"
      else
         commiss[n,4] = "sel" + str(commiss[n,1] + commiss[n,2]-1,3) +
".wav"
      endif
      nwavs = nwavs + 1
      wavs[nwavs] = commiss[n,4]
   endif
next
** if nwavs not incremented, then no selections were made so include
npxx.wav
if nwavs = checkno
   nwavs = nwavs + 1
   wavs[nwavs] = "np" + str(13,2) + ".wav"
endif

==================================================================
= The content of this message, with the exception of any external
= quotations under fair use, are released to the Public Domain
==================================================================
Received on Fri Oct 31 23:17:01 2003

This archive was generated by hypermail 2.1.8 : Fri Oct 31 2003 - 23:17:06 CST