An isogram is a word that has no repeating letters, consecutive or non-consecutive. Implement a function that determines whether a string that contains only letters is an isogram. Assume the empty string is an isogram. Ignore letter case.
is_isogram("Dermatoglyphics" ) == true
is_isogram("aba" ) == false
is_isogram("moOse" ) == false # -- ignore letter case
Here is my code:
def is_isogram(string):
string = string.lower()
for char in string:
if string.count(char) > 1:
return False
else:
return True
And when I tried to run the test code Test.assert_equals(is_isogram("moOse"), False, "same chars may not be same case" ) It failed, but I thought I did convert everything into lowercase. Can someone help?
Try this:
def is_isogram(string):
string = string.lower()
for char in string:
if string.count(char) > 1:
return False
return True
In your code when is_isogram("moose") is called, it will see that the first character's ('m') count is not greater than 1. So it will return True. Once it hits the return statement, it will stop the execution for the rest string. So you should really write return True only after for-loop to make sure that the function checks for the whole string.
If however, at any point, it finds a character's count to be greater than 1, then it will simply return False and stop executing because there's no point of checking any more when one point is found where condition does not hold.
How about using sets? Casting the string into a set will drop the duplicate characters, causing isograms to return as True, as the length of the set won't differ from the length of the original string:
def is_isogram(s):
s = s.lower()
return len(set(s)) == len(s)
print is_isogram("Dermatoglyphics")
print is_isogram("aba")
print is_isogram("moOse")
print is_isogram("")
This outputs:
True
False
False
True
Try this :
def is_isogram(s):
string = s.lower()
if len(s) == len(set(string)):
return True
return False
Try this out:
def is_isogram(string):
return len(string) == len(set(string.lower()))
"Implement a function that determines whether a string that contains only letters is an isogram."
By using sets, you can create unique elements. So if there are any repeating numbers, it will only select one. By calling len() on these strings, you can compare the length to the original.
Sorry if I explained it poorly. I am working on this.
let us define an isogram well:
according to wikipedia An Isogram is a word in which no letter occurs more than once.
check here for more about an isogram
just remind letter
I write this code and it works for me :
def is_isogram(argument):
print(len(argument))
if isinstance(argument,str):
valeur=argument.lower()
if not argument:
return False
else:
for char in valeur:
if valeur.count(char)>1 or not char.isalpha():
return False
return True
else:
raise TypeError("need a string ")
NB: the hidden test is the fact that you must check if the char in the string is a alpha character a-z, when i add this it pass all the hiddens tests
up vote if this help
I reckon this might not be the best solution in terms of maximizing memory space and time. This answer is just for intuition purposes using a dictionary and two for loops:
def is_isogram(string):
#your code here
#create an empty dictionary
m={}
#loop through the string and check for repeating characters
for char in string:
#make all characters lower case to ignore case variations
char = char.lower()
if char in m:
m[char] += 1
else:
m[char] = 1
#loop through dictionary and get value counts.
for j, v in m.items():
#if there is a letter/character with a count > 1 return False
if v > 1:
return False
#Notice the scope of the "return True" command. It is outside.
return True
Related
I need to determine if there are alphabetic and numeric characters in a string. My code for testing the alphabetic one seems to work fine, but numeric is only working if all of the characters are a digit, not if any.
The alphabetic code that works:
from curses.ascii import isalnum, isalpha, isdigit
password = input("Enter your password: ")
def contains_alphabetic():
for i in password:
if isalpha(i):
print("Valid")
return True
else:
print("Invalid")
return False
contains_alphabetic()
This returns "Valid" if at least one of the characters is alphabetic, and "Invalid" if none of them are, which is what I want.
def contains_numeric():
for j in password:
if isdigit(j):
print("Valid")
return True
else:
print("Invalid")
return False
contains_numeric()
This only returns "Valid" if all of the characters are numeric, not if at least one is. How do I fix this?
Also, I tried using is.numeric() instead of is.digit() and it wouldn't even import.
As the comments have pointed out, both your contains_alphabetic and contains_numeric functions don't do what you think they're doing, because they terminate prematurely - during the very first iteration. You start a loop, inspect the current character (which will be the first character of the string during the first iteration of the loop), and immediately return something from the function based on that single character, which of course terminates the loop and the function.
Other suggestions: There's no need to import things from curses. Strings already have isalpha and isdigit predicates available. Additionally, it's probably a good idea to have your functions accept a string parameter to iterate over.
If the idea is to return True if any of the characters in a string satisfy a condition/predicate, and False otherwise (if none of the characters satisfy the condition), then the following would be a working implementation:
def contains_alpha(string):
for char in string:
if char.isalpha():
return True # return True as soon as we see a character that satisfies the condition
return False # Notice the indentation - we only return False if we managed to iterate over every character without returning True
Alternatively:
def contains_alpha(string):
found = False
for char in string:
if char.isalpha():
found = True
break
return found
Or:
def contains_alpha(string):
for char in string:
if char.isalpha():
break
else: # Notice indentation - special for-else syntax: If we didn't break out of the loop, execute the else
return False
return True
Or:
def contains_alpha(string):
return any(char.isalpha() for char in string)
So I wrote this code to find whether there is an uppercase letter AND a number in my string or not and here is what I have so far
def passwordOK(password: str):
for char in password:
if char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and "1234567890":
return True
else:
return False
print(passwordOK(password='roskaisHsodihf'))
but the result only retyrns if the first variable is modified, so the output only prints True if the first variable is a number or an uppercase letter
What changes to my code should be made?
Please do not use import and try to use the least amount of built in functions possible
def passwordOK(txt):
return True if any(t.isupper() for t in txt) and any(t.isdigit() for t in txt) else False
3 issues:
You always return from the first loop iteration
if char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and "1234567890" does not mean what you think it does.
If it did, your logic would still be wrong. A char cannot be an uppercase letter AND a digit at the same time. And if you mean or, one of the two still does not confirm the existence of the other in another position.
The logic you need should go along the following lines:
def passwordOK(password: str):
upper = digit = False
for char in password:
if char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and "1234567890":
upper = True
if char in "1234567890":
digit = True
if upper and digit:
return True
return False
If you were to use some utils you could avoid some of the boilerplate code:
from string import ascii_uppercase, digits
def passwordOK(password: str):
upper = any(c in ascii_uppercase for c in password)
digit = any(c in digits for c in password)
return upper and digit
Or even shorter, using the test methods:
def passwordOK(password: str):
return any(map(str.isupper, password)) and any(map(str.isdigit, password))
Logical comparisons do not work like you expect them judging by your code. Each part left and right to the and keyword will return either True or False. Therefore you need to repeat the char variable to check against your second list of characters like so:
if char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and char in "1234567890":
An non-empty string will return True by default in such a scenario.
Edit:
Also you have to use or because and will only return True if both creterias are met. A single char can't be in two disjunct sets at the same time.
An approach here would be to set a variable if either criteria is met and as soon as both ciriterias are met, you return True.
I have a function that checks if a given string is in a list of strings using a for and while loop. I’m not supposed to use the ‘in’ operator. Here’s my code using a for loop:
def word_in_list(words, word):
for strings in words:
if len(words) > 0 and strings == word:
return True
else:
return False
However, it is not returning True unless the single string is the first element of the list. The list should return False in case the list is empty. And how can I solve the same problem using a while loop (and without 'in' operator)?
Don’t return False the moment you find one mismatch, return False when you are done checking all possibilities and not finding any match:
def word_in_list(words, word):
for strings in words:
if strings == word:
return True
return False
Also, no need to check the length of list every time, if it's zero, you don't run the loop at all and directly return False.
Your code is wrong because of the else statement. Your function must return False only after checking the whole list, not just the first element. Whenever a function gets to a "return" instruction, it stops, so it just checked the first one. This is the correct solution:
def word_in_list(words, word):
i = 0
while i < len(words):
if words[i] == word:
return True
i += 1
return False
simly use this code
def word_in_list(words, word):
if word in words:
return True
else
return False
Your else block kicks-in without finishing the iteration on complete list.
def word_in_list(list_of_words, word_to_search):
found = False
for word in list_of_words:
if word == word_to_search:
found = True
break # breaks iff the word is found
return found
Any particular reason you are adamant not to use the 'in' operator?
Also, please be careful about the indentation in the code you paste.
My python function is supposed to take an input that is a string (of only letters and only lowercase letters). The function should output true if there are no repeating letters ( regardless of whether they are consecutive letters or not) and it's suppose to return false if there are repeating letters. My code only checks if the first letter is repeating or not, but doesn't check any other letter in the string. What is the issue?
Try this
def is_isogram(string):
for x in string:
if string.count(x) > 1:
return False
return True
You want to return True only if you pass through all the for loop
the following should rectify.
def is_isogram(s: str):
# loop through all unique chars
for x in set(s):
if s.count(x) > 1:
return True
# terminate after looping through all chars
return False
additionally convert string to a set to eliminate iterating over same char twice.
You're not making it past the first character because in the first iteration of the for loop, your "else" exits the function if the if statement returns false.
My solution
def is_isogram(x):
if len(str(x)) > len(set(x)):
return False
else:
return True
So I have to build a function that checks if something is a palindrome, but it has to be recursive and it has to be linear and it has to ignore punctuations. I can't use any imports and my teacher told me that using the translation function isn't efficient enough. I'm trying to re-engineer it but iI'm very much stumped.
def isPalindrome(word):
newWrd = word.translate(None, "., ").lower()
if len(newWrd) <= 1:
return True
elif newWrd[0] != newWrd [-1]:
return False
else:
return isPalindrome(newWrd[1:-1])
The concept and motivation are simple:
Check the first and last character of the current string.
If they match, repeat the previous operation, but only take the slice of the string that you haven't processed yet.
If they don't match, return False.
Strings of length 1 are palindromic by default.
Here's what I would come up with. The below assumes a unified case and that all punctuation is stripped out of the word, but if you wish to do that in this method, I leave that as an exercise for the reader.
def palindrome(word):
if not word:
return False
if len(word) == 1:
return True
else:
if word[0] == word[-1]:
return palindrome(word[1:-1])
else:
return False
Normally, you should import string and use string.punctuation, but since you don't want to import anything, you can just hard-copy it to your code.
Since you already have the isPalindrome() recursive function, you can write a wrapper function, isPalindromeWrapper(), which will take the input, process it (remove the punctuations) and then call the isPalindrome() function.
punctuations = '!"#$%&\'()*+,-./:;<=>?#[\\]^_`{|}~'
def removePunctuations(word):
return ''.join( [ c for c in word if c not in punctuations ] )
def isPalindrome(word):
print('isPalindrome({}) called.'.format(word))
if len(word) < 2:
return True
if word[0] == word[-1]:
return isPalindrome(word[1:-1])
return False
def isPalindromeWrapper(word):
word = removePunctuations(word)
return isPalindrome(word)
print isPalindromeWrapper('ab,c!b?a')
Output:
isPalindrome(abcba) called.
isPalindrome(bcb) called.
isPalindrome(c) called.
True