2

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()
Makoto
  • 104,088
  • 27
  • 192
  • 230
user1091975
  • 49
  • 1
  • 3
  • 6
  • 1
    What are the errors? P.S. please reduce the excess empty lines, to make your question more readable. Thank you. – Has QUIT--Anony-Mousse Jan 06 '12 at 13:53
  • Your iteration for x in word[] does not make sense to me. – Has QUIT--Anony-Mousse Jan 06 '12 at 13:54
  • Your variable names are very confusing. For example `num_phrase` is not the number of a phrase, but its *length.* `x` is *completely* non-descriptive. In my experience, sorting out the terminology tends to reveal problems in short order. – kindall Jan 06 '12 at 19:32

6 Answers6

5

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
MattH
  • 37,273
  • 11
  • 82
  • 84
  • Thanks. I don't know how I overlooked that. I guess I just make my function too complicated. – user1091975 Jan 06 '12 at 14:10
  • If you're searching for and/or in large strings there are several [algorithms](http://en.wikipedia.org/wiki/String_searching_algorithm) to speed up the search. – MattH Jan 06 '12 at 14:14
4

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

Community
  • 1
  • 1
D K
  • 5,530
  • 7
  • 31
  • 45
0

Another way :

def count(sequence,item) :

  count = 0

  for x in sequence :

     if x == item :
     count = count+1
  return count   
0

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   
Bogdan
  • 8,017
  • 6
  • 48
  • 64
0

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.

Roman Susi
  • 4,135
  • 2
  • 32
  • 47
-1

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.

Amin Jalali
  • 320
  • 1
  • 5
  • 15