22-01-2010 Steven D'Aprano <st...@remove-this-cybersource.com.au> wrote:

On Fri, 22 Jan 2010 13:17:44 +0100, Gilles Ganault wrote:

To avoid users from creating login names that start with digits in order
to be listed at the top, I'd like to sort the list differently every
minute so that it'll start with the next letter, eg. display the list
from A...Zdigits the first time, then B...ZAdigits, etc.

That way, users have no incentive to create login names that start with
either a digit or letter A.

If you want to prohibit users from starting their login names with a
digit, prohibit them from creating a login name with a digit.

I understand that a real problem is to make all names -- regardless of characters they are made of -- having "the equal rights" in terms of visibility.

I see that dictionaries can be sorted using the... sort() method

List, not dictionaries (they have nothing to do with the matter).

but is it possible to have Python start sorting from a different
letter?

You can write a customer sort routine by using the key parameter to sort,
which will probably be messy.

It could be done e.g. in such a way:

     # (for Python 2.x)
     from collections import deque
     import string

     CHARS = string.ascii_lowercase + string.digits
     def rotated_key(rotated_chars=deque(CHARS)):
         rotated_chars.rotate(1)
         tr_table = string.maketrans(CHARS, ''.join(rotated_chars))
         def key(item):
             return item.translate(tr_table)
         return key

     # generate some names
     import random
     users = [''.join(random.choice(CHARS) for i in xrange(3))
              for j in xrange(50)]

     for i in xrange(50):
         users.sort(key=rotated_key())
         print ','.join(users)
         print

But it still doesn't guarantee real "equal rights in visibility" (holders
of names starting with rarely used characters are in better situation).

What I'd do is keep 27 lists of user names,
according to the first letter (26 letters from A to Z, plus one extra):

users = [  # keep separate lists for each starting letter
    ['aaron', 'avril', 'adam'],
    ['betty', 'bob'],
    ['craig', 'cathy'],
    ['danni', 'da5id', 'donna'],
    # ... and so on
    ['zoe', 'zach'],
    ['4dam', '1-4m-t00-c001']
    ]

But here the second letter becomes important for "visibility" and users
still are not equal.

And all this mess in unnecessary, because there is one perfect and simple
solution -- see the Neil Cerutti's post.

22-01-2010, 14:58:58 Gilles Ganault <nos...@nospam.com> wrote:

On 22 Jan 2010 13:35:26 GMT, Neil Cerutti <ne...@norwich.edu> wrote:
Resorting is more work than is needed. Just choose a different
starting index each time you display the names, and set up your
lister to wrap-around to your arbitrary starting index.

Thanks. In this case, it means that in each loop iteration, I must
search the list to find which item starts with the letter I'd like to
begin sorting, eg. "B". Does Python include a search method or do I
have to use a for loop to locate this starting item?

There is e.g. `bisect' module -- you can search as well as insert with
its functions. But IMHO you shouldn't search for the next starting
*letter*, but for the next *name* in the list (basing on name that was
used recently).

If the list were immutable, no searching would be needed (indexes would
be sufficient), but in real life users can be added and deleted in the
meantime (so index of a particular name changes).

Regards,

*j

--
Jan Kaliszewski (zuo) <z...@chopin.edu.pl>
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to