[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Python byte[]'s - Help me port this crucial Java byte[] method

Posted on 2014-03-01
9
Medium Priority
?
397 Views
Last Modified: 2014-03-03
Hi
The following code is crucial, working code that I have been using in RTS projects that, now that I'm a Python convert, I need assistance in getting it right. It isn't obvious.

I might be suffering from lack of experience issues, even formatting.

This is the working Java code, below, that I'd like to  convert to Python that converts byte arrays to integers, and the other way.
I cant yet do a simple porting, if this even is simple?
Does Python even do static methods, for easy use from anywhere, or must I re-paste this into other classes? Should I make bytearrays.py with all these methods?
Thanks

public static byte[] intToByteArray(int value) {
		byte[] b = new byte[4];
		for (int i = 0; i < 4; i++) {
		int offset = (b.length - 1 - i) * 8;
		b[i] = (byte) ((value >>> offset) & 0xFF);
		}
		return b;
		}

Open in new window


public static int byteArrayToInt(byte[] b, int offset) {  #make offset 0 for beginning
		int value = 0;
		for (int i = 0; i < 4; i++) {
		int shift = (4 - 1 - i) * 8;
		value += (b[i + offset] & 0x000000FF) << shift;
		}
		return value;
		}

Open in new window

0
Comment
Question by:beavoid
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 29

Expert Comment

by:pepr
ID: 39900197
Try the following, but they are written as functions, not as methons. No need for methods here:
def intToBytes(n):
    b = bytearray([0, 0, 0, 0])   # init
    b[3] = n & 0xFF
    n >>= 8
    b[2] = n & 0xFF
    n >>= 8
    b[1] = n & 0xFF
    n >>= 8
    b[0] = n & 0xFF    
    
    # Return the result or as bytearray or as bytes (commented out)
    ##return bytes(b)  # uncomment if you need
    return b
    
    
def bytesToInt(b, offset):
    n = (b[offset+0]<<24) + (b[offset+1]<<16) + (b[offset+2]<<8) + b[offset+3]
    return n

Open in new window

0
 

Author Comment

by:beavoid
ID: 39900410
Thanks for those functions,

but, for some absurd reason, they are not visible from my run method, and I don't know why Python's visibility is non-intuitive?

In my code below, it complains that intToBytes is not visible, when it is the first thing defined!

What could I be doing wrong?
Thanks

import threading, socket

class Server(threading.Thread):

    def intToBytes(n):
        print ("_________intToBytes___________")
        b = bytearray([0, 0, 0, 0])   # init
        b[3] = n & 0xFF
        n >>= 8
        b[2] = n & 0xFF
        n >>= 8
        b[1] = n & 0xFF
        n >>= 8
        b[0] = n & 0xFF    
    
    # Return the result or as bytearray or as bytes (commented out)
    ##return bytes(b)  # uncomment if you need
        return b

    
    
    def bytesToInt(b, offset):
        n = (b[offset+0]<<24) + (b[offset+1]<<16) + (b[offset+2]<<8) + b[offset+3]
        return n



    
    def __init__(self, numclients):
        threading.Thread.__init__(self) # call parent class's __init__ 
        print('Server constructor: ')
        self.numClients=numclients
        print(self.numClients, " clients")
        





    
        
    def run(self):
        
        print('Server run() . . . client join:')

        
        B=intToBytes(150)
       
        print(B[0])
        print(" . ")
        print([1])
        print(" . ")
        print([2])
        print(" . ")
        print([3])
        print(" . ")

        clientJoinMode=True
        
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        port = 1024
        bufferSize = 1024
        s.bind(("", port))

        
        while clientJoinMode :   # CLIENT JOIN LOOP
            
            print ('JOIN waiting on port: ', port)
            
            data, addr = s.recvfrom(bufferSize)
            print ('s received from address ', addr, ': ',data[0]);

            
        


serverThread=Server(2)
serverThread.start()

Open in new window

0
 
LVL 29

Expert Comment

by:pepr
ID: 39900438
Or you place them as functions outside the class definition, or add self as the very first argument. In the later case, you also should prepend self. when calling the methods. It must be explicitly written in Python. This means that then your line 47 must look like B = self.intToBytes(150)
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:beavoid
ID: 39900477
Thanks.

How would you make my run method look like to work? It isn't obvious. - Just a conversion, and a printing of the bytes.
Would you make an external .py file with all the byte[] conversion methods?
0
 
LVL 29

Accepted Solution

by:
pepr earned 2000 total points
ID: 39900514
Try
import threading, socket

class Server(threading.Thread):

    def intToBytes(self, n):
        print ("_________intToBytes___________")
        b = bytearray([0, 0, 0, 0])   # init
        b[3] = n & 0xFF
        n >>= 8
        b[2] = n & 0xFF
        n >>= 8
        b[1] = n & 0xFF
        n >>= 8
        b[0] = n & 0xFF    
    
        # Return the result or as bytearray
        return b

    
    
    def bytesToInt(self, b, offset):
        n = (b[offset+0]<<24) + (b[offset+1]<<16) + (b[offset+2]<<8) + b[offset+3]
        return n



    
    def __init__(self, numclients):
        threading.Thread.__init__(self) # call parent class's __init__ 
        print('Server constructor: ')
        self.numClients=numclients
        print(self.numClients, " clients")
        

    
        
    def run(self):
        
        print('Server run() . . . client join:')

        
        B = self.intToBytes(150)
       
        print(B[0])
        print(" . ")
        print(B[1])
        print(" . ")
        print(B[2])
        print(" . ")
        print(B[3])
        print(" . ")

        clientJoinMode=True
        
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        port = 1024
        bufferSize = 1024
        s.bind(("", port))

        
        while clientJoinMode :   # CLIENT JOIN LOOP
            
            print ('JOIN waiting on port: ', port)
            
            data, addr = s.recvfrom(bufferSize)
            print ('s received from address ', addr, ': ',data[0]);
          
        


serverThread=Server(2)
serverThread.start()

Open in new window

It should print your 150 as four values in the bytes. Notice also the added B's in the print commands.
0
 

Author Closing Comment

by:beavoid
ID: 39900590
Thanks
Why did I get visibility errors? I'd like to avoid that mistake again!
"self" must be first in the arguments declarations? Makes sense
0
 

Author Comment

by:beavoid
ID: 39900637
Thanks again
One last thing,

if I convert -256 to bytes, and try to print it back at the end, I don't get -256,
I get  4294967040
it prints 255 255 255 0 as the four bytes

       B = self.intToBytes(-256)
       
        print(B[0])
        print(" . ")
        print(B[1])
        print(" . ")
        print(B[2])
        print(" . ")
        print(B[3])
        print(" . ")
        print(self.bytesToInt(B,0))

Open in new window

0
 
LVL 29

Expert Comment

by:pepr
ID: 39901777
This is because of how the negative numbers are expressed. Think about a single byte that has 8 bits. One can express 2^8 = 256 states using 8 bits. But you can decide how the states will be used for encoding numbers. The most natural (in some sense) is to use one byte for expressing numbers from zero to 255 (that is 256 states). If you need to express also negative values, then the most natural is to use half of the interval for positive numbers (here from zero to 127), and approximately the other half for the negative values (from minus one to -128). For negative values, the most significant bit of the number is set to one, and the shift to right puts one's to that bit. This is the reason why the all ones appeared. There is the agreement that the bytes and bytearray types interpret the values as small positive integers. This way the byte with all bits set to one is displayed as 255.
0
 
LVL 29

Expert Comment

by:pepr
ID: 39901804
For the self, yes. It must be explicitly declared in Python as the first argument. It could be given a different identifier but it is highly recommended to keep that convention.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question