1

I want to list all names in a file that uses a dictionary by date of birth. I want the oldest to be the first and so on down to the youngest. Here is my code, what would I need to add for this:

#!/usr/bin/python
import sys
import operator
import re
from operator import itemgetter
from datetime import datetime

dictionary={}

f = open('names.txt', "r")

for line in f:
    test = re.split(r'\s*[;,.]\s*', line)
    name = test[0]
    bDay = test[1]
    removeNLine =len(bDay)-1 # get the D.0.B but remove the /n
    bDay = bDay[0:removeNLine]
    dictionary[name] = datetime.strptime(bDay,"%d/%m/%Y")

 #for y,v in sorted(d.iteritems(), key=lambda (k,v1): (v1,k)):
#d2 = sorted(d.values()) 
#d2= sorted(d.keys(), key=d.get, reverse = False)  
#d2= sorted(d.keys(), key=operator.itemgetter(1))
#print d2 
#for y in d: 

for name,birth in dictionary.items():
    dob = dictionary[name]
    timeFormat = dob # just edited 
    timeNow = datetime.now()
    daysTime = timeNow -timeFormat
    days = daysTime.days
    age = days / 365
    print name,age

So my file has a name and a birthday and I want to sort by the birthday from what I have been reading I probably should be able to do it with datetime.strptime but I cant understand how to sort with it. Any ideas on improving the code too will be appreciated but bare in mind that I am new to this and generally very poor at programming languages so readability and the ability to understand fairly easy would be helpful.

the file is as follows:

tom 12/12/1999
ted ; 01/04/2008
tim ; 01/02/2001
mike 09/03/1997
4
  • whats wrong whit sorted(dictionary, key=dictionary.get) ? Commented Nov 29, 2014 at 10:27
  • my dates are in string format, although as you can see I am trying to convert them- just not doing it right. The code you gave just returns a list with the names? Commented Nov 29, 2014 at 10:38
  • as i see you converted the dates , can you show some line of your file ? Commented Nov 29, 2014 at 10:39
  • "but bare in mind that I am new to this and generally very poor at programming languages so readability and the ability to understand fairly easy would be helpful." I think you've done a very good job. Commented Nov 29, 2014 at 11:11

2 Answers 2

2

You're splitting on ;,. but there's no separator of that kind between some of the lines? Also if you have any empty lines it'll fall over.

#!/usr/bin/python
import sys
import operator
import re
from operator import itemgetter
from datetime import datetime

dictionary={}

f = open('names.txt', "r")

for line in f:
    # NB: split on whitespace as well,  PROBLEM 1
    # (nicer to normalize your names txt file if you can).
    test = re.split(r'\s*[;,.\t ]\s*', line) 
    name = test[0]
    bDay = test[1]
    removeNLine =len(bDay)-1 # get the D.0.B but remove the /n
    bDay = bDay[0:removeNLine]
    dictionary[name] = datetime.strptime(bDay,"%d/%m/%Y")

for name,birth in dictionary.items():
    dob = dictionary[name] # this is already a datetime  PROBLEM 2
    timeNow = datetime.now()
    daysTime = timeNow - dob
    days = daysTime.days
    age = days / 365
    print name,age

Now I'm going to be self indulgent and post the code the way I'd write it. First I'd clean the names.txt file so it's space separated. Then I'd do this:

#!/usr/bin/env python
from datetime import datetime

dobs = []

f = open('names.txt', "r")

for line in f.readlines():
    name, bday = line.split()
    dob = datetime.strptime(bday,"%d/%m/%Y")
    dobs.append((name, dob))

# we use this function to tell the list.sort() method what it 
# means for lists of (name, dob) tuples to be sorted
def cmp_dates(name_dob, name_dob2):
    return cmp(name_dob[1], name_dob2[1])

# or this if you want it reversed
#def cmp_dates(name_dob, name_dob2):
#    return cmp(name_dob2[1], name_dob[1])

# sorts in place
dobs.sort(cmp_dates)

for name, dob in dobs:
    now = datetime.now()
    delta = now - dob
    days = delta.days 
    age = days / 365
    print name, age
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the heads up, any input on why I would get the error TypeError: 'datetime.datetime' object is not iterable when I used the code Kasra supplied t=sorted(dictionary[name], key=dictionary.get)
any ideas on how to implement the sort by date.
I've changed my version to handle the sorting. The functional versions other people have posted are ok.. just not as easily and immediately understandable I don't think as spelling it all out.
This almost perfect and very well explained, thank you. Only thing is, can I still implement the regex so if there is a semicolon or the other type symbols you had in the previous regex example?
Sure you can. You are the master of your fate, and the captain of your soul. Just drop the regex in where the line.split() is. Python is fast. It's very often faster to try it and see than ask. Save a copy of your file if you're worried about breaking things and not knowing how to fix them.
|
1

First save the dates in string format and use sorted with following code , also your split regex is wrong , change it to r'[;,\. ]*':

dictionary={}
import re
import datetime
with open("new.txt","r") as f :
    for line in f:
      s=line.replace('\n','')  
      s=re.split(r'[;,\. ]*',s)
      dictionary[s[0]]=s[1]

s_d=sorted(dictionary.values(), key=lambda x: datetime.datetime.strptime(x,'%d/%m/%Y'))

print s_d

result :

['09/03/1997', '12/12/1999', '01/02/2001', '01/04/2008']

Note : you need to remove \n at the end of your lines (line.replace('\n',''))

7 Comments

If I save the dates in string format how will I be to sort by date? can you apply a simple sample so I can understand what you mean?
As you can see in my answer you convert your strings to date type in lambda function !
@user1766709 i edit the answer , you need to pass the dict.values to your sorted function!
@user1766709 exq ... import what ?
I get an error when trying this; 'AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.