Python Forum

Full Version: How to convert "str" to "int"
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hello I am currently reading a file in binary mode.

I do the reading with
with open (args.rom_path, 'rb') as file:
		rom_bytes = file.read ()			
Then part of these rom_bytes are transferred to another variable with:

self.header = rom_bytes [0:HEADER_SIZE]
and finally, one of the bytes stored in the header are transferred to a variable:

self.temp = self.header [4]
This value it is "2" in unsigned 8 bit, as a hexadecimal editor informs me.

However, the above line of code causes:

Quote:TypeError: 'int' does not support the buffer interface

So I need to convert into an int, a value that it is what, a byte?

How can I do it?
Take a look at the struct module.

import struct
four_bytes = b'abcd'  # sample bytesting
struct.unpack("I", four_bytes) # interpret bytesting as unsigned int
colt Wrote:However, the above line of code causes:
Are you sure it's this line that causes this error message? If 'header' is a bytes string (which you can check by printing the type of the variable) there should be no problem accessing header[4], and it must be an integer. In the worst case it could raise an IndexError.
(Oct-06-2019, 05:25 AM)scidam Wrote: [ -> ]Take a look at the struct module.

import struct
four_bytes = b'abcd'  # sample bytesting
struct.unpack("I", four_bytes) # interpret bytesting as unsigned int

From what I see the difference is that you used "I" instead my "h". I changed it and didn't change the error message.

(Oct-06-2019, 06:38 AM)Gribouillis Wrote: [ -> ]Are you sure it's this line that causes this error message? If 'header' is a bytes string (which you can check by printing the type of the variable) there should be no problem accessing header[4], and it must be an integer. In the worst case it could raise an IndexError.

It says line 11, which is the one that uses struct.unpack. I checked the type and it shows
Quote:<class 'bytes'>
colt Wrote:It says line 11, which is the one that uses struct.unpack
There is no struct.unpack in the original post. It will be much easier if you post the whole code that throws the exception, so that we can run it by ourselves.
(Oct-09-2019, 05:51 AM)Gribouillis Wrote: [ -> ]
colt Wrote:It says line 11, which is the one that uses struct.unpack
There is no struct.unpack in the original post. It will be much easier if you post the whole code that throws the exception, so that we can run it by ourselves.

Ok here it is:
from abc import ABCMeta, abstractmethod
import argparse

HEADER_SIZE = 16
KB_SIZE = 16384

class Instruction (object):
	__metaclass_ = ABCMeta
		
	def __init__ (self,identification_byte):
		identity_byte = identification_byte

	def test (self):
		print ("BOTO")

	@abstractmethod
	def process (self):
		print ("Identifier Byte: {}".format(self.identity_byte))

	@abstractmethod
	def process2 (self):
		print ("Identifier Byte2: ", self.identity_byte)
		

class LDAInstruction (Instruction):
	def process (self):
		super.process ()

	def process2 (self):
		super.process()

class ROM (object) :
	def __init__ (self, rom_bytes): 
		self.header = rom_bytes [0:HEADER_SIZE]
		self.temp = self.header [4]
		print (type (self.header))
		self.num_prg_blocks = struct.unpack ("I", self.temp)
		print (type (self.num_prg_blocks))
		self.data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + (16 + KB_SIZE * int (self.num_prg_blocks))]
		self.total_size = 16 + KB_SIZE * self.num_prg_blocks

	def get_byte (self, pc):
		return	(self.data_bytes [pc])

class CPU (object):
	def __init__(self, rom_bytes):
		self.registers = []
		self.rom = ROM (rom_bytes)
		self.pc = 0

	def process_instructions (self):
		for byte in self.rom.data_bytes:
			byte = self.rom.get_byte (self.pc)
			self.pc+=1
			print (byte)
			if (byte == 169):
				instruction = Instruction (byte)
				instruction.process ()
				instruction.process2 ()
			if (self.pc == 3):
				break

def main ():

	parser = argparse.ArgumentParser (description='NES EMULATOR'); 
	parser.add_argument ('rom_path',metavar='R',type=str,help='path to the rom')
	args=parser.parse_args()

	with open (args.rom_path, 'rb') as file:
		rom_bytes = file.read ()			

	cpu = CPU(rom_bytes)
	cpu.process_instructions ()

if __name__ == '__main__':
	main () 
However, this will not run because it needs a file as a command line argument.
Could it be an error similar to this one ?
>>> rom_bytes = b'hello world'
>>> import struct
>>> struct.unpack("I", rom_bytes[4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'int'
>>> struct.unpack("I", rom_bytes[:4])
(1819043176,)
(Oct-09-2019, 05:59 PM)Gribouillis Wrote: [ -> ]Could it be an error similar to this one ?
>>> rom_bytes = b'hello world'
>>> import struct
>>> struct.unpack("I", rom_bytes[4])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'int'
>>> struct.unpack("I", rom_bytes[:4])
(1819043176,)

I don't understand why would be, since is a different error message.

Anyway, I don't know why, but now the code is working on python 3.2, since it converts the values to int. However in 2.6 where the type is 'str', first I receive
Quote:self.data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + (16 + KB_SIZE *(self.num_prg_blocks))]
TypeError: unsupported operand type(s) for +: 'int' and 'str'


Then adding a int before with:

self.data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + (16 + KB_SIZE * int (self.num_prg_blocks))]
I receive:

Quote:ValueError: invalid literal for int() with base 10: '\x02'

finally doing this:

self.temp = self.num_prg_blocks
		struct.unpack ("I", self.temp)
        self.data_bytes = rom_bytes [HEADER_SIZE:HEADER_SIZE + (16 + KB_SIZE * self.temp)] 
makes me receive on python 2.6

Quote:struct.error: unpack requires a string argument of length 4

and on python 3.2

Quote:TypeError: 'int' does not support the buffer interface


What shall be my next step?
colt Wrote:I don't know why, but now the code is working on python 3.2, since it converts the values to int.
That's because in python 3 a bytes string is a sequence of small integers:
>>> # python 3
>>> x = b'\x02'
>>> x[0]
2
in python 2
>>> # python 2
>>> x = '\x02'
>>> x[0]
'\x02'
In python 2 you can convert a one character string to int by using the ord function
>>> ord(x[0])
2
But when calling struct.unpack ("I", self.temp), make sure self.temp is a 4 bytes string.

Finally, do you have to use python 2? Don't use it, it's dead.
(Oct-12-2019, 10:39 PM)Gribouillis Wrote: [ -> ]
colt Wrote:I don't know why, but now the code is working on python 3.2, since it converts the values to int.
That's because in python 3 a bytes string is a sequence of small integers:
>>> # python 3
>>> x = b'\x02'
>>> x[0]
2
in python 2
>>> # python 2
>>> x = '\x02'
>>> x[0]
'\x02'
In python 2 you can convert a one character string to int by using the ord function
>>> ord(x[0])
2
But when calling struct.unpack ("I", self.temp), make sure self.temp is a 4 bytes string.

Finally, do you have to use python 2? Don't use it, it's dead.

Tried
self.num_prg_blocks = ord (self.header [4])
and it solved this issue with old python, but with the new python I receive:
Quote:TypeError: ord() expected string of length 1, but int found

To answer, I do not HAVE to use it, as mandatory
Pages: 1 2