It doesn't give anthing. Can someone help me about dictionaries and objects and classes in python? - python

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

Related

I am having troubles getting the list instead of an bound method

import random
from random import randint as rand
upperCase = chr(rand(65,66))
lowerCase = chr(rand(97,122))
class PasswordLetters:
def __init__(self):
pass
def generateCapitalCaseLetter(self):
uppCase = chr(rand(65,91))
return uppCase
def generateLowerCaseLetter(self):
lowCase = chr(rand(97,122))
return lowCase
def generateSpecialLetter(self):
specLet = random.choice(specialCharacters)
return specLet
def generateNumber(self):
num = rand(1,99)
class PasswordGenerator:
def __init__(self,uppCase,lowCase,specLet,num):
self.uppCaseList = []
lowCaseList = []
specLet = []
numList = []
self.passLetter = PasswordLetters()
for i in range(0,uppCase):
self.uppCaseList.append(self.passLetter.generateCapitalCaseLetter)
password = PasswordGenerator(1,1,1,1)
password.uppCaseList
So The Problem I am facing is when I try to get uppCaseList back from my password object it comes back to me as an method in a list instead of a letter in a list. I think the problem is in my PasswordLetters class but I can't figure it out.
The only thing I want is for
password.uppCaseList
to return a list with letters
Since it's a function you are calling, it would need to include the ( open and close ) parentheses. You may refer here for explanation.
for i in range(0,uppCase):
self.uppCaseList.append(self.passLetter.generateCapitalCaseLetter())

How to dynamically replace chars in a string with chars in another string having same structure based on condition?

I have a graph of dependencies where there's parent and child nodes. Child nodes have a # sign indicating that char/number is the same as the parent node. I understand the title might be weird, let me give you an example:
Initial reference variable:
ref = '12345.1.1'
Strings that will need replacing within:
example1 = '#.1.2'
example2 = '#.#.3'
Outcome after conversion/replacing (this is what I need help with):
# Make some magic, replace #'s with matching parent digits to get this output on string variables above:
example1 = '12345.1.2'
example2 = '12345.1.3'
In essence, how do I replace the # char (if present) to its matching "parent" stringified digits? I guess it might be able to work using replace or regex, but if there's any builtin methods that would work, I'd be happy to know.
Thanks in advance.
ref = '12345.1.1'
example1 = '#.1.2'
example2 = '#.#.3'
def replace(text, ref='12345.1.1', split='.', placeholder='#'):
ref = ref.split(split)
text = text.split(split)
return split.join(txt1 if txt2 == placeholder else txt2
for txt1, txt2 in zip(ref, text))
print(replace(example1))
print(replace(example2))
print(replace('#.#.#'))
output
12345.1.2
12345.1.3
12345.1.1
A bit cumbersome, but this should do it:
import re
class Replacement:
def __init__(self, ref):
self.ref = ref.split(".")
self.counter = 0
def repl(self, match):
if match.group() == "#":
res = self.ref[self.counter]
self.counter += 1
return res
return match.group()
example1 = '#.1.2'
example2 = '#.#.3'
for example in [example1, example2]:
r = Replacement(ref='12345.1.1')
result = re.sub("#", r.repl, example)
print(result)
Output
12345.1.2
12345.1.3
Note that you need to create a new Replacement object or restart the counter for each example in your input data.
Concise function
def replace_char(string: str, palce_holder: str = '#', split: str = '.') -> str:
return split.join((node[0] if node[1] == palce_holder else node[1] for node in zip(ref.split('.'), string.split('.'))))

In Python, how to set value for one __init__ variable based on another?

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.

Replacing multiple words in a string from different data sets in Python

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)

Feedback tester python

Hi for a given function I have 2 parameters which are string and an Int but I don't know which comes first. So I have a function "pick_type()" that tries to guess the order of the parameters. So my question is when "pick_type()" incorrectly guesses the order, how do I record this and make sure "pick_type()" never tries that specific order again ?
for iteration in range(0, 10):
args = []
print("\n def test%d(self):" % (iteration))
for input in range(num_arguments):
args += pick_type()
try:
result = target(*args)
code = test_to_string(target, args, result)
except TypeError as error:
code = test_to_string_exc(target, args, error)
for line in code.splitlines():
print(" "+line)
def pick_type():
lista = []
words = ['rhythms', 'rhythms', 'manager', 'training', 'hotel', 'destroy']
word = choice(words)
num = random.randint(-100, 100)
lists = [word,num]
choices = choice(lists)
if choices == word:
lista.append(word)
else:
lista.append(num)
return lista
I would suggest wrapping your method in a class, then you can have a persistent list of bad orders. It's not clear to me what you mean by an "order", but whatever it is, hopefully this pseudo-code helps:
class PickType:
def __init__(self):
self._bad_orders = []
def pick_type(self):
...# insert body here
if order in self._bad_orders:
## pick another order
## test the new order
if <order is bad>:
self._bad_orders.append(order)
## if your test for bad orders is performed outside pick_type(), you just need a method to add to the list of bad_orders
def add_bad_order(self, order):
self._bad_orders.append(order)

Categories

Resources