[Tutor] Import tabular data file and assign to variables

RenderPipe renderpipe at speedpost.net
Thu Sep 16 22:30:53 CEST 2004


Thanks for the help and explanation. I have been avoiding classes but I
think this is a good time to give it a try.



On Thu, 16 Sep 2004 11:16:34 -0700, "Jeff Shannon" <jeff at ccvcorp.com>
said:
> RenderPipe wrote:
> 
> > I was thinking of creating a dictionary object for each frame but I do
> > not know how to extract the data in the colums and assing them to a
> > dictionary.
> 
> That sounds like a pretty good plan.  If you want to get slightly more 
> advanced, you could write a small class and then create an instance of 
> that class for each line.  The big advantage here is that you can 
> encapsulate a lot of the code to process each line into the class, and 
> you can later add methods that do interesting things with your data. 
> But for a simple approach, dictionaries (or even tuples) will work well.
> 
> > Here's what i have come up with so far:
> > 
> > import string
> 
> You're not actually using the string module here, so you can skip the 
> import.
> 
> > myfile = open("MyFile")
> > data = myfile.readlines()
> > for line in data:
> >         rs  = line.split("\t")
> >         print rs
> 
> If you call split() with no arguments, then it will default to 
> splitting on all whitespace.  If there's multiple whitespace 
> characters together, this default mode will treat them as one.  So, 
> for example, when I do this on one of your sample lines, I get this:
> 
>  >>> x
> '    -31.5227      7.7864    -74.4018     -2.4335     -8.7991\r\n'
>  >>> x.split()
> ['-31.5227', '7.7864', '-74.4018', '-2.4335', '-8.7991']
>  >>>
> 
> Note that this has also eliminated the extra \r\n characters at the 
> end.  However, there's a slight catch here -- these are still strings, 
> not floating-point numbers.  You'll need to convert them, which we can 
> do to the whole list easily with a list comprehension:
> 
>  >>> x
> '    -31.5227      7.7864    -74.4018     -2.4335     -8.7991\r\n'
>  >>> rs = [float(num) for num in x.split()]
>  >>> rs
> [-31.5227, 7.7864000000000004, -74.401799999999994, -2.4335, 
> -8.7990999999999993]
>  >>>
> 
> (The numbers aren't displaying exactly, because there's tiny 
> representation errors when switching between decimal fractions and 
> binary fractions.  It's normal, and shouldn't be a problem unless you 
> need *very* exact precision.)
> 
> With that, you should be able to put your data into a dictionary or a 
> class pretty easily.  Just as an example of how convenient using a 
> class can be, look at this:
> 
>  >>> class Pos3D:
> ...     def __init__(self, transx, transy, transz, rotx, roty):
> ...             self.transx = transx
> ...             self.transy = transy
> ...             self.transz = transz
> ...             self.rotx = rotx
> ...             self.roty = roty
> ...             
>  >>> instance = Pos3D(*rs)
>  >>> instance
> <__main__.Pos3D instance at 0x02C9EA00>
>  >>> instance.transx, instance.transy, instance.transz
> (-31.5227, 7.7864000000000004, -74.401799999999994)
>  >>> instance.rotx, instance.roty
> (-2.4335, -8.7990999999999993)
>  >>>
> 
> Because the Pos3D class knows what order to expect data in, I can 
> simply tell Python to expand the list of data into a normal argument 
> list for __init__() -- that's what the * in Pos3D(*rs) means.  Now I 
> can conveniently refer to all of this data with simple dotted-name 
> syntax.  I could also easily write methods like gettrans(), which 
> would return (transx, transy, transz), and getrot(), which would 
> return (rotx, roty), making further work with the data that much simpler.
> 
> Hope that this helps.
> 
> Jeff Shannon
> Technician/Programmer
> Credit International
> 
> 


More information about the Tutor mailing list