I'm trying to make a mad libs program and am having trouble with .replace and don't know why its not working, I'm pretty new to coding and don't know too much.
import random
def main():
libs = input('Hello! Would you like to play MadLibs? Enter y or n: ')
libs = libs.lower()
while libs == 'y':
paragraph = madLibs()
para = replace(paragraph)
print(para)
libs = input('Would you like to play again? ')
libs = libs.lower()
if libs == 'n':
exit()
if libs != 'y' or 'n':
print('That is not a valid option')
main()
def madLibs():
madLibs = {1 : 'Today I went to the zoo. I saw a(n) ADJECTIVE jumping up and down in its tree',
2 : "I walk through the jungle. I take out my ADJECTIVE canteen.",
3 : 'The day I saw the Monkey King VERB was one of the most interesting days of the year.'}
randNum = random.randint(1, 3)
chosenLib = madLibs.get(randNum, 'Entry not found')
return chosenLib
def replace(para):
for line in para:
if 'ADJECTIVE' in para:
adj = str(input('Type an Adjective: '))
para.replace('ADJECTIVE', adj)
elif 'NOUN' in para:
noun = str(input('Type a Noun: '))
para.replace('NOUN', noun)
elif 'VERB' in para:
verb = str(input('Type a Verb: '))
para.replace('VERB', verb)
elif 'ADVERB' in para:
adv = str(input('Type an Adverb: '))
para.replace('ADVERB', adv)
return para
main()
The problem is in the replace function. Why is it not replacing?
The REPL can help elucidate what is happening:
>>> s = "ABC"
>>> t = s.replace("A","Alpha")
>>> s
'ABC'
>>> t
'AlphaBC'
>>>
Since you are just calling replace() and not saving the result, the original string is being returned.
That said, I think you also have a problem here:
def replace(para):
for line in para:
It's not made clear in your code, but I think you're actually passing a single string into replace, which means your for line in para is actually iterating through each character in the single line you pass in. Therefore, you will never match a full word. You can (dis)prove this by printing out what is coming into the function.
Using a simplified version of what you've written, we can see this in the REPL as well:
>>> def madLibs():
... return "Test ADJECTIVE string"
...
>>> def replace(para):
... for line in para:
... print(f"This is the line: {line}")
...
>>> paragraph = madLibs()
>>> replace(paragraph)
This is the line: T
This is the line: e
This is the line: s
This is the line: t
This is the line:
This is the line: A
This is the line: D
This is the line: J
This is the line: E
This is the line: C
This is the line: T
This is the line: I
This is the line: V
This is the line: E
This is the line:
This is the line: s
This is the line: t
This is the line: r
This is the line: i
This is the line: n
This is the line: g
Your code only replaces one items then returns. You want to keep replacing stuff until there's nothing to replace, and there's no point in doing things line by line. Also, input returns a string, so there is no point in passing it to str.
def replace(para):
while True:
if 'ADJECTIVE' in para:
adj = input('Type an Adjective: ')
para = para.replace('ADJECTIVE', adj)
continue
elif 'NOUN' in para:
noun = input('Type a Noun: ')
para = para.replace('NOUN', noun)
continue
elif 'VERB' in para:
verb = input('Type a Verb: ')
para = para.replace('VERB', verb)
continue
elif 'ADVERB' in para:
adv = input('Type an Adverb: ')
para = para.replace('ADVERB', adv)
continue
return para
There are better ways to do this by using a dict to avoid the multiple ifs. Here's an example that builds the prompt from the part of speech being requested.
def replace(para):
match = True
while match:
match = False
for part in ('ADJECTIVE','NOUN','VERB','ADVERB'):
if part in para:
rep = input('Type a ' + part.title() + ': ')
para = para.replace(part, rep, 1)
match = True
return para
Note that I added "1" to the replace call. That will limit it to replacing one thing at a time. Otherwise, if you had two VERBs in the paragraph, it would replace ALL occurrences of "VERB" with whatever was typed.
Looks like you have the return inside the loop in replace, so you're returning after only replacing one thing, skipping the rest.
Try bringing the return down an indentation level so you can go through all the lines before returning.
Related
This is my dictionary:
def get_dic(filename):
count = 0
db = {}
filename = "words.txt"
with open(filename, "r") as infile:
for line in infile:
if line:
eng_words, spa_words = line.rstrip().split(":")
key = eng_words
val = spa_words.split(",")
db[key] = val
count += 1
print(count, "entries found.")
return db
this is the file it reads from and converts it to a dictionary:
library:la biblioteca
school:el colegio,la escuela
restaurant:el restaurante
movie theater:el cine
airport:el aeropuerto
museum:el museo
park:el parque
university:la universidad
office:la oficina,el despacho
house:la casa
Now I wanna call my db and make a "quiz" game using random() method after user inputs a number from 1 to 10. Since my list is only 10 lines.
import random
def main():
db = get_dic(filename)
random.shuffle(db)
for keyword in db(10):
display = "{}"
print(display.format(keyword))
userinput = input("Enter 1 equivalent Spanish word(s). Word [1]: ")
print(db[keyword])
print(" ")
if userinput == (db[key]):
print("correct!")
correct += 1
If input is "5", how do I get the program to print 5 words?
And I wanna return the score "correct" into another function that is not main(). Which will later write the score to a seperate .txt file, Is this possible? Do I just "return correct" and call it in a function like usual? I've only seen codes call function in "def main():"
output example if input choosen is 2:
English word: museum
Enter 1 equivalent Spanish word(s). Word [1]: el museo
Correct!
---
English word: school
Enter 2 equivalent Spanish word(s). Word [1]: el colegio
Word [2]: la escuela
Correct!
This may be what you want. I ask the user how many rounds first. (I have not validated this input, though)
def main():
db = get_dic(filename)
keys = list(db.keys())
random.shuffle(keys)
rounds = int(input('Enter a number of rounds (1-10): '))
correct = 0
for keyword in keys[:rounds]:
print(keyword)
userinput = input("Enter 1 equivalent Spanish word(s). Word [1]: ")
print(db[keyword])
print(" ")
if userinput == (db[keyword]):
print("correct!")
correct += 1
return correct
correct = main()
print(f'{correct} answers correct')
to validate the input you can also do
def get_num(text,err_text,verify):
try:
the_input = int(input(text))
if verift(the_input):
return the_input
else:
print(err_text)
return get_num(text,err_text)
except:
print(err_text)
return get_num(text,err_text)
#...
rounds = get_num('Enter a number of rounds (1-10): ', 'please enter an integer between 1 and 10', verify=lambda x:x>0 and x <11)
i learn python and i do a discord bot. I have some difficulties to print the element after "anivia". i cant say if there is "anivia" in the 'texte' and i can count him but i don't know how to print the element after "anivia", if someone can help me please :)
#bot.command()
async def counter(ctx, *champion):
champion = " ".join(champion)
url = "https://u.gg/lol/champions/"
counter = "/counter"
uurl = url + champion + counter
await ctx.send(uurl)
import urllib.request
with urllib.request.urlopen(uurl) as response:
texte = response.read()
if ("anivia" in str(texte)):
print("Le mot existe !")
else:
print("Le mot n'existe pas!")
test = str(texte)
z = test.count('anivia')
print(z)
I can count 9 "anivia" with z and i want to print the next element after all the anivia (example: " hello i m anivia and i like anivia test": and, test).
Thanks for your help :)
If you're familiar with regular expressions (regex), this becomes very simple:
import re
# This pattern will capture the first word that comes after "anivia"
pattern = r'anivia (\w+)'
# Using this string as our example input
example_string = "anivia first anivia second and finally anivia third"
results = re.findall(pattern, example_string)
print(results) # Output: ['first', 'second', 'third']
Here is an approach that uses an auxiliary variable to mark when the next word needs to be printed.
test_string = "Hello, I am anivia on mid or anivia jungle"
do_print = False
splitted = test_string.split()
for word in splitted:
if do_print:
do_print = False
print(word)
if word == "anivia":
do_print = True
Output:
on
jungle
yeah, the those solution works with strings (i tried too with regex) but
do_print = False
splitted = test_string.split()
for word in splitted:
# print(word)
if do_print:
do_print = False
if word == "anivia":
do_print = True
test_string = str(texte)
do_print = False
splitted = test_string.split()
for word in splitted:
# print(word)
if do_print:
do_print = False
# print(word)
if word == "champion_id":
do_print = True``
on the first case i have the ("on" and the "jungle") but with my str(texte), that's doesn't fonction :S.
If someone knows why, the 2 test_strings are "strings"
^^ ty for your answers :)
My ideal goal is for the chat bot to recognize that you are talking about one of your siblings. So, when you mention your brother or sister (either by name or the keywords: my brother/sister) the chat bot will already know who they are from the data given in their text file. I have already figured out the keyword part, but when I mention them by name (For example: I can't stand James). The chat bot doesn't print what I want it to and when the user tells the chat bot their sibling's name it ends up printing both ("Oh, so your brother's name is") and ("I'll make sure to remember that, so what about " + brother_status['name'] + "?"). What can I do to fix this problem?
I have already tried this, but this doesn't seem to work either:
import string
user_input = raw_input("Please enter your sisters name: ").translate(string.maketrans("",""), string.punctuation)
with open('file.txt') as sibling_database:
if len(user_input.split()) >= 2:
for line in sibling_database:
for word in line.split(':'):
for words in user_input.split():
if words in word:
print("Oh, so your brother's name is " + line.split(':')[1])
Also here is my original code (In case you want to make any other changes):
import string
brother_status = dict([
('name', ''),
('nickname', ''),
('current age', ''),
('relationship', '')])
brother_keywords = ["Brother", "brother"]
sister_keywords = ["Sister", "sister"]
def main():
while True:
user_input = raw_input("What type of sibling do you have: ").translate(string.maketrans("",""), string.punctuation)
for keyword in brother_keywords:
if keyword in user_input:
with open('file.txt', 'r') as sibling_database:
for brother_data in sibling_database:
if brother_data.startswith("Brother's Name"):
print (brother_data.split(':')[1])
return
break
if user_input.split():
with open('file.txt') as sibling_database:
for line in sibling_database:
for word in user_input.split():
if word in line:
print("Oh, so your brother's name is " + line.split(':')[1] * 1)
return
break
if user_input.split():
for keyword in brother_keywords:
if keyword in user_input:
if user_input not in brother_status:
with open ('file.txt') as sibling_database:
first = sibling_database.read(1)
if not first:
print ("You never mentioned a brother. What's his name?")
user_input = raw_input("What's his name: ")
brother_status['name'] = (user_input)
with open('file.txt', 'w') as sibling_database:
sibling_database.write("Brother's Name:" + brother_status['name'] * 1 + '\n')
print ("I'll make sure to remember that, so what about " + brother_status['name'] + "?")
continue
if __name__ == "__main__":
main()
Your bigger problem is managing the state of your program.
Everyloop; you are testing all of your if, and them being true will get executed all the time, which is not what you want.
I would suggest to not rush steps too quickly, for instance I don't think if not first: does what you expect.
One way to help organise and manage that state is to use functions. Use plenty of them!
Then I would suggest going piece by piece : you need to figure out under what conditions you want each question/answer to appear in your code. If you're asking about a brother you don't know, then probably the code that talks about an unknown brother shouldn't be in the place. Or should have condition to guard the code from executing.
You'll probably get to a point where you'll have conditions all over the place, when that happens (and not before, or for curiosity) you should check out "state machines".
Side notes about python 3 :
Python 2 is becoming obsolete in 2020 and should not be used anymore. Systems will not ship with them, and people are expected to use python 3, and support for python 2 will stop.
This is not to say you shouldn't continue using python 2 as a learning tool, but you should think about learning python 3, you'll get more help more easily. Also there's a few cool features that python 2 doesn't have and you wouldn't want to miss out on that^^
I have updated your code with nltk pos tags to extract out the names from text file. Try it:
import string
import nltk
nltk.download('maxent_treebank_pos_tagger')
brother_status = dict([
('name', ''),
('nickname', ''),
('current age', ''),
('relationship', '')])
brother_keywords = ["Brother", "brother"]
sister_keywords = ["Sister", "sister"]
def main():
while True:
user_input = raw_input("What type of sibling do you have: ").translate(string.maketrans("",""), string.punctuation)
for keyword in brother_keywords:
if keyword in user_input:
with open('file.txt', 'r') as sibling_database:
data = sibling_database.readline()
data = nltk.word_tokenize(data)
tagged_data = nltk.pos_tag(data)
for name, pos in tagged_data:
if pos == "NNP":
print(name)
return
break
if user_input.split():
with open('file.txt') as sibling_database:
for line in sibling_database:
for word in user_input.split():
if word in line:
print("Oh, so your brother's name is " + line.split(':')[1] * 1)
return
break
if user_input.split():
for keyword in brother_keywords:
if keyword in user_input:
if user_input not in brother_status:
with open ('file.txt') as sibling_database:
first = sibling_database.read(1)
if not first:
print ("You never mentioned a brother. What's his name?")
user_input = raw_input("What's his name: ")
brother_status['name'] = (user_input)
with open('file.txt', 'w') as sibling_database:
sibling_database.write("Brother's Name:" + brother_status['name'] * 1 + '\n')
print ("I'll make sure to remember that, so what about " + brother_status['name'] + "?")
continue
if __name__ == "__main__":
main()
i created a function that takes in a word and checks it in a file containing all words from the dictionary , accepts the word if it is found else it prints an error message and ask for the word again
def getHiddenWord():
file = open('dictionary.txt')
found = False
while found == False:
hiddenWord = input('Enter the hidden word')
for word in file.readlines():
if word.strip().lower() == hiddenWord.lower():
found = True
return hiddenWord.lower()
break
else:
continue
print('I don\'t have this word in my dictionary please try another word')
if i wrote a correct word in the first input it works perfectly but and time after that it keeps looping as intended but it doesn't accept the input taking in consideration that if i wrote the same words the first input it will work and get accepted
file.readlines()
can be called only once, when you'll try to call it again on the same opened file it will fail.
Solution: before the loop read the lines and save them into a variable:
def getHiddenWord():
file = open('dictionary.txt')
lines = file.readlines() # <-- here
file.close() # <-- here
found = False
while found == False:
hiddenWord = input('Enter the hidden word')
for word in lines: # <-- and here
if word.strip().lower() == hiddenWord.lower():
found = True
print(hiddenWord.lower() + ' found!') # <-- here
break
else:
print('I don\'t have this word in my dictionary please try another word')
Further, as Óscar López mentioned in his (now deleted) answer: if you want the game to continue after a word was found you shouldn't return - just print "success" and break
A better way would be to convert the file into a set once and the just use in to check if the input is there:
def get_hidden_word():
with open('dictionary.txt') as fp:
words = set(w.strip().lower() for w in fp)
while True:
guess = input('Enter the hidden word').strip().lower()
if guess in words:
return guess
print("I don't have this word in my dictionary please try another word")
I need to replace 1 symbol in a string with a letter, like a decoder game, but with the code I have currently created. I need to develop the part of the program that when someone inputs a symbol and a letter it replaces the symbol with the letter and saves the list, then you keep doing this untill all the symbols have been replaced to create a word.
The list of encoded words:
#+/084&"
#3*#%#+
8%203:
,1$&
!-*%
.#7&33&
#*#71%
&-&641'2
#))85
9&330*
The List of words uncoded:
ACQUIRED
ALMANAC
INSULT
JOKE
HYMN
GAZELLE
AMAZON
EYEBROWS
AFFIX
VELLUM
Clues:
A#
M*
N%
Code:
#Import Section
import random
import string
class Game():
def __init__(self):
words_open = open('Words.txt')
self.words = (words_open.read())
self.fixwords = self.words
solved_open = open('solved.txt')
self.solved = (solved_open.read())
def menu_display(self):
#Display the menu
self.menud = (''' MENU
1. Start Game
2. Quit Game
Please select 1 or 2''')
self.menu()
def menu(self):
print self.menud
#ask player to choose an option
self.menu_choice = raw_input(" >>> ")
print
self.menu_options()
def menu_options(self):
#When menu option is selected
if self.menu_choice == '1':
self.s_game()
elif self.menu_choice == '2':
pass
else:
print "not valid input"
self.menu()
def s_game(self):
print 'Words:'
print self.words
self.clues()
def clues(self):
clue = raw_input('Do you want clues? please enter Yes or No '
'>>> ')
clue = clue.upper()
print clue
clues_open = open('clues.txt')
self.cluesclues = (clues_open.read())
if clue == 'YES':
print '''Words:
'''
print self.words
print 'Clues:'
print self.cluesclues
self.sorting()
elif clue == 'NO':
print self.words
self.sorting()
else:
print "input is not valid"
self.clues()
def sorting(self):
#if self.fixwords == 0:
#self.fixwords = (words_open.read())
#else:
#pass
self.symbol = raw_input("what symbol would you like to replace? >>> ")
if self.symbol in self.fixwords:
self.nletter = raw_input("that symbol is valid, what letter would you like to swap it with >>> ")
self.nletter.upper()
#self.fixwords.replace(self.symbol, self.letter[, max])
#self.fixwords.replace(self.symbol, self.nletter)
string.replace(self.fixwords, self.symbol, self.nletter.upper)
print self.fixwords
print self.cluesclues
self.prechange()
elif self.symbol not in self.fixwords:
print "That symbol is not valid or has already been changed"
self.sorting()
def prechange(self):
self.change = raw_input("Do you want to change a letter for another letter? yes or no >>> ")
self.change = self.change
if self.change == "yes":
self.changing()
elif self.change == "no":
self.sorting()
else:
print "that is not a valid input"
self.prechange()
def changing(self):
self.chanlet = raw_input("what letter would you like to replace? >>> ")
if self.chanlet in self.fixwords:
self.letchan = raw_input("that letter is valid, what letter would you like to swap it with >>> ")
self.fixwords = string.replace(self.fixwords, self.chanlet, self.letchan)
print self.fixwords
self.sorting()
elif self.chanlet not in self.fixwords:
print "That letter does not exist"
self.changing()
game = Game()
game.menu_display()
you can use replace() function. It can replace any character in a string even if it exists several times. All you have to do is each time a user select a symbol to replace and a letter, you loop on the list of encoded words and replace that symbol with the letter :
symbol = input("Enter the symbol to replace : ")
letter = input("Enter the letter : ")
for i in range(0, len(encoded_list)) :
encoded_list[i] = encoded_list[i].replace(symbol, letter, len(encoded))