Error with Python 3 in RPi [duplicate] - python-3.4

This question already has answers here:
Troubleshooting "TypeError: ord() expected string of length 1, but int found"
(2 answers)
Closed 3 years ago.
First, sorry if I have a bad English or if anything is wrong, this is my first "post".
I'm trying to use a USB gamepad to turn an LED on and off with gpiozero.
I have an error while trying to execute the program:
import sys
from gpiozero import LED
led = LED(17)
pipe = open('/dev/input/js0', 'rb')
msg = []
while 1:
for char in pipe.read(1):
msg += [ord(char)]
if len(msg) == 8:
if msg[6] == 1:
if msg[4] == 1:
print ('button', msg[7], 'down')
led.on()
else:
print ('button', msg[7], 'up')
led.off()
msg = []
Error:
File "script.py", line 13, in <module>
msg += [ord(char)]
TypeError: ord() expected string of length 1, but int found
What can I do to solve this?
Thanks.

Looks like to are trying to add items to a list. Make use of append().
Documentation:
list.append(x)
Add an item to the end of the list. Equivalent to a[len(a):] = [x].
Example of append vs extend for future use:
append vs. extend

In the end I didn't get it to work with the version I was using, I just used a different python version instead.
Thanks for the help.

Related

(PyQt6) How can I write bytes to memory using sip.voidptr?

I want to fill the pixel data of an empty QVideoFrame instance. In PySide6, the bits(0) method returns a memory view and I can directly modify it by slicing and assigning. But in PyQt6, sip.voidptr is returned instead and I can't figure out how should I deal with it!
I am not really familiar with Python C bindings. Is there any way to easily access the memory using voidptr? Thanks in advance!
Edit 1
Here is a sample code.
from PyQt6 import QtCore, QtMultimedia
pfmt = QtMultimedia.QVideoFrameFormat.PixelFormat.Format_Y8
ffmt = QtMultimedia.QVideoFrameFormat(QtCore.QSize(1280, 1024), pfmt)
vf = QtMultimedia.QVideoFrame(ffmt)
vf.map(QtMultimedia.QVideoFrame.MapMode.ReadWrite)
# Data manipulation should come here.
vf.unmap()
Edit 2
Ok, I found out that voidptr can be converted to an array by passing the size of the video frame.
In the comment location of the code above,
>>> size = vf.bytesPerLine(0)*vf.height()
>>> vf.bits(0).asarray(size)
PyQt6.sip.array(unsigned char, 1310720)
Modifying a single pixel works fine.
>>> arr = vf.bits(0).asarray(vf.bytesPerLine(0)*vf.height())
>>> arr[0]
0
>>> arr[0] = 255
>>> arr[0]
255
But assigning the bytes to sip.array raised error.
>>> data = bytes(255 for _ in range(size))
>>> arr[:] = data
TypeError: can only assign another array of unsigned char to the slice
Answers in another question raised same error.
Thanks to #musicamante I managed to find the solution. It seems that voidptr can be directly accessed to write the bytes, provided that its size is known. QVideoFrame.bits() returns voidptr with unknown size (perhaps it is a bug of PyQt) so I had to manually set the size from QVideoFrame.mappedBytes.
Here is the full code:
from PyQt6 import QtCore, QtMultimedia
pfmt = QtMultimedia.QVideoFrameFormat.PixelFormat.Format_Y8
ffmt = QtMultimedia.QVideoFrameFormat(QtCore.QSize(1280, 1024), pfmt)
vf = QtMultimedia.QVideoFrame(ffmt)
vf.map(QtMultimedia.QVideoFrame.MapMode.ReadWrite)
ptr = frame.bits(0)
ptr.setsize(frame.mappedBytes(0))
ptr[:] = bytes(255 for _ in range(size))
vf.unmap()

TypeError: argmax(): argument 'input' (position 1) must be Tensor, not str

My code was working fine and when I tried to run it today without changing anything I got the following error:
TypeError: argmax(): argument 'input' (position 1) must be Tensor, not str
Would appreciate if help could be provided.
below is the code snippet where I am getting an error. I am using BERT mdoel
start_scores, end_scores = model(torch.tensor([input_ids]), # The tokens representing our input text.
token_type_ids=torch.tensor(
[segment_ids])) # The segment IDs to differentiate question from answer_text
# ======== Reconstruct Answer ========
# Find the tokens with the highest `start` and `end` scores.
answer_start = torch.argmax(start_scores)
answer_end = torch.argmax(end_scores)
In your line of code
start_scores, end_scores = model(torch.tensor([input_ids]),token_type_ids=torch.tensor([segment_ids]))
you have to make it:
start_scores, end_scores = model(torch.tensor([input_ids]),token_type_ids=torch.tensor([segment_ids]), return_dict=False).
It worked for me. I had the same problem.

update map with another map [duplicate]

This question already has answers here:
Merge maps with recursive nested maps in Groovy
(4 answers)
Closed 4 years ago.
In groovy, I want to update (left merge) a map with another.
def item = [attributes:[color:'Blue', weight:500], name:'hat', price:150]
def itemUpdate = [attributes:[size: 10]]
item << itemUpdate
println item
Gives:
[attributes:[size:10], name:hat, price:150]
But what I want is:
[attributes:[color:'Blue', weight:500, size:10], name:'hat',
price:150]
I have also tried:
item += itemUpdate
or using Updating groovy object fields from a map.
None fulfils my requirements; in python the method would be the update() method.
Edit: I'm wrong about python actually.
What you're doing is effectively overwriting the attributes entry.
What you want to do, instead, is:
item.attributes = item.attributes + itemUpdate
You can even do:
item.attributes += itemUpdate
Both of which yield the expected
[attributes:[color:Blue, weight:500, size:10], name:hat, price:150]

Can LLDB data formatters call methods?

I'm debugging a Qt application using LLDB. At a breakpoint I can write
(lldb) p myQString.toUtf8().data()
and see the string contained within myQString, as data() returns char*. I would like to be able to write
(lldb) p myQString
and get the same output. This didn't work for me:
(lldb) type summary add --summary-string "${var.toUtf8().data()}" QString
Is it possible to write a simple formatter like this, or do I need to know the internals of QString and write a python script?
Alternatively, is there another way I should be using LLDB to view QStrings this way?
The following does work.
First, register your summary command:
debugger.HandleCommand('type summary add -F set_sblldbbp.qstring_summary "QString"')
Here is an implementation
def make_string_from_pointer_with_offset(F,OFFS,L):
strval = 'u"'
try:
data_array = F.GetPointeeData(0, L).uint16
for X in range(OFFS, L):
V = data_array[X]
if V == 0:
break
strval += unichr(V)
except:
pass
strval = strval + '"'
return strval.encode('utf-8')
#qt5
def qstring_summary(value, unused):
try:
d = value.GetChildMemberWithName('d')
#have to divide by 2 (size of unsigned short = 2)
offset = d.GetChildMemberWithName('offset').GetValueAsUnsigned() / 2
size = get_max_size(value)
return make_string_from_pointer_with_offset(d, offset, size)
except:
print '?????????????????????????'
return value
def get_max_size(value):
_max_size_ = None
try:
debugger = value.GetTarget().GetDebugger()
_max_size_ = int(lldb.SBDebugger.GetInternalVariableValue('target.max-string-summary-length', debugger.GetInstanceName()).GetStringAtIndex(0))
except:
_max_size_ = 512
return _max_size_
It is expected that what you tried to do won't work. The summary strings feature does not allow calling expressions.
Calling expressions in a debugger is always interesting, in a data formatter more so (if you're in an IDE - say Xcode - formatters run automatically). Every time you stop somewhere, even if you just stepped over one line, all these little expressions would all automatically run over and over again, at a large performance cost - and this is not even taking into account the fact that your data might be in a funny state already and running expressions has the potential to alter it even more, making your debugging sessions trickier than needed.
If the above wall of text still hasn't discouraged you ( :-) ), you want to write a Python formatter, and use the SB API to run your expression. Your value is an SBValue object, which has access to an SBFrame and an SBTarget. The combination of these two allows you to run EvaluateExpression("blah") and get back another SBValue, probably a char* to which you can then ask GetSummary() to get your c-string back.
If, on the other hand, you are now persuaded that running expressions in formatters is suboptimal, the good news is that QString most certainly has to store its data pointer somewhere.. if you find out where that is, you can just write a formatter as ${var.member1.member2.member3.theDataPointer} and obtain the same result!
this is my trial-and-error adaptation of a UTF16 string interpretation lldb script I found online (I apologise that I don't remember the source - and that I can't credit the author)
Note that this is for Qt 4.3.2 and versions close to it - as the handling of the 'data' pointer has since changed between then and Qt 5.x
def QString_SummaryProvider(valobj, internal_dict):
data = valobj.GetChildMemberWithName('d')#.GetPointeeData()
strSize = data.GetChildMemberWithName('size').GetValueAsUnsigned()
newchar = -1
i = 0
s = u'"'
while newchar != 0:
# read next wchar character out of memory
data_val = data.GetChildMemberWithName('data').GetPointeeData(i, 1)
size = data_val.GetByteSize()
e = lldb.SBError()
if size == 1:
newchar = data_val.GetUnsignedInt8(e, 0) # utf-8
elif size == 2:
newchar = data_val.GetUnsignedInt16(e, 0) # utf-16
elif size == 4:
newchar = data_val.GetUnsignedInt32(e, 0) # utf-32
else:
s = s + '<unexpected char size - error parsing QString>'
break
if e.fail:
s = s + '<parse error:' + e.why() + '>'
break
i = i + 1
if i > strSize:
break
# add the character to our string 's'
# print "char2 = %s" % newchar
if newchar != 0:
s = s + unichr(newchar)
s = s + u'"'
return s.encode('utf-8')

python3 correct argv usage

Here is the code I have for reading a text file a storing it as a dictionary:
from sys import argv
def data(file):
d = {}
for line in file:
if line.strip() != '':
key,value = line.split(":")
if key == 'RootObject':
continue
if key == 'Object':
obj = value.strip()
d[obj]={}
else:
d[obj][key] = value.strip()
return d
file = open(argv[1])
planets = data(file)
print(planets)
My question is did I implement the argv correctly so that any user can run the dictionary by just typing solardictionary.py random.txt in the commandline and run it. I tried running this but I keep getting an index error and I'm not sure there might be something wrong with my argv implementation.
You need to type file = open(sys.argv[1],'r') in order to access the array because it is contained within the sys module.
http://docs.python.org/3.1/library/sys.html#module-sys
You may also be interested in opening the file within a try-catch block.

Resources