Return the number of times that the string "code" appears anywhere in the given string, except we'll accept any letter for the 'd', so "cope" and "cooe" count.
count_code('aaacodebbb') → 1
count_code('codexxcode') → 2
count_code('cozexxcope') → 2
My Code
def count_code(str):
count=0
for n in range(len(str)):
if str[n:n+2]=='co' and str[n+3]=='e':
count+=1
return count
I know the right code (just adding len(str)-3 at line 3 will work) but I'm not able to understand why str[n:n+2] works without '-3' and str[n+3]
Can someone clear my doubt regarding this ?
Say our str was "abcde".
If you didn't have the -3 in the len(str), then we would have an index of n going from 0,1,2,3,4.
str[n+3] with n being 4 would ask python to find the 7th letter of "abcde", and voila, an indexerror.
It is because the for loop will loop through all the string text so that when n is representing the last word. n+1 and n+2does not exist. Which it will tells you that the string index is out of range.
For example: 'aaacodebbb' the index of the last word is 9. So that when the for loop goes to the last word, n=9. But n+1=10 and n+2=11 index does not exist in your word. So that index 10 and 11 is out of range
loop for is an easy way to do that.
def count_code(str):
count = 0
for i in range(len(str)-3):
# -3 is because when i reach the last word, i+1 and i+2
# will be not existing. that give you out of range error.
if str[i:i+2] == 'co' and str[i+3] == 'e':
count +=1
return count
Related
I'm trying to polish my Python skills and this made me confused. Here's the code:
greeting = 'Hello!'
count = 0
for letter in greeting:
count += 1
if count % 2 == 0:
print(letter)
print(letter)
print('done')
I don't understand what the count does.
this exact code doubles letters which position number is even.
count is for counting letter position.
condition count % 2 == 0 to know which position is divided by 2 without leftovers (check if position is even number)
Let's comment up the code with explanations of what each line does and then examine the output.
# assign the string 'Hello!' to the name greeting
greeting = 'Hello!'
# assign the number 0 to the name count
count = 0
# assign letter to each character in greeting one at a time.
# in the first run of the loop, letter would be 'H', then 'e',
# etc.
for letter in greeting:
# add one to count. count starts at 0, so after this line
# on the first run of the loop, it becomes 1, then 2, etc.
count += 1
# use the modulo operator (%) to get the remainder after
# dividing count by 2, and compare the result to 0. this
# is a standard way of determining if a number is even.
# the condition will evaluate to True at 0, 2, 4, etc.
if count % 2 == 0:
# when count is even, print letter once followed by a
# new line. note that to not print a new line, you can
# write print(letter, end="")
print(letter)
# print letter once followed by a new line regardless of the
# value of count
print(letter)
# print 'done' followed by a new line
print('done')
So, based on all that, what should we expect the output to be? Well, we know that every character of greeting will be printed in the last line of the loop. We also know that every even character of greeting will be printed twice, once inside the if block, and once at the end of the loop. Finally, we know that "done" will be printed after the loop is complete. Therefore, we should expect the following output:
H
e
e
l
l
l
o
!
!
done
This this is very simple see:
greeting = 'Hello!'
In this line you assigned the variable greeting a string value Hello!.
count = 0
In this line you assigned the variable count a integer value 0.
Now the next code is:
for letter in greeting:
count += 1
if count % 2 == 0:
print(letter)
print(letter)
As you may know strings are iterable. See this code before understanding the above:
for letter in greeting:
print(letter)
Forget the count. At each iteration of the loop the loop is printing every character of the greeting.
so the output is:
H
e
l
l
o
!
But why there a newline after each letter. The answer is that print has an optional argument end If the above code is like this:
for letter in greeting:
print(letter, end = '')
Then the output will be:
Hello!
Now there comes the count term. It is also simple. when the count is even it prints the letter iterating at that time in loop twice due to twice print statement. And the count is even or not is checked by if count % 2 == 0.
Sarah has just learned to type and go online. As soon as he entered the internet, he decided to enter a chat room and greet everyone. Sarah entered a word in the chat room. If it is possible to delete some letters of the word that Sarah entered and the word hello remains at the end, it means that Sara could say hello otherwise.
It is guaranteed that the input consists only of lowercase English letters.
I try this
input ahhellllloou
output YES
input hlelo
output NO
def isany(str,list):
for c in list:
if c in str:
return "yes"
return "no"
List=['h','e','l','l','o']
Str='hlelo'
print(isany(Str,List))
Consider below code -
def isany(st, lst):
last_idx = 0
for c in lst:
idx = st[last_idx:].find(c) # find the character in the sub string
if -1 == idx: # character not found
return "no"
last_idx += idx + 1
return "yes"
Now for example take the input hlelo.
In the first iteration, c holds value 'h'. So, the substring becomes st[0:] (as last_index was 0) which means the whole string. We find 'h' in that string and got back index 0. So, we update last_index as 1, because we should search from index 1 in the next iteration.
In the next iteration, the substring (i.e. st[last_index:]) becomes st[1:] or "lelo". We find 'e' in that and got idx as 1. Keep in mind that here idx represents the index of the substring (i.e. "lelo") and not the input string (i.e. "hlelo"). So the next index we should search from is idx + 1 after the last_index.
The code runs until the loop exits or the idx becomes -1 when the character is not found and returns result appropriately
string = input()
for i in range(len(string)):
if i % 3 == 0:
final = string.replace(string[i], "")
print(final)
I was asked the question: "Given a string, delete all its characters whose indices are divisible by 3."
The answer for the input Python is yton. However, my code gives Pyton.
The code makes sense to me but I'm a beginner. Any help?
The problem is that while you are looping, you are overriding the final variable every time the index is divisible by 3.
Instead, try defining the final variable before you start the loop, and add the letters as you loop over them, and only when they their index is NOT divisible by 3 (thus, ignoring the ones where the index IS divisible by 3).
Something like this should work:
string = input()
final = ""
for i in range(len(string)):
if i % 3 != 0:
final += string[i]
print(final)
In your current code, final is used through each iteration of the loop. It continues updating by replacing one character. In each iteration, final is replaced by a different string with one letter from string removed. After the loop has completed, it effectively only replaced one letter, which in this case is "h".
Use this instead (thanks to Mateen Ulhaq for the idea):
print("".join(x for i, x in enumerate(input()) if i % 3 != 0))
string=input()
final=""
for i in range(len(string)):
if i % 3 != 0:
final+=string[i]
print(final)
In your code, the line final = string.replace(string[i], "") would run like this.
Supposing the input is "hellobaby":
i=0, final="ellobaby"
i=3, final="helobaby"
i=6, final="hellobby"
I am always plagued with problems that involve checking values for indices i and i+1 within a for loop. However, doing so causes IndexError. One solution is to use range-1 but often that fails to check the last index value.
For example, given the following problem:
Write a function that compares two DNA sequences based on the
following scoring scheme: +1 for a match, +3 for each consecutive
match and -1 for each mismatch.
I wrote the solution in the following way:
def pairwiseScore(seqA, seqB):
if len(seqA) != len(seqB):
return 'Length mismatch'
count = 0
for i in range(len(seqA)-1):
if seqA[i] == seqB[i] and seqA[i+1] == seqB[i+1]:
count += 3
elif seqA[i] == seqB[i]:
count += 1
else:
count -= 1
#print count
return "Score: {c:d}".format(c=count)
print pairwiseScore("ATTCGT", "ATCTAT")
When I run this, I get a score of 1. This is because the program's missing the last index. I can see this if I print the values:
A A
T T
T C
C T
G A
Score: 1
[Finished in 0.1s]
It should return a score of 2.
Another string to check:
pairwiseScore("GATAAATCTGGTCT", "CATTCATCATGCAA")
This should return a score of 4
How do I resolve such types of problems?
You need something like that
def pairwiseScore(seqA, seqB):
a=len(seqA)
if a != len(seqB):
return 'Length mismatch'
count = 0
for i in range(0,a):
if seqA[i] == seqB[i] and i+1<a and seqA[i+1] == seqB[i+1]:
count += 3
elif seqA[i] == seqB[i]:
count += 1
else:
count -= 1
return "Score: {c:d}".format(c=count)
print pairwiseScore("GATAAATCTGGTCT", "CATTCATCATGCAA")
Explanation:
Assuming the lengths are equal. The first element in a list starts with zero. That's why I'm using range(0,a). Then, if i+1<a equals to True, that means there is an element after seqA[i], so one can use seqB[i+1] as the lengths are equal.
Moreover, range(0,a) 'counts' from zero to a-1, where a=len( seqA ). In Python 2.7.x range returns a list that certainly consumes memory. If len(seqA) might be a very big number, I'd suggest to use xrange instead. In Python 3.x you don't need such a precaution.
This is happening because you're only checking the first len(seq)-1 digits. If you want to check all of the digits, you need to for loop through the entire range(len(seq)). To avoid getting an IndexError, place a check at the beginning of the for loop to determine whether you're at the last position. If you are, don't make the consecutive sequence check.
I am trying to count the number of times 'e' appears in a word.
def has_no_e(word): #counts 'e's in a word
letters = len(word)
count = 0
while letters >= 0:
if word[letters-1] == 'e':
count = count + 1
letters = letters - 1
print count
It seems to work fine except when the word ends with an 'e'. It will count that 'e' twice. I have no idea why. Any help?
I know my code may be sloppy, I'm a beginner! I'm just trying to figure out the logic behind what's happening.
>>> word = 'eeeooooohoooooeee'
>>> word.count('e')
6
Why not this?
As others mention, you can implement the test with a simple word.count('e'). Unless you're doing this as a simple exercise, this is far better than trying to reinvent the wheel.
The problem with your code is that it counts the last character twice because you are testing index -1 at the end, which in Python returns the last character in the string. Fix it by changing while letters >= 0 to while letters > 0.
There are other ways you can tidy up your code (assuming this is an exercise in learning):
Python provides a nice way of iterating over a string using a for loop. This is far more concise and easier to read than using a while loop and maintaining your own counter variable. As you've already seen here, adding complexity results in bugs. Keep it simple.
Most languages provide a += operator, which for integers adds the amount to a variable. It's more concise than count = count + 1.
Use a parameter to define which character you're counting to make it more flexible. Define a default argument for using char='e' in the parameter list when you have an obvious default.
Choose a more appropriate name for the function. The name has_no_e() makes the reader think the code checks to see if the code has no e, but what it actually does is counts the occurrences of e.
Putting this all together we get:
def count_letter(word, char='e'):
count = 0
for c in word:
if c == char:
count += 1
return count
Some tests:
>>> count_letter('tee')
2
>>> count_letter('tee', 't')
1
>>> count_letter('tee', 'f')
0
>>> count_letter('wh' + 'e'*100)
100
Why not simply
def has_no_e(word):
return sum(1 for letter in word if letter=="e")
The problem is that the last value of 'letters' in your iteration is '0', and when this happens you look at:
word[letters-1]
meaning, you look at word[-1], which in python means "last letter of the word".
so you're actually counting correctly, and adding a "bonus" one if the last letter is 'e'.
It will count it twice when ending with an e because you decrement letters one time too many (because you loop while letters >= 0 and you should be looping while letters > 0). When letters reaches zero you check word[letters-1] == word[-1] which corresponds to the last character in the word.
Many of these suggested solutions will work fine.
Know that, in Python, list[-1] will return the last element of the list.
So, in your original code, when you were referencing word[letters-1] in a while loop constrained by letters >= 0, you would count the 'e' on the end of the word twice (once when letters was the length-1 and a second time when letters was 0).
For example, if my word was "Pete" your code trace would look like this (if you printed out word[letter] each loop.
e (for word[3])
t (for word[2])
e (for word[1])
P (for word[0])
e (for word[-1])
Hope this helps to clear things up and to reveal an interesting little quirk about Python.
#marcog makes some excellent points;
in the meantime, you can do simple debugging by inserting print statements -
def has_no_e(word):
letters = len(word)
count = 0
while letters >= 0:
ch = word[letters-1] # what is it looking at?
if ch == 'e':
count = count + 1
print('{0} <-'.format(ch))
else:
print('{0}'.format(ch))
letters = letters - 1
print count
then
has_no_e('tease')
returns
e <-
s
a
e <-
t
e <-
3
from which you can see that
you are going through the string in reverse order
it is correctly recognizing e's
you are 'wrapping around' to the end of the string - hence the extra e if your string ends in one
If what you really want is 'has_no_e' then the following may be more appropriate than counting 'e's and then later checking for zero,
def has_no_e(word):
return 'e' not in word
>>> has_no_e('Adrian')
True
>>> has_no_e('test')
False
>>> has_no_e('NYSE')
True
If you want to check there are no 'E's either,
def has_no_e(word):
return 'e' not in word.lower()
>>> has_no_e('NYSE')
False
You don't have to use a while-loop. Strings can be used for-loops in Python.
def has_no_e(word):
count = 0
for letter in word:
if letter == "e":
count += 1
print count
or something simpler:
def has_no_e(word):
return sum(1 for letter in word if letter=="e")