2
\$\begingroup\$

I have created a program to search for a file in the computer. But I feel it can be improved. Can anyone help me with this?

filesearch.py

import win32api
import os
import io
from fuzzywuzzy import process
def filesearch(self,*args):
    drives = win32api.GetLogicalDriveStrings()
    drives = drives.split('\000')[:-1]
    searchfile = ''.join((args))
    print("Searching...")
    try:
        q = io.open("index.txt", "r", encoding="utf-8")# I have created an index using index.py
        x = q.readlines()
        z = searchfile.lower()
        matches=[]
        basenames=[]
        for line in x:
            ##################################
            # I created this part so that if the file doesn't exist it skips the file. But I feel this doesn't work properly.
            #if os.path.exists(line) == False:
                #pass
            ##################################
            if z in os.path.basename(line):
                matches.append((line[:-1]))
        for match in matches:
            basenames.append(os.path.basename(match))
        s=process.extractOne(z, basenames)
        s=list(s)
        for item in matches:
            if s[0] == os.path.basename(item):
                print("Chosen file: %s"%(item) + "\nMatch percent: %s"%(s[1]))
                print (item)
                try:
                    os.startfile(item)
                    break
                except WindowsError:
                    print"Sir, I am not able to open the file."
        print("\nMatches:")
        for match in matches:
            print(match)
        q.close()
    # Ih created this part as a failsafe just in case the index isn't up to date
    except TypeError, e:
        print(e)
        searchfile = re.compile(searchfile,re.I|re.DOTALL)
        matches = []
        for drive in drives:
            if 'C' in drive:
                for folderName, subfolders, filenames in os.walk(drive):
                    # Skip the windows folder as it has to may files and doesn't have anything the user might need.
                    if 'Windows' in folderName:pass
                    else:
                        for filename in filenames:
                            thefile = os.path.join(folderName,filename)
                            mo = searchfile.search(thefile)
                            try:
                                #Update index in case the file didn't exist in the index.
                                matches.append(thefile)
                                q = io.open("index.txt", "a", encoding="utf-8")
                                q.write(("\n"+thefile).lower())
                                q.close()
                            except AttributeError:
                                pass
            else:
                for folderName, subfolders, filenames in os.walk(drive):
                    for filename in filenames:
                        thefile = os.path.join(folderName,filename)
                        mo = searchfile.search(thefile)
                        try:
                            #Update index in case the file didn't exist in the index.
                            matches.append(thefile)
                            q = io.open("index.txt", "a", encoding="utf-8")
                            q.write(("\n"+thefile).lower())
                            q.close()
                        except AttributeError:
                            pass
            if len(matches) != 0:
                print"\nMatches:"
                for m in matches:
                    print("\n"+m)

index.py

from __future__ import unicode_literals
import os, sys
import os
import io
x = open("index.txt", "w")
x.write("")
x.close()
from os.path import join

for (dirname, dirs, files) in os.walk('C:\\'):
for filename in files:
   thefile = os.path.join(dirname,filename)
   print thefile
   x = io.open("index.txt", "a", encoding="utf-8")
   x.write(("\n"+thefile).lower())
   x.close()
for (dirname, dirs, files) in os.walk('D:\\'):
for filename in files:
   thefile = os.path.join(dirname,filename)
   print thefile
   x = io.open("index.txt", "a", encoding="utf-8")
   x.write(("\n"+thefile).lower())
   x.close()
for (dirname, dirs, files) in os.walk('E:\\'):
for filename in files:
   thefile = os.path.join(dirname,filename)
   print thefile
   x = io.open("index.txt", "a", encoding="utf-8")
   x.write(("\n"+thefile).lower())
   x.close()

Also, I believe my program uses depth first search. Is there a better way to search for files on a computer?

\$\endgroup\$
  • 2
    \$\begingroup\$ Your indentation in index.py is still off (the for loops should be nested). \$\endgroup\$ – Graipher Sep 6 '16 at 16:45
2
\$\begingroup\$

A few points:

  • Your program is neither breadth or depth-first; it uses whatever order os.walk returns.

  • In index.py, opening and closing the index file so often when writing it is slow. Instead, put the open and close outside the for loop; also, use the with syntax for auto-closing, something like:

  • In index.py, you're repeating code a lot. Consolidate it.

    from itertools import chain
    
    def drives():
        for drv in "C", "D", "E":
            yield from os.walk("{}:\\".format(drv))
    
    with io.open("index.txt", "a", encoding="utf-8") as x:
        for dirname, dirs, files in drives():
            for filename in files:
                thefile = os.path.join(dirname,filename)
                print thefile
                x.write(("\n"+thefile).lower())
    
\$\endgroup\$
  • \$\begingroup\$ Is the second point missing a code example? \$\endgroup\$ – ferada Sep 8 '16 at 16:45
  • 1
    \$\begingroup\$ no, the code example addresses both the second and third point. \$\endgroup\$ – pjz Sep 8 '16 at 17:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.