more newbie list questions

G

googleboy

Hi there.

I am doing a bunch of processing over a list of lists, and am
interested in doing several things taht don't seem to be working for me
just at the moment.

I have a list of books with several fields (Title, Author1, Author2,
Publisher, ISBN) in a csv.

I have a cell.txt file that looks like this:

++
The title is %title%. <br><br>
The author is %author1% %author2% <br><br>
The Publisher is %publisher1% %publisher2% <br><br>
The ISBN is %ISBN% <br><br>
++

I know how to do something like sAuth = re.sub('%author1%', author1,
sTemplate), but I can't figure out to populate variables within python
from the list of fields.

The second thing I am trying to figure out is how to add a field (or
populate an empty field) called filename with the value of ISBN +
'.txt', though I hope this becomes pretty self evident after someone
helps me with the above.

The last thing that is vexing me at the moment is something I am not
sure if it is possible. Once I have populated this filename field, I
will want to try to do something like:

for book in all_books
open(r'd:\path\to\files\%filename%', 'a')
some_function


Where I replace %filename% with the value of the filename field for
each book. Is it possible to do some sort of search and replace like
that over a command within python?

Or is there another way entirely different to accomplish such a task,
like maybe assigning the path/filename to a variable... ?

TIA!

Googleboy
 
B

Bernhard Holzmayer

googleboy said:
Hi there. Hi googleboy!

I am doing a bunch of processing over a list of lists, and am
interested in doing several things taht don't seem to be working for me
just at the moment.

I have a list of books with several fields (Title, Author1, Author2,
Publisher, ISBN) in a csv.

I have a cell.txt file that looks like this:

++
The title is %title%. <br><br>
The author is %author1% %author2% <br><br>
The Publisher is %publisher1% %publisher2% <br><br>
The ISBN is %ISBN% <br><br>
++

This looks like a DOS-batch-file. Maybe you'd better just leave it to
DOS to populate it, just by exec-uting it in an environment which
has title, authort1, ... set. ??

On the other hand, if you need not relate to the cell.txt file,
you could just use something like

sAuth = "The author is %s" % author1
I know how to do something like sAuth = re.sub('%author1%', author1,
sTemplate), but I can't figure out to populate variables within python
from the list of fields.

I guess, that you open the csv-file and then use readline for each record.
Since csv files are ; separated (or ,), just do
recordlist = current_line.split(';')
which provides all entries from the read line in a list.
Or even better:
(title,author1,author2,publisher1,publisher2,ISBN) = current_line.split(';')
Now you can do something like
sAuth = "The author is %s" % recordlist[1] in the first case, or
sAuth = "The author is %s" % author1 in the second
The second thing I am trying to figure out is how to add a field (or
populate an empty field) called filename with the value of ISBN +
'.txt', though I hope this becomes pretty self evident after someone
helps me with the above.

You're certainly right about the evidence of the following:
filename="%s.txt" % ISBN
The last thing that is vexing me at the moment is something I am not
sure if it is possible. Once I have populated this filename field, I
will want to try to do something like:

for book in all_books
open(r'd:\path\to\files\%filename%', 'a')
some_function


Where I replace %filename% with the value of the filename field for
each book. Is it possible to do some sort of search and replace like
that over a command within python?

Or is there another way entirely different to accomplish such a task,
like maybe assigning the path/filename to a variable... ?
I'd try like this:
0. Initialize an empty list all_books=[]
1. While reading in the csv file line by line, you received the ISBN
for that line(book). (Look above the line with the split command)
Now add this ISBN to the list by:
all_books.append(ISBN)

2. After the list is complete (all records read, file closed),
you can do this as you assumed:
for book in all_books:
f=open(r"d:\path\to\files\%s.txt" % book, 'a')
some_function...
f.close()
TIA!

Googleboy
Bernhard

P.S:
1. Looking into the Python tutorial which is available online at
www.python.org, would have answered most of your questions.
 
S

Sion Arrowsmith

Bernhard Holzmayer said:
This looks like a DOS-batch-file. Maybe you'd better just leave it to
DOS to populate it, just by exec-uting it in an environment which
has title, authort1, ... set. ??

On the other hand, if you need not relate to the cell.txt file,
you could just use something like

sAuth = "The author is %s" % author1

Or

sAuth = "The author is %(author1)s" % locals()

so cell.txt could be replaced by something like

++
The title is %(title)s. <br><br>
The author is %(author1)s %(author2)s <br><br>
The Publisher is %(publisher1)s %(publisher2)s <br><br>
The ISBN is %(ISBN)s <br><br>
++

and you could do everything at once. Obviously you'd be better
off sticking author1 etc. into a dict instead of making them
local variables. This might also solve your problems with
"getting fields into Python" (as someone else said, it's not
entirely clear what your difficulties are):

field_names = ["title", "author1", "author2", "publisher", "ISBN"]
fields_dict = dict(zip(field_names, fields))
sTemplate % field_dict

re.sub() is massive overkill. If you can't get where you want
with % as above, use str.replace instead:

sTemplate.replace('%author1%', author1)

(Er, "you" above refers to OP, not Bernhard.)
 
G

googleboy

Ali said:
It's not really clear what you mean?

Ah. sorry. Let me try again.

I start with a csv that looks something like this:

title, author1, author2, publisher, code, ISBN
frogs of canada, andy humber, , springer press, foc2, 111-20345-556
newts of the UK, nigel snodgrass, sarah strauss, cambridge press,
nsss23,32-443567-130
amphibian environments, nigel snodgrass, , cambridge press, nsxx11,
32443567-120

First problem:

I have a seed file which I have placed a set of easily searchable
keywords (%author1%, %publisher% etc.) in. I want to be able to
replace these keywords with the relevent values from each book, in
order to create an individual text file for each book called code.txt
(where the word code is replaced by the code of each book)

I've read the tutorial and (I think I)know how to use regular
expressions to make the substitions, but I can't figure out how to get
to the individual values of each book.

I have been trying the following:

++
import string, os, re, sys, operator, csv

class Book(object):
def __init__(self, title, author1, author2, publisher, code,ISBN):
params = locals()
del params['self']
self.__dict__.update(params)
def __repr__(self):
all_items = self.__dict__.items()
return str(all_items)

def read_books(filename):
reader = csv.reader(csv_file)
books = [Book(*[field.strip() for field in row]) for row in reader]
csv_file.close()
return books

booklist = read_books("c:\path\to\books.csv")
header = booklist[0]
all_books = booklist[1:]

Template = open(r'c:\path\to\cell.txt', 'r')
sTemplate = Template.read()


author1 = getattr(all_books, 'author1') # trying to assign the author
value to the variable author1.


sAuth = re.sub('%author%', author1, sTemplate) # replace %author1% with
the value in author1 in the variable sTemplate)

++
The getattr causes an error that says "AttributeError: 'list' object
has no attribute 'author1'" so I think I am reading the operator
library page on the python site wrong somehow.

once this works, I move onto the second problem, which is to write out
the string after the substitions to a new file called e.g. foc2.txt
(for the frogs of canada book).

I really am not sure how to go about this. I was thinking of something
like concatenating three strings together

path = "r/'c:\path\to"
code = getattr(code, all_books)
extension = '.txt/''
filename = path + code + extension

f = open(filename, 'w')

however I have serious doubts that doing that will work.

I guess what I am needing, if it doesn't, is some sort of method of
substituting a variable's value into the following:

f = open(r'c:\path\to\%subs%.txt, 'w')


The third thing I am hoping to acheive is to append an extra field to
each book called 'filename' which will simply be a concatenation of the
'code' field + '.txt'. Further thought suggests that I should create
the field first, even if it is empty, so that the books still all
conform to the Book class. Then it simply becomes a question of how to
I change the value of a field in these lists. I am sure that the
answer to that was something I found in the tute, or it will be in my
deitel python book somewhere... The hard bit is part one (assigning
the value of a field to a variable)

Thanks for your help.

Googleboy
 
G

googleboy

Thanks for this. It ahs been very helpful.

I realised that my problem using getattr were because I was trying to
use it over the list of lists, instead of each book. I have written up
a for loop now, and I think I am a lot closer:

for book in all_books:
author1 = getattr(book, 'author1')
sTemplate.replace('author1', author1)
found = sTemplate.find('%author1%')
print '\n.\n.\n'
print author1
print '\n'
print found
print sTemplate


You will notice that I print out various things. I am having some
troubles.

The resulting output of this loop is as follows:

andy humber

47
The title is %title%. <br><br>

The author is %author1% %author2% <br><br>

The Publisher is %publisher1% %publisher2% <br><br>

The ISBN is %ISBN% <br><br>

This is obviously correctly assigning the author's name to the author1
variable, which I was my problem.

It is finding my search string at teh 47th character of the sTemplate
string, which is great.

But it doesn't seem to want to replace the search string with the value
of the author1 variable.

Is there something else I am missing here?

Thanks for the advice.

regards,

googleboy
 
A

Ali

sTemplate.replace() returns a string with that substitution.

so you need to reassign it such as:
sTemplate = sTemplate.replace('author1', author1)

Anyway, Sion Arrowsmith above showed you a much better technique of
filling all those values at once.

Hope this helps,

Ali
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top