Python:使用Pygal模拟掷骰子&练习题

来源:《Python编程:从入门到实践》

文章目录

  • 1
    • 1.1 安装Pygal
    • 1.2 Pygal画廊
    • 1.3 创建Die类
    • 1.4 掷骰子
    • 1.5 分析结果
    • 1.6 绘制直方图
    • 1.7 同时掷两个骰子
    • 1.8 同时掷两个面数不同的骰子
  • 2 练习

1

  • 这部分,将使用Python可视化包Pygal来生成可缩放的矢量图形文件
  • 在这个项目中,将对掷骰子的结果进行分析。掷6面的常规骰子时,出现1~6点的可能性相同。然后,如果同时掷两个骰子,某些点数出现的可能性将比其他点数大。为确定哪些点数出现的可能性最大,我们将生成一个表示掷骰子结果的数据集,并根据结果绘制出一个图形
  • 在数学领域,常利用掷骰子来解释各种数据分析,但它在赌场和其他博弈场景中也得到了实践应用,在游戏《大富翁》以及众多角色扮演游戏中亦如此

1.1 安装Pygal

  • 使用pip安装Pygal
  • Linux和OS X系统,命令类似于:
pip install --user pygal==1.7
  • Windows系统
python -m pip install --user pygal==1.7

1.2 Pygal画廊

  • 想了解Pygal可创建什么样的图表,请查看图表类型画廊:http://www.pygal.org,Document ->> Chart types
  • 每个实例都包含源代码

1.3 创建Die类

  • 下面的类模拟掷一个骰子

die.py

from random import randint

class Die():
    """表示一个骰子的类"""
    
    def __init__(self, num_sides=6):
        """骰子默认为6面"""
        self.num_sides = num_sides
        
    def roll(self):
        """返回一个位于1和骰子面数之间的随机值"""
        return randint(1, self.num_sides)
  • 创建Die实例时,如果没有指定任何实参,面数默认为6
  • 方法roll()使用函数randint()来返回一个1~面数的随机值

1.4 掷骰子

  • 创建图表前,先来掷D6骰子,打印结果看是否合理

die_visual.py

from die import Die

# 创建一个D6
die = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(100):
    result = die.roll()
    results.append(result)
    
print(results)
  • 掷100次的结果存储到results列表
    Python:使用Pygal模拟掷骰子&练习题_第1张图片

1.5 分析结果

  • 分析掷D6骰子的结果,计算每个点数出现的次数

die_visual.py

--snip--
# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000):
    result = die.roll()
    results.append(result)
    
# 分析结果
frequencies = []
for value in range(1, die.num_sides+1):
    frequency = results.count(value)
    frequencies.append(frequency)
    
print(frequencies)
  • 输出可以看到,没有任何点数出现的频率比其他点数高很多
    Python:使用Pygal模拟掷骰子&练习题_第2张图片

1.6 绘制直方图

  • 直方图是一种条形图,指出了各种结果出现的频率

die_visual.py

import pygal
--snip--

# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling one D6 1000 times."
hist.x_labels = ['1', '2', '3', '4', '5', '6']
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6', frequencies)
hist.render_to_file('die_visual.svg')
  • 创建条形图——创建了一个pygal.Bar()实例,并将其存储在hist中
  • 将这个图表渲染为一个SVG文件,扩展名必须为.svg
  • 要查看生成的直方图,最简单的方式是使用Web浏览器
  • 为此,在任何Web浏览器中新建一个标签页,再在其中打开文件die_visual.svg
    Python:使用Pygal模拟掷骰子&练习题_第3张图片
  • 注意: Pygal让这个图表具有交互性:如果将鼠标指向该图表中的任何条形,将看到与之相关联的数据

1.7 同时掷两个骰子

  • 掷两个骰子时,得到的点数更多,结果分布也不同

dice_visual.py

import pygal
from die import Die

# 创建两个D6骰子
die_1 = Die()
die_2 = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000):
    result = die_1.roll() + die_2.roll()
    results.append(result)
    
# 分析结果
frequencies = []
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result+1):
    frequency = results.count(value)
    frequencies.append(frequency)
    
# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling two D6 dice 1000 times."
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6 + D6', frequencies)
hist.render_to_file('die_visual.svg')

Python:使用Pygal模拟掷骰子&练习题_第4张图片

1.8 同时掷两个面数不同的骰子

  • 掷一个6面和一个10面的,同时掷50000次

different_dice.py

import pygal
from die import Die

# 创建一个D6 & 一个D10
die_1 = Die()
die_2 = Die(10)

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(50000):
    result = die_1.roll() + die_2.roll()
    results.append(result)
    
# 分析结果
frequencies = []
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result+1):
    frequency = results.count(value)
    frequencies.append(frequency)
    
# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling a D6 and a D10 50,000 times."
hist.x_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12',
    '13', '14', '15', '16']
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6 + D10', frequencies)
hist.render_to_file('die_visual.svg')

Python:使用Pygal模拟掷骰子&练习题_第5张图片

  • 通过使用Pygal来模拟掷骰子的结果,能够非常自由地探索这种现象

2 练习

  1. 自动生成标签: 请修改die_visual.py和dice_visual.py,将用来设置hist.x_labels值的列表替换为一个自动生成这种列表的循环。如果你熟悉列表解析,可尝试将die_visua.py和dice_visual.py中的其他for循环也替换为列表解析

Solution:

die_visual.py

import pygal
from die import Die

# 创建一个D6
die = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = [die.roll() for roll_num in range(1000)]

# 分析结果
frequencies = [results.count(value) for value in range(1, die.num_sides+1)]
    
# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling one D6 1000 times."
hist.x_labels = [str(x) for x in range(1, die.num_sides+1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6', frequencies)
hist.render_to_file('die_visual.svg')

dice_visual.py

import pygal
from die import Die

# 创建两个D6骰子
die_1 = Die()
die_2 = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = [die_1.roll() + die_2.roll() for roll_num in range(1000)]

# 分析结果
max_result = die_1.num_sides + die_2.num_sides
frequencies = [results.count(value) for value in range(2, max_result+1)]
    
# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling two D6 dice 1000 times."
hist.x_labels = [str(x) for x in range(2, max_result+1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6 + D6', frequencies)
hist.render_to_file('die_visual.svg')
  1. 两个D8骰子: 请模拟同时掷两个8面骰子1000次的结果。逐渐增加掷骰子的次数,直到系统不堪重负为止

Solution:

import pygal
from die import Die

# 创建两个D8骰子
die_1 = Die(8)
die_2 = Die(8)

# 掷几次骰子,并将结果存储在一个列表中
results = [die_1.roll() + die_2.roll() for roll_num in range(50000)]

# 分析结果
max_result = die_1.num_sides + die_2.num_sides
frequencies = [results.count(value) for value in range(2, max_result+1)]
    
# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling two D8 dice 50,000 times."
hist.x_labels = [str(x) for x in range(2, max_result+1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D8 + D8', frequencies)
hist.render_to_file('die_visual.svg')

Output:
Python:使用Pygal模拟掷骰子&练习题_第6张图片

  1. 同时掷三个骰子: 如果你同时掷三个D6骰子,可能得到的最小点数为3,而最大点数为18.请通过可视化展示同时掷三个D6骰子的结果

Solution:

import pygal
from die import Die

# 创建三个D6骰子
die_1 = Die()
die_2 = Die()
die_3 = Die()

# 掷几次骰子,并将结果存储在一个列表中
results = [die_1.roll() + die_2.roll() + die_3.roll() 
    for roll_num in range(50000)]

# 分析结果
max_result = die_1.num_sides + die_2.num_sides + die_3.num_sides
frequencies = [results.count(value) for value in range(3, max_result+1)]
    
# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling three D6 dice 50,000 times."
hist.x_labels = [str(x) for x in range(3, max_result+1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6 + D6 + D6', frequencies)
hist.render_to_file('die_visual.svg')

Output:
Python:使用Pygal模拟掷骰子&练习题_第7张图片

  1. 将点数相乘: 同时掷两个骰子时,通常将它们的点数相加。请通过可视化展示将两个骰子的点数相乘的结果

Solution:

import pygal
from die import Die

die_1 = Die()
die_2 = Die()

results = [die_1.roll() * die_2.roll() for roll_num in range(50000)]

# 分析结果
max_result = die_1.num_sides * die_2.num_sides
frequencies = [results.count(value) for value in range(1, max_result+1)]

# 对结果进行可视化
hist = pygal.Bar()

hist.title = "Results of rolling two D6 dice 50,000 times."
hist.x_labels = [str(x) for x in range(1, max_result+1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"

hist.add('D6 * D6', frequencies)
hist.render_to_file('die_visual.svg')

Output:
Python:使用Pygal模拟掷骰子&练习题_第8张图片

你可能感兴趣的:(Python学习,Python)