考试中知道自己的成绩以及其他所有人的成绩,计算在特定情况下自己参加复试的概率。

      写在最前,我是菜鸟,到现在接触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,如果能和使用者交互会更好,比如允许使用者输入自己的名次,然后得到结果。

写在最后

      程序虽然很小,可是完成下来真的学到了太多的知识,远远比啃书本效率高很多。事先本来想在最后把在这个过程学到的知识点罗列出来,不过玩了才发现,真是太多了,有些只是很小的方面,比如说冒号的使用,所以就不罗列了。

      望各路大神不吝指教!

 

posted @ 2015-04-30 22:05  阿超ach  阅读(152)  评论(0)    收藏  举报