This is part of a code that runs a moderator bot in a chatroom i use. This section of the code is to approve someone's request to cam up but whenever I use the command I get this unbound local error...
I have gone through this so many times and I can't figure out why I'm getting it.
def approveCam(room, identifier):
if not room.bpass:
return
if type(identifier) in [str, unicode, int]:
user = room._getUser(identifier)
if not user:
return "User " + str(identifier) + " was not found..."
if user.broadcasting:
return
room._sendCommand("privmsg", [room._encodeMessage("/allowbroadcast " + room.bpass),
"#0,en" + "n" + str(user.id) + "-" + user.nick])
The problem seems to be at "if user.broadcasting:"
the code worked on a previous version of the bot like this
def approveCam(room, user):
if type(user) is str or type(user) is unicode:
nick = user
user = room._getUser(user)
if not user:
return "User "+nick+" was not found..."
if not room.bpass:
return
room._sendCommand("privmsg", [room._encodeMessage("/allowbroadcast "+room.bpass),
"#0,en"+"n"+ user.id+"-"+user.nick])
and here is the response i get in command prompt when i try to run the command.
Traceback (most recent call last):
File "C:\Users\Ejah\Downloads\Desktop\Tunebot-Master\tinychat.py", line 1262
in onMessage
SETTINGS['onMessageExtend'](self, user, msg)
File "tunebot.py", line 1316, in onMessageExtended
handleUserCommand(room, user, msg)
File "tunebot.py", line 1722, in handleUserCommand
res = botterCommands(room, userCmd, userArgsStr, userArgs, target,
File "tunebot.py", line 2786, in botterCommands
res = approveCam(room, user)
File "tunebot.py", line 4043, in approveCam
if user.broadcasting:
UnboundLocalError: local variable 'user' referenced before assignment"
Update your code to raise an error when identifier is of an invalid type and all will become clear:
def approveCam(room, identifier):
if not room.bpass:
return
if type(identifier) in [str, unicode, int]:
user = room._getUser(identifier)
if not user:
return "User " + str(identifier) + " was not found..."
else:
raise ValueError('Invalid type for identifier')
if user.broadcasting:
return
room._sendCommand("privmsg", [room._encodeMessage("/allowbroadcast " + room.bpass),
"#0,en" + "n" + str(user.id) + "-" + user.nick])
user.broadcasting - This is not correct
At this point user does not exist and hence the interpreter won't allow that. You must initialise local variables before using them.
Make user a global variable with some value to it.
Probably if type(identifier) in [str, unicode, int]: is False, so the body of the if is not executed and user is never inizialized.
Initialize user before the second if if possible, or rethink your code.
P.S. Don't use getter and setter! Python is not Java, if you really need to use them, use a property instead.
Related
I have a litte problem because whenever i run the code print(obj) in the try/except part it throws an exception. i followed it with the debugging tool and it jumps right in the str method but i coded the str methode just for testing. Normally i thought it would jump in the repr method for normal class calls.
The code breaks right in the return command of the str() method.
I just wanted to change the output of the time.time_struct class because i need the string and the attribute represenation.
the print commands ar just for displaying the results, the block in the init statement works but in the try/Except block it doesnt.
Does anyone have an idea?
import time
class timeSelf():
def __init__(self,str):
self.obj = time.strptime(str, "%H:%M")
print(self.obj.tm_hour)
print(type(self.obj))
def __repr__(self):
return "" + self.obj.tm_hour + ":" + self.obj.tm_min
def __str__(self):
return "" + self.obj.tm_hour + ":" + self.obj.tm_min
if __name__ == "__main__":
str= "16:54"
try:
obj = timeSelf(str)
print(obj)
print(type(obj))
print(type(obj.tm_hour))
except Exception:
print("stuff happened")
pass
If you hadn't caught the exception (or if you re-raised it to see what you had caught), you would see the problem is with your definitions of __str__ and __repr__. You are attempting to combine int and "" values with +, and no automatic conversion of int to str occurs there.
Traceback (most recent call last):
File "tmp.py", line 19, in <module>
print(obj)
File "tmp.py", line 13, in __str__
return "" + self.obj.tm_hour + ":" + self.obj.tm_min
TypeError: can only concatenate str (not "int") to str
You have to be explicit:
return "" + str(self.obj.tm_hour) + ":" + str(self.obj.tm_min)
or more simply:
return f"{self.obj.tm_hour}:{self.obj.tm_min}"
f-strings do call __str__ as necessary to convert the value inside {...} to a str.
I am trying to build a bot that connects to slack, and keep receiving a TypeError:
Traceback (most recent call last):
File "happybotV4.2.py", line 217, in <module>
av_mood, user_count, total_mood = datamood(user_answer, user_id, user_count, total_mood, av_mood)
TypeError: 'NoneType' object is not iterable
Here is the code:
if slackinput_list and len(slackinput_list) > 0:
user_answer, user_id, channel, event_type = parse_slack_useranswer(slackinput_list)
#print(user_answer,user_id)#test
if user_answer and user_id and user_id != 'U7GRT34H3' and event_type=="message":
if user_answer=="1" or user_answer=="5":
print(user_answer, user_id, user_count, total_mood, av_mood) #test
#if user_id not in user_list:
av_mood, user_count, total_mood = datamood(user_answer, user_id, user_count, total_mood, av_mood)
And datamood's code:
def datamood(mood, user, count, total_mood, average_mood):
print(user_list)
if user not in user_list:
count = count+1
mood_user.append(mood)
user_list.append(user)
print(user_list, user)
if len(mood_user)>0:
for i in mood_user :
if i=="1":
n=1
elif i=="5":
n=5
total_mood = total_mood + n
print(total_mood)#test
average_mood = total_mood/count
print (average_mood, count) #test
return average_mood, count, total_mood
else:
return average_mood, count, total_mood
In fact datamood works one time, but when I try to call it a second time I get the error. I checked that every variable (that is user_answer, user_id, user_count, total_mood, av_mood) are not None and are in the correct format.
Any ideas?
Your call to the datamood() method is expecting a value to be returned. Since your logic does not explicitly tell your method what to do when a user exists in user_list the method returns None or a NoneType object. When a return is not explicitly set in a Python method, it will always return None. Hence, when you first call the method and the user does not exist, the return value is expected; however, when you call the method and user does exist, your method returns None.
As a part of program I wrote the following method (hidden is a boolean variable). It's located in an object called Deltext, which inherits a type called DelMsg. info_msg() is overriding and using a similar method in its parent type.
def info_msg(self):
info = DelMsg.info_msg(self)
if self.code == 'l': # If message is long message
return info + '#' + str(len(self.content)) + '#' + str(self.hidden)
elif self.code == 'm': # If message is snap message
return info + '#' + str(self.timeout) + '#' + self.content
else: # If message is a normal message
return info + '#' + self.content + '#' + str(self.hidden)
But every time I call the method (from the object instance) it displays an error: TypeError: cannot concatenate 'str' and 'bool' objects, and says the error is in the last line, even though hidden is parsed to string.
Is there any way to solve this without using conditionals?
Here's how you can proceed to debug your code:
check the type of the variables:
Edit you code to include the following print(type(variable))
def info_msg(self):
print(type(info))
print(type(self.content))
return info + '#' + self.content + '#' + str(self.hidden)
Then, run the program and see which other variable is boolean.
add str(...) to the boolean variables
At most, all variables will be of type boolean, so you can edit your code as follows:
def info_msg(self):
return str(info) + '#' + str(self.content) + '#' + str(self.hidden)
An other option is to use str.format, which will take care of casting the variables to string for you:
def info_msg(self):
return "{0}#{1}#{2}".format(info, self.content, self.hidden)
Probably info or content are boolean too. You can overcome this with
def info_msg(self):
return str(info) + '#' + str(self.content) + '#' + str(self.hidden)
I have a problem with this code as I keep geting a syntax error. I created a list with different greetings but I couldn't get it to recall on the line 24. Please Help. Thanks :)
import pyttsx
import sklearn
import random
speech_engine = pyttsx.init('sapi5') # see http://pyttsx.readthedocs.org/en/latest/engine.html#pyttsx.init
speech_engine.setProperty('rate', 150)
def Hello():
words = [line.strip() for line in open('Hello.txt')]
speak(random.choice(words))
def speak(text):
speech_engine.say(text)
speech_engine.runAndWait()
intro=(Hello())
Greeting=input(speak("What is your name"))
Account=input(speak(intro + Greeting + ", Would you like to Log in or create an account"))
if Account==("Create An Account") or Account==("Create An Account") or Account==("create an account"):
Password=input(speak("What is the password going to be for your account"))
text_file = open("Password.txt", "a")
text_file.write("| "+ Greeting +" | "+ Password +" |\n")
text_file.close()
Since your function Hello() does not return anything, it implicitly returns None, so intro = None. Now you try to "add" a string to None, which is exactly, what your error message states.
If you just want to call your Hello() function to greet the user, simply do so by calling Hello() without assigning the return value. Since it is None anyways, there is no obvious reason to include it in the input(...) statement.
EDIT:
Taking your comment into account, I suggest you change your function:
def Hello():
words = [line.strip() for line in open('Hello.txt')]
return random.choice(words)
import datetime
class SMS_Inbox:
def ___init___(self):
self.__inbox=[]
def addNewArrival(self,senderPhone,arrivalTime,msgTxt):
msgInfotuple=(senderPhone,arrivalTime,msgTxt)
singleMsg=[False,msgInfotuple]
self.__main=self.__inbox.append(singleMsg)
return self.__main
someStr=""
def __str__(self):
for msg in self.__inbox:
unread=msg[0]
msgTuple=msg[1]
phoneNum=msgTuple[0]
date=msgTuple[1]
txt=msgTuple[2]
return str(unread)+ someStr+" " +str(phoneNum) + someStr+" " + str(txt)+someStr+" "
how can change this str code to print appropriately
Presumably you just need to append those strings to a list initialized as thelist=[] and then return the '\n'.join(thelist). But there are several other anomalies in your code.
self.__main=self.__inbox.append(singleMsg)
return self.__main
This makes no sense. append always returns None. Why go to all this bother to save None as an attribute of self and return it?!
someStr=""
def __str__(self):
for msg in self.__inbox:
unread=msg[0]
msgTuple=msg[1]
phoneNum=msgTuple[0]
date=msgTuple[1]
txt=msgTuple[2]
return str(unread)+ someStr+" " +str(phoneNum) + someStr+" " + str(txt)+someStr+" "
Besides the obvious error of returning on the first pass of the loop (so there will never be other passes), this will fail because someStr is not in scope in the method; you'd need to use self.someStr instead, I guess. (Still looks weird to me but at least it works:-).
So this method must become something like:
someStr=""
def __str__(self):
thelist = []
someStr = self.someStr
for msg in self.__inbox:
unread=msg[0]
msgTuple=msg[1]
phoneNum=msgTuple[0]
date=msgTuple[1]
txt=msgTuple[2]
s = str(unread)+ someStr+" " +str(phoneNum) + someStr+" " + str(txt)+someStr+" "
thelist.append(s)
return '\n'.join(thelist)