用四种方法进行文字游戏



我有以下问题和两个非常重要的问题。 编写一个名为文字游戏的类。它应该有一个包含单词列表的字段。用户 的类应将他们要使用的单词列表传递给类。应该有 以下方法:

  • words_with_length(长度) — 返回长度长度的所有单词的列表
  • starts_with(s) — 返回以 s 开头的所有单词的列表
  • ends_with(s) — 返回以 s 结尾的所有单词的列表
  • 回文() — 返回列表中所有回文的列表

第一个问题。编译我的程序后,方法以返回相同的单词开头,以返回相同的单词结束。 下一个问题。在这种情况下,我创建了一个包含三个名称的列表。但是,如果我想要求列表大小并在要求输入单词的同时迭代它怎么办。我怎样才能实现这个想法?

class Wordplay:
def __init__(self):
self.words_list=[]
def words_with_lenght(self,lenght):
for i in range(0,len(self.words_list)-1):
if len(self.words_list[i])==lenght:
return self.words_list[i]
def starts_with_s(self,s):
for i in range(0,len(self.words_list)-1):
if s.startswith('s')==True:
return self.words_list[i]
def ends_with_s(self,s):
for i in range(0,len(self.words_list)-1):
if s.endswith('s')==True:
return self.words_list[i]
def palindromes(self):
for i in range(0,len(self.words_list)-1):
normal_word=self.words_list[i]
reversed_word=normal_word[::-1]
if reversed_word==normal_word:
return reversed_word
verification=Wordplay()
verification.words_list=['sandro','abba','luis']
lenght=int(input('Digit size you want to comparen'))
s='s'
print(verification.words_with_lenght(lenght))
print(verification.starts_with_s(s))
print(verification.ends_with_s(s))
print(verification.palindromes())

如果我输入例如大小 4,我希望结果是: 阿巴,路易斯 ; 桑德罗;路易斯;阿爸,不是—— 阿爸;桑德罗;桑德罗;阿爸

在第if s.startswith('s')==True:行中,您已将字符串"s"传递到函数中,导致

if 's'.startswith('s')==True: 
#  ^^^
return self.words_list[i]

这个条件总是正确的。您可能根本不需要这里的参数,因为分配要求您"s"硬编码。您可以使用:

if self.words_list[i].startswith('s'): 
return self.words_list[i]

请注意,上面的示例在找到匹配项后立即使用return。这是一个问题。此程序中的循环会提前中断,一旦找到单个匹配项,就会从函数中返回。您可能打算将每个成功的匹配项附加到列表中并返回结果列表,或者使用yield关键字返回生成器(但如果调用方希望从生成器获得持久列表,则需要使用list())。使用列表构建结果如下所示:

result = []
for i in range(len(self.words_list)):
if self.words_list[i].startswith('s'): 
result.append(self.words_list[i])
return result

另一个问题:该程序中的循环不会一直遍历各自的列表。range()函数包含开始和排除结束,因此您可能打算range(len(self.words_list))而不是range(0, len(self.words_list) - 1)

除此之外,我还想建议一些设计和风格点:

  • 在运算符之间使用水平间距,并在块周围使用垂直空格。

    foo=bar.corge(a,b,c)
    if foo==baz:
    return quux
    

    更清晰为

    foo = bar.corge(a, b, c)
    if foo == baz:
    return quux
    
  • 使用 4 个空格而不是 2 个空格进行缩进,这样可以更轻松地快速确定哪个代码在哪个块中。

  • 更喜欢for element in my_list而不是for i in range(len(my_list))。如果需要索引,在大多数情况下可以使用for i, elem in enumerate(my_list).更好的是,使用列表推导来执行过滤操作,这是此逻辑的大部分。
  • 没有必要
  • 使用if condition == True.if condition就足够了。您可以简化令人困惑和不准确的逻辑,例如:

    def palindromes(self):
    for i in range(0,len(self.words_list)-1):
    normal_word=self.words_list[i]
    reversed_word=normal_word[::-1]
    if reversed_word==normal_word:
    return reversed_word
    

    例如:

    def palindromes(self):
    return [word for word in self.words_list if word[::-1] == word]
    

    也就是说,尽可能避免使用中间变量和索引。

  • 我知道你可能被设计束缚住了,但这对我来说是一种编写实用程序类的奇怪方式。作为对可迭代对象进行操作的静态方法,它会更灵活。典型用法可能是:

    from Wordplay import is_palindrome
    is_palindrome(some_iterable)
    

    而不是:

    wordplay = Wordplay(some_iterable)
    wordplay.palindromes()
    

    我的理由是,这个类基本上是无状态的,所以在不需要状态时强加状态似乎很奇怪。这有点主观,但值得注意的是(如果您曾经使用过mathrandom模块,这是同样的想法)。

    构造函数中缺少参数更加奇怪;类的客户端必须神奇地以某种方式"知道"words_list是他们需要赋值才能填充类状态的内部变量名称。此变量名称应该是客户端不知道的实现详细信息。如果在初始化函数中提供参数失败,则此字段应该有一个 setter(或者只是完全跳过内部状态)。

  • ends_with_s(self, s)是一个愚蠢的功能;设计师似乎在想要写ends_with(self, letter)ends_with_s(self)之间混淆了(前者更可取)。如果你想要一封新信怎么办?您是否需要为每个可能的结束字符ends_with_aends_with_bends_with_c等编写数十个函数?我意识到这只是一个人为的作业,但班级仍然表现出糟糕的设计。

  • 拼写错误:words_with_lenght->words_with_length.


以下是有关如何构建定位这些问题的技能的一般提示:在非常小的块中工作并经常运行程序。看起来这四个函数是一次性编写的,没有在整个过程中测试每个函数以确保它首先工作。这是显而易见的,因为所有四个函数都重复了相同的错误。

s.endswith('s')

将您的输入字符串s("s")与"s"进行比较。"s"以"s"结尾,因此它始终返回您的第一个条目。将其更改为if self.words_list[i].startswith('s'):(与endswith相同)。

我建议更改您的 for 循环以迭代单词本身:

def ends_with_s(self, s):
for word in self.words_list:
if word.endswith('s'):
return word

输入您描述的值列表:

amount = int(input("How many words? "))
words = [input("Word {}".format(i + 1)) for i in range(amount)]

最新更新