[Tutor] Better printing?

Kent Johnson kent37 at tds.net
Mon Jan 22 12:05:21 CET 2007


Steve Nelson wrote:
> Hello,
> 
> See below a program that will go through a directory and for each file
> print user, group, size and md5sum.
> 
> A few questions:
> 
> 1) It seems to fall over if I pass "." as a directory - how can I stop this?

Falls over how?

> 2) When I wrote the methods I decided to do isafile() checks there,
> but subsequently realised that in __main__ it would print out None for
> each non-file, so I put the check in here too.  Which is better?  Or
> is there a better approach?

Are the checks needed in the individual methods? What happens if they 
are passed a non-file? Since you are checking in the main loop, do you care?

> 3) How can I get this to print in a format that makes it easy to read?
> ie tabulated so that the info is presented in aligned columns?

You can print with fixed fields using the string formatting operations.
http://docs.python.org/tut/node9.html#SECTION009100000000000000000
http://docs.python.org/lib/typesseq-strings.html

If you want something even fancier then look at this recipe:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/267662

> def getSize(fn):
>   """Get the size of a file in kb"""
>   fp = os.path.join(wp, fn)
>   if os.path.isfile(fp):
>     return os.stat(fp).st_size
> 
> def getUser(fn):
>   """Get username of file owner."""
>   fp = os.path.join(wp, fn)
>   if os.path.isfile(fp):
>     uid = os.stat(fp).st_uid
>     return pwd.getpwuid(uid).pw_name
> 
> def getGroup(fn):
>   """Get the group name of the file owner."""
>   fp = os.path.join(wp, fn)
>   if os.path.isfile(fp):
>     gid = os.stat(fp).st_gid
>     return grp.getgrgid(gid).gr_name

These functions are using the global variable wp. A better design would 
be to compute the full file path once in the main loop and pass it in.

The above three functions have a lot in common and they are always 
called together. You could combine them into one function that returns a 
tuple of size, user, group.

Kent

> 
> def md5Sum(fn):
>   """Get md5sum for a file."""
>   fp = os.path.join(wp, fn)
>   if os.path.isfile(fp):
>     try:
>       fo = open(fp, 'rb')
>     except (IOError, OSError):
>       print "Could not open file '%s', skipping..." % fp
>       return None
>     else:
>       m = md5.new(fo.read()).hexdigest()
>       fo.close()
>     return m
> 
> # Classes
> 
> # Unit tests
> 
> class UnitTests(unittest.TestCase):
>   """Do not taunt unit tests."""
> 
>   def testGetSize(self):
>     """Get the size of a file in kb"""
>     self.assertEqual(getSize("foo"), 24)
> 
>   def testGetUser(self):
>     """Get the username of the file owner"""
>     self.assertEqual(getUser("foo"), "nelsonst")
> 
>   def testGetGroup(self):
>     """Get the group name of the file owner"""
>     self.assertEqual(getGroup("foo"), "staff")
> 
>   def testMd5Sum(self):
>     """Get md5sum for file."""
>     self.assertEqual(md5Sum("foo"), "faac88479f39ba498e827622a2a4d649")
> 
> def doTests():
>   suite = unittest.makeSuite(UnitTests,'test')
>   runner = unittest.TextTestRunner()
>   result = runner.run(suite)
> 
> if __name__ == "__main__":
>   doTests()
>   for f in os.listdir(wp):
>     if os.path.isfile(os.path.join(wp, f)):
>       print f, getSize(f), getUser(f), getGroup(f), md5Sum(f)
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 
> 




More information about the Tutor mailing list