I am making a project all in python 2.7 but it started to give some errors to me on the final parts since the documentation is in python 3.5. So i am changing everything to python 3.5, but it is giving me a error because of bytesIO. Can you help me to understand why, and what should i do? The error is coming from def repr on string_dinamica.write('P3\n'). I left all the code in case that it´s needed. Thanks for the help. NOTE: Just to confirm this works on python 2.7 but not in 3.5
from io import BytesIO
from cor_rgb_42347 import CorRGB
class Imagem:
def __init__(self, numero_linhas, numero_colunas):
self.numero_linhas = numero_linhas
self.numero_colunas = numero_colunas
self.linhas = []
for n in range(numero_linhas):
linha = []
for m in range(numero_colunas):
linha.append(CorRGB(0.0, 0.0, 0.0))
self.linhas.append(linha)
def __repr__(self):
string_dinamica = BytesIO()
string_dinamica.write('P3\n')
string_dinamica.write("#mcg#leim#isel 2015/16\n")
string_dinamica.write(str(self.numero_colunas) + " " \
+ str(self.numero_linhas) + "\n")
string_dinamica.write("255\n")
for linha in range(self.numero_linhas):
for coluna in range(self.numero_colunas):
string_dinamica.write(str(self.linhas[linha][coluna])+ " ")
string_dinamica.write("\n")
resultado = string_dinamica.getvalue()
string_dinamica.close()
return resultado
def set_cor(self, linha, coluna, cor_rgb):
"""Permite especificar a cor RGB do pixel na linha "linha",
coluna "coluna".
"""
self.linhas[linha-1][coluna-1] = cor_rgb
def get_cor(self, linha, coluna):
"""Permite obter a cor RGB do pixel na linha "linha",
coluna "coluna".
"""
return self.linhas[linha-1][coluna-1]
def guardar_como_ppm(self, nome_ficheiro):
"""Permite guardar a imagem em formato PPM ASCII num ficheiro.
"""
ficheiro = open(nome_ficheiro, 'w')
ficheiro.write(str(self))
ficheiro.close()
if __name__ == "__main__":
imagem1 = Imagem(5,5)
print(imagem1)
Traceback (most recent call last):
File "C:\Users\Utilizador\Desktop\Projectos Finais\Projecto_42347\imagem_42347.py", line 60, in <module>
print(imagem1)
File "C:\Users\Utilizador\Desktop\Projectos Finais\Projecto_42347\imagem_42347.py", line 19, in __repr__
string_dinamica.write('P3\n')
TypeError: a bytes-like object is required, not 'str'
For Python 3, just change BytesIO to StringIO. Python 3 strings are Unicode strings instead of byte strings, and __repr__ should return a Unicode string in Python 3.
If you try to return a bytes object like some other answers suggest, you will get:
TypeError: __repr__ returned non-string (type bytes)
As I mentioned on my comment, BytesIO requires byte-like object.
Demo:
>>> from io import BytesIO
>>>
>>> b = BytesIO()
>>>
>>> b.write('TEST\n')
Traceback (most recent call last):
File "<pyshell#97>", line 1, in <module>
b.write('TEST\n')
TypeError: 'str' does not support the buffer interface
>>>
>>>
>>> b.write(b'TEST\n')
5
>>> v = b.getbuffer()
>>>
>>> v[2:4]=b'56'
>>>
>>> b.getvalue()
b'TE56\n'
So add to the beginning of your the param. in you pass to write method, b(for binary).
Related
I'm doing research on palmprint recognition. for that I use the edcc library for the introduction of the palmprint. but i have problem in saving the encoding result from palm. I want to save the encoding result into a file, but I get an error like below
Traceback (most recent call last):
File "/home/pi/Coba/PalmDetection/PalmRecognition.py", line 18, in <module>
pickle.dump(one_palmprint_code, config_dictionary_file)
_pickle.PicklingError: Can't pickle <class 'ctypes.c_char_Array_849'>: attribute lookup c_char_Array_849 on ctypes failed
My code like this :
import os
import edcc
import cv2
import pickle
TEST_PALMPRINT_DATA_DIR = "/home/pi/Coba/PalmDetection/Data"
TEST_A_01_PALMPRINT_IMAGE = os.path.join(TEST_PALMPRINT_DATA_DIR, "Palm1.jpeg")
#TEST_A_02_PALMPRINT_IMAGE = os.path.join(TEST_PALMPRINT_DATA_DIR, "a_02.bmp")
TEST_B_01_PALMPRINT_IMAGE = os.path.join(TEST_PALMPRINT_DATA_DIR, "palme.jpeg")
#TEST_B_02_PALMPRINT_IMAGE = os.path.join(TEST_PALMPRINT_DATA_DIR, "b_02.bmp")
if __name__ == "__main__":
config = edcc.EncoderConfig(29, 5, 5, 10)
encoder = edcc.create_encoder(config)
one_palmprint_code = encoder.encode_using_file(TEST_A_01_PALMPRINT_IMAGE)
with open('encode.encode', 'wb') as config_dictionary_file:
pickle.dump(one_palmprint_code, config_dictionary_file)
another_palmprint_code = encoder.encode_using_file(TEST_B_01_PALMPRINT_IMAGE)
similarity_score = one_palmprint_code.compare_to(another_palmprint_code)
print(
"{} <-> {} similarity score:{}".format(
TEST_A_01_PALMPRINT_IMAGE, TEST_B_01_PALMPRINT_IMAGE, similarity_score
)
)
What should i do?
The edcc module must use ctypes internally, but really should hide that fact instead of returning a ctypes-wrapped object. A ctypes.c_char_Array_849 is just a C-compatible wrapper around an array of bytes. You can access the equivalent Python bytes object via the .raw property (what edcc should return instead) and write that to the file:
import ctypes
import pickle
one_palmprint_code = (ctypes.c_char * 849)()
with open('encode.encode', 'wb') as config_dictionary_file:
#pickle.dump(one_palmprint_code, config_dictionary_file) # reproduces error
config_dictionary_file.write(one_palmprint_code.raw)
How could I convert the output of pickle.dumps into a string. I need to convert the output to a string.
Current, this what I got:
import pickle
class TestClass:
def __init__(self, number):
self.number = number
t1 = TestClass(14)
s1 = pickle.dumps(t1)
str_version = s1.decode('utf-8', 'backslashreplace')
print(pickle.loads(str_version.encode('utf-8', 'backslashreplace')))
But I'm getting the error:
Traceback (most recent call last):
File "C:\Users\ketha\Downloads\python_testing.py", line 11, in <module>
print(pickle.loads(str_version.encode('utf-8', 'backslashreplace')))
_pickle.UnpicklingError: invalid load key, '\x5c'.
I think this is because when I convert it to a string, it converts \x5c (for example) to \\x5c and doesn't undo this during decoding. How could I undo this?
I got some code working. Code:
import pickle
import sys
class TestClass:
def __init__(self, number):
self.number = number
t1 = TestClass(14)
s1 = pickle.dumps(t1)
str_version = s1.decode('unicode_escape')
decoded = pickle.loads(str_version.encode('utf-8', 'unicode_escape').replace(b'\xc2', b''))
print(decoded.number)
I use this code to encode and compress text. But it doesn't work properly:
Traceback (most recent call last): File "E:\SOUND.py", line 114, in <module>
unhexsring = str(zlib.decompress(unhexsring).encode('utf8'))
TypeError: a bytes-like object is required, not 'str'
Can you help me?
import zlib,gzip
def str2hex(s):
return binascii.hexlify(bytes(str.encode(s)))
def hex2str(h):
return binascii.unhexlify(h)
hexstring = input()
if len(hexstring) > 200:
hexstring = str(zlib.compress(hexstring.encode('utf-8')))
print(hexstring)
hexstring = str2hex(hexstring)
ph = str(hexstring.decode('utf-8'))
print(ph)
#decompressing text
unhexsring = hex2str(hexstring).decode('utf8')
if 'x' in str(unhexsring):
print('compressed')
unhexsring = str(zlib.decompress(unhexsring).encode('utf8'))
print(unhexsring)
This code will not decompress the zlib-compressed text.
So encoding work good.
My trouble is when I get encoded string and compress it I can't decompress it.
How should it works:
1>s = input('some text')
2>if len(s) > 200: s = str(zlib.compress(s.encode('utf-8')))
3>encoding it with str2hex()
4>decode it with hex2str()
5>str(zlib.decompress(unhexs).encode('utf8')) <---------- HERE
And I can't decompress it properly because getting this:
CONSOLE DUMP NEXT
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>>
========================= RESTART: E:\SOUND.py =========================
dghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjghdghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjghdghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjghdghlkdushfgkjdsfhglkjhsdfgjhdskfjhgkdsfhgkjdhfgkjsdhfgjkhsdkjfghlkjsdhgkjhsdfjghdksjhgkjsdhgkjhsdfkjghdskfjghkdjgh
b'x\x9c\xed\x8d\xb1\r\xc0#\x08\x03\x97\xb5\xb0e\x7f\x87\xb2\x7f\x9eO\x93\x05\xd2\xa5\x02\x1d>\x0cj\x05W\xab\x18\xa3K\\\xb1\x1aE\x0b\x9d\xb2\x98\x83\xf7\xf5dz\x86\xb3#q\x8d<\x84\x8fc\n\xe9Q^0C\xe7\x13\x15\xcc\xfe7~\xd0x\x03\x88\x05\xbb\x9d'
6227785c7839635c7865645c7838645c7862315c725c786330405c7830385c7830335c7839375c7862355c786230655c7837665c7838375c7862325c7837665c7839654f5c7839335c7830355c7864325c7861355c7830325c7831643e5c7830636a5c783035575c7861625c7831385c7861334b5c5c5c7862315c783161455c7830625c7839645c7862325c7839385c7838335c7866375c786635647a5c7838365c78623323715c7838643c5c7838345c783866635c6e5c786539515e30435c7865375c7831335c7831355c7863635c786665377e5c786430785c7830335c7838385c7830355c7862625c78396427
compressed
Traceback (most recent call last):
File "E:\SOUND.py", line 114, in <module>
unhexsring = str(zlib.decompress(unhexsring).encode('utf8'))
TypeError: a bytes-like object is required, not 'str'
The exception you see here:
unhexsring = str(zlib.decompress(unhexsring).encode('utf8'))
TypeError: a bytes-like object is required, not 'str'
is raised because zlib.decompress expects bytes. This is easily fixed by changing
unhexsring = hex2str(hexstring).decode('utf8') # -> str
to
unhexsring = hex2str(hexstring) # -> bytes
However this results in a new error:
unhexsring = zlib.decompress(unhexsring)
zlib.error: Error -3 while decompressing data: incorrect header check
This one is happening because of this line:
hexstring = str(zlib.compress(hexstring.encode('utf-8')))
Calling str on a bytes instance doesn't convert the bytes to str, it converts the bytes' repr to str.
>>> bs = 'Hello World'.encode('utf-8')
>>> print(repr(bs))
b'Hello World'
>>> s = str(bs)
>>> print(repr(s))
"b'Hello World'" # <- note the b....
The str conversion is inserting a 'b' at the front of the compressed data and so corrupting the header. Let's leave hexstring as a bytes object for now
hexstring = zlib.compress(hexstring.encode('utf-8'))
But now the code raises yet another exception:
return binascii.hexlify(bytes(str.encode(s)))
TypeError: descriptor 'encode' requires a 'str' object but received a 'bytes'
s is now a bytes object, so there's no need try to convert it (and note that str.encode returns bytes anyway, so the bytes call would be redundant even if s were a string).
So str2hex becomes
def str2hex(s):
return binascii.hexlify(s)
Now yet another error is raised:
unhexsring = str(zlib.decompress(unhexsring).encode('utf8'))
AttributeError: 'bytes' object has no attribute 'encode'
The output of zlib.decompress is a bytes object, so it's already encoded (assuming it was a string to begin with). You want to decode it to get a str:
unhexsring = zlib.decompress(unhexsring).decode('utf8')
This is a version of your code that can be run as a script from the command prompt:
import binascii
import random
import string
import zlib
def str2hex(s):
return binascii.hexlify(s)
def hex2str(h):
return binascii.unhexlify(h)
def main():
# I don't want to type 200+ chars to test this :-)
hexstring = ''.join(random.choices(string.ascii_letters, k=201))
hexstring = hexstring.encode('utf-8')
if len(hexstring) > 200:
hexstring = zlib.compress(hexstring)
print(hexstring)
hexstring = str2hex(hexstring)
ph = hexstring.decode('utf-8')
print(ph)
# decompressing text
unhexsring = hex2str(hexstring)
# Checking for 'x' in the string isn't a good way to check for
# compression. Try decoding first and if that fails we know we have
# compressed text.
try:
unhexsring = unhexsring.decode('utf-8')
except UnicodeDecodeError:
print('compressed')
unhexsring = zlib.decompress(unhexsring).decode('utf8')
print(unhexsring)
if __name__ == '__main__':
main()
Very interesting question ,I think that you should get rid of this
hexstring = input()
Simple example with your code
>>> s ='Vladimir'
>>> str.encode(s)
b'Vladimir'
>>> bytes(str.encode(s))
b'Vladimir'
>>> binascii.hexlify(bytes(str.encode(s)))
b'566c6164696d6972'
>>> binascii.unhexlify(b'566c6164696d6972')
b'Vladimir'
>>> import zlib,gzip
>>> hexstring = str(zlib.compress(s.encode('utf-8')))
>>> type (hexstring)
<class 'str'>
>>> type (s)
<class 'str'>
I was trying out Twitter API but it give me this error:
Traceback (most recent call last):
File "D:/MAGIC/python/twitterdemo.pu.py", line 23, in
text += status.text.encode('utf-8')
TypeError: Can't convert 'bytes' object to str implicitly
Here is my code:
import sys
import operator
import requests
import json
import twitter
from watson_developer_cloud import PersonalityInsightsV2 as PersonalityInsights
twitter_consumer_key = ''
twitter_consumer_secret = ''
twitter_access_token = ''
twitter_access_secret = ''
twitter_api = twitter.Api(consumer_key=twitter_consumer_key, consumer_secret=twitter_consumer_secret, access_token_key=twitter_access_token, access_token_secret=twitter_access_secret)
handle = "#somethingsoemthing"
statuses = twitter_api.GetUserTimeline(screen_name=handle, count=200, include_rts=False)
text = ""
for status in statuses:
print (status.text)
if(status.lang == 'en'): #Enligh tweets
text += status.text.encode('utf-8')
What am I doing wrong?
Your text is initialized as a str, and you're trying to add a bytes object (which is what status.text.encode('utf-8') returns) to it. Initialize text as a bytes object and that error should go away:
text = b''
Alternatively, you could skip encoding the text altogether and it should work:
text += status.text
My code is:
from random import randrange, choice
from string import ascii_lowercase as lc
from sys import maxsize
from time import ctime
tlds = ('com', 'edu', 'net', 'org', 'gov')
for i in range(randrange(5, 11)):
dtint = randrange(maxsize)
dtstr = ctime()
llen = randrange(4, 8)
login = ''.join(choice(lc)for j in range(llen))
dlen = randrange(llen, 13)
dom = ''.join(choice(lc) for j in range(dlen))
print('%s::%s#%s.%s::%d-%d-%d' % (dtstr, login,dom, choice(tlds),
dtint, llen, dlen), file='redata.txt')
I want to print the results in a text file but I get this error:
dtint, llen, dlen), file='redata.txt')
AttributeError: 'str' object has no attribute 'write'
file should be a file object, not a file name. File objects have write method, str objects don't.
From the doc on print:
The file argument must be an object with a write(string) method; if it
is not present or None, sys.stdout will be used.
Also note that the file should be open for writing:
with open('redata.txt', 'w') as redata: # note that it will overwrite old content
for i in range(randrange(5,11)):
...
print('...', file=redata)
See more about the open function here.