Re: how to convert string function to string method?

2009-12-08 Thread Bruno Desthuilliers

Dr. Phillip M. Feldman a écrit :

Bruno- You've made some excellent suggestions, and I'm always grateful for
the opportunity to learn.


Glad to know I've been of any help !-)


 My revised code appears below.  Philllip

def strip_pairs(s, open='([{\'"', close=')]}\'"'):
   """
   OVERVIEW

   This function strips matching pairs of characters from the beginning and
   end of the input string `s`.  If `s` begins with a character in `open`
and
   ends with the corresponding character in `close` (see below), both are
   removed from the string. This process continues until no further matching
   pairs can be removed.

   INPUTS

   `open` and `close`: These arguments, which must be equal-length strings,
   specify matching start-of-scope and end-of-scope characters.  The same
   character may appear in both `open` and `close`; single and double quotes
   conventionally match themselves.  By default, `open` contains a left
   parenthesis, left square bracket, left curly bracket, single quote, and
   double quote), and `close` contains the corresponding characters."""

   if not isinstance(s,(str,unicode)):
  raise TypeError, '`s` must be a string (str or unicode).'


Might be a bit more helpful (for the programmer using your function) to 
specify what 's' actually is. Also, the recommanded way to raise 
exceptions is to use the 'call' syntax, ie:



if not isinstance(s,(str,unicode)):
   raise TypeError("'s' must be a str or unicode, got '%s'" % type(s))



   if not isinstance(open,(str,unicode)) or not
isinstance(close,(str,unicode)):
  raise TypeError, '`open` and `close` must be strings (str or
unicode).'


Mmmm I still wonder why you wouldn't accept a tuple or list of chars 
here.



   if len(open) != len(close): raise ValueError, \
 '\'open\' and \'close\' arguments must be equal-length strings.'

   while len(s) >= 2:

  # Check whether first character of `s` is in `open`:
  i= open.find(s[0])

  # If `s` does not begin with a character from `open`, there are no
more
  # pairs to be stripped:
  if i == -1: break


wrt/ readability, it might be better to put the break statement on it's 
own line - but you can probably count this one as more of a personnal 
preference than a guideline !-)



  # If `s` does not begin and end with matching characters, there are no
  # more pairs to be stripped:
  if s[-1] != close[i]: break

  # Strip the first and last character from `s`:
  s= s[1:-1]
   return s





Steven (D'Aprano) posted a possibly interesting implementation. Might be 
worth timeit'ing both.



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


Re: how to convert string function to string method?

2009-12-07 Thread Dr. Phillip M. Feldman

Bruno- You've made some excellent suggestions, and I'm always grateful for
the opportunity to learn.  My revised code appears below.  Philllip

def strip_pairs(s, open='([{\'"', close=')]}\'"'):
   """
   OVERVIEW

   This function strips matching pairs of characters from the beginning and
   end of the input string `s`.  If `s` begins with a character in `open`
and
   ends with the corresponding character in `close` (see below), both are
   removed from the string. This process continues until no further matching
   pairs can be removed.

   INPUTS

   `open` and `close`: These arguments, which must be equal-length strings,
   specify matching start-of-scope and end-of-scope characters.  The same
   character may appear in both `open` and `close`; single and double quotes
   conventionally match themselves.  By default, `open` contains a left
   parenthesis, left square bracket, left curly bracket, single quote, and
   double quote), and `close` contains the corresponding characters."""

   if not isinstance(s,(str,unicode)):
  raise TypeError, '`s` must be a string (str or unicode).'

   if not isinstance(open,(str,unicode)) or not
isinstance(close,(str,unicode)):
  raise TypeError, '`open` and `close` must be strings (str or
unicode).'

   if len(open) != len(close): raise ValueError, \
 '\'open\' and \'close\' arguments must be equal-length strings.'

   while len(s) >= 2:

  # Check whether first character of `s` is in `open`:
  i= open.find(s[0])

  # If `s` does not begin with a character from `open`, there are no
more
  # pairs to be stripped:
  if i == -1: break

  # If `s` does not begin and end with matching characters, there are no
  # more pairs to be stripped:
  if s[-1] != close[i]: break

  # Strip the first and last character from `s`:
  s= s[1:-1]

   return s
-- 
View this message in context: 
http://old.nabble.com/how-to-convert-string-function-to-string-method--tp26673209p26688035.html
Sent from the Python - python-list mailing list archive at Nabble.com.

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


Re: how to convert string function to string method?

2009-12-07 Thread Terry Reedy

Steven D'Aprano wrote:

On Sun, 06 Dec 2009 22:47:48 -0800, Dr. Phillip M. Feldman wrote:


I wrote a handy-dandy function (see below) called "strip_pairs" for
stripping matching pairs of characters from the beginning and end of a
string.  This function works, but I would like to be able to invoke it
as a string method rather than as a function.  Is this possible?


Not exactly. You can subclass string and add such a method:

class MyString(str):
def strip_pairs(self, ...):
...

but then you have to convert every string to a MyString before you use 
it. That way leads to madness.


Better to just use a function. Don't worry, you're allowed to mix 
functional and OO code :)


Unlike certain other languages, Python is not designed around a fetish 
for calling all functions as methods. s.func(arg) is immediately 
translated to cls.func(s,arg) where cls is either the class of s or some 
superclass thereof. Directly writing mod.func(s,arg), where mod is some 
module, is just as good. Methods have three purposes: bundle several 
related functions in a class-specific namespace; inheritance; mapping of 
operations, like '+', to class-specific (special) methods. Modules are 
an alernative namespace bundle.


Terry Jan Reedy

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


Re: how to convert string function to string method?

2009-12-07 Thread Bruno Desthuilliers

r0g a écrit :
(snip)
 > I've never tried it but I think it is possible to inject new methods

into existing classes, see...


Doesn't work for most builtin types - for both performances and sanity 
reasons.


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


Re: how to convert string function to string method?

2009-12-07 Thread Steven D'Aprano
On Sun, 06 Dec 2009 22:47:48 -0800, Dr. Phillip M. Feldman wrote:

> I wrote a handy-dandy function (see below) called "strip_pairs" for
> stripping matching pairs of characters from the beginning and end of a
> string.  This function works, but I would like to be able to invoke it
> as a string method rather than as a function.  Is this possible?

Not exactly. You can subclass string and add such a method:

class MyString(str):
def strip_pairs(self, ...):
...

but then you have to convert every string to a MyString before you use 
it. That way leads to madness.

Better to just use a function. Don't worry, you're allowed to mix 
functional and OO code :)


As for the function, I think we can re-write it to be a bit more 
Pythonic. We start with a helper function. (Since it's a one-liner, 
that's not strictly necessary.)


def bracketed_by(s, open, close):
"""Return True if string s is bracketed by open and close pairs."""
# I'm too lazy to put proper error handling here...
return s.startswith(open) and s.endswith(close)


# UNTESTED   
def strip_pairs(s, open='([{\'"', close=')]}\'"'):
if len(open) != len(close):
raise ValueError(
"'open' and 'close' arguments must be equal length strings.")
if not isinstance(s, basestring):
# FIX ME: this wrongly fails on UserString arguments.
raise TypeError('argument must be a string')
pairs = zip(open, close)
while any(bracketed_by(s, a, b) for (a,b) in pairs):
s = s[1:-1]
return s



The above is written for simplicity rather than efficiency -- for small 
strings, say, under a couple of megabytes, it is likely to be faster than 
a more "clever" algorithm. If you are routinely dealing with strings 
which are tens of megabytes in size, bracketed by dozens or hundreds of 
pairs of brackets, then the above may be a little slow. But for small 
strings, it will probably be faster than a routine which tries to be 
smarter at avoiding copying strings.



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


Re: how to convert string function to string method?

2009-12-07 Thread Bruno Desthuilliers

Dr. Phillip M. Feldman a écrit :

I wrote a handy-dandy function (see below) called "strip_pairs" for stripping
matching pairs of characters from the beginning and end of a string.  This
function works, but I would like to be able to invoke it as a string method
rather than as a function.  Is this possible?


No. Basic type (strings/unicode, numerics, lists, tuples, dicts etc) are 
not "opened" to monkeypatching. Partly for performance reasons, partly 
to avoid the insanity that we've seen in the Ruby world where everyone 
and it's little sisters extends basic types with tons of more or less 
usefull and often conflicting features.



def strip_pairs(s=None, open='([{\'"', close=')]}\'"'):


Why a default value of None for the first param ???


   """This function strips matching pairs of characters from the beginning
and
   end of the input string `s`.  `open` and `close` specify corresponding
pairs
   of characters, and must be equal-length strings.  If `s` begins with a
   character in `open` and ends with the corresponding character in `close`,
   both are removed from the string.  This process continues until no
further
   matching pairs can be removed."""

   if len(open) != len(close): raise Exception, \
 '\'open\' and \'close\' arguments must be strings of equal length.'



Please use proper exception types. Here you want a ValueError. Also, you 
just dont care whether open and close are proper strings - any sequence 
of characters would do.



   # If input is missing or is not of type `str` (or `unicode`), return
None:
   if s is None or not isinstance(s,(str,unicode)): return None


If s is None, it won't be a str or unicode instance, so the test is 
redundant !-)


But anyway : if this function is supposed to operate on strings, don't 
accept None (and even less provide it as default), and don't fail 
silently - you should really raise a TypeError here IMHO.



   while len(s) >= 2:

  # Check whether first character of `s` is in `open`:
  i= open.find(s[0])

  # If `s` does not begin with a character from `open`, there are no
more
  # pairs to be stripped:
  if i == -1: break

  # If `s` does not begin and end with matching characters, there are no
  # more pairs to be stripped:
  if s[-1] != close[i]: break

  # Strip the first and last character from `s`:
  s= s[1:-1]

   return s


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


Re: how to convert string function to string method?

2009-12-07 Thread r0g
Dr. Phillip M. Feldman wrote:
> I wrote a handy-dandy function (see below) called "strip_pairs" for stripping
> matching pairs of characters from the beginning and end of a string.  This
> function works, but I would like to be able to invoke it as a string method
> rather than as a function.  Is this possible?
> 
> def strip_pairs(s=None, open='([{\'"', close=')]}\'"'):
>"""This function strips matching pairs of characters from the beginning
> and
>end of the input string `s`.  `open` and `close` specify corresponding
> pairs
>of characters, and must be equal-length strings.  If `s` begins with a
>character in `open` and ends with the corresponding character in `close`,
>both are removed from the string.  This process continues until no
> further
>matching pairs can be removed."""
> 
>if len(open) != len(close): raise Exception, \
>  '\'open\' and \'close\' arguments must be strings of equal length.'
> 
># If input is missing or is not of type `str` (or `unicode`), return
> None:
>if s is None or not isinstance(s,(str,unicode)): return None
> 
>while len(s) >= 2:
> 
>   # Check whether first character of `s` is in `open`:
>   i= open.find(s[0])
> 
>   # If `s` does not begin with a character from `open`, there are no
> more
>   # pairs to be stripped:
>   if i == -1: break
> 
>   # If `s` does not begin and end with matching characters, there are no
>   # more pairs to be stripped:
>   if s[-1] != close[i]: break
> 
>   # Strip the first and last character from `s`:
>   s= s[1:-1]
> 
>return s


I've never tried it but I think it is possible to inject new methods
into existing classes, see...

http://www.daniel-lemire.com/blog/archives/2005/12/21/metaclass-programming-in-python/

Not sure how good an idea it would be though, I have heard it refered to
as "monkey patching" and I can imagine doing it to classes as
fundamental as the string class could have negative performace consequences.

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


Re: how to convert string function to string method?

2009-12-07 Thread Peter Otten
Dr. Phillip M. Feldman wrote:

> I wrote a handy-dandy function (see below) called "strip_pairs" for
> stripping
> matching pairs of characters from the beginning and end of a string.  This
> function works, but I would like to be able to invoke it as a string
> method
> rather than as a function.  Is this possible?

This requires a feature called "open classes" (Ruby has them). It is not 
possible in Python, at least for built-in types like str.

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


Re: how to convert string function to string method?

2009-12-06 Thread Stephen Hansen
On Sun, Dec 6, 2009 at 10:47 PM, Dr. Phillip M. Feldman <
pfeld...@verizon.net> wrote:

>
> I wrote a handy-dandy function (see below) called "strip_pairs" for
> stripping
> matching pairs of characters from the beginning and end of a string.  This
> function works, but I would like to be able to invoke it as a string method
> rather than as a function.  Is this possible?
>

No. String objects are immutable and you can not set new attributes/methods
on the type itself.

Really the best thing to do in this case is to just have this in an easy to
access library, and call it as a function and not a string method.

The only alternative is to create a string subtype which has a new method--
but that would require all the strings you're using to be this subclass.
E.g. you'd have to do MyString(regular_String) for each. This is really IMHO
unwieldy and not really worth the effort -- just put strip_pairs into a
library and call it as a function.

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


how to convert string function to string method?

2009-12-06 Thread Dr. Phillip M. Feldman

I wrote a handy-dandy function (see below) called "strip_pairs" for stripping
matching pairs of characters from the beginning and end of a string.  This
function works, but I would like to be able to invoke it as a string method
rather than as a function.  Is this possible?

def strip_pairs(s=None, open='([{\'"', close=')]}\'"'):
   """This function strips matching pairs of characters from the beginning
and
   end of the input string `s`.  `open` and `close` specify corresponding
pairs
   of characters, and must be equal-length strings.  If `s` begins with a
   character in `open` and ends with the corresponding character in `close`,
   both are removed from the string.  This process continues until no
further
   matching pairs can be removed."""

   if len(open) != len(close): raise Exception, \
 '\'open\' and \'close\' arguments must be strings of equal length.'

   # If input is missing or is not of type `str` (or `unicode`), return
None:
   if s is None or not isinstance(s,(str,unicode)): return None

   while len(s) >= 2:

  # Check whether first character of `s` is in `open`:
  i= open.find(s[0])

  # If `s` does not begin with a character from `open`, there are no
more
  # pairs to be stripped:
  if i == -1: break

  # If `s` does not begin and end with matching characters, there are no
  # more pairs to be stripped:
  if s[-1] != close[i]: break

  # Strip the first and last character from `s`:
  s= s[1:-1]

   return s
-- 
View this message in context: 
http://old.nabble.com/how-to-convert-string-function-to-string-method--tp26673209p26673209.html
Sent from the Python - python-list mailing list archive at Nabble.com.

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