How to understand this loop program in Python - python

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.

Related

python showing string index out of range

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

How to use tally from loop outside of that loop

New to coding, sorry if the question is too simple.
I am trying to keep a tally of how many times a character in a certain string range appears. I want to use that tally, count, later and add it to different values, and other tallies. If I return it I can't seem to be able to reuse it. How would I be able to reuse the tally, but outside of the loop?
def function(word):
letters = 'abcdefgh'
while count < len(word):
for i in word:
if i in letters:
count += 1
return count
a = count + 5
print(a)
print(function('AaB5a'))
count should be 2, but how do I take it, and add it to other values, like a = count + 5? print(a) does not print 7, or anything.
Like most of the comments already covered, you should remove the return to the end, and also the while loop doesn't seem to be required (and in fact, appears to provide a wrong result).
Please let me know if this is not what you wanted, and I will correct it based on your input, but it does output 2 and prints 7 as you requested in OP
def function(word):
count = 0
letters = 'abcdefgh'
for i in word:
if i in letters:
count += 1
a = count + 5
print(a)
return count
First, you should probably not use the word function to name your function. I changed your sample to check_letters
You also want to create the variable count outside of the while loop so you can save the incremented count. At the end, return the count.
def check_letters(word):
letters = 'abcdefgh'
count = 0
while count < len(word):
for i in word:
if i in letters:
count += 1
return count
Once that is done, you can call the function and pass in your paramenter, it will return an int which in this case, you want to add 5. We're then saving the results to the variable
a = check_letters('AaB5a') + 5
print (a)
11
if you print the check letters, you'll get the return count to the output.
print (check_letters('AaB5a'))
6
I set the count variable to zero because it throws UnboundLocalError: local variable 'count' referenced before assignment. The function will return the count of the string passed in. The count is now returned by the function. You can then assign it to a variable and then add, subtract, etc., to that variable.
def function(word):
letters = 'abcdefgh'
count=0
while count < len(word):
for i in word:
if i in letters:
count += 1
return count
c=function('AaB5a')
a=c + 5
print(a)

Python newbie here-Python iterations

Python newbie here- could you please explain the following
greeting = 'Hello!'
count = 0
for letter in greeting:
count += 1
if count % 2 == 0:
print(letter)
print(letter)
print('done')
greeting = 'Hello!' <-- set greeting variable.
count = 0 <-- set count variable.
for letter in greeting: <-- this loop will loop six times because greeting contains of six character.
count += 1 <-- each times of loop will increase value of count by one.
if count % 2 == 0: <-- this line will print a index of character that % 2 = 0 (eg. 2%2 = 0, 4%2 = 0, ...)
print(letter)
print(letter) <-- this line will print any index of character of greeting. (ps. this line will error because indentation errors.)
print('done') <-- print 'done'.
So the result will be like this:
H e e l l l o ! ! done
Avoiding the indentation error, I am explaining what your code does.
In your program, you have initialized a variable named greeting with value "Hello!" and also a count with value 0.
greeting = 'Hello!'
count = 0
Thereafter a for loop us used which loop through the greeting i.e. till the end of each word Hello!. However, if you wanted to check it by yourself you can print the letter.
for letter in greeting:
print(letter)
Now coming to your problem where you've also incremented the value of count by 1 where the value increases by 1 on each loop execution.
Then you have a condition to check whether the number is even or not count % 2 == 0 followed by the print statement which executes upon the success of condition. This means the letter at the even position will only get printed.
That is what your program does.
greeting = 'Hello!' <-- set greeting variable.
count = 0 <-- set count variable.
for letter in greeting: <-- this loop will loop six times because greeting contains of six character.
count += 1 <-- each times of loop will increase value of count by one.
if count % 2 == 0: <-- this line will print a index of character that % 2 = 0 (eg. 2%2 = 0, 4%2 = 0, ...)
print(letter)
print(letter) <-- this line will print any index of character of greeting. (ps. this line will error because indentation errors.)
print('done') <-- print 'done'.

Testing string against a set of vowels - Python

This is a module in my program:
def runVowels():
# explains what this program does
print "This program will count how many vowels and consonants are"
print "in a string."
# get the string to be analyzed from user
stringToCount = input("Please enter a string: ")
# convert string to all lowercase letters
stringToCount.lower()
# sets the index count to it's first number
index = 0
# a set of lowercase vowels each element will be tested against
vowelSet = set(['a','e','i','o','u'])
# sets the vowel count to 0
vowels = 0
# sets the consonant count to 0
consonants = 0
# sets the loop to run as many times as there are characters
# in the string
while index < len(stringToCount):
# if an element in the string is in the vowels
if stringToCount[index] in vowels:
# then add 1 to the vowel count
vowels += 1
index += 1
# otherwise, add 1 to the consonant count
elif stringToCount[index] != vowels:
consonants += 1
index += 1
# any other entry is invalid
else:
print "Your entry should only include letters."
getSelection()
# prints results
print "In your string, there are:"
print " " + str(vowels) + " vowels"
print " " + str(consonants) + " consonants"
# runs the main menu again
getSelection()
However, when I test this program, I get this error:
line 28, in runVowels
stringToCount = input("Please enter a string: ")
File "<string>", line 1
PupEman dABest
^
SyntaxError: unexpected EOF while parsing
I tried adding a + 1 to the "while index < len(stringToCount)" but that didn't help either. I'm pretty new to python and I don't really understand what's wrong with my code. Any help would be appreciated.
I researched this error, all I found out was that EOF stands for end of file. This didn't help at all with resolving my problem. Also, I understand that sometimes the error isn't necessarily where python says the error is, so I double-checked my code and nothing seemed wrong in my eyes. Am I doing this the round-about way by creating a set to test the string elements against? Is there a simpler way to test if string elements are in a set?
Question resolved. Thank you to all!
Looks like you're using Python 2. Use raw_input(...) instead of input(...). The input() function will evaluate what you have typed as a Python expression, which is the reason you've got a SyntaxError.
As suggested use raw_input. Also you don't need to do this:
while index < len(stringToCount):
# if an element in the string is in the vowels
if stringToCount[index] in vowels:
# then add 1 to the vowel count
vowels += 1
index += 1
# otherwise, add 1 to the consonant count
elif stringToCount[index] != vowels:
consonants += 1
index += 1
# any other entry is invalid
else:
print "Your entry should only include letters."
getSelection()
Strings in Python are iterable, so you can just do something like this:
for character in stringToCount:
if character in vowelSet : # Careful with variable names, one is a list and one an integer, same for consonants.
vowels += 1
elif character in consonantsSet: # Need this, if something is not in vowels it could be a number.
consonants += 1
else:
print "Your entry should only include letters."
This should do just fine. Using a while is not necessary here, and very non-Pythonic imho. Use the advantage of using a nice language like Python when you can to make your life easier ;)
You can count the vowels like so:
>>> st='Testing string against a set of vowels - Python'
>>> sum(1 for c in st if c.lower() in 'aeiou')
12
You can do something similar for consonants:
>>> sum(1 for c in st if c.lower() in 'bcdfghjklmnpqrstvwxyz')
26
Also,
if stringToCount[index] in vowels:
should read
if stringToCount[index] in vowelSet:
Here's another way you could solve the same thing:
def count_vowels_consonants(s):
return (sum(1 for c in s if c.lower() in "aeiou"),
sum(1 for c in s if c.lower() in "bcdfghjklmnpqrstvwxyz"))
To wit:
>>> count_vowels_consonants("aeiou aeiou yyy")
(10, 3)
>>> count_vowels_consonants("hello there")
(4, 6)
Python truly is grand.
The errors in your file run as follows (plus some suggestions):
stringToCount = input("Please enter a string: ")
This should be raw_input if you want what the user typed in as a string.
stringToCount.lower()
The .lower() method returns a new string with its letters lowered. It doesn't modify the original:
>>> a = "HELLO"
>>> a.lower()
"hello"
>>> a
"HELLO"
vowelSet = set(['a','e','i','o','u'])
Here you could just as easily do:
vowelSet = set("aeiou")
Note you also don't strictly need a set but it is indeed more efficient in general.
# sets the vowel count to 0
vowels = 0
# sets the consonant count to 0
consonants = 0
Please, you don't need comments for such simple statements.
index = 0
while index < len(stringToCount):
You usually don't need to use a while loop like this in python. Note that all you use index for is to get the corresponding character in stringToCount. Should instead be:
for c in stringToCount:
Now instead of:
if stringToCount[index] in vowels:
vowels += 1
index += 1
You just do:
if c in vowels:
vowels += 1
elif stringToCount[index] != vowels:
consonants += 1
index += 1
# any other entry is invalid
Not quite right. You're checking that a character doesn't equal a set. Maybe you meant:
elif c not in vowels:
consonants += 1
But then there'd be no else case... Got to fix your logic here.
print "In your string, there are:"
print " " + str(vowels) + " vowels"
print " " + str(consonants) + " consonants"
The above is more pythonically written as:
print "In your string, there are: %s vowels %s consonants" % (
vowels, consonants)
# runs the main menu again
getSelection()
Not sure why you're calling that there - why not call getSelection() from whatever calls runVowel()?
Hope that helped! Enjoy learning this great language.
Bah, all that code is so slow ;). Clearly the fastest solution is:
slen = len(StringToCount)
vowels = slen - len(StringToCount.translate(None, 'aeiou'))
consonants = slen - vowels
...note that I don't claim it's the clearest... just the fastest :)

Count letters in a word in python debug

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")

Categories