Created
November 22, 2012 15:11
-
-
Save blandry/4131632 to your computer and use it in GitHub Desktop.
A basic path normalizer I wrote for a job interview.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import unittest | |
def normalize(path): | |
## To keep the path pointing to the same place, relative paths should stay | |
## relative, and absolute paths should stay absolute. I decided to treat the | |
## ending the same way for consistency | |
folders = re.split('/', path) | |
normalized_folders = list() | |
for folder in folders: | |
if folder == '..': | |
try: | |
if normalized_folders[-1] != '': # this is false if you are trying to exit the root directory | |
normalized_folders.pop(-1) | |
except IndexError: | |
## I assumed wathever the input, we want the output to be a valid | |
## path pointing to the same place, therefore I do not do change parts of | |
## the path for which I do not have enough information to normalize. The only | |
## exception being that exiting the root keeps you in the root. | |
normalized_folders.append(folder) | |
elif folder != '.': | |
normalized_folders.append(folder) | |
normalized_path = '/'.join(normalized_folders) | |
return normalized_path | |
class TestNormalize(unittest.TestCase): | |
def test_current_dir(self): | |
cases = [("foo/./bar", "foo/bar"), | |
("foo/bar/./baz", "foo/bar/baz"), | |
("./foo/bar", "foo/bar"),] | |
for input, exp_output in cases: | |
self.assertEqual(normalize(input), exp_output) | |
def test_parent_dir(self): | |
cases = [("foo/bar/../baz", "foo/baz"), | |
("/foo/bar/..", "/foo"),] | |
for input, exp_output in cases: | |
self.assertEqual(normalize(input), exp_output) | |
def test_hybrid(self): | |
cases = [("foo/./bar/../baz", "foo/baz"), | |
("foo/../bar/./baz/..", "bar"),] | |
for input, exp_output in cases: | |
self.assertEqual(normalize(input), exp_output) | |
def test_no_op(self): | |
cases = [("foo/bar//baz", "foo/bar//baz"),] | |
for input, exp_output in cases: | |
self.assertEqual(normalize(input), exp_output) | |
def test_edge_cases(self): | |
""" Theses tests do not cover features that were in specs, | |
rather they test behaviours that I have assumed were desired | |
(i.e. they are implementation specific). My implementation always | |
makes sure that the paths stay valid and point to the same place | |
even if they cannot be normalized. | |
""" | |
cases = [("../foo/bar", "../foo/bar"), | |
("foo/bar/../../../", "../"), | |
("/./foo/baz", "/foo/baz")] | |
for input, exp_output in cases: | |
self.assertEqual(normalize(input), exp_output) | |
## this is a very special case, trying to exit the root folder. | |
## Most OS will simply keep you in the root folder, and my | |
## implementation does the same | |
input, exp_output = ("/../foo/bar", "/foo/bar") | |
self.assertEqual(normalize(input), exp_output) | |
if __name__ == "__main__": | |
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
public class Normalizer { | |
private ArrayList<int> primes; | |
public Normalizer() { | |
primes = new ArrayList<int>(); | |
} | |
public static String normalize(String path){ | |
String[] folders = path.split("/"); | |
ArrayList<String> normalized_folders = new ArrayList<String>(); | |
for (String folder : folders){ | |
if (folder.equals("..")){ | |
try { | |
if (!normalized_folders.get(normalized_folders.size()-1).equals("")) { | |
normalized_folders.remove(normalized_folders.size()-1); | |
} | |
} | |
catch(ArrayIndexOutOfBoundsException e) { | |
normalized_folders.add(folder); | |
} | |
} else if (!folder.equals(".")) { | |
normalized_folders.add(folder); | |
} | |
} | |
String normalized_path = new String(); | |
for (int i=0; i<=normalized_folders.size()-1; i++) { | |
normalized_path += normalized_folders.get(i); | |
if (i!=normalized_folders.size()-1){ | |
normalized_path += "/"; | |
} | |
} | |
return normalized_path; | |
} | |
public static void main(String[] args){ | |
String input = "foo/./bar"; | |
System.out.println("Input was: "+input); | |
System.out.println("Output is: "+normalize(input)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment