确定字符串是否是等值线图

Nif*_*Ojo 1 python

任务:
编写一个程序,检查作为参数提供的单词是否是等值线.Isogram是一个不会出现多次字母的单词.

创建一个名为is_isogram的方法,它接受一个参数,一个单词来测试它是否是等值线图.此方法应返回单词的元组和布尔值,指示它是否是等值线图.

如果提供的参数是空字符串,则返回参数和False :(参数,False).如果提供的参数不是字符串,则引发TypeError,并显示消息'Argument should a a string'.

例:

is_isogram("abolishment")
Run Code Online (Sandbox Code Playgroud)

预期结果:

("abolishment", True)
Run Code Online (Sandbox Code Playgroud)

可见测试

from unittest import TestCase

class IsogramTestCases(TestCase):
  def test_checks_for_isograms(self):
    word = 'abolishment'
    self.assertEqual(
      is_isogram(word),
      (word, True),
      msg="Isogram word, '{}' not detected correctly".format(word)
    )

  def test_returns_false_for_nonisograms(self):
    word = 'alphabet'
    self.assertEqual(
      is_isogram(word),
      (word, False),
      msg="Non isogram word, '{}' falsely detected".format(word)
    )

  def test_it_only_accepts_strings(self):
    with self.assertRaises(TypeError) as context:
      is_isogram(2)
      self.assertEqual(
        'Argument should be a string',
        context.exception.message,
        'String inputs allowed only'
      )
Run Code Online (Sandbox Code Playgroud)

我的解决方案

def is_isogram(word):
    if type(word) != str:
        raise TypeError('Argument should be a string')

    elif word == "":
      return (word, False)
    else:
        word = word.lower()
        for char in word:
            if word.count(char) > 1:
                return (word, False)
            else:
                return (word, True) 
Run Code Online (Sandbox Code Playgroud)

但它的功能拒绝通过一些隐藏的测试:我的解决方案出了什么问题?还有另一种优雅的方式来编写这个函数吗?

Chr*_*nds 5

我不确定你的搜索应该是不区分大小写的,所以也许你应该删除word = word.lower(),但你的主要问题是return终止函数,所以当前代码只需要return True在所有测试完成后(即在循环之外):

for char in word:
    if word.count(char) > 1:
        return (word, False)
return (word, True)
Run Code Online (Sandbox Code Playgroud)

无论如何,更好的方法是使用set()从字符串中删除所有重复项,然后比较长度; 还isinstance()用来检查是否word是一个字符串.您可以if w用来检查空字符串.你不需要括号return,逗号就足以构成return一个元组:

def is_isogram(word):
    if isinstance(word,str):
        w = word.lower() # assuming you want a case in-sensitive search
        return word, len(w) == len(set(w)) if w else False
    else:
        raise TypeError('Argument should be a string')
Run Code Online (Sandbox Code Playgroud)

例子:

is_isogram('abolishment')
# ('abolishment', True)
is_isogram('happy')
# ('happy', False)
is_isogram('')
# ('', False)
is_isogram(1)
# TypeError: Argument should be a string
Run Code Online (Sandbox Code Playgroud)