我如何通过加入和离开使这些频道动态可见?
How do I make these channels visible dynamically with just joins and leaves?
考虑这个 MVCE:
import os
from time import sleep
from typing import List, Optional
class Member:
def __init__(self, name: str):
self.name: str = name
class VoiceChannel:
def __init__(self, number: int):
self.number: int = number
self.members: List[Member] = []
self.visible = True
def is_empty(self) -> bool:
return len(self.members) == 0
def add_member(self, member: Member):
self.members.append(member)
def remove_member(self, member: Member):
self.members.remove(member)
class System:
def __init__(self):
self.channels: List[VoiceChannel] = []
for channel_number in range(1, 6):
if channel_number == 1:
self.channels.append(VoiceChannel(channel_number))
else:
_ = VoiceChannel(channel_number)
_.visible = False
self.channels.append(_)
def get_room(self, number: int) -> Optional[VoiceChannel]:
if number > 0:
return self.channels[number - 1]
def on_voice_state_update(
self,
member: Member,
before: Optional[VoiceChannel],
after: Optional[VoiceChannel]
):
def join():
pass
def leave():
pass
if after in self.channels:
join()
if before in self.channels:
leave()
def join(self, member: Member, channel_number):
self.channels[channel_number - 1].add_member(member)
self.update_screen()
self.on_voice_state_update(member, None, self.channels[channel_number])
self.update_screen()
def leave(self, member: Member):
on_leave_channel = None
for channel in self.channels:
if member in channel.members:
on_leave_channel = channel
channel.remove_member(member)
self.update_screen()
break
if on_leave_channel:
self.on_voice_state_update(member, on_leave_channel, None)
def move(self, member: Member, channel_number: int):
for current_channel in self.channels:
if member in current_channel.members:
current_channel.remove_member(member)
self.update_screen()
break
channel = self.get_room(channel_number)
channel.add_member(member)
self.update_screen()
def update_screen(self):
_ = os.system("cls")
print("\n> Debate Rooms")
for channel in self.channels:
if channel.visible:
print(f" Debate {channel.number}")
if not channel.is_empty():
for member in channel.members:
print(f" {member.name}")
else:
print(f" ")
sleep(1.5)
if __name__ == "__main__":
system = System()
# Initialize Members
john = Member("John")
jane = Member("Jane")
abby = Member("Abby")
jess = Member("Jess")
hope = Member("Hope")
kate = Member("Kate")
liam = Member("Liam")
noah = Member("Noah")
jack = Member("Jack")
luke = Member("Luke")
# Prime Members
system.join(john, 1) # Show Debate 2.
system.leave(john) # Hide Debate 2.
system.join(john, 1) # Show Debate 2.
system.join(jane, 1) # Keep Showing Debate 2.
system.leave(john) # Keep Showing Debate 2.
system.leave(jane) # Hide Debate 2.
system.join(john, 1) # Show Debate 2.
system.join(jane, 2) # Show Debate 3.
system.join(abby, 3) # Show Debate 4.
system.leave(john) # Hide Debate 4 since 1 is available.
system.move(jane, 1) # Keep Debate 4 hidden, and Debate 2 shown.
我正尝试根据此要求使这些频道可见和不可见:
- 总是只有一个空频道可见。
- 用户可以加入或离开可见频道[如果没有用户则频道为空]。
- 如果用户加入(单个可见的)空频道,使第一个可用的空频道可见[保持(1)]。
- 如果用户离开导致额外的空频道,只显示第一个空频道[再次,保持(1)]
如何仅使用 on_voice_state_update()
中的 join()
和 leave()
函数来实现此功能?我已经尝试了一段时间,但似乎无法弄清楚。
我会创建一个函数来评估您的条件 1,如果不满足则采取相应的行动。此函数可以在当前状态下工作,而不必知道哪个成员 removed/added 到房间:
def ensure_one_empty_room(self):
empty_visible_channels = \
[channel for channel in self.channels if channel.is_empty() and channel.visible]
if len(empty_visible_channels)==0:
first_empty_channel = next(channel for channel in self.channels if channel.is_empty())
if first_empty_channel:
first_empty_channel.visible=True
elif len(empty_visible_channels)>1:
for channel in empty_visible_channels[1:]:
channel.visible=False
完整系统 class 将变为:
class System:
def __init__(self):
self.channels = [VoiceChannel(i) for i in range(1, 6)]
self.ensure_one_empty_room()
self.update_screen()
def get_room(self, number: int) -> Optional[VoiceChannel]:
if number > 0:
return self.channels[number - 1]
def ensure_one_empty_room(self):
empty_visible_channels = \
[channel for channel in self.channels if channel.is_empty() and channel.visible]
if len(empty_visible_channels)==0:
first_empty_channel = next(channel for channel in self.channels if channel.is_empty())
if first_empty_channel:
first_empty_channel.visible=True
elif len(empty_visible_channels)>1:
for channel in empty_visible_channels[1:]:
channel.visible=False
def on_member_change(self):
self.ensure_one_empty_room()
self.update_screen()
def joined_channels(self, member):
return (channel for channel in self.channels if (member in channel.members))
def join(self, member: Member, channel_number):
self.get_room(channel_number).add_member(member)
self.on_member_change()
def leave(self, member: Member):
for channel in self.joined_channels(member):
channel.remove_member(member)
self.on_member_change()
def move(self, member: Member, channel_number: int):
for channel in self.joined_channels(member):
channel.remove_member(member)
self.get_room(channel_number).add_member(member)
self.on_member_change()
def update_screen(self):
os.system("cls")
print("\n> Debate Rooms")
for channel in self.channels:
if channel.visible:
print(f" Debate {channel.number}")
if not channel.is_empty():
for member in channel.members:
print(f" {member.name}")
else:
print(f" ")
sleep(1.5)
注意:
- 在您的 join() 函数中,没有检查成员是否已经是频道的一部分,因此他可以加入多个频道。因此,我更改为其他功能(移动和离开)以考虑到这一点
- 我在 Python 中合并了一些很好的 列表理解 功能的示例,仅用于说明目的
考虑这个 MVCE:
import os
from time import sleep
from typing import List, Optional
class Member:
def __init__(self, name: str):
self.name: str = name
class VoiceChannel:
def __init__(self, number: int):
self.number: int = number
self.members: List[Member] = []
self.visible = True
def is_empty(self) -> bool:
return len(self.members) == 0
def add_member(self, member: Member):
self.members.append(member)
def remove_member(self, member: Member):
self.members.remove(member)
class System:
def __init__(self):
self.channels: List[VoiceChannel] = []
for channel_number in range(1, 6):
if channel_number == 1:
self.channels.append(VoiceChannel(channel_number))
else:
_ = VoiceChannel(channel_number)
_.visible = False
self.channels.append(_)
def get_room(self, number: int) -> Optional[VoiceChannel]:
if number > 0:
return self.channels[number - 1]
def on_voice_state_update(
self,
member: Member,
before: Optional[VoiceChannel],
after: Optional[VoiceChannel]
):
def join():
pass
def leave():
pass
if after in self.channels:
join()
if before in self.channels:
leave()
def join(self, member: Member, channel_number):
self.channels[channel_number - 1].add_member(member)
self.update_screen()
self.on_voice_state_update(member, None, self.channels[channel_number])
self.update_screen()
def leave(self, member: Member):
on_leave_channel = None
for channel in self.channels:
if member in channel.members:
on_leave_channel = channel
channel.remove_member(member)
self.update_screen()
break
if on_leave_channel:
self.on_voice_state_update(member, on_leave_channel, None)
def move(self, member: Member, channel_number: int):
for current_channel in self.channels:
if member in current_channel.members:
current_channel.remove_member(member)
self.update_screen()
break
channel = self.get_room(channel_number)
channel.add_member(member)
self.update_screen()
def update_screen(self):
_ = os.system("cls")
print("\n> Debate Rooms")
for channel in self.channels:
if channel.visible:
print(f" Debate {channel.number}")
if not channel.is_empty():
for member in channel.members:
print(f" {member.name}")
else:
print(f" ")
sleep(1.5)
if __name__ == "__main__":
system = System()
# Initialize Members
john = Member("John")
jane = Member("Jane")
abby = Member("Abby")
jess = Member("Jess")
hope = Member("Hope")
kate = Member("Kate")
liam = Member("Liam")
noah = Member("Noah")
jack = Member("Jack")
luke = Member("Luke")
# Prime Members
system.join(john, 1) # Show Debate 2.
system.leave(john) # Hide Debate 2.
system.join(john, 1) # Show Debate 2.
system.join(jane, 1) # Keep Showing Debate 2.
system.leave(john) # Keep Showing Debate 2.
system.leave(jane) # Hide Debate 2.
system.join(john, 1) # Show Debate 2.
system.join(jane, 2) # Show Debate 3.
system.join(abby, 3) # Show Debate 4.
system.leave(john) # Hide Debate 4 since 1 is available.
system.move(jane, 1) # Keep Debate 4 hidden, and Debate 2 shown.
我正尝试根据此要求使这些频道可见和不可见:
- 总是只有一个空频道可见。
- 用户可以加入或离开可见频道[如果没有用户则频道为空]。
- 如果用户加入(单个可见的)空频道,使第一个可用的空频道可见[保持(1)]。
- 如果用户离开导致额外的空频道,只显示第一个空频道[再次,保持(1)]
如何仅使用 on_voice_state_update()
中的 join()
和 leave()
函数来实现此功能?我已经尝试了一段时间,但似乎无法弄清楚。
我会创建一个函数来评估您的条件 1,如果不满足则采取相应的行动。此函数可以在当前状态下工作,而不必知道哪个成员 removed/added 到房间:
def ensure_one_empty_room(self):
empty_visible_channels = \
[channel for channel in self.channels if channel.is_empty() and channel.visible]
if len(empty_visible_channels)==0:
first_empty_channel = next(channel for channel in self.channels if channel.is_empty())
if first_empty_channel:
first_empty_channel.visible=True
elif len(empty_visible_channels)>1:
for channel in empty_visible_channels[1:]:
channel.visible=False
完整系统 class 将变为:
class System:
def __init__(self):
self.channels = [VoiceChannel(i) for i in range(1, 6)]
self.ensure_one_empty_room()
self.update_screen()
def get_room(self, number: int) -> Optional[VoiceChannel]:
if number > 0:
return self.channels[number - 1]
def ensure_one_empty_room(self):
empty_visible_channels = \
[channel for channel in self.channels if channel.is_empty() and channel.visible]
if len(empty_visible_channels)==0:
first_empty_channel = next(channel for channel in self.channels if channel.is_empty())
if first_empty_channel:
first_empty_channel.visible=True
elif len(empty_visible_channels)>1:
for channel in empty_visible_channels[1:]:
channel.visible=False
def on_member_change(self):
self.ensure_one_empty_room()
self.update_screen()
def joined_channels(self, member):
return (channel for channel in self.channels if (member in channel.members))
def join(self, member: Member, channel_number):
self.get_room(channel_number).add_member(member)
self.on_member_change()
def leave(self, member: Member):
for channel in self.joined_channels(member):
channel.remove_member(member)
self.on_member_change()
def move(self, member: Member, channel_number: int):
for channel in self.joined_channels(member):
channel.remove_member(member)
self.get_room(channel_number).add_member(member)
self.on_member_change()
def update_screen(self):
os.system("cls")
print("\n> Debate Rooms")
for channel in self.channels:
if channel.visible:
print(f" Debate {channel.number}")
if not channel.is_empty():
for member in channel.members:
print(f" {member.name}")
else:
print(f" ")
sleep(1.5)
注意:
- 在您的 join() 函数中,没有检查成员是否已经是频道的一部分,因此他可以加入多个频道。因此,我更改为其他功能(移动和离开)以考虑到这一点
- 我在 Python 中合并了一些很好的 列表理解 功能的示例,仅用于说明目的