首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DM::Python 3中的OJ老虎机挑战

DM::Python 3中的OJ老虎机挑战
EN

Code Review用户
提问于 2019-01-17 17:19:44
回答 1查看 563关注 0票数 1

我为老虎机对DM的挑战::OJ编写了一个解决方案:

玛莎带着一罐硬币去赌场,目的是想变得富有。她轮流玩三台机器。她不知道这些机器是完全可以预测的。每出戏要花四分之一的钱。第一台机器每35次播放30节;第二台机器每100次播放一次支付60节;第三台每播放10次支付9节。输入规格你的程序应该作为输入,在玛莎的罐子中的25美分(将至少有一个和少于1000),以及每台机器自上次付款以来被播放的次数。输出规格你的程序应该输出玛莎播放的次数,直到她破产。样本输入48,3,10,4样本输出玛莎在破产前玩66次。

我想让它在2秒或更短的时间内运行。

代码语言:javascript
复制
money = int(input())
m1 = int(input())
m2 = int(input())
m3 = int(input())
turns = 0

while (money != 0): 
  #machine 1
  money -= 1
  m1 += 1
  if (m1 == 35): 
    money += 30
    m1 = 0
  turns += 1

  #machine 2
  money -= 1
  m2 += 1
  if (m2 == 100): 
    money += 60
    m2 = 0
  turns += 1

  #machine 3
  money -= 1
  m3 += 1
  if (m3 == 10): 
    money += 9
    m3 = 0
  turns += 1

print ('Martha plays {} times before going broke.'.format(turns))
EN

回答 1

Code Review用户

回答已采纳

发布于 2019-01-17 18:05:19

代码组织,关注点分离和测试

代码是一个单一的单块代码。重新组织一些事情可能是个好主意:让事情变得更清晰,更容易测试,更容易维护,等等。

第一个主要改进可能是编写一个具有明确输入(money、m1、m2、m3)的函数和一个清晰的输出,以解决我们关心的问题:计算循环数。处理输入/输出的逻辑与执行计算的逻辑分离- seel也是https://en.wikipedia.org/wiki/Separation_的_关切

然后,这个函数可以与用户的输入一起使用,但我们也可以为它提供硬编码的值。这可以用于编写测试,以确保该函数运行正常(至少在dmoj提供的示例中如此)。

(在下面提供的代码中,我有一个简单的assert语句来编写测试,但这可能是一个阅读单元测试框架并开始使用它们的好机会)。

然后,您可以轻松地添加任意数量的测试。

现在我们有了单元测试,以防止我们破坏太严重,我们可以开始调整代码。

最后,可以使用if __name__ == "__main__":将代码中的定义与实际使用这些定义的代码分开。它使您的代码更容易通过导入机制重用。

风格

Python有一个风格指南称为PEP 8。Python社区(或多或少严格地)遵循它。强烈建议阅读它,并在相关时尽量坚持下去。在您的例子中,您有多余的括号,缩进两个空格而不是4个多余的空白空间。

在现阶段,我们有:

代码语言:javascript
复制
def get_number_of_games(money, m1, m2, m3):
    """Return the number of games <to be continued>."""
    turns = 0
    while money != 0: 
        #machine 1
        money -= 1
        m1 += 1
        if m1 == 35: 
            money += 30
            m1 = 0
        turns += 1

        #machine 2
        money -= 1
        m2 += 1
        if m2 == 100: 
            money += 60
            m2 = 0
        turns += 1

        #machine 3
        money -= 1
        m3 += 1
        if m3 == 10: 
            money += 9
            m3 = 0
        turns += 1
    return turns

def interactive_main():
    money = int(input())
    m1 = int(input())
    m2 = int(input())
    m3 = int(input())
    print('Martha plays {} times before going broke.'.format(get_number_of_games(money, m1, m2, m3)))

def unit_test():
    """Run unit-tests."""
    assert get_number_of_games(48, 3, 10, 4) == 66
    print("OK")

if __name__ == "__main__":
    unit_test()

幻数

代码中充满了幻数幻数,这使得逻辑难以理解。我们可以用有意义的名称将这些值存储到常量中。

更好的是,我们可以将这些数据存储到适当的数据结构中。对于一个简单的解决方案,我们可以决定使用名称。

代码语言:javascript
复制
from collections import namedtuple

Machine = namedtuple('Machine', ['winning_freq', 'profit'])

MACHINE1 = Machine(35, 30)
MACHINE2 = Machine(100, 60)
MACHINE3 = Machine(10, 9)

def get_number_of_games(money, m1, m2, m3):
    """Return the number of games <to be continued>."""
    turns = 0
    while money != 0:
        money -= 1
        m1 += 1
        if m1 == MACHINE1.winning_freq:
            money += MACHINE1.profit
            m1 = 0
        turns += 1

        #machine 2
        money -= 1
        m2 += 1
        if m2 == MACHINE2.winning_freq:
            money += MACHINE2.profit
            m2 = 0
        turns += 1

        #machine 3
        money -= 1
        m3 += 1
        if m3 == MACHINE3.winning_freq:
            money += MACHINE3.profit
            m3 = 0
        turns += 1
    return turns

未处理的情况(也称为bug)

代码不太健壮。一些情况可能会导致它误入歧途。

让我们举一个简单的例子:我们有1/4,机器还没有被使用。这可以写成:

代码语言:javascript
复制
print(get_number_of_games(1, 0, 0, 0))

当我们运行这个,我们被困在一个无限循环中。我让你调查原因。

另一个例子--它可以被认为是无效的,但确实值得修复,因为它是如此简单:我们有很多钱,机器已经被大量使用了。例如,我们有:

代码语言:javascript
复制
print(get_number_of_games(1000, 36, 101, 11))

假设我们解决了前一个问题:我们玩了多少回合?我们赢了多少次?

当我们修复行为时,您可以添加相应的单元测试,以确保以后不会陷入相同的问题。

更进一步

代码依赖于重复的逻辑来处理不同的机器。一个更好的解决方案是通过同样的逻辑来处理它们。我们可以想象有一个机器列表。

此外,我们可以想象,在给定的机器上播放的旋转次数与Machine类中的其他信息一起存储。然后,get_number_of_games函数可以将一笔钱和一个定义正确的机器的列表作为输入。

带走了Python和非Python代码

  1. 使您的代码可测试
  2. 让您的代码进行测试和更正。
  3. 在保持属性1和2的同时改进它。
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/211709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档