Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Python regular expressions extra credit: creating a Class to house regex.finditer() objects

So after quite some work I was able to get it to work (kinda). I am using a regular expression with group names to find info in an external text file and then instantiate that into a class object. Problem lies at the very end: the reg_ex expression works and finds what I am looking for but when I run it as a class object (see below) it only returns the first set of values (name, email etc.) but does not return the rest of the objects.

i.e. it only returns:

Love, Kenneth <kenneth@teamtreehouse.com> (555) 555-5555 Teacher, Treehouse @kennethlove

Interestingly, if I change the 'return' on the str method to a 'print()' it DOES return all the info , but also raises an exception because str wants a 'return' not a 'print()' (I suppose). i.e. when I use 'print()' instead of 'return':

Love, Kenneth <kenneth@teamtreehouse.com> (555) 555-5555 Teacher, Treehouse      @kennethlove


McFarland, Dave <dave@teamtreehouse.com> (555) 555-5554 Teacher, Treehouse


Arthur, King <king_arthur@camelot.co.uk>  King, Camelot


Österberg, Sven-Erik <governor@norrbotten.co.se>  Governor, Norrbotten   @sverik


Carson, Ryan <ryan@teamtreehouse.com> (555) 555-5543 CEO, Treehouse      @ryancarson


Doctor, The <doctor+companion@tardis.co.uk>  Time Lord, Gallifrey


Exampleson, Example <me@example.com> 555-555-5552 Example, Example Co.   @example


Obama, Barack <president.44@us.gov> 555 555-5551 President, United States of America     @potus44


Chalkley, Andrew <andrew@teamtreehouse.com> (555) 555-5553 Teacher, Treehouse    @chalkers


Vader, Darth <darth-vader@empire.gov> (555) 555-4444 Sith Lord, Galactic Empire  @darthvader


Fernández de la Vega Sanz, María Teresa <mtfvs@spain.gov>  First Deputy Prime Minister, Spanish Govt.


Traceback (most recent call last):
  File "re_treehouse_ec.py", line 70, in <module>
    print(people)
TypeError: __str__ returned non-string (type NoneType)

How can I get this to return ALL the info from the names.txt? AND not do a TypeError?

'''
Write a class to represent a person based on the information in the text file. 
They should have names, email addresses, phone numbers, jobs, and Twitter accounts. 
Remember, some of these can be blank, though!
To go ever further, make a class to act as as address book to 
hold all of the people class instances created above. Can you make it searchable?
'''

import re


data = '''Love, Kenneth kenneth@teamtreehouse.com   (555) 555-5555  Teacher, Treehouse  @kennethlove
McFarland, Dave dave@teamtreehouse.com  (555) 555-5554  Teacher, Treehouse
Arthur, King    king_arthur@camelot.co.uk       King, Camelot
Österberg, Sven-Erik   governor@norrbotten.co.se       Governor, Norrbotten    @sverik
, Tim   tim@killerrabbit.com        Enchanter, Killer Rabbit Cave
Carson, Ryan    ryan@teamtreehouse.com  (555) 555-5543  CEO, Treehouse  @ryancarson
Doctor, The doctor+companion@tardis.co.uk       Time Lord, Gallifrey
Exampleson, Example me@example.com  555-555-5552    Example, Example Co.    @example
Obama, Barack   president.44@us.gov 555 555-5551    President, United States of America @potus44
Chalkley, Andrew    andrew@teamtreehouse.com    (555) 555-5553  Teacher, Treehouse  @chalkers
Vader, Darth    darth-vader@empire.gov  (555) 555-4444  Sith Lord, Galactic Empire  @darthvader
Fernández de la Vega Sanz, María Teresa   mtfvs@spain.gov     First Deputy Prime Minister, Spanish Govt.'''


line = re.compile(r'''
    ^(?P<name>(?P<last>[-\w ]+),\s(?P<first>[-\w ]+))\t   #subgroup first and last added
    (?P<email>[-\w\d.+]+@[-\w\d.+]+)\t      # email
    (?P<phone>\(?\d{3}\)?-?\s?\d{3}-\d{4})?\t        #phone
    (?P<job>[\w\s]+,\s[\w\s.]+)\t?      #job and company
    (?P<twitter>@[\w\d]+)?$               #twitter, dollar sign to check end of string
''', re.X|re.MULTILINE)  #multi line (aka re.M) makes each str. one line (\n treatedend of string)

#for match in line.finditer(data):
#   print('{first} {last} <{email}>'.format(**match.groupdict()))  

class Reg_Ex_Person:
    def __init__(self, name='', email='', phone='', job='', twitter=''):
        re_name = None
        for match in line.finditer(data):
            re_name = match.group('name')
        self.name = re_name

        re_email = None
        for match in line.finditer(data):
            re_email = match.group('email')
        self.email = re_email

        re_phone = None
        for match in line.finditer(data):
            re_phone = match.group('phone')
        self.phone = re_phone

        re_job = None
        for match in line.finditer(data):
            re_job = match.group('job')
        self.job = re_job

        re_twitter = None
        for match in line.finditer(data):
            re_twitter = match.group('twitter')
        self.twitter = re_twitter       

    def __str__(self):
        for match in line.finditer(data):
            return('{name} <{email}> {phone} {job} {twitter}'.format(**match.groupdict(default='')))  
            print('\n')

people = Reg_Ex_Person()
print(people)```