Re: palindrome iteration

2010-09-14 Thread Bearophile
Baba:

 def i_palindrome(pal):
  while len(pal)1:
   if pal[0] == pal[-1]:
pal=pal[1:-1]
  return True

 print i_palindrome('annab')


In normal programming a significant percentage of the time is spent
debugging. Experience shows that even short functions may be buggy. If
you don't want to waste too much time debugging your code you need to
adopt a bit more rigorous approach to write programs. Learning to play
piano requires a lot of self-discipline, programming too needs some.


Ask yourself what are the exact purposes of your function/class/
program. And then define what are the correct outputs for all input
corner cases you are able to find. This is TDD, Thought-driven
development.

For this program, what's the right output for mixed case strings, for
empty strings, for input strings that contain many words with mixed
white space and punctuation between them, for unicode strings that
contain weird characters? Generally even simple functions may become
very complex if you want to manage even complex input cases.

You are free to ignore some of those inputs, to keep your code simple
enough, but it's usually better for your function to not just ignore
some inputs, but give some kind of error for the inputs you don't want
to consider.


Let's say you accept simple Unicode strings, you don't want to ignore
white space, an empty string is palindrome, text cases need to be
ignored.

I don't like Test-Driven development a lot because your most powerful
tool is your brainmind and not your unit-tests, but I like tests a
lot. So you need tests for this small function too. Here doctests are
enough. Your first test is better to fail, to be sure your doctest is
working:


def is_palindrome(text):

 is_palindrome(xy)
False

return True

if __name__ == __main__:
import doctest
doctest.testmod()
print Doctests done.


Code formatting and function and argument names are important to keep
code readable to yourself, improve its future maintenance, and reduce
the total bug count.

You may write this Python function in a high level style like this:

def is_palidrome(text):
ltext = text.lower()
return ltext == ltext[::-1]


But that doesn't teach you much programming, so for learning purposes
you may try to create one function in lower-level style (that also
doesn't stress the garbage collector, despite probably being overall
slower in Python). So we use iterative loops and single char tests.
But if you use a language as Scheme then a recursive solution too is a
normal option.

Now you need to invent the algorithm that solves your problem.
Inventing algorithms that solve your problems is an art that requires
training, experience and even ideas from this little book:
http://en.wikipedia.org/wiki/How_to_Solve_It

There are few ways to solve that problem, one possible way it to look
at the first and last char of the string (ignoring their case), if
they are different the given word is not palindrome, otherwise you
look at the second and penultimate char, and you perform similar
comparisons for all the char pairs. If your string length is odd there
is no need to test the last char, but if you want to test it with
itself because it keeps the code simpler it's not a problem.

To avoid bugs like ones in your code you may think about the loop
invariant and loop variant. This blog post shows an example to follow:
http://reprog.wordpress.com/2010/04/25/writing-correct-code-part-1-invariants-binary-search-part-4a/

I use two indexes, i and j, that move forward and backwards in sync
starting from the first and last char of the 'text' string. The
program stops when they are on the same char or they cross.

I have used an elaborate loop invariant, for this simple program it's
overkill, but shows how you may do it.


  i ==== j
 +--+--+--+--+--+--+--+--+--+
text |  |  |  |  |  |  |  |  |  |
 +--+--+--+--+--+--+--+--+--+
  0  1  2  3  4  5  6  7  8


def _is_palindrome_loop_invariant(i, j, length):
assert i = 0
assert i  length
assert j = 0
assert j  length
assert i = j
assert i == length - 1 - j
return True


def is_palindrome(text):

 is_palindrome()
True
 is_palindrome(1)
True
 is_palindrome(ux)
True
 is_palindrome(aa)
True
 is_palindrome(ab)
False
 is_palindrome(abc)
False
 [is_palindrome(s) for s in [abA, ABA, ABA]]
[True, True, True]
 is_palindrome(aibohphobia)
True
 is_palindrome(aibohphobia * 1000)
True
 is_palindrome(list(aibohphobia))
True
 is_palindrome([1, 2, 3])
Traceback (most recent call last):
  ...
AttributeError: 'int' object has no attribute 'lower'

n = len(text)
i = 0
j = n - 1
while i  j:
assert _is_palindrome_loop_invariant(i, j, n)
if text[i].lower() != text[j].lower():
return False
else:
i += 1
j -= 1
return True


if __name__ == 

Re: palindrome iteration

2010-09-13 Thread Cousin Stanley

 To deal with real palindromes such as, Madam, I'm Adam, 
 you should probably strip all spaces and punctuation:

 # untested
 pat = re.compile(r'[a-z]')
 def is_palindrome(s):
 letters = pat.findall(s.lower())
 return letters == reversed(letters)

  Using python 2.5 the above solution always returned False
  for me until the  reversed( letters )  iterator was explicitly
  coerced into a list  

return letters == list( reversed( letters ) ) 
 

-- 
Stanley C. Kitching
Human Being
Phoenix, Arizona

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-09-12 Thread Chris Colbert
;)

In [29]: s = 'bannab'

In [30]: a = np.frombuffer(s.lower(), dtype='uint8')

In [31]: np.all(a ==  a[::-1])
Out[31]: True

In [32]: s = 'bannac'

In [33]: a = np.frombuffer(s.lower(), dtype='uint8')

In [34]: np.all(a ==  a[::-1])
Out[34]: False
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-09-11 Thread Aahz
In article mailman.103.1282914852.29448.python-l...@python.org,
Dave Angel  da...@ieee.org wrote:

def is_palindrom(s):
s = s.lower()
return s == s[::-1]

To deal with real palindromes such as, Madam, I'm Adam, you should
probably strip all spaces and punctuation:

# untested
pat = re.compile(r'[a-z]')
def is_palindrome(s):
letters = pat.findall(s.lower())
return letters == reversed(letters)
-- 
Aahz (a...@pythoncraft.com)   * http://www.pythoncraft.com/

[on old computer technologies and programmers]  Fancy tail fins on a
brand new '59 Cadillac didn't mean throwing out a whole generation of
mechanics who started with model As.  --Andrew Dalke
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Josh English
This whole conversation got interesting, so I thought I'd run some
speed tests:

The code:
from timeit import Timer

def is_palindrome_recursive(s):
if len(s) = 1:
return True
if s[0] != s[-1]:
return False
else:
return is_palindrome(s[1:-1])

def is_palindrome_slice(s):
return s == s[::-1]

def is_palindrome_list(s):
l = list(s)
l.reverse()
return s == ''.join(l)

def is_palindrome_reversed(s):
return s == ''.join(reversed(s))

t = Timer(is_palindrome_recursive('madamimadam'), from __main__
import is_palindrome_recursive)
print is_palindrome_recursive, min(t.repeat())

t = Timer(is_palindrome_slice('madamimadam'), from __main__ import
is_palindrome_slice)
print is_palindrome_slice, min(t.repeat())

t = Timer(is_palindrome_list('madamimadam'), from __main__ import
is_palindrome_list)
print is_palindrome_list, min(t.repeat())

t = Timer(is_palindrome_reversed('madamimadam'), from __main__
import is_palindrome_reversed)
print is_palindrome_reversed, min(t.repeat())

The results:
is_palindrome_recursive 6.32680866827
is_palindrome_slice 1.23618350114
is_palindrome_list 4.60104846653
is_palindrome_reversed 5.99355296513

The slice method is uglier, I have to admit, but it's the fastest of
these four on my machine.

Josh

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Matteo Landi
Well, I tried the also the solution posted above (recursive w/o
slicing and iterative), and I discovered they were the slowest..

is_palindrome_recursive 2.68151649808
is_palindrome_slice 0.44510699381
is_palindrome_list 1.93861944217
is_palindrome_reversed 3.28969831976
is_palindrome_recursive_no_slicing 6.78929775328
is_palindrome_iterative 4.88826141315

Nothing to say about the iterative function, but the benchmark of the
recursive was unexpected, at least for my point of view: do you think
it is due to the try/except overhead?

On Sun, Aug 29, 2010 at 8:53 AM, Josh English
joshua.r.engl...@gmail.com wrote:
 This whole conversation got interesting, so I thought I'd run some
 speed tests:

 The code:
 from timeit import Timer

 def is_palindrome_recursive(s):
    if len(s) = 1:
        return True
    if s[0] != s[-1]:
        return False
    else:
        return is_palindrome(s[1:-1])

 def is_palindrome_slice(s):
    return s == s[::-1]

 def is_palindrome_list(s):
    l = list(s)
    l.reverse()
    return s == ''.join(l)

 def is_palindrome_reversed(s):
    return s == ''.join(reversed(s))

 t = Timer(is_palindrome_recursive('madamimadam'), from __main__
 import is_palindrome_recursive)
 print is_palindrome_recursive, min(t.repeat())

 t = Timer(is_palindrome_slice('madamimadam'), from __main__ import
 is_palindrome_slice)
 print is_palindrome_slice, min(t.repeat())

 t = Timer(is_palindrome_list('madamimadam'), from __main__ import
 is_palindrome_list)
 print is_palindrome_list, min(t.repeat())

 t = Timer(is_palindrome_reversed('madamimadam'), from __main__
 import is_palindrome_reversed)
 print is_palindrome_reversed, min(t.repeat())

 The results:
 is_palindrome_recursive 6.32680866827
 is_palindrome_slice 1.23618350114
 is_palindrome_list 4.60104846653
 is_palindrome_reversed 5.99355296513

 The slice method is uglier, I have to admit, but it's the fastest of
 these four on my machine.

 Josh

 --
 http://mail.python.org/mailman/listinfo/python-list




-- 
Matteo Landi
http://www.matteolandi.net/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Gregory Ewing

Steven D'Aprano wrote:

 I'm not entirely sure what the use-case for swapcase is.


Obviously it's for correcting things that were typed
in with tHE cAPS lOCK kEY oN bY mISTAKE. :-)

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Arnaud Delobelle
Matteo Landi landima...@gmail.com writes:

 Well, I tried the also the solution posted above (recursive w/o
 slicing and iterative), and I discovered they were the slowest..

 is_palindrome_recursive 2.68151649808
 is_palindrome_slice 0.44510699381
 is_palindrome_list 1.93861944217
 is_palindrome_reversed 3.28969831976
 is_palindrome_recursive_no_slicing 6.78929775328
 is_palindrome_iterative 4.88826141315

What are the last two functions?

I suggest another:

def is_palindrome(s):
return all(map(str.__eq__, s, reversed(s)))

:)

 Nothing to say about the iterative function, but the benchmark of the
 recursive was unexpected, at least for my point of view: do you think
 it is due to the try/except overhead?

 On Sun, Aug 29, 2010 at 8:53 AM, Josh English
 joshua.r.engl...@gmail.com wrote:
 This whole conversation got interesting, so I thought I'd run some
 speed tests:

 The code:
 from timeit import Timer

 def is_palindrome_recursive(s):
    if len(s) = 1:
        return True
    if s[0] != s[-1]:
        return False
    else:
        return is_palindrome(s[1:-1])

This should be return is_palindrome_recursive(s[1:-1]).  If this is
copy-pasted, then you may call a different is_palindrome function and
invalidate the timings!

[...]

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Matteo Landi
I thought they reached you. Here they are again:

def palindrome(str, i=0, j=-1):
   try:
   if str[i] == str[j]:
   return palindrome(str, i + 1, j - 1)
   return False
   except IndexError:
   return True

def palindrome(str, i=0, j=-1):
   try:
   while True:
   if str[i] != str[j]:
   return False
   i, j = i + 1, j - 1
   return True
   except IndexError:
   return True

On Sun, Aug 29, 2010 at 12:36 PM, Arnaud Delobelle
arno...@googlemail.com wrote:
 Matteo Landi landima...@gmail.com writes:

 Well, I tried the also the solution posted above (recursive w/o
 slicing and iterative), and I discovered they were the slowest..

 is_palindrome_recursive 2.68151649808
 is_palindrome_slice 0.44510699381
 is_palindrome_list 1.93861944217
 is_palindrome_reversed 3.28969831976
 is_palindrome_recursive_no_slicing 6.78929775328
 is_palindrome_iterative 4.88826141315

 What are the last two functions?

 I suggest another:

 def is_palindrome(s):
    return all(map(str.__eq__, s, reversed(s)))

 :)

 Nothing to say about the iterative function, but the benchmark of the
 recursive was unexpected, at least for my point of view: do you think
 it is due to the try/except overhead?

 On Sun, Aug 29, 2010 at 8:53 AM, Josh English
 joshua.r.engl...@gmail.com wrote:
 This whole conversation got interesting, so I thought I'd run some
 speed tests:

 The code:
 from timeit import Timer

 def is_palindrome_recursive(s):
    if len(s) = 1:
        return True
    if s[0] != s[-1]:
        return False
    else:
        return is_palindrome(s[1:-1])

 This should be return is_palindrome_recursive(s[1:-1]).  If this is
 copy-pasted, then you may call a different is_palindrome function and
 invalidate the timings!

 [...]

 --
 Arnaud
 --
 http://mail.python.org/mailman/listinfo/python-list




-- 
Matteo Landi
http://www.matteolandi.net/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread bruno.desthuilli...@gmail.com
On 27 août, 18:20, Mark Lawrence breamore...@yahoo.co.uk wrote:
 On 27/08/2010 15:43, Bruno Desthuilliers wrote:

  Dave Angel a écrit :
  (snip)

  or (untested)
  def is_palindrom(s):
  s = s.lower()
  return s == s[::-1]

  Right, go on, make me feel a bit more stupid :-/
  Who's next ?

 It could be worse, try responding to issue 9702. :)

lol ! Nice one, indeed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread bruno.desthuilli...@gmail.com
On 27 août, 20:05, Jussi Piitulainen jpiit...@ling.helsinki.fi  def
palindromep(s):
     return ( s ==  or
              ( s[0] == s[-1] and
                palindromep(s[1:-1]) ) )


I-can-write-lisp-in-any-language-p !-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread bruno.desthuilli...@gmail.com
On 29 août, 06:39, Gregory Ewing greg.ew...@canterbury.ac.nz wrote:
 Steven D'Aprano wrote:
   I'm not entirely sure what the use-case for swapcase is.

 Obviously it's for correcting things that were typed
 in with tHE cAPS lOCK kEY oN bY mISTAKE. :-)


+1 QOTW !-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Roy Smith
In article 8dunm7fv5...@mid.individual.net,
 Gregory Ewing greg.ew...@canterbury.ac.nz wrote:

 Steven D'Aprano wrote:
   I'm not entirely sure what the use-case for swapcase is.
 
 Obviously it's for correcting things that were typed
 in with tHE cAPS lOCK kEY oN bY mISTAKE. :-)

So it would seem (http://bugs.python.org/msg94026).

It's also useful for when you're looking for a crypto algorithm and 
rot13 is too strong.

It also provides a handy way to write is_alpha()...

def is_alpha(c):
return abs(ord(c) - ord(c.swapcase())) == 32

print is_alpha('a')
print is_alpha('A')
print is_alpha('1')
print is_alpha('')
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Josh English
I have no idea. That's a lower level of programming than I'm used to
dealing with.

Josh

(I also only tried the one value. Had I tried with other strings that
would fail the test, some
functions may have performed better.)

On Aug 29, 2:19 am, Matteo Landi landima...@gmail.com wrote:
 Well, I tried the also the solution posted above (recursive w/o
 slicing and iterative), and I discovered they were the slowest..

 is_palindrome_recursive 2.68151649808
 is_palindrome_slice 0.44510699381
 is_palindrome_list 1.93861944217
 is_palindrome_reversed 3.28969831976
 is_palindrome_recursive_no_slicing 6.78929775328
 is_palindrome_iterative 4.88826141315

 Nothing to say about the iterative function, but the benchmark of the
 recursive was unexpected, at least for my point of view: do you think
 it is due to the try/except overhead?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread MRAB

On 29/08/2010 21:34, Roy Smith wrote:

In article8dunm7fv5...@mid.individual.net,
  Gregory Ewinggreg.ew...@canterbury.ac.nz  wrote:


Steven D'Aprano wrote:

  I'm not entirely sure what the use-case for swapcase is.


Obviously it's for correcting things that were typed
in with tHE cAPS lOCK kEY oN bY mISTAKE. :-)


So it would seem (http://bugs.python.org/msg94026).

It's also useful for when you're looking for a crypto algorithm and
rot13 is too strong.

It also provides a handy way to write is_alpha()...

def is_alpha(c):
 return abs(ord(c) - ord(c.swapcase())) == 32

print is_alpha('a')
print is_alpha('A')
print is_alpha('1')
print is_alpha('')


How is that better than:

print 'a'.isalpha()
print 'A'.isalpha()
print '1'.isalpha()
print ''.isalpha()
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-29 Thread Roy Smith
In article mailman.174.1283114875.29448.python-l...@python.org,
 MRAB pyt...@mrabarnett.plus.com wrote:

 On 29/08/2010 21:34, Roy Smith wrote:
  In article8dunm7fv5...@mid.individual.net,
Gregory Ewinggreg.ew...@canterbury.ac.nz  wrote:
 
  Steven D'Aprano wrote:
I'm not entirely sure what the use-case for swapcase is.
 
  Obviously it's for correcting things that were typed
  in with tHE cAPS lOCK kEY oN bY mISTAKE. :-)
 
  So it would seem (http://bugs.python.org/msg94026).
 
  It's also useful for when you're looking for a crypto algorithm and
  rot13 is too strong.
 
  It also provides a handy way to write is_alpha()...
 
  def is_alpha(c):
   return abs(ord(c) - ord(c.swapcase())) == 32
 
  print is_alpha('a')
  print is_alpha('A')
  print is_alpha('1')
  print is_alpha('')
 
 How is that better than:
 
 print 'a'.isalpha()
 print 'A'.isalpha()
 print '1'.isalpha()
 print ''.isalpha()

Think of my post as an implemention of is_reader_humour_impaired().
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Jussi Piitulainen
Terry Reedy writes:
 On 8/27/2010 3:43 PM, Jussi Piitulainen wrote:
  Dave Angel writes:
 
  There could easily be a .reverse() method on strings. It would return
  the reversed string, like .swapcase() returns the swapcased string.
 
 Could be, but the main use case seems to be for palindrome testing ;-)
 Given that slicing and reversed() can do the same thing, the need is thin.

The need is quite thin, but immutability of strings is not an issue,
just like there can be .swapcase() though strings are immutable. That
is all I am saying above.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Jussi Piitulainen
Richard Arts writes:

 On Fri, Aug 27, 2010 at 10:51 PM, Jussi Piitulainen wrote:

 Meanwhile, I have decided to prefer this:

 def palindromep(s):
    def reversed(s):
        return s[::-1]
    return s == reversed(s)
 
 That seems like a bit of overkill... Why would you want to define a
 function in a function for something trivial like this? Just
 
 def palindrome(s):
 return s[::-1]
 
 will do fine.

I'm sure your version will do something just fine, but what that
something is, I can not tell. The body of your version is quite
obscure and does not seem to agree with the name of the function.

I find (s == reversed(s)) a clearer expression than (s == s[::-1]),
and I found a simple way to use my preferred expression.

 Of course, you can stick the inner function in a library somewhere
 if you like.

From my point of view, it would be an understatement to say that
setting up a library for this would be an overkill. A simple local
auxiliary function is nothing.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Ian

 On 27/08/2010 21:51, Jussi Piitulainen wrote:

Meanwhile, I have decided to prefer this:

def palindromep(s):
 def reversed(s):
 return s[::-1]
 return s == reversed(s)

I like this.

s[::-1] is obscure and non-obvious, especially to Python noobs.

This makes it clear what is going on and why at a cost of very little code.

Very helpful to the maintenance programming in 18 months time!

Regards

Ian
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Paul Rubin
Ian hobso...@gmaiil.com writes:
  On 27/08/2010 21:51, Jussi Piitulainen wrote:
 Meanwhile, I have decided to prefer this:

 def palindromep(s):
  def reversed(s):
  return s[::-1]
  return s == reversed(s)
 I like this.
 s[::-1] is obscure and non-obvious, especially to Python noobs.

Overriding the 'reversed' builtin even in an inner scope is a little bit
ugly.

If you don't mind some overhead, list(s)==list(reversed(s)) (using the
built-in reversed, not the special obscure one) is pretty clear.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Arnaud Delobelle
Paul Rubin no.em...@nospam.invalid writes:

 Ian hobso...@gmaiil.com writes:
  On 27/08/2010 21:51, Jussi Piitulainen wrote:
 Meanwhile, I have decided to prefer this:

 def palindromep(s):
  def reversed(s):
  return s[::-1]
  return s == reversed(s)
 I like this.
 s[::-1] is obscure and non-obvious, especially to Python noobs.

It may be non-obvious to newcomers, but it is quite a well known idiom.
Also, I an not aware that it is customary in python to name predicate
functions with a p suffix - Python is not Lisp!


 Overriding the 'reversed' builtin even in an inner scope is a little bit
 ugly.

I agree.

 If you don't mind some overhead, list(s)==list(reversed(s)) (using the
 built-in reversed, not the special obscure one) is pretty clear.

May I suggest a comment instead:

def ispalindrome(s):
# s[::-1] evaluates to the string s reversed
return s == s[::-1]

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Steven D'Aprano
On Sat, 28 Aug 2010 09:48:47 +0100, Ian wrote:

 On 27/08/2010 21:51, Jussi Piitulainen wrote:
 Meanwhile, I have decided to prefer this:

 def palindromep(s):
  def reversed(s):
  return s[::-1]
  return s == reversed(s)
 I like this.

It's silly, needlessly complicated, and inefficient. Why create a *one 
line* nested function that only gets called once? Every single time you 
call the function, it has to create the inner function again, then call 
it once, then throw it away. Admittedly Python does recreate the inner 
function from pre-compiled parts, which is quick, but still, it doesn't 
gain you anything that a simple comment wouldn't give:

def palindromep(s):
return s == s[::-1]  # Compare s to its reverse.


 s[::-1] is obscure and non-obvious, especially to Python noobs.

*Only* to Python noobs. Slicing is fundamental to Python, and using a 
slice of [::-1] to reverse something is a basic Python idiom.


 This makes it clear what is going on and why at a cost of very little
 code.
 
 Very helpful to the maintenance programming in 18 months time!

Only if writing three lines when one would do is your definition of 
helpful.




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Steven D'Aprano
On Sat, 28 Aug 2010 09:22:13 +0300, Jussi Piitulainen wrote:

 Terry Reedy writes:
 On 8/27/2010 3:43 PM, Jussi Piitulainen wrote:
  Dave Angel writes:
 
  There could easily be a .reverse() method on strings. It would return
  the reversed string, like .swapcase() returns the swapcased string.
 
 Could be, but the main use case seems to be for palindrome testing ;-)
 Given that slicing and reversed() can do the same thing, the need is
 thin.
 
 The need is quite thin, but immutability of strings is not an issue,
 just like there can be .swapcase() though strings are immutable. That is
 all I am saying above.


You're right, there could be a reversed() method for strings. There could 
also be a disemvowel method that removes vowels, a randomise method that 
shuffles the letters around, a studlycaps method that changes the case of 
each letter randomly, and a method to check that brackets () are well-
formed. They would all be useful to somebody. There are lots of different 
methods that strings could have. Where do you draw the line?

Not everything needs to be a built-in method. There is already a standard 
way to spell reverse a string:

astring[::-1]

If you don't like that, you can do this:

''.join(reversed(astring))


I don't object to a hypothetical reverse() method on strings, but the 
gain is minimal.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Jussi Piitulainen
Steven D'Aprano writes:
 On Sat, 28 Aug 2010 09:22:13 +0300, Jussi Piitulainen wrote:
 Terry Reedy writes:
 On 8/27/2010 3:43 PM, Jussi Piitulainen wrote:
  Dave Angel writes:
 
  There could easily be a .reverse() method on strings. It would return
  the reversed string, like .swapcase() returns the swapcased string.
 
 Could be, but the main use case seems to be for palindrome testing ;-)
 Given that slicing and reversed() can do the same thing, the need is
 thin.
 
 The need is quite thin, but immutability of strings is not an issue,
 just like there can be .swapcase() though strings are immutable. That is
 all I am saying above.
 
 You're right, there could be a reversed() method for strings. There
 could also be a disemvowel method that removes vowels, a randomise
 method that shuffles the letters around, a studlycaps method that
 changes the case of each letter randomly, and a method to check that
 brackets () are well- formed. They would all be useful to
 somebody. There are lots of different methods that strings could
 have. Where do you draw the line?

When I said that there could be such a method, I was merely objecting
to a statement, made in response to me, that there could not be such a
method because strings are immutable. You clearly agree with me that
that statement was not correct. Would you have let it stand if it was
made to you?

To answer your question, I don't see a real need for .reversed() in
strings, but I do think .reversed() would be much more useful than
.swapcase() which is in Python now and for which I see no use at all.

I have not proposed adding anything to Python. I have only asked if
there is any nicer expression for string reversal than [::-1] in
Python now, and corrected an incorrect statement that was made in
response to me that there could not be a string reversal method
because Python strings are immutable.

I am still not proposing that anything be added to Python.

I have not even criticized Python for not having a nicer expression
for string reversal than [::-1]. I have merely asked if there is one,
because I didn't know if there is one, and I have shown some snippets
of code to illustrate what I might mean by nicer. Someone even
understood me. (Thanks.)

I think I have received the answer to my question by now - that there
is no obviously nicer way, and all other string reversal expressions
require some extra cruft and overhead.

 Not everything needs to be a built-in method. There is already a
 standard way to spell reverse a string:
 
 astring[::-1]
 
 If you don't like that, you can do this:
 
 ''.join(reversed(astring))

I know. I agree. I was also shown a different way to test for
palindromicity,

list(s) == list(reversed(s))

which is quite nice apart from the overhead.

 I don't object to a hypothetical reverse() method on strings, but
 the gain is minimal.

I have not suggested that such a method should be added to the
language. I merely corrected a statement that there could not be such
a method because strings are immutable. I would not have bothered to
do even that if that incorrect statement had not been made in response
to my own post.

I agree that the gain would be minimal. There is no harm in the method
either, so I would not object to it if somebody were to propose its
addition, but just to clarify my position: I have not proposed it.

Hope this helps.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Jussi Piitulainen
Arnaud Delobelle writes:

 Also, I an not aware that it is customary in python to name
 predicate functions with a p suffix - Python is not Lisp!

Just to clarify my position: I did not mean to imply that names like
palindromep might be customary in Python - clearly they are not - and
I am quite aware that Python is not Lisp.

My background is elsewhere, I was not paying particular attention to
the name at all, and I just could not be bothered to look up what
implications any of palindrome, palindromic, ispalindrome,
is_palindrome, isPalindrome, has_palindrome_nature, check_palindrome
and so on might have in Python.

Perhaps I should have used a neutral name like f or test or so, but it
did not occur to me at the time.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Jussi Piitulainen
Paul Rubin writes:
 Ian writes:
   On 27/08/2010 21:51, Jussi Piitulainen wrote:
  Meanwhile, I have decided to prefer this:
 
  def palindromep(s):
   def reversed(s):
   return s[::-1]
   return s == reversed(s)
  I like this.
  s[::-1] is obscure and non-obvious, especially to Python noobs.
 
 Overriding the 'reversed' builtin even in an inner scope is a little
 bit ugly.
 
 If you don't mind some overhead, list(s)==list(reversed(s)) (using
 the built-in reversed, not the special obscure one) is pretty clear.

Thanks for that. I'm beginning to like it - not its overhead but
certainly its natural clarity. It wins over ''.join(reversed(s))
easily, in my eyes.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Jon Clements
On Aug 28, 11:55 am, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 On Sat, 28 Aug 2010 09:22:13 +0300, Jussi Piitulainen wrote:
  Terry Reedy writes:
  On 8/27/2010 3:43 PM, Jussi Piitulainen wrote:
   Dave Angel writes:

[snip]
 Not everything needs to be a built-in method. There is already a standard
 way to spell reverse a string:

 astring[::-1]

 If you don't like that, you can do this:

 ''.join(reversed(astring))

I've had to debug code that assumed str(reversed('abc')) == 'cba'
 str(reversed('abc'))
'reversed object at 0xa66f78c'

So, a str doesn't construct like tuple/list...it's a call to
__str__().
It's designated as a friendly print out (that's my phrasing).

 list('abc')
['a', 'b', 'c']

I s'pose str is special (2.6) in some way, but it doesn't parallel the
other builtins.

[Not at Terry / Steve intended -- just most relevant post to respond
to]

Jon.







-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread D'Arcy J.M. Cain
On Sat, 28 Aug 2010 09:48:47 +0100
Ian hobso...@gmaiil.com wrote:
  def palindromep(s):
   def reversed(s):
   return s[::-1]
   return s == reversed(s)
 I like this.
 
 s[::-1] is obscure and non-obvious, especially to Python noobs.
 
 This makes it clear what is going on and why at a cost of very little code.

It seems unnecessary to me.  Even if you can't figure it out through
simple inspection, it takes seconds to fire up Python and type print
'abc'[::-1] into it to see what that does. Then you have another tool
in your toolbox.

-- 
D'Arcy J.M. Cain da...@druid.net |  Democracy is three wolves
http://www.druid.net/darcy/|  and a sheep voting on
+1 416 425 1212 (DoD#0082)(eNTP)   |  what's for dinner.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Dave Angel

Jussi Piitulainen wrote:

Steven D'Aprano writes:
  

On Sat, 28 Aug 2010 09:22:13 +0300, Jussi Piitulainen wrote:


Terry Reedy writes:
  

On 8/27/2010 3:43 PM, Jussi Piitulainen wrote:


Dave Angel writes:
  
There could easily be a .reverse() method on strings. It would return

the reversed string, like .swapcase() returns the swapcased string.
  

Could be, but the main use case seems to be for palindrome testing ;-)
Given that slicing and reversed() can do the same thing, the need is
thin.


The need is quite thin, but immutability of strings is not an issue,
just like there can be .swapcase() though strings are immutable. That is
all I am saying above.
  

You're right, there could be a reversed() method for strings. There
could also be a disemvowel method that removes vowels, a randomise
method that shuffles the letters around, a studlycaps method that
changes the case of each letter randomly, and a method to check that
brackets () are well- formed. They would all be useful to
somebody. There are lots of different methods that strings could
have. Where do you draw the line?



When I said that there could be such a method, I was merely objecting
to a statement, made in response to me, that there could not be such a
method because strings are immutable. You clearly agree with me that
that statement was not correct. Would you have let it stand if it was
made to you?

  
Since you repeat that assertion three times, I figure you must think 
it's important.  And it was I who asserted that a reverse() method 
wouldn't be possible on an immutable object.  reverse() would reverse 
the characters in place, and return None.  At least it would if it tried 
to be at all consistent with the list, array, and audioop methods of the 
same name.


reversed() is certainly possible, and it'd make a new string with the 
reverse order of the original.



DaveA

--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-28 Thread Steven D'Aprano
On Sat, 28 Aug 2010 15:11:03 +0300, Jussi Piitulainen wrote:

[...]
 When I said that there could be such a method, I was merely objecting to
 a statement, made in response to me, that there could not be such a
 method because strings are immutable. You clearly agree with me that
 that statement was not correct. Would you have let it stand if it was
 made to you?

Ha ha, you're new here aren't you?

 To answer your question, I don't see a real need for .reversed() in
 strings, but I do think .reversed() would be much more useful than
 .swapcase() which is in Python now and for which I see no use at all.

It's hard to disagree with that. I'm not entirely sure what the use-case 
for swapcase is. It's not quite as specialised as sTUdlEycApS but not far 
off.


[...]
 I agree that the gain would be minimal. There is no harm in the method
 either, so I would not object to it if somebody were to propose its
 addition, but just to clarify my position: I have not proposed it.

Then we are in agreement :)

I think the only thing we disagree on is that I think [::-1] is a 
perfectly nice expression for reversal, while you don't. True, it's not 
entirely intuitive to newbies, or self-documenting, you need to learn 
slicing to understand it. But then, if you were Dutch and had not learned 
English, you would probably be looking for a method called omgekeerde and 
would find reverse equally unintuitive.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


palindrome iteration

2010-08-27 Thread Baba
level: beginner

the following code looks ok to me but it doesn't work. I would like
some hints as to where my reasoning / thought goes wrong

def i_palindrome(pal):
 while len(pal)1:
  if pal[0] == pal[-1]:
   pal=pal[1:-1]
 return True

print i_palindrome('annab')


my reasoning:
- i check the length of the string: if  1 continue
- i check first and last char: if they are equal continue
- create a new, shorter string starting at index 1 and ending at
second last index (up to but not including index-1
-restart the while loop as long as length of string is  1
- exiting this loop means all compared chars were identical hence it
is a palindrome and i return True

tnx
Baba
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Xavier Ho
One possible reason I can think of -
- exiting this loop means all compared chars were identical hence it
is a palindrome and i return True

is probably incorrect reasoning. Think again.

Also, you may consider posting your code in a way that preserves the
whitespace characters.

Cheers,
Xav

On 27 August 2010 18:53, Baba raoul...@gmail.com wrote:

 level: beginner

 the following code looks ok to me but it doesn't work. I would like
 some hints as to where my reasoning / thought goes wrong

 def i_palindrome(pal):
  while len(pal)1:
  if pal[0] == pal[-1]:
   pal=pal[1:-1]
  return True

 print i_palindrome('annab')


 my reasoning:
 - i check the length of the string: if  1 continue
 - i check first and last char: if they are equal continue
 - create a new, shorter string starting at index 1 and ending at
 second last index (up to but not including index-1
 -restart the while loop as long as length of string is  1
 - exiting this loop means all compared chars were identical hence it
 is a palindrome and i return True

 tnx
 Baba
 --
 http://mail.python.org/mailman/listinfo/python-list

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Peter Otten
Baba wrote:

 level: beginner
 
 the following code looks ok to me but it doesn't work. I would like
 some hints as to where my reasoning / thought goes wrong
 
 def i_palindrome(pal):
  while len(pal)1:
   if pal[0] == pal[-1]:
pal=pal[1:-1]
  return True

Do yourself a favour and use 4-space indent. That makes the structure of 
your code more obvious.
 
 print i_palindrome('annab')
 
 
 my reasoning:
 - i check the length of the string: if  1 continue
 - i check first and last char: if they are equal continue
 - create a new, shorter string starting at index 1 and ending at
 second last index (up to but not including index-1
 -restart the while loop as long as length of string is  1
 - exiting this loop means all compared chars were identical hence it
 is a palindrome and i return True

If the test pal[0] == pal[-1] fails, i. e. the two compared characters 
differ, what happens?

More generally, if pal is not a palindrome, can your function ever return 
False? If not, at what point should it?

Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Bruno Desthuilliers

Baba a écrit :

level: beginner

the following code looks ok to me but it doesn't work.


doesn't work is about the most useless description of a problem. 
Please specify what you expected and what actually happens.



I would like
some hints as to where my reasoning / thought goes wrong

def i_palindrome(pal):
 while len(pal)1:
  if pal[0] == pal[-1]:
   pal=pal[1:-1]


Can you explain what happens if pal[0] != pal[-1] ? (answer below)


 return True



print i_palindrome('annab')


And then you go in an infinite loop !-)



my reasoning:
- i check the length of the string: if  1 continue
- i check first and last char: if they are equal continue
- create a new, shorter string starting at index 1 and ending at
second last index (up to but not including index-1
-restart the while loop as long as length of string is  1
- exiting this loop means all compared chars were identical hence it
is a palindrome and i return True


Your problem is that when first and last char are not equal, you don't 
exit the while loop. You need a return False somewhere here, ie:


def is_palindrom(pal):
  while len(pal)1:
# NB : inverted the test here to make exit more obvious
if pal[0] != pal[-1]:
  return False
pal=pal[1:-1]
  return True


Now there is another solution. A palindrom is made of two symetric 
halves, with (odd len) or without (even len) a single char between the 
symetric halves, ie :


* odd : ABCBA ('AB' + 'C' + 'BA')
* even : ABCCBA ('ABC' + 'CBA')

So you just have to extract the symetric halves, reverse one, and 
compare both (case insensitive compare while we're at it). Here's a 
possible (and a bit tricky) Python 2.x implementation:


def is_palindrom(s):
s = s.lower()
slen = len(s)
until = slen / 2 # Python 2x integer division
offset = int(not(slen % 2))
runtil = until - offset
return s[0:until] == s[-1:runtil:-1]


--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Richard Arts
 Now there is another solution. A palindrom is made of two symetric halves,
 with (odd len) or without (even len) a single char between the symetric
 halves, ie :

 * odd : ABCBA ('AB' + 'C' + 'BA')
 * even : ABCCBA ('ABC' + 'CBA')

 So you just have to extract the symetric halves, reverse one, and compare
 both (case insensitive compare while we're at it).

Yes, this is a correct observation, but it is not necessary to compare
the halves; Simply compare the complete string with its reverse. If
they match, it is a palindrome.

 Here's a possible (and a
 bit tricky) Python 2.x implementation:

 def is_palindrom(s):
    s = s.lower()
    slen = len(s)
    until = slen / 2 # Python 2x integer division
    offset = int(not(slen % 2))
    runtil = until - offset
    return s[0:until] == s[-1:runtil:-1]



At first glance this seems to be correct, but it is tricky indeed.
Particularly the assignment of the offset variable, casting a bool to
an integer of a negated expression. Given that Baba notes that this is
a beginners level query, it wouldn't have hurt to be a little bit more
verbose there.

Richard
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Matteo Landi
 Yes, this is a correct observation, but it is not necessary to compare
 the halves; Simply compare the complete string with its reverse. If
 they match, it is a palindrome.

I've always used to implement the is_palindrome function as you
suggest, i.e. comparing the original string with the reverse one, but
while reading, I tought about a imho nicer version which prevent from
creating another string.

Here are both the recursive/iterative versions of the function:

def palindrome(str, i=0, j=-1):
try:
if str[i] == str[j]:
return palindrome(str, i + 1, j - 1)
return False
except IndexError:
return True

def palindrome(str, i=0, j=-1):
try:
while True:
if str[i] != str[j]:
return False
i, j = i + 1, j - 1
return True
except IndexError:
return True

Regards,
Matteo


 Here's a possible (and a
 bit tricky) Python 2.x implementation:

 def is_palindrom(s):
    s = s.lower()
    slen = len(s)
    until = slen / 2 # Python 2x integer division
    offset = int(not(slen % 2))
    runtil = until - offset
    return s[0:until] == s[-1:runtil:-1]



 At first glance this seems to be correct, but it is tricky indeed.
 Particularly the assignment of the offset variable, casting a bool to
 an integer of a negated expression. Given that Baba notes that this is
 a beginners level query, it wouldn't have hurt to be a little bit more
 verbose there.

 Richard
 --
 http://mail.python.org/mailman/listinfo/python-list




-- 
Matteo Landi
http://www.matteolandi.net/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Dave Angel



Bruno Desthuilliers wrote:
div class=moz-text-flowed style=font-family: -moz-fixedBaba a 
écrit :

level: beginner

the following code looks ok to me but it doesn't work.


doesn't work is about the most useless description of a problem. 
Please specify what you expected and what actually happens.



I would like
some hints as to where my reasoning / thought goes wrong

def i_palindrome(pal):
 while len(pal)1:
  if pal[0] == pal[-1]:
   pal=pal[1:-1]


Can you explain what happens if pal[0] != pal[-1] ? (answer below)


 return True



print i_palindrome('annab')


And then you go in an infinite loop !-)



my reasoning:
- i check the length of the string: if  1 continue
- i check first and last char: if they are equal continue
- create a new, shorter string starting at index 1 and ending at
second last index (up to but not including index-1
-restart the while loop as long as length of string is  1
- exiting this loop means all compared chars were identical hence it
is a palindrome and i return True


Your problem is that when first and last char are not equal, you don't 
exit the while loop. You need a return False somewhere here, ie:


def is_palindrom(pal):
  while len(pal)1:
# NB : inverted the test here to make exit more obvious
if pal[0] != pal[-1]:
  return False
pal=pal[1:-1]
  return True


Now there is another solution. A palindrom is made of two symetric 
halves, with (odd len) or without (even len) a single char between the 
symetric halves, ie :


* odd : ABCBA ('AB' + 'C' + 'BA')
* even : ABCCBA ('ABC' + 'CBA')

So you just have to extract the symetric halves, reverse one, and 
compare both (case insensitive compare while we're at it). Here's a 
possible (and a bit tricky) Python 2.x implementation:


def is_palindrom(s):
s = s.lower()
slen = len(s)
until = slen / 2 # Python 2x integer division
offset = int(not(slen % 2))
runtil = until - offset
return s[0:until] == s[-1:runtil:-1]



or  (untested)
def is_palindrom(s):
   s = s.lower()
   return s == s[::-1]

DaveA
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Bruno Desthuilliers

Richard Arts a écrit :

Now there is another solution. A palindrom is made of two symetric halves,
with (odd len) or without (even len) a single char between the symetric
halves, ie :

* odd : ABCBA ('AB' + 'C' + 'BA')
* even : ABCCBA ('ABC' + 'CBA')

So you just have to extract the symetric halves, reverse one, and compare
both (case insensitive compare while we're at it).


Yes, this is a correct observation, but it is not necessary to compare
the halves; Simply compare the complete string with its reverse. If
they match, it is a palindrome.


Duh :(

I kinda feel stupid right now, thanks Richard :-/


--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Bruno Desthuilliers

Dave Angel a écrit :
(snip)


or  (untested)
def is_palindrom(s):
   s = s.lower()
   return s == s[::-1]




Right, go on, make me feel a bit more stupid :-/
Who's next ?
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread D'Arcy J.M. Cain
On Fri, 27 Aug 2010 11:49:42 -0400
D'Arcy J.M. Cain da...@druid.net wrote:
 is_palindrome = lambda x: x == x.lower()[::-1]

Oops.  Simple and wrong.

is_palindrome = lambda x: x.lower() == x.lower()[::-1]

-- 
D'Arcy J.M. Cain da...@druid.net |  Democracy is three wolves
http://www.druid.net/darcy/|  and a sheep voting on
+1 416 425 1212 (DoD#0082)(eNTP)   |  what's for dinner.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Mark Lawrence

On 27/08/2010 15:43, Bruno Desthuilliers wrote:

Dave Angel a écrit :
(snip)


or (untested)
def is_palindrom(s):
s = s.lower()
return s == s[::-1]




Right, go on, make me feel a bit more stupid :-/
Who's next ?


It could be worse, try responding to issue 9702. :)

Cheers.

Mark Lawrence.

--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Ian

 On 27/08/2010 09:53, Baba wrote:

level: beginner

the following code looks ok to me but it doesn't work. I would like
some hints as to where my reasoning / thought goes wrong

def i_palindrome(pal):
  while len(pal)1:
   if pal[0] == pal[-1]:
pal=pal[1:-1]
  return True

print i_palindrome('annab')


If you want to or must  do it recursively.
(Shown in pseudo code to make the logic clearer)

def isPalindrome(pal)
''' test pal (a list) is a palindrome '''
if length of pal = 1
return True # all one letter strings are palindromes.
if first equals last
# pal could be a palindrome
#  so test inner part
p = pal with first and last removed
return  isPalendrome(p)   #  and true - implied
else
return False # it can't be

Of course, the simpler way is to use the definition of a Palindrome as 
the same backwards and forwards.


def isPalindrome(pal)
return pal == pal.reverse



--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread D'Arcy J.M. Cain
On Fri, 27 Aug 2010 16:43:16 +0200
Bruno Desthuilliers bruno.42.desthuilli...@websiteburo.invalid wrote:
 Dave Angel a écrit :
  def is_palindrom(s):
 s = s.lower()
 return s == s[::-1]
 
 
 Right, go on, make me feel a bit more stupid :-/
 Who's next ?

How about a one-liner?

is_palindrome = lambda x: len(x) 0 and x == x.lower()[::-1]

Note that the above assumes that single characters are palindromes but
empty strings are not.  I'm not 100% sure that that last is true.  If
not then this can be simplified.

is_palindrome = lambda x: x == x.lower()[::-1]

-- 
D'Arcy J.M. Cain da...@druid.net |  Democracy is three wolves
http://www.druid.net/darcy/|  and a sheep voting on
+1 416 425 1212 (DoD#0082)(eNTP)   |  what's for dinner.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread MRAB

On 27/08/2010 17:20, Mark Lawrence wrote:

On 27/08/2010 15:43, Bruno Desthuilliers wrote:

Dave Angel a écrit :
(snip)


or (untested)
def is_palindrom(s):
s = s.lower()
return s == s[::-1]




Right, go on, make me feel a bit more stupid :-/
Who's next ?


It could be worse, try responding to issue 9702. :)


As a wise man once said: Ay caramba! :-)
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Mark Lawrence

On 27/08/2010 17:53, MRAB wrote:

On 27/08/2010 17:20, Mark Lawrence wrote:

On 27/08/2010 15:43, Bruno Desthuilliers wrote:

Dave Angel a écrit :
(snip)


or (untested)
def is_palindrom(s):
s = s.lower()
return s == s[::-1]




Right, go on, make me feel a bit more stupid :-/
Who's next ?


It could be worse, try responding to issue 9702. :)


As a wise man once said: Ay caramba! :-)


Isn't that a syntax error?  Shouldn't it be  ¡Ay caramba! :)

Cheers.

Mark Lawrence.

--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Terry Reedy

On 8/27/2010 4:53 AM, Baba wrote:

level: beginner

the following code looks ok to me but it doesn't work. I would like
some hints as to where my reasoning / thought goes wrong

def i_palindrome(pal):
  while len(pal)1:
   if pal[0] == pal[-1]:
pal=pal[1:-1]
  return True

print i_palindrome('annab')


General practical debugging procedurewhen logic inspection fails: insert 
print statements at key points.


In the case above, put print pal before the if statement and you 
should see the problem. And/or print 'equal' after the if.


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread MRAB

On 27/08/2010 18:28, Mark Lawrence wrote:

On 27/08/2010 17:53, MRAB wrote:

On 27/08/2010 17:20, Mark Lawrence wrote:

On 27/08/2010 15:43, Bruno Desthuilliers wrote:

Dave Angel a écrit :
(snip)


or (untested)
def is_palindrom(s):
s = s.lower()
return s == s[::-1]




Right, go on, make me feel a bit more stupid :-/
Who's next ?


It could be worse, try responding to issue 9702. :)


As a wise man once said: Ay caramba! :-)


Isn't that a syntax error? Shouldn't it be ¡Ay caramba! :)


I stand (OK, sit) corrected.
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Jussi Piitulainen
Ian writes:

 If you want to or must  do it recursively.
 (Shown in pseudo code to make the logic clearer)
 
 def isPalindrome(pal)
  ''' test pal (a list) is a palindrome '''
  if length of pal = 1
  return True # all one letter strings are palindromes.
  if first equals last
  # pal could be a palindrome
  #  so test inner part
  p = pal with first and last removed
  return  isPalendrome(p)   #  and true - implied
  else
  return False # it can't be

def palindromep(s): 
return ( s ==  or
 ( s[0] == s[-1] and
   palindromep(s[1:-1]) ) )

 Of course, the simpler way is to use the definition of a Palindrome
 as the same backwards and forwards.
 
 def isPalindrome(pal)
  return pal == pal.reverse

Agreed. But is there any nicer way to spell .reverse than [::-1] in
Python? There is .swapcase() but no .reverse(), right?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Dave Angel



Jussi Piitulainen wrote:

Ian writes:

  

If you want to or must  do it recursively.
(Shown in pseudo code to make the logic clearer)

def isPalindrome(pal)
 ''' test pal (a list) is a palindrome '''
 if length of pal = 1
 return True # all one letter strings are palindromes.
 if first equals last
 # pal could be a palindrome
 #  so test inner part
 p = pal with first and last removed
 return  isPalendrome(p)   #  and true - implied
 else
 return False # it can't be



def palindromep(s): 
return ( s ==  or

 ( s[0] == s[-1] and
   palindromep(s[1:-1]) ) )

  

Of course, the simpler way is to use the definition of a Palindrome
as the same backwards and forwards.

def isPalindrome(pal)
 return pal == pal.reverse



Agreed. But is there any nicer way to spell .reverse than [::-1] in
Python? There is .swapcase() but no .reverse(), right?

  
There can't be a .reverse() method on string, because it's immutable.  
You could use


   .join(reversed(pal))

but I'd prefer  pal[::-1]  as I said earlier.

DaveA

--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread D'Arcy J.M. Cain
On Fri, 27 Aug 2010 12:02:39 -0400
D'Arcy J.M. Cain da...@druid.net wrote:
 On Fri, 27 Aug 2010 11:49:42 -0400
 D'Arcy J.M. Cain da...@druid.net wrote:
  is_palindrome = lambda x: x == x.lower()[::-1]
 
 Oops.  Simple and wrong.
 
 is_palindrome = lambda x: x.lower() == x.lower()[::-1]

slightly more efficient I think.

is_palindrome = lambda y: (lambda x: x == x[::-1])(y.lower())

-- 
D'Arcy J.M. Cain da...@druid.net |  Democracy is three wolves
http://www.druid.net/darcy/|  and a sheep voting on
+1 416 425 1212 (DoD#0082)(eNTP)   |  what's for dinner.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Jussi Piitulainen
Dave Angel writes:

 Jussi Piitulainen wrote:
 Ian writes:
 Of course, the simpler way is to use the definition of a
 Palindrome as the same backwards and forwards.

 def isPalindrome(pal)
  return pal == pal.reverse

 Agreed. But is there any nicer way to spell .reverse than [::-1] in
 Python? There is .swapcase() but no .reverse(), right?

 There can't be a .reverse() method on string, because it's
 immutable. You could use
 
 .join(reversed(pal))
 
 but I'd prefer  pal[::-1]  as I said earlier.

There could easily be a .reverse() method on strings. It would return
the reversed string, like .swapcase() returns the swapcased string.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread MRAB

On 27/08/2010 20:43, Jussi Piitulainen wrote:

Dave Angel writes:


Jussi Piitulainen wrote:

Ian writes:

Of course, the simpler way is to use the definition of a
Palindrome as the same backwards and forwards.

def isPalindrome(pal)
  return pal == pal.reverse


Agreed. But is there any nicer way to spell .reverse than [::-1] in
Python? There is .swapcase() but no .reverse(), right?


There can't be a .reverse() method on string, because it's
immutable. You could use

 .join(reversed(pal))

but I'd prefer  pal[::-1]  as I said earlier.


There could easily be a .reverse() method on strings. It would return
the reversed string, like .swapcase() returns the swapcased string.


Lists have a .reverse method, but it's an in-place reversal. In order
to reduce confusion, a string method which returned the string reversed
would be better called .reversed().
--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Jussi Piitulainen
MRAB writes:
 On 27/08/2010 20:43, Jussi Piitulainen wrote:
 Dave Angel writes:
 Jussi Piitulainen wrote:
 Agreed. But is there any nicer way to spell .reverse than [::-1]
 in Python? There is .swapcase() but no .reverse(), right?

 There can't be a .reverse() method on string, because it's
 immutable. You could use

  .join(reversed(pal))

 but I'd prefer  pal[::-1]  as I said earlier.

 There could easily be a .reverse() method on strings. It would
 return the reversed string, like .swapcase() returns the swapcased
 string.
 
 Lists have a .reverse method, but it's an in-place reversal. In
 order to reduce confusion, a string method which returned the string
 reversed would be better called .reversed().

Yes, agreed.

Meanwhile, I have decided to prefer this:

def palindromep(s):
def reversed(s):
return s[::-1]
return s == reversed(s)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Terry Reedy

On 8/27/2010 3:43 PM, Jussi Piitulainen wrote:

Dave Angel writes:



There could easily be a .reverse() method on strings. It would return
the reversed string, like .swapcase() returns the swapcased string.


Could be, but the main use case seems to be for palindrome testing ;-)
Given that slicing and reversed() can do the same thing, the need is thin.

--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Richard Arts
On Fri, Aug 27, 2010 at 10:51 PM, Jussi Piitulainen
jpiit...@ling.helsinki.fi wrote:
 MRAB writes:
 On 27/08/2010 20:43, Jussi Piitulainen wrote:
 Dave Angel writes:
 Jussi Piitulainen wrote:
 Agreed. But is there any nicer way to spell .reverse than [::-1]
 in Python? There is .swapcase() but no .reverse(), right?

 There can't be a .reverse() method on string, because it's
 immutable. You could use

      .join(reversed(pal))

 but I'd prefer  pal[::-1]  as I said earlier.

 There could easily be a .reverse() method on strings. It would
 return the reversed string, like .swapcase() returns the swapcased
 string.

 Lists have a .reverse method, but it's an in-place reversal. In
 order to reduce confusion, a string method which returned the string
 reversed would be better called .reversed().

 Yes, agreed.

 Meanwhile, I have decided to prefer this:

 def palindromep(s):
    def reversed(s):
        return s[::-1]
    return s == reversed(s)
 --
 http://mail.python.org/mailman/listinfo/python-list


That seems like a bit of overkill... Why would you want to define a
function in a function for something trivial like this? Just

def palindrome(s):
return s[::-1]

will do fine.

Of course, you can stick the inner function in a library somewhere if you like.

Regards,
Richard
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: palindrome iteration

2010-08-27 Thread Richard Arts
On Fri, Aug 27, 2010 at 11:47 PM, Richard Arts arts.rich...@gmail.com wrote:
 On Fri, Aug 27, 2010 at 10:51 PM, Jussi Piitulainen
 jpiit...@ling.helsinki.fi wrote:
 MRAB writes:
 On 27/08/2010 20:43, Jussi Piitulainen wrote:
 Dave Angel writes:
 Jussi Piitulainen wrote:
 Agreed. But is there any nicer way to spell .reverse than [::-1]
 in Python? There is .swapcase() but no .reverse(), right?

 There can't be a .reverse() method on string, because it's
 immutable. You could use

      .join(reversed(pal))

 but I'd prefer  pal[::-1]  as I said earlier.

 There could easily be a .reverse() method on strings. It would
 return the reversed string, like .swapcase() returns the swapcased
 string.

 Lists have a .reverse method, but it's an in-place reversal. In
 order to reduce confusion, a string method which returned the string
 reversed would be better called .reversed().

 Yes, agreed.

 Meanwhile, I have decided to prefer this:

 def palindromep(s):
    def reversed(s):
        return s[::-1]
    return s == reversed(s)
 --
 http://mail.python.org/mailman/listinfo/python-list


 That seems like a bit of overkill... Why would you want to define a
 function in a function for something trivial like this? Just

 def palindrome(s):
    return s[::-1]

 will do fine.

 Of course, you can stick the inner function in a library somewhere if you 
 like.

 Regards,
 Richard


Duh, of course I mean

def palindrome(s):
   return s == s[::-1]

I'm sorry.

Richard
-- 
http://mail.python.org/mailman/listinfo/python-list