Sunday, 1 January 2012
iControlPad Review with HTC Desire HD
Mobile gaming is taking off in a big way but not, as many might have supposed, thanks to the efforts of Microsoft, Nintendo or Sony. No, instead the biggest player in the mobile gaming is scene is the humble mobile phone. To describe a modern smart-phone as humble is, of course, entirely misleading. The latest models from the likes of Apple, HTC, Samsung et al are all fully-fledged handheld computers featuring multi-core processors, graphics accelerators, huge amounts of RAM and enough storage space to make even the largest titles viable.
Saturday, 31 December 2011
Understanding eBay/PayPal fees
Selling things on eBay used to be a pretty simple and straightforward affair. The costs were fairly easy to understand and people, generally speaking, were happy. Then eBay bought PayPal which should have made things even easier for all concerned, but strangely (or not so strangely) has resulted in a multitude of costs, fees and other considerations that directly impact your bottom line. I wouldn't exactly call these "hidden" costs, but nor would I describe them as "well advertised" and could certainly catch the unwary seller off-guard. Here is a brief guide on what to watch out for.
Sunday, 11 December 2011
An implementation of LZW compression in Python
I've been doing some research on data compression and differencing recently and came across an excellent article by Mark Nelson on the LZW compression algorithm: http://marknelson.us/2011/11/08/lzw-revisited/
It's well worth a read, however all the code examples are in C++ so I decided to implement LZW in Python to enhance my understanding of the algorithm.
To start with we need something to compress. I picked the opening paragraph from George Orwell's 1984:
The next step is to initialize a dictionary with all possible single character codes:
Here's the compressor:
To decompress the data we just compressed, we need to initialize another dictionary containing all possible single character codes. In order for the algorithm to work, this dictionary needs to be the same as the dictionary used to compress the data:
You might have noticed that whilst this new dictionary contains the same data as the first the Keys and Values have swapped positions.
Here's the decompressor:
Finally, let's take a peek at the codes the compressor created and also display the decompressed string:
Conclusion
LZW is a pretty clever algorithm, but is also pretty easy to implement. Part of the cleverness is the way the decompressor is able to reconstruct the code dictionary used by the compressor on-the-fly and does not require the dictionary to be sent with the data.
My implementation is incomplete as it doesn't put a restriction on the number of codes generated and used, specify the control character or interface with files or streams external to the script, but even so I found it to be a useful examination of LZW and a good introduction to the techniques of lossless data compression.
It's well worth a read, however all the code examples are in C++ so I decided to implement LZW in Python to enhance my understanding of the algorithm.
To start with we need something to compress. I picked the opening paragraph from George Orwell's 1984:
string = """It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith, his chin nuzzled into his breast in an effort to escape the vile wind, slipped quickly through the glass doors of Victory Mansions, though not quickly enough to prevent a swirl of gritty dust from entering along with him."""
The next step is to initialize a dictionary with all possible single character codes:
codes = dict([(chr(x), x) for x in range(256)])
Here's the compressor:
compressed_data = [] code_count = 257 current_string = "" for c in string: current_string = current_string + c if not (codes.has_key(current_string)): codes[current_string] = code_count compressed_data.append(codes[current_string[:-1]]) code_count += 1 current_string = c compressed_data.append(codes[current_string])A couple of quick notes: I'm using a list - compressed_data - to store the compressed data, in the real world you'd probably want to use a file. You may also notice that code_count is initialized to 257, whilst the dictionary only has codes 0-255. What happened to 256? This is reserved for a control character, which I haven't implemented.
To decompress the data we just compressed, we need to initialize another dictionary containing all possible single character codes. In order for the algorithm to work, this dictionary needs to be the same as the dictionary used to compress the data:
strings = dict([(x, chr(x)) for x in range(256)])
You might have noticed that whilst this new dictionary contains the same data as the first the Keys and Values have swapped positions.
Here's the decompressor:
next_code = 257 decompressed_string = "" previous_string = "" for c in compressed_data: if not (strings.has_key(c)): strings[c] = previous_string + (previous_string[0]) decompressed_string += strings[c] if not(len(previous_string) == 0): strings[next_code] = previous_string + (strings[c][0]) next_code +=1 previous_string = strings[c]Again, next_code reserves 256 for an un-implemented control character. Also you'll see that I'm decompressing the data to a string, decompressed_string.
Finally, let's take a peek at the codes the compressor created and also display the decompressed string:
print "".join(str(compressed_data)) print decompressed_string
Conclusion
LZW is a pretty clever algorithm, but is also pretty easy to implement. Part of the cleverness is the way the decompressor is able to reconstruct the code dictionary used by the compressor on-the-fly and does not require the dictionary to be sent with the data.
My implementation is incomplete as it doesn't put a restriction on the number of codes generated and used, specify the control character or interface with files or streams external to the script, but even so I found it to be a useful examination of LZW and a good introduction to the techniques of lossless data compression.
Friday, 7 October 2011
Setup Virtual Box shared folders with Linux Mint guest
Here's how to setup Virtual Box shared folders with a Windows 7 host and a Linux Mint 11 guest and have it automatically mount in Linux Mint on boot.
Software used:
Windows 7 (host OS)
Linux Mint 11 (guest OS)
VirtualBox v4.1.4
Instructions
1) Create a folder on your host machine - I created mine in the root of C: and called it Shared.
2) Start your Linux Mint virtual machine.
3) Once booted, click the Virtual Box Devices > Shared Folders... menu option:
4) Make sure Machine Folders is selected and click the Add button:
5) Navigate to the shared folder on the host and tick the Make Permanent box.
6) In Linux Mint we now want to create a folder where the shared folder will be "mounted". Open a terminal and type:
sudo mkdir /mnt/shared
and enter your password when prompted.
sudo mkdir /mnt/shared
and enter your password when prompted.
7) We'll now make the share mount on boot. In the terminal type:
sudo gedit /etc/fstab
sudo gedit /etc/fstab
8) At the bottom of the file add a new line that reads:
Shared /mnt/Shared vboxsf default 0 1
9) Save the file and reboot Linux Mint.
10) If everything went to plan, you should now be able to navigate to /mnt/Shared and view the shared folder!
How to: Install FreeBSD on Windows Virtual PC
DON'T BOTHER! YOU'LL ONLY WASTE YOUR TIME!
It took me about four hours to realise this, but Microsoft really don't want you hosting non-Microsoft operating systems in Windows Virtual PC. 95, 98, XP, Vista and hell even 7 hosting 7 works fine. Try a *nix O/S though and you're out of luck.
By the time I'd finally got FreeBSD installed - after much piss-balling about with vhd's - I thought I was on to a winner. But no. The cocking thing wouldn't boot and entered an eternal "Kernel Panic" reboot mode. Then, for fun, it did boot but wouldn't reboot properly. And finally, just for the kicks, it decided that the vhd was no longer a valid boot device!
I don't blame the FreeBSD lot for this. I installed VirtualBox and FreeBSD into it on the same machine and that worked fine. I'd suggest you do the same if you fell into the same Microsoft trap I fell into.
It took me about four hours to realise this, but Microsoft really don't want you hosting non-Microsoft operating systems in Windows Virtual PC. 95, 98, XP, Vista and hell even 7 hosting 7 works fine. Try a *nix O/S though and you're out of luck.
By the time I'd finally got FreeBSD installed - after much piss-balling about with vhd's - I thought I was on to a winner. But no. The cocking thing wouldn't boot and entered an eternal "Kernel Panic" reboot mode. Then, for fun, it did boot but wouldn't reboot properly. And finally, just for the kicks, it decided that the vhd was no longer a valid boot device!
I don't blame the FreeBSD lot for this. I installed VirtualBox and FreeBSD into it on the same machine and that worked fine. I'd suggest you do the same if you fell into the same Microsoft trap I fell into.
Thursday, 6 October 2011
List comprehensions are cool!
Lists - or arrays - are an essential part of programming. While their usage varies depending on the problem being solved, the typical method of constructing one is to create a loop and append each new item to an array or list, as the following pseudo-code shows:
While this is perfectly ok, Python - and indeed other languages - provide an alternate method of creating lists based on existing lists known as list comprehensions. Lets see how the above pseudo-code example could be implemented in a Python list comprehension:
The first and most immediate benefit is that the list comprehension took only one line of code to implement. This cuts down on the amount of boiler-plate required to do something as common as creating a list and also has the effect of making the code easier to read.
What if we wanted to build a list containing only the even numbers in the range? Well this is catered for by including an if clause in the comprehension:
(Here I used the modulo division operator to only append the item (i) to the list if the remainder of the division i/2 is equal to 0)
List comprehensions aren't just for ranges of numbers:
In this example I'm scanning through a string and only appending the character to the list if it appears in the string "abcdef", and:
here I'm looking though the directories in my Photos directory and only appending those directories that start with the word Holiday.
As you can probably see from those few trivial examples, list comprehensions are pretty flexible and powerful and they save a considerable amount of time!
myList = new List for i = 0 to 9 myList.append(i) end for
While this is perfectly ok, Python - and indeed other languages - provide an alternate method of creating lists based on existing lists known as list comprehensions. Lets see how the above pseudo-code example could be implemented in a Python list comprehension:
[i for i in range(10)]
The first and most immediate benefit is that the list comprehension took only one line of code to implement. This cuts down on the amount of boiler-plate required to do something as common as creating a list and also has the effect of making the code easier to read.
What if we wanted to build a list containing only the even numbers in the range? Well this is catered for by including an if clause in the comprehension:
[i for i in range(10) if i%2 == 0]
(Here I used the modulo division operator to only append the item (i) to the list if the remainder of the division i/2 is equal to 0)
List comprehensions aren't just for ranges of numbers:
[c for c in "abjkfghi" if c in "abcdef"]
In this example I'm scanning through a string and only appending the character to the list if it appears in the string "abcdef", and:
[d for d in os.listdir(r"C:\Photos") if d.startswith("Holiday")]
here I'm looking though the directories in my Photos directory and only appending those directories that start with the word Holiday.
As you can probably see from those few trivial examples, list comprehensions are pretty flexible and powerful and they save a considerable amount of time!
Saturday, 24 September 2011
Improving my random password generator in Python
Learning Python is a great programming experience. The immediacy of the environment lends itself perfectly to experimentation, trying out new things and a very iterative approach to coding.
Previously I wrote a random password generator in Python. This worked well, but had a couple of problems. The first, identified at the time, was that there was a slight bias in the algorithm which would return certain characters more often than others. A second problem, identified after some pondering, was the inclusion of some redundant code. That version of the function had three lists and a dictionary - could this be consolidated down to just the dictionary? As it happens... YES!
The typical usage of dictionaries is to pass in a key to obtain a value. However, it's perfectly possible to obtain a key, value or both by supplying an index using a dictionary's .keys(), .values() or .items() methods and supplying the index such as:
This means, of course, that it would be possible to get a randomly generated index from the dictionary, like so:
Knowing this meant I was able to alter my code to get rid of the three lists and use just the dictionary itself. It also got rid of the bias noted earlier.
Here's the complete listing:
And here's the function's output run 10 times specifying a length of 8:
Previously I wrote a random password generator in Python. This worked well, but had a couple of problems. The first, identified at the time, was that there was a slight bias in the algorithm which would return certain characters more often than others. A second problem, identified after some pondering, was the inclusion of some redundant code. That version of the function had three lists and a dictionary - could this be consolidated down to just the dictionary? As it happens... YES!
The typical usage of dictionaries is to pass in a key to obtain a value. However, it's perfectly possible to obtain a key, value or both by supplying an index using a dictionary's .keys(), .values() or .items() methods and supplying the index such as:
phoneticDictionary.items()[15]
This means, of course, that it would be possible to get a randomly generated index from the dictionary, like so:
phoneticDictionary.items()[random.randint(0, 61)]
Knowing this meant I was able to alter my code to get rid of the three lists and use just the dictionary itself. It also got rid of the bias noted earlier.
Here's the complete listing:
import random
def getRandomPassword(length):
phoneticDictionary = {"A" : "ALPHA",
"B" : "BRAVO",
"C" : "CHARLIE",
"D" : "DELTA",
"E" : "ECHO",
"F" : "FOXTROT",
"G" : "GOLF",
"H" : "HOTEL",
"I" : "INDIA",
"J" : "JULIET",
"K" : "KILO",
"L" : "LIMA",
"M" : "MIKE",
"N" : "NOVEMBER",
"O" : "OSCAR",
"P" : "PAPA",
"Q" : "QUEBEC",
"R" : "ROMEO",
"S" : "SIERRA",
"T" : "TANGO",
"U" : "UNIFORM",
"V" : "VICTOR",
"W" : "WHISKEY",
"X" : "XRAY",
"Y" : "YANKEE",
"Z" : "ZULU",
"a" : "alpha",
"b" : "bravo",
"c" : "charlie",
"d" : "delta",
"e" : "echo",
"f" : "foxtrot",
"g" : "golf",
"h" : "hotel",
"i" : "india",
"j" : "juliet",
"k" : "kilo",
"l" : "lima",
"m" : "mike",
"n" : "november",
"o" : "oscar",
"p" : "papa",
"q" : "quebec",
"r" : "romeo",
"s" : "sierra",
"t" : "tango",
"u" : "uniform",
"v" : "victor",
"w" : "whiskey",
"x" : "xray",
"y" : "yankee",
"z" : "zulu",
"0" : "Zero",
"1" : "One",
"2" : "Two",
"3" : "Three",
"4" : "Four",
"5" : "Five",
"6" : "Six",
"7" : "Seven",
"8" : "Eight",
"9" : "Nine"}
password = []
phoneticPassword = []
for i in range(length):
c, pc = phoneticDictionary.items()[random.randint(0, 61)]
password.append(c)
phoneticPassword.append(pc)
return "".join(password), "-".join(phoneticPassword)
And here's the function's output run 10 times specifying a length of 8:
pnReI0lg papa-november-ROMEO-echo-INDIA-Zero-lima-golf 7g7SnNKl Seven-golf-Seven-SIERRA-november-NOVEMBER-KILO-lima 7Q3Zy4Ya Seven-QUEBEC-Three-ZULU-yankee-Four-YANKEE-alpha 697vxMRX Six-Nine-Seven-victor-xray-MIKE-ROMEO-XRAY R214zUMk ROMEO-Two-One-Four-zulu-UNIFORM-MIKE-kilo f0db3LbG foxtrot-Zero-delta-bravo-Three-LIMA-bravo-GOLF IC9046VT INDIA-CHARLIE-Nine-Zero-Four-Six-VICTOR-TANGO 8mg5Vufa Eight-mike-golf-Five-VICTOR-uniform-foxtrot-alpha C2Puu9dc CHARLIE-Two-PAPA-uniform-uniform-Nine-delta-charlie tcK6OCsG tango-charlie-KILO-Six-OSCAR-CHARLIE-sierra-GOLF
Subscribe to:
Posts (Atom)



