For loop in a function - not iterating through string - python

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

Related

How to compare two strings by character and print matching positions in python

I want to compare two strings by character and then print how many times they have the same character in the same position. If I were to input 'soon' and 'moon' as the two strings, it would print that they match in 3 positions.
I've run into another problem where if the 2nd string is shorter, it gives me an error "string index out of range".
I tried
a = input('Enter string')
b = input('Enter string')
i=0
count = 0
while i<len(a):
if b[i] == a[i]:
match = match + 1
i = i + 1
print(match, 'positions.')
You have some extraneous code in the form of the 2nd if statement and you don't have the match incrementor in the first if statement. You also don't need the found variable. This code should solve the problem
# get input from the user
A = input('Enter string')
B = input('Enter string')
# set the incrementors to 0
i=0
match = 0
# loop through every character in the string.
# Note, you may want to check to ensure that A and B are the same lengths.
while i<len(A):
# if the current characters of A and B are the same advance the match incrementor
if B[i] == A[I]:
# This is the important change. In your code this line
# is outside the if statement, so it advances for every
# character that is checked not every character that passes.
match = match + 1
# Move to the next character
i = i + 1
# Display the output to the user.
print(match, 'positions.')
num_matching = 0
a = "Hello"
b = "Yellow"
shortest_string = a if len(a) <= len(b) else b
longest_string = b if shortest_string == a else a
for idx, val in enumerate(shortest_string):
if val == b[idx]:
num_matching += 1
print(f"In {a} & {b} there are {num_matching} characters in the same position!")
Simplifying my answer in light of #gog's insight regarding zip versus zip_longest:
string1 = "soon"
string2 = "moon"
matching_positions = 0
for c1, c2 in zip(string1, string2):
if c1 == c2:
matching_positions += 1
print(matching_positions)
Output:
3

Python: list index out of range when trying to compare two strings at index?

I have this function to check if a string contains three or more lowercase letters.
def lowerCaseValid(word):
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
i = 0
flag = 0
while i <= len(word):
j = 0
while j <= len(lowCharList):
if lowCharList[j] == word[i]:
flag += 1
j = 0
else:
j += 1
i += 1
if flag >= 3:
return True
In simple terms, I pass in a string (word) and create a list of acceptable characters (lowCharList).
Then, I set up a nested while loop that checks word[i] at every index of lowCharList, until it finds a match.
Then it resets lowCharList counter and adds 1 to flag, and moves on to word[i+1].
If it doesn't find a match by the time it reaches z, then it moves onto word[i+1] anyways.
For some reason, why I try my sample input in my main function.
def main():
word = 'corRe!33'
print(lowerCaseValid(word))
I get this error:
in lowerCaseValid
if lowCharList[j] == word[i]:
IndexError: list index out of range
Why is it throwing this error? Thank you.
using python's in operator is easier...
def lowerCaseValid(word):
cnt = 0
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
chars = lowCharList.pop ()
for ch in word:
if ch in chars:
cnt += 1
return cnt >= 3
or with using sets just 2 lines of code
def lowerCaseValid(word):
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
return len(set(lowCharList.pop()) & set(word)) >=3
or one liner with map and lambda
def lowerCaseValid(word):
return len(list(map(lambda x: x.islower, list(word)))) >=3
Another alternative approach using a list comprehension and string.ascii_lowercase instead of redefining the lowercase letters:
from string import ascii_lowercase
def lowerCaseValid(word):
return sum[x in ascii_lowercase for x in word] >= 3
How this works is that the list comprehension goes through each letter in word. The x in ascii_lowercase will return a boolean value of either True (1) or False (0), then sum up the Trues
Change
lowCharList = ['abcdefghijklmnopqrstuvwxyz']
to
lowCharList = list('abcdefghijklmnopqrstuvwxyz')
I believe this should help, since you have a list containing only 1 item, whereas this way, you create a list with 24 items (all different letters).
As heemayl pointed out in the comments, lowCharList is 1 element long! Now you have 2 options: make lowCharList an actual list (lowCharList = list ("abcd...")), or keep lowCharList a string, which will work just fine (remove the brackets in the definition.
Might I suggest another method: checking if str.islower count adds up to >=3. So:
lower_count = 0
for letter in word:
if letter.islower(): lower_count += 1
if lower_count >= 3: return True
Also, as suggested in the comments:
return len ([letter for letter in word if letter.islower()]) >= 3
would work (better than my answer, which is just the expanded form of it)

Write a Python function that accepts a string and calculate the number of upper case letters and lower case letters

Question:
Write a Python function that accepts a string and calculate the number of upper case letters and lower case letters.
Sample String : 'Hello Mr. Rogers, how are you this fine Tuesday?'
Expected Output :
No. of Upper case characters : 4
No. of Lower case Characters : 33
function:
def up_low(s):
for a in s:
u = u.count(a.isupper())
l = l.count(a.islowwer())
print(u, l)
why this one doesn't work?
You can use List comprehensions and sum function to get the total number of upper and lower case letters.
def up_low(s):
u = sum(1 for i in s if i.isupper())
l = sum(1 for i in s if i.islower())
print( "No. of Upper case characters : %s,No. of Lower case characters : %s" % (u,l))
up_low("Hello Mr. Rogers, how are you this fine Tuesday?")
Output:
No. of Upper case characters : 4,No. of Lower case characters : 33
You are understanding wrong the count function, count, first of all, is a string functrion, and as parameter take a string, instead of doing this, you can simply do:
def up_low(string):
uppers = 0
lowers = 0
for char in string:
if char.islower():
lowers += 1
elif char.isupper():
uppers +=1
else: #I added an extra case for the rest of the chars that aren't lower non upper
pass
return(uppers, lowers)
print(up_low('Hello Mr. Rogers, how are you this fine Tuesday?'))
4 33
Problem
why this one doesn't work?
Along with having syntax errors and run-time errors, you code's logic is quite a ways off. You are actual not doing what the question asked. You seem to be trying to count the number of uppercase characters in a single character. That's incorrect.
Let's look back over the question to implement this correctly:
Write a Python function that accepts a string and calculate the number of upper case letters and lower case letters. Sample String : 'Hello Mr. Rogers, how are you this fine Tuesday?' Expected Output : No. of Upper case characters : 4 No. of Lower case Characters : 33.
Ok, so we have a clear definition of our problem. Given a single string, count the number of lower case characters the string contains, and uppercase characters the string contains. Let's start writing our function.
First we should define a function:
def count_upper_and_lower(string):
I know we'll need two variables; How? Because we need one to count the uppercase letters, and one to count the lowercase letters. So let's initialize those:
def count_upper_lower(string):
lowercase_letter_count = 0
uppercase_letter_count = 0
Now what do we need? Well the problem says to count each letter in the string. It sounds like we need to iterate over each character in the string. So we should use a for loop:
def count_upper_lower(string):
lowercase_letter_count = 0
uppercase_letter_count = 0
for letter in string:
OK, so what logic do we need in our for loop? Well we need to first check if a letter is upper case. If it is, we need to increment uppercase_letter_count. If not, we'll then test if the character is lowercase. If so, we'll increment lowercase_letter_count. Otherwise, we'll do nothing. Here is what that would look like in code:
if letter.isupper():
uppercase_letter_count += 1
elif letter.islower():
lowercase_letter_count += 1
Let's add that to our for loop:
def count_upper_lower(string):
lowercase_letter_count = 0
uppercase_letter_count = 0
for letter in string:
if letter.isupper():
uppercase_letter_count += 1
elif letter.islower():
lowercase_letter_count += 1
And were done. All that's left to do is to print the values at the end of the function:
def count_upper_lower(string):
lowercase_letter_count = 0
uppercase_letter_count = 0
for letter in string:
if letter.isupper():
uppercase_letter_count += 1
elif letter.islower():
lowercase_letter_count += 1
print uppercase_letter_count, lowercase_letter_count
Demo
def count_upper_lower(string):
lowercase_letter_count = 0
uppercase_letter_count = 0
for letter in string:
if letter.isupper():
uppercase_letter_count += 1
elif letter.islower():
lowercase_letter_count += 1
print uppercase_letter_count, lowercase_letter_count
count_upper_lower("Hello Mr. Rogers, how are you this fine Tuesday?")
# Output: 4 33
count_upper_lower("The FAT Cat Moaned AlL day!")
# Output: 8 13
If people are posting code...
def up_low(s):
up = filter(str.isupper, s)
low = filter(str.islower, s)
return len(up), len(low)
In Python 3, each filter will need to be converted into a list or thrown into a sum(1 for _ in ...) expression:
def up_low(s):
counter = lambda f: sum(1 for c in s if f(c))
return counter(str.upper), counter(str.lower)
A bit late to the party, but for the sake of completeness:
import string
def up_low(s):
return (sum(map(s.count, string.ascii_uppercase)),
sum(map(s.count, string.ascii_lowercase)))
And to test it:
u, l = up_low('Hello Mr. Rogers, how are you this fine Tuesday?')
print("No. of Upper case characters : {}\nNo. of Lower case Characters : {}".format(u, l))
Which gives:
No. of Upper case characters : 4
No. of Lower case Characters : 33
A manual loop & count is probably faster, tho.
I think this is the easiest approach for a beginner.
def up_low(s):
a=list(s)
u=[]
l=[]
for x in a:
if x.isupper():
u.append(x)
elif x.islower():
l.append(x)
else:
pass
return u, l
u, l = up_low(s)
print(f'No. of Upper case characters: {len(u)}')
print(f'No. of Lower case Characters: {len(l)}')
One simple
def up_low(s):
c_upper = 0
c_lower = 0
for letters in s:
if letters.isupper():
c_upper += 1
elif letters.islower():
c_lower += 1
else:
pass
print("Total characters :",len(s.replace(" ", "")),"\nNo. of Upper case characters :",c_upper, "\nNo. of Lower case Characters :",c_lower)
INPUT
mystring = 'Hello Mr. Rogers, how are you this fine Tuesday?'
up_low(mystring)
OUTPUT
Total characters : 40
No. of Upper case characters : 4
No. of Lower case Characters : 33
def up_low(s):
u, l = [], []
for a in s:
if a.isupper():
u.append(a)
else:
l.append(a)
print(len(u), len(l))

Counting uppercase letters in a list excluding the first capital in a word

So my function must take a list of strings and return the total number of capital letters that appear in positions other than the beginning of a word. Also to break this problem into a sub problem, it needs a second function that takes a single word and returns the number of capital letters that appear in positions other than the beginning of that word. So far I have a function that works, but I have been told it needs to be done better and I am not quite sure how to do that.
def count_strange_caps(words):
if words[0].isupper():
count = abs(1 -sum(1 for c in words if c.isupper())
elif words[0].islower():
count = abs(sum(1 for c in words if c.isupper()))
return count
def total_strange_caps(words):
total_count = 0
for word in words:
if word[0].isupper():
total_count -= 1
for letter in word:
if letter.isupper():
total_count += 1
return total_count
My teacher told me to combine the two list comprehensions in count_strange_caps as they are basically the same code and use the code from count_strange_caps in the inner for loop for the second function.
print(total_strange_caps(["Five","FiVe","fIVE"]))
print(total_strange_caps(["fIVE"]))
print(count_strange_caps("fIVE"))
These are the types of tests it needs to pass and if anyone could help me with a solution using more rudimentary concepts it would be much appreciated. I can not use numpy if that makes a difference.
You may use str.isupper() and sum() to achieve this. Using these, the function definition of count_strange_caps() should be like:
def count_strange_caps(word):
return sum(my_char.isupper() for my_char in word[1:]) # word[1:] to skip the first character
Sample run:
>>> count_strange_caps('HeLlo')
1
>>> count_strange_caps('HeLLo')
2
>>> count_strange_caps('heLLo')
2
Also, your total_strange_caps() can be simplified using sum() as:
def total_strange_caps(words):
return sum(count_strange_caps(word) for word in words)
Sampl run:
>>> total_strange_caps(['HeLlo', 'HeLLo', 'heLLo'])
5
You can use string comprehension as follows:
def total_strange_caps(words):
total_count = 0
for letter in words[1:]:
if letter.isupper():
total_count += 1
return total_count
print total_strange_caps("AbCdE")
Output:
2

Can't get my count function to work in 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.

Categories