python的random函数掷色子和为7的概率_案例(7):模拟掷骰子

本章通过模拟掷骰子计算的5案例来进行学习基础的Python程序

案例描述

通过计算机程序模拟抛掷骰子,并显示各点数的出现次数及频率

比如:抛掷2个骰子50次,出现点数为7的次数是8,频率是0.16

模拟图

案例分析

根据以下函数判断密码强度并输出:

1.设置一个变量strength_level用于记录密码的强度,初始为0。满足一个条件,对其加1;

2.长度判断:使用len()方法;

3.包含数字判断:对密码字符串遍历,使用isnumeric()方法;

4.包含字母判断:对密码字符串遍历,使用isalpha()方法;

5.如果strength_level等于3,密码强度合格,否则不合格

v1.0

新建一个简单的Python程序,1.0功能:模拟抛掷1个骰子,并输出其结果;通过Python的random模块模拟随机事件或者生成随机数;遍历列表时,使用enumerate()函数同时获取每个元素的索引号及其元素值。首先掷骰子编写成一个函数,然后编写主函数设置参数并开始掷骰子,最后输出结果。

知识点:

1.random模块

(1)random模块用于生成随机数,包含整数,浮点数,获取列表中的随机元素

(2)常用函数,random库里面有几个常用的函数,分别如下:

random常用函数

2.enumerate()函数

(1)enumerate()函数用于将可遍历的组合转换为一个索引序列

(2)一般用于for循环中,同时列出元素和元素的索引号

random模块函数示例:

enumerate函数示例:

扔骰子函数,先引入ramdom库,randint(1,6)返回的是1 - 6的整数赋值给dice_num,最后返回该结果:

import random

def roll_dice():

"""

掷骰子

"""

dice_num = random.randint(1, 6)

return dice_num

主体代码,里面先初始化主要的参数是total_time次数和result_list次数统计列表,for循环迭代range(total_times)对象,计算每次掷骰子的结果然后再for循环给统计列表计数,若符合则+1,最后enumerate()会返回两个参数,第1个给i,第2个给result再进行for循环迭代,因为列表下标是从0开始的,所以format的i需要+1正确显示0:

# 掷骰子次数

total_times = 1000

# 初始化结果列表[0,0,0,0,0,0]

result_list = [0] * 6

# 开始掷骰子

for i in range(total_times):

roll = roll_dice()

# 给列表计数

for j in range(1, 7):

if roll == j:

result_list[j - 1] += 1

# 输出结果

for i, result in enumerate(result_list):

print("计数为{}的骰子出现次数{},频率:{}".format(i + 1, result, result / total_times))

结果如图所示:

1个骰子1000次结果统计

v2.0

在v1.0的基础上,2.0功能:模拟抛掷2个骰子,并输出其结果。由于要2个骰子,因此骰子的点数要新建列表,然后使用字典将对应的点数和次数关联起来。zip()函数的作用就是把骰子列表和统计列表组合成元组,然后用dict()转换成字典。

知识点:

1.zip()函数:

(1)zip()函数用于将对应的元素打包成一个个元组

(2)注意:元组中的元素是不可修改的,若要修改元素值可转换成字典类型;如:dict(zip(l1, l2))

(3)Python2.x版本和Python3版本的zip()函数返回结果不同,示例如下:

Python2

Python3示例

zip函数示例:

投掷子函数之前相同,不展示了。

具体代码,首先新建结果列表,因为2个骰子的结果有11种,所以要[0]*11,而点数列表对应也有11种,并且是2 - 12。dict(zip(roll_list, result_list))返回的结果是key为点数,value为结果计数的字典:

# 掷骰子次数

total_times = 1000

# 初始化结果列表[0,0,0,0,0,0]

result_list = [0] * 11

# 初始化点数列表

roll_list = list(range(2, 13))

roll_dict = dict(zip(roll_list, result_list))

print(roll_dict)

# 开始掷骰子

for i in range(total_times):

roll1 = roll_dice()

roll2 = roll_dice()

# 给列表计数

for j in range(2, 13):

if (roll1 + roll2) == j:

roll_dict[j] += 1

# 输出结果

for i, result in roll_dict.items():

print("计数为{}出现的次数为{},频率:{}".format(i, result, result / total_times))

运行结果:

v3.0

在2.0的基础上,3.0功能:可视化抛掷2个骰子的结果;通过绘制散点图图像,简单分析数据的分布情况,使用到matploylib库。

知识点:

1.Python数据可视化:matplotlib模块

(1)matplotlib是一个数据可视化函数库

(2)matplotlib的子模块pyplot提供了2D图表制作的基本函数

(3)例子:https://matplotlib.org/gallery.html

(4)散点图绘制操作

import matplotlib.pyplot as plt

plt.scatter(x, y) # x, y分别是x坐标和y坐标的列表

plt.show()

2.scatter()参数详解

matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, *, data=None, **kwargs)

参数的解释:

x,y:表示的是大小为(n,)的数组,也就是我们即将绘制散点图的数据点

s:是一个实数或者是一个数组大小为(n,),这个是一个可选的参数。

c:表示的是颜色,也是一个可选项。默认是蓝色'b',表示的是标记的颜色,或者可以是一个表示颜色的字符,或者是一个长度为n的表示颜色的序列等等,感觉还没用到过现在不解释了。但是c不可以是一个单独的RGB数字,也不可以是一个RGBA的序列。可以是他们的2维数组(只有一行)。

marker:表示的是标记的样式,默认的是'o'。

cmap:Colormap实体或者是一个colormap的名字,cmap仅仅当c是一个浮点数数组的时候才使用。如果没有申明就是image.cmap

norm:Normalize实体来将数据亮度转化到0-1之间,也是只有c是一个浮点数的数组的时候才使用。如果没有申明,就是默认为colors.Normalize。

vmin,vmax:实数,当norm存在的时候忽略。用来进行亮度数据的归一化。

alpha:实数,0-1之间。

主要代码,骰子的计数方式和之前相同,新增绘制散点图。散点图绘制要先import引入库,在用scatter()设置骰子1和2的显示方式,参数包含x轴坐标,y轴坐标,颜色和透明度,最后显示:

# 掷骰子次数

total_times = 1000

# 初始化结果列表[0,0,0,0,0,0]

result_list = [0] * 11

# 初始化点数列表

roll_list = list(range(2, 13))

roll_dict = dict(zip(roll_list, result_list))

# 初始化骰子结果列表

roll1_result = []

roll2_result = []

# 开始掷骰子

for i in range(total_times):

roll1 = roll_dice()

roll2 = roll_dice()

roll1_result.append(roll1)

roll2_result.append(roll2)

# 给列表计数

for j in range(2, 13):

if (roll1 + roll2) == j:

roll_dict[j] += 1

# 输出结果

for i, result in roll_dict.items():

print("计数为{}出现的次数为{},频率:{}".format(i, result, result / total_times))

# 绘制散点图

x = range(1, total_times + 1)

plt.scatter(x, roll1_result, c="red", alpha=0.5)

plt.scatter(x, roll2_result, c="blue", alpha=0.5)

plt.show()

代码部分运行结果:

散点图

v4.0

在v3.0的基础上,4.0功能:对结果进行简单的数据统计和分析。使用matplotlib直方图做简单的数据统计分析。直方图可以直接看到分布情况,简单易懂。在做数据分析或机器学习时会经常用到。

知识点:

1.matplotlib直方图

(1)直方图是一种对数据分布情况的图形表示

(2)首先要对数据进行分组,然后统计每个分组内数据的数量。

(3)作用:

• 显示各分组频率或数量分布的情况

• 易于显示各组之间频率或数量的差别

(4)matplotlib绘制直方图

plt.hist(data, bins)

data: 数据列表

bins: 分组边界

2.hist()参数和返回值:

调用方式:

n, bins, patches = plt.hist(arr, bins=10, normed=0, facecolor='black', edgecolor='black',alpha=1,histtype='bar')

hist的参数非常多,但常用的就这六个,只有第一个是必须的,后面四个可选

arr: 需要计算直方图的一维数组

bins: 直方图的柱数,可选项,默认为10

normed: 是否将得到的直方图向量归一化。默认为0

facecolor: 直方图颜色

edgecolor: 直方图边框颜色

alpha: 透明度

histtype: 直方图类型,‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’

返回值 :

n: 直方图向量,是否归一化由参数normed设定

bins: 返回各个bin的区间范围

patches: 返回每个bin里面包含的数据,是一个list

plt.rcParams[]详解参考:http://www.cnblogs.com/pacino12134/p/9776882.html

主要代码,骰子的计数方式和之前相同,新增绘制直方图。直方图绘制要先import引入库,在用hist()设置直方图的显示形状,参数包含x轴坐标,y轴坐标,归一化即y轴数据修改为频率,边框颜色(间隔开方便观察);title()设置直方图标题,xlabel()设置x轴标题,ylabel设置y轴标题,这3个都用size更改字体大小。最后显示::

# 掷骰子次数

total_times = 100000

# 初始化结果列表[0,0,0,0,0,0]

result_list = [0] * 11

# 初始化点数列表

roll_list = list(range(2, 13))

roll_dict = dict(zip(roll_list, result_list))

# 掷骰子结果初始化

roll_list = []

# 开始掷骰子

for i in range(total_times):

roll1 = roll_dice()

roll2 = roll_dice()

roll_list.append(roll1 + roll2)

# 给列表计数

for j in range(2, 13):

if (roll1 + roll2) == j:

roll_dict[j] += 1

# 输出结果

for i, result in roll_dict.items():

print("计数为{}出现的次数为{},频率:{}".format(i, result, result / total_times))

# 绘制散点图

plt.hist(roll_list, bins=range(2, 14), density=1, edgecolor="yellow", rwidth=3) # normed=1

plt.title("骰子点数统计",size=16)

plt.xlabel("点数", size=10)

plt.ylabel("频率", size=10)

plt.show()

执行结果:

v5.0

在v4.0的基础上,5.0功能:使用科学计算库简化程序,完善数据可视化结果。使用科学计算库NumPy简化程序。numpy可以直接生成大量的随机数对象数组,不需要再每次生成1个再加入列表中了,除此之外numpy还包含其他处理多维数组的方法。

知识点:

NumPy

(1)NumPy (Numeric Python):用Python实现的科学计算库

(2)包括:

a.强大的N维数组对象array

b.成熟的科学函数库

c.实用的线性代数、随机数生成函数等

(3)NumPy的操作对象是多维数组ndarray

(4)ndarray.shape 数组的维度;操作方法如下:

创建数组:np.array(),np.arrange() …

改变数组形状 reshape()

2.histogram()详解

umpy.histogram(a, bins=10, range=None, normed=False, weights=None, density=None)

参数:

a : array_like

输入数据。直方图在平顶阵列上计算。

bin : int或scalars或str的序列,可选

如果bin是int,则它定义给定范围内的等宽bin的数量(默认为10)。如果bin是一个序列,它定义了一个单调增加的bin边缘数组,包括最右边的边,允许不均匀的bin宽度。

range :( float,float),可选

箱子的下部和上部范围。如果没有提供,范围很简单。超出范围的值将被忽略。范围的第一个元素必须小于或等于第二个元素。range也会影响自动bin计算。虽然基于范围内的实际数据计算箱宽度是最佳的,但箱计数将填充整个范围,包括不包含数据的部分。(a.min(), a.max())

normed : bool,可选

从版本1.6.0开始不推荐使用。

这相当于density参数,但是对于不相等的bin宽度产生不正确的结果。不应该使用它。

weights : array_like,可选

一系列重量,形状与a相同。中的每个值 一个不仅有助于其相关联的权重对所述的箱数(而不是1)。如果密度为True,则将权重归一化,以使密度在整个范围内的积分保持为1。

density : bool,可选

如果False,结果将包含每个bin中的样本数。如果True,结果是bin处的概率密度函数的值,则归一化使得该范围上的积分为1.注意,除非选择单位宽度的区间,否则直方图值的总和将不等于1; 它不是概率质量函数。

返回值,有两个,

hist : array

bin_edges : array of dtype float,bin edges 的长度要是 hist 的长度加1,bin edges (length(hist)+1),也即 (bin_edges[0], bin_edges[1]) ⇒ hist[0],….,(bin_edges[-2], bin_edges[-1]) ⇒ hist[-1],bin_edges 参数与输入参数的 bins 保持一致;

主函数代码,先导入numpy库,调用里面的random.randint()直接生成含有大量随机数的对象数组,方法函数包含起始数,终结数,数据数量;然后调用np.histogram统计结果,返回2-12点数的出现次数和对应的区间;然后hist绘制直方图,参数包含y轴数据,x轴数据,归一化,边框颜色,边框宽度,方条间隔;xticks()设置x轴坐标点的显示,参数包含显示坐标(这里+0.5居中显示方便观看)和坐标点显示的标题;接着设置标题,y和x的标题,最后显示。

# 掷骰子次数

total_times = 1000000

# 使用array操作随机数

roll1_arr = np.random.randint(1, 7, size=total_times)

roll2_arr = np.random.randint(1, 7, size=total_times)

# 统计结果、

result_arr = (roll1_arr + roll2_arr)

hist, bins = np.histogram(result_arr, bins=range(2, 14))

print(hist)

print(bins)

# 绘制散点图

plt.hist(result_arr, bins=range(2, 14), density=1, edgecolor="yellow", linewidth=1, rwidth=0.8) # normed=1

# 设置x轴坐标点显示

tick_labels = ["2点", "3点", "4点", "5点",

"6点", "7点", "8点", "9点", "10点", "11点", "12点"]

tick_pos = np.arange(2, 13) + 0.5

plt.xticks(tick_pos, tick_labels)

plt.title("骰子点数统计", size=16)

plt.xlabel("点数", size=10)

plt.ylabel("频率", size=10)

plt.show()

执行结果:

总结

模拟掷骰子的5个例子,知识点归纳如下:

重点是Numpy库的知识点和相关操作和matplotlib库的操作

完整代码查看码云

你可能感兴趣的:(python的random函数掷色子和为7的概率_案例(7):模拟掷骰子)