I forgot to handle upper case. Note that the following is  (~5%)
faster than calling .upper() on the input::

    _phone_chars = {
        'a': '2',
        'b': '2',
        'c': '2',
        'd': '3',
        'e': '3',
        'f': '3',
        'g': '4',
        'h': '4',
        'i': '4',
        'j': '5',
        'k': '5',
        'l': '5',
        'm': '6',
        'n': '6',
        'o': '6',
        'p': '7',
        'q': '7',
        'r': '7',
        's': '7',
        't': '8',
        'u': '8',
        'v': '8',
        'w': '9',
        'x': '9',
        'y': '9',
        'z': '9',
        }
    _phone_chars_compiled = None

    def phone2numeric(value):
        global _phone_chars_compiled
        if _phone_chars_compiled is None:
            _phone_chars_compiled = {}
            for i in range(256):
                a = chr(i)
                b = a.upper()
                _phone_chars_compiled[a] = _phone_chars.get(a, a)
                _phone_chars_compiled[b] = _phone_chars.get(b, b)

        return ''.join(map(_phone_chars_compiled.__getitem__, value))

Of course, premature optimization is the root of all evil. There is
certainly a lot more code here, and I'm not sure phone2numeric is that
often called in applications. (As opposed to database/template
operations.) I'll leave you with a great comment on python
optimization [1].

Cheers,
Mike

1: http://www.codeirony.com/?p=9

On Fri, Jan 15, 2010 at 9:15 AM, Mike Axiak <m...@axiak.net> wrote:
> If you really want to be fast, you can do the following, a la urllib.quote::
>
>    _phone_chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>             'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k':
> '5', 'l': '5',
>             'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r':
> '7', 's': '7',
>             't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y':
> '9', 'z': '9',
>             }
>    _phone_chars_compiled = None
>
>    def phone2number(szinput):
>        global _phone_chars_compiled
>        if _phone_chars_compiled is None:
>            _phone_chars_compiled = {}
>            for i in range(256):
>                a = chr(i)
>                _phone_chars_compiled[a] = _phone_chars.get(a, a)
>
>        return ''.join(map(_phone_chars_compiled.__getitem__, szinput))
>
> It yields a 4x speedup over your code (which constructs the map on
> every iteration?). Of course we're talking about microseconds, but I
> guess every bit counts...
>
> Cheers,
> Mike
>
> On Fri, Jan 15, 2010 at 6:41 AM, Andrew Gwozdziewycz <apg...@gmail.com> wrote:
>> Why use regular expressions at all for this? A timeit benchmark shows
>> a greater than 4x speedup with a rangetest in a loop over the string:
>>
>> def phone2number(str):
>>    chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>>         'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5',
>>         'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7',
>>         't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9',
>>        }
>>
>>    out = ''
>>    for n in phone:
>>        x = n.lower()
>>        o = ord(x)
>>        if o > 96 and o < 123:
>>            out += chars[x.lower()]
>>        else:
>>            out += x
>>    return out
>>
>> I know your patch was just adding back Q and Z, but there's no need
>> for a regular expression here.
>>
>> On Thu, Jan 14, 2010 at 5:33 PM, Gabriel Hurley <gab...@gmail.com> wrote:
>>> I've opened a ticket and submitted a patch that fixes this strange
>>> oversight: http://code.djangoproject.com/ticket/12613
>>>
>>> Thanks!
>>>    - Gabriel
>>>
>>> On Jan 14, 5:05 am, Harro <hvdkl...@gmail.com> wrote:
>>>> hmm that's indeed weird. The regex excludes those as well
>>>> specifically.
>>>> The Q and Z should be added or a comment should be added to the code
>>>> explaining the reason for leaving them out.
>>>>
>>>> On Jan 14, 11:23 am, Gabriel Hurley <gab...@gmail.com> wrote:
>>>>
>>>>
>>>>
>>>> > 1. Is there a reason Django's phone2numeric method doesn't work for
>>>> > the letters Q or Z? I realize that those two letters are the ones that
>>>> > share four letters to a number instead of the standard three, but
>>>> > that's no reason to leave them out. Most modern phones include the
>>>> > full alphabet on their keys and it's silly not to let people convert
>>>> > those two letters.
>>>>
>>>> > If there's no reason, I'd be happy to submit a patch since it's such
>>>> > an easy fix.
>>>>
>>>> > 2. I was also wondering if there's a reason that the dictionary of
>>>> > numbers/letters used in that function is in such a seemingly random
>>>> > order... is there some brilliant logic behind it?
>>>>
>>>> > The source for the function I'm referring to is here:
>>>>
>>>> >http://code.djangoproject.com/browser/django/trunk/django/utils/text....
>>>>
>>>> > Thanks!
>>>>
>>>> >     - Gabriel
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups 
>>> "Django developers" group.
>>> To post to this group, send email to django-develop...@googlegroups.com.
>>> To unsubscribe from this group, send email to 
>>> django-developers+unsubscr...@googlegroups.com.
>>> For more options, visit this group at 
>>> http://groups.google.com/group/django-developers?hl=en.
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> http://www.apgwoz.com
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Django developers" group.
>> To post to this group, send email to django-develop...@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> django-developers+unsubscr...@googlegroups.com.
>> For more options, visit this group at 
>> http://groups.google.com/group/django-developers?hl=en.
>>
>>
>>
>>
>
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.


Reply via email to