动手试一试代码实现
(1)习题内容
15-1 立方:数字的三次方被称为立方。请绘制一个图形,显示前5个整数的立方值,再绘制一个图形,显示前5000个整数的立方值。
15-2 彩色立方:给你前面绘制的立方图指定颜色映射。
15-3 分子运动:修改rw_visual.py,将其中的plt.scatter()替换为plt.plot()。为模拟花粉在水滴表面的运动路径,向plt.plot()传递rw.x_values和rw.y_values,并指定实参值linewidth。使用5000个点而不是50000个点。
15-4 改进的随机漫步:在类RandomWalk中,x_step和y_step是根据相同的条件生成的:从列表[1,-1]中随机地选择方向,并从列表[0,1,2,3,4]中随机地选择距离。请修改这些列表中的值,看看对随机漫步路径有何影响。尝试使用更长的距离选择列表,如0~8;或者将-1从x或者y方向列表中删除。
15-5 重构:方法fill_walk()很长。请新建一个名为get_step()的方法,用于确定每次漫步的距离和方向,并计算这次漫步将如何移动。然后,在fill_walk()中调用get_step()两次:
x_step = self.get_step()
y_step = self.get_step()
通过这样的重构,可缩小fill_walk()的规模,让这个方法阅读和理解起来更容易。
15-6 自动生成标签:请修改die.py和dice_visual.py,将用来设置hist.x_labels值的列表替换为一个自动生成这种列表的循环。如果你熟悉列表解析,可尝试将die_visual.py和dice_visual.py中的的其他for循环也替换为列表解析。
15-7 两个D8骰子:请模拟同时掷两个8面骰子1000次的结果。逐渐增加掷骰子的同学,直到系统不堪重负为止。
15-8 同时掷三个骰子:如果你同时掷三个D6骰子,可能得到的最小点数为3,而最大点数为18。请通过可视化展示同时掷D6骰子的结果。
15-9 将点数相乘:同时掷两个骰子时,通常将它们的点数相加。请通过可视化展示将两个骰子的点数相乘的结果。
(2)代码实现
# coding=utf_8
#
# 15-1 立方
import matplotlib.pyplot as plt
# 绘制显示前5个整数的立方值
input_values=[1,2,3,4,5]
cube=[1,8,27,64,125]
plt.plot(input_values,cube,linewidth=5)
plt.title("Cube Numbers",fontsize=18)
plt.xlabel("Value",fontsize=16)
plt.ylabel("Cube of Value",fontsize=16)
plt.show()
# 绘制显示前5000个整数的立方值
x_values=list(range(1,5001))
y_values=[x**3 for x in x_values]
plt.scatter(x_values,y_values,edgecolor='none',s=40)
plt.title("Cube Numbers",fontsize=18)
plt.xlabel("Value",fontsize=16)
plt.ylabel("Cube of Value",fontsize=16)
plt.axis([0,5100,0,130000000000])
plt.show()
#
# 15-2 彩色立方
x_values=list(range(1,5001))
y_values=[x**3 for x in x_values]
plt.scatter(x_values,y_values,c=y_values,cmap=plt.cm.Reds,edgecolor='none',s=40)
plt.title("Cube Numbers",fontsize=18)
plt.xlabel("Value",fontsize=16)
plt.ylabel("Cube of Value",fontsize=16)
plt.axis([0,5100,0,130000000000])
plt.show()
#
# 15-3 分子运动
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,就不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,并将其包含的点都绘制出来
rw = RandomWalk()
rw.fill_walk()
# 调整窗口屏幕分辨率和尺寸
plt.figure(dpi=128,figsize=(10,6))
# 画连线图
plt.plot(rw.x_values,rw.y_values,linewidth=1)
# 突出起点和终点
plt.scatter(0,0,c='green',edgecolor='none',s=100)
plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',edgecolors='none',s=100)
# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
#
# 15-4 改进的随机漫步
# (1)尝试使用更长的距离选择列表
import matplotlib.pyplot as plt
from improve_random_walk_1 import Improve_RandomWalk_1
# 只要程序处于活动状态,就不断地模拟随机漫步
while True:
# 创建一个Improve_RandomWalk_1实例,并将其包含的点都绘制出来
rw = Improve_RandomWalk_1()
rw.fill_walk()
# 调整窗口屏幕分辨率和尺寸
plt.figure(dpi=128,figsize=(10,6))
# 使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓
point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values,rw.y_values,c=point_numbers,cmap=plt.cm.Blues,edgecolor='none',s=15)
# 突出起点和终点
plt.scatter(0,0,c='green',edgecolor='none',s=100)
plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',edgecolors='none',s=100)
# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
# (2)将-1从x轴方向列表中删除(y轴类似)
import matplotlib.pyplot as plt
from improve_random_walk_2 import Improve_RandomWalk_2
# 只要程序处于活动状态,就不断地模拟随机漫步
while True:
# 创建一个Improve_RandomWalk_1实例,并将其包含的点都绘制出来
rw = Improve_RandomWalk_1()
rw.fill_walk()
# 调整窗口屏幕分辨率和尺寸
plt.figure(dpi=128,figsize=(10,6))
# 使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓
point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values,rw.y_values,c=point_numbers,cmap=plt.cm.Blues,edgecolor='none',s=15)
# 突出起点和终点
plt.scatter(0,0,c='green',edgecolor='none',s=100)
plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',edgecolors='none',s=100)
# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
#
# 15-5 重构(refactoring)
import matplotlib.pyplot as plt
from refactoring_random_walk import Refactoring_RandomWalk
# 只要程序处于活动状态,就不断地模拟随机漫步
while True:
# 创建一个Improve_RandomWalk_1实例,并将其包含的点都绘制出来
rw = Refactoring_RandomWalk()
rw.fill_walk()
# 调整窗口屏幕分辨率和尺寸
plt.figure(dpi=128,figsize=(10,6))
# 使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓
point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values,rw.y_values,c=point_numbers,cmap=plt.cm.Blues,edgecolor='none',s=15)
# 突出起点和终点
plt.scatter(0,0,c='green',edgecolor='none',s=100)
plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',edgecolors='none',s=100)
# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
#
# 15-6 自动生成标签
# (1)将hist.x_labels值的列表替换为一个自动生成列表的循环
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=[]
for label_value in range(2,max_result+1):
hist.x_labels.append(str(label_value))
hist.x_title="Result"
hist.y_title="Frequency of Result"
hist.add('D6+D6',frequencies)
hist.render_to_file('dice_visual_1.svg')
# (2)使用列表解析自动生成列表
# 修改die_visual.py的所有for循环
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(label_value) for label_value 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_1.svg')
#
# 修改dice_visual.py的for循环
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(label_value) for label_value 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('dice_visual_2.svg')
#
# 15-7 两个D8骰子
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(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 D8 dice 1000 times."
hist.x_labels=[str(label_value) for label_value 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('dice_visual_3.svg')
#
# 15-8 同时掷三个骰子
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(1000)]
# 分析结果
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 1000 times."
hist.x_labels=[str(label_value) for label_value 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('dice_visual_4.svg')
#
# 15-9 将点数相乘
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(10000)]
# 分析结果
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 10000 times."
hist.x_labels=[str(label_value) for label_value 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('dice_visual_5.svg')
(3)模块
die模块
# coding=utf-8
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)