Python Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesPython Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old January 26th, 2013, 06:16 PM
taeBaby taeBaby is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2013
Posts: 27 taeBaby User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
Re.findall help

Hi, so I'm fairly new to python but I've been practicing coding on my own.

Recently, I'm working with the re.match, re.findall, re.ignorecase.

This is my code:
Code:
def mission(s):
  match = re.findall(r'\d+', s, re.IGNORECASE)
  return match

It gives me this output:
Code:
['1', '0']
['20', '500']
['3']
['20', '1']

From this:
Code:
mission('Recon Mission 1 accomplished. Enemy found: 0.') 
mission('recon mission 20 accomplished. enemies found: 500.') 
mission("Recon Mission 3 failed.")
mission("I have 20 carrots and 1 mushroom.")


But I need to get this output:
Code:
(1, 0)
(20, 500)
(3, failed)
fourth line returns empty b/c it does not contain mission or status

I'm not sure how to extract mission number and status (either 'failed' or number of enemies found)

Any suggestions on how to do this correctly?

Reply With Quote
  #2  
Old January 26th, 2013, 07:27 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 8 h 3 m 36 sec
Reputation Power: 383
1) convert the number strings to integers.
2) Use simple regular expressions. Don't try to parse English with a single re.
This code might be closer to what you want. Could be more restrictive about accepting interesting sentences.
Code:
# python -m doctest -v p.py

import re

def mission(s):
    '''
        >>> (1, 0) == mission('Recon Mission 1 accomplished. Enemy found: 0.')
        True
        >>> (20, 500) == mission('recon mission 20 accomplished. enemies found: 500.')
        True
        >>> (3, 'failed') == mission("Recon Mission 3 failed.")
        True
        >>> () == mission("I have 20 carrots and 1 mushroom.")
        True
    '''
    match = list(map(int,re.findall(r'\d+', s)))
    sl = s.lower()
    if 'mission' in sl:
        if ('accomplished' in sl) and ('found' in sl):
            return tuple(match)
        if match and ('failed' in sl):
            return (match[0],'failed',)
    return ()
__________________
[code]Code tags[/code] are essential for python code!

Reply With Quote
  #3  
Old January 26th, 2013, 07:56 PM
taeBaby taeBaby is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2013
Posts: 27 taeBaby User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
Thanks for that @b49P23TIvg

what does map() do?

But while I was away, I actually figured out how to do it another way, the only problem I have now is how to remove the brackets and quotation marks from the numbers to just have parentheses.

This is my code now:
Code:
def mission(s):
  first = re.findall(r'Recon Mission (\d+)', s, re.IGNORECASE)
  second = re.findall(r'found: (\d+)', s)
  if first and second:
    s = first, second
  elif first and second !=None:
    second = 'failed'
    s = first, second
  else:
    s = None
  return s

My output:
Code:
(['1'], ['0'])
(['2'], ['500'])
(['3'], 'failed')
None

How to code to get my (['1'], ['0']) to output as (1, 0)?
Or is it not possible to do so unless I do it your way or another way?

Reply With Quote
  #4  
Old January 26th, 2013, 08:43 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 8 h 3 m 36 sec
Reputation Power: 383
Using your mission function, we can clean the output into strings matching your requirement.
Code:
import re

def mission(s):
    first = re.findall(r'Recon Mission (\d+)', s, re.IGNORECASE)
    second = re.findall(r'found: (\d+)', s)
    if first and second:
        s = first, second
    elif first and second !=None:
        second = 'failed'
        s = first, second
    else:
        s = None
    return s

def clean(s):
    '''
        >>> print(clean(mission('Recon Mission 1 accomplished. Enemy found: 0.')))
        (1, 0)
        >>> print(clean(mission('recon mission 20 accomplished. enemies found: 500.')))
        (20, 500)
        >>> print(clean(mission("Recon Mission 3 failed.")))
        (3, failed)
        >>> print(clean(mission("I have 20 carrots and 1 mushroom.")))
        None
    '''
    return re.sub("[][']",'',str(s)) # as a regular expression

    return str(s).replace('[','').replace(']','').replace("'",'')   # with builtin string methods
map(function,iterable)
Suppose function(object_x) returns object_y .
Then if iterating iterable gives objects_x
map(function,objects_x)
is an iterable that, when iterated gives objects_y . I've stated this confusingly, obtusely, but generally. map changed between python 2 and 3. In python 3 map uses lazy evaluation, it avoids calling the function until the result is needed. map isn't so hard.
For example, in python 2 and 3
Code:
>>> def double(a): return 2*a
... 

>>> list(map(double,[3,'ho']))
[6, 'hoho']
>>> 

Reply With Quote
  #5  
Old January 26th, 2013, 09:07 PM
taeBaby taeBaby is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2013
Posts: 27 taeBaby User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
thank you, I understand the map function now

Also, thanks for the other code, I've implemented it and although it removed the brackets and double quotes, it still seems to have the single quotes, at least it's replaced it all with the single quote.

My output is closer to what I want but instead of (1,0) I now get '(1,0)'

Is there a way to get rid of ' around the parentheses? Or is there a way to replace ' with an empty str?

thank you again!

Reply With Quote
  #6  
Old January 26th, 2013, 09:21 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 8 h 3 m 36 sec
Reputation Power: 383
>>> print( 'string' )
string
>>> 'string'
'string'
>>>

Reply With Quote
  #7  
Old January 26th, 2013, 09:37 PM
taeBaby taeBaby is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2013
Posts: 27 taeBaby User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
Hmm...I understand the print ('string') but I think it's different from what I actually want b/c that's the word itself: string
I'm not sure that it will work in my situation...sry if I'm a bit slow and not really explaining myself well...

I guess I'll continue to play around with the code and google some more.

this is my code now:
Code:
def mission(s):
  first = re.findall(r'Recon Mission (\d+)', s, re.IGNORECASE)
  second = re.findall(r'found: (\d+)', s)
  if first and second:
    s = first, second
    x = str(s).replace('[','').replace(']','').replace("'",'')
  elif first and second !=None:
    second = 'failed'
    t = first, second
    x = str(t).replace('[','').replace(']','').replace("'",'')
  else:
    x = None
  return x

My output:
Code:
'(1, 0)'
'(2, 500)'
'(3, failed)'
None


I think I'm suppose to use int() but when I tried implementing that, it didn't really work, I kept getting an error.

Reply With Quote
  #8  
Old January 26th, 2013, 09:48 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 8 h 3 m 36 sec
Reputation Power: 383
We've come full circle, using integers then removing characters from strings to make them look like numbers.

If you truly want
(3, failed)
then it's a string, not a number and a piece that doesn't look like a number or a string.

Reply With Quote
  #9  
Old January 26th, 2013, 10:08 PM
taeBaby taeBaby is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2013
Posts: 27 taeBaby User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
yeah, I feel like I'm making things worse and confusing myself more. Sry about that.

I went back and decided to just implement your earlier code so now I have this:

Code:
def mission(s):
  match = map(int,re.findall(r'\d+', s))
  sl = s.lower()
  if 'mission' in sl:
    if ('accomplished' in sl) and ('found' in sl):
      s = tuple(match)
    if match and ('failed' in sl):
      s = (match[0],'failed',)
  else:
    s = None
  return s

It works the way I want it to now so thank you.

Just one last question, if I wanted to implement re.Ignorecase instead of using s.lower(), how would I go about doing that?

Reply With Quote
  #10  
Old January 27th, 2013, 12:47 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 3 Days 8 h 3 m 36 sec
Reputation Power: 383
I removed Ignorecase because it had nothing to do with digits. Maybe with these.
Code:
  if re.search('mission',s,re.Ignorecase):
    if re.search('accomplished.*found',s,re.Ignorecase):
    if match and (re.search('failed',s,re.Ignorecase)):
 
untested.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPython Programming > Re.findall help

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap