2
\$\begingroup\$

Here is my code for simplifying a Unix path. Any advice is highly appreciated, including higher efficiency from an algorithm time complexity perspective, or any bugs.

'''
Simplify Unix path
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
'''

def simplify_path(original_path):
    result = []
    levels = original_path.split('/')
    for level in levels:
        if level == '.':
            continue
        elif level == '..':
            result.pop(-1)
        else:
            result.append(level)

    result_str = '/'.join(result)
    return result_str[0:len(result_str)-1]

if __name__ == "__main__":
    print simplify_path('/a/./b/../../c/')
    print simplify_path('/home/')
\$\endgroup\$
  • \$\begingroup\$ @Dex'ter, for sure, in the 2nd example, the 2nd / is useless, since /home/ is the same as /home, where the latter one is more simplified. If you have any advice on original question, it will be great. :) \$\endgroup\$ – Lin Ma Dec 6 '16 at 6:56
  • 1
    \$\begingroup\$ If you like an answer, you can up-vote it (as soon as you reach 15 reputation). If after some time (usually at least a day is recommended to give people in other time-zones also the chance to answer), you find that you like one answer best, you can accept it using the green check mark to the left of the post. \$\endgroup\$ – Grajdeanu Alex. Dec 7 '16 at 10:24
  • 2
    \$\begingroup\$ What should the simplification of /foo//bar/quux look like? \$\endgroup\$ – Vatine Dec 8 '16 at 15:49
  • 1
    \$\begingroup\$ You can always compare yours to Pythons std-lib... \$\endgroup\$ – Peilonrayz Dec 9 '16 at 17:40
  • \$\begingroup\$ @Vatine, I think it should be /foo/bar/quux, if you have any ideas on my original code and related questions, it will be great. Especially functional bugs or performance improvements. \$\endgroup\$ – Lin Ma Dec 11 '16 at 5:05
3
\$\begingroup\$

OK, due to the fact the OP wants to practice his coding skills, and does not want an already built-in solution, I'll try commenting on his actual code.

Fix the bug

If your path looks like this:

simplify_path('/home/dexter')

You'll get as a result:

/home/dexte

To fix this, you should slightly change your return statement:

def simplify_path(original_path):
    ...
    return result_str[0:len(result_str) - 1] if result_str.endswith('/') else result_str[0:len(result_str)]

Apart from the above fix, I think your solution is ok.

\$\endgroup\$
  • \$\begingroup\$ Nice comment, Dex' ter, vote up. \$\endgroup\$ – Lin Ma Dec 11 '16 at 5:08
  • \$\begingroup\$ I see you have a sign ..., what it is for? \$\endgroup\$ – Lin Ma Dec 11 '16 at 5:10
  • \$\begingroup\$ BTW, appreciate for all the comments, mark your reply as answer before we discussed further topics. :) \$\endgroup\$ – Lin Ma Dec 11 '16 at 7:02
5
\$\begingroup\$

There's definitely an easier way of doing this. You can use os.path.realpath() to get the canonical path.

os.path.realpath(path)
Return the canonical path of the specified filename, eliminating any symbolic links encountered in the path (if they are supported by the operating system).

Example:

from os.path import realpath


def simplify_path(original_path):
"""
Given an absolute path for a file, simplify it
"""
    return realpath(original_path)

if __name__ == '__main__':
    print(simplify_path('/a/./b/../../c/'))
    print(simplify_path('/home/'))
[dexter@localhost]$ python simplify_path.py 
/c
/home
\$\endgroup\$
  • \$\begingroup\$ Thanks Dex' ter, the purpose of this question is to implement realpath from scratch. It is not always meaningful, and it is just a coding exercise to practice coding skills. If you have any ideas how to implement from scratch, it will be great. \$\endgroup\$ – Lin Ma Dec 8 '16 at 4:59
  • 3
    \$\begingroup\$ În that case, I'd very much like you to add the reinventing-the-wheel tag to your question. Keep this in mind for your other similar questions \$\endgroup\$ – Grajdeanu Alex. Dec 8 '16 at 6:14
  • \$\begingroup\$ Thanks Dex' ter, I buy-in what you recommended, for this question, it is more about a coding exercise for good (bug free and good performance) python code, than the function I implement itself. If you have any ideas on my original code and related questions, it will be great. Especially functional bugs or performance improvements. BTW, sometimes it is a bit sensitive I cannot post real issues I am working on, so I can only post some common understandable questions for review here. thanks for the understanding. :) \$\endgroup\$ – Lin Ma Dec 11 '16 at 5:08

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.