Python Loop Unable to interrupt - python

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)

Related

Non callable variable

I'm trying to make a password generator with Python. Everything else seems to work correctly, but when I try to save the password in a .txt file, the program crashes, telling me that ok_to_save is "non callable". Why does this happen, and how do I fix it?
PS: Don't mind option 6 I'm still experimenting with it.
import random
import string
print('Hi, would you like me to create a password that no one can guess ?')
confirmation=input()
print('If you want a password with only letters press 1 and then enter, for one with only numbers press 2 and then enter.')
print('For a password with both press 3 and then enter.')
print('For a password with letters, numbers and symbols press 4 and then enter.')
print('To remember a password you previously saved in this application press 5 and then enter.')
print('To save a password you made yourself press 6 and then enter')
a=input()
b=''
ok_to_save=''
if a=='1':
b=input = ''.join([random.choice(string.ascii_letters) for x in range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='2':
b=input = ''.join([random.choice(string.digits) for n in
range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='3':
b=input = ''.join([random.choice(string.ascii_letters + string.digits) for n in
range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='4':
b=input = ''.join([random.choice(string.ascii_letters + string.digits + '!' + '#' + '#' + '$' + '%' + '^' + '&' + '*' + '(' + ')') for n in range(12)])
print(b)
print('Would you like me to save this password ?')
ok_to_save=input()
elif a=='5':
f=open("database.txt","r")
f=open('database.txt','r')
print(f.read())
elif a=='6':
print('What is the password ?')
alt_b=input()
if ok_to_save=='Yes' or ok_to_save=='yes':
print('What is this password for ? ')
c=input()
f=open('database.csv','w')
password=''+b+','+c
f.write(password)
f.close()
Ok so from my experimenting, the issue comes in here. When you do
b=input= ''.join([random.choice(string.ascii_letters + string.digits) for n in
range(12)])
What this does is it creates a variable named 'input' and stores the result of the join method in the variable input as well as in the varible b. The reason you get an error at the ok to save line is because you're doing
ok_to_save = input()
The python interpreter sees input and is thinking that you're referring to the variable that you created above and not the function which takes input and therefore says 'str object not callable' because the str object is not a function that you can call.
As a future reference, avoid creating variables with the same name as functions. To solve your issue that you have now, wherever you have
b = input = ...
remove the input and make it
b = ...
or just change input to input1 or something else.
This should resolve the problem.

KeyError Codes from User Input

Good Evening All,
I have been working on my first self directed project and have run into a bit of a snag. The program calculates what a character would have to roll to hit another based on their THAC0 and AC. The two scores in question are kept in a pair of dictionaries. If something is entered that is not in the dictionary I want the program to let whoever is operating it know. I've managed to get it to produce an error code, but I still get a KeyError. How do I get it to stop doing that?
defender = input("Who are they attacking?")
dict_thaco = {"Serena" : 19, "Morris" : 19}
if aggressor in dict_thaco:
pass
else:
print("I don't know that attacker")
dict_ac = {"Serena" : 6, "Morris" : -1}
if defender in dict_ac:
pass
else:
print("I don't know that defender")
def thaco_calc(thaco, ac):
to_hit = thaco - ac
return to_hit
aggressor_thaco = dict_thaco[aggressor]
defender_ac = dict_ac[defender]
hit = thaco_calc(aggressor_thaco, defender_ac)
print(aggressor + " would need to roll a " + str(hit) + " to hit " + defender + ".")
Perhaps you need something like
...
try:
aggressor_thaco = dict_thaco[aggressor]
defender_ac = dict_ac[defender]
hit = thaco_calc(aggressor_thaco, defender_ac)
print(aggressor + " would need to roll a " + str(hit) + " to hit " + defender + ".")
except KeyError as e:
print(e)

I want to add tkinter to this code and will do that but i don't know where to place the tkinter variables?, they will eventually be in the while true

my code should be looking for search options and appending to a list that compares to the search, all im trying to figure out is how to get tkinter in the loop, because i dont know where to put things such as the if name == "main":
stuff
from tkinter import *
ideas = ["pooop", "pooop", "yaaah"]
describe = ["A software that provides poop images", "Fart noises", "kid on crack"]
window = Tk()
window.title("Exists?")
while True:
function = input("Append or Search: ").lower().strip()
if function == "append":
appending = input("What would you like to append enter keywords/possible names..... ")
ideas.append(appending)
appending2 = input("Describe what you would like to append, please do not enter blank values as that will make "
"your software harder to find ")
describe.append(appending2)
print(ideas.index(str(appending)))
print(describe.index(str(appending2)))
searcher = input("What would you like to search for, enter keywords/possible names")
if searcher in ideas:
print(ideas)
print("description: " + describe[ideas.index(searcher)])
print(searcher in ideas)
numberOfResults = str(ideas.count(searcher))
print("0 results found")
if searcher not in ideas:
print(ideas)
print(searcher in ideas)
of = str(len(ideas))
print("0 results found of " + of)
if function == "search":
searcher = input("What would you like to search for, enter keywords/possible names")
if searcher in ideas:
print(ideas)
print("description: " + describe[ideas.index(searcher)])
print(searcher in ideas)
numberOfResults = str(ideas.count(searcher))
print(numberOfResults + " results found")
if searcher not in ideas:
print(ideas)
print(searcher in ideas)
of = str(len(ideas))
print("0 results found of " + of)
if __name__ == "__main__":
window.mainloop()
Put the code in an infinite loop and exit when a word other than append or search is entered
ideas = ["pooop", "pooop", "yaaah"]
describe = ["A software that provides poop images", "Fart noises", "kid on crack"]
while True: # infinity loop
function = input("Append or Search: ").lower().strip()
if function == "append":
pass # ... you code instead
elif function == "search":
pass # ... you code instead
else: # other input
print("That's all!")
break # exit loop

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