Search code examples
pythonrecursiondirectorydirectory-structure

Python Implementation of Folder Directory in Console


I am given an array of arrays in which I am to simulate a folder system based off of the given. For example:

Given = [[('folder1',), 'file1'], [('folder2',), 'file2', [('folder3',), 'file3', 'file4']]]

The output should be:

folder1
└───file1
folder2
├───file2
└───folder3
    ├───file3
    └───file4

Folders are identified as the first of every array, and they are in tuples, while files are just strings inside the arrays.

I have an initial code but it's not outputting the the right result. There are mistakes in generating ├───, └───, etc. How do we recursively implement this?

Here's my code:

arrayOfArrays = [[('folder1',), 'file1'], [('folder2',), 'file2', [('folder3',), 'file3', 'file4']]]
def sChar(indent):                        # Creates the indentation and
    if indent > 1:                        # Special Characters
        print("│", end='')
        while indent != 1:
            print("   ", end='')
            indent-=1
    if indent == 1:
        print("├───", end='')
        
def folderDirectory(directory, indent = 0):
    for i in range(len(directory)):
        if isinstance(directory[i], tuple):
            sChar(indent)
            print(directory[i][0])
            indent+=1
        elif isinstance(directory[i], list):
            folderDirectory(directory[i], indent)
        else:
            sChar(indent)
            print(directory[i])
            
folderDirectory(arrayOfArrays)

Actual Output:

folder1
├───file1
folder2
├───file2
├───folder3
│   ├───file3
│   ├───file4

Test Case 2:

Given: [('folder1',), [('folder2',), 'file1', 'file2', 'file3', 'file4', 'file5', 'file6', 'file7'], 'file8', 'file9', [('folder3',), 'file10', 'file11', 'file12'], 'file13']

Expected Output:

folder1
├───folder2
│   ├───file1
│   ├───file2
│   ├───file3
│   ├───file4
│   ├───file5
│   ├───file6
│   └───file7
├───file8
├───file9
├───folder3
│   ├───file10
│   ├───file11
│   └───file12
└───file13

Test Case 3:

Given: [[('folder1',)], [('folder2',), [('folder3',), 'file2', 'file3']], [('folder4',), [('folder5',), 'file4']]]

Expected:

folder1
folder2
└───folder3
    ├───file3
    └───file2
folder4
└───folder5
    └───file4

Test Case 4:

Given: [('folder1',), [('folder2',), [('folder3',), 'file2', 'file3']], [('folder3',), [('folder4',), 'file4', 'file5']]]

Expected:

folder1
├───folder2
│   └───folder3
│       ├───file2
│       └───file3
└───folder3
    └───folder4
        ├───file4
        └───file5

Worst Case (Folders are placed before files, depth of 10)

[('f01',), [('f02',), [('f03',), [('f04',), [('f05',), [('f06',), [('f07',), [('f08',), [('f09',), [('f10',), 'g09', 'g10'], 'g08'], 'g07'], 'g06'], 'g05'], 'g04'], 'g03'], 'g02'], 'g01'], [('f11',), 'g11']]

f01
├───f02
│   ├───f03
│   │   ├───f04
│   │   │   ├───f05
│   │   │   │   ├───f06
│   │   │   │   │   ├───f07
│   │   │   │   │   │   ├───f08
│   │   │   │   │   │   │   ├───f09
│   │   │   │   │   │   │   │   ├───f10
│   │   │   │   │   │   │   │   │   ├───g09
│   │   │   │   │   │   │   │   │   └───g10
│   │   │   │   │   │   │   │   └───g08
│   │   │   │   │   │   │   └───g07
│   │   │   │   │   │   └───g06
│   │   │   │   │   └───g05
│   │   │   │   └───g04
│   │   │   └───g03
│   │   └───g02
│   └───g01
└───f11
    └───g11

You can use this code to use the special characters

import sys
sys.stdout.reconfigure(encoding='utf-8')

Latest code (Works!)

import sys
sys.stdout.reconfigure(encoding='utf-8')

def lister(directory, ind=0, f = True):
    yield f'{(("    "*(ind-1)) if not f else "")}{"" if not ind else ""*(ind-1)+("" if f else "└")+"───"}'+directory[0][0]
    for i, a in enumerate(directory[1:]):
        if isinstance(a, str):
            yield f'{(("    "*(ind)) if not f else "") + ("└" if i == len(directory[1:]) - 1 else "├")+"───"}'+a
        else:
            for k in lister(a, ind=ind+1, f= i + 1 != len(directory[1:])):
                yield ('│' if not k.startswith("─") else "├") +("" if k.startswith("───") else '   ' if not k.startswith('   ') else '')+k if i + 1 != len(directory[1:]) else k
                
def get_results(s):
  for i in ([s] if isinstance(s[0], tuple) else s):
     print('\n'.join(lister(i)))
     
data = [('f01',), [('f02',), [('f03',), [('f04',), [('f05',), [('f06',), [('f07',), [('f08',), [('f09',), [('f10',), 'g09', 'g10'], 'g08'], 'g07'], 'g06'], 'g05'], 'g04'], 'g03'], 'g02'], 'g01'], [('f11',), 'g11']]
get_results(data)

Solution

  • You can slightly tweak your recursion and use ascii characters , and :

    import re
    def get_struct(folder, ind=0, f = True):
       yield f'{(("    "*(ind-1)) if not f else "")}{"" if not ind else ""*(ind-1)+("" if f else "└")+"───"}'+folder[0][0]
       for i, a in enumerate(folder[1:]):
         if isinstance(a, str):
            yield f'{(("    "*(ind)) if not f else "") + ("└" if i == len(folder[1:]) - 1 else "│")+"───"}'+a
         else:
            for k in get_struct(a, ind=ind+1, f= i + 1 != len(folder[1:])):
              yield '│'+("" if k.startswith("───") else '    ' if not k.startswith('    ') else '')+k if i + 1 != len(folder[1:]) else k
    
    def get_results(s):
      for i in ([s] if isinstance(s[0], tuple) else s):
         print('\n'.join(get_struct(i)))
    
    data = [('f01',), [('f02',), [('f03',), [('f04',), [('f05',), [('f06',), [('f07',), [('f08',), [('f09',), [('f10',), 'g09', 'g10'], 'g08'], 'g07'], 'g06'], 'g05'], 'g04'], 'g03'], 'g02'], 'g01'], [('f11',), 'g11']]
    
    get_results(data)
    data1 = [('folder1',), [('folder2',), [('folder3',), 'file2', 'file3']], [('folder3',), [('folder4',), 'file4', 'file5']]]
    get_results(data1)
    data2 = [('folder1',), [('folder2',), 'file1', 'file2', 'file3', 'file4', 'file5', 'file6', 'file7'], 'file8', 'file9', [('folder3',), 'file10', 'file11', 'file12'], 'file13']
    get_results(data2)
    data3 = [[('folder1',), 'file1', [('folder1',), 'file1']], [('folder2',), 'file2', [('folder3',), 'file3', 'file4']]]
    get_results(data3)
    

    Output(1):

    f01
    │───f02
    │    │───f03
    │    │    │───f04
    │    │    │    │───f05
    │    │    │    │    │───f06
    │    │    │    │    │    │───f07
    │    │    │    │    │    │    │───f08
    │    │    │    │    │    │    │    │───f09
    │    │    │    │    │    │    │    │    │───f10
    │    │    │    │    │    │    │    │    │    │───g09
    │    │    │    │    │    │    │    │    │    └───g10
    │    │    │    │    │    │    │    │    └───g08
    │    │    │    │    │    │    │    └───g07
    │    │    │    │    │    │    └───g06
    │    │    │    │    │    └───g05
    │    │    │    │    └───g04
    │    │    │    └───g03
    │    │    └───g02
    │    └───g01
    └───f11
        └───g11
    

    Output(2):

    folder1
    │───folder2
    │    └───folder3
    │        │───file2
    │        └───file3
    └───folder3
        └───folder4
            │───file4
            └───file5
    

    Output(3):

    folder1
    │───folder2
    │   │───file1
    │   │───file2
    │   │───file3
    │   │───file4
    │   │───file5
    │   │───file6
    │   └───file7
    │───file8
    │───file9
    │───folder3
    │   │───file10
    │   │───file11
    │   └───file12
    └───file13
    

    Output(4):

    folder1
    │───file1
    └───folder1
        └───file1
    folder2
    │───file2
    └───folder3
        │───file3
        └───file4