I am trying to generate a function which tells me if a word is an isogram (contains duplicate values). However, this code always returns a generator object.
def is_isogram(string):
return (True if (string.lower().count(letter) == 1) else False for letter in string.lower())
I know how to solve the problem, I was just wondering what is wrong with my code.
I suppose your function is intended to return a boolean, but the return statement has an iteration happening, where each value is mapped to a boolean. The parentheses give you an iterator over those booleans. The function's description suggests that the function should return True when the input has duplicate letters, but the mapping gives True when a letter is not duplicate. So you have three problems:
The iterator
The multiple booleans, when you want one boolean
The booleans indicate the inverse of what you want to return
So your idea for an algorithm should be changed to this:
def is_isogram(string):
return any(letter for letter in string.lower() if string.lower().count(letter) > 1)
Side note: this algorithm is not efficient. More efficient is to create a set:
def is_isogram(string):
return len(set(string.lower())) < len(string)
By wrapping your returned value into parenthesis you've created a generator expression, check https://peps.python.org/pep-0289/ for details.
Related
I am trying to write a function to check whether a string is palindrome or not, but every string is showing as palindrome
def is_palindrome(input_string):
x=0
reverse_string = ""
while x<len(input_string):
reverse_string+=input_string[x]
x=x+1
if input_string == reverse_string:
return True
else:
return False
print(is_palindrome("abc")) # Should be False but it return True
In your code, the variabile "reverse_string" will always be equal to "input_string" since you are just appending the characters in the same order with the += operator.
A simple way to reverse a string in Python is to use slicing like that:
def is_palindrome(input_string):
if input_string == input_string[::-1]:
return True
return False
input_string[::-1] means "start from the first index to the last in the reverse order (-1)"
Your problem is in the reversal of the string. (your x is going from 0 to len(input_string)-1 but it should go the other way)
That's why it's important to break code into functions that do one and only one thing (at least in the beginning)
In this case is an overkill, but it will help you when your code grows more complex.
your function can then be simplified as:
def is_palindrome(input_string):
return input_string == reverse_string(input_string)
If you look at it is self explanatory. Is the input string equal to its reverse?
Now we need to implement the function reverse_string.
The advantage of having a function that just reverses a string is that we can do a lot of tests on it to check just this particular function
In your case, you can use negative indexes, or you can start with the index set to len(input_string)-1 and go towards 0.
But it's also a good moment to learn about string slicing and how to do things in a pythonic way, so the reverse function can be written as:
def reverse_string(input_string):
return input_string[::-1]
Feel free to put your own implementation of reverse_string if you are not yet confident with string slicing, but with this function you have separated two different things: reversing a string and checking is string is a palindrome. You can even reuse that reverse_string function later on.
Now we can test it with many cases until we are confident that it works as expected.
I'd recommend taking a look at unit tests it might seem too much for such an easy problem, but it will help you a lot in the future.
Just test what happens if you pass a palindrome, a non-palindrome, an empty string, a number, a None...
I'm trying to build logic in programming. I need to write a python function that takes string as input and checks whether any character appears more than once. The function should return True if there are no repetitions and False otherwise. I have searched online and found several examples related to it. I wrote the code and it seemed fine initially but then I realized my mistake and now I'm not getting how should I go about it. Please guide
def repfree(S):
for char in S:
if S.count(char) > 1:
return True
return False
Here, you can create a character list to keep track of the characters that have already occurred in S.
Have a look at the code below, hope it helps:>
def repfree(S):
freq = []
for char in S:
# if the character is already in list that means S contains repeated char
if char in freq:
return False
else:
freq.append(char)
return True
How about you use a set
def repfree(s):
char_set = set()
for c in s:
char_set.append(c)
return len(char_set) == len(s)
You can try on the following code.
def rep_free(text):
return len(text) != len(set(text))
A set object is an unordered collection of distinct hashable objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference. (For other containers see the built-in dict, list, and tuple classes, and the collections module.)
From python doc
This should be done using set data structure of python, set is having a property where it will always have unique characters only.
string="country"
def repetion(string):
if len(set(string)) == len(string):
print("string is having unique chars")
else:
print("chars are different")
I have a function like this in Python 3.4:
def is_value_valid(the_str):
return len(the_str) != 0
There are of course other ways to write this, such as return the_str != "". Are there more pythonic ways of writing this expression? I am familiar with the concepts of truthy/falsy, so I know I could shortcut this in an if condition:
if not the_str:
# do stuff
But the if expects a boolean result in its expression (this is my naive oversimplification here as a C++ programmer; I'm not familiar with standardese for this). However, there is nothing there to force the expression to evaluate to boolean in the return statement. I have tried just returning the string, and as long as no one treats the returned value as a string, it works just fine in calling code under boolean context. But from a post-condition perspective, I don't want to return a non-boolean type.
This is exactly what the bool() function does; return a boolean based on evaluating the truth value of the argument, just like an if statement would:
return bool(the_str)
Note that if doesn't expect a boolean value. It simply evaluates the truth value of the result of the expression.
>>> bool("foo")
True
>>> bool("")
False
Empty strings evaluate to False, but everything else evaluates to True. So this should not be used for any kind of parsing purposes.
So just return bool(the_str) in your case.
The if statement automatically evaluates a string as a boolean. However, if you want to return your string as a boolean you would simply do
return bool(the_str)
bool(the_str) is definitely the way to go, as several have mentioned.
But if your method requires that a string be given, I would also test for the string actually being a string (because bool(5) and bool("this is a string") will both return true.
return isinstance(the_str, str) and bool(the_str)
Or when used in an if statement:
if isinstance(the_str, str) and the_str:
# here we are sure it's a string whose length > 0
def is_value_valid(the_str):
return bool(len(the_str) != 0)
Using bool(x) converts the value to a boolean. This function takes len(the_str) != 0, evaluates it, converts it to bool, then returns the value.
The bool(x) is not required, you can just have the parentheses, because it will already return a bool, as evaluations return boolean by default.
This is what I have so far:
count=0
mystring=input("enter")
for ch in mystring:
if mystring.lower():
count+=1
print(count)
I figured out how to make a program that displays the number of lower case letters in a string, but it requires that I list each letter individually: if ch=='a' or ch=='b' or ch=='c', etc. I am trying to figure out how to use a command to do so.
This sounds like homework! Anway, this is a fun way of doing it:
#the operator module contains functions that can be used like
#their operator counter parts. The eq function works like the
#'=' operator; it takes two arguments and test them for equality.
from operator import eq
#I want to give a warning about the input function. In python2
#the equivalent function is called raw_input. python2's input
#function is very different, and in this case would require you
#to add quotes around strings. I mention this in case you have
#been manually adding quotes if you are testing in both 2 and 3.
mystring = input('enter')
#So what this line below does is a little different in python 2 vs 3,
#but comes to the same result in each.
#First, map is a function that takes a function as its first argument,
#and applies that to each element of the rest of the arguments, which
#are all sequences. Since eq is a function of two arguments, you can
#use map to apply it to the corresponding elements in two sequences.
#in python2, map returns a list of the elements. In python3, map
#returns a map object, which uses a 'lazy' evaluation of the function
#you give on the sequence elements. This means that the function isn't
#actually used until each item of the result is needed. The 'sum' function
#takes a sequence of values and adds them up. The results of eq are all
#True or False, which are really just special names for 1 and 0 respectively.
#Adding them up is the same as adding up a sequence of 1s and 0s.
#so, map is using eq to check each element of two strings (i.e. each letter)
#for equality. mystring.lower() is a copy of mystring with all the letters
#lowercase. sum adds up all the Trues to get the answer you want.
sum(map(eq, mystring, mystring.lower()))
or the one-liner:
#What I am doing here is using a generator expression.
#I think reading it is the best way to understand what is happening.
#For every letter in the input string, check if it is lower, and pass
#that result to sum. sum sees this like any other sequence, but this sequence
#is also 'lazy,' each element is generated as you need it, and it isn't
#stored anywhere. The results are just given to sum.
sum(c.islower() for c in input('enter: '))
You have a typo in your code. Instead of:
if my.string.lower():
It should be:
if ch.islower():
If you have any questions ask below. Good luck!
I'm not sure if this will handle UTF or special characters very nicely but should work for at least ASCII in Python3, using the islower() function.
count=0
mystring=input("enter:")
for ch in mystring:
if ch.islower():
count+=1
print(count)
The correct version of your code would be:
count=0
mystring=input("enter")
for ch in mystring:
if ch.islower():
count += 1
print(count)
The method lower converts a string/char to lowercase. Here you want to know if it IS lowercase (you want a boolean), so you need islower.
Tip: With a bit of wizardry you can even write this:
mystring= input("enter")
count = sum(map(lambda x: x.islower(), mystring))
or
count = sum([x.islower() for x in mystring])
(True is automatically converted to 1 and False to 0)
:)
I think you can use following method:
mystring=input("enter:")
[char.lower() for char in mystring].count( True ) )
I want to define a recursive function that passes a str and returns a bool telling whether or not the characters in the parameter are in alphabetical order.
Like if I defined said sortfunc('abcdefg') it would return True; and sortfunc('banana') would return False.
How would I approach this? This is what I have so far... but I'm sort of stuck. I understand the concept of recursion but I don't know how to implement it.
def sortfunc(s):
if s == '':
return False
else:
return True if s[0] < s[1:] else False
Here's one possible method:
def is_sorted(s):
if len(s) == 1:
return True # Base case
elif s[0] <= s[1]:
return is_sorted(s[1:]) # Recursive case
else:
return False # Base case
Explanation:
So, whenever, we want to write a recursive function, we always need to think about the following:
How can I break the problem down into smaller steps?
What is the base case? (when I can stop the recursion?)
What is the recursive case? (when do I need to keep going?)
To me, the first step is always the trickiest one -- breaking the problem down. Usually, once we figure out this step, the rest falls into place.
There are usually many different ways to break a problem down, and to a certain extent, which one you pick is a bit arbitrary. In this case, I chose to break the problem down by repeatedly comparing the first two characters in the string.
If the two characters are in order, then I repeat the process, except I remove the first character. If I have only one character left in my string, or if the first two characters are out of order, I know that I can stop and return True or False respectively.
For example, if we visualize calling is_sorted('abcd'), it would look something like this:
call is_sorted('abcd')
'a' is less then 'b'
call is_sorted('bcd')
'b' is less then 'c'
call is_sorted('cd')
'c' is less then 'd'
call is_sorted('d')
only one character left, return True
return True
return True
return True
In contrast, if we tried calling is_sorted('azbc'), it would look something like this:
call is_sorted('azbc')
'a' is less then 'z'
call is_sorted('zbc')
'z' is NOT less than 'b', return False
return False
So then, here are the answers to the three steps:
How can I break the problem down into smaller steps?
Keep comparing the first two characters
What is the base case? (when I can stop the recursion?)
Either when the two characters are out of order, or if I have only one character left
What is the recursive case? (when do I need to keep going?)
If I have two or more characters left in my string.
Notice that the recursive case always requires a "leap of faith" -- you have to trust that calling the is_sorted method will accurately tell you if the rest of the string (besides the first two characters) is correctly sorted or not. It's a bit of an odd feeling -- it feels like we never explicitly told the code how to determine if the string is coded or not, or passed in any information, but it does so anyways!
However, that's part of the beauty of recursion: so long as we correctly define the base case(s) and recursive case(s), it'll magically work.
In your attempt you are missing the recursion part. Please check the following implementation.
def sortfunc(current_string, previous_character = ""):
if current_string == "":
return True # Base condition
if previous_character and previous_character > current_string[0]:
return False # Failure case
return sortfunc(current_string[1:], current_string[0]) # Recursion
If you want to know how to do this without recursion,
def sortfunc(current_string):
return "".join(sorted(current_string)) == current_string
Sample runs:
print sortfunc('abcdefg') # True
print sortfunc('banana') # False
Without less programming logic!
-> Split the string to an array and send this array to function
-> we can easily compare values by converting them to respective ascii values
sortfunc(str) {
for(int i=0;i<str.length;i++){
if ( (int) str[i] >(int) str[i+1] ) {
result = true
}
else
result = false;
return result;
}