案例(7):模擬擲骰子

本章通過模擬擲骰子計算的5案例來進行學(xué)習(xí)基礎(chǔ)的Python程序

案例描述

通過計算機程序模擬拋擲骰子,并顯示各點數(shù)的出現(xiàn)次數(shù)及頻率
比如:拋擲2個骰子50次,出現(xiàn)點數(shù)為7的次數(shù)是8,頻率是0.16

模擬圖

案例分析

根據(jù)以下函數(shù)判斷密碼強度并輸出:
1.設(shè)置一個變量strength_level用于記錄密碼的強度,初始為0。滿足一個條件,對其加1;
2.長度判斷:使用len()方法;
3.包含數(shù)字判斷:對密碼字符串遍歷,使用isnumeric()方法;
4.包含字母判斷:對密碼字符串遍歷,使用isalpha()方法;
5.如果strength_level等于3,密碼強度合格,否則不合格

v1.0

新建一個簡單的Python程序,1.0功能:模擬拋擲1個骰子,并輸出其結(jié)果;通過Python的random模塊模擬隨機事件或者生成隨機數(shù);遍歷列表時,使用enumerate()函數(shù)同時獲取每個元素的索引號及其元素值。首先擲骰子編寫成一個函數(shù),然后編寫主函數(shù)設(shè)置參數(shù)并開始擲骰子,最后輸出結(jié)果。

知識點:

1.random模塊
(1)random模塊用于生成隨機數(shù),包含整數(shù),浮點數(shù),獲取列表中的隨機元素
(2)常用函數(shù),random庫里面有幾個常用的函數(shù),分別如下:


random常用函數(shù)

2.enumerate()函數(shù)
(1)enumerate()函數(shù)用于將可遍歷的組合轉(zhuǎn)換為一個索引序列
(2)一般用于for循環(huán)中,同時列出元素和元素的索引號
random模塊函數(shù)示例:



enumerate函數(shù)示例:


PS:更多random模塊的方法請參考:https://docs.python.org/3/library/random.html

扔骰子函數(shù),先引入ramdom庫,randint(1,6)返回的是1 - 6的整數(shù)賦值給dice_num,最后返回該結(jié)果:

import random

def roll_dice():
    """
        擲骰子
    """
    dice_num = random.randint(1, 6)
    return dice_num

主體代碼,里面先初始化主要的參數(shù)是total_time次數(shù)和result_list次數(shù)統(tǒng)計列表,for循環(huán)迭代range(total_times)對象,計算每次擲骰子的結(jié)果然后再for循環(huán)給統(tǒng)計列表計數(shù),若符合則+1,最后enumerate()會返回兩個參數(shù),第1個給i,第2個給result再進行for循環(huán)迭代,因為列表下標(biāo)是從0開始的,所以format的i需要+1正確顯示0:

    # 擲骰子次數(shù)
    total_times = 1000
    # 初始化結(jié)果列表[0,0,0,0,0,0]
    result_list = [0] * 6

    # 開始擲骰子
    for i in range(total_times):
        roll = roll_dice()
        # 給列表計數(shù)
        for j in range(1, 7):
            if roll == j:
                result_list[j - 1] += 1

    # 輸出結(jié)果
    for i, result in enumerate(result_list):
        print("計數(shù)為{}的骰子出現(xiàn)次數(shù){},頻率:{}".format(i + 1, result, result / total_times))

結(jié)果如圖所示:


1個骰子1000次結(jié)果統(tǒng)計

v2.0

在v1.0的基礎(chǔ)上,2.0功能:模擬拋擲2個骰子,并輸出其結(jié)果。由于要2個骰子,因此骰子的點數(shù)要新建列表,然后使用字典將對應(yīng)的點數(shù)和次數(shù)關(guān)聯(lián)起來。zip()函數(shù)的作用就是把骰子列表和統(tǒng)計列表組合成元組,然后用dict()轉(zhuǎn)換成字典。

知識點:

1.zip()函數(shù):
(1)zip()函數(shù)用于將對應(yīng)的元素打包成一個個元組
(2)注意:元組中的元素是不可修改的,若要修改元素值可轉(zhuǎn)換成字典類型;如:dict(zip(l1, l2))
(3)Python2.x版本和Python3版本的zip()函數(shù)返回結(jié)果不同,示例如下:


Python2
Python3示例

zip函數(shù)示例:


投擲子函數(shù)之前相同,不展示了。

具體代碼,首先新建結(jié)果列表,因為2個骰子的結(jié)果有11種,所以要[0]*11,而點數(shù)列表對應(yīng)也有11種,并且是2 - 12。dict(zip(roll_list, result_list))返回的結(jié)果是key為點數(shù),value為結(jié)果計數(shù)的字典:

    # 擲骰子次數(shù)
    total_times = 1000
    # 初始化結(jié)果列表[0,0,0,0,0,0]
    result_list = [0] * 11
    # 初始化點數(shù)列表
    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()
        # 給列表計數(shù)
        for j in range(2, 13):
            if (roll1 + roll2) == j:
                roll_dict[j] += 1

    # 輸出結(jié)果
    for i, result in roll_dict.items():
        print("計數(shù)為{}出現(xiàn)的次數(shù)為{},頻率:{}".format(i, result, result / total_times))

運行結(jié)果:

v3.0

在2.0的基礎(chǔ)上,3.0功能:可視化拋擲2個骰子的結(jié)果;通過繪制散點圖圖像,簡單分析數(shù)據(jù)的分布情況,使用到matploylib庫。

知識點:

1.Python數(shù)據(jù)可視化:matplotlib模塊
(1)matplotlib是一個數(shù)據(jù)可視化函數(shù)庫
(2)matplotlib的子模塊pyplot提供了2D圖表制作的基本函數(shù)
(3)例子:https://matplotlib.org/gallery.html
(4)散點圖繪制操作
import matplotlib.pyplot as plt
plt.scatter(x, y) # x, y分別是x坐標(biāo)和y坐標(biāo)的列表
plt.show()


2.scatter()參數(shù)詳解
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)

參數(shù)的解釋:
x,y:表示的是大小為(n,)的數(shù)組,也就是我們即將繪制散點圖的數(shù)據(jù)點
s:是一個實數(shù)或者是一個數(shù)組大小為(n,),這個是一個可選的參數(shù)。
c:表示的是顏色,也是一個可選項。默認是藍色'b',表示的是標(biāo)記的顏色,或者可以是一個表示顏色的字符,或者是一個長度為n的表示顏色的序列等等,感覺還沒用到過現(xiàn)在不解釋了。但是c不可以是一個單獨的RGB數(shù)字,也不可以是一個RGBA的序列??梢允撬麄兊?維數(shù)組(只有一行)。
marker:表示的是標(biāo)記的樣式,默認的是'o'。
cmap:Colormap實體或者是一個colormap的名字,cmap僅僅當(dāng)c是一個浮點數(shù)數(shù)組的時候才使用。如果沒有申明就是image.cmap
norm:Normalize實體來將數(shù)據(jù)亮度轉(zhuǎn)化到0-1之間,也是只有c是一個浮點數(shù)的數(shù)組的時候才使用。如果沒有申明,就是默認為colors.Normalize。
vmin,vmax:實數(shù),當(dāng)norm存在的時候忽略。用來進行亮度數(shù)據(jù)的歸一化。
alpha:實數(shù),0-1之間。

主要代碼,骰子的計數(shù)方式和之前相同,新增繪制散點圖。散點圖繪制要先import引入庫,在用scatter()設(shè)置骰子1和2的顯示方式,參數(shù)包含x軸坐標(biāo),y軸坐標(biāo),顏色和透明度,最后顯示:

    # 擲骰子次數(shù)
    total_times = 1000
    # 初始化結(jié)果列表[0,0,0,0,0,0]
    result_list = [0] * 11
    # 初始化點數(shù)列表
    roll_list = list(range(2, 13))
    roll_dict = dict(zip(roll_list, result_list))
    # 初始化骰子結(jié)果列表
    roll1_result = []
    roll2_result = []

    # 開始擲骰子
    for i in range(total_times):
        roll1 = roll_dice()
        roll2 = roll_dice()
        roll1_result.append(roll1)
        roll2_result.append(roll2)

        # 給列表計數(shù)
        for j in range(2, 13):
            if (roll1 + roll2) == j:
                roll_dict[j] += 1

    # 輸出結(jié)果
    for i, result in roll_dict.items():
        print("計數(shù)為{}出現(xiàn)的次數(shù)為{},頻率:{}".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()

代碼部分運行結(jié)果:


散點圖

v4.0

在v3.0的基礎(chǔ)上,4.0功能:對結(jié)果進行簡單的數(shù)據(jù)統(tǒng)計和分析。使用matplotlib直方圖做簡單的數(shù)據(jù)統(tǒng)計分析。直方圖可以直接看到分布情況,簡單易懂。在做數(shù)據(jù)分析或機器學(xué)習(xí)時會經(jīng)常用到。

知識點:

1.matplotlib直方圖
(1)直方圖是一種對數(shù)據(jù)分布情況的圖形表示
(2)首先要對數(shù)據(jù)進行分組,然后統(tǒng)計每個分組內(nèi)數(shù)據(jù)的數(shù)量。
(3)作用:
? 顯示各分組頻率或數(shù)量分布的情況
? 易于顯示各組之間頻率或數(shù)量的差別
(4)matplotlib繪制直方圖
plt.hist(data, bins)
data: 數(shù)據(jù)列表
bins: 分組邊界
2.hist()參數(shù)和返回值:
調(diào)用方式:
n, bins, patches = plt.hist(arr, bins=10, normed=0, facecolor='black', edgecolor='black',alpha=1,histtype='bar')

hist的參數(shù)非常多,但常用的就這六個,只有第一個是必須的,后面四個可選
arr: 需要計算直方圖的一維數(shù)組
bins: 直方圖的柱數(shù),可選項,默認為10
normed: 是否將得到的直方圖向量歸一化。默認為0
facecolor: 直方圖顏色
edgecolor: 直方圖邊框顏色
alpha: 透明度
histtype: 直方圖類型,‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’

返回值 :
n: 直方圖向量,是否歸一化由參數(shù)normed設(shè)定
bins: 返回各個bin的區(qū)間范圍
patches: 返回每個bin里面包含的數(shù)據(jù),是一個list

hist()函數(shù)參數(shù)詳解:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.hist.html
https://blog.csdn.net/qq_41940950/article/details/82937966
3.hist示例和中文顯示錯誤解決方法




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

主要代碼,骰子的計數(shù)方式和之前相同,新增繪制直方圖。直方圖繪制要先import引入庫,在用hist()設(shè)置直方圖的顯示形狀,參數(shù)包含x軸坐標(biāo),y軸坐標(biāo),歸一化即y軸數(shù)據(jù)修改為頻率,邊框顏色(間隔開方便觀察);title()設(shè)置直方圖標(biāo)題,xlabel()設(shè)置x軸標(biāo)題,ylabel設(shè)置y軸標(biāo)題,這3個都用size更改字體大小。最后顯示::

# 擲骰子次數(shù)
    total_times = 100000
    # 初始化結(jié)果列表[0,0,0,0,0,0]
    result_list = [0] * 11
    # 初始化點數(shù)列表
    roll_list = list(range(2, 13))
    roll_dict = dict(zip(roll_list, result_list))
    # 擲骰子結(jié)果初始化
    roll_list = []
    # 開始擲骰子
    for i in range(total_times):
        roll1 = roll_dice()
        roll2 = roll_dice()
        roll_list.append(roll1 + roll2)
        # 給列表計數(shù)
        for j in range(2, 13):
            if (roll1 + roll2) == j:
                roll_dict[j] += 1

    # 輸出結(jié)果
    for i, result in roll_dict.items():
        print("計數(shù)為{}出現(xiàn)的次數(shù)為{},頻率:{}".format(i, result, result / total_times))

    # 繪制散點圖
    plt.hist(roll_list, bins=range(2, 14), density=1, edgecolor="yellow", rwidth=3)  # normed=1
    plt.title("骰子點數(shù)統(tǒng)計",size=16)
    plt.xlabel("點數(shù)", size=10)
    plt.ylabel("頻率", size=10)
    plt.show()

執(zhí)行結(jié)果:


v5.0

在v4.0的基礎(chǔ)上,5.0功能:使用科學(xué)計算庫簡化程序,完善數(shù)據(jù)可視化結(jié)果。使用科學(xué)計算庫NumPy簡化程序。numpy可以直接生成大量的隨機數(shù)對象數(shù)組,不需要再每次生成1個再加入列表中了,除此之外numpy還包含其他處理多維數(shù)組的方法。

知識點:
  1. NumPy
    (1)NumPy (Numeric Python):用Python實現(xiàn)的科學(xué)計算庫
    (2)包括:
    a.強大的N維數(shù)組對象array
    b.成熟的科學(xué)函數(shù)庫
    c.實用的線性代數(shù)、隨機數(shù)生成函數(shù)等
    (3)NumPy的操作對象是多維數(shù)組ndarray
    (4)ndarray.shape 數(shù)組的維度;操作方法如下:
    創(chuàng)建數(shù)組:np.array(<list>),np.arrange() …
    改變數(shù)組形狀 reshape()
    2.histogram()詳解
    umpy.histogram(a, bins=10, range=None, normed=False, weights=None, density=None)

參數(shù):
a : array_like
輸入數(shù)據(jù)。直方圖在平頂陣列上計算。

bin : int或scalars或str的序列,可選
如果bin是int,則它定義給定范圍內(nèi)的等寬bin的數(shù)量(默認為10)。如果bin是一個序列,它定義了一個單調(diào)增加的bin邊緣數(shù)組,包括最右邊的邊,允許不均勻的bin寬度。

range :( float,float),可選
箱子的下部和上部范圍。如果沒有提供,范圍很簡單。超出范圍的值將被忽略。范圍的第一個元素必須小于或等于第二個元素。range也會影響自動bin計算。雖然基于范圍內(nèi)的實際數(shù)據(jù)計算箱寬度是最佳的,但箱計數(shù)將填充整個范圍,包括不包含數(shù)據(jù)的部分。(a.min(), a.max())

normed : bool,可選
從版本1.6.0開始不推薦使用。
這相當(dāng)于density參數(shù),但是對于不相等的bin寬度產(chǎn)生不正確的結(jié)果。不應(yīng)該使用它。

weights : array_like,可選
一系列重量,形狀與a相同。中的每個值 一個不僅有助于其相關(guān)聯(lián)的權(quán)重對所述的箱數(shù)(而不是1)。如果密度為True,則將權(quán)重歸一化,以使密度在整個范圍內(nèi)的積分保持為1。

density : bool,可選
如果False,結(jié)果將包含每個bin中的樣本數(shù)。如果True,結(jié)果是bin處的概率密度函數(shù)的值,則歸一化使得該范圍上的積分為1.注意,除非選擇單位寬度的區(qū)間,否則直方圖值的總和將不等于1; 它不是概率質(zhì)量函數(shù)。

返回值,有兩個,
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 參數(shù)與輸入?yún)?shù)的 bins 保持一致;

PS:numpy詳細教程參考:https://blog.csdn.net/a373595475/article/details/79580734
數(shù)組維度詳解:https://www.cnblogs.com/Allen-rg/p/9592590.html
np.arange()函數(shù)詳解:https://jingyan.baidu.com/article/e6c8503c1e89d6e54f1a188c.html
reshape()函數(shù)詳解:https://blog.csdn.net/qq_28618765/article/details/78083895
數(shù)組的使用:http://www.cnblogs.com/dwnblogs/archive/2012/07/15/2592714.html
histogram()詳解參考:https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html

主函數(shù)代碼,先導(dǎo)入numpy庫,調(diào)用里面的random.randint()直接生成含有大量隨機數(shù)的對象數(shù)組,方法函數(shù)包含起始數(shù),終結(jié)數(shù),數(shù)據(jù)數(shù)量;然后調(diào)用np.histogram統(tǒng)計結(jié)果,返回2-12點數(shù)的出現(xiàn)次數(shù)和對應(yīng)的區(qū)間;然后hist繪制直方圖,參數(shù)包含y軸數(shù)據(jù),x軸數(shù)據(jù),歸一化,邊框顏色,邊框?qū)挾龋綏l間隔;xticks()設(shè)置x軸坐標(biāo)點的顯示,參數(shù)包含顯示坐標(biāo)(這里+0.5居中顯示方便觀看)和坐標(biāo)點顯示的標(biāo)題;接著設(shè)置標(biāo)題,y和x的標(biāo)題,最后顯示。

    # 擲骰子次數(shù)
    total_times = 1000000

    # 使用array操作隨機數(shù)
    roll1_arr = np.random.randint(1, 7, size=total_times)
    roll2_arr = np.random.randint(1, 7, size=total_times)
    # 統(tǒng)計結(jié)果、
    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
    # 設(shè)置x軸坐標(biāo)點顯示
    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("骰子點數(shù)統(tǒng)計", size=16)
    plt.xlabel("點數(shù)", size=10)
    plt.ylabel("頻率", size=10)
    plt.show()

執(zhí)行結(jié)果:


總結(jié)

模擬擲骰子的5個例子,知識點歸納如下:


重點是Numpy庫的知識點和相關(guān)操作和matplotlib庫的操作
完整代碼查看碼云

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Python語言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個如下例子,分析運行結(jié)果: 代碼一: a = 1 def...
    時光清淺03閱讀 572評論 0 0
  • 寫在前面的話 代碼中的# > 表示的是輸出結(jié)果 輸入 使用input()函數(shù) 用法 注意input函數(shù)輸出的均是字...
    FlyingLittlePG閱讀 3,237評論 0 9
  • 自己找的路,一路上陽光鮮花雨露,風(fēng)霜雨雪坎坷,經(jīng)歷過,才知道什么是路,什么是絕境,過程也是一條成熟的路,每個人都是...
    藍云飛雪閱讀 179評論 0 0
  • 小時候 獨生子女一代總是被關(guān)在家里,可能雙魚座如水浪漫主義的性格,一個人可以想象童話中的城堡?;孟胫约旱睦寺」?..
    小魚芳芳閱讀 2,216評論 8 38
  • 你發(fā)現(xiàn)了嗎 所有的作品 并不是 一開始就很好的 比如歌要聽很多遍 比如詩要讀很多遍 比如畫要不斷不斷 盯著看很久很...
    天野丟閱讀 224評論 4 3

友情鏈接更多精彩內(nèi)容