python - 骰子直方图 - OOP(作业)
问题描述
我是 Python 的初学者,过去几天我一直在尝试解决一个练习,但没有成功。这是老师让我们做的一个面向对象的编程练习。
这是提供的主要练习和代码:
锻炼:
在本作业中,您将编写一个程序来构建掷骰子的直方图。询问用户要进行多少轮(掷两个骰子)。该程序应该模拟许多随机回合,并输出一个直方图,计算两个骰子的总数为 2、3、4 ... 最多 12 的次数。这是一个典型的运行:
你想打几轮?(或 Enter 退出):1000000
1000000 轮后:2:计数为 28012 或 2 %
3:计数为 55665 或 5 %
4:计数为 83513 或 8 %
5:计数为 110874 或 11 %
6:计数为 138351 或 13 %
7:计数为 166296 或 16 %
8:计数为 139313 或 13 %
9:计数为 110814 或 11 %
10:计数为 83521 或 8 %
11:计数为 55792 或 5 %
12:计数为 27849 或 2 %
这个想法是采用三层方法:
1) 主代码创建一个“游戏”对象。然后主代码循环运行,询问用户要进行多少轮,然后告诉 Game 对象“运行”模拟。
2) Game 对象的初始化应该创建 13 个“Bin”对象 - 一个表示每个可能的总数(即使不可能用两个骰子得到 0 或 1。)并将这些对象存储在 Bin 对象列表中。然后当主代码告诉 Game 对象运行时,Game 对象应该重置 Bin 对象并执行给定数量的模拟滚动。每次滚动时,它应该告诉相应的 bin 增加自身。最后,它应该打印一个标题,然后告诉每个 Bin 对象显示它的报告。
3) 每个 Bin 对象都应该使用它的 bin 编号进行初始化,并保持一个计数,即滚动总计 Bin 所代表的数量的次数。Bin 对象应具有以下方法:
__init__
- 将在 bin 标识符中传递(0 到 12 之间的数字)
reset
- 将通过要完成的总卷数
increment
- 没有要传入的值
show
- 没有要传入的值。模拟结束时调用。仅当 bin 标识符为 2 或更多时才应打印。它应该计算百分比并打印 bin 标识符、计数和百分比。
所以,老师提供的初始文件是:
初始代码(空白):
import random
class Bin():
def __init__(self, binIdentifier):
pass
def reset(self, nRoundsToDo):
pass
def increment(self):
pass
def show(self):
pass
class GameMgr():
def __init__(self):
pass
def run(self, nRounds):
pass
oGameMgr = GameMgr()
while True:
maxRounds = input('How many rounds do you want to do? (or Enter to exit): ')
if maxRounds == '':
break
maxRounds = int(maxRounds)
oGameMgr.run(maxRounds)
print('OK bye')
这是我到目前为止所取得的成就:
# Dice - count totals in user-defined number of rounds
import random
class Bin():
def __init__(self, binIdentifier):
self.binIdentifier = binIdentifier
binIdentifier = 0
self.number_of_rounds = 0
def reset(self, nRoundsToDo):
self.nRoundsToDo = nRoundsToDo
nRoundsToDo = 0
self.bin_count = 0
def increment(self):
self.bin_count = self.bin_count + 1
def show(self):
print(bin_count)
self.bin_chances = self.bin_count/self.number_of_rounds
print(bin_chances)
class GameMgr():
def __init__(self):
self.bins_list = [ ]
for i in range(0,13):
self.bins_list.append(Bin(i))
def run(self, nRounds):
self.nRounds = nRounds
dice1 = random.randint(1,6)
dice2 = random.randint(1,6)
for i in self.bins_list:
i.reset(self.nRoundsToDo)
for o in self.bins_list:
bin_roll = dice1 + dice2
self.bins_list[bin_roll].increment()
oGameMgr = GameMgr()
while True:
maxRounds = input('How many rounds do you want to do? (or Enter to exit): ')
if maxRounds == '':
break
maxRounds = int(maxRounds)
oGameMgr.run(maxRounds)
print('OK bye')
解决方案
您正在为变量名混合 camelCase 和 snake_case(您的类名很好)。选择一种命名约定并坚持下去。
在你Bin
的__init__
方法中,你有:
class Bin():
def __init__(self, binIdentifier):
self.binIdentifier = binIdentifier
binIdentifier = 0
self.number_of_rounds = 0
不需要将 binIdentifier 设置为零,因为这基本上没有任何作用。
在你Bin
的reset
方法中,你有:
def reset(self, nRoundsToDo):
self.nRoundsToDo = nRoundsToDo
nRoundsToDo = 0
self.bin_count = 0
同样,您不需要将参数 (nRoundsToDo) 设置为零。根据此方法,您的类有一个名为 的实例变量nRoundsToDo
,但根据您的__init__
方法,您的类也有一个名为 的实例变量number_of_rounds
。在我看来,这两个应该代表相同的数量。选择一个并坚持下去(我个人number_of_rounds
更喜欢)。此外,也许更关键的是,一个 Bin 对象不应该真正关心有多少轮。关心轮数的是 GameMgr(游戏管理器)类。我会给 GameMgr 类这个实例变量。
编辑* 看来 Bin 类确实需要知道轮数(在 show 方法中,计算百分比)。
此外,你会希望你Bin
的 's最初__init__
设置bin_count
为零。
最后,你GameMgr
的run
方法需要以某种方式使用轮数。您必须创建一个循环来滚动两个骰子 n 次(其中 n 是轮数)。
推荐阅读
- javascript - 如何在触发下一个事件之前让可观察对象等待
- javascript - 创建一个名为 toQueryString 的函数
- c - 获取C中二维数组中的元素数
- javascript - Socket.io如何实现一个wss连接?
- translation - Microsoft 翻译服务的身份验证错误
- ios - SwiftUI 无法关闭呈现的第二张工作表
- python - python如何将代码更改为递归函数
- docker-compose - 如何在 Docker compose yaml 中定义事件中心?
- linux - 错误无法连接到zsys守护进程:连接错误:desc =“传输:拨号时出错拨号unix /run/zsysd.sock:
- sql - 更新列表中的多个条件