Why do this?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Matthew Warren

    #1

    Why do this?

    Ok, not really python focused, but it feels like the people here could
    explain it for me :)

    Now, I started programming when I was 8 with BBC Basic.

    I never took any formal classes however, and I have never become an
    expert programmer. I'm an average/hobbyist programmer with quite a few
    languages under my belt but I cant do any really fancy tricks with any
    of them. (although Python might be nudging me into more advanced things,
    now I'm starting to get what all the __method__ thingies and operators
    are all about)

    I learned over the years to do things like the following, and I like
    doing it like this because of readability, something Python seems to
    focus on :-

    Print "There are "+number+" ways to skin a "+furryanim al

    But nowadays, I see things like this all over the place;

    print("There are %s ways to skin a %s" % (number, furryanimal))

    Now I understand there can be additional formatting benefits when
    dealing with numbers, decimal places etc.. But to me, for strings, the
    second case is much harder to read than the first.

    I hope I'm not being dense.

    The result is that I have pathalogically avoided print "%s" % (thing)
    because it seems to just over complicate things.


    Ta, :)

    Matt.





    This email is confidential and may be privileged. If you are not the intended recipient please notify the sender immediately and delete the email fromyour computer.

    You should not copy the email, use it for any purpose or disclose its contents to any other person.
    Please note that any views or opinions presented in this email may be personal to the author and do not necessarily represent the views or opinions ofDigica.
    It is the responsibility of the recipient to check this email for the presence of viruses. Digica accepts no liability for any damage caused by any virus transmitted by this email.

    UK: Phoenix House, Colliers Way, Nottingham, NG8 6AT UK
    Reception Tel: + 44 (0) 115 977 1177
    Support Centre: 0845 607 7070
    Fax: + 44 (0) 115 977 7000
    Digica | International AI powered software solutions company developing smart intelligent software solutions for Cloud, IoT and Embedded.


    SOUTH AFRICA: Building 3, Parc du Cap, Mispel Road, Bellville, 7535, South Africa
    Tel: + 27 (0) 21 957 4900
    Fax: + 27 (0) 21 948 3135
    Digica | International AI powered software solutions company developing smart intelligent software solutions for Cloud, IoT and Embedded.

  • Marc 'BlackJack' Rintsch

    #2
    Re: Why do this?

    In <mailman.1336.1 160044062.10491 .python-list@python.org >, Matthew Warren
    wrote:
    I learned over the years to do things like the following, and I like
    doing it like this because of readability, something Python seems to
    focus on :-
    >
    Print "There are "+number+" ways to skin a "+furryanim al
    >
    But nowadays, I see things like this all over the place;
    >
    print("There are %s ways to skin a %s" % (number, furryanimal))
    >
    Now I understand there can be additional formatting benefits when
    dealing with numbers, decimal places etc.. But to me, for strings, the
    second case is much harder to read than the first.
    For me it's the other way around -- I find the second one more readable
    especially without syntax highlighting to see which characters are inside
    and which are outside the quotes.

    With the second one there's a clear visual separation of the string
    literal and the variables, even without colors.

    Another advantage of the second way is much easier localization and other
    tasks where the sentence itself is not hardcoded but read from files,
    databases, etc.

    And the '%s' automatically converts the objects to strings. The
    equivalent to the second example without string formatting would be::

    print 'There are' + str(number) + ' ways to skin a ' + str(furryanimal )

    Ciao,
    Marc 'BlackJack' Rintsch

    Comment

    • Duncan Booth

      #3
      Re: Why do this?

      "Matthew Warren" <Matthew.Warren @Digica.comwrot e:
      Print "There are "+number+" ways to skin a "+furryanim al
      >
      But nowadays, I see things like this all over the place;
      >
      print("There are %s ways to skin a %s" % (number, furryanimal))
      >
      Now I understand there can be additional formatting benefits when
      dealing with numbers, decimal places etc.. But to me, for strings, the
      second case is much harder to read than the first.
      >
      apart from the spurious parentheses you added in the second one, you also
      missed out this variant:

      print "There are", number, "ways to skin a", furryanimal

      That only works for print though, not for other uses of strings, but it is
      related to the main reason I use format strings instead of concatenation.

      The problem I have with your first option is the large number of times I've
      written:

      print "There are"+number+"wa ys to skin a"+furryanim al

      or at least something equivalent to it. If I try to make the same mistake
      with a format string it jumps out to me as wrong:

      "There are%sways to skin a%s" % (number, furryanimal)

      Also, having a variable of type str called 'number' seems perverse (and
      probably error prone), so I suspect I might need something like:

      print "There are "+str(numbe r)+" ways to skin a "+furryanim al

      but the format string does the conversion for free.

      The other main reason for preferring format strings is that they make it
      easier to refactor the code. If you ever want to move the message away from
      where the formatting is done then it's a lot easier to extract a single
      string than it is to clean up the concatenation.

      Comment

      • Ivan Voras

        #4
        Re: Why do this?

        Duncan Booth wrote:
        print "There are"+number+"wa ys to skin a"+furryanim al
        >
        or at least something equivalent to it. If I try to make the same mistake
        with a format string it jumps out to me as wrong:
        >
        "There are%sways to skin a%s" % (number, furryanimal)
        Related to this, formatting with sequences is also much more readable
        when there are complex interpunction and quoting characters present,
        like this:

        print "'"+var1+"','"+ var2'"+","+var3

        the above is much more readable as

        print "'%s', '%s', %s" % (var1, var2, var3)

        Comment

        • Maric Michaud

          #5
          Re: Why do this?

          Le jeudi 05 octobre 2006 13:16, Ivan Voras a écrit :
          print "'"+var1+"','"+ var2'"+","+var3
          >
          the above is much more readable as
          >
          print "'%s', '%s', %s" % (var1, var2, var3)
          It feels not IMO, one proof I see is that you forgot the spaces after periods
          in your first example, and it's even not easy to figure it out...

          In fact this is a typical case I replace the first by the second, when the
          string comes a little complex.

          --
          _____________

          Maric Michaud
          _____________

          Aristote - www.aristote.info
          3 place des tapis
          69004 Lyon
          Tel: +33 426 880 097

          Comment

          • hanumizzle

            #6
            Re: Why do this?

            On 10/6/06, Dennis Lee Bieber <wlfraed@ix.net com.comwrote:
            On Thu, 5 Oct 2006 11:28:08 +0100, "Matthew Warren"
            <Matthew.Warren @Digica.comdecl aimed the following in comp.lang.pytho n:
            >

            Now, I started programming when I was 8 with BBC Basic.
            Remember what the acronym BASIC stands for?
            Boobie-drawing Adolescent Symbolic Instruction Code.

            -- Theerasak

            Comment

            • Hendrik van Rooyen

              #7
              Re: Why do this?

              "Dennis Lee Bieber" <wlfraed@ix.net com.comwrote:
              On Thu, 5 Oct 2006 11:28:08 +0100, "Matthew Warren"
              <Matthew.Warren @Digica.comdecl aimed the following in comp.lang.pytho n:
              >

              Now, I started programming when I was 8 with BBC Basic.
              Remember what the acronym BASIC stands for?
              8<-----------------------------------------------

              yes

              - Hendrik


              Comment

              • half.italian@gmail.com

                #8
                Re: Why do this?

                Nobody's mentioned the ability to save a formatted string and then
                substitute the variables later...

                string = "There are %s ways to skin a %s"

                print string % (3, "furry animal")
                print string % (166, "beast")

                ~half.italian

                Matthew Warren wrote:
                Ok, not really python focused, but it feels like the people here could
                explain it for me :)
                >
                Now, I started programming when I was 8 with BBC Basic.
                >
                I never took any formal classes however, and I have never become an
                expert programmer. I'm an average/hobbyist programmer with quite a few
                languages under my belt but I cant do any really fancy tricks with any
                of them. (although Python might be nudging me into more advanced things,
                now I'm starting to get what all the __method__ thingies and operators
                are all about)
                >
                I learned over the years to do things like the following, and I like
                doing it like this because of readability, something Python seems to
                focus on :-
                >
                Print "There are "+number+" ways to skin a "+furryanim al
                >
                But nowadays, I see things like this all over the place;
                >
                print("There are %s ways to skin a %s" % (number, furryanimal))
                >
                Now I understand there can be additional formatting benefits when
                dealing with numbers, decimal places etc.. But to me, for strings, the
                second case is much harder to read than the first.
                >
                I hope I'm not being dense.
                >
                The result is that I have pathalogically avoided print "%s" % (thing)
                because it seems to just over complicate things.
                >
                >
                Ta, :)
                >
                Matt.
                >
                >
                >
                >
                >
                This email is confidential and may be privileged. If you are not the intended recipient please notify the sender immediately and delete the email from your computer.
                >
                You should not copy the email, use it for any purpose or disclose its contents to any other person.
                Please note that any views or opinions presented in this email may be personal to the author and do not necessarily represent the views or opinions of Digica.
                It is the responsibility of the recipient to check this email for the presence of viruses. Digica accepts no liability for any damage caused by any virus transmitted by this email.
                >
                UK: Phoenix House, Colliers Way, Nottingham, NG8 6AT UK
                Reception Tel: + 44 (0) 115 977 1177
                Support Centre: 0845 607 7070
                Fax: + 44 (0) 115 977 7000
                Digica | International AI powered software solutions company developing smart intelligent software solutions for Cloud, IoT and Embedded.

                >
                SOUTH AFRICA: Building 3, Parc du Cap, Mispel Road, Bellville, 7535, South Africa
                Tel: + 27 (0) 21 957 4900
                Fax: + 27 (0) 21 948 3135
                http://www.digica.com

                Comment

                • Corrado Gioannini

                  #9
                  Re: Why do this?

                  On Thu, Oct 05, 2006 at 10:48:36AM +0000, Duncan Booth wrote:
                  The other main reason for preferring format strings is that they make it
                  easier to refactor the code. If you ever want to move the message away from
                  where the formatting is done then it's a lot easier to extract a single
                  string than it is to clean up the concatenation.
                  This is a good point imho.
                  I often do things like this:

                  sql = a_complex_selec t_sql % (id_foo, value_bar, ...)
                  cursor.execute( sql)

                  inside the body of a function (or a class method), where
                  a_complex_selec t_sql is a string, containing several %s, %d ecc.,
                  that is defined globally (or somewhere else in the class).

                  c.
                  --
                  "Thought is only a flash between two long nights,
                  but this flash is everything."
                  (H. Poincaré)

                  Comment

                  • Duncan Booth

                    #10
                    Re: Why do this?

                    Corrado Gioannini <gioco@nekhem.c omwrote:
                    I often do things like this:
                    >
                    sql = a_complex_selec t_sql % (id_foo, value_bar, ...)
                    cursor.execute( sql)
                    >
                    inside the body of a function (or a class method), where
                    a_complex_selec t_sql is a string, containing several %s, %d ecc.,
                    that is defined globally (or somewhere else in the class).
                    >
                    I hope you have a good reason why you don't do:

                    cursor.execute( a_complex_selec t_sql, (id_foo, value_bar, ...))

                    instead.

                    Comment

                    • Corrado Gioannini

                      #11
                      Re: Why do this?

                      On Fri, Oct 06, 2006 at 10:09:14AM +0000, Duncan Booth wrote:
                      I hope you have a good reason why you don't do:
                      >
                      cursor.execute( a_complex_selec t_sql, (id_foo, value_bar, ...))
                      >
                      instead.
                      hehe.
                      i was just trying to be didactic, simplifying the actual situation.
                      (anyway, sometimes i had to print, or store, the sql statement, or
                      to execute the same sql statement on different databases etc. etc..)

                      regards,
                      c.
                      --
                      no, sono sempre io, non mi cambierete quel che ho dentro
                      forse ho solo un'altra faccia
                      ho più cicatrici di prima, sorrido un po' meno,
                      forse penso di più.
                      (Kina)

                      Comment

                      • Lawrence D'Oliveiro

                        #12
                        Re: Why do this?

                        In message <Xns98547173763 B6duncanbooth@1 27.0.0.1>, Duncan Booth wrote:
                        Corrado Gioannini <gioco@nekhem.c omwrote:
                        >
                        >I often do things like this:
                        >>
                        > sql = a_complex_selec t_sql % (id_foo, value_bar, ...)
                        > cursor.execute( sql)
                        >>
                        >inside the body of a function (or a class method), where
                        >a_complex_sele ct_sql is a string, containing several %s, %d ecc.,
                        >that is defined globally (or somewhere else in the class).
                        >>
                        I hope you have a good reason why you don't do:
                        >
                        cursor.execute( a_complex_selec t_sql, (id_foo, value_bar, ...))
                        >
                        instead.
                        I use the above when I can, when I can't I fall back on
                        <http://groups.google.c o.nz/groups?selm=efc 5b3$can$1@lust. ihug.co.nz>,
                        <http://groups.google.c o.nz/groups?selm=efh n5v$fia$2@lust. ihug.co.nz>.

                        Comment

                        • Duncan Booth

                          #13
                          Re: Why do this?

                          Lawrence D'Oliveiro <ldo@geek-central.gen.new _zealandwrote:
                          I use the above when I can, when I can't I fall back on
                          ><http://groups.google.c o.nz/groups?selm=efc 5b3$can$1@lust. ihug.co.nz>,
                          ><http://groups.google.c o.nz/groups?selm=efh n5v$fia$2@lust. ihug.co.nz>.
                          Yes, so you said, but you never came up with a convincing use case where
                          that function was better than using the parameterised queries.

                          Comment

                          • Lawrence D'Oliveiro

                            #14
                            Re: Why do this?

                            In message <Xns985755C7111 58duncanbooth@1 27.0.0.1>, Duncan Booth wrote:
                            Lawrence D'Oliveiro <ldo@geek-central.gen.new _zealandwrote:
                            >
                            >I use the above when I can, when I can't I fall back on
                            >><http://groups.google.c o.nz/groups?selm=efc 5b3$can$1@lust. ihug.co.nz>,
                            >><http://groups.google.c o.nz/groups?selm=efh n5v$fia$2@lust. ihug.co.nz>.
                            >
                            Yes, so you said, but you never came up with a convincing use case where
                            that function was better than using the parameterised queries.
                            First of all, the parametrization doesn't handle wildcards, as we discussed
                            previously.

                            Secondly, it's less convenient for cases where a dynamic query is being
                            built. I previously gave the SQLStringList example. If that's not enough,
                            here's another (simple) one:

                            Conditions = []
                            if Name != None :
                            Conditions.appe nd("name = %s" % SQLString(Name) )
                            #end if
                            if Address != None :
                            Conditions.appe nd("address = %s" % SQLString(Addre ss))
                            #end if
                            if PhoneNr != None :
                            Conditions.appe nd("phone_nr = %s" % SQLString(Phone Nr))
                            #end if
                            Query = "select * from table"
                            if len(Conditions) != 0 :
                            Query += " where " + " and ".join(Conditio ns)
                            #end if

                            Comment

                            • Fredrik Lundh

                              #15
                              Re: Why do this?

                              Lawrence D'Oliveiro wrote:
                              Secondly, it's less convenient for cases where a dynamic query is being
                              built. I previously gave the SQLStringList example. If that's not enough,
                              here's another (simple) one:
                              >
                              Conditions = []
                              if Name != None :
                              Conditions.appe nd("name = %s" % SQLString(Name) )
                              #end if
                              if Address != None :
                              Conditions.appe nd("address = %s" % SQLString(Addre ss))
                              #end if
                              if PhoneNr != None :
                              Conditions.appe nd("phone_nr = %s" % SQLString(Phone Nr))
                              #end if
                              Query = "select * from table"
                              if len(Conditions) != 0 :
                              Query += " where " + " and ".join(Conditio ns)
                              #end if
                              now that's some remarkably ugly Python code. it's well-known that people can
                              write Fortran in all languages, but writing Visual Basic in Python? (shudder)

                              here's a straight-forward and more efficient translation of that code:

                              where = []; params = []
                              if name is not None:
                              where.append("n ame=?"); params.append(n ame)
                              if address is not None:
                              where.append("a ddress=?"); params.append(a ddress)
                              if phone_nr is not None:
                              where.append("p hone_nr=?"); params.append(p hone_nr)
                              query = "select * from table"
                              if where:
                              query += " where " + " and ".join(wher e)
                              cursor.execute( query, tuple(params))

                              which works for all data types and without any error-prone explicit quotation non-
                              sense, and which can be trivially refactored into

                              where = []; params = []
                              def append(column, value):
                              if value is not None:
                              where.append(co lumn+"=?"); params.append(v alue)

                              append("name", name)
                              append("address ", address)
                              append("phone_n r", phone_nr)

                              query = "select * from table"
                              if where:
                              query += " where %s " + " and ".join(wher e)

                              cursor.execute( query, tuple(params))

                              which scales a lot better if when you're adding more fields, and which can be trivially
                              refactored into a full statement builder:

                              def select(table, **kw):
                              where = []; params = []
                              for column, value in kw.items():
                              if value is not None:
                              where.append(co lumn+"=?")
                              params.append(v alue)
                              query = "select * from " + table
                              if where:
                              query += " where " + " and ".join(wher e)
                              return query, tuple(params)

                              cursor.execute( *select("table" , name=name, address=address , phone_nr=phone_ nr))

                              where the "select" function can of course be put in a support library and reused every-
                              where you make simple selects; alternatively, you can wrap the whole thing into a some-
                              thing like

                              class where_statement :
                              def __init__(self, db):
                              self.where = []
                              self.params = []
                              if db.paramstyle == "qmark":
                              self.marker = "?"
                              if db.paramstyle == "format":
                              self.marker = "%s"
                              else:
                              raise NotImplementedE rror(
                              "unsupporte d parameter style: %r" % db.paramstyle
                              )
                              def __setitem__(sel f, column, value):
                              if value is not None:
                              self.where.appe nd(column+"="+s elf.marker)
                              self.params.app end(value)
                              def __str__(self):
                              if not self.where:
                              return ""
                              return " where " + " and ".join(self.whe re)
                              def __iter__(self):
                              return iter(self.param s)

                              where = where_statement (database)
                              where["name"] = name
                              where["address"] = address
                              where["phone_nr"] = phone_nr
                              cursor.execute( "select * from table" + str(where), tuple(where))

                              which actually protests if you run it on a database that doesn't use the same para-
                              meter markers, and can be trivially extended to support more DB-API variants.

                              or, of course, refactored into something that's even easier to use for the actual
                              use cases.

                              this is Python, after all, and as we all know, "the joy of coding Python should be
                              in seeing short, concise, readable classes that express a lot of action in a small
                              amount of clear code - not in reams of trivial code that bores the reader to death".

                              </F>



                              Comment

                              Working...