An entire file size retriever using a recursive os function in python I'm a beginner and i just started with automate the boring stuff with python course and reached his first os lesson, so i decided to make a recursive directory size finder since apparently os.path.getsize doesn't get the size of folders.
Need a way to improve my code or advice on coding tricks, to make it more efficient

import os
class FileSizeFinder:

    def calculate_directory_size_in_bytes(self, directory: str, totalsize=0):
        for filename in tuple(os.listdir(directory)):
            current_directory = os.path.join(directory, filename)
            if os.path.isdir(current_directory):
                totalsize += FileSizeFinder.calculate_directory_size_in_bytes("self", current_directory)
            if not os.path.isfile(current_directory):
                continue
            totalsize += os.path.getsize(current_directory)
        return totalsize

    def get_file_size(self, directory: str, totalsize=0):
        total_size_in_bytes = FileSizeFinder.calculate_directory_size_in_bytes("self", directory)
        if total_size_in_bytes &gt; 1024000000:
            totalsize = "Size in GB: " + str(round(total_size_in_bytes / 1024000000, 3))
        elif total_size_in_bytes &gt; 1024000:
            totalsize = "Size in MB: " + str(round(total_size_in_bytes/ 1024000, 3))
        elif total_size_in_bytes &gt; 1024:
            totalsize = "Size in KB: " + str(round(total_size_in_bytes / 1024, 3))
        return totalsize

print(FileSizeFinder.get_file_size("self", r"E:\Utilities_and_Apps\Python"))
If there's no reason to make it a class, don't make it a class.  (A good clue is that your class doesn't have any instance variables, and that both of its methods could be static without changing the way they work.)
Both of your functions return the same information (formatted differently), but one calls it file_size and the other calls it directory_size even though it's the same number.  In addition, neither has a type annotation for the return value.  This all adds up to make it hard to figure out what each function does.  Maybe it'd be better to just have one function that gets the size and a seperate one that formats it as a string?
The totalsize parameter does not seem to serve any purpose as a parameter, and should be removed.
There's no reason to convert os.listdir into a tuple; you can iterate over it as-is.
current_directory is not necessarily a directory, so this name is confusing.
Your size formatting logic has an obvious gap in its if...elif chain.  Adding an else case fixes that.
This is a style thing, but I think f-strings are nicer looking than explicitly converting to str and using concatenation.
Your GB/MB/KB definitions are both copy+pasted and wrong.  Maybe this whole if...elif construction could be done more cleanly by turning the unit definitions into a table (where each unit size is defined exactly once) and iterating over the table?
Your recursive function would actually be simpler if it accepted any arbitrary path.  That way you wouldn't have to do as much logic inside the body of your iteration over the os.listdir results, and could actually just do it as a simple sum of recursive calls.
It's easier to test your code if you write a __main__ block that accepts a command line parameter!


Here's my massaged version of your code (does basically the same thing, but it uses the units as I've defined them rather than your hybrid 1024 * 10^N units -- having them defined the way I did it here makes it very easy to change if you'd rather make them 2^10, 2^20, etc).

import os
import sys

def recursive_get_size(path: str) -&gt; int:
    """Gets size in bytes of the given path, recursing into directories."""
    if os.path.isfile(path):
        return os.path.getsize(path)
    if not os.path.isdir(path):
        return 0
    return sum(
        recursive_get_size(os.path.join(path, name))
        for name in os.listdir(path)
    )

def format_size(num_bytes: int) -&gt; str:
    """Formats a size (given in bytes) into a human-readable string."""
    for unit_name, unit_size in [
        ("GB", 10**9),
        ("MB", 10**6),
        ("KB", 10**3),
    ]:
        if num_bytes &gt; unit_size:
            return f"Size in {unit_name}: {round(num_bytes / unit_size, 3)}"
    else:
        return f"Size in bytes: {num_bytes}"

if __name__ == '__main__':
    print(format_size(recursive_get_size(
        sys.argv[1] if len(sys.argv) &gt; 1 else r"E:\Utilities_and_Apps\Python"
    )))