473,326 Members | 2,126 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

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 "+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
16 1135
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
"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
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
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
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
"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
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
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
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
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: James | last post by:
I have a from with 2 fields: Company & Name Depening which is completed, one of the following queries will be run: if($Company){ $query = "Select C* From tblsample Where ID = $Company...
5
by: Scott D | last post by:
I am trying to check and see if a field is posted or not, if not posted then assign $location which is a session variable to $location_other. If it is posted then just assign it to...
2
by: Nick | last post by:
Can someone please tell me how to access elements from a multiple selection list? From what ive read on other posts, this is correct. I keep getting an "Undefined variable" error though... Form...
2
by: Alexander Ross | last post by:
I have a variable ($x) that can have 50 different (string) values. I want to check for 7 of those values and do something based on it ... as I see it I have 2 options: 1) if (($x=="one") ||...
0
by: Dan Foley | last post by:
This script runs fine, but I'd like to know why it's so slow.. Thanks for any help out there on how i can make it faster (it might take up to 5 min to write these 3 export files whith 15 records...
5
by: Lee Redeem | last post by:
Hi there I've created abd uploaded this basic PHP script: <html> <head> <title>PHP Test</title> </head> <body> <H1 align="center">
5
by: christopher vogt | last post by:
Hi, i'm wondering if there is something like $this-> to call a method inside another method of the same class without using the classname in front. I actually use class TEST { function...
6
by: Phil Powell | last post by:
Ok guys, here we go again! SELECT s.nnet_produkt_storrelse_navn FROM nnet_produkt_storrelse s, nnet_produkt_varegruppe v, nnet_storrelse_varegruppe_assoc sv, nnet_produkt p WHERE...
1
by: Michel | last post by:
a site like this http://www.dvdzone2.com/dvd Can you make it in PHP and MySQL within 6 weeks? If so, send me your price 2 a r a (at) p a n d o r a . b e
11
by: Maciej Nadolski | last post by:
Hi! I can`t understand what php wants from me:( So: Cannot send session cache limiter - headers already sent (output started at /home/krecik/public_html/silnik.php:208) in...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.