I am trying to set validation for given sentence (input). These are criteria
- Word contains letters, hyphens and punctuation only (no digits)
- Maximum number of hyphen is one per word. If present, hyphens must be placed between letters (“ab-ab” not “-ab” or “ab-“
- Maximum number of punctuation mark is one as well. If present, punctuation mark must be placed at the end of the word (“ab!”, “ab,” not “a!b” “a!!b”)
sentence = “these are valid words” is expected as [True, True, True, True]
sentence = “!this 1-s b8d!” is expected as [False, False, False]
sentence = “mciheal mnefiodonvass? W-O-W” is expected as [True, True, False]
sentence = “it’s Minecraft, not Mine-Craft!!” is expected as [False, True, True, False]) however i got [‘False’, ‘False’, ‘False’, ‘False’]
I got first three correct however for last one i am not getting the correct answer. Also for first criterion which is word with letters only will return True, it works for first but does not in last example. Can you explain me why and how can I fix it?
for last example I got [‘False’, ‘False’, ‘False’, ‘False’]
import string
def valid_words_mask(sentence):
sentence_list = sentence.split() punctuations = string.punctuation.replace("-","") true_false_list = [] count_hyphen = 0 count_punctuations = 0 validity = False for words in sentence_list: for characters in words: if characters.isalpha(): validity = True elif characters == "-": validity = True elif characters in punctuations: count_punctuations += 1 validity = True else: validity = False break count_hyphen = words.count("-") for characters in words: if characters in punctuations: count_punctuations += 1 if validity is True: if any(number.isdigit() for number in words): validity = False if count_hyphen > 1 or count_punctuations > 1: validity = False if words.startswith("-") or words.endswith("-"): validity = False if count_punctuations == 1: for not_last in range(len(words)-1): if words[not_last] in punctuations: validity = False if words[-1] in punctuations: validity = True if validity is False: true_false_list.append("False") elif validity is True: true_false_list.append("True") return (true_false_list.count("True"), true_false_list)
Advertisement
Answer
Based on your constraints, I suggest you break your code into a function with only 1 purpose: to check a single word. You can use something like:
def is_valid(word): punctuations = string.punctuation # constraint 1 if not all([d in punctuations or d.isalpha() for d in word]): return False # constraint 2 if word.startswith("-") or word.endswith("-"): return False if word.count("-") > 1: return False if "-" in word: dash_i = word.find("-") if (not word[dash_i - 1].isalpha()) or (not word[dash_i + 1].isalpha()): return False # constraint 3 punct = [d for d in word if d in punctuations] if len(punct) > 1: return False elif len(punct) == 1: punct_i = word.find(punct[0]) if punct_i != len(word) - 1: return False # all ok return True
To apply to each word in your sentence (split by whitespace I guess), so:
import string for word in "it's Minecraft, not Mine-Craft!!".split(): print(is_valid(word))
prints
False True True False