By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,550 Members | 1,189 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,550 IT Pros & Developers. It's quick & easy.

Why do this?

P: n/a
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 "+furryanimal

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
http://www.digica.com

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
Oct 5 '06 #1
Share this Question
Share on Google+
16 Replies


P: n/a
In <ma***************************************@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 "+furryanimal

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
Oct 5 '06 #2

P: n/a
"Matthew Warren" <Ma************@Digica.comwrote:
Print "There are "+number+" ways to skin a "+furryanimal

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+"ways to skin a"+furryanimal

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(number)+" ways to skin a "+furryanimal

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.
Oct 5 '06 #3

P: n/a
Duncan Booth wrote:
print "There are"+number+"ways to skin a"+furryanimal

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)
Oct 5 '06 #4

P: n/a
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
Oct 5 '06 #5

P: n/a
On 10/6/06, Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On Thu, 5 Oct 2006 11:28:08 +0100, "Matthew Warren"
<Ma************@Digica.comdeclaimed the following in comp.lang.python:

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
Oct 6 '06 #6

P: n/a
"Dennis Lee Bieber" <wl*****@ix.netcom.comwrote:
On Thu, 5 Oct 2006 11:28:08 +0100, "Matthew Warren"
<Ma************@Digica.comdeclaimed the following in comp.lang.python:

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

yes

- Hendrik
Oct 6 '06 #7

P: n/a
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 "+furryanimal

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
http://www.digica.com

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
Oct 6 '06 #8

P: n/a
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_select_sql % (id_foo, value_bar, ...)
cursor.execute(sql)

inside the body of a function (or a class method), where
a_complex_select_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é)
Oct 6 '06 #9

P: n/a
Corrado Gioannini <gi***@nekhem.comwrote:
I often do things like this:

sql = a_complex_select_sql % (id_foo, value_bar, ...)
cursor.execute(sql)

inside the body of a function (or a class method), where
a_complex_select_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_select_sql, (id_foo, value_bar, ...))

instead.
Oct 6 '06 #10

P: n/a
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_select_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)

Oct 6 '06 #11

P: n/a
In message <Xn*************************@127.0.0.1>, Duncan Booth wrote:
Corrado Gioannini <gi***@nekhem.comwrote:
>I often do things like this:

sql = a_complex_select_sql % (id_foo, value_bar, ...)
cursor.execute(sql)

inside the body of a function (or a class method), where
a_complex_select_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_select_sql, (id_foo, value_bar, ...))

instead.
I use the above when I can, when I can't I fall back on
<http://groups.google.co.nz/gr**********************@lust.ihug.co.nz>,
<http://groups.google.co.nz/gr**********************@lust.ihug.co.nz>.
Oct 9 '06 #12

P: n/a
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrote:
I use the above when I can, when I can't I fall back on
<http://groups.google.co.nz/gr**********************@lust.ihug.co.nz>,
<http://groups.google.co.nz/gr**********************@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.
Oct 9 '06 #13

P: n/a
In message <Xn*************************@127.0.0.1>, Duncan Booth wrote:
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrote:
>I use the above when I can, when I can't I fall back on
<http://groups.google.co.nz/gr**********************@lust.ihug.co.nz>,
<http://groups.google.co.nz/gr**********************@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.append("name = %s" % SQLString(Name))
#end if
if Address != None :
Conditions.append("address = %s" % SQLString(Address))
#end if
if PhoneNr != None :
Conditions.append("phone_nr = %s" % SQLString(PhoneNr))
#end if
Query = "select * from table"
if len(Conditions) != 0 :
Query += " where " + " and ".join(Conditions)
#end if
Oct 9 '06 #14

P: n/a
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.append("name = %s" % SQLString(Name))
#end if
if Address != None :
Conditions.append("address = %s" % SQLString(Address))
#end if
if PhoneNr != None :
Conditions.append("phone_nr = %s" % SQLString(PhoneNr))
#end if
Query = "select * from table"
if len(Conditions) != 0 :
Query += " where " + " and ".join(Conditions)
#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("name=?"); params.append(name)
if address is not None:
where.append("address=?"); params.append(address)
if phone_nr is not None:
where.append("phone_nr=?"); params.append(phone_nr)
query = "select * from table"
if where:
query += " where " + " and ".join(where)
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(column+"=?"); params.append(value)

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

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

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(column+"=?")
params.append(value)
query = "select * from " + table
if where:
query += " where " + " and ".join(where)
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 NotImplementedError(
"unsupported parameter style: %r" % db.paramstyle
)
def __setitem__(self, column, value):
if value is not None:
self.where.append(column+"="+self.marker)
self.params.append(value)
def __str__(self):
if not self.where:
return ""
return " where " + " and ".join(self.where)
def __iter__(self):
return iter(self.params)

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>

Oct 9 '06 #15

P: n/a
Fredrik Lundh wrote:
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.append("name = %s" % SQLString(Name))
#end if
if Address != None :
Conditions.append("address = %s" % SQLString(Address))
#end if
if PhoneNr != None :
Conditions.append("phone_nr = %s" % SQLString(PhoneNr))
#end if
Query = "select * from table"
if len(Conditions) != 0 :
Query += " where " + " and ".join(Conditions)
#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)
[...]
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".
I especially liked the #end if comments after the single guarded lines.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 9 '06 #16

P: n/a
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrote:
>>I use the above when I can, when I can't I fall back on
<http://groups.google.co.nz/gr**********************@lust.ihug.co.nz>,
<http://groups.google.co.nz/gr**********************@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.
No, your separate function for escaping wildcards is fine, and works in
conjunction with parameterized queries. It's the SQLString function you
never managed to justify.
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:
See Frederik's excellent response on this point.
Oct 9 '06 #17

This discussion thread is closed

Replies have been disabled for this discussion.