Function that checks if a string occurs in another string - python

I'm currently reading and doing each and every of the exercises in John Guttag's Introduction to Computation and Programming Using Python. One particular problem I cannot solve for the life of me:
Write a function isIn that accepts two strings as arguments and
returns True if either string occurs anywhere in the other, and False
otherwise. Hint: you might want to use the built-in str operation in.
I went through every discussion I could find here, tried with both in and find, constantly changing something in the code, but every time I would run my program to check if 'abc' occurs in 'efg' the answer would be True.
Any idea how to solve it? Again, I need to write a function, not simply go with in like:
x='abc'
y='efg'
if x in y:
# Blah
else:
# another Blah
The code I wrote (I'm adding this as apparently some would like to see it) was basically this:
def isIn(x,y):
if x in y or y in x:
return True
else:
return False
a='abc'
b='efg'
isIn(a,b)
if True:
print "True"
else:
print "False"

The problem is that you are completely ignoring the return value of the function isIn, and the reason why you always get True printed by the code is that the condition you are checking in the if statement is the boolean constant True, which is of course always True.
Try changing your code to:
a='abc'
b='efg'
r = isIn(a,b)
if r:
print "True"
else:
print "False"

Simply put:
x=input('Enter string #1: ')
y=input('Enter string #2: ')
#can also just define x and y separately in the console and invoke the
# function on those values
def isIn(x,y):
if x in y:
return True
elif y in x:
return True
else:
return 'False'
print(isIn(x,y)) #invokes and prints the results of the function evaluating
#the x and y the user inputs; otherwise nothing is returned

I'm getting the impression that you are a newcomer to Python, so here is the solution to your problem below laid out just as the question asks :)
def isIn(string_1, string_2): #This is the function that returns true/false
if (string_1 in string_2) or (string_2 in string_1):
is_in = True
else:
is_in = False
return is_in
if __name__ == "__main__":
string_1 = input ("String 1 here: ")
string_2 = input ("string 2 here: ")
is_in = isIn(string_1, string_2) #Calls function with strings as parameters
print (is_in) #Prints the evaluation of the function after it has run
The problem with your code was that you say if True, but you aren't giving it anything to check against. if True on its own is always true.
If you want me to explain how this code works in more detail I'd be happy to do so :)

you are not printing the isIn(x,y)
def is_in(x,y):
if x in y or y in x:
return True
else:
return False
print(is_in("hello","hello world"))
try this :)

Related

I get an error when I end the if statement with a concluding else statement

I wrote this Python code that would check a list and return True if two items in the list next to each other are of the same value:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
Result 1:
>>> samer([1,3,44,5,5,8])
False
This is where I'm puzzled because I feel it should return True.
Result 2:
>>> samer([3,3,49,93,5,8])
True
It only returns True if the first and second number in the list is True.
The solution:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
return False
The above code works well, so my question is since the else statement indented under the if condition's purpose is to return False if no number in the list is next to each other in the process of the for loop, why do I still get False in Result 1?
Is it that it doesn't loop again after checking the first two boxes and why is that since it's the purpose of the for loop to go over each iteration and then check for the conditions?
When a function returns, that's it. The function is done, over, finished..
Since you're returning either true or false when checking each and every element, you really only check the first time through the loop (elements one and two), as you observe.
You should return true if a match is found and only return false at the end, when you've checked everything and, therefore, no matches are found. That code is already in your question, the bit under The solution.
So to chip in here, once that first iteration check occurs, we know that it's going to be returning False as the first two elements are not the same and the program ends there. If you want to really see that this is the case, make use of print() built-in function to see what's going on everytime the element is iterated within the for loop:
Like this:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
print(True)
else:
print(False)
### adding a main method is always a good idea for clarity.
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is this:
False
False
False
True
False
See it returned True for the 3th element as they are equal and next to each other.
But with the way you had it structured in the first example it does return False as it hit the roadblock once it checked and saw that the first iteration were not equal to each other and thus returned False.
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is:
False
With your solution approach which is great, the loop only 'terminates' when it really cannot find a match (same two numbers), it will return False without depending on a else statement. So if it finds a match then it will return True which is does and then stops iterating and exits the program.

python if/else logic explained please

I have a really basic if/else logic question for Python. An exercise in the book required me to write a function that takes a list of integers are returns True if the list contains all even numbers and False if it doesn't.
I wrote:
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
else:
return True
This code always returns True. Why is that? Doesn't the code see the -1 during the loop of all the values of the list and returns the False?
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
return True
The book gives the answer of this. Why does this work and mine doesn't?
Pay close attention to where that else is placed. Indentation and nesting matters here!
In your first example, it will return True on the first element that satisfies your condition because your first if check fails.
In your second example, it will return True after all elements have been iterated through and a return value hasn't been produced.
The first function checks the first number only, since it returns something as soon as the for loop starts.
By the way, you can but should not use list as an argument or a variable name, since it is a keyword.
I strongly recommend writing a print statement to output x before both of your return statements. It will help you understand the flow of the code.
The short answer is that only the first element is being checked by your code, and the function returns True or False based on that value.
In the book solution, any failure causes a return of False, but the loop simply continues otherwise. Only if all elements are checked without failure does the return True reached.

Are two instances of return in Python problematic?

Background:
An exercise on Codeacademy calls for creating code where a cube function returns the variable cubed.
Then, when that function is called by the function by_three, the authors suggest using another return:
Make sure both functions return their values rather than printing them, and that both branches of the if/else statement in by_three have return statements in them.
The code, which is accepted as a correct answer, is:
def cube(n):
cubed = n**3
return cubed
def by_three(n):
if n % 3 == 0:
return cube(n)
else:
return False
Question:
Why do there need to be two instances of return? First in cube, and then again in if for by_three. Shouldn't the former be enough?
Or does the duplication help the code execute, and why? Can it be harmful?
If a function does not return anything, it defaults to returning None.
Your cube function, instead of printing the result, returns the result so it can be used elsewhere. If it were just print cubed instead of return, then return cube(n) would be equivalent to return None, and this isn't what you want. Because return returns (or in this case, assigns) the value to a variable.
In your by_three function, it is useful to have the else: return False, because, as mentioned above, it will otherwise return None. This might not be helpful, because you may need the value False to determine something else later in your code. The reason you were asked to put the returns in the if/else was because that was what Codecademy wanted you to do :p. It's probably not going to be useful for you later during Codecademy, but it's good practice :) later on when you start writing your own code :).
mycubed = by_three(6)
# mycubed is now 216
mycubed2 = by_three(4)
# mycubed2 is now False.
Always return a value from a function when there is an if/elif/else statement. But it's always, always handy to return something, no matter the situation. (note how something is the opposite of no(ne)thing)
Why do there need to be two instances of return?
There don't have to be - you can express the function in a many ways with just a single return statement.
There's the "only return at the end" pattern...
def by_three(n):
if n % 3 == 0:
result = cube(n)
else:
result = False
return result
...which can be combined with the "default result" pattern...
def by_three(n):
result = False
if n % 3 == 0:
result = cube(n)
return result
...and the "do everything on one line" pattern...
def by_three(n):
return False if n % 3 else cube(n)
...which is fairly readable, but the following is not...
def by_three(n):
return next(iter(map({True: lambda x: False, False: cube}[bool(n % 3)], (n,))))
...although it still passes the tests on Codecademy.
Update
...I meant that I don't understand the need for the second instance of
return (when it's already in the first)
Well, they're two separate functions, so each needs its own return statement if it needs to return a value.

Python - function to do string comparison

def name(x):
return x==('Jenson'or'Amra'or'McCay'or'Spinner'or'Jones')
print(name('Jenson'))
print(name('McCay'))
This is the question:
"Write a function that takes as input a name of a person (e.g.,
“smith”, “jones”, etc.) This function should check to see if the name
is one of the five names of people on the board. The five names are:
“Jenson”,”Amra”, “McCay”,”Spinner”, and “Jones”. If the name input
into the function is one of those five names, the function should
return the Boolean value True, and if it isn’t, the function should
return False. (remember comments with input types, description, and
test cases) Test the function to make sure it works."
It works if I am doing Jenson but it comes out with false if I put in any other name.
Try like this,
def name(x):
return x in ('Jenson', 'Amra' ,'McCay', 'Spinner','Jones')
How about the "long" way:
def check_name(x):
names_to_check = ('Jenson','Amra','McCay','Spinner','Jones')
for i in names_to_check:
if i == x:
return True
return False
Here is what is happening in your code:
x = 'Jenson', since this is what you have passed in.
This line x == ('Jenson' or 'Amra' or 'McCay' or 'Jones') is actually a boolean operation, and the result of it is always Jenson.
Boolean operations check truth values, and a non-empty string in Python is always True. So actually what ('Jenson' or 'Amra' or 'McCay' or 'Jones') is saying is:
"Either Jenson or Amra or McCay or Jones which ever one is True, set the value to that".
Since Jenson is the first item, and its True (that is, its not an empty string), the entire expression is equal to Jenson (which is why it only works when you pass in Jenson).
A simple example:
>>> ('a' or 'b' or 'c')
'a'
>>> ('b' or 'a' or 'c')
'b'
>>> ('' or '' or 'a')
'a'
>>> (0 or 0 or 1)
1
>>> (False or False or True)
True
The last three illustrate the same comparison. I am checking two empty strings and 'a'. Since an empty string is False in Python, the only thing that is "True" is 'a', which is what is returned, just as if I was comparing 0 with 1.
The syntax x==('Jenson' or 'Amra' or 'McCay' or 'Spinner'or'Jones') is wrong.
It should be like Adem says. or maybe
def name(x):
return x=='Jenson' or x== 'Amra' or x == 'McCay' or x == 'Spinner' or x == 'Jones'
I imagine what is happening is that ('Jenson'or'Amra'or'McCay'or'Spinner'or'Jones') is being evaluated first, and is evaluated to 'Jenson'. That is computed before x is even considered because it is in parentheses. Then x is checked for equality against Jenson. You need to either use a more advanced syntax like x in... as in Adem's answer, or else use return x == 'Jenson' or x == 'Amra' or x == 'McCay'... so that each comparison is run one after another.

How can this behavior be acomplished? Python "short circuting" test

I have the following code:
def testGeodatabase(self):
geodatabaseList = self.gp.ListWorkspaces("*","ALL")
for x in geodatabaseList:
if x == self.outputGeodatabase:
return True
else:
pass
return False
What i need to know the following: in case the if condition evaluates to true, will the function stop looking in the list and never return False? Or do i need a break statement?
def testGeodatabase(self):
geodatabaseList = self.gp.ListWorkspaces("*","ALL")
for x in geodatabaseList:
if x == self.outputGeodatabase:
return True
break
else:
pass
return False
If the following code does not solve my problem, what can i use to do simulate that behavior?
Thanks
return is the end of the line, and nothing else will happen in that function afterwards. On the other hand, you could rewrite your function as
def testGeodatabase(self):
return self.outputGeodatabase in self.gp.ListWorkspaces("*","ALL")
You don't need the break keyword in the code above. Actually, you don't need the
else:
pass
either. The
return True
will exit the function.
The return statement will indeed cause the function to be exited at that point. No further code is executed in the function.
Here is a simple test which you could run to prove the point:
def someFunction(nums):
for i in nums:
if i == 1:
return "Found 1!"
return "Never found 1"
And running it:
>>> someFunction([2])
'Never found 1'
>>> someFunction([2,1,3])
'Found 1!'
I think that using any() is the best choice:
def testGeodatabase(self):
geodatabaseList = self.gp.ListWorkspaces("*","ALL")
return any(x == self.outputGeodatabase for x in geodatabaseList)

Categories

Resources