Google+ Pieces o' Eight

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.

7) We'll now make the share mount on boot. In the terminal type:
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.

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:

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:

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

Space Harrier 32X

Here's a quick video - level 1 of 32x Space Harrier played by me!


A random password generator in Python

For a recent project I needed to create a lot of random passwords. There are plenty of websites out there that can do this for you, but as I'm learning Python I thought I'd have a go at rolling my own solution.

My requirements were that each password be of a specified length and constructed from a random pick of the letters A-Z and a-z and the digits 0-9. I also wanted the function to return a phonetic spelling of each password. Here's what I came up with:


import random

def randomPasswordGenerator(length):
    upperCase = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    lowerCase = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
    numbers =   ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "1", "3", "5", "2", "4", "6"]
    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"}
                          
    all = [upperCase, lowerCase, numbers]
    password = []
    phoneticPassword = []
    
    for i in range(length):
        character = all[random.randint(0,2)][random.randint(0,25)]
        password.append(character)
        phoneticPassword.append(phoneticDictionary[character])

    return ''.join(password), '-'.join(phoneticPassword)

It's pretty simple. The function takes a length n and then loops n times randomly picking one of three lists (A-Z, a-z or 0-9) and then picks a random entry from that list.

The chosen character is then appended to the "password" list and also passed to the phonetic dictionary, which returns the phonetic spelling of the character and appends it to the "phoneticPassword" list. Finally the function returns the password and phonetic password by joining the arrays into strings.

Here's the output of the function run 10 times specifying a password length of 8:

FAhFh0fy FOXTROT-ALPHA-hotel-FOXTROT-hotel-Zero-foxtrot-yankee
46Ne3XNu Four-Six-NOVEMBER-echo-Three-XRAY-NOVEMBER-uniform
1PcCnBX2 One-PAPA-charlie-CHARLIE-november-BRAVO-XRAY-Two
qAYVAB75 quebec-ALPHA-YANKEE-VICTOR-ALPHA-BRAVO-Seven-Five
y41Q3w7l yankee-Four-One-QUEBEC-Three-whiskey-Seven-lima
4NW55yYH Four-NOVEMBER-WHISKEY-Five-Five-yankee-YANKEE-HOTEL
bjihtPPk bravo-juliet-india-hotel-tango-PAPA-PAPA-kilo
H56a0Ydf HOTEL-Five-Six-alpha-Zero-YANKEE-delta-foxtrot
KaQkrlk8 KILO-alpha-QUEBEC-kilo-romeo-lima-kilo-Eight
77m302O1 Seven-Seven-mike-Three-Zero-Two-OSCAR-One

You might have noticed that the numeric character list contains some repetition to get the list length up to 26. I did this largely for expediency, but it does create some bias in that the numbers 1-6 have a slightly higher chance of being picked than 0,7-9. I'm not sure if this makes much of a difference, but it's as well to aware that this could be a potential weakness of the algorithm.

Without a doubt you could achieve the same in practically any programming language. What I particularly liked about Python for this, however, was the immediacy of the scripting environment and the built-in methods - such as "join" - which negate having to write tedious boiler-plate code to stitch strings together.

Saturday, 9 April 2011

Fish! (A maths puzzle and a proposed solution)

A fish is made up of three parts: head, tail and body.

The tail is equal in length to the head, plus one-quarter of the length of the body.
The body is equal to three-quarters of the entire length of the fish.
The head is 4cm in length.


How long is the entire fish?

SOLUTION

Let's pose this in the following way:

T = Tail
B = Body
H = Head
L = Total Length

Therefore:
4 + 4 + 1/4 B + 3/4 L = L

Which can be simplified to give:
8 + 1/4B + 3/4L = L

Look also at the relationship between the Tail, Body and Total Length. The body, so we're told, is 3/4 of the Total Length and the fractional part of the tail is 1/4 of the length of the body. This means that we must be able to describe the fractional part of the tail in terms of the Total Length:

1/4 x 3/4 = 3/16

So the fractional part of the tail is 3/16 of the length of the fish!

Now we know that, we can work out what proportion of the fish the fractional part of the tail plus the body is:

3/16 + 3/4 = 3/16 + 12/16 = 15/16

So the fractional part of the tail and the body account for 15/16 of the Total Length, giving us:

8 + 15/16 L = L

What of the remaining 1/16 L? Well given the above, 1/16 L must be equal to 8 which means:

8 x 16 = Total Length = 128

So the fish must be 128cm in length! Lets try it:

1/16 L + 3/16 L + 12/16 L = 1/16 x 128 + 3/16 x 128 + 12/16 x 128 = 8 + 24 + 96 = 128