Google+ Pieces o' Eight

Sunday, 13 May 2012

Sunday, 22 April 2012

Captain Morgane and the Golden Turtle (PC Review)

Introduction

I'm a big fan of point-and-click adventures and have been ever since I first played the original Monkey Island some 20+ years ago. Sadly the genre is no longer a mainstay of video gaming, with new releases few and far between, so when I heard about Captain Morgane and the Golden Turtle - a new piratically themed point-and-click adventure - I immediately rushed out to buy it.

What follows is my (admittedly amateur) review of the PC version. Read on, me hearties, to see how she fared!



Wednesday, 18 April 2012

Using VB6/VBScript to connect to a SQL Server 2012 LocalDB instance

In a previous post I covered how to use Python to connect to a SQL Server 2012 LocalDB instance. In this post I'll show you how to connect via VB6/VBScript. As per the Python post, you'll need to download and install the SQL Server 2012 LocalDb software, along with the SQL Server Native Client 11 database driver. 

One of the key differences - and one that took me some time to figure out - is that you need to specify a slightly different connection string: 

connectionString = "Provider=SQLNCLI11;Data Source=(localdb)\v11.0;Integrated Security=SSPI;"


One of the gotchas I encountered was with the Integrated Security parameter. If this isn't set to SSPI, you'll get Multiple-Step OLE DB Operation Errors.

Here's a complete listing you should be able to copy into a VBScript file to test:

connectionString = "Provider=SQLNCLI11;Data Source=(localdb)\v11.0;Integrated Security=SSPI;"
Set conn = CreateObject("ADODB.Connection")
Set com = CreateObject("ADODB.Command")
conn.Open connectionString
set com.ActiveConnection = conn
com.CommandText = "SELECT 'Hello, World!'"
set rs = com.Execute
while not rs.eof
    msgbox CStr(rs.Fields(0))
    rs.movenext()
wend
conn.close 



Monday, 26 March 2012

Using Python to connect to a SQL Server 2012 LocalDb instance

One of the new features of SQL Server 2012 Express is the LocalDB installation. This is a standalone install of SQL Server Express designed to support local databases which, importantly, requires practically no configuration . Although the documentation hints that developers were Microsoft's primary consideration behind LocalDB, there are many scenarios where having a zero configuration install of SQL Server could be very useful, such as offering offline access to a LoB application without needing to port the data to different database engine or necessitating a full blown SQL Server Express install on a user's machine.

Today I was experimenting with getting Python to talk to SQL Server LocalDB's - which proved to be very easy indeed!

First up, you'll need to install SQL Server Express 2012 LocalDB: http://www.microsoft.com/betaexperience/pd/SQLEXPCTAV2/enus/default.aspx

Next up you'll want to install the latest Native Client Drivers (SQLNCLI11): http://www.microsoft.com/Download/en/details.aspx?id=29065 (it's about halfway down this page)

Once both of those are installed, you're pretty much ready to go.

My Python environment is 2.7.2 on Windows 32-Bit. Into this I've installed pyodbc 3.03. From there, fire up IDLE and enter:

import pyodbc
con = pyodbc.connect('Driver={SQL Server Native Client 11.0};Server=(localdb)\\v11.0;integrated security = true')


And that should be you connected and ready to use a LocalDB from Python!

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:

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.