考试中知道自己的成绩以及其他所有人的成绩,计算在特定情况下自己参加复试的概率。
写在最前,我是菜鸟,到现在接触python不足两周,这期间看书以及视频学习基本知识,不过总感觉效果不理想。前几天我参加了一个事业单位招聘考试,两天后公布了所有考生的成绩,一共3196名。看完后我就有个想法,想计算我能参加复试的概率,就拿python来练手,边练边学,看效果怎样。
要求是这样的:
总参考人数3196名考生的考号和对应分数在excel表格中,已知我所报考单位只招聘一人,报考该单位考生一共71人,按1:3参加复试,也就是说这71人里边前三名可以参 加复试。已知我的成绩,想求我能参加复试的概率。(注:在这3196名考生中,不知道是哪70人和自己报考同一单位)
因为是新手,接下来我会详细记录我的学习过程,如果在看文章的你也是刚刚接触python并想深入学习,希望我的学习历程能对你有所帮助,若有幸能被高手读到,还希望能不吝指教。
我把目标拆分成几个步骤,如下:
1,除去自己,在其余3195名中找出包含70个元素的所有组合,并统计组合的个数为Y;
2,将自己的成绩添加到每个组合中;
3,对这些组合从大到小排序;
4,统计自己的成绩在前三名的组合的个数为X;
5,计算X/Y,即得自己能参加复试的概率。
下面各个解决
1,首先解决如何找出包含70个元素的组合,代码如下
1 import itertools 2 Combinatorial_Sequences = itertools.combinations(test_result,70) #test_result是存储成绩序列的变量
刚开始问题就出现了,电脑一直卡死,我猜想问题应该是结果太多,计算量太大。于是我决定计算一下组合的个数,根据基本公式C(m,n)=m!/[(m-n)!*n!],编写代码如下:
def combinatorial_num(m,n): #定义求解组合个数函数 t = 1 i = m-1 u = n-1 while t < n: m = m*i i -= 1 t += 1 while u >0: n = n*u u -= 1 return int(m/n) >>> combinatorial_num(3195,70) 8014553219879436656594612402147999867010534534563546688481573383337953460075426682671389800532431942744732420482095853198125506158432530850643968
1 >>> combinatorial_num(5,3) #刚才忘记了,我要验证一下这段代码正确与否,好让你相信上面那一长串数字是正确的结果。 2 10 3 >>> combinatorial_num(6,4) 4 15 5 >>> combinatorial_num(7,3) 6 35
显然组合个数太TM多了,怪不得会卡死。所以,必须改变路线——缩小数字,在理想情况下计算结果。但是这样就没办法计算我能参加复试的概率了,不过这也无妨,因为结果已经公布了——我没有进入复试,管他呢,现在的目标是学习Python解决我提出的问题。
问题更改为
总参考人数15名考生的考号和对应分数在excel表格中,已知我所报考单位只招聘一人,报考该单位考生一共4人,按1:2参加复试,也就是说这4人里边前2名可以参 加复试。已知我的成绩排在第5名,想求我能参加复试的概率。(注:在这15名考生中,不知道是哪4人和自己报考同一单位)
第一步:除去自己,在其余15名中找出包含3个元素的所有组合;
请原谅我真的把这364个组合一并贴出来了
1 import itertools 2 all_results = [81.25,80.05,78.95,78.7,76.65,76.5,76.15,75.7,75.15,74.25,73.9,73.75,73.7,73.65,73.4] #15个考生的成绩列表 3 exclude_me = all_results[:4]+all_results[5:] #假设自己是第5名,除去自己的成绩(注:python从0开始计数) 4 combinations_exclude_me = itertools.combinations(exclude_me,3) #计算出包含三个元素的所有组合,存在变量combinations_exclude_me中 5 print(list(combinations_exclude_me)) #输出所有组合
[(81.25, 80.05, 78.95), (81.25, 80.05, 78.7), (81.25, 80.05, 76.5), (81.25, 80.05, 76.15), (81.25, 80.05, 75.7), (81.25, 80.05, 75.15), (81.25, 80.05, 74.25), (81.25, 80.05, 73.9), (81.25, 80.05, 73.75), (81.25, 80.05, 73.7), (81.25, 80.05, 73.65), (81.25, 80.05, 73.4), (81.25, 78.95, 78.7), (81.25, 78.95, 76.5), (81.25, 78.95, 76.15), (81.25, 78.95, 75.7), (81.25, 78.95, 75.15), (81.25, 78.95, 74.25), (81.25, 78.95, 73.9), (81.25, 78.95, 73.75), (81.25, 78.95, 73.7), (81.25, 78.95, 73.65), (81.25, 78.95, 73.4), (81.25, 78.7, 76.5), (81.25, 78.7, 76.15), (81.25, 78.7, 75.7), (81.25, 78.7, 75.15), (81.25, 78.7, 74.25), (81.25, 78.7, 73.9), (81.25, 78.7, 73.75), (81.25, 78.7, 73.7), (81.25, 78.7, 73.65), (81.25, 78.7, 73.4), (81.25, 76.5, 76.15), (81.25, 76.5, 75.7), (81.25, 76.5, 75.15), (81.25, 76.5, 74.25), (81.25, 76.5, 73.9), (81.25, 76.5, 73.75), (81.25, 76.5, 73.7), (81.25, 76.5, 73.65), (81.25, 76.5, 73.4), (81.25, 76.15, 75.7), (81.25, 76.15, 75.15), (81.25, 76.15, 74.25), (81.25, 76.15, 73.9), (81.25, 76.15, 73.75), (81.25, 76.15, 73.7), (81.25, 76.15, 73.65), (81.25, 76.15, 73.4), (81.25, 75.7, 75.15), (81.25, 75.7, 74.25), (81.25, 75.7, 73.9), (81.25, 75.7, 73.75), (81.25, 75.7, 73.7), (81.25, 75.7, 73.65), (81.25, 75.7, 73.4), (81.25, 75.15, 74.25), (81.25, 75.15, 73.9), (81.25, 75.15, 73.75), (81.25, 75.15, 73.7), (81.25, 75.15, 73.65), (81.25, 75.15, 73.4), (81.25, 74.25, 73.9), (81.25, 74.25, 73.75), (81.25, 74.25, 73.7), (81.25, 74.25, 73.65), (81.25, 74.25, 73.4), (81.25, 73.9, 73.75), (81.25, 73.9, 73.7), (81.25, 73.9, 73.65), (81.25, 73.9, 73.4), (81.25, 73.75, 73.7), (81.25, 73.75, 73.65), (81.25, 73.75, 73.4), (81.25, 73.7, 73.65), (81.25, 73.7, 73.4), (81.25, 73.65, 73.4), (80.05, 78.95, 78.7), (80.05, 78.95, 76.5), (80.05, 78.95, 76.15), (80.05, 78.95, 75.7), (80.05, 78.95, 75.15), (80.05, 78.95, 74.25), (80.05, 78.95, 73.9), (80.05, 78.95, 73.75), (80.05, 78.95, 73.7), (80.05, 78.95, 73.65), (80.05, 78.95, 73.4), (80.05, 78.7, 76.5), (80.05, 78.7, 76.15), (80.05, 78.7, 75.7), (80.05, 78.7, 75.15), (80.05, 78.7, 74.25), (80.05, 78.7, 73.9), (80.05, 78.7, 73.75), (80.05, 78.7, 73.7), (80.05, 78.7, 73.65), (80.05, 78.7, 73.4), (80.05, 76.5, 76.15), (80.05, 76.5, 75.7), (80.05, 76.5, 75.15), (80.05, 76.5, 74.25), (80.05, 76.5, 73.9), (80.05, 76.5, 73.75), (80.05, 76.5, 73.7), (80.05, 76.5, 73.65), (80.05, 76.5, 73.4), (80.05, 76.15, 75.7), (80.05, 76.15, 75.15), (80.05, 76.15, 74.25), (80.05, 76.15, 73.9), (80.05, 76.15, 73.75), (80.05, 76.15, 73.7), (80.05, 76.15, 73.65), (80.05, 76.15, 73.4), (80.05, 75.7, 75.15), (80.05, 75.7, 74.25), (80.05, 75.7, 73.9), (80.05, 75.7, 73.75), (80.05, 75.7, 73.7), (80.05, 75.7, 73.65), (80.05, 75.7, 73.4), (80.05, 75.15, 74.25), (80.05, 75.15, 73.9), (80.05, 75.15, 73.75), (80.05, 75.15, 73.7), (80.05, 75.15, 73.65), (80.05, 75.15, 73.4), (80.05, 74.25, 73.9), (80.05, 74.25, 73.75), (80.05, 74.25, 73.7), (80.05, 74.25, 73.65), (80.05, 74.25, 73.4), (80.05, 73.9, 73.75), (80.05, 73.9, 73.7), (80.05, 73.9, 73.65), (80.05, 73.9, 73.4), (80.05, 73.75, 73.7), (80.05, 73.75, 73.65), (80.05, 73.75, 73.4), (80.05, 73.7, 73.65), (80.05, 73.7, 73.4), (80.05, 73.65, 73.4), (78.95, 78.7, 76.5), (78.95, 78.7, 76.15), (78.95, 78.7, 75.7), (78.95, 78.7, 75.15), (78.95, 78.7, 74.25), (78.95, 78.7, 73.9), (78.95, 78.7, 73.75), (78.95, 78.7, 73.7), (78.95, 78.7, 73.65), (78.95, 78.7, 73.4), (78.95, 76.5, 76.15), (78.95, 76.5, 75.7), (78.95, 76.5, 75.15), (78.95, 76.5, 74.25), (78.95, 76.5, 73.9), (78.95, 76.5, 73.75), (78.95, 76.5, 73.7), (78.95, 76.5, 73.65), (78.95, 76.5, 73.4), (78.95, 76.15, 75.7), (78.95, 76.15, 75.15), (78.95, 76.15, 74.25), (78.95, 76.15, 73.9), (78.95, 76.15, 73.75), (78.95, 76.15, 73.7), (78.95, 76.15, 73.65), (78.95, 76.15, 73.4), (78.95, 75.7, 75.15), (78.95, 75.7, 74.25), (78.95, 75.7, 73.9), (78.95, 75.7, 73.75), (78.95, 75.7, 73.7), (78.95, 75.7, 73.65), (78.95, 75.7, 73.4), (78.95, 75.15, 74.25), (78.95, 75.15, 73.9), (78.95, 75.15, 73.75), (78.95, 75.15, 73.7), (78.95, 75.15, 73.65), (78.95, 75.15, 73.4), (78.95, 74.25, 73.9), (78.95, 74.25, 73.75), (78.95, 74.25, 73.7), (78.95, 74.25, 73.65), (78.95, 74.25, 73.4), (78.95, 73.9, 73.75), (78.95, 73.9, 73.7), (78.95, 73.9, 73.65), (78.95, 73.9, 73.4), (78.95, 73.75, 73.7), (78.95, 73.75, 73.65), (78.95, 73.75, 73.4), (78.95, 73.7, 73.65), (78.95, 73.7, 73.4), (78.95, 73.65, 73.4), (78.7, 76.5, 76.15), (78.7, 76.5, 75.7), (78.7, 76.5, 75.15), (78.7, 76.5, 74.25), (78.7, 76.5, 73.9), (78.7, 76.5, 73.75), (78.7, 76.5, 73.7), (78.7, 76.5, 73.65), (78.7, 76.5, 73.4), (78.7, 76.15, 75.7), (78.7, 76.15, 75.15), (78.7, 76.15, 74.25), (78.7, 76.15, 73.9), (78.7, 76.15, 73.75), (78.7, 76.15, 73.7), (78.7, 76.15, 73.65), (78.7, 76.15, 73.4), (78.7, 75.7, 75.15), (78.7, 75.7, 74.25), (78.7, 75.7, 73.9), (78.7, 75.7, 73.75), (78.7, 75.7, 73.7), (78.7, 75.7, 73.65), (78.7, 75.7, 73.4), (78.7, 75.15, 74.25), (78.7, 75.15, 73.9), (78.7, 75.15, 73.75), (78.7, 75.15, 73.7), (78.7, 75.15, 73.65), (78.7, 75.15, 73.4), (78.7, 74.25, 73.9), (78.7, 74.25, 73.75), (78.7, 74.25, 73.7), (78.7, 74.25, 73.65), (78.7, 74.25, 73.4), (78.7, 73.9, 73.75), (78.7, 73.9, 73.7), (78.7, 73.9, 73.65), (78.7, 73.9, 73.4), (78.7, 73.75, 73.7), (78.7, 73.75, 73.65), (78.7, 73.75, 73.4), (78.7, 73.7, 73.65), (78.7, 73.7, 73.4), (78.7, 73.65, 73.4), (76.5, 76.15, 75.7), (76.5, 76.15, 75.15), (76.5, 76.15, 74.25), (76.5, 76.15, 73.9), (76.5, 76.15, 73.75), (76.5, 76.15, 73.7), (76.5, 76.15, 73.65), (76.5, 76.15, 73.4), (76.5, 75.7, 75.15), (76.5, 75.7, 74.25), (76.5, 75.7, 73.9), (76.5, 75.7, 73.75), (76.5, 75.7, 73.7), (76.5, 75.7, 73.65), (76.5, 75.7, 73.4), (76.5, 75.15, 74.25), (76.5, 75.15, 73.9), (76.5, 75.15, 73.75), (76.5, 75.15, 73.7), (76.5, 75.15, 73.65), (76.5, 75.15, 73.4), (76.5, 74.25, 73.9), (76.5, 74.25, 73.75), (76.5, 74.25, 73.7), (76.5, 74.25, 73.65), (76.5, 74.25, 73.4), (76.5, 73.9, 73.75), (76.5, 73.9, 73.7), (76.5, 73.9, 73.65), (76.5, 73.9, 73.4), (76.5, 73.75, 73.7), (76.5, 73.75, 73.65), (76.5, 73.75, 73.4), (76.5, 73.7, 73.65), (76.5, 73.7, 73.4), (76.5, 73.65, 73.4), (76.15, 75.7, 75.15), (76.15, 75.7, 74.25), (76.15, 75.7, 73.9), (76.15, 75.7, 73.75), (76.15, 75.7, 73.7), (76.15, 75.7, 73.65), (76.15, 75.7, 73.4), (76.15, 75.15, 74.25), (76.15, 75.15, 73.9), (76.15, 75.15, 73.75), (76.15, 75.15, 73.7), (76.15, 75.15, 73.65), (76.15, 75.15, 73.4), (76.15, 74.25, 73.9), (76.15, 74.25, 73.75), (76.15, 74.25, 73.7), (76.15, 74.25, 73.65), (76.15, 74.25, 73.4), (76.15, 73.9, 73.75), (76.15, 73.9, 73.7), (76.15, 73.9, 73.65), (76.15, 73.9, 73.4), (76.15, 73.75, 73.7), (76.15, 73.75, 73.65), (76.15, 73.75, 73.4), (76.15, 73.7, 73.65), (76.15, 73.7, 73.4), (76.15, 73.65, 73.4), (75.7, 75.15, 74.25), (75.7, 75.15, 73.9), (75.7, 75.15, 73.75), (75.7, 75.15, 73.7), (75.7, 75.15, 73.65), (75.7, 75.15, 73.4), (75.7, 74.25, 73.9), (75.7, 74.25, 73.75), (75.7, 74.25, 73.7), (75.7, 74.25, 73.65), (75.7, 74.25, 73.4), (75.7, 73.9, 73.75), (75.7, 73.9, 73.7), (75.7, 73.9, 73.65), (75.7, 73.9, 73.4), (75.7, 73.75, 73.7), (75.7, 73.75, 73.65), (75.7, 73.75, 73.4), (75.7, 73.7, 73.65), (75.7, 73.7, 73.4), (75.7, 73.65, 73.4), (75.15, 74.25, 73.9), (75.15, 74.25, 73.75), (75.15, 74.25, 73.7), (75.15, 74.25, 73.65), (75.15, 74.25, 73.4), (75.15, 73.9, 73.75), (75.15, 73.9, 73.7), (75.15, 73.9, 73.65), (75.15, 73.9, 73.4), (75.15, 73.75, 73.7), (75.15, 73.75, 73.65), (75.15, 73.75, 73.4), (75.15, 73.7, 73.65), (75.15, 73.7, 73.4), (75.15, 73.65, 73.4), (74.25, 73.9, 73.75), (74.25, 73.9, 73.7), (74.25, 73.9, 73.65), (74.25, 73.9, 73.4), (74.25, 73.75, 73.7), (74.25, 73.75, 73.65), (74.25, 73.75, 73.4), (74.25, 73.7, 73.65), (74.25, 73.7, 73.4), (74.25, 73.65, 73.4), (73.9, 73.75, 73.7), (73.9, 73.75, 73.65), (73.9, 73.75, 73.4), (73.9, 73.7, 73.65), (73.9, 73.7, 73.4), (73.9, 73.65, 73.4), (73.75, 73.7, 73.65), (73.75, 73.7, 73.4), (73.75, 73.65, 73.4), (73.7, 73.65, 73.4)]
>>>
昨天看了微软build大会,一直到夜里3点,白天没休息,太困了,明天继续。
接下来任务是将我的成绩添加到各个组合中。问题来了,在经过多次尝试之后发现无法将元素添加进去,后来知道元组在确定之后是不允许修改的。所以需要把上面列表中的364个元组转换为列表。代码如下(这里只用假设的例子完成转换过程)
然后将自己的成绩添加到各个列表(此处假设将6添加到个列表),将这两步一并给出。
1 a = [(5,2,7),(8,4,1),(9,3,6)] #假设一个包含三个元组的列表a 2 i = 0 3 new_a = [] 4 while i < (len(a)): 5 t = list(a[i]) #将a的第i个元素转换为列表并赋给变量t 6 t.append(6) #将元素‘6’添加到个列表 7 new_a = new_a + [t] 8 i +=1 9 print(new_a)
[[5, 2, 7, 6], [8, 4, 1, 6], [9, 3, 6, 6]] >>>
然后对各个列表从大到小排序
1 new_a = [[5, 2, 7, 6], [8, 4, 1, 6], [9, 3, 6, 6]] 2 i = 0 3 sorted_a = [] 4 while i < len(new_a): 5 new_a[i].sort(reverse=True) # 将各个列表从大到小排序 6 sorted_a = sorted_a + [new_a[i]] # 拼接列表 7 i += 1 8 print(sorted_a) [[7, 6, 5, 2], [8, 6, 4, 1], [9, 6, 6, 3]] >>>
下面统计6在各个列表中排前三名的个数,并计算排前三名的个数站总组合个数的比例
1 sorted_a = [[7, 6, 5, 2], [8, 6, 4, 1], [9, 6, 6, 3]] 2 i = 0 3 n = 0 4 while i < len(sorted_a): 5 t = sorted_a[i].index(6) #查找6在各个列表中的排名位数,返回给t 6 if t < 3: 7 n +=1 #当t<3时,即排在前三名时,计数变量n加1 8 else : 9 n = n #当不在前三名,计数不变 10 i += 1 11 print('排在前三位的个数为',n) 12 print('总组合个数为',len(sorted_a)) 13 final_p = n/(len(sorted_a)) #排前三个数除以总组合个数 14 print("参加复试的概率为","%.2f%%" % (final_p*100)) #以百分比形式打印出此概率
>>> 排在前三位的个数为 3 总组合个数为 3 参加复试的概率为 100.00% # -_-|| 这算是自己讽刺自己么,明明没参加复试,还找一个概率是100%的例子。。。
好吧,最后就用原始数据,当然是截取过的原始数据,来用完整代码跑一下。
1 import itertools 2 3 all_results = [81.25,80.05,78.95,78.7,76.65,76.5,76.15,75.7,75.15,74.25,73.9,73.75,73.7,73.65,73.4] 4 results_exclude_me = all_results[:4]+all_results[5:] #除去我的分数 5 all_combinations = list(itertools.combinations(results_exclude_me,3)) #得到除我以外的含有三个元素的所有组合 6 i = 0 7 success_num = 0 #初始化排前三位的个数 8 while i < (len(all_combinations)): 9 t = list(all_combinations[i]) #将元组转换为列表 10 t.append(all_results[4]) #将我的成绩添加到各组合 11 t.sort(reverse=True) #对组合进行排序 12 n = t.index(all_results[4]) 13 if n < 3: 14 success_num +=1 15 else: 16 success_num = success_num 17 i += 1 18 combinations_num = len(all_combinations) 19 print('排在前三位的次数为:',success_num) 20 print('总组合个数为:',combinations_num) 21 print('参加复试的概率为',"%.2f%%" % ((success_num/combinations_num)*100))
结果如下
>>>
当测试者排第4位时
排在前三位的次数为: 360
总组合个数为: 364
参加复试的概率为 98.90%
当测试者排第8位时: #此行非程序运行得到 排在前三位的次数为: 308 总组合个数为: 364 参加复试的概率为 84.62% >>>
至此完毕,暂时得到了最初想要的结果,不过我认为还有太多地方可以改进,暂时想到的改进点有:
1,原始数据可以通过读取文件的方式导入
2,如果能和使用者交互会更好,比如允许使用者输入自己的名次,然后得到结果。
写在最后
程序虽然很小,可是完成下来真的学到了太多的知识,远远比啃书本效率高很多。事先本来想在最后把在这个过程学到的知识点罗列出来,不过玩了才发现,真是太多了,有些只是很小的方面,比如说冒号的使用,所以就不罗列了。
望各路大神不吝指教!