Проблема с подбором скребка 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")
Вернуться на верх