Python concatenating boolean to string doesn't work - python

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)

Related

how to concatenate tow Values as strings into an odoo Char field?

i'm trying to get fields from another model then do some operation on them, there is no problem with logic but I'm getting this error when the methods runs
psycopg2.DataError: invalid input syntax for type double precision: "1.007 t"
these all what I have done
class uom_custom(models.Model):
_inherit = 'product.template'
uom_qty = fields.Char(store=True,compute='get_qty')
#api.depends('qty_available')
def get_qty(self):
uoms=self.env['uom.uom'].search(['&',('category_id', '=', self.uom_id.category_id.id),('show_qty','=',True)])
if uoms.uom_type == 'bigger':
self.uom_qty= str(str(self.qty_available / uoms.factor_inv) + ' ' + uoms.name)
elif self.uom_type =='smaller':
self.uom_qty= str(self.qty_available * uoms.factor_inv) + ' ' + uoms.name
else:
self.uom_qty= str(self.qty_available) + ' ' + uoms.name
return self.uom_qty
so how can I display the value of mathematic operation and uom name beside it
Thanks in advance
The error states that the column in database is defined as double precision. Are you sure you've restarted Odoo and updated your module?
And there are some common mistakes in your compute method. Firstly and i can't repeat it often enough: try to stick to the Odoo naming guideline and name it compute_uom_qty. Secondly without a special decorator a compute method can and will be called with more than one record, so loop on that records. Thirdly: you search for uom.uom which can lead to more than one record, too. So either limit the search to one record or/and implement a check if something was found. uoms.name can lead to SingletonError. And at last: you don't have to return anything in compute methods.
#api.depends('qty_available')
def compute_uom_qty(self):
for record in self:
uoms = self.env['uom.uom'].search(
[('category_id', '=', record.uom_id.category_id.id),
('show_qty','=',True)], limit=1)
if uoms.uom_type == 'bigger':
qty = record.qty_available / uoms.factor_inv
record.uom_qty = "{} {}".format(qty, uoms.name)
elif uoms.uom_type =='smaller':
qty = record.qty_available * uoms.factor_inv
record.uom_qty = "{} {}".format(qty, uoms.name)
else:
record.uom_qty = "{} {}".format(record.qty_available, uoms.name)

UnboundLocalError: Local variable 'user' referenced before assignment

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.

python ignoring one of the 2 conditions in maya

I'm pretty new with python (20days) but I already created few stuff in maya, for example pickers, ik-fk snap, and few more things. Now I'm trying to create a button to mirror the pose.
the problem is that i must give 2 conditions to my if cycle but maya is ignoring the second condition
import maya.cmds as cmds
cmds.select('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
baseOBJ = cmds.ls(sl=True)
cmds.select('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
targetOBJ = cmds.ls(sl=True)
attr = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'IK' ]
for i in range(len (attr) ):
for x in range(len (targetOBJ) ):
if (cmds.attributeQuery(attr[i], node = targetOBJ[x], exists = True) \
and cmds.getAttr(targetOBJ[x] + '.' + attr[i], lock = False)):
newValue = cmds.getAttr(baseOBJ[x] + '.' + attr[i])
cmds.setAttr(baseOBJ[x] + '.' + attr[i], newValue)
else:
pass
the error is:
Error: RuntimeError: file <maya console> line 17: setAttr: The attribute 'arm_lf_FK_ctrl1.translateX' is locked or connected and cannot be modified. #
but in the if cycle I wrote: cmds.getAttr(targetOBJ[x] + '.' + attr[i], lock = False)
any hint?
EDIT SOLUTION:
here is the code fixed
import maya.cmds as cmds
cmds.select('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
baseOBJ = cmds.ls(sl=True)
cmds.select('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
targetOBJ = cmds.ls(sl=True)
attr = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'IK' ]
for i in range(len (attr) ):
for x in range(len (baseOBJ) ):
if (cmds.attributeQuery(attr[i], node = baseOBJ[x], exists = True) \
and cmds.getAttr(baseOBJ[x] + '.' + attr[i], lock = False)):
newValue = cmds.getAttr(baseOBJ[x] + '.' + attr[i])
cmds.setAttr(targetOBJ[x] + '.' + attr[i], newValue)
else:
pass
You need to specify
cmds.getAttr(item + attribute, lock=True)
even if you are checking for an attribute you expect to be locked: the 'lock = true' says 'tell me the lock state', not 'tell me if lock is true'.
You can do this a little more simply using three common python tricks (and also by not adding the extra selections, which will just duplicate the lists you've passed in)
The first is to use a foreach loop -- getting values directly out of the list -- instead of using array indices. This is the standard method for doing loops in python. So instead of
for index in range(len(list_of_things)):
do_something(list_of_things[index])
you just do
for item in list_of_things:
do_something(item)
The second is to use zip() to match up to lists and loop over them as pairs: This makes it much easier to write loops that read cleanly as you keep values in sync.
The final thing is to use try...except and allow some kinds of errors to happen rather than pre-checking. This is a common python trick since exceptions are not expensive and the resulting code is often much more readable.
Putting these together you could do the same code like this:
sources = ('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
targets = ('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
attr = ('.translateX', '.translateY', '.translateZ', '.rotateX', '.rotateY', '.rotateZ', '.IK' )
for source, target in zip(sources, targets):
for attrib in attr:
try:
val = cmds.getAttr(source + attrib)
cmds.setAttr(target + attrib, val)
except Exception as e:
print 'skipped', source + attrib, target + attrib
In this case Maya will throw a RuntimeError if you pass it a bad object, a bad attribute, or if you try to set a locked attribute. You'll really want to be more careful with the check than I was here, depending on what you wish to do when the system tries to do something impossible.
One last trick that will make your life easier is to separate out your condition checks from the logic. Instead of
if (cmds.attributeQuery(attr[i], node = baseOBJ[x], exists = True) \
and cmds.getAttr(baseOBJ[x] + '.' + attr[i], lock = False)):
You may find it easier in the long run to do :
exists, locked = False
try:
exists = cmds.ls(object + attrib) is not None
locked = cmds.getAttr(object + attrib, lock = True)
except:
pass # if the object or attrib is missing, both vals will still be false
if exists and not locked:
#do something
writing it this way makes it easier to insert debug printouts when things go wrong.
I do not know maya, but it looks like the issue is happening in the first condition itself, thus the second is being ignored. moreover the exception says issue while running setAttr. This function will be call when you run an attributeQuery, saying exists = True, which would essentially mean you will end up adding the attribute if not already present.

This program stores text message inside a class how can i print this in the class

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)

TypeError: Can't convert 'list' object to str implicitly

I have python class:
class Athlete:
def __init__(self,fullName,dob,times):
self.fullName = fullName
self.dob = dob
self.times = times
## print('times is ',times)
def __str__(self):
return ''.join("Athlete[fullName="+self.fullName +",dob="+self.dob+",sortedTimes="+self.sortedTimes+"]")
def __repr__(self):
return self.__str__()
Instances of this class are stored in map athleteMap as values.
When I do print(athleteMap) I get this error:
File "D:/Software/ws/python_ws/collections\athleteList.py", line 11, in __str__
return ''.join("Athlete[fullName="+self.fullName +",dob="+self.dob+",sortedTimes="+self.sortedTimes+"]")
TypeError: Can't convert 'list' object to str implicitly
I need to print Athlete instance in print method.
How to do this in python?
Convert times to a string explicitly then:
return "Athlete[fullName=" + self.fullName + ",dob=" + self.dob + ",sortedTimes=" + str(self.sortedTimes) + ']'
You don't need ''.join() here.
A better option is to use string formatting:
return "Athlete[fullName={0.fullName},dob={0.dob},sortedTimes={0.sortedTimes}]".format(self)
Your join call doesn't make sense. You probably want something like this:
def __str__(self):
return "Athlete[fullName="
+ str(self.fullName)
+ ",dob="
+ str(self.dob)
+ ",sortedTimes="
+ str(self.sortedTimes)
+ "]"
I've added str to every attribute because I can't know for sure in which one of them you put a list. The problem is evident from the error - lists can't be converted implicitly to string - you need to mark this conversion explicitly via str() call. One of your attributes (dob or times most probably) is a list.

Categories

Resources