这现在是一次反复的回顾。下一个迭代可以找到这里。
是啊。Python中的Fizzbuzz。
我用Python编写了90分钟的代码。
有什么想法?
以start_num和end_num作为用户输入
请求除数/值对,直到用户输入非y的响应为止
在指定的范围内进行迭代,并按适当的输入顺序追加文本。
FizzBuzz.pyclass 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()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发布于 2016-10-04 14:28:20
您拥有的唯一方法是静态(它不以self作为参数),因此不需要类。
由于元组解压缩,Pair类也是不必要的。
请避免过于复杂的Fizz-Buzz。
中
而不是一流的进入课堂。
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())
)发布于 2016-10-04 14:32:37
除了什么Caridorc在他的回答中说:
一些与PEP8相关的建议是,在编写python代码时遵循这些建议是很好的:
,之后,还应该有一个空格使用if __name__ == '__main__':
这样做的原因之一是,有时您编写一个模块(一个.py文件),它可以直接执行。或者,它也可以导入并在另一个模块中使用。通过执行主检查,您可以让该代码只在您希望将模块作为程序运行时执行,而不是让它在某人只想导入您的模块并自己调用您的函数时执行。
此外,我同意上面的答案,即在这个程序中使用类并没有带来任何好处。只是头疼而已。不要试图通过用类编写小程序来使小程序过于复杂。有一个很棒的线程,叫做:面向对象编程是一场代价高昂的灾难,必须结束。。
虽然我不同意里面写的所有东西,但是你应该读它,因为它包含了一些有用的信息。
使用Caridorc的提议,我想补充如下:
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()发布于 2016-10-05 07:37:55
我发现您处理某些用户输入的方式有问题:
开始号码?hello (最近一次调用):文件"python",第7行,在文件“python”中,第9行,在fizzbuzz ValueError中:
这是此转换为int的结果,而无需检查它实际上是否可以转换为int:
int(输入(‘开始编号?’)#和其他喜欢它的人
您可以使用while循环和try...except继续请求输入,直到它可用为止:
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不是肯定的。当然,简单的修复:
while response.lower() == 'y':您的class divisor_text_pair() (顺便说一句,Python中的类名应该遵循TitleCase)除了保存两个值之外没有任何功能。相反,使用本机namedtuple类型将简化代码,同时仍然允许您使用点表示法x.divisor和x.text检索值:
from collections import namedtuple
DivisorTextPair = namedtuple('DivisorTextPair', 'divisor text')
class FizzBuzz(): #...使用namedtuple的语法类似于类的语法:
pair = DivisorTextPair(divisor, text)虽然您的class fizzbuzz()方法可以而且已经受到了批评,但我想从实际使用类方法的角度来处理它,但方法要更好。
您的主类实际上更像是一个过程,因为它没有构造函数,而且很多逻辑都直接在类的主体中,而不是在方法中。
P.S.:请注意,我将在方法/函数签名中使用Python3.5 类型提示,我建议使用该签名。
在我的类重构(repl.it上的可运行演示)中,第一部分是构造函数,以及一旦调用__init__之后会发生什么:
class FizzBuzz():
def __init__(self):
self.start_fizzbuzz()以及控制一般流程的方法:
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,继续读)。在不使用元组解压缩的情况下,用“长”的方式编写相同的东西应该是这样的:
start_end_nums = self.get_start_end_numbers()
start_num = start_end_nums[0]
end_num = start_end_nums[1]从这里,我们从一个方法获得开始和结束的数字,在这个方法中,我将用户输入逻辑移到:
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_numget_divisor_text_pairs()方法是您所期望的,上面应用了:
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_listprint_numbers_and_texts()方法基本上没有变化(除了签名中的类型提示)
https://codereview.stackexchange.com/questions/143207
复制相似问题