Discussion:
[Tutor] Is there a way to use "with" across suite boundaries?
Jim Mooney Py3.4.3winXP
2015-05-23 05:56:44 UTC
Permalink
'''I was using with open...:, but I'm printing a header in one function,
calling a looping
function to print detail lines, then returning to the calling function to
print
the footer. But that didn't work since the with statement only seems to work
with the lexical suite and the file wasn't open in the detail print
function. Is there
a way around this, other than passing the file as I have here? Also, is it a
good idea to pass a file handle like that or is there a better way?

Using the below csv file co2-sample.csv to print a simple HTML table
(header omitted)
Since this is a file there are enclosing single quotes not visible:

"ANTIGUA AND BARBUDA",0,0,0,0,0
"ARGENTINA",37,35,33,36,39
"BAHAMAS, THE",1,1,1,1,1
"BAHRAIN",5,6,6,6,6
"SPANISH INQUISITION, THE, SILLY",10,33,14,2,8

Program follows (py3.4, winxp):'''

htbegin = '''
<html>
<head>
<title>htest</title>
<style>
table, td {border:2px solid black; border-collapse:collapse;}
td {padding:3px; background-color:pink;
text-align:right;font-family:verdana;}
td.l {text-align:left}
</style>

</head>
<body>
<table>
'''

htend = '''
</table>
</body>
</html>
'''

def make_lines():
co2 = open('co2-sample.csv')
ht = open('output.html', 'w')
linelist = []
print(htbegin, file=ht)
for line in co2:
newlist = line.rsplit(',', 5) # ending is regular so split it out
first
for token in newlist: # since split char inside quotes for
nation is problematic
linelist.append(token.strip('"')) # get rid of extra quotes
linelist[-1] = linelist[-1].strip()
fprint(linelist, ht)
linelist = []
co2.close()
print(htend, file=ht)
ht.close()


def fprint(linelist, ht):
# size formatting irrelevant for HTML
formatted_string = "<td
class=l>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td>".format(*linelist)
print(formatted_string, file=ht)
print('</tr>', file=ht)


if __name__ == "__main__":
make_lines()
--
Jim
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Peter Otten
2015-05-23 06:55:06 UTC
Permalink
Post by Jim Mooney Py3.4.3winXP
'''I was using with open...:, but I'm printing a header in one function,
calling a looping
function to print detail lines, then returning to the calling function to
print
the footer. But that didn't work since the with statement only seems to
work with the lexical suite and the file wasn't open in the detail print
function. Is there
a way around this, other than passing the file as I have here? Also, is it
a good idea to pass a file handle like that or is there a better way?
Something else must have gone wrong as

def make_lines():
with open('co2-sample.csv') as co2:
with open('output.html', 'w') as ht:
linelist = []
print(htbegin, file=ht)
for line in co2:
newlist = line.rsplit(',', 5)
for token in newlist:
linelist.append(token.strip('"'))
linelist[-1] = linelist[-1].strip()
fprint(linelist, ht)
linelist = []
print(htend, file=ht)

should run without error. Also possible:

with open('co2-sample.csv') as co2, open('output.html', 'w') as ht:
...

But may I suggest that you delegate parsing the CSV to the standard library?
Then you can write

import csv

def make_lines():
with open('co2-sample.csv') as co2:
rows = csv.reader(co2)
with open('output.html', 'w') as ht:
print(htbegin, file=ht)
for linelist in rows:
fprint(linelist, ht)
print(htend, file=ht)
Post by Jim Mooney Py3.4.3winXP
Using the below csv file co2-sample.csv to print a simple HTML table
(header omitted)
"ANTIGUA AND BARBUDA",0,0,0,0,0
"ARGENTINA",37,35,33,36,39
"BAHAMAS, THE",1,1,1,1,1
"BAHRAIN",5,6,6,6,6
"SPANISH INQUISITION, THE, SILLY",10,33,14,2,8
Program follows (py3.4, winxp):'''
htbegin = '''
<html>
<head>
<title>htest</title>
<style>
table, td {border:2px solid black; border-collapse:collapse;}
td {padding:3px; background-color:pink;
text-align:right;font-family:verdana;}
td.l {text-align:left}
</style>
</head>
<body>
<table>
'''
htend = '''
</table>
</body>
</html>
'''
co2 = open('co2-sample.csv')
ht = open('output.html', 'w')
linelist = []
print(htbegin, file=ht)
newlist = line.rsplit(',', 5) # ending is regular so split it out
first
for token in newlist: # since split char inside quotes for
nation is problematic
linelist.append(token.strip('"')) # get rid of extra quotes
linelist[-1] = linelist[-1].strip()
fprint(linelist, ht)
linelist = []
co2.close()
print(htend, file=ht)
ht.close()
# size formatting irrelevant for HTML
formatted_string = "<td
class=l>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td>".format(*linelist)
Post by Jim Mooney Py3.4.3winXP
print(formatted_string, file=ht)
print('</tr>', file=ht)
make_lines()
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Mark Lawrence
2015-05-23 07:02:22 UTC
Permalink
Post by Jim Mooney Py3.4.3winXP
'''I was using with open...:, but I'm printing a header in one function,
calling a looping
function to print detail lines, then returning to the calling function to
print
the footer. But that didn't work since the with statement only seems to work
with the lexical suite and the file wasn't open in the detail print
function. Is there
a way around this, other than passing the file as I have here? Also, is it a
good idea to pass a file handle like that or is there a better way?
Will you please be precise about the problems that you have, "that
didn't work" is usually less than useless. However on this occasion it
seems that all you have to do is pass the file handle, it's a standard
way of doing things.
--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-05-23 09:27:54 UTC
Permalink
Post by Jim Mooney Py3.4.3winXP
'''I was using with open...:, but I'm printing a header in one function,
calling a looping
function to print detail lines, then returning to the calling function to
print
the footer. But that didn't work since the with statement only seems to work
with the lexical suite and the file wasn't open in the detail print
function.
What does that mean? Did you get an error message? If so what?
Was the file empty? What happened? Be specific.
Post by Jim Mooney Py3.4.3winXP
a way around this, other than passing the file as I have here?
Passing the file object around is good, its not "a way around".
Its what you should be doing. Passing objects into functions and getting
a result back is what good programming encourages.
Leaking objects across function boundaries from the outside
(eg with global variables) is bad and should be avoided.
I don't know what you mean by that.
What is a file? The data below?
Why would that put it in enclosing quotes?
Post by Jim Mooney Py3.4.3winXP
"ANTIGUA AND BARBUDA",0,0,0,0,0
"ARGENTINA",37,35,33,36,39
"BAHAMAS, THE",1,1,1,1,1
"BAHRAIN",5,6,6,6,6
"SPANISH INQUISITION, THE, SILLY",10,33,14,2,8
Program follows (py3.4, winxp):'''
htbegin = '''
...
Post by Jim Mooney Py3.4.3winXP
'''
htend = '''
...
Post by Jim Mooney Py3.4.3winXP
'''
co2 = open('co2-sample.csv')
ht = open('output.html', 'w')
linelist = []
print(htbegin, file=ht)
Why not just write to the file directly?

ht.write(htbegin)
Post by Jim Mooney Py3.4.3winXP
newlist = line.rsplit(',', 5) # ending is regular so split it out
first
for token in newlist: # since split char inside quotes for
nation is problematic
Use the csv file to parse csv files, it is much more reliable and avoids
all the strange exceptional cases such as embedded commas,
split lines etc.
Post by Jim Mooney Py3.4.3winXP
linelist.append(token.strip('"')) # get rid of extra quotes
linelist[-1] = linelist[-1].strip()
fprint(linelist, ht)
linelist = []
I don't think resetting the list adds much value?
Post by Jim Mooney Py3.4.3winXP
co2.close()
print(htend, file=ht)
ht.write(htend)
Post by Jim Mooney Py3.4.3winXP
ht.close()
# size formatting irrelevant for HTML
formatted_string = "<td
class=l>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td>".format(*linelist)
your table has no rows, is that deliberate? I'd expect a <tr> at the
beginning...
Post by Jim Mooney Py3.4.3winXP
print(formatted_string, file=ht)
ht.write(formatted_string)
Post by Jim Mooney Py3.4.3winXP
print('</tr>', file=ht)
and now you add a </tr> at the end. Why not just put it
inside the string?
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Peter Otten
2015-05-23 09:52:48 UTC
Permalink
Post by Jim Mooney Py3.4.3winXP
function. Is there
a way around this, other than passing the file as I have here? Also, is it
a good idea to pass a file handle like that or is there a better way?
Not necessarily better, but instead of passing around the file you can
rewrite your code to use generators:

import csv


def make_lines():
with open('co2-sample.csv') as co2:
yield htbegin
for linelist in csv.reader(co2):
yield from fprint(linelist)
yield htend


def fprint(linelist):
yield ("<td class=l>{}</td><td>{}</td><td>{}</td>"
"<td>{}</td><td>{}</td><td>{}</td>\n").format(*linelist)
yield '</tr>\n'


if __name__ == "__main__":
with open('output.html', 'w') as ht:
ht.writelines(make_lines())


Python versions before 3.3 don't understand

yield from fprint(linelist)

You have to write

for s in fprint(linelist):
yield s

instead.


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Cameron Simpson
2015-05-23 06:17:26 UTC
Permalink
Post by Jim Mooney Py3.4.3winXP
'''I was using with open...:, but I'm printing a header in one function,
calling a looping
function to print detail lines, then returning to the calling function to
print
the footer. But that didn't work since the with statement only seems to work
with the lexical suite and the file wasn't open in the detail print
function. Is there
a way around this, other than passing the file as I have here? Also, is it a
good idea to pass a file handle like that or is there a better way?
It is just fine. Example:

with open("blah", "w") as blahfp:
print("header", file=blahfp)
print_details(blahfp, ...)
print("footer", file=blahfp)

def print_details(fp, blah_info):
... loop using blah_info to write data to "fp"

Cheers,
Cameron Simpson <***@zip.com.au>
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Continue reading on narkive:
Loading...