What I am trying to do with the code below is a sort of group check. I have assigned people to groups using group numbers so:
fname lname group
mark anthony 2
macy grey 3 etc..
I want to prevent any two people with the same first and last names from being in the same group. So I wrote an action to try to do this but I think I may have found myself in an infinite loop, either way its not working.
def groupcheck(modeladmin, request, queryset):
groups=[]
N = 7 # number of groups
for X in queryset:
item = "".join([X.fname, X.lname, str(X.group)]) #the information I am trying to check
if item in groups: # check if it is the array above (groups)
while item in groups:
G = X.group
Y = int(G) + int(1) #change the group number
if Y > N: # This is my attempt to not allow the group number to be more than the number of groups i allowed (N)
Y = 0
removeditemnumber = ''.join([i for i in item if not i.isdigit()]) # I am removing the group number
item = removeditemnumber + str(Y) # now I am trying to replace it
groups.append(item) #once the loop is done i want the edited version to be added to the array
X.group = Y
X.save() # I want the new group number to be saved to the databse
else:
groups.append(item)
I tried to add comments to help guide through the code in case I did it wrong, if it's distracting let me know and i will remove them, please help if you can
I would suggest refactoring this entirely and taking a different approach. You're essentially mapping group numbers to to groups of people, so this sounds like the perfect place to use a dictionary instead. Try this:
import pprint
name_list = [
"mark anthony 2",
"macy grey 3",
"bob jones 4",
"macy grey 6",
"mike johnson 5",
"macy grey 6",
"mark anthony 2"]
pprint.pprint(name_list)
N = 7
# create a dictionary where the keys are gorup numbers
groups = {n:[] for n in xrange(N)}
# this lambda function will increment the input up to N
# then wrap around to zero
increment = lambda x: x+1 if x+1 < N else 0
for name in name_list:
fname, lname, group_num = name.split()
group_num = int(group_num)
old_group = group_num
# increment the group number while the name is in
# the current group
while (fname, lname) in groups[group_num]:
group_num = increment(group_num)
if group_num == old_group:
# if we've checked all the groups and there's
# no space for this name, raise exception
raise NoMoreSpaceError
# we found a spot! add the current name to the current
# group number
groups[group_num].append((fname, lname))
pprint.pprint(groups)
Output:
['mark anthony 2',
'macy grey 3',
'bob jones 4',
'macy grey 6',
'mike johnson 5',
'macy grey 6',
'mark anthony 2']{0: [('macy', 'grey')],
1: [],
2: [('mark', 'anthony')],
3: [('macy', 'grey'), ('mark', 'anthony')],
4: [('bob', 'jones')],
5: [('mike', 'johnson')],
6: [('macy', 'grey')]}
Notice that in the input, there were two instances of "mark anthony" assigned to group 2, so one got bumped to group 3. Two instances of of "macy grey" stayed where they are (groups 3 and 6) because they are in different groups, but the second one that was assigned to group six got bumped around to group 0. Now you end up with an organized dictionary, and I think this code is much easier to follow and maintain. For now, I've raised an exception if there are too many occurances of a specific name, but you'll have to decide how you want to handle that.
I removed all the extra stuff from your code. Havent checked it. There should only be minor errors.
groups = []
N = 7
for X in queryset:
item = "".join([X.fname, X.lname, str(X.group)])
nCount = 0
while item in groups:
X.group = (X.group + 1)%N
item = "".join([X.fname, X.lname, str(X.group)])
# This part only checks for a very stringent condition. Mostly
# unnecessary for real names. Only the couple of lines above
# are meaningful as far as the code is concerned.
nCount += 1
if nCount > N:
print X.fname, X.lname, 'exists in all', N, 'groups ...'
sys.exit(1)
groups.append(item)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.