How do I call .lower on a class object? - python

I have a class I've called Earthquake, and it has a location as a string, and a few other parts that aren't important to this question (I don't think).
I've written a function (filter_by_place) that iterates through a list of Earthquakes that I've passed it, and looks for a given word in each Earthquake location string. If the word is found in the Earthquake's location, then it adds that Earthquake to a list. My problem is that it cannot be case sensitive, and I'm trying to make it that way by looking for an all lowercase word in an all lowercase version of the location string.
def filter_by_place(quakes, word):
lst = []
for quake in quakes:
if word.lower in (quake.place).lower:
lst.append(quake)
return lst
I get an error saying "TypeError: argument of type 'builtin_function_or_method' is not itterable"
So, my question is: How do I get that string within the class to become lowercase just for this function so I can search for the word without worrying about case sensitivity?
I've already tried adding
if word.lower or word.upper in quake.place:
inside the for loop, but that didn't work, and I can understand why. Help?

You're getting the error because you're not actually calling the lower string function. I am guessing you're coming from ruby where this wouldn't be required.
Try:
def filter_by_place(quakes, word):
lst = []
for quake in quakes:
if word.lower() in quake.place.lower():
lst.append(quake)
return lst

You need to do word.lower(). You're missing the brackets. Happens all the time :)
Try this
def filter_by_place(quakes, word):
lst = []
for quake in quakes:
if word.lower() in quake.place.lower():
lst.append(quake)
return lst
Because you're using python, you might want to take a look at list comprehensions. You're code would then look something like this
def filter_by_place(quakes, place):
return [quake for quake in quakes if quakes.place.lower() is place]

Related

Checking input for the whole exact string in a list

So I'm creating a simple program to check the input for words contained in the list. I have something like this...
def function():
list = ["hell", "yeah"]
check_input = input("Sentence to check: ")
check_input.split()
check = any(item in check_input for item in list)
if check is True:
print("List word found!")
else:
print("Clean!")
The problem is I want it to check the input for the exact same string from the list. Not if the input contains just a part of it.
Basically: I want it so if the user types "hello world" into the input, check would return as false and print clean because "hello" isn't "hell".
I guess I need to use something different than any() function, but I can't come up with anything that would solve this.
Any ideas?
Your code is slightly wrong due to which it is not working correctly.
Replace check_input.split() with check_input=check_input.split()
Or use check_input = input("Sentence to check: ").split()

looping over optional arguments (strings) in python

I have lists of strings, some are hashtags - like #rabbitsarecool others are short pieces of prose like "My rabbits name is fred."
I have written a program to seperate them:
def seperate_hashtags_from_prose(*strs):
props = []
hashtags = []
for x in strs:
if x[0]=="#" and x.find(' ')==-1:
hashtags += x
else:
prose += x
return hashtags, prose
seperate_hashtags_from_prose(["I like cats","#cats","Rabbits are the best","#Rabbits"])
This program does not work. in the above example when i debug it, it tells me that on the first loop:
x=["I like cats","#cats","Rabbits are the best",#Rabbits].
Thisis not what I would have expected - my intuition is that something about the way the loop over optional arguments is constructed is causing an error- but i can't see why.
There are several issues.
The most obvious is switching between props and prose. The code you posted does not run.
As others have commented, if you use the * in the function call, you should not make the call with a list. You could use seperate_hashtags_from_prose("I like cats","#cats","Rabbits are the best","#Rabbits") instead.
The line hashtags += x does not do what you think it does. When you use + as an operator on iterables (such as list and string) it will concatenate them. You probably meant hashtags.append(x) instead.

Kaggle Python course Exercise: Strings and Dictionaries Q. no. 2

Here's the question,
A researcher has gathered thousands of news articles. But she wants to focus her attention on articles including a specific word. Complete the function below to help her filter her list of articles.
Your function should meet the following criteria:
Do not include documents where the keyword string shows up only as a part of a larger word. For example, if she were looking for the keyword “closed”, you would not include the string “enclosed.”
She does not want you to distinguish upper case from lower case letters. So the phrase “Closed the case.” would be included when the keyword is “closed”
Do not let periods or commas affect what is matched. “It is closed.” would be included when the keyword is “closed”. But you can assume there are no other types of punctuation.
Here's my ans(I want to solve this just using loops and ifs):
def word_search(doc_list, keyword):
"""
Takes a list of documents (each document is a string) and a keyword.
Returns list of the index values into the original list for all documents
containing the keyword.
Example:
doc_list = ['The Learn Python Challenge Casino', 'They bought a car, and a horse', 'Casinoville?']
word_search(doc_list, 'casino')
>>> [0]
"""
#non-course provided and my own code starts here.
k=0
print(doc_list,keyword)
for string in doc_list:
print(string)
for char in string:
if char.upper()==keyword[0] or char.lower()==keyword[0]:
print(char,string[string.index(char)-1])
if (string[string.index(char)-1]==" " or string[string.index(char)-1]=="" or string[string.index(char)-1]==".") and (string[string.index(char)+len(keyword)]==" " or string[string.index(char)+len(keyword)]=="" or string[string.index(char)+len(keyword)]=="."):
print(string[string.index(char)-1])
for k in range(len(keyword)):
print(k)
if string[string.index(char)+k].upper()==keyword[k] or string[string.index(char)+k].lower()==keyword[k]:
c=c+k
if len(c)==len(keyword):
x=[doc_list.index(string)]
return x
But after running the check code:
q2.check() #returns,
Incorrect: Got a return value of None given doc_list=['The Learn Python Challenge Casino', 'They bought a car, and a horse', 'Casinoville?'], keyword='casino', but expected a value of type list. (Did you forget a return statement?)
Here's what gets printed out after executing the code:
['The Learn Python Challenge Casino', 'They bought a car, and a horse',
'Casinoville?'] casino
The Learn Python Challenge Casino
C
C
They bought a car, and a horse
c
Casinoville?
C ?
The code is compiling successfully without syntax and other explicit errors. But I can't find any implicit bugs that's generating a wrong ans after struggling for 5+ hrs. please help!
If I remember correctly Kaggle courses also provide you with the solution which is the solution you should understand and use moving forward. Your code has many conditions and it will be tough to determine which of these conditions is not implemented correctly. Might as well check Kaggles' solution because you cant use this moving forward. Also the solution you have has a nested for-loop checking each letter one-by-one. That is extremely inefficient. Nice beginners attempt though :)
Here is the solution using regex
import re
def word_search(documents, keyword):
res=[]
for i,j in enumerate(documents):
if re.findall('\\b'+keyword+'\\b',j,flags=re.IGNORECASE):
res.append(i)
return res
As stated by the answer, your function should return a list. You are instead returning a None value, because at some points in your nested ifs you are going at the end of your function, in which is not specified any return. When you don't specify any return keyword at the end of your function, it will return None as default
By the way, python offers a lot of utils libraries, for example the str.index() method that return the string index if found in the original string
This I think is a better development of your solution:
def word_search(doc_list, keyword):
"""
Takes a list of documents (each document is a string) and a keyword.
Returns list of the index values into the original list for all documents
containing the keyword.
Example:
doc_list = ['The Learn Python Challenge Casino', 'They bought a car, and a horse', 'Casinoville?']
word_search(doc_list, 'casino')
>>> [0]
"""
my_list = []
for doc in doc_list:
curr_doc = doc.lower()
try:
curr_index = curr_doc.index(keyword.lower())
my_list.append(curr_index)
except:
my_list.append(None)
return my_list
print(word_search(['The Learn Python Challenge Casino', 'They bought a car, and a horse', 'Casinoville?'], 'casino'))
output: [27, None, 0]
As you can see, in my code I am returning a List at the end of the function definition, as requested from the problem
A better approach to solve this would be to use the method contains(). An example of its usage can be found here.
So the algorithm would become:
list_to_return = []
counter = 0
for item in doc_list:
if item.contains(word):
list_to_return.append(counter)
counter += 1
return list_to_return
def word_search(doc_list, keyword):
res = []
sum = 0
for i in range(len(doc_list)-1):
if(doc_list[i] == keyword):
sum=sum+1
res.append(doc_list[i])
return sum, res

AttributeError: 'function' object has no attribute 'replace'

I'm using this code to try to replace a character:
from another_test import test_once_more
test_once_more()
question = input("1 letter ")
for letter in question:
if letter == "a":
test_once_more.replace("1","a")
print (test_once_more)
This is the code I am using. All I want it to do is replace the 1 in this code.
def test_once_more():
print ("123456789")
and replace it with an "A"
You can't.
The function is printing something and returns None. There's no way to change that after the fact.
What you should do is have the function return a value and work on that:
def test_once_more():
return "123456789"
and then
from another_test import test_once_more
result = test_once_more()
question = input("1 letter ")
for letter in question:
if letter == "a":
result = result.replace("1","a")
print (result)
although I'm puzzled why you're using a for loop to iterate over a string that will be a single character (at least if your user follows your request)...
You have a very simple error here; test_once_more is the name of your function, while question is the name of your string. Try question.replace (and fix the other similar mistake).
P.S. strings cannot be mutated in Python, so you need to assign the result of calling replace to another variable in order to see the effect of calling replace().

Python: Choose random word from list then remove it

The question is to chooses a random word from a list of words you have defined, and then remove the word from the list. The computer should display a jumble of the word and ask the user to guess what the word is. Once the player has guessed the word, another random word should be selected from the list and the game continues until the list of words is empty.
When I run it, i have an error.
Traceback (most recent call last):
File "F:\Computer Science\Unit 3\3.6\3.6 #5.py", line 21, in <module>
word_jamble (random_word)
File "F:\Computer Science\Unit 3\3.6\3.6 #5.py", line 14, in word_jamble
word = list(word)
TypeError: 'list' object is not callable
This is my program
list = ['mutable', 'substring', 'list', 'array', 'sequence']
from random import shuffle
def word_jamble(word):
word = list(word)
shuffle(word)
print ''.join(word)
from random import choice
random_word = choice(list)
word_jamble (random_word)
user_input = raw_input("What's the word? ")
if user_input == choice(list):
del list[index(choice(list))]
You should change your first variable, list, to something else. It is being confused with the built-in list type, and your list object is of course not callable.
The main problem is the variable's name, list. Its a builtin type constructor's name. When you use say list, it shadows the builtin type's name. Apart from that, you can use pop method, like this, to get the random words out of the list easily
words_list = ['mutable', 'substring', 'list', 'array', 'sequence']
import random
while words_list:
print words_list.pop(random.randrange(len(words_list)))
It means exactly what it says:
TypeError: 'list' object is not callable
It is complaining about
word = list(word)
because at this point,
list = ['mutable', 'substring', 'list', 'array', 'sequence']
has already happened.
Once you make list a name for that particular list, it can no longer be a name for the built-in list class. A name only names one thing at a time.
There are a few basic problems with the code:
list = ['mutable', 'substring', 'list', 'array', 'sequence']
list is the list constructor. You should never name your variables after python keywords.
del list[index(choice(l))]
del is very rarely needed in python. My suggestion is that, if you're a begginner, you should forget about it entirely. The proper way of removing elements from lists is using either list.remove (based on element equality) or list.pop (based on index)
def word_jamble(word):
word = list(word)
shuffle(word)
print ''.join(word)
Here, you're using a function to achieve to distinct tasks: shuffling a word, and printing it. Generally, it's a good practice to make each function perform only a specific task - this leads to more reusable and organized code. Instead of printing the result inside the function, consider returning it, and printing it outside.
from random import shuffle
# some code
from random import choice
It's good practice to keep your imports together, and on the beggining of your program. If you're importing two elements from the same module, you can separate them using a comma:
from random import shuffle, choice
Finally, since you want to repeat the game until there are no words left, you need to use a cycle:
while len(word_list)>0: # can be written simply as "while len(word_list):"
#your code here

Categories