NEWBIE: ishexdigit revisited

Paul Rubin http
Mon Dec 29 18:34:03 EST 2003


engsolnom at ipns.com writes:
> After looking at the suggestions for a ishexdigit method, (thanks
> again), I decided on the following, partly because I don't have to
> import string, and I believe it's pretty readable by Python newbies,
> which we (including myself) have at work:
> 
> def ishexdigit(sx):
>     ix = 0
>     for cx in sx:
>         ix += 1
>         if not cx in '0123456789abcdefABCDEF': return 0
>     if ix % 2 == 0: return 1
>     else: return 'Extra nibble'

Some remarks:

1) I think the name is a misnomer: "ishexdigit" should test just one
digit, not a multi-digit string.  This function should be called
"ishexnumber" instead.

2) I'm not sure why you return 'extra nibble' if there's an odd number
of digits.  Isn't '123' a perfectly good hex number (= 291 decimal)?

3) Even if you do want to check that the length is odd, you don't
   need to count the chars in the loop:

     def ishexnumber(sx):
         for cx in sx:
             if not cx in '0123456789abcdefABCDEF': return 0
         if len(sx) % 2 == 0: return 1
         return 'Extra nibble'

   (the final 'else' is not needed)

4) You could also use a regular expression to test for hex digits:

     def ishexnumber(sx):
         import re
         if not re.match('[0123456789abcdefABCDEF]*$', sx): return 0
         if len(sx) % 2 == 0: return 1
         return 'Extra nibble'

5) If you want the number of bytes to be even because the hex string
   is supposed to represent a character string, and you're going to
   do the conversion next, there's already a library function for that:

      import binascii     
      s = binascii.unhexlify(sx)

6) If you want it to be a number but still need the digit count to
   be even for some reason, then checking for the special value 
   'Extra nibble' is messy.  It's usually better to raise an exception
   instead:

     def ishexnumber(sx):
         for cx in sx:
             if not cx in '0123456789abcdefABCDEF': return 0
         if len(sx) % 2 != 0:
             raise ValueError, 'Extra nibble in hex string'
         return 1

   The caller then has to catch the exception, of course.

7) If you want to just check that the hex string represents an
   integer, possibly the most robust way is:

     def ishexnumber(sx):
         try:
             n = int(sx, 16)
         except ValueError:
             return 0
         return 1

   Note this will fail for hex strings are too long to fit in a short int.




More information about the Python-list mailing list