Random character string as output - python

I’m trying to write code that draws a random synonym from a list.
Instead of that, I’m getting a random string of characters that seem to bear no relation to any of my code.
Here’s the main module code:
from output import *
import definitions
from responses import *
…
def respond(wordList):
output = ""
for word in wordList:
output = (output + " " + (random.choice(word)))
return output
def edison():
mood = ask("Hi, " + username + "! How are you today? ")
if mood.lower() in definitions.positive:
print(respond(['i_am', 'happy', 'to' 'hear', 'that']) + "!")
elif mood.lower() in definitions.negative:
print(respond(['i_am', 'sorry_unhappy', 'to' 'hear', 'that']) + "!")
…
edison()
Here’s the code for responses.py:
i_am = ["I am", "I'm"]
happy = ["cheerful", "delighted", "glad", "joyful", "joyous", "overjoyed", "pleased", "thrilled", "gleeful", "happy"]
sorry_unhappy = ["sorry"]
to = ["to"]
hear = ["listen to", "hear"]
that = ["that"]
Here’s a sample of my output:
Hi, Test User! How are you today? bad
m _ h h!

The problem is likely random.choice(word). word is an element of wordList, and a random choice from a string chooses a random letter. Try random.choice(wordList) instead.
If you want to concatenate the wordList as output, since it looks somehow like a sentence already, you could do this:
output = " ".join(wordList)

You weren't using the built in responses from `responses.py' but a fixed str response
Replace edison with:
def edison():
mood = ask("Hi, " + username + "! How are you today? ")
if mood.lower() in definitions.positive:
print(respond([i_am, happy, to, hear, that]) + "!")
elif mood.lower() in definitions.negative:
print(respond([i_am, sorry_unhappy, to, hear, that]) + "!")

Related

Why is wikipedia.summary(string) removing letters from my string?

I am working on a program that can search wikipedia given an input like: "Who is Elon Musk" - however, with his specific example (and others), when the variable is placed into wikipedia.summary(string), it removes the "l" in "Elon Musk". Attached is my function:
import wikipedia
import spacy
def search_wiki(self, search):
nlp = spacy.load('en_core_web_sm')
doc = nlp(search)
subject_phrase = get_subject_phrase(doc)
try:
results = wikipedia.page(str(subject_phrase)) #removes here
final = results
print(wikipedia.summary(final, sentences=1))
except wikipedia.exceptions.PageError:
results = wikipedia.search(str(subject_phrase))
print("\nDid you mean " + results[0] + "?\n")
possible = results[0]
if input() == "yes":
final = possible
print(final) #prints "Elon Musk"
print(wikipedia.summary(final, sentences=1)) #removes here too
else:
print("\nThese are the other searches that came up for " + str(subject_phrase) + ":\n")
for r in results:
print(r)
print("\nPlease type the result you want me to search for:\n")
final = input()
print(wikipedia.summary(final, sentences=1))
except wikipedia.exceptions.DisambiguationError as e:
print("I couldn't find anything for " + str(subject_phrase) + ". Here are some related results:")
for o in e.options:
print(o)
print("\nWhich of these did you mean?")
final = input()
print(wikipedia.summary(final, sentences=2))
print("\nWould you like to hear more about " + final + "?\n")
if input() == "yes":
print("\nYou can read more about " + final + " at " + wikipedia.page(final).url + "\n")
entry = wikipedia.summary(final, sentences=3)
return lambda: entry, True
else:
entry = wikipedia.summary(final, sentences=1)
return lambda: entry, False`
I am pretty stuck, I have the variable printing right before the call to wikipedia.summary(string), so I know that the variable is not changing on my end (or at least I think).

Python Loop Unable to interrupt

I'm making a curency converter, time converter and weather app for an year 12 computer sciences project. Im unable to interrupt the loop that is being used for the main menu/location selector.
Can anyone help?
The code is below.
##This program is intended to help travellers with date and currency conversions ##
##Changelog----->##
##V1 - Include code for Forex Converter, code modified from - https://www.w3schools.in/python/examples/real-time-currency-converter##
##V2 - Implement GUI##
##V2.1 - Implement Multiple Screens GUI##
##V3 - Remove all GUI aspects##
##V3.1 - Create initial loop##
##Import Modules##
from forex_python.converter import CurrencyRates
import time
import datetime
import python_weather
import asyncio
##Opening info##
##V3.1##
global enter
enter = 'GO'
while enter == 'GO':
print("========================================================================================================================================================================================")
print("")
print("Welcome to the Traveller Assisstant. This program is able to help you with currency conversions, date and time conversions and viewing weather details of your destination.")
print("")
print("========================================================================================================================================================================================")
time.sleep(2.5)
ori = str(input("Please enter your current country: "))
dest = str(input("Please enter your destination country: "))
time.sleep(5)
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
if check == 'YES':
enter = 'STOP'
elif check == 'NO':
print("Returning to Location Selector")
enter = 'GO'
##V1##
##Change Currency##
#cr = CurrencyRates()
#output = cr.convert(entry1, entry2, entry3)
#final = round(output, 2)
#print("THE FINAL AMOUNT IS:", final, c2)
A simple typo, that's all that was wrong.
In this line of code:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
You are attempting to use the method
.upper()
But your fatal flaw is that you forgot the parentheses.
I changed this:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
To this:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper()
And the code worked perfectly for me
EXPLANATION
In the original code, check could never be equal to 'YES' or 'NO', because of the typo;
.upper was never recognized as a strings' function and returned with this value:
<built-in method upper of str object at 0x105fec130>
.upper() on the other IS in fact a valid function for a string and returned with this value when it was supplied with the input of 'yes':
YES
If you need to exit from the loop when a condition is met you can achieve that easily by using break. So when your condition is met:
either add bellow enter = "STOP" the statement break or just replace enter = "STOP" for break
if check == 'YES':
enter = "STOP"
break
or
if check == 'YES':
break
both should work, I guess you could go with the first answer if you need to keep the state of the variable enter otherwise you could just use the second.
The problem with your original code is that you are missing a parenthesis on the declaration of the upper method in this line:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
instead it should be:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper()
if you don't add the parenthesis to upper() it means you are declaring the object method itself not triggering instead what the method actually does. (In this case making the string uppercase)

Using random.choice to print two words from a random line in a file

I'm currently making a music quiz game and I'm trying to select a random line and print the 2 variables I've already assigned in that line, however I can't find a good way to do this. Bellow you can see what I've done so far along with how linked 2 variables per line in the file. Thanks for any help!
This is how I'm adding variables to the different lines
Artist='Cold Play';Song1='Clocks'
file.write(Artist + " " + Song1 + "\n")
Artist='Beatles';Song1='Revolution'
file.write(Artist + " " + Song1 + "\n")
Artist='Pharrel Williams';Song1='Happy'
file.write(Artist + " " + Song1 + "\n")
Artist='Owl City';Song1='Fireflies'
file.write(Artist + " " + Song1 + "\n")
Artist='Oasis';Song1='Wonderwall'
file.write(Artist + " " + Song1 + "\n")
file.close()
This Is the bit I'm stuck with
Song = (random.choice(open("SongFile2.txt").read().split()))
print("Please type yes to continue playing")
print("or type something random to recieve a nice message and quit the
game")
PlayerAnswer = input()
if PlayerAnswer == ("yes"):
print("Question:" + str(Question))
print("" + Song1[0] + ": This is the first letter of the song" )
print("The Artist is: " + Artist)
print("Now guess the Song (Remember to use capital letters for
Names)")
PlayerGuess = input()
What I want is for the program to output the first letter of a song and the Artist associated with the song from a random line of the file
You should switch the way to store your data - use a seperator character between artist and song that does not occur in either one.
A '|' is a good divider for songs and artists. You can use it like so:
Write data file:
# use a seperator character between artist and song that does not occur in either
with open("songs.txt","w") as f:
f.write('''Cold Play|Clocks
Beatles|Revolution
Pharrel Williams|Happy
Owl City|Fireflies
Oasis|Wonderwall''') # write a multiline-file
Game:
import random
def get_all_music():
"""Load music from songs.txt and return as list of 2-elem-lists.
Lines not containing | are ignored."""
with open("songs.txt") as f:
return [x.strip().split("|") for x in f.readlines() if '|' in x]
all_music = get_all_music()
for _ in range(3):
artist, song = random.choice(all_music)
print("Song starting with '{}' by '{}'.".format(song[0],artist))
s = input("What is it's name?")
if s == song:
print("Correct!")
else:
print("'{}' is wrong. It was '{}'".format(s,song))
Output:
Song starting with 'C' by 'Cold Play'.
What is it's name? Clocks
Correct!
Song starting with 'F' by 'Owl City'.
What is it's name? Clocks
'Clocks' is wrong. It was 'Fireflies'
....
The read() method returns the entire file contents as one long string, which makes it harder to pick out a random song. Try using readlines() instead, which returns each line in the file in a list, making it much easier to use random.choice().
And as others have said, using a space to separate the artist and song title makes it much harder to tell where the artist name ends and the song title begins, because the artist and song title can also contain spaces.
You could do something like this to get a random line:
import random
with open("file.txt","r") as f:
list_of_lines = f.readlines()
list_of_indexes = list(range(len(list_of_lines)))
rand_index = random.choice(list_of_indexes)
random_line = list_of_lines[rand_index]
When you get the random line use regular expressions to get the desired elements. This is a useful site to test your regular expression:
https://regex101.com/

Looping and saving multiple inputs

I'm trying to loop through a set of inputs where I ask for a user's course grade, course hours and course code. The loop keeps on repeating until the user enters "done". Once the user has entered done I want it to print out the entered courses with grade and hours.
For Example:
course_count = False
#LOOP through Inputs
while not course_count:
#GET course code
course_code = input( "Please Enter the Course Code (or done if finished): " )
#IF course code is not equal to done (convert to lowercase)
if course_code.lower() != "done":
#GET course hours
course_hours = int( input( "How many credit hours was " + course_code + "? " ) )
#GET grade earned
course_grade = float( input( "What grade did you earn in " + course_code + "? " ) )
#ELSE END LOOP
else:
course_count = True
print("Course: " + course_code + " Weight: " + str( course_hours ) + " hours " + "Grade: " + str( course_grade ) + "%")
The problem is it will always print out only one inputted course, hour and grade. How would I save more than one answer using only accumulative strings?
The output I'm looking to make is:
# Please Enter the Course Code (or done if finished): COMP 10001
# How many credit hours was COMP 10001? 5
# What grade did you earn in COMP 10001? 75
# Please Enter the Course Code (or done if finished): COMP 20002
# How many credit hours was COMP 10001? 8
# What grade did you earn in COMP 10001? 95
# Please Enter the Course Code (or done if finished): done
# Course: COMP 10001 Weight: 5 Grade: 75%
# Course: COMP 20002 Weight: 8 Grade: 95%
It's for a school practice problem and were not allowed to use lists, arrays or dictionaries if that makes sense
You may find it useful to keep your information in a dictionary structure where the key is stored as the course code. Then it is as simple as iterating over each course saved in your dictionary to get the details.
Example:
course_count = False
course_info = {}
#LOOP through Inputs
while not course_count:
#GET course code
course_code = input( "Please Enter the Course Code (or done if finished): " )
course_info[course_code] = {};
#IF course code is not equal to done (convert to lowercase)
if course_code.lower() != "done":
#GET course hours
course_hours = int( input( "How many credit hours was " + course_code + "? " ) )
course_info[course_code]['hours'] = course_hours;
#GET grade earned
course_grade = float( input( "What grade did you earn in " + course_code + "? " ) )
course_info[course_code]['grade'] = course_grade
#ELSE END LOOP
else:
course_count = True
For course_code in course_info :
course_hours = course_info[course_code]['hours']
course_grade = course_info[course_code]['grade']
print("Course: " + course_code + " Weight: " + str( course_hours ) + " hours " + "Grade: " + str( course_grade ) + "%")
See if you can relate this simplified example to your code. To get the output you describe, you need to store the output text somehow and access it later:
output_lines = []
for i in range(10):
input_string = input("Enter some input")
output_lines.append(input_string)
for output_line in output_lines:
print(output_line)
From the comments, using only string "accumulation" (warning: quadratically bad):
output_text
for i in range(10):
input_string = input("Enter some input")
output_text = output_text + '\n' + input_string
print(output_text)
Note that the preferred way to build up a long string is to append to a list and use 'separator'.join(list_of_strings) or print one-by-one as above.
Use an output string output_string
Add each new line to the output string
...
output_string += "Course: {} Weight: {} hours Grade: {}\n".format(course_code, course_hours, course_grade"
#ELSE END LOOP
...
This accumulates the information into a string, using standard string formatting to insert the data from each pass through the loop.
At the end of the program, print the output string.
As others have noted, this is a pretty silly way of storing data, since accessing it, except to print out, will be difficult. Lists/dictionaries would be a lot better.

Nested If Expression with user validation - repeating the prompt for user input

Thank you #Idor I am making some progress but I am not 100% there yet. Right now my code looks as following:
def easy_game(easy_text, parts_of_speech1):
replaced = []
easy_text = easy_text.split()
i = 0
for word in easy_text:
replacement = word_in_pos_easy(word, parts_of_speech1)
if replacement != None:
user_input = raw_input("Type in: " + replacement + " ")
word = word.replace(replacement, user_input)
while word != solutions[i]:
print "Sorry, you are wrong"
user_input = raw_input("Type in: " + replacement + " ")
print i
i = i + 1
print i
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
print
#time.sleep(1)
print "Ok, lets see your results. Does it make sense?"
print
#time.sleep(1)
return replaced
print
#time.sleep(1)
print easy_game(easy_text, parts_of_speech1)
You can see I added the while loop. I also added an index and for troubleshooting I added print i to see what the program is doing. It still confuses me a bit or doesn't work as I would expect it. But being a newbie to programming my expectations are probably wrong. Here's what's happening:
When you enter the correct answer the program continues to question 2 and also increases i by 1
This works from beginning to end if you enter everything correctly
When you enter the wrong answer you are prompted to enter it again. Good!
However the user then gets stuck in this very question although i has been increased to the right value.
I don't really understand why the user would be stuck at this point when i has been increased, i.e. we would check at the right position in the list for the correct answer.
This is the full code of the game. I can successfully run it on my Mac but see the above behavior. Any thoughts on this by any chance? thanks in advance!
parts_of_speech1 = ["Word1", "Word2", "Word3", "Word4"]
# The following is the text for the easy text..
easy_text = "Python is a Word1 language that provides constructs intended to enable clear programs on both small and large scale. Python implementation was started in December Word2 by Guido von Rossum. The most simple Word3 in Python is Word4 and normally used at the beginning to tell Python to write 'Hello World' on the screen."
solutions = ["programming", "1989", "function", "print"]
# Checks if a word in parts_of_speech is a substring of the word passed in.
def word_in_pos_easy(word, parts_of_speech1):
for pos in parts_of_speech1:
if pos in word:
return pos
return None
# Plays a full game of mad_libs. A player is prompted to replace words in the easy text,
# which appear in parts_of_speech with their own words.
def easy_game(easy_text, parts_of_speech1):
replaced = []
easy_text = easy_text.split()
i = 0
for word in easy_text:
replacement = word_in_pos_easy(word, parts_of_speech1)
if replacement != None:
user_input = raw_input("Type in: " + replacement + " ")
word = word.replace(replacement, user_input)
while word != solutions[i]:
print "Sorry, you are wrong"
user_input = raw_input("Type in: " + replacement + " ")
print i
i = i + 1
print i
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
print
#time.sleep(1)
print "Ok, lets see your results. Does it make sense?"
print
#time.sleep(1)
return replaced
print
#time.sleep(1)
print easy_game(easy_text, parts_of_speech1)
I am building out a quiz based on raw_input using several different list operations. I also want to validate the user input against a list before moving on to the next question in the quiz.
The function currently looks like this:
def play_game(ml_string, parts_of_speech):
replaced = []
ml_string = ml_string.split()
for word in ml_string:
replacement = word_in_pos(word, parts_of_speech)
if replacement != None:
user_input = raw_input("Type in a: " + replacement + " ")
word = word.replace(replacement, user_input)
if word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
In Line 9 I am checking against the List containing the solution words. Whereas the validation itself works the function just continues to the next question but I need it to repeat the question until getting the correct answer. I tried to reposition the different lines but simply can't get my head around it at this point in time. Where or how do I need to place the validation of the user input correctly to prompt the user for the same question again?
It seems to me that what you are looking for is a while loop.
Instead of:
if word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
Try:
while word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
user_input = raw_input("Type in a: " + replacement + " ") # ask the user again
word = word.replace(replacement, user_input)
This way the user will have to answer the question again (raw_input) until he gets it right.

Categories