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

Discussion in 'Python' started by cstrutton11@gmail.com, Feb 8, 2014.

  1. Guest

    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
     
    , Feb 8, 2014
    #1
    1. Advertising

  2. Asaf Las Guest

    On Saturday, February 8, 2014 9:41:53 AM UTC+2, wrote:
    > 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
     
    Asaf Las, Feb 8, 2014
    #2
    1. Advertising

  3. Rustom Mody Guest

    On Saturday, February 8, 2014 1:11:53 PM UTC+5:30, wrote:
    > 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
     
    Rustom Mody, Feb 8, 2014
    #3
  4. Peter Otten Guest

    wrote:

    > 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", ...)
     
    Peter Otten, Feb 8, 2014
    #4
  5. Guest

    On Saturday, February 8, 2014 3:35:34 AM UTC-5, Rustom Mody wrote:
    > On Saturday, February 8, 2014 1:11:53 PM UTC+5:30, wrote:
    >
    > > 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


    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.
     
    , Feb 8, 2014
    #5
  6. Guest

    On Saturday, February 8, 2014 3:13:54 AM UTC-5, Asaf Las wrote:

    >
    > 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?
     
    , Feb 8, 2014
    #6
  7. Guest

    On Saturday, February 8, 2014 3:13:54 AM UTC-5, Asaf Las wrote:

    >
    > 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.
     
    , Feb 8, 2014
    #7
  8. On Sat, 08 Feb 2014 01:56:46 -0800, cstrutton11 wrote:

    > On Saturday, February 8, 2014 3:13:54 AM UTC-5, Asaf Las wrote:
    >> 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.


    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.



    --
    Steven
     
    Steven D'Aprano, Feb 8, 2014
    #8
  9. Asaf Las Guest

    On Saturday, February 8, 2014 11:56:46 AM UTC+2, wrote:
    > On Saturday, February 8, 2014 3:13:54 AM UTC-5, Asaf Las wrote:
    >
    >
    >
    > >

    >
    > > 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, 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)
     
    Asaf Las, Feb 8, 2014
    #9
  10. Roy Smith Guest

    In article <>,
    Rustom Mody <> wrote:

    > On Saturday, February 8, 2014 1:11:53 PM UTC+5:30, wrote:
    > > 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


    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.
     
    Roy Smith, Feb 8, 2014
    #10
  11. Rustom Mody Guest

    On Saturday, February 8, 2014 4:58:03 PM UTC+5:30, Asaf Las wrote:
    > 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

    >>> str_t= ( '<script type="text/javascript'

    .... '<src="/{0}/jquery/jqueryui.js"></script>'
    .... '<script type="text/javascript'
    .... 'src="/{1}/jquery/jquery.js"></script>'
    .... )

    >>> str_t

    '<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

    >>> dc={'pth':'bella', 'file':'donna'}
    >>> formatstr='<script type="text/javascript<src="/%(pth)s/jquery/jqueryui.js"></script><script type="text/javascriptsrc="/%(file)s/jquery/jquery.js"></script>'


    >>> formatstr % dc

    '<script type="text/javascript<src="/bella/jquery/jqueryui.js"></script><script type="text/javascriptsrc="/donna/jquery/jquery.js"></script>'
     
    Rustom Mody, Feb 8, 2014
    #11
  12. On 08/02/2014 10:11, wrote:
    > On Saturday, February 8, 2014 3:13:54 AM UTC-5, Asaf Las wrote:
    >
    >>
    >> 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.
    >


    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.

    --
    My fellow Pythonistas, ask not what our language can do for you, ask
    what you can do for our language.

    Mark Lawrence

    ---
    This email is free from viruses and malware because avast! Antivirus protection is active.
    http://www.avast.com
     
    Mark Lawrence, Feb 8, 2014
    #12
  13. Dave Angel Guest

    Wrote in message:

    >
    > 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.
    --
    DaveA
     
    Dave Angel, Feb 8, 2014
    #13
  14. On 2/8/2014 3:35 AM, Rustom Mody wrote:
    > On Saturday, February 8, 2014 1:11:53 PM UTC+5:30, wrote:
    >> 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

    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
     
    Eric S. Johansson, Feb 8, 2014
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Carl J. Van Arsdall
    Replies:
    4
    Views:
    502
    Bruno Desthuilliers
    Feb 7, 2006
  2. Manuel Ebert
    Replies:
    3
    Views:
    342
    Steven D'Aprano
    Aug 31, 2008
  3. Andrew Fong

    Most pythonic way to truncate unicode?

    Andrew Fong, May 28, 2009, in forum: Python
    Replies:
    6
    Views:
    303
    John Machin
    May 29, 2009
  4. Angus
    Replies:
    6
    Views:
    481
    Angus
    Jan 5, 2010
  5. david jensen
    Replies:
    10
    Views:
    394
Loading...

Share This Page