Проблема с подбором скребка Django: match_maker Возвращает только 4 участника вместо 150
Вопрос:
Я работаю над проектом на Django, который использует Scrapy для удаления профилей участников с веб-сайта. Данные, которые были удалены, обрабатываются методом, называемым match_maker. Однако я столкнулся с проблемой, из-за которой match_maker возвращает только 4 участника, несмотря на наличие 150 участников в базе данных (за исключением 3 сотрудников).
Подробности:
База данных: Содержит 153 участника; 3 из них являются сотрудниками, в результате чего остается 150 постоянных участников. Типы профилей: У каждого участника есть тип профиля "Мужчина", "Женщина", "Транс" или "Пара".
Проблема:
В методе match_maker есть цикл, который обрабатывает номера и назначает их участникам. Набор с именем used_rooms используется для отслеживания назначенных номеров, чтобы гарантировать, что каждый номер назначается только один раз. Соответствующий фрагмент кода выглядит следующим образом:
if room["username"] in used_rooms:
continue
Когда это условие активировано, возвращаются только 4 участника. Если я закомментирую эту проверку, метод обработает все 150 участников, но количество доступных комнат превысит миллион, что неверно.
Цель:
Мне нужно, чтобы каждая комната была назначена только одному участнику, гарантируя, что определенной комнатой владеет не более одного участника. Я ищу руководство о том, как решить эту проблему, чтобы match_maker корректно обрабатывал все 150 участников, не назначая нескольких участников в одну комнату.
Что я пробовал:
Обеспечена уникальность: Проверено, что номер["username"] уникален для каждого номера. Отлажены настройки used_rooms: Распечатано содержимое used_rooms до и после проверки, чтобы убедиться, что оно заполняется правильно. Проверена структура данных о номере: подтверждено, что номер["имя пользователя"] уникален для всех номеров. Несмотря на предпринятые усилия, проблема сохраняется. Мы будем признательны за любую информацию или предложения.
Фрагмент кода:
def match_maker(self, members, room_data: list):
matched_items = []
used_rooms = set() # Keep track of assigned rooms
room_data_copy = deepcopy(room_data)
# Group rooms by profile_type for quick lookup
rooms_by_type = defaultdict(list)
for room in room_data_copy:
if len(room["body"]) >= 5: # Only store rooms with a valid description
rooms_by_type[room["profile_type"]].append(room)
users = set()
for member in members:
if member.is_staff:
continue
# Get matching rooms for this profile_type
available_rooms = rooms_by_type.get(member.profile_type, [])
for room in available_rooms:
if room["id"] in used_rooms:
continue
if room["profile_type"] != member.profile_type:
continue
users.add(member.username)
matched_items.append((member, room))
used_rooms.add(room["id"])
print(f"The users are: {users}")
print(f"The number of users are: {len(users)}")
random.shuffle(matched_items)
return matched_items
Из предоставленного вами кода следует, что в этом вложенном цикле, когда условие if room[“username”] in used_rooms:
активно, первый пользователь с определенным типом профиля займет все доступные комнаты определенного типа, потому что вы не используете break
оператор после того, как пользователю будет назначена комната. Этот цикл должен выглядеть примерно так:
for room in available_rooms:
if room["username"] in used_rooms:
continue
if room["profile_type"] != member.profile_type:
continue
users.add(member.username)
matched_items.append((member, room))
used_rooms.add(room["username"])
break
Теперь это должно сработать, если все, что вы написали, верно, а именно room[“username”]
уникально и если оно возвращает True
во всех случаях и выводит этот текст на консоль 'There are enough rooms'
:
import itertools
import operator
it = itertools.groupby(members, key=operator.attrgetter('profile_type'))
for profile_type, [*members] in it:
if len(rooms_by_type[profile_type]) >= len(members):
print('There are enough rooms')
else:
print("There aren't enough rooms to assign to all users")