NameError: name 'countrychoice' is not defined - python

I'm having some trouble with the current program I'm writing.
I'm letting the user type in a country, and then a city city in that country, and then see a weather forecast for the choosen city using API.
I'm using a class, like this:
class requestChoice:
def __init__(self):
self.countrychoice = None
self.citychoice = None
def countryChoice(self):
self.countrychoice = input("Enter which country your city is in(in english): ")
def cityChoice(self):
self.citychoice = input("Enter the name of the city: ")
And my main program looks like this:
from requestchoice import requestChoice
import requests
if __name__ == '__main__':
"""Introducion"""
print ("\nThis program lets you see a weather forecast for your choosen city.")
rc = requestChoice()
while True:
print("\nWhen you have typed in country and city, press 3 in the menu to see the weather forecast for your choice.\n")
menu = input("\nPress 1 for contry\nPress 2 for city\nPress 3 to see forecast\nPress 4 to exit\n")
if menu == "1":
rc.countryChoice()
elif menu == "2":
rc.cityChoice()
elif menu == "3":
r = requests.get("http://api.wunderground.com/api/0def10027afaebb7/forecast/q/" + countrychoice + "/" + citychoice + ".json")
data = r.json()
try:
for day in data['forecast']['simpleforecast']['forecastday']:
print (day['date']['weekday'] + ":")
print ("Conditions: ", day['conditions'])
print ("High: ", day['high']['celsius'] + "C", '\n' "Low: ", day['low']['celsius'] + "C", '\n')
except Exception as e:
print ("\nHave you typed in the correct country and city?\nBecause we got a" ,e, "error")
else:
print ("\nGoodbye")
break
When I run my program I get the error NameError: name 'countrychoice' is not defined. It is going to be the same error with the citychoice. I've tried creating a list in my class and append the countrychoice to the list but without any luck. How am I supposed to make it work as wished?

You are getting a NameError on here:
r = requests.get("http://api.wunderground.com/api/0def10027afaebb7/forecast/q/" + countrychoice + "/" + citychoice + ".json")
because you have no names countrychoice and citychoice defined. Perhaps you meant to use rc.countrychoice and rc.citychoice instead?

You have to access them with the corresponding object name. In this case
rc.countrychoice
rc.citychoice
So, this line
r = requests.get("http://api.wunderground.com/api/0def10027afaebb7/forecast/q/" + countrychoice + "/" + citychoice + ".json")
becomes
r = requests.get("http://api.wunderground.com/api/0def10027afaebb7/forecast/q/" + rc.countrychoice + "/" + rc.citychoice + ".json")

You need to use rc.countrychoice and rc.citychoice here
r = requests.get("http://api.wunderground.com/api/0def10027afaebb7/forecast/q/" + rc.countrychoice + "/" + rc.citychoice + ".json")

Related

getRecommednations() function works, but it prints artists in your preferences when it should remove them

I am trying to create a music recommender that returns artists based on similar artists liked by other users. The recommendations should return each artist individually, but if the artist is already in your preferences, it should not be returned. I believe the section that is failing begins after the line "if simCounter == 0"
import copy
musicrec1 = "musicrecplus.txt"
def loadUserToDictionary(fileName): # Anthony, Deming & William.
'''Takes in a text file and converts the user information into a dictionary.'''
userDictionary = {}
try:
file = open(fileName, 'r+')
for line in file:
[userName, bands] = line.strip().split(":")
bandList = bands.split(",")
bandList.sort()
titledL = []
for bands in bandList:
titledL.append(bands.title())
userDictionary[userName.title()] = titledL
file.close()
except IOError:
file = open(fileName, "w")
return userDictionary
users = loadUserToDictionary(musicrec1)
def loadUsersToText(fileName): # Anthony, Deming & William.
'''Takes in a dictionary and converts the user information in a text file with the proper format.'''
names = list(users.keys())
people = copy.deepcopy(users)
l = ""
file = open(fileName, 'w')
for line in range(len(names)):
l = names[line].strip() + ":" + ','.join(people[names[line]])
l += "\n"
file.write(l)
file.close()
def greeting(): # Anthony, Deming & William.
'''This is the initial function a user sees when using the program. If they are a new user, they will be prompted to input preferences. If they are a returning user, they will be brought to the menu.'''
username = input("Enter you name (put a $ symbol after your name if you wish your preferences to " + "\n" "remain private): " + "\n")
if username.title() in users:
menu(username.title())
else:
if username.title() != "":
users[username.title()] = []
enterPreference(username.title())
def menu(username): # Anthony, Deming & William.
'''This is the menu that redirects the user to the proper function based on their input.'''
firstResponse = input("Enter a letter to choose an option: " + "\n" + "e - Enter preferences " + "\n" + "r - Get recommendations " + "\n" + "p - Show most popular artists " + "\n" + "h - How popular is the most popular " + "\n" + "m - Which user has the most the likes " + "\n" + "q - Save and quit " + "\n")
if firstResponse.lower() == "e":
enterPreference(username.title())
if firstResponse.lower() == "r":
print(getRecommendations(username.title()))
if firstResponse.lower() == "p":
print(showPopularArtist(username.title())[0])
print(showPopularArtist(username.title())[1])
print(showPopularArtist(username.title())[2])
if firstResponse.lower() == "h":
print(howPopularIsArtist(username.title()))
if firstResponse.lower() == "m":
print(mostLikes(username.title()))
if firstResponse.lower() == "q":
saveAndQuit()
else:
menu(username.title())
def enterPreference(username): # Anthony, Deming & William.
'''This function allows the user to add preferences, and properly stores them in the correct location in the dictionary based on the given username.'''
L = users[username]
likedArtist = input("Enter an artist that you like (Enter to finish): " + "\n")
while likedArtist != "":
if likedArtist.title() in users[username]:
likedArtist = input("Enter an artist that you like (Enter to finish): " + "\n")
else:
L.append(likedArtist.title())
likedArtist = input("Enter an artist that you like (Enter to finish): " + "\n")
L.sort()
users[username] = L
menu(username)
def publicUsersOnly(): # Anthony, Deming & William.
'''This function returns a dictionary of the public users only. There username and preferences are stores in the dictionary.'''
publicUsers = copy.deepcopy(users)
currentUser = ""
publicUsersNames = list(users.keys())
for i in range(len(publicUsersNames)):
lastLetter = len(publicUsersNames[i]) - 1
currentUser = publicUsersNames[i]
if currentUser[lastLetter] == "$":
del publicUsers[publicUsersNames[i]]
return publicUsers
def getRecommendations(username): # Anthony, Deming & William.
'''This function returns other user's preferences based on the amount of artists you have in common. Takes in the current user's username as an input to ensure the proper preferences are being added.'''
def counterSimilarity(currentUserArtists, otherUserArtists):
'''Takes the current user's preferences and the preferences of the other users and compares the similarities. The other user's preferences will be iterated through using a for loop in the getRecommendations() function.'''
counter = 0
for sim in range(len(otherUserArtists)):
if otherUserArtists[sim] in currentUserArtists:
counter += 1
return counter
names = list(publicUsersOnly().keys())
currentUserArtists = users[username]
otherUserArtists = []
mostSimilar = publicUsersOnly()[names[0]]
simCounter = 0
for people in range(1, len(publicUsersOnly())):
otherUserArtists = publicUsersOnly()[names[people]]
if currentUserArtists != otherUserArtists:
if counterSimilarity(currentUserArtists, mostSimilar) < counterSimilarity(currentUserArtists, otherUserArtists):
mostSimilar = publicUsersOnly()[names[people]]
simCounter += 1
if counterSimilarity(currentUserArtists, mostSimilar) > counterSimilarity(currentUserArtists, otherUserArtists):
simCounter += 1
if simCounter == 0:
str = "No recommendations available at this time."
return str
#print(currentUserArtists)
if len(mostSimilar) < len(currentUserArtists):
for artists in range(len(mostSimilar)):
if mostSimilar[artists] in currentUserArtists:
mostSimilar.remove(currentUserArtists[artists])
if len(mostSimilar) > len(currentUserArtists):
for artists in range(len(currentUserArtists)):
if currentUserArtists[artists] in mostSimilar:
mostSimilar.remove(currentUserArtists[artists])
for recs in range(len(mostSimilar)):
print(mostSimilar[recs])
menu(username)
I am expecting it to return other user's preferences based on their similarity to yours. That part of my function works, but the part that removes it from recommendations if it is already in your list isn't working.

TypeError: can only concatenate str (not "dict") to str

All my variables seem to be string data types however I keep getting the above error message
elif menu == 'a':
pass
user_1 = input("Please enter a user name: ")
task_title = input("Please enter a title for the task to be done: ")
task_desc = input("Please describe the task: ")
task_due = input("Please enter due date of the task: ")
date_assign = str(date.today())
with open("task.txt", "a") as fa:
fa.write("\n" + {} + {} + {} + {} + {} + "No".format(task_title,task_desc,task_due,str(date_assign)))
Your brackets need to actually be within the string itself in order to use the str.format() function. So your code line:
fa.write("\n" + {} + {} + {} + {} + {} + "No".format(task_title,task_desc,task_due,str(date_assign)))
should look more like this:
fa.write("\n{} {} {} {} No".format(task_title,task_desc,task_due,str(date_assign)))
To add on to Nathan Robert's answer, consider using f-strings like so:
with open("task.txt", "a") as fa:
fa.write(f"\n{task_title} {task_desc} {task_due} {date_assign} No")
I find them to be much cleaner then '+' string concatenation.
You cannot create a format string with:
"\n" + {} + {} + {} + {} + {} + "No"
You could:
"\n" + repr({}) + repr({}) + repr({}) + repr({}) + repr({}) + "No"
Which will yield:
"\n{}{}{}{}{}No"
But if you want:
"\n + {} + {} + {} + {} + {} + No"
Then you just need to eliminate two "s.
"\n + {} + {} + {} + {} + {} + No"
Also note that you've provided 5 sets of brackets, but only four arguments to format. This suggests a possible error on your part.

unitval.replace statements overwriting other part of code?

I am trying to convert units within an excel file. The code below was working until I added the unitval.replace statements, after which the unit conversion doesn't occur. These are to replace , to . in the data and " " to no space. Is it possible to write something like this and still get the unit conversion code below it to work? Thanks!
def unitConversion(ssheet,scollist,units,c):
if (units != None):
unitval = str(ssheet.cell_value(units,c))
factor = 1
if "," in unitval:
unitval = unitval.replace(",",".")
if " " in unitval:
unitval = unitval.replace(" ", "")
try:
factor = REF.conversions[unitval]
for i in range(0,len(scollist),1):
try:
scollist[i] = float(scollist[i]) * factor
except:
if (scollist[i] == ""):
scollist[i] = ""
elif ((scollist[i][0] == "<") or (scollist[i][0] == ">")):
temp = float(scollist[i][1:])
scollist[i] = "-" + str(temp/1000)

In Python how do I make a space between a list and string?

I need to put a space between the list (a cat's name) and the index.
Right now it comes out like this:
Pussy0
Pinky1
Fats2
I want it to print out like this:
Pussy 0
Pinky 1
Fats 2
catNames = []
while True:
print('Enter the name of cat ' + str(len(catNames) + 1) +
' (Or enter nothing to stop.):')
name = input()
if name == '':
break
catNames = catNames + [name] # list concatenation
print('The cat names are:')
#for name in range(len(catNames)):
#print(name)
for i in range(len(catNames)):
print(catNames[i] + str(i))
Just do this:
catNames = []
while True:
print('Enter the name of cat ' + str(len(catNames) + 1) +
' (Or enter nothing to stop.):')
name = input()
if name == '':
break
catNames = catNames + [name] # list concatenation
print('The cat names are:')
#for name in range(len(catNames)):
#print(name)
for i in range(len(catNames)):
print(catNames[i] + " " + str(i))
Though its always better to use f-strings or format:
catNames = []
while True:
print('Enter the name of cat ' + str(len(catNames) + 1) +
' (Or enter nothing to stop.):')
name = input()
if name == '':
break
catNames = catNames + [name] # list concatenation
print('The cat names are:')
#for name in range(len(catNames)):
#print(name)
for i in range(len(catNames)):
print(f"{catNames[i]} {str(i)}")
Using f-strings makes the code much cleaner, and simpler to understand. Look here for more details. Note that f-strings are only for python 3.6 or above. If you have a version of python below 3.6, check my previous answer to see how you can use f-strings in below python 3.6.
Try string formatting:
catnames = ['Fuzzy', 'Pinky', 'Fats']
for i, cname in enumerate(catnames):
print('{} {}'.format(cname, str(i)))
I would suggest using string interpolation for this:
for i in range(len(catNames)):
print(f"{catNames[i]} {i}")
I with the help of "Demolution Brother" showed me how to write a list in a string followed by an index.
print(str(i),":",catNames[I])
print function
Turn the interfere into a string - (str(
After the str( we now have the interfere (str(I)
Important to use the , to separate the string to put in " : ". It has to be done with
double-quotes.
Now after the comma , we can continue with catNames[I]) (The List)
List item now prints after the index.
Answer - print(catNames[i], " : ", str(I))
Some of the other ways to it was tried out:
#print(str(i),":",catNames[i])
#print(catNames[i], i, end=' ')
#print(catNames[i],end=' ' + str(i))
The code -cat_names
catNames = []
while True:
print('Enter the name of cat ' + str(len(catNames) + 1) +
' (Or enter nothing to stop.):')
name = input()
if name == '':
break
catNames = catNames + [name] # list concatenation
print('The cat names are:')
#for name in range(len(catNames)):
#print(name)
for i in range(len(catNames)):
print(str(i),":",catNames[i])
#print(catNames[i], " : ", str(i))

using a function to call a class in a while loop

I'm currently writing a python gui that will ultimately generate a random village for use in tabletop RPG (mainly dungeons and dragons)
I have the code below that will generate a number of taverns based on how big a town the user wants and so far it works fine. I hope the GUI will eventually create shops, temples and other buildings too.
class NPC:
def __init__(self, first, last):
self.first = first
self.last = last
self.name = first + ' ' + last
class Tavern:
def __init__(self, name1, name2):
self.name1 = name1
self.name2 = name2
self.name = 'The ' + name1 + ' ' + name2
while num_tav != 0:
morf = random.randint(1, 2)
if morf == 1:
sex = 'male'
else:
sex = 'female'
first = open(set_race + '_' + sex + '.txt')
name1 = first.readlines()
first = random.choice(name1).strip()
last = open(set_race + '_surnames.txt')
name2 = last.readlines()
last = random.choice(name2).strip()
npcname = NPC(first, last)
tavern1 = open('tavnames1.txt')
name1 = tavern1.readlines()
name1 = random.choice(name1).strip()
tavern2 = open('tavnames2.txt')
name2 = tavern2.readlines()
name2 = random.choice(name2).strip()
tavern = Tavern(name1, name2)
print('Taverns/Inns: ' + tavern.name + "The inkeeper is a tall " + set_race + ' ' + sex + " named " + npcname.name + '\n')
num_tav = num_tav - 1
w.insert(END, not_b + 'Taverns/Inns: ' + tavern.name + "The inkeeper is a tall " + set_race + ' ' + sex + " named " + npcname.name + '\n' + 'Population is approx. ' + str(population) + ' people\n')
The NPC class basically genreates a random name and I'd like to use this in other areas (shops, markets, blacksmith, etc.), not just to generate the name of an innkeeper.
My question is;
Is it possible to create a function that will use the script
first = open(set_race + '_' + sex + '.txt')
name1 = first.readlines()
first = random.choice(name1).strip()
last = open(set_race + '_surnames.txt')
name2 = last.readlines()
last = random.choice(name2).strip()
npcname = NPC(first, last)
as a function that will call the NPC class, and then just have other while loops calls it? Instead of having the same code repeated in each of the loops I'll use to generate other buildings?
I'm assuming so but I just don't know what it would be called so any help is appreciated.
define the while loop in a function with maybe an extra parameter that gets the type of entity that it is supposed to generate (Tavern, shop,...) and then put it in another python file and import it. as a module.
def mynewfunction(set_race,sex):
first = open(set_race + '_' + sex + '.txt')
name1 = first.readlines()
first = random.choice(name1).strip()
last = open(set_race + '_surnames.txt')
name2 = last.readlines()
last = random.choice(name2).strip()
return NPC(first, last)
Then:
while (x,y,z):
npcname = mynewfunction(set_race):

Categories