How to use count for bytearray - python-3.x

>>> help(bytearray.count)
Help on method_descriptor:
count(...)
B.count(sub[, start[, end]]) -> int
Return the number of non-overlapping occurrences of subsection sub in
bytes B[start:end]. Optional arguments start and end are interpreted
as in slice notation.
>>> b = bytearray(b'abcd')
>>> b
bytearray(b'abcd')
>>> b.count('a')
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: Type str doesn't support the buffer API
Question> How to use count for bytearray?

You pretty clearly need to pass another byte array to b.count:
>>> b.count(b'a')

You can search for bytes, not Unicode strings:
>>> b.count(b'a')
1

Related

TypeError: 'tuple' object is not callable when converting a list to tuple as return value

I want to convert the final list as tuple. However i am receiving an error.How can i get rid of this?
li= [(19343160,),(39343169,)]
def render_list_sql(li):
l = []
for index, tuple in enumerate(li):
idd = str(tuple[0])
l.append(idd)
return tuple(l)
print(render_list_sql(li))
Expected value to be returned is:
(19343160,39343169)
Error
Traceback (most recent call last):
File "test.py", line 20, in <module>
print(render_list_sql(list))
File "test.py", line 14, in render_list_sql
return tuple(l)
TypeError: 'tuple' object is not callable
As commented, don't use names for variables that mean other things to Python. This is called "shadowing" and you lose the meaning of the original name.
Example:
>>> tuple # This is the class used to create tuples.
<class 'tuple'>
>>> for index,tuple in enumerate([1,2,3]): # This is similar to your code
... print(index,tuple)
...
0 1
1 2
2 3
>>> tuple # tuple is no longer a class, but an instance of an integer.
3
>>> tuple([1,2,3]) # so this fails
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable
>>> 3([1,2,3]) # You are basically doing this:
<interactive input>:1: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable
So don't do that:
li = [(19343160,),(39343169,)] # don't reassign list
def render_list_sql(li):
l = []
for index, tup in enumerate(li): # don't reassign tuple
idd = str(tup[0])
l.append(idd)
return tuple(l) # now this will work
print(render_list_sql(li))
Output:
('19343160', '39343169')
FYI, a shorter version using a generator:
li = [(19343160,),(39343169,)]
tup = tuple(str(i[0]) for i in li)
print(tup)

Python Windows path with escape character error

I have a windows path stored in a variable called "a". When I tried to print or use it in the code, somehow some special characters are added to the string.
>>> import re
>>> from pathlib import Path
>>>
>>>
>>> a = "E:\POC\testing\functionalities\logs\timer.logs"
>>> a
'E:\\POC\testing\x0cunctionalities\\logs\timer.logs'
>>>
>>> Path(a)
WindowsPath('E:/POC\testing\x0cunctionalities/logs\timer.logs')
>>> Path.absolute(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\program files (x86)\python38-32\lib\pathlib.py", line 1159, in absolute
if self._closed:
AttributeError: 'str' object has no attribute '_closed'
>>>
>>> re.escape(a)
'E:\\\\POC\\\testing\\\x0cunctionalities\\\\logs\\\timer\\.logs'
>>>
>>> a.replace("\\", "/")
'E:/POC\testing\x0cunctionalities/logs\timer.logs'
>>> a.__repr__()
"'E:\\\\POC\\testing\\x0cunctionalities\\\\logs\\timer.logs'"
>>>
I'm able to handle all the special characters but \f is somehow changed to \x0c.
One solution is adding r to the string, but my path is stored in a variable. How I can achieve that? I'm using python 3.8.5 and Windows 10
>>> a = r"E:\POC\testing\functionalities\logs\timer.logs"
>>> a
'E:\\POC\\testing\\functionalities\\logs\\timer.logs'
>>>
>>>
>>> a = "E:\POC\testing\functionalities\logs\timer.logs"
>>> a = r"" + a
>>> a
'E:\\POC\testing\x0cunctionalities\\logs\timer.logs'
>>>
Use raw string or escape the backward slash:
a = r"E:\POC\testing\functionalities\logs\timer.logs"
or
a = "E:\\POC\\testing\\functionalities\\logs\\timer.logs"
Based on your comment under #user8086906's post, couldn't you just do
a.replace('\\', '\')
? I see you tried a.replace("\\", "/") above - could you explain what the desired behavior is? On my machine, the first snippet I posted works.
EDIT:
Thanks #Gopirengaraj C - I see what the issue is now. The problem is that \f is an escape character in Unicode - more specifically, it is called a "form feed". I think a good way to get around this would then be to avoid replace and do something like this instead:
a = r'{0}'.format(a)
Lmk if that works.

How to perform mathematical operations on specific numbers in a string of numbers

If I input a random number, let's say 1101, how do I multiply the first digit by 8, the second by 4, the third by 2, and the fourth by 1, and add the values together.
You can convert a binary str to a number using int(str, 2)
>>> int("1101", 2)
13
>>> int(str(1101), 2)
13
>>> int("1000111101010011101", 2)
293533
>>> int("38", 2)
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
int("38", 2)
ValueError: invalid literal for int() with base 2: '38'
You can use int('1') to parse '1' to 1
r = "1101"
sum = int(r[0])*8 + int(r[1])*4 + int(r[2])*2 + int(r[3])*1

Issue with python 2 to python 3 TypeError: cannot use a string pattern on a bytes-like object

I have the following code and would like to make it compatible with both python 2.7 and python 3.6
from re import sub, findall
return sub(r' ', ' ', sub(r'(\s){2,}', ' ',sub(r'[^a-z|\s|,]|_|
(x)\1{1,}', '', x.lower())))
I received the following error:
TypeError: cannot use a string pattern on a bytes-like object
I understood that the python3 distinguishes byte and string(unicode),but not sure how to proceed.
Thanks.
tried the following and not working
return sub(rb' ', b' ', sub(rb'(\s){2,}', b' ',sub(rb'[^a-z|\s|,]|_|(x)\1{1,}', b'', x.lower())))
Have you tried using re.findall? For instance:
import re
respdata = # the data you are reading
content = re.findall(r'#findall from and too#', str(respdata)) # output in string
for contents in content:
print(contents) # print results
The "string" you have must be a series of bytes, which you can convert to a real string using x.decode('utf-8'). You can see the problem with a simple example:
>>> import re
>>> s = bytes('hello', 'utf-8')
>>> s
b'hello'
>>> re.search(r'[he]', s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/re.py", line 183, in search
return _compile(pattern, flags).search(string)
TypeError: cannot use a string pattern on a bytes-like object
>>> s.decode('utf-8')
'hello'
>>> re.search(r'[he]', s.decode('utf-8'))
<re.Match object; span=(0, 1), match='h'>
I'm assuming your bytes represent UTF-8 data, but if you're working with a different encoding then just pass its name to decode() instead.

Am having difficulties with unicode strings serialport.write("\x23o0 \x23f") not being supported

We are having difficulty with the following code
#Get the heading from the IMU
#Translate the IMU from magnetic north to true north since the calcs use true north
def getcurheading():
# The escape character for # is \x23 in hex
serialport.write("\x23o0 \x23f")
headresponse = serialport.readline()
# print(headresponse)
words = headresponse.split(",")
if len(words) > 2:
try:
curheading = (float(words[0])) + 180
if curheading + Declination > 360: curheading = curheading - 360 + Declination
else: curheading = curheading + Declination
except:
curheading = 999
# print(curheading)
return curheading
Here is the error reported:
Traceback (most recent call last):
File "solarrobot7-core.py", line 256, in <module>
if (getcurheading() < getsolarheading()) and (getsolarangle() > 2) and (getcurheading() != 999):
File "solarrobot7-core.py", line 118, in getcurheading
serialport.write("\x23o0 \x23f")
File "/usr/local/lib/python3.2/dist-packages/serial/serialposix.py", line 518, in write
d = to_bytes(data)
File "/usr/local/lib/python3.2/dist-packages/serial/serialutil.py", line 58, in to_bytes
raise TypeError('unicode strings are not supported, please encode to bytes: %r' % (seq,))
TypeError: unicode strings are not supported, please encode to bytes: '#o0 #f'
It looks like i can use:
a_string = '\x23o0 \x23f Python'
by = a_string.encode('utf-8')
serialport.write(“\x23o0 \x23f “) a serialport.write(by)
Is this correct? Since i'm not a coder i'm not sure if this fix is correct. i've tried it and the code continues until it throws another error which appears to be related to this step. This is why we're backtracking to see if this is correct before moving on.
In Python 3.X, strings such as "abc" by default are Unicode strings. Strings must be encoded for transmission, or just start with a byte string b"abc" (note the b). Either of these will work:
serialport.write(b"\x23o0 \x23f")
or:
serialport.write("\x23o0 \x23f".encode('ascii'))
Note that specifying an encoding is optional and defaults to utf8.
bytearray is a mutable form of a byte string and isn't really needed here. It should have given you an error without an encoding on Python 3:
>>> bytearray("abc")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
>>> bytearray("abc",'ascii')
bytearray(b'abc')
You can edit bytearrays:
>>> bytes = bytearray("abc",'ascii')
>>> bytes[1]=50
>>> bytes
bytearray(b'a2c')
but not byte strings:
>>> bytes = b'abc'
>>> bytes[1] = 50
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment

Resources