2

I am struggling with the logic for the problem below and I know that even if I nailed the logic, I would probably implement it clumsily, so any advice would be awesome.

I have a dictionary representing a file:

the_file = {'Filename':'x:\\myfile.doc','Modified':datetime(2012,2,3),'Size':32412}

I have a list of filters and I want to filter the file dictionary to determine a match.

filters = [
    {'Key':'Filename','Criteria':'Contains','Value':'my'},
    {'Key':'Filename','Criteria':'Does not end with','Value':'-M.txt'},
    {'Key':'Modified','Criteria':'After','Value':datetime(2012,1,1)}
    ]

My best attempt at creating a function to do this (which doesn't work):

def is_asset(the_file, filters):
match = False
for f in filters:
    if f['Key'] == u'Filename':
        if f['Criteria'] == u'Contains':
            if f['Value'] in the_file['Filename']:
                match = True
        elif f['Criteria'] == u'Starts with':
            if the_file['Filename'].startswith(f['Value']):
                match = True
        elif f['Criteria'] == u'Ends with':
            if the_file['Filename'].endswith(f['Value']):
                match = True
        elif not f['Criteria'] == u'Does not end with':
            if the_file['Filename'].endswith(f['Value']):
                match = False
        elif f['Criteria'] == u'Equals':
            if os.path.basename(the_file['Filename']) == f['Value']:
                match = True
        elif f['Criteria'] == u'Does not contain':
            if f['Value'] in the_file['Filename']:
                match = False
    elif f['Key'] == u'Modified':
        mtime = int(os.path.getmtime(the_file['Filename']))
        if f['Criteria'] == u'Before':
            if f['Value'] > datetime.fromtimestamp(mtime):
                the_file['Modified'] = mtime
                match = True
        elif f['Criteria'] == u'After':
            if f['Value'] < datetime.fromtimestamp(mtime):
                the_file['Modified'] = mtime
                match = True
    elif f['Key'] == u'Size':
        size = long(os.path.getsize(the_file['Filename']))
        if f['Criteria'] == u'Bigger':
            if f['Value'] < size:
                the_file['Size'] = size
                match = True
            elif f['Value'] > size:
                the_file['Size'] = size
                match = True
    if match:
        return the_file

2 Answers 2

4

Instead of trying to do it in one megafunction, break it down into smaller steps.

filenamecondmap = {
  u'Contains': operator.contains,
  u'Does not end with': lambda x, y: not x.endswith(y),
   ...
}

 ...

condmap = {
  u'Filename': filenamecondmap,
  u'Modified': modifiedcondmap,
   ...
}

And then walk the structures until you have the conditional, then execute it.

condmap[u'Filename'][u'Contains'](thefile['Filename'], 'my')
Sign up to request clarification or add additional context in comments.

Comments

2

You can simply use functions as your 'criteria'. This makes it much simpler, as you don't have to write a big if-else ladder. Something like this:

def contains(value, sub):
    return sub in value

def after(value, dt):
    return value > dt

filters = [
    {'Key': 'FileName', 'Criteria': contains, 'Value': 'my'},
    {'Key': 'Modified', 'Criteria': after,  'Value': datetime(2012,1,1)}
]

for f in filters:
    if f['Criteria'](filename[f['Key']], f['Value']):
       return True

1 Comment

I also learned a lot from your post, although I can only mark one answer. Thanks a lot.

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.