Counting two words in a string - python-2.7

I have to count two words 'cat' and 'dog' from a string.
If the counts are equal, I would like to return True else false.
For example, for input "dogdoginincatcat" my method should return True.
Here is my code,
def cat_dog(str):
count=0
count1=0
for i in range(len(str)):
if str[i:i+3] == 'cat':
count=count+1
if str[i:i+3] == 'dog':
count1=count+1
if count == count1:
return True
else:
return False
cat_dog('catdog')

just one line to do this using count on a string:
z= "dogdoginincatcat"
print(z.count("cat")==z.count("dog"))

First, DON'T use str (the string class) as a variable name. While Python won't cry at that very moment, you'll regret it later.
Second, it doesn't look like the count and count1 are indented as inside blocks of the 'if' statements, so your code is seen as:
for i in range(len(str))
if something:
pass
count = count + 1
if something_else:
pass
count1 = count1 + 1
Other than that, your code seems to work

Related

Finding a string in a phrase

I am using regexpi to find a string in a phrase. But I also encountered with something different which I never intended.
Let's say the words I need to find are anandalak and nandaki.
str1 = {'anandalak'};
str2 = {'nanda'};
button = {'nanda'};
Both of the following return me logical 1:
~cellfun('isempty',regexpi(str1,button))
~cellfun('isempty',regexpi(str2,button))
How can I avoid this? I need logical 0 in first case and logical 1 in the second.
You probably need to use the word-boundaries(\<\>) in order to get the match which you require.
You may try:
str1 = {'anandalak'}
str2 = {'nanda'}
button = {'\<nanda\>'} % Notice this
~cellfun(#isempty,regexpi(str1,button)) % Returns ans = 0 No match
~cellfun(#isempty,regexpi(str2,button)) % Return ans = 1 Exact match
You can find the sample run result of the above implementation in here.

Is there a pythonic way to count the number of leading matching characters in two strings?

For two given strings, is there a pythonic way to count how many consecutive characters of both strings (starting at postion 0 of the strings) are identical?
For example in aaa_Hello and aa_World the "leading matching characters" are aa, having a length of 2. In another and example there are no leading matching characters, which would give a length of 0.
I have written a function to achive this, which uses a for loop and thus seems very unpythonic to me:
def matchlen(string0, string1): # Note: does not work if a string is ''
for counter in range(min(len(string0), len(string1))):
# run until there is a mismatch between the characters in the strings
if string0[counter] != string1[counter]:
# in this case the function terminates
return(counter)
return(counter+1)
matchlen(string0='aaa_Hello', string1='aa_World') # returns 2
matchlen(string0='another', string1='example') # returns 0
You could use zip and enumerate:
def matchlen(str1, str2):
i = -1 # needed if you don't enter the loop (an empty string)
for i, (char1, char2) in enumerate(zip(str1, str2)):
if char1 != char2:
return i
return i+1
An unexpected function in os.path, commonprefix, can help (because it is not limited to file paths, any strings work). It can also take in more than 2 input strings.
Return the longest path prefix (taken character-by-character) that is a prefix of all paths in list. If list is empty, return the empty string ('').
from os.path import commonprefix
print(len(commonprefix(["aaa_Hello","aa_World"])))
output:
2
from itertools import takewhile
common_prefix_length = sum(
1 for _ in takewhile(lambda x: x[0]==x[1], zip(string0, string1)))
zip will pair up letters from the two strings; takewhile will yield them as long as they're equal; and sum will see how many there are.
As bobble bubble says, this indeed does exactly the same thing as your loopy thing. Its sole pro (and also its sole con) is that it is a one-liner. Take it as you will.

Python - Obtain the most frequent word in a sentence, if there is a tie return the word that appears first in alphabetical order

I have written the following code below. It works without errors, the problem that I am facing is that if there are 2 words in a sentence that have been repeated the same number of times, the code does not return the first word in alphabetical order. Can anyone please suggest any alternatives? This code is going to be evaluated in Python 2.7.
"""Quiz: Most Frequent Word"""
def most_frequent(s):
"""Return the most frequently occuring word in s."""
""" Step 1 - The following assumptions have been made:
- Space is the default delimiter
- There are no other punctuation marks that need removing
- Convert all letters into lower case"""
word_list_array = s.split()
"""Step 2 - sort the list alphabetically"""
word_sort = sorted(word_list_array, key=str.lower)
"""Step 3 - count the number of times word has been repeated in the word_sort array.
create another array containing the word and the frequency in which it is repeated"""
wordfreq = []
freq_wordsort = []
for w in word_sort:
wordfreq.append(word_sort.count(w))
freq_wordsort = zip(wordfreq, word_sort)
"""Step 4 - output the array having the maximum first index variable and output the word in that array"""
max_word = max(freq_wordsort)
word = max_word[-1]
result = word
return result
def test_run():
"""Test most_frequent() with some inputs."""
print most_frequent("london bridge is falling down falling down falling down london bridge is falling down my fair lady") # output: 'bridge'
print most_frequent("betty bought a bit of butter but the butter was bitter") # output: 'butter'
if __name__ == '__main__':
test_run()
Without messing too much around with your code, I find that a good solution can be achieved through the use of the index method.
After having found the word with the highest frequency (max_word), you simply call the index method on wordfreq providing max_word as input, which returns its position in the list; then you return the word associated to this index in word_sort.
Code example is below (I removed the zip function as it is not needed anymore, and added two simpler examples):
"""Quiz: Most Frequent Word"""
def most_frequent(s):
"""Return the most frequently occuring word in s."""
""" Step 1 - The following assumptions have been made:
- Space is the default delimiter
- There are no other punctuation marks that need removing
- Convert all letters into lower case"""
word_list_array = s.split()
"""Step 2 - sort the list alphabetically"""
word_sort = sorted(word_list_array, key=str.lower)
"""Step 3 - count the number of times word has been repeated in the word_sort array.
create another array containing the word and the frequency in which it is repeated"""
wordfreq = []
# freq_wordsort = []
for w in word_sort:
wordfreq.append(word_sort.count(w))
# freq_wordsort = zip(wordfreq, word_sort)
"""Step 4 - output the array having the maximum first index variable and output the word in that array"""
max_word = max(wordfreq)
word = word_sort[wordfreq.index(max_word)] # <--- solution!
result = word
return result
def test_run():
"""Test most_frequent() with some inputs."""
print(most_frequent("london bridge is falling down falling down falling down london bridge is falling down my fair lady")) # output: 'down'
print(most_frequent("betty bought a bit of butter but the butter was bitter")) # output: 'butter'
print(most_frequent("a a a a b b b b")) #output: 'a'
print(most_frequent("z z j j z j z j")) #output: 'j'
if __name__ == '__main__':
test_run()

python 2.7 - trying to print a string and the (printed) output of function in the same line

I have the following function defined:
def displayHand(hand):
"""
Displays the letters currently in the hand.
For example:
>>> displayHand({'a':1, 'x':2, 'l':3, 'e':1})
Should print out something like:
a x x l l l e
The order of the letters is unimportant.
hand: dictionary (string -> int)
"""
for letter in hand.keys():
for j in range(hand[letter]):
print letter, # print all on the same line
print '' # print an empty line
Now, I want to print the following:
Current hand: a b c
To do this, I try to do:
print "Current hand: ", displayHand({'a':1, 'b':1, 'c':1})
And I get:
Current hand: a b c
None
I know that None is printed cause I am calling the print function on the displayHand(hand) function, which doesn't return anything.
Is there any way to get rid of that "None" without modifying displayHand(hand)?
if you want to use your function in a print statement, it should return a string and not print something itself (and return None) - as you would do in a __str__ method of a class. something like:
def displayHand(hand):
ret = ''
for letter in hand.keys():
for j in range(hand[letter]):
ret += '{} '.format(letter) # print all on the same line
# ret += '\n'
return ret
or even
def displayHand(hand):
return ''.join(n*'{} '.format(k) for k,n in hand.items() )
When you trail a print with a ,, the next print will appear on the same line, so you should just call the two things on separate lines, as in:
def printStuff():
print "Current hand: ",
displayHand({'a':1, 'b':1, 'c':1})
Of course you could just adapt this and create a method like:
def printCurrentHand(hand):
print "Current hand: ",
displayHand(hand)
The only way to do this (or I believe the only way to do this) is to use return instead of print in your displayhand() function. Sorry if I didn't answer your question.
Your function 'displayHand' does not have to print the output,
it has to return a string.
def displayHand(hand):
mystring=''
for letter in hand.keys():
for j in range(hand[letter]):
mystring+= letter # concatenate all on the same line
return mystring
BUT, you have to check the '.keys' command help as the order of the input (a/b/c) may not be respected

Converting integers for loop in Python - Loop ignores function value?

I'm working on a number guessing game and can't seem to get my loop to work while utilizing a function. I was manually typing out conversion under each if/elif in the block, but that was tedious and only checking for integers - string inputs couldn't read and broke the system.
I tried creating a conversion function to check the values and determine if it was an integer or string and change the variable type accordingly. However this results in an infinite loop fo line 18.
Can someone point out what I'm doing wrong here?
Heads up, I do have the random.py script from Python.org and am importing it so the game plays differently each time.
from random import randint
print 'Hello, my name is Skynet. What\'s yours?'
myName = raw_input()
print 'Good to meet you, ' + myName + '! Let\'s play a game.'
print 'I\'m thinking of a number between between 1 and 20, can you guess it?'
pcNum = randint(1,20)
myNum = raw_input()
def checkNum(myNum):
try:
int(myNum)
except ValueError:
returnVAL = 'That\'s not a number I know, try again.'
else:
returnVAL = int(myNum)
return returnVAL
while myNum != pcNum:
if myNum > pcNum:
print 'That\'s too high! Try again.'
myNum = raw_input()
checkNum(myNum)
else:
print 'That\'s too low! Try again.'
myNum = raw_input()
checkNum(myNum)
if myNum == pcNum:
print 'Good job, my number was ' + str(pcNum) + ' too! Good job, ' + myName
Any input is appreciated. I did some browsing here and got some a better idea of how to pull this off, or so I thought, and now here I am asking. First post!
print "I'm thinking of a number between between 1 and 20, can you guess it?"
while True:
guess = raw_input("What's your guess? ")
try:
guess = int(guess, 10)
except ValueError:
print "That's not a number I know, try again."
continue
if guess == pcNum:
...
break
elif guess > pcNum:
...
else:
...
Don't mix responsibilities. It is wrong to have myNum be both a number and an error message.
Also, think what you want to do when a user enters a non-number. In your case, the user's guess is "That's not a number I know, try again.", and it's being compared to pcNum; this makes no sense. If it was me, I would want the user to enter the number again. So rather than checkNum, I want input_valid_integer:
def input_valid_integer():
result = None
while result is None:
text = raw_input()
try:
result = int(text)
except ValueError:
print 'That\'s not a number I know, try again.'
return result