Strategy/ Advice for How to Best Attack this Problem?
Saran A
ahlusar.ahluwalia at gmail.com
Fri Apr 3 09:40:45 EDT 2015
On Friday, April 3, 2015 at 6:46:21 AM UTC-4, Peter Otten wrote:
> Saran A wrote:
>
> > I debugged and rewrote everything. Here is the full version. Feel free to
> > tear this apart. The homework assignment is not due until tomorrow, so I
> > am currently also experimenting with pyinotify as well.
>
> Saran, try to make a realistic assessment of your capability. Your
> "debugged" code still has this gem
>
> > while True:
> > time.sleep(1) #time between update check
>
> and you are likely to miss your deadline anyway.
>
> While the inotify approach may be the "right way" to attack this problem
> from the point of view of an experienced developer like Chris as a newbie
> you should stick to the simplest thing that can possibly work.
>
> In a previous post I mentioned unit tests, but even an ad-hoc test in the
> interactive interpreter will show that your file_len() function doesn't work
>
> > #returns length of file
> > def file_len(f):
> > with open(f) as f:
> > for i, l in enumerate(f):
> > pass
> > return i + 1
> >
>
> $ python
> Python 2.7.6 (default, Mar 22 2014, 22:59:56)
> [GCC 4.8.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>> #returns length of file
> ... def file_len(f):
> ... with open(f) as f:
> ... for i, l in enumerate(f):
> ... pass
> ... return i + 1
> ...
> >>> with open("tmp.txt", "w") as f: f.write("abcde")
> ...
> >>> file_len("tmp.txt")
> 1
>
> It reports size 1 for every file.
>
> A simple unit test would look like this (assuming watchscript.py is the name
> of the script to be tested):
>
> import unittest
>
> from watchscript import file_len
>
> class FileLen(unittest.TestCase):
> def test_five(self):
> LEN = 5
> FILENAME = "tmp.txt"
> with open(FILENAME, "w") as f:
> f.write("*" * LEN)
>
> self.assertEqual(file_len(FILENAME), 5)
>
> if __name__ == "__main__":
> unittest.main()
>
> Typically for every tested function you add a new TestCase subclass and for
> every test you perform for that function you add a test_...() method to that
> class. The unittest.main() will collect these methods, run them and generate
> a report. For the above example it will complain:
>
> $ python test_watchscript.py
> F
> ======================================================================
> FAIL: test_five (__main__.FileLen)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "test_watchscript.py", line 12, in test_five
> self.assertEqual(file_len(FILENAME), 5)
> AssertionError: 1 != 5
>
> ----------------------------------------------------------------------
> Ran 1 test in 0.001s
>
> FAILED (failures=1)
>
>
> The file_len() function is but an example of the many problems with your
> code. There is no shortcut, you have to decide for every function what
> exactly it should do and then verify that it actually does what it is meant
> to do. Try to negotiate an extra week or two with your supervisor and then
> start small:
>
> On day one make a script that moves all files from one directory to another.
> Make sure that the source and destination directory are only stored in one
> place in your script so that they can easily be replaced. Run the script
> after every change and devise tests that demonstrate that it works
> correctly.
>
> On day two make a script that checks all files in a directory. Put the
> checks into a function that takes a file path as its only parameter.
> Write a few correct and a few broken files and test that only the correct
> ones are recognized as correct, and only the broken ones are flagged as
> broken, and that all files in the directory are checked.
>
> On day three make a script that combines the above and only moves the
> correct files into another directory. Devise tests to verify that both
> directories contain the expected files before and after your script is
> executed.
>
> On day four make a script that also moves the bad files into another
> directory. Modify your tests from the previous day to check the contents of
> all three directories.
>
> On day five wrap your previous efforts in a loop that runs forever.
> I seems to work? You are not done. Write tests that demonstrate that it does
> work. Try to think of the corner cases: what if there are no new files on
> one iteration? What if there is a new file with the same name as a previous
> one? Don't handwave, describe the reaction of your script in plain English
> with all the gory details and then translate into Python.
>
> Heureka!
>
> Note that a "day" in the above outline can be 15 minutes or a week. You're
> done when you're done. Also note that the amount of code you have written
> bears no indication of how close you are to your goal. An experienced
> programmer will end up with less code than you to fulfill the same spec.
> That shouldn't bother you. On the other hand you should remove code that
> doesn't contribute to your script's goal immediately. If you keep failed
> attempts and side tracks your code will become harder and harder to
> maintain, and that's the last thing you need when it's already hard to get
> the necessary parts right.
>
> Good luck!
@Peter: Thank you emphasizing unit testing. I will be sure to be more mindful regarding this moving forward. FYI I addressed those "gems" :) It's amazing what some sleep can do.
More information about the Python-list
mailing list