首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类fizzbuzz():

类fizzbuzz():
EN

Code Review用户
提问于 2016-10-04 14:14:24
回答 3查看 3K关注 0票数 15

这现在是一次反复的回顾。下一个迭代可以找到这里

是啊。Python中的Fizzbuzz。

我用Python编写了90分钟的代码。

有什么想法?

程序流

start_numend_num作为用户输入

请求除数/值对,直到用户输入非y的响应为止

在指定的范围内进行迭代,并按适当的输入顺序追加文本。

FizzBuzz.py

代码语言:javascript
运行
复制
class divisor_text_pair():

    def __init__(self,divisor,text):
        self.divisor=divisor
        self.text=text

class fizzbuzz():

    start_num = int(input('Start Number? '))
    end_num =int(input('End Number? '))

    pair_list = []

    response = 'y'
    while response == 'y':

        divisor = int(input('Divisor? '))
        text = input('Text? ')
        pair = divisor_text_pair(divisor, text)
        pair_list.append(pair)
        response = input('Input Another Divisor (y/n)? ')

    def print_numbers_and_texts(start_num, end_num, pair_list):

        for num in range(start_num, end_num + 1):

            out_text = str(num)

            for pair in pair_list:

                if num % pair.divisor == 0:
                    out_text += ' '
                    out_text += pair.text

            print(out_text)

    print_numbers_and_texts(start_num, end_num, pair_list)

fizzbuzz()

示例输入/输出:

代码语言:javascript
运行
复制
Start Number? 1
End Number? 10
Divisor? 2
Text? Fizz
Input Another Divisor (y/n)? y
Divisor? 3
Text? Buzz
Input Another Divisor (y/n)? n
1
2 Fizz
3 Buzz
4 Fizz
5
6 Fizz Buzz
7
8 Fizz
9 Buzz
10 Fizz
EN

回答 3

Code Review用户

回答已采纳

发布于 2016-10-04 14:28:20

您不需要类

您拥有的唯一方法是静态(它不以self作为参数),因此不需要类。

由于元组解压缩,Pair类也是不必要的。

请避免过于复杂的Fizz-Buzz。

输入处理在一个单独的函数

而不是一流的进入课堂。

终解

代码语言:javascript
运行
复制
def print_numbers_and_texts(start_num, end_num, pair_list):
    for num in range(start_num, end_num + 1):
        print(num, end='')
        for divisor, text in pair_list:
            if num % divisor == 0:
                print(' ' + text)

def ask_pairs():
    while True:
        yield (int(input("Divisor? ")), input("Text? "))
        if input('Input Another Divisor (y/n)?') == 'n':
            break

print_numbers_and_texts(
    int(input('Start Number? ')),
    int(input('End Number? ')),
    list(ask_pairs())
)
票数 16
EN

Code Review用户

发布于 2016-10-04 14:32:37

除了什么Caridorc在他的回答中说

一些与PEP8相关的建议是,在编写python代码时遵循这些建议是很好的:

  • 类名应遵循CamelCase约定
  • 在操作符周围有一个空格是可以的
  • ,之后,还应该有一个空格
  • 类/方法之间应该有两行,而不是只有一行。

使用if __name__ == '__main__'

这样做的原因之一是,有时您编写一个模块(一个.py文件),它可以直接执行。或者,它也可以导入并在另一个模块中使用。通过执行主检查,您可以让该代码只在您希望将模块作为程序运行时执行,而不是让它在某人只想导入您的模块并自己调用您的函数时执行。

此外,我同意上面的答案,即在这个程序中使用类并没有带来任何好处。只是头疼而已。不要试图通过用类编写小程序来使小程序过于复杂。有一个很棒的线程,叫做:面向对象编程是一场代价高昂的灾难,必须结束。

虽然我不同意里面写的所有东西,但是你应该读它,因为它包含了一些有用的信息。

使用Caridorc的提议,我想补充如下:

代码语言:javascript
运行
复制
def print_numbers_and_texts(start_num, end_num, pair_list):
    for num in range(start_num, end_num + 1):
        print num
        for divisor, text in pair_list:
            if num % divisor == 0:
                print ' ' + text


def ask_pairs():
    while True:
        yield (int(input("Divisor? ")), input("Text? "))
        if input('Input Another Divisor (y/n)?') == 'n':
            break


def main():
    print_numbers_and_texts(
        int(input('Start Number? ')),
        int(input('End Number? ')),
        list(ask_pairs())
    )

if __name__ == '__main__':
    main()
票数 10
EN

Code Review用户

发布于 2016-10-05 07:37:55

处理无效输入

我发现您处理某些用户输入的方式有问题:

开始号码?hello (最近一次调用):文件"python",第7行,在文件“python”中,第9行,在fizzbuzz ValueError中:

这是此转换为int的结果,而无需检查它实际上是否可以转换为int

int(输入(‘开始编号?’)#和其他喜欢它的人

您可以使用while循环和try...except继续请求输入,直到它可用为止:

代码语言:javascript
运行
复制
input_is_valid = False
while not input_is_valid:
    start_num = input('Start Number? ')
    end_num =input('End Number? ')
    try:
        start_num = int(start_num)
        end_num = int(end_num)
        input_is_valid = True
    except ValueError:
        print('Invalid number input for start "{0}" or end "{1}".'.format(start_num, end_num))

如果情况并非如此,也值得考虑添加另一个检查,以确保开始号小于结束号,以防止令人困惑的行为。

另一个与用户输入有关的问题是:

同时响应== 'y':

尽管规模很小,但它认为大写Y不是肯定的。当然,简单的修复:

代码语言:javascript
运行
复制
while response.lower() == 'y':

您的class divisor_text_pair() (顺便说一句,Python中的类名应该遵循TitleCase)除了保存两个值之外没有任何功能。相反,使用本机namedtuple类型将简化代码,同时仍然允许您使用点表示法x.divisorx.text检索值:

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

DivisorTextPair = namedtuple('DivisorTextPair', 'divisor text')

class FizzBuzz(): #...

使用namedtuple的语法类似于类的语法:

代码语言:javascript
运行
复制
pair = DivisorTextPair(divisor, text)

类逼近

虽然您的class fizzbuzz()方法可以而且已经受到了批评,但我想从实际使用类方法的角度来处理它,但方法要更好。

您的主类实际上更像是一个过程,因为它没有构造函数,而且很多逻辑都直接在类的主体中,而不是在方法中。

P.S.:请注意,我将在方法/函数签名中使用Python3.5 类型提示,我建议使用该签名。

在我的类重构(repl.it上的可运行演示)中,第一部分是构造函数,以及一旦调用__init__之后会发生什么:

代码语言:javascript
运行
复制
class FizzBuzz():
    def __init__(self):
        self.start_fizzbuzz()

以及控制一般流程的方法:

代码语言:javascript
运行
复制
    def start_fizzbuzz(self) -> None:
        """Controls the overall logic of a FizzBuzz program."""
        start_num, end_num = self.get_start_end_numbers()
        pair_list = self.get_divisor_text_pairs()
        self.print_numbers_and_texts(start_num, end_num, pair_list)

注意可拆装 (通常称为“元组解压”)在start_num, end_num = self.get_start_end_numbers()中的使用(该方法将返回一个tuple,继续读)。在不使用元组解压缩的情况下,用“长”的方式编写相同的东西应该是这样的:

代码语言:javascript
运行
复制
start_end_nums = self.get_start_end_numbers()
start_num = start_end_nums[0]
end_num = start_end_nums[1]

从这里,我们从一个方法获得开始和结束的数字,在这个方法中,我将用户输入逻辑移到:

代码语言:javascript
运行
复制
def get_start_end_numbers(self) -> tuple:
    input_is_valid = False
    while not input_is_valid:
        start_num = input('Start Number? ')
        end_num =input('End Number? ')
        try:
            start_num = int(start_num)
            end_num = int(end_num)
            input_is_valid = True
        except ValueError:
            print('Invalid number input for start "{0}" or end "{1}".'.format(start_num, end_num))
    return start_num, end_num

get_divisor_text_pairs()方法是您所期望的,上面应用了:

代码语言:javascript
运行
复制
def get_divisor_text_pairs(self) -> list:
    pair_list = []
    response = 'y'
    while response.lower() == 'y':
        input_is_valid = False
        while not input_is_valid:
            divisor = input('Divisor? ')
            try:
                divisor = int(divisor)
                input_is_valid = True
            except ValueError:
                print('"{0}" is not a valid number.'.format(divisor))
        text = input('Text? ')
        pair = DivisorTextPair(divisor, text)
        pair_list.append(pair)
        response = input('Input Another Divisor (y/n)? ')
    return pair_list

print_numbers_and_texts()方法基本上没有变化(除了签名中的类型提示)

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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