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
Francesco Cabiddu
2,297 PointsExtra credit regular expressions
Hi everyone! I've tried to complete the extra credit task for the regular expressions course. What do you think about my code? How could I make it better?
Thank you very much in advance for all of your answers!
person_info.py
class Person:
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
book.py
import re
from person_info import Person
class Book:
def __init__(self):
book = self.write_book()
print("search a person details or [Q]uit")
while True:
search_person = input("name and surname > ").lower()
if search_person == "q":
print("bye!")
exit()
elif search_person in book.keys():
print(vars(book[search_person]))
def write_book(self):
names_file = open("names.txt", encoding="utf-8")
data = names_file.read()
names_file.close()
pattern = re.compile(r'''
^(?P<last>[-\w ]*),\s(?P<first>[-\w ]+)\t # last and first name
(?P<email>[-\w\d.+]+@[-\w\d.]+)\t # Email
(?P<phone>\(?\d{3}\)?-?\s?\d{3}-\d{4})?\t # phone numbers
(?P<job>[\w\s]+,\s[\w\s.]+)\t # job and company
(?P<twitter>@[\w\s]+)?$ # twitter
''', re.X | re.M)
addresses = {}
for match in pattern.finditer(data):
name = match.group("first") + " " + match.group("last")
addresses[name.lower().replace(", ", " ")] = Person(**match.groupdict())
return addresses
Book()
1 Answer
Chris Freeman
Treehouse Moderator 68,468 PointsHi Francesco! As Christopher mentioned, your code is well organized and neat. I have a few observations.
Your code demonstrates that you understand how class can be called and how methods work. This is a great start!
Python classes usually represent an object with attributes to hold data and methods to manipulate that data. When a class object is instantiated, an instance is returned and other code then operates on that instance.
In your code, the class is being used as a manner of flow control, in that, the default __init__ execution is being used to start the execution flow and, in turn, calling the method write_book more as a helper function than as a method that modifies the class instance.
I noticed the internal book variable is not saved. This means it's discarded as soon as the __init__ method exits.
The purpose of the __init__ method is to initiate the class attributes. This follows after hidden execution if the inherented method __new__ (from the base class object) that creates the class instance.
I also noticed, the self attribute is never referenced by write_book. This would make it a static method that doesn't necessarily need to be inside the class. It could be a helper function outside the class.
Try to think of classes as a way to organize data that might be stored in a database. Since there is no data stored as attributes inside the class, there isn't a need for the class at all.
I would suggest
- not using a class
- move both methods outside the class as regular functions
- rename
__init__to "main" - remove the "self" parameters
- call
main()instead ofBook()to initiate the flow
Now you have a principle function main that uses the helper function write_book.
As a bonus suggestion, I would add the following code that only calls main() if book.py is run interactively and not if book.py is imported by another file.
if __name__ == "__main__":
main()
Post back if you have any questions. Good luck!!!
Christopher Shaw
Python Web Development Techdegree Graduate 58,248 PointsChristopher Shaw
Python Web Development Techdegree Graduate 58,248 PointsI have not tried to run your code, but assume that you have it working.
It does look neat and concise, and I do not see any way you could simplify it further. So job well done.