参赛系统源代码

import sys
import time
import math

class CompetitionSystem(object):
    def __init__(self):
        self.assign_final_num_generator = 1
        self.teams = {}#存储队伍的信息
        self.graph = {}#存储地图信息

    def start(self):
        self.welcome()
        all_teams = self.load_team_file()
        for x in all_teams:
            self.teams[x.team_num] = x
        self.graph = self.load_place_graph()

    def run(self):#菜单
        print("=====================================")
        while True:
            print(
                "请选择:\n    1: 管理参赛队基本信息\n    2: 根据参赛队编号查询\n    3: 根据学校查询参赛队\n    4: 根据类别查询参赛队\n    5: 决赛叫号\n    6: 赛场导游\n    7: 退出")
            menu = self.user_input_number(lambda x: 1 <= x and x <= 7)
            if menu == 1:
                self.manage_teams()
            elif menu == 2:
                self.query_by_team_num()
            elif menu == 3:
                self.query_by_school()
            elif menu == 4:
                self.query_by_category()
            elif menu == 5:
                self.final_competition()
            elif menu == 6:
                self.navigation()
            else:
                print("谢谢使用!")
                sys.exit(0)

    def welcome(self):
        print('========== 欢迎来到设计大赛 ==========\n')
        print('系统正在启动,请稍后......')

    def manage_teams(self):#管理参赛队基本信息
        while True:
            print('\n管理参赛队信息:\n    1: 新增参赛队\n    2: 删除参赛队\n    3: 修改参赛队\n    4: 回到上一级')
            menu = self.user_input_number(lambda x: 1 <= x and x <= 4)
            if menu == 1:
                print('  请输入要新增的参赛队编号:')
                team_num = self.user_input_number()
                if team_num in self.teams:
                    sys.stderr.write('新增失败: 参赛队{0}已经存在\n'.format(team_num))
                else:
                    print('  请输入作品名称:')
                    work_name = self.user_input()
                    print('  请输入学校名称:')
                    school = self.user_input()
                    print('  请输入赛事类别:')
                    category_word = self.user_input()
                    print('  请输入参赛者:')
                    who = self.user_input()
                    print('  请输入指导教师:')
                    teacher = self.user_input()
                    team = Team(team_num, work_name, school, self.to_category(category_word), category_word, who,
                                teacher, self.next_assign_final_room(), self.next_assign_final_num())

                    self.teams[team_num] = team
                    print('新增成功')
            elif menu == 2:
                print('  请输入要删除的参赛队编号:')
                del_team_num = self.user_input_number()
                if del_team_num in self.teams:
                    self.teams[del_team_num] = None
                    print('删除成功')
                else:
                    print('删除失败')

            elif menu == 3:
                print('  请输入要修改的参赛队编号:')
                team_num = self.user_input_number()
                if team_num in self.teams:
                    t = self.teams[team_num]
                    print('  请输入作品名称:')
                    t.work_name = self.user_input()
                    print('  请输入学校名称:')
                    t.school = self.user_input()
                    print('  请输入赛事类别:')
                    t.category_word = self.user_input()
                    print('  请输入参赛者:')
                    t.who = self.user_input()
                    print('  请输入指导教师:')
                    t.teacher = self.user_input()
                    print('修改成功')
                else:
                    sys.stderr.write('修改失败: 参赛队{0}不存在\n'.format(team_num))
            else:
                return

    def query_by_team_num(self):#根据参赛队编号查询
        print('  请输入查询的参赛队编号:')
        team_num = self.user_input_number()
        self.create_binary_tree(team_num)

    def query_by_school(self):#根据学校查找参赛队
        print('  请输入学校名称:')
        school = self.user_input()
        ts = list(filter(lambda x: x.school == school, self.teams.values()))
        ts.sort(key=lambda x: x.category)
        for t in ts:
            print(
                '{0}	#	{1}	#	{2}	#	{3}	#	{4}	#	{5}\n'.format(str(t.team_num), t.work_name,
                                                                                           t.school, t.category_word,
                                                                                           t.who, t.teacher))

    def query_by_category(self):#根据类别查找参赛队
        print('  请输入参赛类别:')
        category_word = self.user_input()
        category = self.to_category(category_word)
        ts = list(filter(lambda x: x.category == category, self.teams.values()))
        ts.sort(key=lambda t: t.team_num)#按照队伍编号进行排序
        for t in ts:
            print(
                '{0}	#	{1}	#	{2}	#	{3}	#	{4}	#	{5}\n'.format(str(t.team_num), t.work_name,
                                                                                           t.school, t.category_word,
                                                                                           t.who, t.teacher))

    def final_competition(self):#叫号系统
        print('  现在开始叫号......')
        time.sleep(1)
        for i in range(1, 10):
            print('请决赛室是{0}号的同学依次进场:'.format(i))
            ts = list(filter(lambda x: x.final_room == i, self.teams.values()))#筛选出该决赛室的所有参赛队伍
            ts.sort(key=lambda t: t.final_num)
            for t in ts:
                print('    决赛号为{0}的同学进入{1}号决赛室'.format(t.final_num, i))
                time.sleep(0.1)
            print('所有决赛室号为{0}的同学已经进入该决赛室,现在开始决赛.....'.format(i))
            time.sleep(5)
        print("叫号结束")

    def navigation(self):
        print('  1行政大楼:学校办公的地方\n'
              '  2海韵湖:学校的标志性景点\n'
              '  3图书馆:大部分学生自习的地方\n'
              '  4东苑食堂:靠近图书馆的学生可以去这吃饭,有三楼可供选择\n'
              '  5东区操场:学生运动的地方,大部分外国人在这运动\n'
              '  6南门:可以从该门出校\n'
              '  7文体中心:体育课学生上课的地方,有大量体育活动室\n'
              '  8西区操场:学生踢足球的地方,也是大量户外活动举办的场所\n'
              '  9经世楼:学生上课的大楼之一\n'
              '  10文理大楼:学校的标志性建筑,是学校的最高建筑,其中有许多面向专门课程的教室\n')
        print('请输入起始地点编号:')
        from_num = self.user_input_number(lambda x: 1 <= x and x <= len(self.graph.nodes)) - 1
        print('请输入目的地点编号:')
        to_num = self.user_input_number(lambda x: 1 <= x and x <= len(self.graph.nodes)) - 1
        self.graph.cal_dis(from_num, to_num)#调用cal_dis方法

    def create_binary_tree(self, team_num):#创建一个二叉树
        all_teams = self.load_team_file()
        binary_tree = BinaryTree(all_teams)
        node = binary_tree.search_by_team_num(team_num)#用于根据参赛队伍编号查找对应的参赛队伍节点
        if node != None:
            t = node.team
            print('平均查找长度 ASL:{0}'.format(binary_tree.ASL))
            print(
                '{0}	#	{1}	#	{2}	#	{3}	#	{4}	#	{5}\n'.format(str(t.team_num), t.work_name,
                                                                                           t.school, t.category_word,
                                                                                           t.who, t.teacher))
        else:
            print('查找失败')

    def user_input_number(self, f=lambda x: True):#获取用户输入的数字
        return int(self.user_input(lambda x: x.isdigit() and f(int(x))))#判断用户输入是否是否满足条件

    def user_input(self, f=lambda x: len(x) > 0):#确保用户输入的内容符合要求
        while True:
            line = sys.stdin.readline().strip()
            if not f(line):
                sys.stderr.write('输入不合法,请重新输入\n')
            else:
                return line

    def next_assign_final_room(self):
        return (self.assign_final_num_generator % 9) + 1#计算下一轮应该召集的决赛室编号

    def next_assign_final_num(self):
        self.assign_final_num_generator += 1#计算下一个编号
        return self.assign_final_num_generator - 1

    def load_team_file(self):#从磁盘中读取文件,并将其转化为一组Team对象
        all_teams = []
        with open('team.txt', 'r', encoding='GBK') as f:
            title = f.readline()
            if not title or title.startswith('参赛队编号') == False or len(title.split('	#	')) != 6:
                sys.stderr.write('team.txt 不合法!\n')
                sys.exit(-1)
            else:
                line = f.readline()
                while line:
                    line = line.strip()
                    if len(line) > 0:
                        one_team = line.split('	#	')
                        one_team = [word.strip() for word in one_team]
                        if len(one_team) != 6 or not one_team[0].isdigit():
                            sys.stderr.write('team.txt 内容不合法: "{0}"\n'.format(line))
                            sys.exit(-1)
                        all_teams.append(#添加到列表 all_teams
                            Team(int(one_team[0]), one_team[1], one_team[2], self.to_category(one_team[3]), one_team[3],
                                 one_team[4], one_team[5], self.next_assign_final_room(), self.next_assign_final_num()))
                    line = f.readline()
        return all_teams

    def load_place_graph(self):#读取文件,构建Graph对象
        graph = Graph()#创建新的Graph对象
        with open('place.txt', 'r', encoding='GBK') as f:
            self.until_read_line(f, lambda line: line == '#<places>')
            f.readline()
            line = f.readline().strip()
            while line != '#<distances>':
                parts = line.strip().split(' ')
                place = {'num': int(parts[0].strip()), 'name': parts[1].strip(), 'intra': parts[2].strip()}
                graph.nodes[place['num']] = place
                line = f.readline().strip()

            graph.init_edges()

            line = f.readline().strip()
            while line != '#<end>':
                parts1 = line.split('<->')
                parts2 = parts1[1].strip().split(':')
                from_num = int(parts1[0].strip())
                to_num = int(parts2[0].strip())
                distance = int(parts2[1].strip())
                graph.add_edge(from_num - 1, to_num - 1, distance)
                line = f.readline().strip()
        return graph

    def until_read_line(self, f, func=lambda line: True):#用于读取的每一行将其传递给 func 函数进行判断
        line = f.readline()
        while line:
            line = line.strip()
            if func(line):
                return
        sys.stderr.write('文件不合法\n')
        sys.exit(-1)

    def to_category(self, category_word):#根据类别查询参赛队
        # 2023年大赛分设11个大类,分别是:
        #   (1)软件应用与开发;
        #   (2)微课与教学辅助;
        #   (3)物联网应用;
        #   (4)大数据应用;
        #   (5)人工智能应用;
        #   (6)信息可视化设计;
        #   (7)数媒静态设计;
        #   (8)数媒动漫与短片;
        #   (9)数媒游戏与交互设计;
        #   (10)计算机音乐创作;
        #   (11)国际生“学汉语,写汉字”
        if category_word.find('应用') >= 0 and category_word.find('开发') >= 0:
            return 1
        if category_word.find('微课') >= 0 or category_word.find('课程') >= 0 or category_word.find(
                '在线') >= 0 or category_word.find('小学') >= 0:
            return 2
        if category_word.find('物联网') >= 0:
            return 3
        if category_word.find('大数据') >= 0:
            return 4
        if category_word.find('人工智能') >= 0 or category_word.find('AI') >= 0:
            return 5
        if category_word.find('可视化') >= 0:
            return 6
        if category_word.find('漫画') >= 0 or category_word.find('静态') >= 0 or category_word.find('平面设计') >= 0:
            return 7
        if category_word.find('动画') >= 0 or category_word.find('片') >= 0 or category_word.find('视频') >= 0:
            return 8
        if category_word.find('游戏') >= 0 or category_word.find('交互') >= 0:
            return 9
        if category_word.find('音乐') >= 0:
            return 10
        if category_word.find('汉字') >= 0 or category_word.find('汉语') >= 0:
            return 11
        else:
            return 1


class Graph(object):
    MAX = 99999999#用于表示两个节点间无连线

    def __init__(self):
        self.nodes = {}
        self.edges = []

    def init_edges(self):
        self.edges = [[Graph.MAX for col in range(len(self.nodes))] for row in range(len(self.nodes))]
        #edges列表中的所有元素初始化为一个较大的数,用于表示两个节点之间没有连线

    def add_edge(self, from_num, to_num, distance):#添加边
        self.edges[from_num][to_num] = distance
        self.edges[to_num][from_num] = distance

    def cal_dis(self, from_num, to_num):#计算最短路径,使用Dijkstra算法计算从起点到终点的最短路径
        dis = self.edges[from_num].copy()
        path = self.edges[from_num].copy()
        for i in range(len(path)):
            path[i] = from_num if self.edges[from_num][i] < Graph.MAX else -1

        visited = [False for i in range(len(self.nodes))]
        visited[from_num] = True#表示起点已经被访问
        dis[from_num] = 0

        for i in range(len(self.nodes)):#遍历所有节点,找到距离起点最近的节点u,并将该节点标记为visited
            min = Graph.MAX
            u = from_num
            for j in range(len(self.nodes)):
                if not visited[j] and dis[j] <= min:
                    min = dis[j]
                    u = j

            visited[u] = True

            for j in range(len(self.nodes)):#更新起点到其他节点的距离和路径信息
                if not visited[j] and dis[j] > dis[u] + self.edges[u][j]:
                    dis[j] = dis[u] + self.edges[u][j]
                    path[j] = u

        path_result = []
        #使用深度优先算法to_path_result
        self.to_path_result(from_num, to_num, path, path_result)#使用递归的方式

        print('从{0}到{1}的最短路径计算结果:'.format(from_num + 1, to_num + 1))
        print('    最短路径长度{0}米'.format(dis[to_num]))
        print('    最短路径的节点编号依次是: {0}'.format(list(reversed(path_result))))

    def to_path_result(self, from_num, to_num, path, path_result):#深度优先算法,算出起点到终点的路径该如何走
        path_result.append(to_num + 1)
        if from_num != to_num:
            self.to_path_result(from_num, path[to_num], path, path_result)


class Team(object):#定义一个代表参赛队的类
    def __init__(self, team_num, work_name, school, category, category_word, who, teacher, final_room, final_num):
        self.team_num = team_num
        self.work_name = work_name
        self.school = school
        self.category = category
        self.category_word = category_word
        self.who = who
        self.teacher = teacher
        self.final_room = final_room
        self.final_num = final_num

    def is_final_competition(self, final_room, final_num):  # 判断是否被叫到
        return final_room == self.final_room and final_num == self.final_num


class BinaryNode(object):#二叉树的结点
    def __init__(self, team, parent=None):
        self.team = team
        self.parent = parent
        self.left = None
        self.right = None

    def insert(self, team):#插入一个节点,用于接收一个参数team
        if self.team.team_num > team.team_num:
            if self.left == None:
                self.left = BinaryNode(team, self)
            else:
                self.left.insert(team)
        else:
            if self.right == None:
                self.right = BinaryNode(team, self)
            else:
                self.right.insert(team)


class BinaryNode(object):#二叉树的结点
    def __init__(self, team, parent=None):
        self.team = team
        self.parent = parent
        self.left = None
        self.right = None

    def insert(self, team):#插入一个节点,用于接收一个参数team
        if self.team.team_num > team.team_num:
            if self.left == None:
                self.left = BinaryNode(team, self)
            else:
                self.left.insert(team)
        else:
            if self.right == None:
                self.right = BinaryNode(team, self)
            else:
                self.right.insert(team)


class BinaryNode(object):#二叉树的结点
    def __init__(self, team, parent=None):
        self.team = team
        self.parent = parent
        self.left = None
        self.right = None

    def insert(self, team):#插入一个节点,用于接收一个参数team
        if self.team.team_num > team.team_num:
            if self.left == None:
                self.left = BinaryNode(team, self)
            else:
                self.left.insert(team)
        else:
            if self.right == None:
                self.right = BinaryNode(team, self)
            else:
                self.right.insert(team)


class BinaryNode(object):#二叉树的结点
    def __init__(self, team, parent=None):
        self.team = team
        self.parent = parent
        self.left = None
        self.right = None


    def insert(self, team):#插入一个节点,用于接收一个参数team
        if self.team.team_num > team.team_num:
            if self.left == None:
                self.left = BinaryNode(team, self)
            else:
                self.left.insert(team)
        else:
            if self.right == None:
                self.right = BinaryNode(team, self)
            else:
                self.right.insert(team)


class BinaryTree(object):#创建二叉树
    def __init__(self, all_teams):
        all_teams.sort(key=lambda t: t.team_num)
        self.levels = [0 for i in range(int(math.log(len(all_teams) + 1, 2)) + 2)]#算出二叉树的深度
        self.root_node = self.create(all_teams, 0, len(all_teams), 1)
        self.ASL = 0
        for i in range(len(self.levels)):
            self.ASL += i * self.levels[i]
        self.ASL = self.ASL / len(all_teams)

    def search_by_team_num(self, team_num):#表示要查找的队伍编号
        node = self.root_node
        while node != None:
            if node.team.team_num == team_num:
                return node
            elif node.team.team_num > team_num:
                node = node.left
            else:
                node = node.right
        return None

    def insert(self, team):#表示要插入的队伍
        self.root_node.insert(team)

    def create(self, all_teams, low, high, level):
        self.levels[level] += 1#当前节点所处的层数加1
        mid = int((low + high) / 2)#根节点
        node = BinaryNode(all_teams[mid])
        node.left = None if mid == low else self.create(all_teams, low, mid, level + 1)#左子树为空
        node.right = None if mid == high - 1 else self.create(all_teams, mid + 1, high, level + 1)
        return node



if __name__ == "__main__":
    cs = CompetitionSystem()
    cs.start()
    cs.run()

以上的按队伍编号查找求平均查找长度有错误,正确的可以看上一个发布的代码,那个是正确的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值