Multiple strings in one variable - python

Say, for example, I have some code that goes like this:
sentence = input("Enter input: ")
target_letter = "a" or "b" or "c"
print(sentence.index(target_letter))
My main aim is to get the program to print any of the target letters' minimum index in the sentence. However when the Boolean "or" operators are used here it only recognizes the first string in the variable. For example: If I type
Ice cream
The program should recognize the 'c' as the first valid string in the index and print "1" but it skips to 'a' and prints "7".
The same sort of problem arises with the "and" operator:
sentence = input("Enter input: ")
target_letter = "a" and "b" and "c"
print(sentence.index(target_letter))
This time the program only recognizes the last string in the variable instead, if I type:
Exactly
The program throws back "3" becuase c's index is 3 but the first letter is actually 'a' with index 2. And when the input had only a "b" in it out of the strings, the program threw an error because it was neither the first string or the last string.
How would this problem be fixed so that I could place multiple possible strings in a variable so that one of the strings in the variable would be recognized later in the program?

Let's examine the target_letter = "a" or "b" or "c" first.
>>> target_letter = "a" or "b" or "c"
>>> target_letter # will always return 'a' because 'a' is true.
'a'
>>> # The only string which will return false is the empty string '' or "".
A proposed solution
sentence = input("Enter input: ")
target_letters = ["a", "b", "c"]
for letter in sentence:
if letter in target_letters:
print(letter, 'was found at location in ',sentence.index(letter))
else:
print(letter, "was not found in sentence,", sentence)
Output
Enter input: Ice creeam
I was not found in sentence, Ice creeam
c was found at location in 1
e was not found in sentence, Ice creeam
was not found in sentence, Ice creeam
c was found at location in 1
r was not found in sentence, Ice creeam
e was not found in sentence, Ice creeam
e was not found in sentence, Ice creeam
a was found at location in 8
m was not found in sentence, Ice creeam
Process finished with exit code 0

One way to do this is with a regular expression that matches any of those characters.
import re
pattern = r'[abc]' # define regex that matches 'a' OR 'b' OR 'c'
sentence = 'Exactly'
m = re.search(pattern, sentence)
if m:
print(m.start())

Based on what I understood from your description, I guess, this should help.
sentence = input("Enter input: ")
for i in sentence:
if i in "abc":
print(i, " : ", sentence.index(i))

We can achieve this using next and a generator expression along with enumerate.
>>> s = "ice cream"
>>> next((i for i, ch in enumerate(s) if ch in "abc"), None)
1
enumerate gives us the index as we iterate over the string. The generator returns indices where the corresponding character is in "abc". Then we call next to get the first match or None is a match is not found.

Related

How to count words that end with a letter? (python)

I am a beginner and this is what I came up with so far. However, it does not output the correct number of words that end with "a" or "b." Any tips on how to correct this code?
names = input("Enter list of names: ")
name = names.split(" ")
num = len(name)
ab = ""
print("Number of words:", num)
for i in range(num):
if name[i] == ' ':
if name[i-1] == a:
ab.append() + " "
elif name[i-1] == b:
ab.append() + " "
a_b = ab.split(' ')
print("Number of words that end with a or b: ",len(a_b))
In Python boolean (True and False) are the same as the integers 1 and 0. This means you can use sum() to count True booleans. str.endswith() returns a boolean. This means you can just do this:
words = ["stab", "drama", "hello", "magma", "test"]
a_b = sum(word.endswith(('a', 'b')) for word in words)
# 3
z_c = sum(word.endswith(('z', 'c')) for word in words)
# 0
Any tips on how to correct this code?
Others have answered alternative, working solutions, but I want to try to point out the specific things wrong in your code snippet and tips to correct.
First here's a copy of your snippet with some simple debugging prints along with their output (running in python 3.10).
names = "Barry Lima Bab"
name = names.split(" ")
print(f"{name=}") # name=['Barry', 'Lima', 'Bab']
num = len(name)
print(f"{num=}") # num=3
ab = ""
print("Number of words:", num)
for i in range(num):
print(name[i]) # Barry -> Lima -> Bab
if name[i] == ' ':
if name[i-1] == a:
ab.append() + " "
elif name[i-1] == b:
ab.append() + " "
print(f"{ab=}") # ab=''
a_b = ab.split(' ')
print(f"{a_b=}") # a_b=['']
Breaking things down step by step like this is a great starting point for better understanding what's going on.
if name[i] == ' ': Notice the value of name[i] so this check never resolves to True meaning the code inside never runs
if the inner code did run, you'd hit a NameError: name 'a' is not defined. Did you mean: 'ab'? because a is undefined. Probably meant 'a' here. same for b
In my example, name[i-1] would be 'Bab' -> 'Barry' -> 'Lima' which is probably not what you're expecting. This is because you're getting the -1th, 0th, 1st items in name. to get the last letter from the name, you want name[i][-1] here
if you then get into either of the furthest inside conditions, you'd encounter AttributeError: 'str' object has no attribute 'append' which happens because append is for list not str. You couldchange ab to be a list to use this in which case you'd want ab.append(name[i]) or you can use string concatenation like ab += " " + name[i] or using str.concat
1 last note of interest, you may have noticed your code as-is really likes to return and say that there's 1 item. This is because the above issues always (if the program doesn't break) leaves ab == '' and ''.split(' ') => [''] and thus len(ab.split(" ")) => 1
1 tip that I think would help in code comprehension is that the name variable here is not a single name string like it implies. It's actually a list[str]. I'd probably denote the variables something more like names_str: str vs names: list[str] or raw_names vs names. Then just use something like for name in names: and not worry about indexes. You can also use name.endswith('a') instead of name[-1] == 'a' for better readability.
Eventually you can combine these into a list comprehension for maximal succinctness -> len([name for name in names if name.endswith('a') or name.endswith('b')]).
words = ["ab", "bab", "pa", "pap"]
result = 0
for word in words:
if word[-1] in "ab":
result += 1
print(result)
As a list comprehension:
words = ["word1a", "word2b", "word3", "word4", "word5a"] # ['word1a', 'word2b', 'word5a']
filtered_words = [word for word in words if word[-1] in "ab"]
filtered_words = [word for word in words if word.endswith(("a", "b"))] # better, if you have multiple endings you want to search for with different lengths
len(filtered_words) # 3
name[i-1] is the previous name in the list, not the last character of the current name in the loop.
There's no need to append the matching names to a string. If you just need the count of matches, increment a counter variable.
You need to put a and b in quotes to make them strings, not variables.
names = input("Enter list of names: ")
name = names.split(" ")
matches = 0
print("Number of words:", len(name))
for cur_name in name:
if cur_name.endswith('a') or cur_name.endswith('b'):
matches += 1
print("Number of words that end with a or b: ", matches)
Use the endswith string method to detect if the last letter is "a" or "b"
names = ["bob","boba","larry","curly","moe"]
count = 0
for name in names:
if name.endswith("a") or name.endswith("b"):
count += 1
print(f"{count=}") # count=2

How to extract unique substring from a string in Python, when comparing it against another string?

I have two strings, say 'a' and 'b'. I want to compare 'a' against 'b' and extract only the unique part of 'a'. I could simply check if 'b' is in a and extract. But the issue here is, either string 'a' or 'b' has randomly ignored whitespaces, thus making it slightly difficult.
Here is what I have done so far
a = "catsand dogs some other strings"
b = "cats and dogs"
a_no_space = a.replace(" ", "")
b_no_space = b.replace(" ", "")
if(b_no_space in a_no_space and len(a_no_space) > len(b_no_space)):
unique = a[b_no_space.index(b_no_space)+len(b_no_space):]
With this solution, I get the following result
s some other strings
I don't want that 's' in the beginning. How can I fix this in python?
Does using regex help here? If so how?
You can convert your search string to a regular expression where spaces are replaced by '\s*' which will accept any number of intermediate spaces between words (including no spaces):
a = "catsand dogs some other strings"
b = "cats and dogs"
import re
pattern = r"\s*".join(map(re.escape,re.split("\s+",b))) # r'cats\s*and\s*dogs'
r = re.sub(pattern,"",a) # ' some other strings'
Here is a solution that progressively slices the larger string according to the letters of the substring:
idx = 0
if len(a) > len(b):
for letter in b:
if letter in a and letter != " ":
a= a[a.index(letter) + 1:]
print(a)
else:
for letter in a:
if letter in b and letter != " ":
b= b[b.index(letter) + 1:]
print(b)

Removing 1 letter each time from the word

I am trying to make a program that asks for a word, and then prints it to the console multiple times, each time removing the first character until the word ends. Program also asks if the word should be printed as shown or backwards.
The printing action is the same regardless if the word should be printed forwards or backwards.
The output should be something like this:
Give a word: milkfloat
Print forward? (yes/no): yes
milkfloat
ilkfloat
lkfloat
kfloat
float
loat
oat
at
t
Give a word: hippopotamus
Print forward? (yes/no): no
sumatopoppih
umatopoppih
matopoppih
atopoppih
topoppih
opoppih
poppih
oppih
ppih
pih
ih
h
I am trying but I cant figure out how to do it. Can anybody help?
Use the input() function to get some input from the command line e.g.
word = input('Enter word: ')
print(word)
>>> Enter word:
>>> Enter word: dog
>>> 'dog'
Use the print() function to print strings e.g.
word = 'dog'
print(word)
>>> 'dog'
Use an if statement to evaluate a condition e.g.
word = 'dog'
if word == 'dog':
print('I love dogs!')
elif word == 'cat':
print('I am more of a dog person...')
else:
print('Do you not like animals?')
>>> I love dogs!
Use [] square brackets to slice strings into the pieces you want e.g.
word = 'dog'
print(word[:-1])
>>> 'do'
print(word[1:])
>>> 'og'
Use the len() function to work out the length of a string e.g.
word = 'dog'
print(len(word))
>>> 3
Use a for loop with range() to do something a certain number of times e.g.
for i in range(3):
print(i)
>>> 0
>>> 1
>>> 2
I'll leave the rest to you.
def printer(word):
for i in range(len(word)):
print(word[i::])
text = input("Give a word: ")
forward = input("Print forward? (yes/no): ")
if forward=="yes":
printer(text)
else:
printer(text[::-1])
So this is something that I've set a friend to do as an exercise to get more comfortable with python.
The exercise is called "word pyramids" and this is the answer that I came up with (so that they have something to refer to later if they get stuck):
def print_backwards_word_pyramid(word):
for i in range(0, len(word)):
if i == 0:
print(word[::-1])
else:
print(word[:i-1:-1])
return
and this will print, for the word "juice"
eciuj
eciu
eci
ec
e
But, if you want something a little bit more elegant, the back half can be done as:
def print_backwards_word_pyramid(word):
for i in range(0, len(word)):
print(word[i:][::-1])
return
... which if read from right to left (for those who need a hand with what this is telling python) says:
In reverse, the slice starting at the "i'th" character, of the string value of variable "word", print.

Detect Repetition In a Letter

I'm writing a Hangman Program, and I'm basically done, I'm just stuck on one part. So you have to detect repetition in your input, i got that part done, but then i messes up with words that have the same letter in it.
For Example:
The Word is apple:
when I input a, it says well done, the letter is in the word and prints a----
but when I input p, it says well done as well but only prints the first p, so the output looks like this ap---
but i want it to detect all p in the word, for example : app--
here are my codes for that part:
def getGuessedWord():
position = word.index(letter.lower())
global words
words = words[:position] + letter.lower() + words[position+1:]
print(words)
return words
You need to find all the positions of the letter in your word!
Iterate through your word(enumerate function returns the list of index and value) and check if the value is the letter your are searching for!
Then
modify your words string!
That is
def getGuessedWord(letter,words,word):
for position, ltr in enumerate(word):
if ltr == letter:
words = words[:position] + letter.lower() + words[position+1:]
print(words)
return words
word='apple'
words='-'*len(word)
while '-' in words:
words = getGuessedWord(raw_input('Enter a letter : '),words,word)
Output:
Enter a letter : l
---l-
Enter a letter : e
---le
Enter a letter : a
a--le
Enter a letter : p
apple
Hope it helps!
Given, for example:
letter = 'p'
word = 'apple'
With this list comprehension:
[x==letter for x in word]
You can detect where is a certain letter is, if it is at all, in this example it would return:
[False, True, True, False, False]
Which corresponds with the fact that only the second and third letters in apple are "p".
Because True is 1 in Python, the same happens with 0 and False. So, if you want a numeric value you can just sum the values in the list, by doing:
sum([x==letter for x in word])
You could try this to verify the previous statement:
>>> True == 1
True
>>> False == 0
True
For a more detailed/specific answer, I'll need more information about how it is implemented.

Find words in a sentence and its index position using a for loop

I am writing a code that prompts the user to enter a sentence which is then defined as str1 and then is prompted to enter a word defined as str2.
For example:
Please enter a sentence: i like to code in python and code things
Thank you, you entered: i like to code in python and code things
Please enter a word: code
I want to use a for loop to find str2 in str1 to print whether the word is or is not found, and if it has been found, the index position(s) of str2.
Currently I have this code:
str1Input = input("Please enter a sentence: ")
print("Thank you, you entered: ",str1Input)
str1 = str1Input.split()
str2 = input("Please enter a word: ")
if str2 in str1:
for str2 in str1:
print("That word was found at index position", str1.index(str2)+1)
else:
print("Sorry that word was not found")
Although, the outcome appears to print whether or not the index position was found but then prints the index position of every word inside the sentence. Also if I am searching of a certain word that appears twice in that sentence, it just prints the index position of the first time the word is seen in the sentence, for example:
Please enter a sentence: i like to code in python and code things
Please enter a word: code
Thank you, you entered: i like to code in python and code things
That word was found at index position: 1
That word was found at index position: 2
That word was found at index position: 3
That word was found at index position: 4
That word was found at index position: 5
That word was found at index position: 6
That word was found at index position: 7
That word was found at index position: 4
That word was found at index position: 9
If anyone could help me and anyone else attempting something similar to this that would be extremely helpful!
You can use a conditional list comprehension (it's like a for-loop):
>>> str1 = 'i like to code in python and code things'
>>> str2 = 'code'
>>> indices = [idx for idx, word in enumerate(str1Input.split(), 1) if word == str2]
>>> indices
[4, 8]
Giving you the indices of the matches. Then you can do whatever you like with those:
if indices:
for idx in indices:
print('word found at position {}'.format(idx)
else:
print('word not found')
Your attempt actually wasn't too bad but you did one mistake: for str2 in str1: this overwrites your str2 variable which holds the string to look for! Also index will always give you the first index of your variable so when you did str1.index(str2)+1 you looked for the first occurence of the currently investigated item! That's why you had That word was found at index position: 4 two times because it only looked for the first 'code'.
The documentation is always useful to read:
list.index:
Return the index in the list of the first item whose value is x. It is an error if there is no such item.
Use the enumerate python built-in function:
for index, word in enumerate(splitted_sentence):
if word == target_word:
print("Index: ", index)
docs: https://docs.python.org/3.3/library/functions.html#enumerate
UPD: list.index() method returns the lowest index of matching element. That's why you always get same index if your word appears twice in a sentence.
Check the docs on this as well: https://docs.python.org/3.6/tutorial/datastructures.html#more-on-lists
Just make sure to use comparisons in if/else statements and think about what your loop is doing.
Hope this is simple enough but effective:
EDIT: Add a counter rather than using ".index()". Just keeps it nice and basic:
str1In = "I like to code a few things and code a lot"
str2 = "code"
str1 = str1In.split()
indexCount = 0
for word in str1:
if word == str2:
print("Your word was found at index point",int(indexCount))
else:
print("Your word was not found at",int(indexCount))
indexCount += 1
Your problem is in for loop: you assign values from str1 to local variable str1 each iteration. It's called variable shadowing.
The solution is to use different variable name in loop declaration.
What you can do is make a list out of str1 and find where str2 occurs in the list. Here is the code:
str1 = "i like to code in python and code things"
str2 = "code"
the_indexes = []
the_new_list = [str1.split(' ')]
the_count = str1.count(str2)
if the_count > 0:
for i in range(len(the_new_list[0])):
if the_new_list[0][i] == str2:
the_indexes.append(i)
else:
print str2, " not found in the first sentence"
print "The indexes are: "
for i in the_indexes:
print i

Categories

Resources