[Tutor] Looking at a String as a Struct?
Marc Tompkins
marc.tompkins at gmail.com
Thu Sep 11 17:39:03 CEST 2008
On Thu, Sep 11, 2008 at 3:58 AM, Wayne Watson
<sierra_mtnview at sbcglobal.net>wrote:
> Is it possible in Python to look at a string as a "struct". I don't think
> a struct exists in python. Actually, is there something analogous to a
> record. In the case of strings, suppose I have string that is composed of
> sub-strings like, first_name, last-name, date_of birth, which consists of
> month, day, and year, and finally SSN, street_address, state, city, and
> zip_code. I'd like to access these fields directly instead of lastname =
> record[38:55]. What if fields are not just strings, but some numeric values?
>
>
I had to do a similar thing in my first real Python program (actually, I
ended up making it into a library of modules that I reuse over and over.) I
do a lot of work with a legacy cTree database application - fixed-length
data records, C strings, lots of stuff stored as packed decimal, etc. The
database is normalized into 45 files, each with its own record length and
layout. I wrote 45 separate classes; here's "Patient".
Note: this is OLD code, and I haven't revisited it to optimize. If I ever
find the time, I'll rework these into generators - as it stands, opening
each file and reading records from it and loading the resulting objects into
a list or dictionary (or SQL database) is left to the calling program.
Remember, this was a beginner effort. (But the programs that use this are
still going strong...)
You'll notice that I call, and use, "struct" - it doesn't do quite what you
think it does, I think... I believe that the entire class is closer to what
you meant by "struct".
import struct
from utils import B2int, BBBB2date, BBBB2ssn, BBBB2zip, raw2phone
# some utility functions - convert a single byte to integer, 4 bytes BCD to
a date,
# 4 bytes BCD to a Social Security number, 4 bytes BCD to a Zip code,
# format a 10-digit number into "(999) 999-9999"
class Patient(object):
RecordLength = 1024
TLA = "pat"
ID = ""
def __init__(self, rec=False):
"""Extract fields from patient records"""
self.Valid = False
if rec:
if not (rec[5] == "\x00"): # skip deleted and invalid records
self.Valid = True
self.ChartNumber =
rec[5:16].split("\x00")[0].rstrip() # these are C strings,
self.LastName = "" +
rec[16:31].split("\x00")[0].rstrip() # therefore null-terminated -
self.FirstName = "" +
rec[32:44].split("\x00")[0].rstrip() # but also might
self.MI = "" + rec[45]
self.AccountNumber =
rec[16:31].split("\x00")[0].rstrip() # contain spaces
self.Address1 =
rec[982:1010].split("\x00")[0].rstrip()
self.Street =
rec[72:100].split("\x00")[0].rstrip()
self.City =
rec[101:116].split("\x00")[0].rstrip()
self.State =
rec[117:119].split("\x00")[0].rstrip()
self.Zip = BBBB2zip(rec[120:124])
self.HomePhone =
raw2phone(rec[124:134].split("\x00")[0])
self.DrivLicNum =
rec[135:147].split("\x00")[0].rstrip()
self.SSN = BBBB2ssn(rec[148:152])
self.Birthdate = BBBB2date(rec[152:156])
self.Sex = rec[156].split("\x00")[0]
self.EmergContact =
rec[157:187].split("\x00")[0].rstrip()
self.EmergPhone =
raw2phone(rec[188:198].split("\x00")[0])
self.EmergRelCode =
rec[199:205].split("\x00")[0].rstrip()
self.Message1 =
rec[206:238].split("\x00")[0].rstrip()
self.Message2 =
rec[239:271].split("\x00")[0].rstrip()
self.NrstRelName =
rec[272:302].split("\x00")[0].rstrip()
self.NrstRelStreet =
rec[303:331].split("\x00")[0].rstrip()
self.NrstRelCity =
rec[332:347].split("\x00")[0].rstrip()
self.NrstRelState =
rec[348:350].split("\x00")[0].rstrip()
self.NrstRelZip = BBBB2zip(rec[351:355])
self.NrstRelPhone =
raw2phone(rec[355:365].split("\x00")[0])
self.NrstRelRelCode =
rec[366:372].split("\x00")[0].rstrip()
self.EmpRefSrcCode = struct.unpack('B',rec[979])[0]
self.EmpName =
rec[373:403].split("\x00")[0].rstrip()
self.EmpContact =
rec[947:975].split("\x00")[0].rstrip()
self.EmpStreet =
rec[404:432].split("\x00")[0].rstrip()
self.EmpCity =
rec[433:448].split("\x00")[0].rstrip()
self.EmpState =
rec[455:457].split("\x00")[0].rstrip()
self.EmpZip = BBBB2zip(rec[458:462])
self.EmpPhone =
raw2phone(rec[462:472].split("\x00")[0])
self.EmpPhone2 =
raw2phone(rec[473:483].split("\x00")[0])
self.EmpPhone2Ext =
rec[484:488].split("\x00")[0].rstrip()
self.Doctor =
rec[489:491].split("\x00")[0].rstrip()
self.MessageCode =
rec[492:495].split("\x00")[0].rstrip()
self.RecallCycle =
rec[496:500].split("\x00")[0].rstrip()
self.Ailment = B2int(rec[501])
self.Operator =
rec[503:506].split("\x00")[0].rstrip()
self.EntryDate = BBBB2date(rec[507:511])
self.ChampSpnsrGrade =
rec[515:517].split("\x00")[0].rstrip()
self.ChampBranchOfSvc = rec[518].split("\x00")[0]
self.ChampDutyStatus = struct.unpack('B',rec[520])[0]
self.Facility =
rec[528:531].split("\x00")[0].rstrip()
self.Pharmacy =
rec[570:573].split("\x00")[0].rstrip()
self.Diagnosis1 =
rec[574:580].split("\x00")[0].rstrip()
self.Diagnosis2 =
rec[581:587].split("\x00")[0].rstrip()
self.Diagnosis3 =
rec[588:594].split("\x00")[0].rstrip()
self.Diagnosis4 =
rec[595:601].split("\x00")[0].rstrip()
self.ReferredBy =
rec[602:606].split("\x00")[0].rstrip()
self.OtherRef1 =
rec[607:611].split("\x00")[0].rstrip()
self.OtherRef2 =
rec[612:616].split("\x00")[0].rstrip()
self.OtherRef3 =
rec[617:621].split("\x00")[0].rstrip()
self.InsuranceType =
rec[622:624].split("\x00")[0].rstrip()
self.FinancialCategory =
rec[625:627].split("\x00")[0].rstrip()
self.MaritalStatus = rec[628].split("\x00")[0]
self.StatementCode = rec[629].split("\x00")[0]
self.BillingCycle = rec[630].split("\x00")[0]
self.AssignmentYN = rec[631].split("\x00")[0]
self.FinanceChargeYN = rec[632].split("\x00")[0]
self.PriInsDeductible = struct.unpack('i',rec[633:637])[0]
self.PriInsCopay =
rec[637:643].split("\x00")[0].rstrip()
self.PriInsCompany =
rec[644:650].split("\x00")[0].rstrip()
self.SecInsCompany =
rec[651:657].split("\x00")[0].rstrip()
self.TerInsCompany =
rec[658:654].split("\x00")[0].rstrip()
self.PriInsuredID =
rec[665:685].split("\x00")[0].rstrip()
self.SecInsuredID =
rec[686:706].split("\x00")[0].rstrip()
self.TerInsuredID =
rec[707:727].split("\x00")[0].rstrip()
self.PriInsPlanName =
rec[728:748].split("\x00")[0].rstrip()
self.SecInsPlanName =
rec[749:769].split("\x00")[0].rstrip()
self.TerInsPlanName =
rec[770:790].split("\x00")[0].rstrip()
self.PriInsPolicy =
rec[791:806].split("\x00")[0].rstrip()
self.SecInsPolicy =
rec[807:822].split("\x00")[0].rstrip()
self.TerInsPolicy =
rec[823:838].split("\x00")[0].rstrip()
self.PriInsuredRel = rec[932].split("\x00")[0]
self.SecInsuredRel = rec[933].split("\x00")[0]
self.TerInsuredRel = rec[934].split("\x00")[0]
self.PmtAuthType = rec[935].split("\x00")[0].rstrip()
--
www.fsrtechnologies.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20080911/25d1a85b/attachment-0001.htm>
More information about the Tutor
mailing list