Jan-17-2023, 05:02 AM
(This post was last modified: Jan-17-2023, 05:02 AM by deanhystad.)
If it can run on anything, using backslash is a bad idea. If you are running this on Mac or Linux, looking for '\\' is guaranteed to fail.
When posting code, post the least amount of code needed to demonstrate the problem. I would make a copy of the code and start removing things. My first pass would look like this:
That would lead to my second attempt.
I think about other ways my code might fail. I write better tests using unittest.
While learning about unit test and reading posts about getting just the filename without path or extension, I saw pathlib mentioned. I read up on pathlib and it sounds like it does what I need. I write a new version of my function that uses pathlib.
Since my function is only 1 line long, I question whether I need the function at all. I modify my program to use pathlib instead of writing my own functions that I need to test and maintain.
When posting code, post the least amount of code needed to demonstrate the problem. I would make a copy of the code and start removing things. My first pass would look like this:
def findFilename(details): fullpath = details[::-1] filename = "" for index, letter in enumerate(fullpath): if index > 3: print(letter) if letter == "\\": break filename = filename + letter print(filename[::-1]) filename = r"C:\this\is\a\test.txt" findFilename(filename) print(filename)
Output:t
s
e
t
\
test
C:\this\is\a\test.txt
This would demonstrate that the findFilename function kind of works, but it doesn't change the value of "filename". "filename" inside findFilename() is not the same as filename outside the function. These are two completely different variables that just happen to have the same hame. You would search for this problem online and learn that using variables to return values from a function is a bad idea, You should use the return statement.That would lead to my second attempt.
def findFilename(details): fullpath = details[::-1] filename = "" for index, letter in enumerate(fullpath): if index > 3: if letter == "\\": break filename = filename + letter return filename[::-1] filename = findFilename(r"C:\this\is\a\test.txt") print(filename)
Output:test
That appears to work, so next I might write some quick and dirty tests,def findFilename(details): fullpath = details[::-1] filename = "" for index, letter in enumerate(fullpath): if index > 3: if letter == "\\": break filename = filename + letter return filename[::-1] assert findFilename(r"C:\this\is\a\test.txt") == "test" assert findFilename(r"C:\test.txt") == "test" assert findFilename(r"C:\test") == "test"
Error:line 15, in <module>
assert findFilename(r"C:\test") == "test"
AssertionError
This points out that my code is sensitive to the length of the extension. If I select a file without a three letter extension, it fails.I think about other ways my code might fail. I write better tests using unittest.
import unittest def findFilename(details): fullpath = details[::-1] filename = "" for index, letter in enumerate(fullpath): if index > 3: if letter == "\\": break filename = filename + letter return filename[::-1] class TestFindFilename(unittest.TestCase): def test_normal(self): self.assertEqual(findFilename(r"C:\this\isa\test.txt"), "test") def test_no_path(self): self.assertEqual(findFilename(r"test.txt"), "test") def test_no_extension(self): self.assertEqual(findFilename(r"C:\test"), "test") def test_long_extension(self): self.assertEqual(findFilename(r"C:\test.text"), "test") def test_short_extension(self): self.assertEqual(findFilename(r"C:\test.text"), "tt") def test_slashes(self): self.assertEqual(findFilename("/this/isa/test.txt"), "test") if __name__ == "__main__": unittest.main()
Output:======================================================================
FAIL: test_long_extension (__main__.TestFindFilename)
----------------------------------------------------------------------
Traceback (most recent call last):
File "c:\Users\hystadd\Documents\python\sandbox\junk2.py", line 27, in test_long_extension
self.assertEqual(findFilename(r"C:\test.text"), "test")
AssertionError: 'test.' != 'test'
- test.
? -
+ test
======================================================================
FAIL: test_no_extension (__main__.TestFindFilename)
----------------------------------------------------------------------
Traceback (most recent call last):
File "c:\Users\hystadd\Documents\python\sandbox\junk2.py", line 24, in test_no_extension
self.assertEqual(findFilename(r"C:\test"), "test")
AssertionError: '' != 'test'
+ test
======================================================================
FAIL: test_short_extension (__main__.TestFindFilename)
----------------------------------------------------------------------
Traceback (most recent call last):
File "c:\Users\hystadd\Documents\python\sandbox\junk2.py", line 30, in test_short_extension
self.assertEqual(findFilename(r"C:\testtt"), "test")
AssertionError: 'tes' != 'test'
- test.
+ tt
======================================================================
FAIL: test_slashes (__main__.TestFindFilename)
----------------------------------------------------------------------
Traceback (most recent call last):
File "c:\Users\hystadd\Documents\python\sandbox\junk2.py", line 33, in test_slashes
self.assertEqual(findFilename("/this/isa/test.txt"), "test")
AssertionError: '/this/isa/test' != 'test'
- /this/isa/test
+ test
----------------------------------------------------------------------
Ran 6 tests in 0.003s
FAILED (failures=4)
Only 2 tests passed! I have a problem with short, long, or missing extensions. I also have a problem with slash vs backslash. I think linux uses slash, so this is a problem if I want to run on linux.While learning about unit test and reading posts about getting just the filename without path or extension, I saw pathlib mentioned. I read up on pathlib and it sounds like it does what I need. I write a new version of my function that uses pathlib.
from pathlib import Path import unittest def findFilename(filedescr): return Path(filedescr).stem class TestFindFilename(unittest.TestCase): def test_normal(self): self.assertEqual(findFilename(r"C:\this\isa\test.txt"), "test") def test_no_path(self): self.assertEqual(findFilename(r"test.txt"), "test") def test_no_extension(self): self.assertEqual(findFilename(r"C:\test"), "test") def test_long_extension(self): self.assertEqual(findFilename(r"C:\test.text"), "test") def test_short_extension(self): self.assertEqual(findFilename(r"C:\test.tt"), "test") def test_slashes(self): self.assertEqual(findFilename("/this/isa/test.txt"), "test") if __name__ == "__main__": unittest.main()
Output:......
----------------------------------------------------------------------
Ran 6 tests in 0.001s
OK
All 6 tests pass!Since my function is only 1 line long, I question whether I need the function at all. I modify my program to use pathlib instead of writing my own functions that I need to test and maintain.