Thursday, March 04, 2010

Python exercise - alternative solution

I promised to post an alternative solution to a Python exercise for an on-site today. For other interested parties, the code lists unused ports from /etc/services:

import sys

# set the file name depending on the operating system
if sys.platform == 'win32':
file = r'C:\WINDOWS\system32\drivers\etc\services'
file = '/etc/services'

# Create an empty dictionary
ports = dict()

# Iterate through the file, one line at a time
for line in open(file):

# Ignore lines starting with '#' and those containing only whitespace
if line[0:1] != '#' and not line.isspace():

# Extract the second field (seperated by \s+)
pp = line.split(None, 1)[1]

# Extract the port number from port/protocol
port = pp.split ('/', 1)[0]

# Convert to int, then store as a dictionary key
port = int(port)
ports[port] = None

# Give up after port 200
if port > 200: break

# Print any port numbers not present as a dictionary key
for num in xrange(1,201):
if not num in ports:
print "Unused port", num

Here is a smaller solution using Regular Expressions:

import sys,re

file = r'C:\WINDOWS\system32\drivers\etc\services' \
if sys.platform == 'win32' else '/etc/services'

found = set()
for line in open(file):
m ='^[^#].*\s(\d+)/(tcpudp)\s',line)
if m:
port = int(m.groups()[0])
if port > 200: break

print set(range(1,201)) - found

1 comment:

Clive said...

By the way, some delegates have taken this as a challenge, and produced a solution based on sets which is tiny: I'll post.