• python-实现不放回抽签


    需求:1.不放回抽签 2.把名单上的人员都抽取完以后才能开始下一轮 3.每次打分数都累加 4.可以查看前三和后三名

    使用excel实现:思路就是先拿到名单数据,然后抽签(判断抽出来的人在不在新list中),打分,排序。使用递归调用实现多次抽取。

    数据样例:

    import xlrd
    import random
    import sys
    from openpyxl import load_workbook
    
    filename = '参训人员名单.xlsx'
    name_new_list = []
    
    def open_excel():
        xl = xlrd.open_workbook(filename)
        sheet = xl.sheet_by_index(0)
        return sheet
    
    def read_name():
        sheet = open_excel()
        row_num = sheet.nrows# 获取excel中有多少行
        name_score = []
        for i in range(1,row_num):
            value = sheet.row_values(i)#取出每一行的名字和分数
            name_score.append(value)
        new_name_score = dict(name_score)  #返回姓名分数列表
        return new_name_score
    
    def draw_people():
        names = read_name()  # 获取姓名分数字典
        name_list = list(names.keys())  # 把姓名拿出来,当一个列表,用来抽取
        if len(name_new_list) == len(name_list):# 如果原始列表和存放抽取名字的列表相等,清空存放名字列表
            nu = input('名单上的人员都已被抽过!开启新一轮的抽签请输入1
     返回上级菜单请输入2
    ')
            if nu == '1':
                name_new_list.clear()
            else:
                return   #返回主菜单
        people_name = random.choice(name_list)
        if people_name not in name_new_list:
            name_new_list.append(people_name)
            name_num = name_list.index(people_name)+2  # 获取序号+2,因为下标从0开始,
            print('此次抽中的人员是:',people_name)
            mark_score(name_num)
        else:
            draw_people()
    
    def mark_score(people_num):
        wb = load_workbook(filename)
        wb1 = wb.active  # 激活sheet
        old_score = wb1.cell(row = people_num,column = 2).value #取出原始分数
        print("该人员的现有分数是:",old_score)
        while True:
            try:
                this_score = input("请给抽中的人员打分数(请输入整数):")
                this_score = int(this_score)
                break
            except ValueError:
                print('请输入一个整数')
        now_score = int(old_score) + int(this_score)
        wb1.cell(people_num,2,now_score)#写入分数列
        wb.save(filename)  # 保存
    
    def sort_score():  #排序
        all_score = read_name()#拿到姓名和分数组成的字典
        for key in all_score:
            all_score[key] = int(all_score[key])  # 把数字的小数点去掉才排序
        desc = sorted(all_score.items(),key=lambda x:x[1], reverse=False)[:3]#倒序排,输出前三
        asc = sorted(all_score.items(),key=lambda x:x[1], reverse=True)[:3]#正序排,输出前三
        print("排名前三的人员:",asc)
        print("排名后三的人员:",desc)
    
    def main():
        num = input("---抽签,请输入1
    ---查看排名,请输入2
    ---退出程序,请输入3
    ")
        if num == '1' :
            draw_people()
            main()
        elif num == '2':
            sort_score()
            main()
        else:
            sys.exit(0)
    
    if __name__ == '__main__':
        main()

    用txt实现:先读出全部数据,然后分割成列表。写入的时候现封装成一个列表,再写进去。排序时应该先把value转成int,才能进行排序

    数据样例:

    import random
    import sys
    import codecs
    import operator
    
    filename = '名单.txt'
    name_new_list = []
    name_dict = {}
    
    
    def read_txt():
        with codecs.open(filename, 'r', 'utf-8') as fp:
            data = fp.readlines()
            '''
            读取到的data:
            ['张三:62
    ', '李四:117
    ', 'waang2:40
    ', 'yuuu:60
    ', '李磊:90']
            '''
            for line in data:
                name_score = line.replace('
    ', '').replace('
    ', '').split(':')  # 把每一行数据用:拆分成2个元素
                '''
                ['张三', '62']
                ['李四', '117']
                ['waang2', '40']
                ['yuuu', '60']
                ['李磊:90']
                '''
                if len(name_score) == 2:  # 以防txt里面有空行
                    name_dict[name_score[0]] = int(name_score[1]) #把value转成int,用于后面的加减和排序
            return name_dict
    
    
    def draw_people(name_list):
        if len(name_new_list) == len(name_list):  # 如果原始列表和存放抽取名字的列表相等,清空存放名字列表
            nu = input('名单上的人员都已被抽过!开启新一轮的抽签请输入1  返回上级菜单请输入2
    ')
            if nu == '1':
                name_new_list.clear()
            else:
                return
        while True:
            people_name = random.choice(name_list)
            if people_name not in name_new_list:
                name_new_list.append(people_name)
                print('此次抽中的人员是:', people_name)
                mark_score(people_name, name_dict)
                break
    
    
    '''
    使用递归调用
        people_name = random.choice(name_list)
        if people_name not in name_new_list:
            name_new_list.append(people_name)
            print('此次抽中的人员是:', people_name)
            mark_score(people_name, name_dict)
        else:
            draw_people()
    '''
    
    
    def mark_score(people_name, name_dict):
        print("该人员的现有分数是:%s分" % (name_dict[people_name]))
        while True:
            try:
                now_score = int(input("请给抽中的人员打分数(请输入整数):"))
                name_dict[people_name] += now_score # 总分
                with open(filename, 'w', encoding='utf-8') as f:
                    tmp = ''
                    for key in name_dict:  # 用key来循环,把key和value组装
                        tmp += (str(key) + ":" + str(name_dict[key]) + '
    ')
                    f.writelines(tmp)  # 一次性写入
                    f.close()  # 保存
                break
            except ValueError:
                print('请输入一个整数')
    
    
    def sort_score(name_and_score):  # 排序
        desc = sorted(
            name_and_score.items(),
            key=operator.itemgetter(1),
            reverse=False)[:3]  # 倒序排,输出前三
        asc = sorted(
            name_and_score.items(),
            key=operator.itemgetter(1),
            reverse=True)[:3]  # 正序排,输出前三
        '''
        name_and_score.items(): dict_items([('张三', 506), ('李四', '344'), ('waang2', '4029'), ('yuuu', '64')])
        operator排序速度比匿名函数更快,也支持多个关键字同时排序。,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。
        itemgetter(1)是获取items()对象的第一个域,对域的值排序(对value排序)
        '''
        print("排名前三位的人员:", dict(asc))
        print("排名后三位的人员:", dict(desc))
    
    
    def main():
        name_score = read_txt()
        name_list = list(name_score.keys())  # 把姓名拿出来,当一个列表,用来抽取
        num = input("---抽签,请输入1
    ---查看排名,请输入2
    ---退出程序,请输入3
    请输入:")
        if num == '1':
            draw_people(name_list)
            print('
    ')
            main()
        elif num == '2':
            sort_score(name_score)
            print('
    ')
            main()
        else:
            sys.exit(0)
    
    
    if __name__ == '__main__':
        main()

    抽签方法不用递归,用while循环实现

    def draw_people():
        name_score = read_txt()
        name_list = list(name_score.keys())  # 把姓名拿出来,当一个列表,用来抽取
        if len(name_new_list) == len(name_list):# 如果原始列表和存放抽取名字的列表相等,清空存放名字列表
            nu = input('名单上的人员都已被抽过!开启新一轮的抽签请输入1  返回上级菜单请输入2
    ')
            if nu == '1':
                name_new_list.clear()
            else:
                return
        while True:
            people_name = random.choice(name_list)
            if people_name not in name_new_list:
                name_new_list.append(people_name)
                print('此次抽中的人员是:',people_name)
                mark_score(people_name,name_dict)
                break
  • 相关阅读:
    软工第三次团队作业
    软工第四次团队作业
    【alpha阶段】第一次Scrum Meeting
    Alpha阶段发布说明
    【Alpha】阶段第十次Scrum Meeting
    【Alpha】阶段第九次Scrum Meeting
    【Alpha】阶段第八次Scrum Meeting
    【Alpha】阶段第七次Scrum Meeting
    【Alpha】阶段第六次Scrum Meeting
    【Alpha】阶段第五次Scrum Meeting
  • 原文地址:https://www.cnblogs.com/dydxw/p/14973053.html
Copyright © 2020-2023  润新知