Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Saturday, July 28, 2012

Working With Binary Data in Python

This puzzled me for quite a time, so here is a post explaining some of my findings.
First we define a bytes array:
 s = bytearray(b"Hello World")
 for i in s: 
     print i
 ...
 72
 101
 108
 108
 111
 32
 87
 111
 114
 108
 100

now, let's write this data to a file:
 f = open('helloword.bin','wb')
 for i in s:                                                                                                                                       
    f.write(struct.pack("I",i))
 f.close()

Let's inspect the file created:
 
 $ du -h points.bin
 4.0K    points.bin
 $ file points.bin
 points.bin: data
 $ less points.bin
 "points.bin" may be a binary file.  See it anyway?

Binary file sizes

let's us write "hello world" into a text file in a text form:

 f = open('helloword.txt")
 f.write("hello world")
 f.close()

Once again we can inspect the file:

$ du -h   helloworld.txt
 4.0K    helloworld.txt


Now, what happens if we make a longer binary array?


 s.split()
 s.append(33)
 bytearray(b'Hello World!')
 for i in range(10000): s.append(33)
 f = open('longhelloword.bin', 'wb')
 import struct      
 for i in s: f.write(struct.pack("I",i))
 f.close()
 f = open('longhelloword.txt', 'w')
 hello = "Hello World!"
 for i in range(10000): hello = hello+"!"
In a shell, examaining the file sizes:
 
 $ du -h longhelloword.bin
 40K     longhelloword.bin
 $ du -h longhelloword.txt
 12K     longhelloword.txt

Wait a minute ! Why is the binary file almost 4 times bigger?

The answer is: it depends on the format specifier in struct.pack.
Namely, we used an unsigned int, for each character we then reserved 4 bytes!.
When we saved the text, every character was assigned to the file exactly as a char which takes one byte only.

If we repeat the above with struct.pack("b",i) the sizes of the file won't differ:

 f = open('longhellowordwithchar.bin', 'w')
 for i in s: f.write(struct.pack('b',i))
 f.close()

and in the shell:

 $ du  longhellowordwithchar.bin
 12      longhellowordwithchar.bin
 $ du  longhelloword.txt       
 12      longhelloword.txt

Credits:
http://dabeaz.blogspot.de/2010/01/few-useful-bytearray-tricks.html
http://docs.python.org/library/struct.html#module-struct

Friday, March 16, 2012

The weired Indexing in Perl

I am learning Perl. I am doing it with a lot of a resentment, but I am slowly learning it.
Normal people count from 1. Computer Scientist count from 0. Perl developers count from -1?

WTF?

oz@server ~ $ test.pl test
num of args 0 
oz@server ~ $ test.pl test test
num of args 1 
0
test
1
test
oz@server ~ $ test.pl          
num of args -1 
No arguments!
oz@server ~ $ 
My Code, just in case I am totally wrong about this here, :
$ cat test.pl 
#!/usr/local/bin/perl -w


print "num of args $#ARGV \n";
if ( $#ARGV > 0   ){

   for ( my $i = 0 ; $i <= $#ARGV  ; ++$i  ) {

   print "$i\n";
   print "$ARGV[$i]\n";
   }
}
if ( @ARGV > 0 )
{
  print "Number of arguments: " . scalar @ARGV . "\n";
}
else
{
print "No arguments!\n";
}