Omnimaga

General Discussion => Technology and Development => Computer Programming => Topic started by: Munchor on February 10, 2011, 04:05:52 pm

Title: I give up, I need help with Python
Post by: Munchor on February 10, 2011, 04:05:52 pm
Assemblex has been stuck because of the 8xp file maker...

Code: [Select]
def ExporTo8xp(event):
def to_binary(hex_string):
ints = [int(hex_string[i:i+2], 16) for i in range(0,len(hex_string),2)]
return struct.pack('B' * len(ints), *ints)

dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "8XP Files (*.8xp)|*.8xp", \
wx.SAVE | wx.OVERWRITE_PROMPT)

if dlg.ShowModal() == wx.ID_OK:

programData = self.inputText.GetValue()

self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')


filehandle.write(to_binary(finalProgram))
filehandle.close()

self.SetTitle('Assemblex - '+self.filename)

dlg.Destroy()

This is the GUI code for it, the programData variable is the Hexadecimal code given by the user...

However, all I need to move on is to create a 8xp file:

Code: [Select]
programData = self.inputText.GetValue()
Code: [Select]
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000029000D
0018000650524F47
52414D0000001800
1600BB6DCE0B

This is a sample code of an assembly program, I need to change the size of the program. I can count the length of it, so let's say it is 98 bytes:
> How can I make 98 bytes, what is the size of the program in the hex code of it?


I know this is very general, I'll try to give you more details when I can.
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 12, 2011, 04:50:10 pm
This is a sample code of an assembly program, I need to change the size of the program. I can count the length of it, so let's say it is 98 bytes:
> How can I make 98 bytes, what is the size of the program in the hex code of it?


I know this is very general, I'll try to give you more details when I can.

What do you mean by the size of the "program in the hex code"? Remember that two hex digits make up one byte.
Title: Re: I give up, I need help with Python
Post by: Binder News on February 12, 2011, 05:29:14 pm
I think he means: "How do I find the size of the file? And how do I get the checksum?"
Title: Re: I give up, I need help with Python
Post by: Munchor on February 12, 2011, 05:33:33 pm
I think he means: "How do I find the size of the file? And how do I get the checksum?"

No I don't. I mean I can get a size in bytes, I just can't make that size little endian...

Quote
53 (35h)        2 bytes        Length, in bytes, of the data section of the file. This number should be 57 (39h) bytes less than the file size.

http://www.cemetech.net/forum/viewtopic.php?p=132898#132898 (http://www.cemetech.net/forum/viewtopic.php?p=132898#132898)

Just like Deep Thought says there, I need the size - 57 bytes in little endian.

So let's say the file is 98 bytes (I can get that value, no issues there), 98-57 is 41. Then 41 in little endian is 4100. That is easy, but with larger files I don't know how to.

It's a python question. Any ideas?
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 12, 2011, 05:48:55 pm
I think he means: "How do I find the size of the file? And how do I get the checksum?"

No I don't. I mean I can get a size in bytes, I just can't make that size little endian...

Quote
53 (35h)        2 bytes        Length, in bytes, of the data section of the file. This number should be 57 (39h) bytes less than the file size.

http://www.cemetech.net/forum/viewtopic.php?p=132898#132898 (http://www.cemetech.net/forum/viewtopic.php?p=132898#132898)

Just like Deep Thought says there, I need the size - 57 bytes in little endian.

So let's say the file is 98 bytes (I can get that value, no issues there), 98-57 is 41. Then 41 in little endian is 4100. That is easy, but with larger files I don't know how to.

It's a python question. Any ideas?

Oh, that's easy. Take the number %256 (modulus), insert it as the first byte, then put the number /256 into the byte after it.
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 09:21:49 am

Oh, that's easy. Take the number %256 (modulus), insert it as the first byte, then put the number /256 into the byte after it.

Sorry, I can't understand.

Let's say the size, in bytes, is 98.
98-57=41
Then 41 in hex is 29.
29 in little endian is 2900.

I need a python code for that, the problem is the little endian/hex :S
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 13, 2011, 09:39:08 am

Oh, that's easy. Take the number %256 (modulus), insert it as the first byte, then put the number /256 into the byte after it.

Sorry, I can't understand.

Let's say the size, in bytes, is 98.
98-57=41
Then 41 in hex is 29.
29 in little endian is 2900.

I need a python code for that, the problem is the little endian/hex :S

Why would you subtract 57? If 98 is the number of bytes in the program, you add 57 to account for the header and stuff when calculating the overall filesize for the .8xp program, a small portion of which is the actual TI program.

But anyway, let's just say you want to convert the number 8811 to little-endian. Big-endian is easy; it's just hex(8811), which is 0x226B. But if you want to find the little-endian number, remember that little-endian is basically just flipping the bytes, putting the least-significant byte in front. So you want it to be 6B22, or 27426.

Since you're just flipping the bytes, you need to find the two bytes individually. The least-significant byte (the one that you want to put in front) is just 8811 % 256 (what you get as a remainder when you divide 8811 by 256), and the most-significant byte is 8811 / 256. So to combine the two, multiply the least-significant byte by 256 (to "force" it to become the byte in front), and add the other byte on.

So here's the code:

Code: (Python) [Select]
le = be % 256 * 256 + (be / 256)

where be is the big-endian number and le is the little-endian number.
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 10:03:15 am
I got it Deep Thought.

However, when doing this:

Code: [Select]
littleEndian = dataLengthBigEndian% 256 * 256 + (dataLengthBigEndian / 256)

I got this error:

Code: [Select]
littleEndian = dataLengthBigEndian% 256 * 256 + (dataLengthBigEndian / 256)
TypeError: not all arguments converted during string formatting


I think I know why: hex(number) will return something like 0x2A.

Now, should I divide 2A by hex(256)? Is that what you mean?


Thanks.

EDIT, I tried:

Code: [Select]
littleEndian = dataLengthBigEndian% hex(256) * hex(256) + (dataLengthBigEndian / hex(256))
And I got the same error, not sure what I should do, though (concerning hexadecimal objects and integers).
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 13, 2011, 10:38:01 am
No, never use hex(. hex( just converts a number into a hex string. Remember that a number is a number whether it's a decimal or a hex. 0x226B is exactly the same as 8811, so don't bother converting it to hex. To the computer it's all the same, anyway.

The only real time you'd ever use hex( would be if you wanted to display something that way.

Hope this helps?
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 10:49:54 am
No, never use hex(. hex( just converts a number into a hex string. Remember that a number is a number whether it's a decimal or a hex. 0x226B is exactly the same as 8811, so don't bother converting it to hex. To the computer it's all the same, anyway.

The only real time you'd ever use hex( would be if you wanted to display something that way.

Hope this helps?

I get it, then how do I get big-endian value?

dataLengthBigEndian = hex((len(programData)/2))

This is what I was doing :S
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 13, 2011, 11:28:07 am
Yeah, but because of hex(, dataLengthBigEndian is now a string. You can't do operations on a string.

Just replace that with

Code: (Python) [Select]
dataLengthBigEndian = len(programData)/2

Remember, whether it's in hex or decimal does not matter. It's exactly the same number.
Title: Re: I give up, I need help with Python
Post by: TheMindNinja on February 13, 2011, 12:24:20 pm
In Python, hex( will turn values into hex variables, so neither integers nor strings.

This makes it impossible to make calculus with it, I think, so you can use the integer values of hexadecimal variables for this type of calculus.
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 12:26:16 pm
In Python, hex( will turn values into hex variables, so neither integers nor strings.

This makes it impossible to make calculus with it, I think, so you can use the integer values of hexadecimal variables for this type of calculus.

Yeah I've just noticed :P Thanks and it seems like you're new, welcome!

Now, I already got to the point where I don't get errors when making 8xp files but still not creating valid 8xp files.

210100C9 This is what I entered.
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000010240D
0018000650524F47
52414D0000001800
1600BB6D210100C9
CE0B
This is the 8xp file it created.

Now, the size in the 8xp file created is 1024, which is certainly wrong since my program data size, in bytes, is 2 (bytes). This would make the little endian code be 0200, so something in my code is wrong:

Code: [Select]
def to_binary(hex_string):
ints = [int(hex_string[i:i+2], 16) for i in range(0,len(hex_string),2)]
return struct.pack('B' * len(ints), *ints)
programData = self.inputText.GetValue()

dataLengthBigEndian = len(programData)/2

littleEndian = dataLengthBigEndian %  256 * 256 + (dataLengthBigEndian / 256)


sample8xp = "2A2A54493833462A1A0A0046696C652067656E657261746564206279205761626269745369676E0000000000000000000000000000"""+str(littleEndian)+"0D0018000650524F4752414D00000018001600BB6D"+programData+"CE0B"


self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')


filehandle.write(to_binary(sample8xp))
                        filehandle.close()
Note: The identation is correct, any idea what's wrong? Thanks.
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 13, 2011, 12:54:34 pm
In Python, hex( will turn values into hex variables, so neither integers nor strings.

It's actually a string, and that's why you can't do math: http://docs.python.org/library/functions.html#hex

Welcome to Omnimaga, by the way :)

Now, the size in the 8xp file created is 1024, which is certainly wrong since my program data size, in bytes, is 2 (bytes). This would make the little endian code be 0200, so something in my code is wrong:

Um, how is that two bytes?

210100C9 is four bytes (eight nibbles).

And replace str(littleEndian) with hex(littleEndian)[2:]. Since you're dealing with a hex string, you need that to be a hex string too. (The [2:] is because hex( converts it into '0xHH' form.)
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 12:57:20 pm
1. Yeah, eight nibbles, 4 bytes, bad calculation XD
2. I know 1024 is the size, because:
...0010240D00180...

The 1024 is at the location where the size should be and I also added a print line to print the little endian value of the data section and it returned '1024'.
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 13, 2011, 12:58:15 pm
1. Yeah, eight nibbles, 4 bytes, bad calculation XD
2. I know 1024 is the size, because:
...0010240D00180...

The 1024 is at the location where the size should be and I also added a print line to print the little endian value of the data section and it returned '1024'.

See my edit above. Use hex(littleEndian)[2:] instead :)

EDIT: Dammit, new page >:(

So you don't have to click back, here's what I said:

And replace str(littleEndian) with hex(littleEndian)[2:]. Since you're dealing with a hex string, you need that to be a hex string too. (The [2:] is because hex( converts it into '0xHH' form.)
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 01:16:14 pm
210100C9
It returned this:
Code: [Select]
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
00000000004000D0
018000650524F475
2414D00000018001
600BB6D210100C9C
E00B

4000 is the size, but it was supposed to be 0400. So, am I missing a switch in the code?

Code: [Select]
def to_binary(hex_string):
ints = [int(hex_string[i:i+2], 16) for i in range(0,len(hex_string),2)]
return struct.pack('B' * len(ints), *ints)
   
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "8XP Files (*.8xp)|*.8xp", \
wx.SAVE | wx.OVERWRITE_PROMPT)

if dlg.ShowModal() == wx.ID_OK:

programData = self.inputText.GetValue()

dataLengthBigEndian = len(programData)/2

littleEndian = dataLengthBigEndian %  256 * 256 + (dataLengthBigEndian / 256)


sample8xp = "2A2A54493833462A1A0A0046696C652067656E657261746564206279205761626269745369676E0000000000000000000000000000"""+str(hex(littleEndian)[2:])+"0D0018000650524F4752414D00000018001600BB6D"+programData+"CE0B"

print littleEndian
print dataLengthBigEndian

self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'wb')


filehandle.write(to_binary(sample8xp))
filehandle.close()

self.SetTitle('Assemblex - '+self.filename)

dlg.Destroy()
Title: Re: I give up, I need help with Python
Post by: Deep Toaster on February 13, 2011, 01:18:07 pm
Don't bother doing str(hex(. hex( returns a string variable already. Try that, but I'm not sure if that's it...

EDIT: Hey, I figured it out!

Hold on...

EDIT2: Basically, it's this: When you do hex( when the length of data is 4, it returns '0x400'. See the problem? You slice it with [2:], and it becomes '400'. That's still not the value you want. You need to pad it so it's exactly 4 chars long.

A really crude (but simple) way to do it is to do something like

Code: (Python) [Select]
if len(le) == 3:
    le = '0' + le

Then put it in the data.

EDIT3: How about this:

(le if len(le) == 4 else ('0' + le))

where le is the little-endian hex string as found by hex(littleEndian)[2:].

Nice and concise? ;D
Title: Re: I give up, I need help with Python
Post by: Munchor on February 13, 2011, 01:44:48 pm
Code: [Select]
2A2A54493833462A
1A0A0046696C6520
67656E6572617465
6420627920576162
6269745369676E00
0000000000000000
000000000004000D
0018000650524F47
52414D0000001800
1600BB6D210100C9
CE0B

The size created seems perfect ;D