Beginner String formatting question

John Machin sjmachin at lexicon.net
Sat Jan 26 20:17:22 EST 2008


On Jan 27, 7:15 am, JAMoor... at gmail.com wrote:
> I apologize for the lack of details in my last post.

There is nothing to apologise for. Unlike some, you gave enough
information, without prompting, to get answers to your questions.
Don't go to the other extreme :-)

>  This time
> formatting program is a piece of a larger program I am trying to write
> to de-clutter GPS transmission.  I have a GPS receiver that transmits
> its readings via bluetooth.  I've been able to use pySerial and store
> X number of bytes, then write that to a file (the next step will be
> finding a way to write the stream to a file directly).  The raw GPS
> data is tranmitted in the NMEA format (http://vancouver-webpages.com/
> peter/nmeafaq.txt):
>
> $GPRMC,024830,V,,N,,E,,,260108,,,N*58
> $GPVTG,,T,,M,,N,,K,N*2C
> $GPGGA,024831,LAT_GOES_HERE,N,LONG_GOES_HERE,E,0,00,,,M,,M,,*61
> $GPGSA,A,1,,,,,,,,,,,,,,,*1E
> $GPGSV,3,1,09,09,,,37,13,,,00,18,,,00,23,,,00*75
> $GPGSV,3,2,09,01,,,00,29,,,00,14,,,00,26,,,00*7A
> $GPGSV,3,3,09,12,,,00,,,,,,,,,,,,*73
> $GPRMC,024831,V,LAT_GOES_HERE,N,LONG_GOES_HERE,E,,,260108,,,N*59
> $GPVTG,,T,,M,,N,,K,N*2C
>
> the "$GPGGA" and "$GPRMC" lines are the ones that will give you your
> Latitude and Longitude data --or the would if I had a signal.
> All the entries are comma delimited, so I used the split(',') function
> to parse the appropriate statements.  Here's the code for that:
> =============================
> input = open('c:\sample_readout.txt','r')   #location of the Raw GPS
> data
> output = open('c:\GPSout.txt', 'w')

Presumably you are running MS-DOS 2.0 or later, so you have a
hierarchical file system. Don't put files in your root directory!!!

Don't use single backslashes in Windows file names -- e.g. in 'foo
\noddy' the \n will be interpreted as a newline. Use one of the
following methods:
'c:\\GPS\\test1.txt'
r'c:\GPS\test1.txt'
'c:/GPS/test1.txt'

It's not really a good habit to have constant paths in your scripts
anyway, especially for output files.

>
> output.write("Timestamp \t Latitude \t Longitude \t Velocity")
>
> s = input.readlines()
>
> for line in s:

Instead of the above two lines, do this:
    for line in input:

>
>   if line.startswith('$GPGGA'):
>     InputTuple = line.split(',')

Try choosing meaningful names. It's not a tuple, it's a list.

And read this:
http://www.python.org/dev/peps/pep-0008/

>
>     time = InputTuple[1]
>     lat  = InputTuple[2]+' '+InputTuple[3]
>     long = InputTuple[4]+' '+InputTuple[5]
>
>     out = '\n '+ time + '\t\t' + lat + '\t\t\t' + long
>
>     output.writelines(out)
>
>   elif line.startswith('$GPRMC'):
>     InputTuple = line.split(',')

You should write the code to parse the input format *once* and parse
it *correctly* -- at the moment the last field will contain
'data*checksum\n' instead of just 'data'.

Following is an example of one style of input parsing:

C:\junk>type nmea.py

sample = """
$GPRMC,024830,V,,N,,E,,,260108,,,N*58
$GPVTG,,T,,M,,N,,K,N*2C
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,09,09,,,37,13,,,00,18,,,00,23,,,00*75
$GPGSV,3,2,09,01,,,00,29,,,00,14,,,00,26,,,00*7A
$GPGSV,3,3,09,12,,,00,,,,,,,,,,,,*73
$GPVTG,,T,,M,,N,,K,N*2C
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
"""

def unpack_nmea_message(line):
    line = line.rstrip() # remove any newline etc
    if not line:
        return [] # empty line
    if line[0] != '$':
        raise Exception('NMEA line %r: should start with $' % line)
    try:
        apos = line.rindex('*')
    except ValueError:
        raise Exception('NMEA line %r: missing checksum?' % line)
    try:
        cksum = int(line[apos+1:], 16)
    except ValueError:
        raise Exception('NMEA line %r: checksum not hex' % line)
    if not(0 <= cksum <= 255):
        raise Exception(
            'NMEA line %r: checksum not in range 0-255 inclusive'
            % line)
    calc_cksum = 0
    data = line[1:apos]
    for c in data:
        calc_cksum = calc_cksum ^ ord(c)
    if calc_cksum != cksum:
        print calc_cksum, cksum, repr(chr(calc_cksum ^ cksum))
        raise Exception('NMEA line %r: invalid checksum' % line)
    fields = data.split(',')
    # maybe check for minimum number of fields
    return fields

if __name__ == '__main__':
    for x, line in enumerate(sample.splitlines()):
        print 'Line %3d: %r' % (x+1, line)
        print '        : %r'% unpack_nmea_message(line)

C:\junk>nmea.py
Line   1: ''
        : []
Line   2: '$GPRMC,024830,V,,N,,E,,,260108,,,N*58'
        : ['GPRMC', '024830', 'V', '', 'N', '', 'E', '', '', '260108',
'', '', 'N']
Line   3: '$GPVTG,,T,,M,,N,,K,N*2C'
        : ['GPVTG', '', 'T', '', 'M', '', 'N', '', 'K', 'N']
Line   4: '$GPGSA,A,1,,,,,,,,,,,,,,,*1E'
        : ['GPGSA', 'A', '1', '', '', '', '', '', '', '', '', '', '',
'', '', '', '', '']
Line   5: '$GPGSV,3,1,09,09,,,37,13,,,00,18,,,00,23,,,00*75'
        : ['GPGSV', '3', '1', '09', '09', '', '', '37', '13', '', '',
'00', '18', '', '', '00', '23', '', '', '00']
Line   6: '$GPGSV,3,2,09,01,,,00,29,,,00,14,,,00,26,,,00*7A'
        : ['GPGSV', '3', '2', '09', '01', '', '', '00', '29', '', '',
'00', '14', '', '', '00', '26', '', '', '00']
Line   7: '$GPGSV,3,3,09,12,,,00,,,,,,,,,,,,*73'
        : ['GPGSV', '3', '3', '09', '12', '', '', '00', '', '', '',
'', '', '','', '', '', '', '', '']
Line   8: '$GPVTG,,T,,M,,N,,K,N*2C'
        : ['GPVTG', '', 'T', '', 'M', '', 'N', '', 'K', 'N']
Line   9: '$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,
46.9,M,,*47'
        : ['GPGGA', '123519', '4807.038', 'N', '01131.000', 'E', '1',
'08', '0.9', '545.4', 'M', '46.9', 'M', '', '']

C:\junk>

HTH,
John



More information about the Python-list mailing list