The problem with duck typing

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Jun 2008
Posts: 46
Reputation: Fuse is an unknown quantity at this point 
Solved Threads: 3
Fuse's Avatar
Fuse Fuse is offline Offline
Light Poster

The problem with duck typing

 
0
  #1
Jun 8th, 2008
I have a problem guys. It's due to duck typing. Now I expected to run into something like this sooner or later, but I can't help but feel there's a better solution.

  1. import re
  2. def patternMatching(pattern, string):
  3. matchList = re.findall(pattern, string)
  4. print '\n'.join(['%s' % v for v in matchList])

If you run that function as patternMatching(r'The (fox)', 'The fox'), it gives you 'fox', right? Because matchList is ['fox'].

But what if you run it as patternMatching(r'(The) (fox)', 'The fox')? You get an error. Because matchList is [('The','fox')].

Duck typing is messing with my types, so the print function won't work.

Traceback (most recent call last):
  File "<pyshell#52>", line 1, in <module>
    print '\n'.join(['%s' % v for v in matchList])
TypeError: not all arguments converted during string formatting

What's a programmer to do? My patch solution is to check the type of the first element and then do two cases. But that won't hold if I get something like [('hello','bye'),'hello']... which I'm not sure I ever will, but the point remains.
Mir's Fuselage

Because what's not to like about being killed by a toilet seat from Mir's atmospheric re-entry?
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 138
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: The problem with duck typing

 
0
  #2
Jun 8th, 2008
It is only a duck if it acts, looks and sounds like one. Processed duck is not a duck.
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 46
Reputation: Fuse is an unknown quantity at this point 
Solved Threads: 3
Fuse's Avatar
Fuse Fuse is offline Offline
Light Poster

Re: The problem with duck typing

 
0
  #3
Jun 8th, 2008
Actually, it it is looking, acting and sounding like a duck. It's a 1-tuple, so it's still a tuple. Python seems to think a 1-tuple is better expressed simply as the element within the 1-tuple, however, which causes this problem.
Mir's Fuselage

Because what's not to like about being killed by a toilet seat from Mir's atmospheric re-entry?
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 1,546
Reputation: Ene Uran has a spectacular aura about Ene Uran has a spectacular aura about 
Solved Threads: 174
Ene Uran's Avatar
Ene Uran Ene Uran is offline Offline
Posting Virtuoso

Re: The problem with duck typing

 
0
  #4
Jun 8th, 2008
I think you have to write it this way:
patternMatching(r"The|fox", 'The little brown fox')
drink her pretty
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 128
Reputation: slate is an unknown quantity at this point 
Solved Threads: 31
slate slate is offline Offline
Junior Poster

Re: The problem with duck typing

 
0
  #5
Jun 8th, 2008
Help on function findall in module re:

findall(pattern, string, flags=0)
Return a list of all non-overlapping matches in the string.

If one or more groups are present in the pattern, return a
list of groups; this will be a list of tuples if the pattern
has more than one group.

Empty matches are included in the result.
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 46
Reputation: Fuse is an unknown quantity at this point 
Solved Threads: 3
Fuse's Avatar
Fuse Fuse is offline Offline
Light Poster

Re: The problem with duck typing

 
0
  #6
Jun 8th, 2008
Originally Posted by Ene Uran View Post
I think you have to write it this way:
patternMatching(r"The|fox", 'The little brown fox')
Thanks! That would normally work. Unfortunately, that's not possible. This programme is designed to accept a user's own regular expression, so I have to accept the full range of regular expression syntax. I've got this solution so far, but I figured surely something more elegant would exist.

  1. def patternMatching(self, event):
  2. matchList = re.findall(self.patternArea.GetValue(), self.inputArea.GetValue())
  3. for n in range(0, len(matchList)):
  4. if type(matchList[n]) == type(''):
  5. matchList[n] = (matchList[n],)
  6. outputString = ''
  7. for tupleElement in matchList:
  8. outputString += '\n'.join(['%s' % stringElement for stringElement in tupleElement])
  9. self.outputArea.SetValue(outputString)

Slate: Yes, but that's counter-intuitive. If there's one group you'll be iterating over a string, but if there's more than one it will be a tuple. Kind of un-Pythonic, no? It would make much more sense for the case of one group to be a 1-tuple.
Last edited by Fuse; Jun 9th, 2008 at 12:06 am.
Mir's Fuselage

Because what's not to like about being killed by a toilet seat from Mir's atmospheric re-entry?
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 128
Reputation: slate is an unknown quantity at this point 
Solved Threads: 31
slate slate is offline Offline
Junior Poster

Re: The problem with duck typing

 
0
  #7
Jun 9th, 2008
The title of the forum is about duck typing. The problem at hand has nothing to do with it IMHO.

I agree. Re.findall function is not so well suited for taking a user input regular expression, because it changes the output type depending on the input regexp.

This design decission can be argued against. A pro argument would be, that most of the time the regular expression is programmed by hand, and most of the time there is no more than one group. I don't know if it is true however. An against is your use case.
Reply With Quote Quick reply to this message  
Join Date: Sep 2007
Posts: 33
Reputation: paddy3118 is an unknown quantity at this point 
Solved Threads: 8
paddy3118 paddy3118 is offline Offline
Light Poster

Re: The problem with duck typing

 
0
  #8
Jul 2nd, 2008
Try re.finditer as in:

  1. def patternMatching(pattern, string):
  2. print '\n'.join(string[matchobj.start():matchobj.end()]
  3. for matchobj in re.finditer(pattern, string))

- Paddy.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Python Forum


Views: 1062 | Replies: 7
Thread Tools Search this Thread



Tag cloud for Python
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC