My method store_useful_words take some text and compare each word in the entered text and then compares those words to some keywords in my database. The impWords variable stores those words that match with the database from the sentence. I have imported WebOutput to my database file and I want to use the impWords list to iterate through. How do I use the impWords variable in the database file?
WebOutput.py file
import DatabaseInteractor
import nltk
db = DatabaseInteractor.DatabaseInteractor()
class WebOutput:
def __init__(self,text, impWords = None):
self.text= text
self.impWords = self.store_useful_words()
def store_useful_words(self):
keywords = db.get_keywords()
tweetWords = []
for word in self.text.split():
if word in keywords:
tweetWords.append(word)
return tweetWords
Just pass keyword to __init__ and then create instance of class. Code:
class WebOutput:
def __init__(self, text, keywords, impWords=None):
self.text = text
self.keywords = keywords
self.impWords = self.store_useful_words()
def store_useful_words(self):
tweetWords = []
for word in self.text.split():
if word in self.keywords:
tweetWords.append(word)
return tweetWords
# Using
db = DatabaseInteractor.DatabaseInteractor()
output = WebOutput('some_text', db.get_keywords())
for word in output.impWords:
print(word)
# ... do something else ...
Related
I've got a parent class and a child class. I want the child class to take the method from the parent class, perform a operation and apply it. What I'm trying to do is loop through a wordlist file in the parent class method openWordlist(), and for every word in that wordlist file, pass it to the child class method scanDomain() to perform an operation which is to loop through website directories that are available to the public.
class Main:
def __init__(self):
self.wordlistFile = ''
self.word = ''
def openWordlist(self):
with open(self.wordlistFile, 'r') as suppliedWordlist:
for word in suppliedWordlist:
word = word.strip()
self.word = word
class DirectoryScan(Main):
def scanDomain(self):
try:
self.cleanURL = 'https://google.com' + self.word
self.reqURL = requests.get(self.cleanURL)
if self.reqURL.status_code == 200:
print('Found: {self.cleanURL}')
elif self.reqURL.status_code != 200:
pass
except InvalidURL:
print(f'{self.targetURL} does NOT exist.')
if __name__ == '__main__':
s = Main()
d = DirectoryScan()
directoryScan.openWordlist()
directoryScan.scanDomain()
However, the result that I'm getting is just the https://google.com/ back. Is there something wrong with the inheritance that I'm doing?
The name of your input file is '', which can't be opened.
Thus, you never set self.word to anything except ''.
And even if you did open a file, you would only set self.word to the last word in the file.
Do what you say you want to do; "loop through a wordlist file in the parent class method openWordlist(), and for every word in that wordlist file, pass it to the [...] method scanDomain()"
class Main:
def __init__(self, filename):
self.wordlistFile = filename
def scanDomain(self, word):
pass
def openWordlist(self):
with open(self.wordlistFile, 'r') as suppliedWordlist:
for word in suppliedWordlist:
self.scanDomain(word.strip())
class DirectoryScan(Main):
def scanDomain(self, word):
try:
self.cleanURL = 'https://google.com/' + word
self.reqURL = requests.get(self.cleanURL)
if self.reqURL.status_code == 200:
print('Found: {self.cleanURL}')
elif self.reqURL.status_code != 200:
pass
except InvalidURL:
print(f'{self.targetURL} does NOT exist.')
if __name__ == '__main__':
d = DirectoryScan('somefile.txt')
d.openWordlist()
(The point of this inheritance structure is a mystery, though.)
I think your issue is here:
def openWordlist(self):
with open(self.wordlistFile, 'r') as suppliedWordlist:
for word in suppliedWordlist:
word = word.strip()
self.word = word
You are iterating over the suppliedWordList and set self.word = word.
But from the context I get, the suppliedWordList can be longer. So maybe your last line does not contain what you actually want to add there to your url.
I am trying to print frequencies of all words in a text.
I wanna print all keys according to their sorted values.
Namely, I wanna print the frequencies from most frequent to least frequent.
Here is my code:
freqMap = {}
class analysedText(object):
def __init__(self, text):
# remove punctuation
formattedText = text.replace('.', '').replace('!', '').replace('?', '').replace(',', '')
# make text lowercase
formattedText = formattedText.lower()
self.fmtText = formattedText
def freqAll(self):
wordList = self.fmtText.split(' ')
freqMap = {}
for word in set(wordList):
freqMap[word] = wordList.count(word)
return freqMap
mytexte = str(input())
my_text = analysedText(mytexte)
my_text.freqAll()
freqKeys = freqMap.keys()
freqValues = sorted(freqMap.values())
a = 0
for i in freqValues:
if i == a:
pass
else:
for key in freqKeys:
if freqMap[key] == freqValues[i]:
print(key,": ", freqValues[i])
a = i
Your function freqAll returns a value that you are not catching.
It should be:
counts = my_text.freqAll()
Then you use the counts variable in the rest of your code.
freqAll method of your class does return freqMap which you should store but do not do that, therefore you are in fact processing empty dict freqMap, which was created before class declaration. Try replacing
my_text.freqAll()
using
freqMap = my_text.freqAll()
def __init__(self):
#self.data = []
self.random_word = random.choice(open("EnglishDictionary.txt").readlines()).strip()
self.length_notice = "The word you're guessing is {} letters long.".format(len(random_word))
This just returns the error: Name 'random_word' is undefined
You set self.random_word, not random_word, so you need to use self.random_word:
self.length_notice = "The word you're guessing is {} letters long.".format(len(self.random_word))
# Add self. ^^^^^
Just use it:
def __init__(self):
#self.data = []
with open("EnglishDictionary.txt") as f:
msg = "The word you're guessing is {} letters long."
self.random_word = random.choice(f).strip()
self.length_notice = msg.format(len(self.random_word))
Ask yourself, though, if self.random_word really needs to be an instance attribute, or if random_word can simply be a local variable inside the function, like msg.
I'm trying to implement an iterator class named CharCounter. This class opens a textfile and provides an iterator that returns words from the text file containing a user specified number of characters. It should output a word per line. Which is not what's it's doing, it's outputting the words as a list and then it continuously outputs 'a'. How can I fix my code?
class CharCounter(object):
def __init__(self, fileNm, strlen):
self._fileNm = fileNm
self._strlen = strlen
fw = open(fileNm)
text = fw.read()
lines = text.split("\n")
words = []
pwords =[]
for each in lines:
words += each.split(" ")
chkEnd = ["'",'"',",",".",")","("]
if words[-1] in chkEnd:
words = words.rstrip()
for each in words:
if len(each) == strlen:
pwords.append(each)
print(pwords)
def __iter__(self):
return CharCounterIterator(self._fileNm)
class CharCounterIterator(object):
def __init__(self,fileNm):
self._fileNm = fileNm
self._index = 0
def __iter__(self):
return self
def next(self):
try:
ret = self._fileNm[self._index]
return ret
except IndexError:
raise StopIteration
if __name__=="__main__":
for word in CharCounter('agency.txt',11):
print "%s" %word
Code posted on SO should not read a file unless the question is about reading files. The result cannot be duplicated and verified. (See MCVE.) Instead, define a text string as a stand-in for the file.
Your code prints the words of length n as a list because that is what you ask it to do with print(pwords). It repeatedly prints the first char of the filename because that is what you ask it to do in the __next__ method.
Your class __init__ does more than you describe. The attempt to strip punctuation from words does not do anything. The code below defines a class that turns a text into a list of stripped words (with duplicates). It also defines a parameterized generator method that filters the word list.
class Words:
def __init__(self, text):
self.words = words = []
for line in text.split('\n'):
for word in line.split():
words.append(word.strip(""",'."?!()[]{}*$#"""))
def iter_n(self, n):
for word in self.words:
if len(word) == n:
yield word
# Test
text = """
It should output a word per line.
Which is not what's it's doing!
(It outputs the words as a [list] and then continuously outputs 'a'.)
How can I fix my #*!code?
"""
words = Words(text)
for word in words.iter_n(5):
print(word)
# Prints
Which
doing
words
Essentially I have a python script that loads in a number of files, each file contains a list and these are used to generate strings. For example: "Just been to see $film% in $location%, I'd highly recommend it!" I need to replace the $film% and $location% placeholders with a random element of the array of their respective imported lists.
I'm very new to Python but have picked up most of it quite easily but obviously in Python strings are immutable and so handling this sort of task is different compared to other languages I've used.
Here is the code as it stands, I've tried adding in a while loop but it would still only replace the first instance of a replaceable word and leave the rest.
#!/usr/bin/python
import random
def replaceWord(string):
#Find Variable Type
if "url" in string:
varType = "url"
elif "film" in string:
varType = "film"
elif "food" in string:
varType = "food"
elif "location" in string:
varType = "location"
elif "tvshow" in string:
varType = "tvshow"
#LoadVariableFile
fileToOpen = "/prototype/default_" + varType + "s.txt"
var_file = open(fileToOpen, "r")
var_array = var_file.read().split('\n')
#Get number of possible variables
numberOfVariables = len(var_array)
#ChooseRandomElement
randomElement = random.randrange(0,numberOfVariables)
#ReplaceWord
oldValue = "$" + varType + "%"
newString = string.replace(oldValue, var_array[randomElement], 1)
return newString
testString = "Just been to see $film% in $location%, I'd highly recommend it!"
Test = replaceWord(testString)
This would give the following output: Just been to see Harry Potter in $location%, I'd highly recommend it!
I have tried using while loops, counting the number of words to replace in the string etc. however it still only changes the first word. It also needs to be able to replace multiple instances of the same "variable" type in the same string, so if there are two occurrences of $film% in a string it should replace both with a random element from the loaded file.
The following program may be somewhat closer to what you are trying to accomplish. Please note that documentation has been included to help explain what is going on. The templates are a little different than yours but provide customization options.
#! /usr/bin/env python3
import random
PATH_TEMPLATE = './prototype/default_{}s.txt'
def main():
"""Demonstrate the StringReplacer class with a test sting."""
replacer = StringReplacer(PATH_TEMPLATE)
text = "Just been to see {film} in {location}, I'd highly recommend it!"
result = replacer.process(text)
print(result)
class StringReplacer:
"""StringReplacer(path_template) -> StringReplacer instance"""
def __init__(self, path_template):
"""Initialize the instance attribute of the class."""
self.path_template = path_template
self.cache = {}
def process(self, text):
"""Automatically discover text keys and replace them at random."""
keys = self.load_keys(text)
result = self.replace_keys(text, keys)
return result
def load_keys(self, text):
"""Discover what replacements can be made in a string."""
keys = {}
while True:
try:
text.format(**keys)
except KeyError as error:
key = error.args[0]
self.load_to_cache(key)
keys[key] = ''
else:
return keys
def load_to_cache(self, key):
"""Warm up the cache as needed in preparation for replacements."""
if key not in self.cache:
with open(self.path_template.format(key)) as file:
unique = set(filter(None, map(str.strip, file)))
self.cache[key] = tuple(unique)
def replace_keys(self, text, keys):
"""Build a dictionary of random replacements and run formatting."""
for key in keys:
keys[key] = random.choice(self.cache[key])
new_string = text.format(**keys)
return new_string
if __name__ == '__main__':
main()
The varType you are assigning will be set in only one of your if-elif-else sequence and then the interpreter will go outside. You would have to run all over it and perform operations. One way would be to set flags which part of sentence you want to change. It would go that way:
url_to_change = False
film_to_change = False
if "url" in string:
url_to_change = True
elif "film" in string:
film_to_change = True
if url_to_change:
change_url()
if film_to_change:
change_film()
If you want to change all occurances you could use a foreach loop. Just do something like this in the part you are swapping a word:
for word in sentence:
if word == 'url':
change_word()
Having said this, I'd reccomend introducing two improvements. Push changing into separate functions. It would be easier to manage your code.
For example function for getting items from file to random from could be
def load_variable_file(file_name)
fileToOpen = "/prototype/default_" + file_name + "s.txt"
var_file = open(fileToOpen, "r")
var_array = var_file.read().split('\n')
var_file.clos()
return var_array
Instead of
if "url" in string:
varType = "url"
you could do:
def change_url(sentence):
var_array = load_variable_file(url)
numberOfVariables = len(var_array)
randomElement = random.randrange(0,numberOfVariables)
oldValue = "$" + varType + "%"
return sentence.replace(oldValue, var_array[randomElement], 1)
if "url" in sentence:
setnence = change_url(sentence)
And so on. You could push some part of what I've put into change_url() into a separate function, since it would be used by all such functions (just like loading data from file). I deliberately do not change everything, I hope you get my point. As you see with functions with clear names you can write less code, split it into logical, reusable parts, no needs to comment the code.
A few points about your code:
You can replace the randrange with random.choice as you just
want to select an item from an array.
You can iterate over your types and do the replacement without
specifying a limit (the third parameter), then assign it to the same object, so you keep all your replacements.
readlines() do what you want for open, read from the file as store the lines as an array
Return the new string after go through all the possible replacements
Something like this:
#!/usr/bin/python
import random
def replaceWord(string):
#Find Variable Type
types = ("url", "film", "food", "location", "tvshow")
for t in types:
if "$" + t + "%" in string:
var_array = []
#LoadVariableFile
fileToOpen = "/prototype/default_" + varType + "s.txt"
with open(fname) as f:
var_array = f.readlines()
tag = "$" + t + "%"
while tag in string:
choice = random.choice(var_array)
string = string.replace(tag, choice, 1)
var_array.remove(choice)
return string
testString = "Just been to see $film% in $location%, I'd highly recommend it!"
new = replaceWord(testString)
print(new)