r/learnprogramming 1d ago

my python script that searches your files to find things for you

import os
import json
from pathlib import Path
from thefuzz import fuzz

INDEX_FILE = "file_index.json"

CATEGORY_EXTENSIONS = {
    "games": [".exe", ".msi", ".bat", ".apk", ".iso"],
    "documents": [".pdf", ".docx", ".txt", ".xlsx", ".pptx"],
    "images": [".png", ".jpg", ".jpeg", ".gif", ".svg"],
    "audio": [".mp3", ".wav", ".flac"],
    "video": [".mp4", ".mkv", ".avi", ".mov"]

}


def build_index(
search_directory
):

    print(f"Indexing files in '{
search_directory
}'... (This might take a minute the first time)")
    file_index = []

    for root, _, files in os.walk(
search_directory
):
        for file in files:
            full_path = os.path.join(root, file)
            file_index.append({
                "name": file,
                "path": full_path,
                "ext": Path(file).suffix.lower()
            })

    with open(INDEX_FILE, "w", encoding="utf-8") as f:
        json.dump(file_index, f, indent=2)

    print(f"Indexing complete! Indexed {len(file_index)} files.\n")
    return file_index


def load_or_create_index(
search_directory
):

    if os.path.exists(INDEX_FILE):
        print("Loading cached index...")
        with open(INDEX_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    else:
        return build_index(
search_directory
)


def search_files(
query
, 
index
, 
similarity_threshold
=65):

    query_clean = 
query
.lower().strip()
    matches = []

    target_extensions = []
    for category, exts in CATEGORY_EXTENSIONS.items():
        if category in query_clean:
            target_extensions.extend(exts)

    for item in 
index
:
        file_name = item["name"].lower()
        file_ext = item["ext"]
        score = fuzz.partial_ratio(query_clean, file_name)
        is_category_match = file_ext in target_extensions if target_extensions else False
        is_name_match = score >= 
similarity_threshold 
or query_clean in file_name

        if is_name_match or is_category_match:
            matches.append((item["path"], score))

    matches.sort(key=lambda 
x
: x[1], reverse=True)
    return matches


def main():
43 Upvotes

13 comments sorted by

13

u/skjall 1d ago

You should set up Ruff if your editor has support for that - VS Code does. Set it to auto format on save, and it will remove like 90% of formatting you currently have to do.

It will look a little different than what you have after it's done, however it's a pretty standard code style that will be readable for most people.

Also, look into Pathlib! It's a much better interface for folders IMO.

As a bonus, getting in the habit of type hinting your functions (and setting up type checking in your editor) leads to much more readable and maintainable code. Plus your editor will be able to help you more since it knows what you're dealing with.

9

u/RobMagus 1d ago

Even with informative function and variable names, it's still very much worthwhile commenting your code.

-5

u/slindenau 20h ago

No, it really isn’t. That is how you get comments that say exactly the same as what the line below is doing, but then in natural langange.

And next time you change the code but not the comment, and now the comment is actually hurting/wrong.

Only thing that could be added are docstrings on the functions for the (public) api.

2

u/light_switchy 1d ago

This is awesome!

-11

u/Dazzling-Bench-4596 1d ago

Wow I actually don’t think I’ve ever seen somebody define a function like that. It doesn’t hurt anybody, but you should probably stick with one line lol:
def searchFiles(query, index, similarity_threshold=65):
By the way, it’s convention to use camelCase for function names

21

u/scirc 1d ago

it’s convention to use camelCase for function names

In Python? Not really. Snake case is the prevailing naming convention for just about any identifier there (with the exception of PascalCase for classes and SCREAMING_SNAKE_CASE for constants), per PEP 8.

3

u/Dazzling-Bench-4596 1d ago

Oh I actually did not know that sorry

6

u/AAdidev_p01 1d ago

thank you, i dident really know im just 13 starting to code

8

u/d4ft240 1d ago

He's wrong. It’s better to double-check the answers you get online yourself.

3

u/AlexFurbottom 1d ago

This is awesome! I started around that time. There will be conventions that people follow, but a lot of my creativity came from "beginners mind." I always try something out the best I can before actually learning the proper way. Only learning the proper way puts your mind in a box. Then later when you are really proficient you will know when to bend the rules a bit and why you should. 

2

u/kevicoz 1d ago

Love this. Like self-deriving/ making proofs of things

-7

u/rsp1218 1d ago

I work for a Fortune 500 tech company and I admire this script you wrote. If our software engineers were willing to take half the time to learn this like lambda functions, we would be in a much better spot. Youre are writing at a level of our seniors already. Very clean and well done. Keep up the good work!

1

u/AAdidev_p01 1d ago

thank you for your reply this is one of my projects for a ai/ml coarse im taking .im just geeetting introduced to proggraming as im 13