How to print random items from a dictionary? - python

everyone. I'm trying to complete a basic assignment. The program should allow a user to type in a phrase. If the phrase contains the word "happy" or "sad", that word should then be randomly replaced by a synonym (stored in a dictionary). The new phrase should then be printed out. What am I doing wrong? Every time I try to run it, the program crashes. This is the error I get:
0_part1.py", line 13, in <module>
phrase["happy"] = random.choice(thesaurus["happy"])
TypeError: 'str' object does not support item assignment
Here is what I have so far:
import random
thesaurus = {
"happy": ["glad", "blissful", "ecstatic", "at ease"],
"sad": ["bleak", "blue", "depressed"]
}
phrase = input("Enter a phrase: ")
phrase2 = phrase.split(' ')
if "happy" in phrase:
phrase["happy"] = random.choice(thesaurus["happy"])
if "sad" in phrase:
phrase["sad"] = random.choice(thesaurus["sad"])
print(phrase)

The reason for your error is that phrase is a string, and strings are immutable. On top of that, strings are sequences, not mappings; you can index them or slice them (e.g., happy_index = phrase.find("happy"); phrase[happy_index:happy_index+len("happy")]), but you can't use them like dictionaries.
If you want to create a new string, replacing the substring happy with another word, use the replace method.
And there's no reason to check first; if happy isn't found, replace wil do nothing.
So:
phrase = phrase.replace("happy", random.choice(thesaurus["happy"]))
While we're at it, instead of explicitly looking up each key, you may want to loop over the dictionary and apply all the synonyms:
for key, replacements in thesaurus.items():
phrase = phrase.replace(key, random.choice(replacements))
Finally, notice that this code will replace all instances of happy with the same replacement. Which I think your intended code was also trying to do. If you want to replace each of them with a separately randomly-chosen synonym, that's a bit more complicated. You could loop over phrase.find("happy", offset) until it returns -1, but a neat trick might make it simpler: split the string around each instance of happy, substitute in a different synonym for each split part, then join them all back together. Like this:
parts = phrase.split("happy")
parts[:-1] = [part + random.choice(thesaurus["happy"]) for part in parts[:-1]]
phrase = ''.join(parts)

Generate a random number from (0..[size of list - 1]). Then, access that index of the list. To get the length of a list, just do len(list_name).

Related

check if string contains word in any variation

I'm trying to build a bad words filter in python (I accept non-coded answers, just need to know more about an algorithm that would work) and I need to know how I can check if a string, contains a specific word in any variation.
For example, let's say my bad word array is:
['others','hello','banana']
And the String I need to check is:
Thinking alike or understanding something in a similar way with others.
For now, I'm looping on the string by checking every time if any element of the array exists in the phrase, but what if I want to check variations of the array? Like 0th3rs,Oth3r5 for the first element? For now, I'm manually checking it by doing multiple if statements and replacing a with # etc... But this would not be good for a production code since I cannot prevent every scenario of character replacing, So I thought of something like an array of objects, where the index is the letter, like A which contains an array of its variations and check it dynamically in the string, but would this take too much time? Since it needs to check every type of word variation? Or is this achievable and usable in a real scenario?
Have you try using replace()?
For example:
input="0th3rs"
replace_pair={'0':'o','3':'e'}
for old, new in replace_pair.items():
input = input.replace(old, new)
print(input)
will give you "others"
You have to still provide the replacement pairs but that would be better than "if" statement.
I cannot prevent every scenario of character replacing
That's true. However, you can handle the majority of scenarios.
I would consider declaring a mapping of replacements and their meaning:
REPLACEMENTS_DICT = {
"#": "a",
"4": "a",
"3": "e",
"0": "o",
...
}
Then, before checking if a particular string is inside the bad_word_array, one should translate the string with regard to the replacement dict and then make a case-insensitive comparison:
def translate(word: str) -> str:
return "".join(REPLACEMENTS_DICT.get(c, c) for c in word).lower()
def is_bad_word(word: str) -> bool:
return translate(word) in BAD_WORDS
Example
BAD_WORDS = ["others", "hello", "banana"]
print(is_bad_word("0th3rs")) # True
print(is_bad_word("Oth3rs")) # True
For tokenizing the text into words you can use nltk.
import nltk
sentence = "Thinking alike or understanding something in a similar way with others."
words = nltk.word_tokenize(sentence)
for word in words:
assert is_bad_word(word)
can't you just extend your list of bad words to contain different variations?
bad_words = ["others", "0th3rs", "banana"]
text = "this is the text about bananas and 0th3rs"
for word in bad_words:
if word in text:
text = text.replace(word, "*flowers*")

Python - Capture string with or without specific character

I am trying to capture the sentence after a specific word. Each sentences are different in my code and those sentence doesn't necessarily have to have this specific word to split by. If the word doesn't appear, I just need like blank string or list.
Example 1: working
my_string="Python is a amazing programming language"
print(my_string.split("amazing",1)[1])
programming language
Example 2:
my_string="Java is also a programming language."
print(my_string.split("amazing",1)[1]) # amazing word doesn't appear in the sentence.
Error: IndexError: list index out of range
Output needed :empty string or list ..etc.
I tried something like this, but it still fails.
my_string.split("amazing",1)[1] if my_string.split("amazing",1)[1] == None else my_string.split("amazing",1)[1]
When you use the .split() argument you can specify what part of the list you want to use with either integers or slices. If you want to check a specific word in your string you can do is something like this:
my_str = "Python is cool"
my_str_list = my_str.split()
if 'cool' in my_str_list:
print(my_str)`
output:
"Python is cool"
Otherwise, you can run a for loop in a list of strings to check if it finds the word in multiple strings.
You have some options here. You can split and check the result:
tmp = my_string.split("amazing", 1)
result = tmp[1] if len(tmp) > 1 else ''
Or you can check for containment up front:
result = my_string.split("amazing", 1)[1] if 'amazing' in my_string else ''
The first option is more efficient if most of the sentences have matches, the second one if most don't.
Another option similar to the first is
result = my_string.split("amazing", 1)[-1]
if result == my_string:
result = ''
In all cases, consider doing something equivalent to
result = result.lstrip()
Instead of calling index 1, call index -1. This calls the last item in the list.
my_string="Java is also a programming language."
print(my_string.split("amazing",1)[1])
returns ' programming language.'

Python coding flaw for making acronyms

The code written below should give results like below. For example, if input is ' Lion head and Snake tail', output should be - 'LHAST'.
Instead the result is 'LLLLL'. Please check my code. If possible please suggest better practice and help me with better code.
Code is as follows:
#ask for Input
name = input('Input words to make acroname :')
#make all in caps
name = name.upper()
#turn them in list
listname = name.split()
#cycle through
for namee in listname:
#Get the first letter & type in same line
print(name[0],end="")
print()
input (' press a key to move out' )
You may correct your code. Instead of print(name[0]) you should use print(namee[0]) as you want to print the first letter of the word, not the original name.
A good practice is to name the variables the more descriptive you can so as to avoid such typos.
If you want to print the acronym in same line I would suggest to use below code to get variable acronym with the desired output:
phrase = raw_input('Input words to make acronym:')
phrase = phrase.upper()
list_words = phrase.split()
acronym = [word[0] for word in list_words]
acronym = "".join(acronym)
print acronym
You could use str.join with a generator-expression for a one-line solution to the problem:
>>> name = "Lion head and Snake tail"
>>> ''.join(i[0].upper() for i in name.split())
'LHAST'
why?
Well if we start from inside the generator, we are iterating through name.split(). The .split method of a str returns a list of all the different strings which have been found by splitting on what is passed into the method. The default character is a space and since we want the words, this is fine for us.
We then say that for each word i in this list, take the first character from the string with: i[0]. We then convert this to upper case with str.upper().
Then, the final step is to join all these characters together and that is done with the str.join method.
Simply:
print ''.join([P[0] for P in input('Input words to make acroname :').upper().split()])
Use input('') for python 3 and raw_input('') for python 2

Remove punctuation from list using for loop

I'm using python 2.7.13 and I'm stuck on an assignment. I'm completely new to python.
I'm supposed to remove punctuation from names in a list, this is the code that has been given to me:
import string
name = ""
result = []
persons = [["Lisa", "Georgia"],
["Chris", "New York"],
["Wes", "Oregon"],
["Jo-Ann", "Texas"],
["Angie", "Florida"]]
I want to print the exact same list, except "Jo-Ann" needs to be printed as "JoAnn". The assignment says that I need to check every character and if it's not a punctuation I need to add it to the variable "name". I'm completely lost; I have no idea how to do this with a for loop.
My teacher gave me some pointers:
for every letter in name
if letter is not a punctuation, add to variable "name"
print
This doesn't make things clearer for a complete newbie like me. Is there someone that can give me some pointers? I would very much appreciate it.
try this:
import string
new_persons = [[x[0].translate(None, string.punctuation), x[1]] for x in persons]
Explanation:
to remove punctuations from a string, we can use 'one-example'.translate(None, string.punctuation)
[... for x in persons] is a list comprehension (short-hand looping) to create a new list by using elements( assigned to x on every loop) in the list persons
Within a loop iteration, x is just the inner array of two elements. e.g. ["Jo-Ann", "Texas"]
x[0] is "Jon-Ann" and x[1] is "Texas"
[x[0].translate(None, string.punctuation), x[1]] means we create an array of two elements from x but with the punctuations removed from the first one.
I think this a pretty obvious and simple way how a beginner could do it.
import string
result = []
# Loop over the [name, state] pairs.
for [name, state] in persons:
# Make a new name by only keeping desired
# characters.
newName = ""
for letter in name:
if letter not in string.punctuation:
newName += letter
# Add to result.
result.append([newName, state])
It makes use of a few very handy Python tricks to know!
The first one is unpacking of composed values in a loop, in this case the [name, state] pairs. It roughly amounts to doing like
[a, b] = [1, 2]
to extract values from a list.
The second is implicit looping over characters in a string. If you write
for l in "word":
print(l)
you'll see that each letter is printed on a new line. Python automatically splits a string in characters.
Afterwards, you can start looking into list comprehensions.
get all punctuation marks in a string
use triple quotes for marking start and end of string
import string
punc_marks=string.punctuation
name = ''
for i in persons:
for j in i:
for k in j:
if k not in punc_marks:
name+=k
print(name+"\n")
Here is an example using your teacher's approach, basically what you should learn right now and what your teacher wants:
import string
name = ""
result = []
persons = [["Lisa", "Georgia"],
["Chris", "New York"],
["Wes", "Oregon"],
["Jo-Ann", "Texas"],
["Angie", "Florida"]]
for person in persons:
for every_letter in person[0]: # name
if every_letter not in string.punctuation: # check if it isn't a punctuation
name += every_letter # add it to name
result.append([name, person[1]]) # add the name with no punctuation to result
name = "" # reset name
print(result)
Please try to learn from this and not just copy and paste to your home work
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer(r'\w+')
tokenizer=tokenizer.tokenize(persons)

finding strings in one list and based on what it says, replacing it with strings from another list

basically I have a user enter a sentence
eg. "hello, how are you?"
and from a large list it replaces "are" with "am" and "you" with "I". to return:
"hello, how am i?"
problem is i have no idea how to do this.
so my list looks a bit like reflections = [["I, you"],["are","am]] ---> etc.
and so far i've got some code which collects raw input from the user and then calls this function to reply to it.
def reflects_users_string(reply):
reply_list = reply.split()
for _ in reply_list
if ????
????
????
else
print "i don't understand"
from what I understand (noob here) it turns the users input into a list and then compares each item in that list with items in the "reflections" list, then it replaces the identical string in one list with the string next to it eg. "are" with "am"
ive been playing with all sorts of ways to do this but just cant seem to figure it out
Try learning to use list comprehensions, it's a powerful way to filter out lists in make iterations.
Let's try to solve your problems with list comprehensions:
#first we need to create mappings in a dict for your reflections
reflect = {
'you': 'I',
'are': 'am'
}
# After we read user input
user_input = 'hello, how are you ?'
#Now look how we can replace all words in user_input from reflect with one line
reflected = [word for word in [reflect.get(key, key) for key in user_input.split()]]
print ' '.join(reflected)
Let's analyse the list comprehension:
First we split user input into a list user_input.split()
Then we iter through the user input words for key in
user_input.split()
For each word in user input words we query the reflect dict. Using
reflect.get(key, key) is a way to query the reflect dict for key
and if we can't find the key a default value of key is returned
instead.
Finally, we wrap all this comprehension with [word for word in [getting reflected words from user input and a default value of the same word if we can't find it's reflection]]
And Voila !
It's a good start so far. As for next step, make a big dict of all the mappings of words, look up each word in that dict, and replace it if it has a replacement.

Categories

Resources