What is the most pythonic way to build up large strings?

C

cstrutton11

I am writing a couple of class methods to build up several lines of html. Some of the lines are conditional and most need variables inserted in them. Searching the web has given me a few ideas. Each has its pro's and cons.

The best I have come up with is:


def output_header_js(self, jquery=True, theme=None):
if self.static_path is None :
return None

if jquery is True:
output = '"<script type="text/javascript" '
output += 'src="/%s/jquery/jqueryui.js"></script>'% static
output += '"<script type="text/javascript" '
output += 'src="/%s/jquery/jquery.js"></script>'% static

if theme is not None:
output += '<link href="/%s/jtable/themes/%s/jtable.css" '% static, theme
output += 'rel="stylesheet" type="text/css" />'

output += '"<script type="text/javascript" '
output += 'src="/%s/jtable/jquery.jtable.js"></script>' % "static"


I realize that a lot of the above looks repetitive but it is designed to eliminate boilerplate HTML.

I have another method that will build some javascript that looks like this:

$('#StudentTableContainer').jtable({
title: 'The Student List',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'Name ASC', //Set default sorting
actions: {
listAction: '/Demo/StudentList',
deleteAction: '/Demo/DeleteStudent',
updateAction: '/Demo/UpdateStudent',
createAction: '/Demo/CreateStudent'
},
fields: {
StudentId: {
key: true,
create: false,
edit: false,
list: false
},
Name: {
title: 'Name',
width: '23%'
},
EmailAddress: {
title: 'Email address',
list: false
},
...

Almost every line in this code will require variable insertion or if statements.

Any thoughts on how to improve this? Thanks in advance. Chris
 
A

Asaf Las

I am writing a couple of class methods to build up several
lines of html. Some of the lines are conditional and most need
variables inserted in them. Searching the web has given me a
few ideas. Each has its pro's and cons.

The best I have come up with is:

def output_header_js(self, jquery=True, theme=None):
if self.static_path is None :
return None

if jquery is True:
output = '"<script type="text/javascript" '
output += 'src="/%s/jquery/jqueryui.js"></script>'% static
output += '"<script type="text/javascript" '
output += 'src="/%s/jquery/jquery.js"></script>'% static

if theme is not None:
output += '<link href="/%s/jtable/themes/%s/jtable.css" '% static, theme

output += 'rel="stylesheet" type="text/css" />'

output += '"<script type="text/javascript" '
output += 'src="/%s/jtable/jquery.jtable.js"></script>' % "static"

I realize that a lot of the above looks repetitive but it is
designed to eliminate boilerplate HTML.

note, due to strings are immutable - for every line in sum operation
above you produce new object and throw out older one. you can write
one string spanned at multiple lines in very clear form.


/Asaf
 
R

Rustom Mody

I am writing a couple of class methods to build up several lines of html. Some of the lines are conditional and most need variables inserted in them. Searching the web has given me a few ideas. Each has its pro's and cons.

For creating html the method of choice is a template engine -- cheetah, mako
and a dozen others

You can of course roll your own (poor mans version) template engine
For that look up
1. triple quoted strings
2. format operator
 
P

Peter Otten

I am writing a couple of class methods to build up several lines of html.
Some of the lines are conditional and most need variables inserted in
them. Searching the web has given me a few ideas. Each has its pro's and
cons.

The best I have come up with is:


def output_header_js(self, jquery=True, theme=None):
if self.static_path is None :
return None

if jquery is True:
output = '"<script type="text/javascript" '

Try to call the function with jquery=False ;)
output += 'src="/%s/jquery/jqueryui.js"></script>'% static
output += '"<script type="text/javascript" '
output += 'src="/%s/jquery/jquery.js"></script>'% static

if theme is not None:
output += '<link href="/%s/jtable/themes/%s/jtable.css" '% static,
theme output += 'rel="stylesheet" type="text/css" />'

output += '"<script type="text/javascript" '
output += 'src="/%s/jtable/jquery.jtable.js"></script>' % "static"


I realize that a lot of the above looks repetitive but it is designed to
eliminate boilerplate HTML.

I sometimes use a variation of the above

def output_header(...):
if jquery:
yield """src=..."""
if theme is not None:
yield """<link href..."""

and then use it

sys.stdout.writelines(output_header(...))

but if you are doing this a lot you should pick one of the many template
languages and use that to build your html
I have another method that will build some javascript that looks like
this:

$('#StudentTableContainer').jtable({
title: 'The Student List',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'Name ASC', //Set default sorting
actions: {
listAction: '/Demo/StudentList',
deleteAction: '/Demo/DeleteStudent',
updateAction: '/Demo/UpdateStudent',
createAction: '/Demo/CreateStudent'
},
fields: {
StudentId: {
key: true,
create: false,
edit: false,
list: false
},
Name: {
title: 'Name',
width: '23%'
},
EmailAddress: {
title: 'Email address',
list: false
},
...

Almost every line in this code will require variable insertion or if
statements.

Any thoughts on how to improve this? Thanks in advance. Chris

Again, you can build this with Python proper

"... title: {title} ...".format(title="The Student List", ...)

but a template language will make sure that your data is escaped properly,
think

"... title: {title} ...".format(title="The Student's List", ...)
 
C

cstrutton11

For creating html the method of choice is a template engine -- cheetah, mako

and a dozen others



You can of course roll your own (poor mans version) template engine

For that look up

1. triple quoted strings

2. format operator

I am using this with a template engine. This method is going into a pyramid view class which will be rendered with chameleon or any other template engine. Actually it is going into a base class to be inherited into a view class. The idea is to setup all the parameters for the HTML when the view class is created and reuse all that info for the initial page as well as allthe ajax calls.

I didn't realize I could use formatting with triple quoted strings. I willlook into that.
 
C

cstrutton11

note, due to strings are immutable - for every line in sum operation

above you produce new object and throw out older one. you can write

one string spanned at multiple lines in very clear form.

I get what your saying here about immutable strings. Is there anyway efficiently build large strings with lots of conditional inclusions, repetative sections built dynamically by looping (see the field section above)etc. Is there a mutable string class?
 
C

cstrutton11

note, due to strings are immutable - for every line in sum operation

above you produce new object and throw out older one. you can write

one string spanned at multiple lines in very clear form.

/Asaf

I think I going to rewrite this to build up a list of strings and then run a join on them at the end. Each section can be conditionally built up with variable insertions as required. This should be more efficient and will scale nicely as required.
 
S

Steven D'Aprano

I get what your saying here about immutable strings. Is there anyway
efficiently build large strings with lots of conditional inclusions,
repetative sections built dynamically by looping (see the field section
above)etc.

Yes. Build up all the substrings individually, storing them in a list.
Then, when you are ready to actually use the string, assemble it in one
go.

substrings = []
for x in whatever():
if condition():
substrings.append("something")

process("".join(substrings))

Is there a mutable string class?

No. Well, actually there is, but it's a toy, and operates under the hood
by creating new immutable strings, so there's no point using it. It may
even have been removed from more recent versions of Python.
 
A

Asaf Las

I get what your saying here about immutable strings.
Is there anyway efficiently build large strings with
lots of conditional inclusions, repetitive sections
built dynamically by looping (see the field section above)etc.
Is there a mutable string class?

Check this approach if it suits you:

str_t= '<script type="text/javascript' \
'<src="/{0}/jquery/jqueryui.js"></script>' \
'<script type="text/javascript'\
'src="/{1}/jquery/jquery.js"></script>'.format('bella', 'donna')

print(str_t)
 
R

Roy Smith

Rustom Mody said:
For creating html the method of choice is a template engine -- cheetah, mako
and a dozen others

Absolutely agree. No need to reinvent a wheel which has already been
invented in so many shapes, sizes, and colors.

We use http://jinja.pocoo.org/, but like Rustom said, there are many to
pick from. Any of them is likely to be a better solution than what you
would roll yourself.
 
R

Rustom Mody

Check this approach if it suits you:
str_t= '<script type="text/javascript' \
'<src="/{0}/jquery/jqueryui.js"></script>' \
'<script type="text/javascript'\
'src="/{1}/jquery/jquery.js"></script>'.format('bella', 'donna')
print(str_t)


Many people prefer this
.... '<src="/{0}/jquery/jqueryui.js"></script>'
.... '<script type="text/javascript'
'<script type="text/javascript<src="/{0}/jquery/jqueryui.js"></script><script type="text/javascriptsrc="/{1}/jquery/jquery.js"></script>'

Which is to say use the fact that adjacent string constants get automatically
concatenated. You avoid the ugly \ at EOL though you then need an enclosing paren.

However this is still C programmer style
Triple quotes are better
And templating engine is still better

And for more heavy duty use of format, it may be better to use
named-formats + a dict
'<script type="text/javascript<src="/bella/jquery/jqueryui.js"></script><script type="text/javascriptsrc="/donna/jquery/jquery.js"></script>'
 
M

Mark Lawrence

I think I going to rewrite this to build up a list of strings and then run a join on them at the end. Each section can be conditionally built up with variable insertions as required. This should be more efficient and will scale nicely as required.

An alternative is to use io.Stringio which is available in Python 2.7
and 3.x.

Also would you please read and action this
https://wiki.python.org/moin/GoogleGroupsPython to prevent us seeing the
double line spacing above, thanks.
 
D

Dave Angel

I didn't realize I could use formatting with triple quoted strings. I will look into that.


You probably realize this, but formatting does not work on
literals of any kind. It works on str objects, which can be
created by any kind of literal, or by concatenation, or by
conversion, or by I/O, or ...

So all 16 (?) variants of string literals may be used.
 
E

Eric S. Johansson

For creating html the method of choice is a template engine -- cheetah, mako
and a dozen others

You can of course roll your own (poor mans version) template engine
For that look up
1. triple quoted strings
2. format operator
as so happens, I'm traveling down a similar path myself. My goal is to
use it to generate code for disabled, speech recognition using
programmers (like myself). I believe my best route is using a modified
version of string.Template but I wonder if my biases keep me from seeing
a good alternative. I believe the following characteristics are essential:

Easy to speak
output generated with the right indentation
recursive expansion
can list substitution names


Here's an example of use. The current model for visual output is a split
screen simulated as text between two long lines of
--------------------------------:

Saying: add method

----------------------- in the GUI/editor
-----------------------------------------
method_name??undefined
-------------------------
def method_name():
-----------------------------------------------------------------------------------------

Saying: add three arguments
----------------------- in the GUI/editor
-----------------------------------------
method_name??undefined
argument_1??undefined
argument_2??undefined
argument_3??undefined
-------------------------
def method_name(argument_1, argument_2, argument_3):
-----------------------------------------------------------------------------------------

Saying: fix undefined
----------------------- in the GUI/editor
-----------------------------------------
method_name??^
argument_1??undefined
argument_2??undefined
argument_3??undefined
-------------------------
def method_name(argument_1, argument_2, argument_3):
-----------------------------------------------------------------------------------------

Saying some method name
----------------------- in the GUI/editor
-----------------------------------------
method_name??some method name
argument_1??undefined
argument_2??undefined
argument_3??undefined
-------------------------
def some method name(argument_1, argument_2, argument_3):
-----------------------------------------------------------------------------------------

You repeat the process saying "fix undefined"until all of the
substitution names were filled in and the expanded template in the lower
window was correct. The conversion from string names such as "some
method argument" to codenames (SmMnm) happens in a different part of the
process.

The problem am working on now is if I change something in the list of
substitution names (upper window) how does that affect the code
generated and shown in the lower window? The vast majority of the time,
deleting a substitution name resets it to undefined. But deleting
argument is special. At the moment, I'm going with explicit alteration
of an argument list rather than inferring the argument list from the
arguments in the substitution name window.

I'm reasonably sure that templates, some sort, are the way to go for
reducing vocal load. What I'm still wrestling with is the kind of
overhead I impose on the programmer and that, in turn, defines the kind
of templates I need for programming by speech.

Solving this problem has made me curse one feature of Python which is
it's type system. Something, more static, would make things much easier
because the type information could be used to predict what will be said
next thereby reducing the number of hacks, such as templates, necessary
to write code. However, given that one can write Python reasonably well
using ordinary speech recognition, I can almost live with its type
system. :) but, if somebody knows a way to make an empirical
determination of type, I wouldn't turn away the help
 

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,968
Messages
2,570,152
Members
46,698
Latest member
LydiaHalle

Latest Threads

Top