Problem with wrapping GNU Units

TheSeeker duane.kaufman at gmail.com
Mon Apr 3 00:01:50 EDT 2006


Hi,
As part of a larger project, I am trying to use the GNU Units program
to provide unit conversions between quantities.

My first iteration, which worked OK, was to simply use units as a
command-line app, and capture its output. The larger program however,
calls the conversion routine many times, and the overhead of starting
units for every call made things too slow.

I then re-formulated my use of units to open it using popen2, and do
conversions with it through stdin and stdout (Windows XP). This too
works OK, at least up to the point I want to stop the program, which is
where I am having problems.

If I simply try to exit my app, python.exe hangs, and units.exe keeps
running, according to the Task Manager. If I try sending Control-D, as
the on-line help suggests, the program hangs too.

Does anyone have any ideas on how to control this app?

Here is some of my code:

# Functions for driving GNU Units (if installed)
GNU_Units_stdin = None
GNU_Units_stdout = None

def SetupGNU_Units():
    import time, os, sys
    # Initialization routine to set up pipe to running GNU Units
process
    # Start GNU Units as a child and feed and read through stdin and
stdout
    global GNU_Units_stdin, GNU_Units_stdout
    CurrentDir = os.getcwd()
    # Hack to find correct directory
    if not 'units.exe' in os.listdir(os.getcwd()):
        UnitsDir = os.path.join(CurrentDir, 'GNU_Units')
    else:
        UnitsDir = CurrentDir
    print "CurrentDir ", CurrentDir
    os.chdir(UnitsDir)
    (GNU_Units_stdin, GNU_Units_stdout) = os.popen2('units.exe -f
.\units.dat')
    time.sleep(0.5)
    print 'First initialization read: ', GNU_Units_stdout.readline()
    time.sleep(0.5)
    print 'Second initialization read: ', GNU_Units_stdout.readline()
    time.sleep(0.5)
    print 'Units initialization complete.'

def ShutdownGNU_Units():
    global GNU_Units_stdin, GNU_Units_stdout
    # From the GNU Units help, to quit the program from the interactive
prompt
    #    (which is how we are using it), one needs to feed it Control-D
    GNU_Units_stdin.write(chr(4))
    # ResponseLine1 = GNU_Units_stdout.readline()
    GNU_Units_stdin = None
    GNU_Units_stdout = None

def ConvertUnits(Value, FromUnitStr, ToUnitStr):
    import os, sys
    global GNU_Units_stdin, GNU_Units_stdout
    # Sanity check on the numerical portion of the input
    try:
        dummy=float(Value)
    except ValueError:
        raise ConvertUnitsError('ConvertUnits: non-numeric input')
        return 0
    if not GNU_Units_stdin:
        # Initialize pipes to GNU Units
        SetupGNU_Units()
    FromStr = str(Value)
    FromStr += ' ' + FromUnitStr + '\r'
    ToStr = ToUnitStr + '\r'
    GNU_Units_stdin.write(FromStr)
    GNU_Units_stdin.write(ToStr)
    ResponseLine1 = GNU_Units_stdout.readline()
    ResponseLine2 = GNU_Units_stdout.readline()
    ReadBackLine = GNU_Units_stdout.readline()
    ReadBackLine2 = GNU_Units_stdout.readline()
    if 'conformability error' == ReadBackLine.strip():
        raise ConvertUnitsError('ConvertUnits: conformability error')
    AnswerElement = ReadBackLine.strip()
    return float(AnswerElement.split()[1])

Thanks in advance,
Duane




More information about the Python-list mailing list