[Tutor] creating variable names from string slices

Bruce Dykes Bruce Dykes" <bkd@graphnet.com
Wed Apr 2 08:36:02 2003


----- Original Message -----
From: "Jeff Shannon" <jeff@ccvcorp.com>
To: <tutor@python.org>
Cc: "noc" <bkd@graphnet.com>
Sent: Tuesday, April 01, 2003 13:24
Subject: Re: [Tutor] creating variable names from string slices


> noc wrote:
>
> >I'm telnetting to a mainframe, and capturing a screendump of data that's
> >neatly column formatted:
> >
> >[...]
> >What I want to do is define a function that gets passed each line, and
> >returns a dictionary with the first element  as the name, and the
subsequent
> >elements as the key:value pairs:
> >
>
> Something like this, perhaps?
>
> First, we get the imported data into a list of lines:

ayup...I'm using:

records=string.split(telnet.readuntil(prompt),'\n')

but I'll also need to do read from a file....


> Now, we write a function that deals with a single line.  Since we know
> the structure of the line, we can take advantage of that fact.
>
>  >>> def processline(line):
> ...     fields = ['haircolor', 'role']
> ...     line = line.split()
> ...     fielddata = zip(fields, line[1:])
> ...     return line[0], dict(fielddata)
> ...
>  >>>

As I said, I need to slice data from the string, since it's columnar, but we
can get around that simply enough:

  >>> def processline(line):
 ...     fields = ['haircolor', 'role']
 ...     name = line.split()[0]
 ...     line = [line[5:10],line[15:20]]
 ...     fielddata = zip(fields, line)
 ...     return name, dict(fielddata)
 ...
  >>>

yes?

> This function returns a tuple of a name (the first column of input) and
> a dictionary that's constructed from the second and subsequent columns,
> along with the column names.  (If we wanted to get fancy, we might build
> the list of fields from the first line of our input, reading column
> headers, but for now I'm just using a statically defined list of fields.)
>
> Now all we have to do is run each line through this function, and store
> the results.
>
>  >>> data = {}
>  >>> for line in lines:
> ...     name, info = processline(line)
> ...     data[name] = info
> ...

But we can combine this with above for:

  >>> def processline(line):
 ...     fields = ['haircolor', 'role']
 ...     name = line.split()[0]
 ...     line = [line[5:10],line[15:20]]
 ...     fielddata = zip(fields, line)
 ...     record = {}
 ...     record[name] = fielddata
 ...     return record
 ...
  >>>

And that should return our dictionary:
{'Betty': {'haircolor': 'Blond', 'role': 'Stude'}},

yes?

> Depending on how you're using this data, it might also be practical to
> define a class, and make each line into an instance of that class, with
> attributes named 'haircolor' and 'role'.

Well, let's not get too crazy here! <g>

I don't think I really need anything as elaborate creating a class from it.
I'm looking at 9 fields, to which I'll be adding date,  time, and an
ancillary field, for a few hundred records. Times four. But that's just for
the current snapshot of data.

The script will be running every 15 minutes, and I'll be keeping and loading
a file that holds 90 minutes worth of snapshots, which means 6 datasets.

Hmmm. That's rather a lot.

I'll be comparing one field of each record in the current snapshot, with the
same field in the most recent snapshot, and then performing some action
based on if the field changes.

The file of stored data

So the question is, when do you decide to make a class, and when do you
stick with Python's native dictionary tools?

> Note the use of '*line.split()' to feed arguments to Girl.  This has the
> effect of passing each element of the list returned by line.split() as
> an individual parameter, rather than as an aggregated list.  Now we can
> process each line, and do whatever with the resulting objects.

>  >>> data = {}
>  >>> for line in lines:
> ...     name, info = processline(line)
> ...     data[name] = info
> ...
>  >>> pprint.pprint(data)
> {'Betty': <__main__.Girl instance at 0x01608918>,
>  'Ginger': <__main__.Girl instance at 0x0162D710>,
>  'Maryann': <__main__.Girl instance at 0x01622690>,
>  'Veronica': <__main__.Girl instance at 0x015EF3C8>}
>  >>> for item in data.values():
> ...     print item.name, item.role
> ...
> Veronica Student
> Betty Student
> Ginger Castaway
> Maryann Castaway
>  >>>

And the answer is, when we need the additional abstraction of handling
objects and flexible access to attributes is necessary?

Bruce