Can't get my count function to work in Python - python

I'm trying to create a function where you can put in a phrase such as "ana" in the word "banana", and count how many times it finds the phrase in the word. I can't find the error I'm making for some of my test units not to work.
def test(actual, expected):
""" Compare the actual to the expected value,
and print a suitable message.
"""
import sys
linenum = sys._getframe(1).f_lineno # get the caller's line number.
if (expected == actual):
msg = "Test on line {0} passed.".format(linenum)
else:
msg = ("Test on line {0} failed. Expected '{1}', but got '{2}'.".format(linenum, expected, actual))
print(msg)
def count(phrase, word):
count1 = 0
num_phrase = len(phrase)
num_letters = len(word)
for i in range(num_letters):
for x in word[i:i+num_phrase]:
if phrase in word:
count1 += 1
else:
continue
return count1
def test_suite():
test(count('is', 'Mississippi'), 2)
test(count('an', 'banana'), 2)
test(count('ana', 'banana'), 2)
test(count('nana', 'banana'), 1)
test(count('nanan', 'banana'), 0)
test(count('aaa', 'aaaaaa'), 4)
test_suite()

Changing your count function to the following passes the tests:
def count(phrase, word):
count1 = 0
num_phrase = len(phrase)
num_letters = len(word)
for i in range(num_letters):
if word[i:i+num_phrase] == phrase:
count1 += 1
return count1

Use str.count(substring). This will return how many times the substring occurs in the full string (str).
Here is an interactive session showing how it works:
>>> 'Mississippi'.count('is')
2
>>> 'banana'.count('an')
2
>>> 'banana'.count('ana')
1
>>> 'banana'.count('nana')
1
>>> 'banana'.count('nanan')
0
>>> 'aaaaaa'.count('aaa')
2
>>>
As you can see, the function is non-overlapping. If you need overlapping behaviour, look here: string count with overlapping occurrences

You're using the iteration wrong, so:
for i in range(num_letters): #This will go from 1, 2, ---> len(word)
for x in word[i:i+num_phrase]:
#This will give you the letters starting from word[i] to [i_num_phrase]
#but one by one, so : for i in 'dada': will give you 'd' 'a' 'd' 'a'
if phrase in word: #This condition doesnt make sense in your problem,
#if it's true it will hold true trough all the
#iteration and count will be
#len(word) * num_phrase,
#and if it's false it will return 0
count1 += 1
else:
continue

I guess, str.count(substring) is wrong solution, because it doesn't count overlapping substrings and test suite fails.
There is also builtin str.find method, which could be helpful for the task.

Another way :
def count(sequence,item) :
count = 0
for x in sequence :
if x == item :
count = count+1
return count

A basic question rais this times.
when u see a string like "isisisisisi" howmany "isi" do u count?
at first state you see the string "isi s isi s isi" and return 3 as count.
at the second state you see the string "isisisisisi" and counts the "i" tow times per phrase like this "isi isi isi isi isi".
In other word second 'i' is last character of first 'isi' and first character of second 'isi'.
so you have to return 5 as count.
for first state simply can use:
>>> string = "isisisisisi"
>>> string.count("isi")
3
and for second state you have to recognize the "phrase"+"anything"+"phrase" in the search keyword.
the below function can do it:
def find_iterate(Str):
i = 1
cnt = 0
while Str[i-1] == Str[-i] and i < len(Str)/2:
i += 1
cnt += 1
return Str[0:cnt+1]
Now you have many choice to count the search keyword in the string.
for example I do such below:
if __name__ == "__main__":
search_keyword = "isi"
String = "isisisisisi"
itterated_part = find_iterate(search_keyword)
c = 0
while search_keyword in String:
c += String.count(search_keyword)
String = String.replace(search_keyword, itterated_part)
print c
I do not know if a better way be in python.but I tried to do this with help of Regular Expressions but found no way.

Related

For loop in a function - not iterating through string

I'm looking to take in two strings via user input and to call a function to match each character from the first string to that of the second string, and count them. So String 1 = bad and String 2 = bed would return a count of 2 characters matched
def occurrences(text1, text2):
count = 0
for c in firstword :
if c == secondword :
count += 1
return True
return False
firstword = input("Enter first word")
secondword = input("Enter second word")
occurrences(firstword, secondword)
Passing the two strings into the function returns false, even if they're exactly the same word. Just wondering where I'm going wrong with the for loop here, why is the if statement not matching the strings and counting.
Thanks
for c in firstword :
if c == secondword :
You're iterating over the first string character by character (for c in firstword), and you match that one character to the entire second string secondword. Not to mention that:
you're using the outer variables firstword and secondword instead of the function parameters text1 and text2
your function only returns True or False, at no point does it even attempt to return a count
you return True right on the first match, if there ever was one, so it could never progress beyond 1
To compare two strings character by character, you need to iterate both string in parallel. The best way to do that is zip:
count = 0
for c1, c2 in zip(text1, text2):
if c1 == c2:
count += 1
Which can be made into a one-liner with sum:
def occurrences(text1, text2):
return sum(c1 == c2 for c1, c2 in zip(text1, text2))
Silly bonus round, if you want to be really fancy and functional about it:
from operator import eq
from itertools import starmap
def occurrences(text1, text2):
return sum(starmap(eq, zip(text1, text2)))
In function when you arrive on return, the function is ending so when you want counting and end of for-loop return your counter don't set return in for-loop.
try this:
def occurrences(text1, text2):
count = 0
for c in firstword :
if c in secondword :
count += 1
return count
firstword = input("Enter first word : ")
secondword = input("Enter second word : ")
occurrences(firstword, secondword)
output:
Enter first word : bad
Enter second word : bed
2

counting number of occurrence in string

I'm trying to count the number of times "bob" has occurred in a given string. this is what I tried:
s = input("give me a string:")
count = 0
for i in s:
if i=="b":
for j in s:
x=0
if j!="b":
x+=1
else:
break
if s[x+1]=="o" and s[x+2]=="b":
count+=1
print(count)
if I give the string "bob", it gives back 2, and if I give something like "jbhxbobalih", it gives back 0. I don't know why this happens. any idea?
The easiest manual count would probably use indeces and slices. The main difference between this and the much simpler s.count("bob") is that it also counts overlapping occurrences:
# s = "aboboba" -> 2
count = 0
for i, c in enumerate(s):
if s[i:i+3] == "bob":
count += 1
You can try checking 3 consecutive characters, if they are 'bob', just add our counter up, and do nothing otherwise.
Your code should be like this:
s = input("give me a string:")
count = 0
for i in range(0, len(s) - 3):
if s[i] == 'b' and s[i + 1] == 'o' and s[i + 2] == 'b':
count += 1
print(count)
100 % working this will work for all string.
import re
def check(string, sub_str):
count = 0
val = re.findall(sub_str, string)
for i in val:
count+=1
print(count)
# driver code
string = "baadbobaaaabobsasddswqbobdwqdwqsbob"
sub_str = "bob"
check(string, sub_str)
This gives the correct output.

How to count specific substrings using slice notation

I want to count the number of occurrences of the substring "bob" within the string s. I do this exercise for an edX Course.
s = 'azcbobobegghakl'
counter = 0
numofiterations = len(s)
position = 0
#loop that goes through the string char by char
for iteration in range(numofiterations):
if s[position] == "b": # search pos. for starting point
if s[position+1:position+2] == "ob": # check if complete
counter += 1
position +=1
print("Number of times bob occurs is: " + str(counter))
However it seems that the s[position+1:position+2] statement is not working properly. How do i adress the two chars behind a "b"?
The second slice index isn't included. It means that s[position+1:position+2] is a single character at position position + 1, and this substring cannot be equal to ob. See a related answer. You need [:position + 3]:
s = 'azcbobobegghakl'
counter = 0
numofiterations = len(s)
position = 0
#loop that goes through the string char by char
for iteration in range(numofiterations - 2):
if s[position] == "b": # search pos. for starting point
if s[position+1:position+3] == "ob": # check if complete
counter += 1
position +=1
print("Number of times bob occurs is: " + str(counter))
# 2
You could use .find with an index:
s = 'azcbobobegghakl'
needle = 'bob'
idx = -1; cnt = 0
while True:
idx = s.find(needle, idx+1)
if idx >= 0:
cnt += 1
else:
break
print("{} was found {} times.".format(needle, cnt))
# bob was found 2 times.
Eric's answer explains perfectly why your approach didn't work (slicing in Python is end-exclusive), but let me propose another option:
s = 'azcbobobegghakl'
substrings = [s[i:] for i in range(0, len(s))]
filtered_s = filter(substrings, lambda s: s.startswith("bob"))
result = len(filtered_s)
or simply
s = 'azcbobobegghakl'
result = sum(1 for ss in [s[i:] for i in range(0, len(s))] if ss.startswith("bob"))

Programming error in a basic python code

I am writing simple python code:
Question:
Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
Solution I worked:
def match_ends(words):
for items in words:
count = 0
los = len(items)
first_char= items[0]
last_char= items[los-1]
if los >=2 and first_char is last_char:
count = count+1
else:
count = count
print count
return
def main():
print 'match_ends'
match_ends(['aba', 'xyz', 'aa', 'x', 'bbb'])
I keep on Getting answer as 1 all the time, I think it is not looping entirely. Where is the error
another more concise way to do this is just:
sum(1 for s in words if len(s) > 1 and s[0] == s[-1])
I would use the == operator to compare the characters instead of the is keyword. Also you can use the [-1] index to slice from the back to get the last character instead of essentially doing [len-1]. You are also resetting the count to 0 at the beginning of each loop (also count is already a function name, try to avoid naming a variable with the same name)
That being said, here is the same idea with a few changes for readability and fixes for the above.
def matches(words):
total = 0
for word in words:
if (len(word) > 1) and (word[0] == word[-1]):
total += 1
return total
>>> matches(['aba', 'xyz', 'aa', 'x', 'bbb'])
3
The reason is that you need to place count = 0 before the line for items in words:

How to calculate and print the least and most occurring vowels in a string?

I am required to input a string, calculate the number of vowels in that string, and then calculate the most and least occurring vowels. When the string contains no vowels at all, a message should print saying "no vowels were entered". Where there are vowels which occur the same number of times (e.g. if a and e both occur twice ), these vowels should both appear as being most or least occurring. However, if some vowels are in the string but not all, then the ones which do not appear in the sting should be ignored (rather than printing "a=0"). I think the counting part at the start is correct to an extent, but not quite. As for the most/least occurrences, I don't even know where to begin. Any help would be appreciated!
myString = str(input("Please type a sentence: ").lower())
count = [0, 0, 0, 0, 0]
for vowel in myString:
if vowel == "a" :
count[0]=count[0]+1
if vowel == "e" :
count[1]=count[1]+1
if vowel == "i" :
count[2]=count[2]+1
if vowel == "o" :
count[3]=count[3]+1
if vowel == "u" :
count[4]=count[4]+1
while count[0] > 0:
print ("acount :",count[0])
break
while count[1] > 0:
print ("ecount :",count[1])
break
while count[2] > 0:
print ("icount :",count[2])
break
while count[3] > 0:
print ("ocount :",count[3])
break
while count[4] > 0:
print ("ucount :",count[4])
break
else:
if count[0] == 0 and count[1] == 0 and count[2] == 0 and count[3] == 0 and count[4] == 0:
print ("No vowels were found")
from collections import Counter
d = Counter(input("Enter Sentence:"))
print sorted("aeiou",key=lambda x:d.get(x,0))
seems like a much easier way to do it ...
Well, you've got a list, count, with 5 counts in it. How do you find out which count is the highest? Just call max on it:
>>> count = [7, 1, 3, 10, 2]
>>> max(count)
10
Now that you know the max is 10, how do you know which letters have counts of 10?
>>> max_count = max(count)
>>> for i, n in enumerate(count):
... if n == max_count:
... # use i the same way you use it above
You should be able to figure out how to do the minimum count as well.
But there's one extra problem for minimum count: it sounds like you want the minimum that's not 0, not the absolute minimum. I'd write it like this:
>>> min_count = min(x for x in count if x>0)
… or, maybe more compactly:
>>> min_count = min(filter(bool, count))
But I'm guessing you don't understand comprehensions yet. In which case, you'll need to explicitly loop over the values, keeping track of the minimum value(s) that aren't 0. This implementation of max should help guide you in the right direction:
def my_max(iterable):
max_value = None
for value in iterable:
if max_value is None or value > max_value:
max_value = value
return max_value
All that being said, this is one of many cases where using the right data structure makes the job a lot easier. For example, if you used a dictionary instead of a list, you could replace the whole first half of your code with this:
count = dict.from_keys('aeiou', 0)
for vowel in myString:
if vowel in 'aeiou':
count[vowel] += 1
Using a defaultdict or a Counter makes it even easier; then you don't need to explicitly initialize the counts to 0.
count=[0,0,0,0,0]
myString = str(input("Please type a sentence: ").lower())
for x in mystring:
flag = 'aeiou'.find(x)
if flag>=0:
count[flag] +=1
print max(count)
here find function will try to find the 'x' from aeiou if found return position of 'x` else return -1. so in flag i will get the position else -1

Categories