欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Python编程:从入门到实践】第十五章练习题

程序员文章站 2024-03-11 20:22:49
...

15-10  练习使用本章介绍的两个库 :尝试使用 matplotlib 通过可视化来模拟掷骰子的情况,并尝试使用 Pygal 通过可视化来模拟随机漫步的情况。

使用 matplotlib 通过可视化来模拟掷骰子的情况,效果如下图:

【Python编程:从入门到实践】第十五章练习题

代码:

die.py(表示一个骰子的类)。

默认6个面(num_sides=6),可任意修改这个数字;方法roll用来生成一个任意数。

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_mpl.py(生成图表)。

函数“autolabel”用来生成柱形上面的数字,plt.text前两个为数字的坐标,第三个为要显示的数字值(字符串)。

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from die import Die

# 显示柱形上面的数字
def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() / 2 - 0.2, height + 1, '%s' % int(height))

# 创建一个D6和D10
die6 = Die()
die10 = Die(10)

# 掷几次骰子,并将结果存储在一个列表中
results = []
for roll_num in range(1000):
	result = die6.roll() + die10.roll()
	results.append(result)
# 获取骰子数的循环数
num_sides = die6.num_sides + die10.num_sides
name_list = range(2, num_sides + 1)
# 分析结果
frequencies = []
for value in name_list:
	frequency = results.count(value)
	frequencies.append(frequency)
	# print(frequency)

# 标题
plt.title('Die Mpl', pad=10.0, fontsize=24)
# 图例
plt.legend(handles=[mpatches.Patch(color='#d93d0b', label='D6+D10')])
autolabel(plt.bar(range(len(frequencies)), frequencies, color='#d93d0b', tick_label=name_list))
# plt.bar(range(len(frequencies)), frequencies, tick_label=name_list)
plt.show()

使用 Pygal 通过可视化来模拟随机漫步的情况,效果如下图:

【Python编程:从入门到实践】第十五章练习题

代码:

random_walk.py(生成随机的x, y点)

from random import choice

class RandomWalk():
	""" 一个生成随机漫步数据的类 """
	def __init__(self, num_points=5000):
		""" 初始化随机漫步的属性 """
		self.num_points = num_points
		#  所有随机漫步都始于 (0, 0)
		self.x_values = [0]
		self.y_values = [0]

	def fill_walk(self):
		""" 计算随机漫步包含的所有点 """
		#  不断漫步,直到列表达到指定的长度
		while len(self.x_values) < self.num_points:
			x_step = self.get_step()
			y_step = self.get_step()
			#  拒绝原地踏步
			if x_step == 0 and y_step == 0:
				continue
			#  计算下一个点的 x 和 y 值
			next_x = self.x_values[-1] + x_step
			next_y = self.y_values[-1] + y_step
			self.x_values.append(next_x)
			self.y_values.append(next_y)
	def get_step(self):
		"""决定前进方向以及沿这个方向前进的距离"""
		direction = choice([1, -1])
		distance = choice([0, 1, 2, 3, 4])
		step = direction * distance
		return step

rw_visual_pygal.py(生成svg文件)。

利用for (x, y) in zip(rw.x_values, rw.y_values)生成元组列表。

import pygal
from random_walk import RandomWalk

#  创建一个 RandomWalk 实例,并将其包含的点都绘制出来
rw = RandomWalk()
rw.fill_walk()

# 生成坐标列表
coordinate = []
for (x, y) in zip(rw.x_values, rw.y_values):
	coordinate.append((x, y))

xy_chart = pygal.XY(stroke=False)
xy_chart.title = 'RandomWalk'
xy_chart.add('RandomWalk', coordinate)
xy_chart.render()
# 生成svg文件
xy_chart.render_to_file('file/RandomWalk_pygal.svg')