Quantcast
Channel: 懒得折腾
Viewing all 764 articles
Browse latest View live

Computational Photography Programming Assignment 1

$
0
0

part0.py

import sys
import os
import numpy as np
import random
import cv2
import run

def convolve(image, kernel):
  '''Convolve the given image and kernel

  Inputs:

  image - a single channel (rows, cols) image with dtype uint8

  kernel - a matrix of shape (d, d) and dtype float

  Outputs:

  output - an output array of the same dtype as image, and of shape
  (rows - d + 1, cols - d + 1)
 
  Every element of output should contain the application of the kernel to the
  corresponding location in the image.

  Output elements that result in values that are greater than 255 should be 
  cropped to 255, and output values less than 0 should be set to 0.
  '''
  output = None
  # Insert your code here.----------------------------------------------------
  (rows, cols) = image.shape
  (drows, dcols) = kernel.shape
  d = 0
  if drows != dcols:
    raise ValueError('The kernel must be a square')
  else:
    d = drows
  if (d % 2 != 1):
    raise ValueError('The kernel size must be a odd number')
  k = (d - 1)/2
  output = np.zeros((rows - d + 1, cols - d + 1), dtype = np.uint8)
  for i in range(rows - d + 1):
    for j in range(cols - d + 1):
      result = 0
      for u in range(-k, k + 1):
        for v in range(-k, k + 1):
          result = result + kernel[u + k, v + k] * image[i - u + k, j - v + k]
      if (result < 0):
          result = 0
      if (result > 255):
          result = 255
      output[i, j] = result
  #---------------------------------------------------------------------------
  return output 

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''
  images = []
  kernels = []
  outputs = []

  x = np.zeros((9,9), dtype = np.uint8)
  x[4,4] = 255 
  images.append(x)

  x = np.zeros((5,5), dtype = np.uint8)
  x[2,2] = 255 
  images.append(x)

  y = np.array(
      [[-0.9,-0.7, 0.5, 0.3, 0.0],
       [-0.7, 0.5, 0.3, 0.0, 0.4],
       [ 0.5, 0.1, 0.0, 0.4, 0.6],
       [ 0.1, 0.0, 0.2, 0.6, 0.8],
       [ 0.0, 0.2, 0.6, 0.8, 1.2]])
  kernels.append(y)

  y = np.array(
      [[0.1, 0.1, 0.1],
       [0.1, 0.2, 0.1],
       [0.1, 0.1, 0.1]])
  kernels.append(y)

  z = np.array(
      [[   0,   0, 127,  76,   0],
       [   0, 127,  76,   0, 102],
       [ 127,  25,   0, 102, 153],
       [  25,   0,  51, 153, 204],
       [   0,  51, 153, 204, 255]], dtype = np.uint8)
  outputs.append(z)

  z = np.array(
      [[ 25,  25,  25],
       [ 25,  51,  25],
       [ 25,  25,  25]], dtype = np.uint8)
  outputs.append(z)

  for image, kernel, output in zip(images, kernels, outputs):
    if __name__ == "__main__":
      print "image:\n{}".format(image)
      print "kernel:\n{}".format(kernel)

    usr_out = convolve(image, kernel)

    if not type(usr_out) == type(output):
      if __name__ == "__main__":
        print "Error- output has type {}. Expected type is {}.".format(
            type(usr_out), type(output))
      return False

    if not usr_out.shape == output.shape:
      if __name__ == "__main__":
        print "Error- output has shape {}. Expected shape is {}.".format(
            usr_out.shape, output.shape)
      return False

    if not usr_out.dtype == output.dtype:
      if __name__ == "__main__":
        print "Error- output has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, output.dtype)
      return False

    if not np.all(usr_out == output):
      if __name__ == "__main__":
        print "Error- output has value:\n{}\nExpected value:\n{}".format(
            usr_out, output)
      return False
    if __name__ == "__main__":
      print "Passed."

  if __name__ == "__main__":
    print "Success."
  return True

if __name__ == "__main__":
  # Testing code
  print "Performing unit test."
  test()

part1.py

import sys
import os
import numpy as np
from scipy import signal
import math
import random
import cv2
import run

def make_gaussian(k, std):
  '''Create a gaussian kernel.
  
  Input:

  k - the radius of the kernel.
  
  std - the standard deviation of the kernel.
  
  Output:

  output - a numpy array of shape (2k+1, 2k+1) and dtype float.
  
  If gaussian_1d is a gaussian filter of length 2k+1 in one dimension, 
  kernel[i,j] should be filled with the product of gaussian_1d[i] and 
  gaussian_1d[j].
 
  Once all the points are filled, the kernel should be scaled so that the sum
  of all cells is equal to one.'''
  kernel = None
  # Insert your code here.----------------------------------------------------
  kernel = np.zeros((2 * k + 1, 2 * k + 1), dtype = np.float)
  #---------------------------------------------------------------------------
  gaussian_1d = np.zeros((2 * k + 1), dtype = np.float)
  for i in range(-k, k + 1):
    gaussian_1d[i + k] = math.exp(-0.5*i*i/(std*std))
  total = 0
  for u in range(-k, k + 1):
    for v in range(-k, k + 1):
      kernel[u + k, v + k] = gaussian_1d[u + k] * gaussian_1d[v + k]  #math.exp(-(u*u + v*v)/(std*std))/(2*math.pi*std*std)
      total = total + kernel[u + k, v + k]
  for u in range(-k, k + 1):
    for v in range(-k, k + 1):
      kernel[u + k, v + k] = kernel[u + k, v + k]/total
  return kernel

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''

  np.set_printoptions(precision=3)

  ks =  [1, 2, 1, 2, 1]
  sds = [1, 2, 3, 4, 5]
  outputs = []
  # 1,1
  y = np.array([[ 0.075,  0.124,  0.075],
             [ 0.124,  0.204,  0.124],
             [ 0.075,  0.124,  0.075]])
  outputs.append(y)
  # 2,2
  y = np.array([[ 0.023,  0.034,  0.038,  0.034,  0.023],
             [ 0.034,  0.049,  0.056,  0.049,  0.034],
             [ 0.038,  0.056,  0.063,  0.056,  0.038],
             [ 0.034,  0.049,  0.056,  0.049,  0.034],
             [ 0.023,  0.034,  0.038,  0.034,  0.023]])
  outputs.append(y)
  # 1,3
  y = np.array([[ 0.107,  0.113,  0.107],
             [ 0.113,  0.120,  0.113],
             [ 0.107,  0.113,  0.107]])
  outputs.append(y)
  # 2,4
  y = np.array([[ 0.035,  0.039,  0.04 ,  0.039,  0.035],
             [ 0.039,  0.042,  0.044,  0.042,  0.039],
             [ 0.04 ,  0.044,  0.045,  0.044,  0.04 ],
             [ 0.039,  0.042,  0.044,  0.042,  0.039],
             [ 0.035,  0.039,  0.04 ,  0.039,  0.035]])
  outputs.append(y)
  # 1,5
  y = np.array([[ 0.11 ,  0.112,  0.11 ],
             [ 0.112,  0.114,  0.112],
             [ 0.11 ,  0.112,  0.11 ]])
  outputs.append(y)

  for k, sd, output in zip(ks, sds, outputs):
    if __name__ == "__main__":
      print "k:{}, sd:{}".format(k, sd)

    usr_out = make_gaussian(k, sd)

    if not type(usr_out) == type(output):
      if __name__ == "__main__":
        print "Error- output has type {}. Expected type is {}.".format(
            type(usr_out), type(output))
      return False

    if not usr_out.shape == output.shape:
      if __name__ == "__main__":
        print "Error- output has shape {}. Expected shape is {}.".format(
            usr_out.shape, output.shape)
      return False

    if not usr_out.dtype == output.dtype:
      if __name__ == "__main__":
        print "Error- output has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, output.dtype)
      return False

    if not np.all(np.abs(usr_out - output) < .005):
      if __name__ == "__main__":
        print "Error- output has value:\n{}\nExpected value:\n{}".format(
            usr_out, output)
      return False

    if __name__ == "__main__":
      print "Passed."

  if __name__ == "__main__":
    print "Success."
  return True

if __name__ == "__main__":
  # Testing code
  print "Performing unit test. Tests will be accepted if they are within .005 \
of the correct answer."
  test()

part2.py

import sys
import os
import numpy as np
from scipy.stats import norm
import math
import random
import cv2
import run

def make_sharp(k, sd):
  '''Create a sharpen kernel.
  
  Input:

  k - the radius of the kernel.
  sd - the standard deviation of the gaussian filter used to make the kernel.
  
  Output:

  output - a numpy array of shape (2k+1, 2k+1) and dtype float.
  
  The sharpen filter is constructed by first taking a filter with a 2 in the
  center and 0's everywhere else, and subtracting from that a gaussian filter.
  
  Note:

  You can use the make_gaussian function from part one by typing:

  import part1
  part1.make_gaussian(k, sd)
  '''
  kernel = None
  # Insert your code here.----------------------------------------------------
  kernel = np.zeros((2 * k + 1, 2 * k + 1), dtype = np.float)
  kernel[k, k] = 2
  import part1
  kernel = kernel - part1.make_gaussian(k, sd)    
  #---------------------------------------------------------------------------
  return kernel

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''

  np.set_printoptions(precision=3)

  ks =  [1, 2, 1, 2, 1]
  sds = [1, 2, 3, 4, 5]
  outputs = []
  # 1,1
  y = np.array([[-0.075, -0.124, -0.075],
                [-0.124,  1.796, -0.124],
                [-0.075, -0.124, -0.075]])
  outputs.append(y)
  # 2,2
  y = np.array([[-0.023, -0.034, -0.038, -0.034, -0.023],
                [-0.034, -0.049, -0.056, -0.049, -0.034],
                [-0.038, -0.056,  1.937, -0.056, -0.038],
                [-0.034, -0.049, -0.056, -0.049, -0.034],
                [-0.023, -0.034, -0.038, -0.034, -0.023]])
  outputs.append(y)
  # 1,3
  y = np.array([[-0.107, -0.113, -0.107],
                [-0.113,  1.880, -0.113],
                [-0.107, -0.113, -0.107]])
  outputs.append(y)
  # 2,4
  y = np.array([[-0.035, -0.039, -0.04 , -0.039, -0.035],
                [-0.039, -0.042, -0.044, -0.042, -0.039],
                [-0.04 , -0.044,  1.955, -0.044, -0.04 ],
                [-0.039, -0.042, -0.044, -0.042, -0.039],
                [-0.035, -0.039, -0.04 , -0.039, -0.035]])
  outputs.append(y)
  # 1,5
  y = np.array([[-0.11 , -0.112, -0.11 ],
                [-0.112,  1.886, -0.112],
                [-0.11 , -0.112, -0.11 ]])
  outputs.append(y)

  for k, sd, output in zip(ks, sds, outputs):
    if __name__ == "__main__":
      print "k:{}, sd:{}".format(k, sd)

    usr_out = make_sharp(k, sd)

    if not type(usr_out) == type(output):
      if __name__ == "__main__":
        print "Error- output has type {}. Expected type is {}.".format(
            type(usr_out), type(output))
      return False

    if not usr_out.shape == output.shape:
      if __name__ == "__main__":
        print "Error- output has shape {}. Expected shape is {}.".format(
            usr_out.shape, output.shape)
      return False

    if not usr_out.dtype == output.dtype:
      if __name__ == "__main__":
        print "Error- output has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, output.dtype)
      return False

    if not np.all(np.abs(usr_out - output) < .005):
      if __name__ == "__main__":
        print "Error- output has value:\n{}\nExpected value:\n{}".format(
            usr_out, output)
      return False

    if __name__ == "__main__":
      print "Passed."

  if __name__ == "__main__":
    print "Success."
  return True

if __name__ == "__main__":
  # Testing code
  print "Performing unit test. Answers will be accepted as long as they are \
within .005 of the input."
  test()

import sys
import os
import numpy as np
from scipy.stats import norm
import math
import random
import cv2
import run

def filter_median(image, k):
  '''Filter the image using a median kernel.
  
  Inputs:

  image - a single channel image of shape (rows, cols)

  k - the radius of the neighborhood you should use (positive integer)

  Output:

  output - a numpy array of shape (rows - 2k, cols - 2k) and the same dtype as 
  image.
  
  Each cell in the output image should be filled with the median value of the
  corresponding (2k+1, 2k+1) patch in the image.
  '''
  output = None
  # Insert your code here.----------------------------------------------------
  (rows, cols) = image.shape
  if (k <= 0):
    raise ValueError('The k must be a postive integer') 
  output = np.zeros((rows - 2*k, cols - 2*k), dtype = image.dtype)
  for i in range(rows - 2*k):
    for j in range(cols - 2*k):
      patch = np.zeros((2*k + 1, 2*k + 1), dtype = image.dtype)
      for u in range(2*k + 1):
        for v in range(2*k + 1):
          patch[u, v] = image[i + u, j + v]
      output[i, j] = np.median(patch)
  #---------------------------------------------------------------------------
  return output 

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''
  images = []
  x = np.array([[   0,   1,   2,   3,   4],
                [   5,   6,   7,   8,   9],
                [  10,  11,  12,  13,  14],
                [  15,  16,  17,  18,  19],
                [  20,  21,  22,  23,  24]], dtype = np.uint8)
  images.append(x)
  images.append(x)

  x = np.array([[ 0,  1,  2,  3,  4,  5,  6],
                [ 7,  8,  9, 10, 11, 12, 13],
                [14, 15, 16, 17, 18, 19, 20],
                [21, 22, 23, 24, 25, 26, 27],
                [28, 29, 30, 31, 32, 33, 34],
                [35, 36, 37, 38, 39, 40, 41],
                [42, 43, 44, 45, 46, 47, 48]], dtype = np.uint8)
  images.append(x)
  images.append(x)

  ks = [1, 2, 1, 2]
  outputs = []

  z = np.array([[ 6,  7,  8],
                [11, 12, 13],
                [16, 17, 18]], dtype=np.uint8)
  outputs.append(z)

  z = np.array([[12]], dtype=np.uint8)
  outputs.append(z)

  z = np.array([[ 8,  9, 10, 11, 12],
                [15, 16, 17, 18, 19],
                [22, 23, 24, 25, 26],
                [29, 30, 31, 32, 33],
                [36, 37, 38, 39, 40]], dtype=np.uint8)
  outputs.append(z)

  z = np.array([[16, 17, 18],
                [23, 24, 25],
                [30, 31, 32]], dtype=np.uint8)
  outputs.append(z)

  for image, k, output in zip(images, ks, outputs):
    if __name__ == "__main__":
      print "image:\n{}".format(image)
      print "k:\n{}".format(k)

    usr_out = filter_median(image, k)

    if not type(usr_out) == type(output):
      if __name__ == "__main__":
        print "Error- output has type {}. Expected type is {}.".format(
            type(usr_out), type(output))
      return False

    if not usr_out.shape == output.shape:
      if __name__ == "__main__":
        print "Error- output has shape {}. Expected shape is {}.".format(
            usr_out.shape, output.shape)
      return False

    if not usr_out.dtype == output.dtype:
      if __name__ == "__main__":
        print "Error- output has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, output.dtype)
      return False

    if not np.all(usr_out == output):
      if __name__ == "__main__":
        print "Error- output has value:\n{}\nExpected value:\n{}".format(
            usr_out, output)
      return False

    if __name__ == "__main__":
      print "Passed."

  if __name__ == "__main__":
    print "Success."
  return True

if __name__ == "__main__":
  # Testing code
  print "Performing unit test."
  test()

import sys
import os
import numpy as np
import cv2
from scipy.signal import convolve2d
from scipy.ndimage.filters import gaussian_filter
import math

import part0
import part1
import part2
import part3
import run

def sobel_filter_x():
  '''Return a 3x3 sobel filter in the x direction.
  '''
  return np.array([[-1, 0, 1],
                   [-2, 0, 2],
                   [-1, 0, 1]])

def sobel_filter_y():
  '''Return a 3x3 sobel filter in the y direction.
  '''
  return np.array([[-1,-2,-1],
                   [ 0, 0, 0],
                   [ 1, 2, 1]])

def transform_xy_theta(dx, dy):
  '''Transform from xy gradients to edge direction.
  
  Input:

  dx, dy - the gradient images generated by applying sobel filters to an
  image. They both have shape (rows, cols) and dtype float.

  Output:

  theta - a numpy array of shape (rows, cols) and dtype float.
  
  Each location theta[i,j] should contain the inverse tangent of dy[i,j]/dx[i,j]
  , in the range of [-pi/2, pi/2] radiants.

  Hint: you may find the np.arctan function useful here.
  '''
  
  # To avoid dividing by zero, set dy to a small value in locations where it
  # is zero.
  dx[dx == 0] = 0.001

  theta = None
  
  # Insert your code here -------------------------------------------------------

  #------------------------------------------------------------------------------
  (rowsx, colsx) = dx.shape
  (rowsy, colsy) = dy.shape
  if (rowsx != rowsy or colsx != colsy):
    raise ValueError('dx and dy must have the same size.')
  theta = np.zeros((rowsx, colsx), dtype = np.float)
  for i in range(rowsx):
    for j in range(colsx):
      theta[i, j] = np.arctan(dy[i,j]/dx[i,j])
  return theta

def transform_xy_mag(dx, dy):
  '''Transform from xy gradients to edge direction.
  
  Input:

  dx, dy - the gradient images generated by applying sobel filters to an
  image. They both have shape (rows, cols) and dtype float.

  Output:

  mag - a numpy array of shape (rows, cols) and dtype float.
  
  Each location mag[i,j] should contain the magnitude of the gradient, which
  is sqrt(dx[i,j]^2 + dy[i,j]^2)

  Hint: you may find the np.sqrt and np.square funcitons useful here.
  '''
  
  mag = None
  
  # Insert your code here -------------------------------------------------------

  #------------------------------------------------------------------------------
  (rowsx, colsx) = dx.shape
  (rowsy, colsy) = dy.shape
  if (rowsx != rowsy or colsx != colsy):
    raise ValueError('dx and dy must have the same size.')
  mag = np.zeros((rowsx, colsx), dtype = np.float)
  for i in range(rowsx):
    for j in range(colsx):
      mag[i, j] = math.sqrt(dx[i,j]*dx[i,j] + dy[i,j]*dy[i,j])
  return mag

def get_color(theta, mag):
  '''Return the color for a given edge theta and magnitude.

  Given the local edge orientation and magnitude, return the corresponding
  color. The intensity of the color is given by the magnitude (stronger edges
  are brighter)
  '''

  boundaries = np.array([0.375, 0.125, -0.125, -0.375]) * math.pi

  # crop the magnitude to 0, 255 range.
  if mag < 0:
    mag = 0

  if mag > 255:
    mag = 255

  # (vertical) | yellow
  if theta > boundaries[0] or theta < boundaries[3] :
    return (0, mag, mag)
  
  # \ green
  if theta >= boundaries[3] and theta < boundaries[2] :
    return (0, mag, 0)

  # -- blue
  if theta >= boundaries[2] and theta < boundaries[1] :
    return (mag, 0, 0)
  
  # / red
  if theta >= boundaries[1] and theta < boundaries[0] :
    return (0, 0, mag)

def run_edges(image):
  ''' This function finds and colors all edges in the given image.
  '''

  # Convert image to gray
  if len(image.shape) > 2:
    grayimage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  else:
    grayimage = image

  # blur so the gradient operation is less noisy.
  # uses a gaussian filter with sigma = 2
  grayimage = gaussian_filter(grayimage, 2).astype(float)
  
  # Filter with x and y sobel filters
  dx = convolve2d(grayimage, sobel_filter_x())
  dy = convolve2d(grayimage, sobel_filter_y())
  
  # Convert to orientation and magnitude images
  theta = transform_xy_theta(dx, dy)
  mag = transform_xy_mag(dx, dy)

  outimg = np.zeros((image.shape[0], image.shape[1], 3), dtype = np.uint8)

  # Fill with corresponding color.
  for r in range(outimg.shape[0]):
    for c in range(outimg.shape[1]):
      outimg[r,c,:] = get_color(theta[r,c], mag[r,c])

  return outimg

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''

  dxs = []
  dys = []
  thetas = []
  mags = []

  y = np.array([[ 0, 1],
                [-1, 0]], dtype = float)
  dys.append(y)

  x = np.array([[ 1, 0],
                [ 0,-1]], dtype = float)
  dxs.append(x)
  
  theta = np.array([[ 0.  ,  math.pi/2],
                    [-math.pi/2,  0.  ]], dtype = float)
  thetas.append(theta)

  mag = np.array([[ 1, 1],
                  [ 1, 1]], dtype = float)
  mags.append(mag)

  y = np.array([[ 0, 0, 0],
                [ 1, 1, 1],
                [-1,-1,-1]], dtype = float)
  dys.append(y)

  x = np.array([[ 0, 1,-1],
                [ 0, 1,-1],
                [ 0, 1,-1]], dtype = float)
  dxs.append(x)
  
  theta = np.array([[         0,          0,          0],
                    [ math.pi/2,  math.pi/4, -math.pi/4],
                    [-math.pi/2, -math.pi/4,  math.pi/4]], dtype = float)
  thetas.append(theta)

  mag= np.array([[ 0,     1,     1],
                 [ 1, 1.414, 1.414],
                 [ 1, 1.414, 1.414]], dtype = float)
  mags.append(mag)

  for dx, dy, theta, mag in zip(dxs, dys, thetas, mags):
    if __name__ == "__main__":
      print "dx:\n{}\n, dy:\n{}\n".format(dx, dy)

    usr_theta = transform_xy_theta(dx, dy)
    usr_mag = transform_xy_mag(dx, dy)

    for usr_out, true_out, name in zip((usr_theta, usr_mag), (theta, mag), ('theta', 'mag')):
      if not type(usr_out) == type(true_out):
        if __name__ == "__main__":
          print "Error- {} has type {}. Expected type is {}.".format(
              name, type(usr_out), type(true_out))
        return False

      if not usr_out.shape == true_out.shape:
        if __name__ == "__main__":
          print "Error- {} has shape {}. Expected shape is {}.".format(
              name, usr_out.shape, true_out.shape)
        return False

      if not usr_out.dtype == true_out.dtype:
        if __name__ == "__main__":
          print "Error- {} has dtype {}. Expected dtype is {}.".format(
              name, usr_out.dtype, true_out.dtype)
        return False

      if not np.all(np.abs(usr_out - true_out) < .05):
        if __name__ == "__main__":
          print "Error- {} has value:\n{}\nExpected value:\n{}".format(
              name, usr_out, true_out)
        return False

      if __name__ == "__main__":
        print "{} passed.".format(name)

  if __name__ == "__main__":
    print "Success."
  return True

if __name__ == "__main__":
  print "Performing unit tests. Your functions will be accepted if your result is\
within 0.05 of the correct output."
  np.set_printoptions(precision=3)
  if not test():
    print "Unit test failed. Halting"
    sys.exit() 

  sourcefolder = os.path.abspath(os.path.join(os.curdir, 'images', 'source'))
  outfolder = os.path.abspath(os.path.join(os.curdir, 'images', 'filtered'))

  print 'Searching for images in {} folder'.format(sourcefolder)

  # Extensions recognized by opencv
  exts = ['.bmp', '.pbm', '.pgm', '.ppm', '.sr', '.ras', '.jpeg', '.jpg', 
    '.jpe', '.jp2', '.tiff', '.tif', '.png']

  # For every image in the source directory
  for dirname, dirnames, filenames in os.walk(sourcefolder):
    for filename in filenames:
      name, ext = os.path.splitext(filename)
      if ext in exts:
        print "Reading image {}.".format(filename)
        img = cv2.imread(os.path.join(dirname, filename))

        print "Applying edges."
        outimg = run_edges(img)
        outpath = os.path.join(outfolder, name + 'edges' + ext)

        print "Writing image {}.".format(outpath)
        cv2.imwrite(outpath, outimg)



MOE GIS portal data update

$
0
0

To change the tool tip, go to Language -> Caption Editor -> Permit To TAke Water – 2013_tolltip

OPERATIONS.PTTW_20120913: run a python script
EMR_PUB.PARCEL_OWNERSHIP_WITHPIN: add one field
EMR_PUB.PARCEL_CROWN

# ---------------------------------------------------------------------------
# PTTW.py
# Created on: Thu Apr 11 2013 01:44:22 PM
#   (generated by ArcGIS/ModelBuilder)
# ---------------------------------------------------------------------------

# Import system modules
import sys, string, os, arcgisscripting

# Create the Geoprocessor object
gp = arcgisscripting.create()

# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Data Management Tools.tbx")

# Local variables...
PTTW__2_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__3_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__4_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__5_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__6_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__7_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__8_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__9_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__10_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__11_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__12_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__13_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__14_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW__15_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW"
PTTW_Project__2_ = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW_Project"
PTTW_project = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW_Project"
PTTW_project_1 = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW_Project"
PTTW_projected_2 = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW_Project"
PTTW_Project = "C:\\working\\PTTW\\20130411\\test\\PTTW.gdb\\PTTW_Project"

# Process: Add Field...
gp.AddField_management(PTTW__3_, "OUTOFUTM", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (2)...
gp.AddField_management(PTTW__2_, "NOUTM", "DOUBLE", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (3)...
gp.AddField_management(PTTW, "PERMIT_UC", "TEXT", "", "", "50", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (4)...
gp.AddField_management(PTTW__4_, "FILENO_UC", "TEXT", "", "", "200", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (5)...
gp.AddField_management(PTTW__5_, "CLNTNM_UC", "TEXT", "", "", "200", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (6)...
gp.AddField_management(PTTW__6_, "CLNTNO_UC", "TEXT", "", "", "150", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (7)...
gp.AddField_management(PTTW__7_, "LATITUDE", "DOUBLE", "16", "8", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (8)...
gp.AddField_management(PTTW__8_, "LONGITUDE", "DOUBLE", "16", "8", "", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (9)...
gp.AddField_management(PTTW__9_, "ID", "TEXT", "", "", "500", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Add Field (10)...
gp.AddField_management(PTTW__10_, "LEGEND", "TEXT", "", "", "50", "", "NULLABLE", "NON_REQUIRED", "")

# Process: Calculate Field...
gp.CalculateField_management(PTTW__11_, "PERMIT_UC", "UCase ( [PERMITNO] )", "VB", "")

# Process: Calculate Field (2)...
gp.CalculateField_management(PTTW__12_, "FILENO_UC", "UCase ( [FILENO]  )", "VB", "")

# Process: Calculate Field (3)...
gp.CalculateField_management(PTTW__13_, "CLNTNM_UC", "UCase ( [CLIENTNAME] )", "VB", "")

# Process: Calculate Field (4)...
gp.CalculateField_management(PTTW__14_, "CLNTNO_UC", "UCase ( [CLIENTNO] )", "VB", "")

# Process: Project...
gp.Project_management(PTTW__15_, PTTW_Project, "GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]]", "", "PROJCS['MNR_Lambert_Conformal_Conic',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Lambert_Conformal_Conic'],PARAMETER['False_Easting',930000.0],PARAMETER['False_Northing',6430000.0],PARAMETER['Central_Meridian',-85.0],PARAMETER['Standard_Parallel_1',44.5],PARAMETER['Standard_Parallel_2',53.5],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]]")

# Process: Calculate Field (7)...
gp.CalculateField_management(PTTW_project, "ID", "[PERMITNO] & \"--\" & Str( [UTMZONE] )& \"--\" & [SOURCEID]", "VB", "")

# Process: Calculate Field (5)...
gp.CalculateField_management(PTTW_Project, "LATITUDE", "pPoint.Y", "VB", "Dim pGeo As IGeometry\\n Set pGeo = [Shape]\\n Dim pPoint As IPoint\\n Set pPoint = pGeo")

# Process: Calculate Field (6)...
gp.CalculateField_management(PTTW_Project__2_, "LONGITUDE", "pPoint.X", "VB", "Dim pGeo As IGeometry\\n Set pGeo = [Shape]\\n Dim pPoint As IPoint\\n Set pPoint = pGeo")

# Process: Calculate Field (8)...
gp.CalculateField_management(PTTW_project_1, "LEGEND", "result", "VB", "dim result as String\\n\\nif [ACTIVE] = 'No' then\\n    result   =  'No'\\nend if\\n\\nif [ACTIVE] = 'Yes' then\\n    result   =  'Yes' & \"-\" & [SURFGRND]\\nend if")


PingPong Game

$
0
0
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Program.java
 *
 * Main entry point for game. Creates two threads,
 * Ping and Pong, that alternately display “Ping”
 * and “Pong” respectively on the console.
 */
public class Program {

    public static void main(String[] args) {

        // Create a lock to be acquired by the player thread that is to return the ball.
        // To ensure that each player thread acquires the lock in turn, the fairness
        // parameter is set to true to favor granting access to the longest-waiting thread.
        ReentrantLock lock = new ReentrantLock(true);

        // Countdown latch to ensure that the main thread waits until the player threads
        // are finished before terminating the program.
        CountDownLatch latch = new CountDownLatch(6);

        System.out.println("Ready... Set... Go!");

        // Start playing!
        Player ping = new Player(latch, lock, "Ping!");
        Player pong = new Player(latch, lock, "Pong!");

        try {
            latch.await(); // wait for countdown latch to reach 0
        } catch (InterruptedException e) {
            System.out.println(e);
        } finally {
            // Terminate threads
            ping.terminate();
            pong.terminate();
        }
        System.out.println("Done!");
    }
}

/**
 * Player Thread with safe terminate() method.
 */
class Player implements Runnable {
    private volatile boolean running = true; // thread-safe flag
    private CountDownLatch latch;
    private ReentrantLock lock;
    private String name;

    Player(CountDownLatch latch, ReentrantLock lock, String name) {
        this.latch = latch;
        this.lock = lock;
        this.name = name;
        new Thread(this).start();
    }

    public void terminate() {
        running = false;
    }

    public void run() {

        while (running) // run the thread until it is terminated
        {
            try {
                // Wait for a return from the opponent
                lock.lock(); // acquire the lock (lock() will return when the lock is not owned by another thread)

                if (!running)
                    break; // exit loop if thread is terminated

                // Signal a return
                System.out.println(name);
                latch.countDown(); // decrement count

                Thread.sleep(1000); // sleep for 1 second for simulation and to allow context switch
            } catch (InterruptedException e) {
                System.out.println(e);
            } finally {
                lock.unlock(); // release the lock (letting the other player return the ball)
            }
        }
    }
}
// Cesar De la Paz
// POSA 2013
// Assignment 1 written in Java

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/* The algorithm alterantes between ping and pong by synchronizing
 * with the use of a monitor and a static "turn" variable.  
 * Nofity/Wait are NOT required but useful to prevent wasting computer 
 * resources.  They prevent wasteful loops checking for threadTurn == X
 */
public class PingPong implements Runnable {
    public static Lock lock = new ReentrantLock();
    public static int i = 0;
    public static int threadTurn = 0;

    public void run() {
        while (i < 10) {
            synchronized (lock) {
                if (threadTurn == 0) {
                    System.out.println("Ping!");
                    threadTurn = 1;
                } else {
                    System.out.println("Pong!");
                    threadTurn = 0;
                }
                i++;
                lock.notify();
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
        synchronized(lock){ lock.notify();}
    }

    public static void main(String[] args) {
        Thread threadA = new Thread(new PingPong());
        Thread threadB = new Thread(new PingPong());
        System.out.println("Ready... Set... Go!");
        threadA.start();
        threadB.start();
        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException ignore) {}
        System.out.println("Done!");
    }
}

public class ProgramAssignment1 {
    private Object mLock = new Object();
    private boolean mIsPingPrinted = false;
    private static final String READY_SET_GO = "Ready… Set… Go!";
    private static final String PING = "Ping!";
    private static final String PONG = "Pong!";
    private static final String DONE = "Done!";
    private static final int COUNTER = 5;
    /**
    * Ping thread which prints Ping!
    */
    private class PingThread extends Thread {
        @Override
        public void run() {
            super.run();
            printPing();
        }
        private void printPing() {
            int counter = COUNTER;
            synchronized (mLock) {
                while (counter-- > 0) {
                    if (mIsPingPrinted) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(PING);
                    mIsPingPrinted = true;
                    mLock.notify();
                }
            }
        }
    }
    /**
    * Pong thread which prints Pong!
    */
    private class PongThread extends Thread {
        @Override
        public void run() {
            super.run();
            printPong();
        }
        private void printPong() {
            int counter = COUNTER;
            synchronized (mLock) {
                while (counter-- > 0) {
                    if (!mIsPingPrinted) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(PONG);
                    mIsPingPrinted = false;
                    mLock.notify();
                }
            }
        }
    }
    public static void main(String[] args) {
        System.out.println(READY_SET_GO);
        System.out.println();
        ProgramAssignment1 pa1 = new ProgramAssignment1();
        PingThread pingThread = pa1.new PingThread();
        PongThread pongThread = pa1.new PongThread();
        pingThread.start();
        pongThread.start();
        try {
            pingThread.join();
            pongThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(DONE);
    }
}

class Main
{

    private static class MyThread extends Thread
    {
	private static int next_id = 0;
	private static Object lock = new Object();
	
	private String msg;
	private int id;

	private MyThread(String msg, int id)
	{
	    this.msg = msg;
	    this.id = id;
	}

	public void run()
	{	  	    
	    try
		{   
		    for(int i = 0; i < 3; i++)
			{
			    synchronized (lock) {
				if (next_id != id)
				    {
					lock.wait();			    
				    }
			    
				System.out.println(msg);
				next_id = (id == 0) ? 1 : 0;
				lock.notify();
			    }
			}
		}
	    catch (Exception e)
		{
		    System.out.println(e.getClass().getName());
		}			    
	}
    }

    
    public static void main(String[] args) throws InterruptedException
    {
	
	System.out.println("Ready! Set! Go!");
	System.out.println();
	    
	MyThread th1 = new MyThread("Ping!", 0);
	MyThread th2 = new MyThread("Pong!", 1);
	
	th1.start();
	th2.start();
	
	th1.join();
	th2.join();

	System.out.println("Done!");
    }
}

Algorithms II: 3-way radix quicksort

$
0
0
Suppose that you run 3-way radix quicksort (do not shuffle) on the following
array of 12 strings:

    7637 8658 3548 2618 4264 8833 6517 4646 8688 7571 7116 3617 

What is the array immediately after the first partitioning step?
Here is the contents of the array after each step:

     lt   i  gt     0    1    2    3    4    5    6    7    8    9   10   11 
    ------------------------------------------------------------------------
      0   1  11  7637 8658 3548 2618 4264 8833 6517 4646 8688 7571 7116 3617 
      0   1  10  7637 3617 3548 2618 4264 8833 6517 4646 8688 7571 7116 8658 
      1   2  10  3617 7637 3548 2618 4264 8833 6517 4646 8688 7571 7116 8658 
      2   3  10  3617 3548 7637 2618 4264 8833 6517 4646 8688 7571 7116 8658 
      3   4  10  3617 3548 2618 7637 4264 8833 6517 4646 8688 7571 7116 8658 
      4   5  10  3617 3548 2618 4264 7637 8833 6517 4646 8688 7571 7116 8658 
      4   5   9  3617 3548 2618 4264 7637 7116 6517 4646 8688 7571 8833 8658 
      4   6   9  3617 3548 2618 4264 7637 7116 6517 4646 8688 7571 8833 8658 
      5   7   9  3617 3548 2618 4264 6517 7116 7637 4646 8688 7571 8833 8658 
      6   8   9  3617 3548 2618 4264 6517 4646 7637 7116 8688 7571 8833 8658 
      6   8   8  3617 3548 2618 4264 6517 4646 7637 7116 7571 8688 8833 8658 
      6   9   8  3617 3548 2618 4264 6517 4646 7637 7116 7571 8688 8833 8658

Algorithms, Part II Assignment 3

$
0
0

Programming Assignment 3: Baseball Elimination

Given the standings in a sports division at some point during the season, determine which teams have been mathematically eliminated from winning their division.

The baseball elimination problem.   In the baseball elimination problem, there is a division consisting of N teams. At some point during the season, team i has w[i] wins, l[i] losses, r[i] remaining games, and g[i][j] games left to play against team j. A team is mathematically eliminated if it cannot possibly finish the season in (or tied for) first place. The goal is to determine exactly which teams are mathematically eliminated. For simplicity, we assume that no games end in a tie (as is the case in Major League Baseball) and that there are no rainouts (i.e., every scheduled game is played).

The problem is not as easy as many sports writers would have you believe, in part because the answer depends not only on the number of games won and left to play, but also on the schedule of remaining games. To see the complication, consider the following scenario:

 
                w[i] l[i] r[i]        g[i][j]
i  team         wins loss left   Atl Phi NY  Mon
------------------------------------------------
0  Atlanta       83   71    8     -   1   6   1
1  Philadelphia  80   79    3     1   -   0   2
2  New York      78   78    6     6   0   -   0
3  Montreal      77   82    3     1   2   0   -

Montreal is mathematically eliminated since it can finish with at most 80 wins and Atlanta already has 83 wins. This is the simplest reason for elimination. However, there can be more complicated reasons. For example, Philadelphia is also mathematically eliminated. It can finish the season with as many as 83 wins, which appears to be enough to tie Atlanta. But this would require Atlanta to lose all of its remaining games, including the 6 against New York, in which case New York would finish with 84 wins. We note that New York is not yet mathematically eliminated despite the fact that it has fewer wins than Philadelphia.

It is sometimes not so easy for a sports writer to explain why a particular team is mathematically eliminated. Consider the following scenario from the American League East on August 30, 1996:

                w[i] l[i] r[i]          g[i][j]
i  team         wins loss left   NY Bal Bos Tor Det
---------------------------------------------------
0  New York      75   59   28     -   3   8   7   3
1  Baltimore     71   63   28     3   -   2   7   4
2  Boston        69   66   27     8   2   -   0   0
3  Toronto       63   72   27     7   7   0   -   0
4  Detroit       49   86   27     3   4   0   0   -

It might appear that Detroit has a remote chance of catching New York and winning the division because Detroit can finish with as many as 76 wins if they go on a 27-game winning steak, which is one more than New York would have if they go on a 28-game losing streak. Try to convince yourself that Detroit is already mathematically eliminated. Here’s one ad hoc explanation; we will present a simpler explanation below.

A maxflow formulation.   We now solve the baseball elimination problem by reducing it to the maxflow problem. To check whether team x is eliminated, we consider two cases.

  • Trivial elimination. If the maximum number of games team x can win is less than the number of wins of some other team i, then team x is trivially eliminated (as is Montreal in the example above). That is, if w[x] +r[x] < w[i], then team x is mathematically eliminated.
  • Nontrivial elimination. Otherwise, we create a flow network and solve a maxflow problem in it. In the network, feasible integral flows correspond to outcomes of the remaining schedule. There are vertices corresponding to teams (other than team x) and to remaining divisional games (not involving team x). Intuitively, each unit of flow in the network corresponds to a remaining game. As it flows through the network froms to t, it passes from a game vertex, say between teams i and j, then through one of the team vertices i or j, classifying this game as being won by that team.More precisely, the flow network includes the following edges and capacities.
    • We connect an artificial source vertex s to each game vertex i-j and set its capacity to g[i][j]. If a flow uses all g[i][j] units of capacity on this edge, then we interpret this as playing all of these games, with the wins distributed between the team vertices i and j.
    • We connect each game vertex i-j with the two opposing team vertices to ensure that one of the two teams earns a win. We do not need to restrict the amount of flow on such edges.
    • Finally, we connect each team vertex to an artificial sink vertex t. We want to know if there is some way of completing all the games so that team x ends up winning at least as many games as team i. Since teamx can win as many as w[x] + r[x] games, we prevent team i from winning more than that many games in total, by including an edge from team vertex i to the sink vertex with capacity w[x] + r[x] - w[i].

    If all edges in the maxflow that are pointing from s are full, then this corresponds to assigning winners to all of the remaining games in such a way that no team wins more games than x. If some edges pointing from sare not full, then there is no scenario in which team x can win the division. In the flow network below Detroit is team x = 4.

    What the min cut tells us.   By solving a maxflow problem, we can determine whether a given team is mathematically eliminated. We would also like to explain the reason for the team’s elimination to a friend in nontechnical terms (using only grade-school arithmetic). Here’s such an explanation for Detroit’s elimination in the American League East example above. With the best possible luck, Detroit finishes the season with 49 + 27 = 76 wins. Consider the subset of teams R = { New York, Baltimore, Boston, Toronto }. Collectively, they already have 75 + 71 + 69 + 63 = 278 wins; there are also 3 + 8 + 7 + 2 + 7 = 27 remaining games among them, so these four teams must win at least an additional 27 games. Thus, on average, the teams in R win at least 305 / 4 = 76.25 games. Regardless of the outcome, one team in R will win at least 77 games, thereby eliminating Detroit.

In fact, when a team is mathematically eliminated there always exists such a convincing certificate of elimination, where R is some subset of the other teams in the division. Moreover, you can always find such a subset Rby choosing the team vertices on the source side of a min s-t cut in the baseball elimination network. Note that although we solved a maxflow/mincut problem to find the subset R, once we have it, the argument for a team’s elimination involves only grade-school algebra.

Your assignment.   Write an immutable data type BaseballElimination that represents a sports division and determines which teams are mathematically eliminated by implementing the following API:

public BaseballElimination(String filename)                    // create a baseball division from given filename in format specified below
public              int numberOfTeams()                        // number of teams
public Iterable<String> teams()                                // all teams
public              int wins(String team)                      // number of wins for given team
public              int losses(String team)                    // number of losses for given team
public              int remaining(String team)                 // number of remaining games for given team
public              int against(String team1, String team2)    // number of remaining games between team1 and team2
public          boolean isEliminated(String team)              // is given team eliminated?
public Iterable<String> certificateOfElimination(String team)  // subset R of teams that eliminates given team; null if not eliminated

The last six methods should throw a java.lang.IllegalArgumentException if one (or both) of the input arguments are invalid teams.

Input format.   The input format is the number of teams in the division N followed by one line for each team. Each line contains the team name (with no internal whitespace characters), the number of wins, the number of losses, the number of remaining games, and the number of remaining games against each team in the divsion. For example, the input files teams4.txt and teams5.txt correspond to the two examples discussed above.

% more teams4.txt
4
Atlanta       83 71  8  0 1 6 1
Philadelphia  80 79  3  1 0 0 2
New_York      78 78  6  6 0 0 0
Montreal      77 82  3  1 2 0 0

% more teams5.txt
5
New_York    75 59 28   0 3 8 7 3
Baltimore   71 63 28   3 0 2 7 4
Boston      69 66 27   8 2 0 0 0
Toronto     63 72 27   7 7 0 0 0
Detroit     49 86 27   3 4 0 0 0

You may assume that N ≥ 1 and that the input files are in the specified format and internally consistent. Note that a team’s total number of remaining games does not necessarily equal the number of remaining games against divisional rivals since teams may play opponents outside of their own division.

Output format.   Use the following main() function, which reads in a sports division from an input file and prints out whether each team is mathematically eliminated and a certificate of elimination for each team that is eliminated:

public static void main(String[] args) {
    BaseballElimination division = new BaseballElimination(args[0]);
    for (String team : division.teams()) {
        if (division.isEliminated(team)) {
            StdOut.print(team + " is eliminated by the subset R = { ");
            for (String t : division.certificateOfElimination(team))
                StdOut.print(t + " ");
            StdOut.println("}");
        }
        else {
            StdOut.println(team + " is not eliminated");
        }
    }
}

Below is the desired output:

% java BaseballElimination teams4.txt
Atlanta is not eliminated
Philadelphia is eliminated by the subset R = { Atlanta New_York }
New_York is not eliminated
Montreal is eliminated by the subset R = { Atlanta }

% java BaseballElimination teams5.txt
New_York is not eliminated
Baltimore is not eliminated
Boston is not eliminated
Toronto is not eliminated
Detroit is eliminated by the subset R = { New_York Baltimore Boston Toronto }

Analysis.   Analyze the worst-case memory usage and running time of your algorithm.

  • What is the order of growth of the amount of memory (in the worst case) that your program uses to determine whether one team is eliminated? In particular, how many vertices and edges are in the flow network as a function of the number of teams N?
  • What is the order of growth of the running time (in the worst case) of your program to determine whether one team is eliminated as a function of the number of teams N? In your calculation, assume that the order of growth of the running time (in the worst case) to compute a maxflow in a network with V vertices and E edges is V E2.

Also, use the output of your program to answer the following question:

  • Consider the sports division defined in teams12.txt. Explain in nontechnical terms (using the results of certificate of elimination and grade-school arithmetic) why Japan is mathematically eliminated.

Extra credit.   Create and submit an interesting test input file (in the specified format) and name it teams.txt. Your input file should contain one or more teams whose elimination would not be obvious to a sports writer. Ideally, your input file should be based on real-world data.

Submission.   Submit BaseballElimination.java and any other files needed to compile your program (excluding those in stdlib.jar and algs4.jar).

This assignment was developed by Kevin Wayne.
Copyright © 2003.


public class BaseballElimination {
    private int numberOfTeams;
    private LinearProbingHashST<String, Integer> teams;
    private int [] w;
    private int [] l;
    private int [] r;
    private int [][] g;
    private LinearProbingHashST<String, SET<String>> certificateOfElimination;
    private LinearProbingHashST<String, Boolean> isEliminated;
    
    // create a baseball division from given filename in format specified below
    public BaseballElimination(String filename) {
        In baseballEliminationIn = new In(new java.io.File(filename));
        numberOfTeams = baseballEliminationIn.readInt();
        teams = new LinearProbingHashST<String, Integer>();
        certificateOfElimination = new LinearProbingHashST<String, SET<String>>();
        isEliminated = new LinearProbingHashST<String, Boolean>();
        w = new int[numberOfTeams];
        l = new int[numberOfTeams];
        r = new int[numberOfTeams];
        g = new int[numberOfTeams][numberOfTeams];
        
        for (int i = 0; i < numberOfTeams; i++) {
            String team = baseballEliminationIn.readString();
            teams.put(team, i);
            w[i] = baseballEliminationIn.readInt();
            l[i] = baseballEliminationIn.readInt();
            r[i] = baseballEliminationIn.readInt();
            for (int j = 0; j < numberOfTeams; j++) {
                g[i][j] = baseballEliminationIn.readInt();
            }
        }
    }
    
    // number of teams
    public int numberOfTeams() {
        return numberOfTeams;
    }
    
    // all teams
    public Iterable<String> teams() {
        return teams.keys();
    }
    
    // number of wins for given team
    public int wins(String team) {
        if (!teams.contains(team)) {
            throw new IllegalArgumentException();
        }
        return w[teams.get(team)];
    }
    
    // number of losses for given team
    public int losses(String team) {
        if (!teams.contains(team)) {
            throw new IllegalArgumentException();
        }
        return l[teams.get(team)];
    }
    
    // number of remaining games for given team
    public int remaining(String team) {
        if (!teams.contains(team)) {
            throw new IllegalArgumentException();
        }
        return r[teams.get(team)];
    }
    
    // number of remaining games between team1 and team2
    public int against(String team1, String team2) {
        if (!teams.contains(team1) || !teams.contains(team2)) {
            throw new IllegalArgumentException();
        }
        return g[teams.get(team1)][teams.get(team2)];
    }
    
    private void eliminateAnalysis(String team) {
        int index = teams.get(team);
        int wx = w[index];
        int rx = r[index];
        SET<String> set = new SET<String>();
        for (String key: teams.keys()) {
            int i = teams.get(key);
            if (i == index) continue;
            if (w[i] > wx + rx) {
                set.add(key);
            }
        }
        if (set.size() > 0) {
            certificateOfElimination.put(team, set);
            isEliminated.put(team, true);
            return;
        }

        
        int gamesNode = (numberOfTeams - 1) * (numberOfTeams - 2)/2 + 1;
        int V = 1 + gamesNode + (numberOfTeams - 1) + 1;
        FlowNetwork flowNetwork = new FlowNetwork(V - 1);
        int incr = 1;
        for (int i = 0; i < numberOfTeams; i++) {
            for (int j = i + 1; j < numberOfTeams; j++) {
                if ((i != index) && (j != index)) {
                    FlowEdge flowEdge1 = new FlowEdge(0, incr, g[i][j]);
                    flowNetwork.addEdge(flowEdge1);
                    int teamNodeIndex = i;
                    if (teamNodeIndex > index) {
                        teamNodeIndex = teamNodeIndex - 1;
                    }
                    int endIndex = gamesNode + teamNodeIndex;
                    FlowEdge f2 = new FlowEdge(incr, endIndex, Integer.MAX_VALUE);
                    flowNetwork.addEdge(f2);
                    teamNodeIndex = j;
                    if (teamNodeIndex > index) {
                        teamNodeIndex = teamNodeIndex - 1;
                    }
                    endIndex = gamesNode + teamNodeIndex;
                    FlowEdge f3 = new FlowEdge(incr, endIndex, Integer.MAX_VALUE);
                    flowNetwork.addEdge(f3);                    
                    incr++;
                }
            }
        }
        
        for (int i = 0; i < numberOfTeams; i++) {
            if (i == index) continue;
            int teamNodeIndex = i;
            if (teamNodeIndex > index) {
                teamNodeIndex = teamNodeIndex - 1;
            }
            int startIndex = gamesNode + teamNodeIndex;
            int endIndex = flowNetwork.V() - 1;
            FlowEdge flowEdge = new FlowEdge(startIndex, endIndex, wx + rx - w[i]);
            flowNetwork.addEdge(flowEdge);
        }
        int endIndex = flowNetwork.V() - 1;
        FordFulkerson maxflow = new FordFulkerson(flowNetwork, 0, endIndex);
        //StdOut.println(flowNetwork);
        boolean result = false;
        for (FlowEdge e : flowNetwork.adj(0))
            if ((e.flow() != e.capacity()) && e.flow() >= 0) {
                result = true;
                break;
            }
        if (result) {
            set = new SET<String>();
            for (String key: teams.keys()) {
                int i = teams.get(key);
                if (i == index) continue;
                int teamNodeIndex = i;
                if (teamNodeIndex > index) {
                    teamNodeIndex = teamNodeIndex - 1;
                }
                if (maxflow.inCut(gamesNode + teamNodeIndex)) {
                    set.add(key);
                }
            }            
            certificateOfElimination.put(team, set);
            isEliminated.put(team, true);
        } else {
            certificateOfElimination.put(team, null);
            isEliminated.put(team, false);
        }
    }
    // is given team eliminated?
    public boolean isEliminated(String team) {
        if (!teams.contains(team)) {
            throw new IllegalArgumentException();
        }
        if (!isEliminated.contains(team)) {
            eliminateAnalysis(team);
        }
        return isEliminated.get(team);
    }
    
    // subset R of teams that eliminates given team; null if not eliminated
    public Iterable<String> certificateOfElimination(String team) {
        if (!teams.contains(team)) {
            throw new IllegalArgumentException();
        }
        if (!certificateOfElimination.contains(team)) {
            eliminateAnalysis(team);
        }
        return certificateOfElimination.get(team);
    } 
    
    public static void main(String[] args) {
        BaseballElimination division = new BaseballElimination(args[0]);
        
        //StdOut.println(division.isEliminated("Japan"));
        for (String team : division.teams()) {
            if (division.isEliminated(team)) {
                StdOut.print(team + " is eliminated by the subset R = { ");
                for (String t : division.certificateOfElimination(team))
                    StdOut.print(t + " ");
                StdOut.println("}");
            }
            else {
                StdOut.println(team + " is not eliminated");
            }
        }
    }
}


Computational Photography Programming Assignment 3 – Image

$
0
0
import numpy as np
import scipy.signal
import cv2

def generating_kernel(a):
  '''Return a 5x5 generating kernel with parameter a.
  '''
  w_1d = np.array([0.25 - a/2.0, 0.25, a, 0.25, 0.25 - a/2.0])
  return np.outer(w_1d, w_1d)

def reduce(image):
  '''Reduce the image to half the size.

  image - a float image of shape (r, c)
  output - a float image of shape (ceil(r/2), ceil(c/2))
  
  For instance, if the input is 5x7, the output will be 3x4.

  You should filter the image with a generating kernel of a = 0.4, and then
  sample every other point.

  Please consult the lectures and tutorial videos for a more in-depth discussion
  of the reduce function.
  '''
  out = None
  # Insert your code here ------------------------------------------------------
  kernel = generating_kernel(0.4)
  import scipy.signal
  smooth = scipy.signal.convolve(image, kernel, 'same')
  size = image.shape
  import math
  width = int(math.ceil(size[0]/2.0))
  height = int(math.ceil(size[1]/2.0))
  out = np.zeros((width, height), dtype = np.float)
  for i in range(width):
    for j in range(height):
      out[i, j] = smooth[2*i, 2*j]

  # ----------------------------------------------------------------------------
  return out
  
def expand(image):
  '''Expand the image to double the size.

  image - a float image of shape (r, c)
  output - a float image of shape (2*r, 2*c)

  You should upsample the image, and then filter it with a generating kernel of
  a = 0.4. Finally, scale the output by the appropraite amount to make sure that
  the net weight contributing to each output pixel is 1.

  Please consult the lectures and tutorial videos for a more in-depth discussion
  of the expand function.
  '''
  out = None
  # Insert your code here ------------------------------------------------------
  (width, height) = image.shape
  out = np.zeros((2*width, 2*height), dtype = np.float)
  for i in range(width):
    for j in range(height):
      out[2*i, 2*j] = image[i, j]
  kernel = generating_kernel(0.4)

  # ----------------------------------------------------------------------------
  return out

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''
  # Each subsequent layer is a reduction of the previous one
  reduce1 =[np.array([[   0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.],
                      [   0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.],
                      [   0.,    0.,  255.,  255.,  255.,  255.,    0.,    0.],
                      [   0.,    0.,  255.,  255.,  255.,  255.,    0.,    0.],
                      [   0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.],
                      [   0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.]]),
            np.array([[   0.64,    8.92,   12.11,    3.82],
                      [   8.29,  116.03,  157.46,   49.73],
                      [   3.82,   53.55,   72.67,   22.95]]),
            np.array([[ 12.21,  31.85],
                      [ 17.62,  45.97]]),
            np.array([[ 9.77]])] 

  reduce2 = [np.array([[ 255.,  255.,  255.,  255.,  255.,  255.,  255.],
                       [ 255.,  255.,  255.,  255.,  255.,  255.,  255.],
                       [ 255.,  255.,  125.,  125.,  125.,  255.,  255.],
                       [ 255.,  255.,  125.,  125.,  125.,  255.,  255.],
                       [   0.,    0.,    0.,    0.,    0.,    0.,    0.]]),
             np.array([[ 124.62,  173.95,  173.95,  124.62],
                       [ 165.35,  183.1 ,  183.1 ,  165.35],
                       [  51.6 ,   49.2 ,   49.2 ,   51.6 ]]),
             np.array([[  72.85,  104.71],
                       [  49.53,   68.66]]),
             np.array([[ 31.37]])] 

  if __name__ == "__main__":
    print 'Evaluating reduce.'
  for red_pyr in reduce1, reduce2:
    for imgin, true_out in zip(red_pyr[0:-1], red_pyr[1:]):
      if __name__ == "__main__":
        print "input:\n{}\n".format(imgin)

      usr_out = reduce(imgin)

      if not type(usr_out) == type(true_out):
        if __name__ == "__main__":
          print "Error- reduce out has type {}. Expected type is {}.".format(
              type(usr_out), type(true_out))
        return False

      if not usr_out.shape == true_out.shape:
        if __name__ == "__main__":
          print "Error- reduce out has shape {}. Expected shape is {}.".format(
              usr_out.shape, true_out.shape)
        return False

      if not usr_out.dtype == true_out.dtype:
        if __name__ == "__main__":
          print "Error- reduce out has dtype {}. Expected dtype is {}.".format(
              usr_out.dtype, true_out.dtype)
        return False

      if not np.all(np.abs(usr_out - true_out) < 1):
        if __name__ == "__main__":
          print "Error- reduce out has value:\n{}\nExpected value:\n{}".format(
              usr_out, true_out)
        return False

  if __name__ == "__main__":
    print "reduce passed.\n"
    print "Evaluating expand."

  expandin = [np.array([[255]]),
              np.array([[125, 255],
                        [255,   0]]),
              np.array([[ 255.,    0.,  125.,  125.,  125.],
                        [ 255.,    0.,  125.,  125.,  125.],
                        [  50.,   50.,   50.,   50.,   50.]])] 

  expandout =[np.array([[ 163.2 ,  102.  ],
                        [ 102.  ,   63.75]]),
              np.array([[ 120.8 ,  164.75,  175.75,  102.  ],
                        [ 164.75,  158.75,  121.  ,   63.75],
                        [ 175.75,  121.  ,   42.05,   12.75],
                        [ 102.  ,   63.75,   12.75,    0.  ]]),
              np.array([[ 183.6, 114.75, 34.2, 56.25, 101.25, 112.5, 112.5,112.5, 101.25,  56.25],
                        [ 204. ,  127.5,  38.,  62.5,  112.5,  125.,  125., 125.,  112.5,  62.5 ],
                        [ 188.1, 119.75, 39.2, 61.25, 106.25, 117.5, 117.5,117.5, 105.75,  58.75],
                        [ 124.5,  88.75, 44. , 56.25,  81.25,  87.5,  87.5, 87.5,  78.75,  43.75],
                        [  56.4,  52.75, 43.8, 46.25,  51.25,  52.5,  52.5, 52.5,  47.25,  26.25],
                        [  22.5,    25.,  25.,   25.,    25.,   25.,   25.,  25.,   22.5,  12.5 ]])]

  for imgin, true_out in zip(expandin, expandout):
    if __name__ == "__main__":
      print "input:\n{}\n".format(imgin)

    usr_out = expand(imgin)

    if not type(usr_out) == type(true_out):
      if __name__ == "__main__":
        print "Error- expand out has type {}. Expected type is {}.".format(
            type(usr_out), type(true_out))
      return False

    if not usr_out.shape == true_out.shape:
      if __name__ == "__main__":
        print "Error- expand out has shape {}. Expected shape is {}.".format(
            usr_out.shape, true_out.shape)
      return False

    if not usr_out.dtype == true_out.dtype:
      if __name__ == "__main__":
        print "Error- expand out has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, true_out.dtype)
      return False

    if not np.all(np.abs(usr_out - true_out) < 1):
      if __name__ == "__main__":
        print "Error- expand out has value:\n{}\nExpected value:\n{}".format(
            usr_out, true_out)
      return False

  if __name__ == "__main__":
    print "expand passed."

  if __name__ == "__main__":
    print "All unit tests successful."
  return True

if __name__ == "__main__":
  print "Performing unit tests. Your functions will be accepted if your result is\
    within 1 of the correct output."
  np.set_printoptions(precision=1)

  test()


Dining philosophers problem

$
0
0
package posa

import scala.actors.Actor

/**
 * Actor representing a philosopher.
 * When receives message n, will eat n times and terminate. Eat sequence:
 * 1. picks up left chopstick (may block until available)
 * 2. picks up right chopstick (may block until available)
 * 3. eats
 * 4. puts down right chopstick
 * 5. puts down left chopstick
 */
class Philosopher(id: Int, leftChopstick: Int, rightChopstick: Int) extends Actor {
  def act() {
    receive {
      case n: Int =>
        // Repeat the eat sequence n times
        for (i <- 1 to n) {
          while (!Dinner.pickUpChopstick(id, leftChopstick, true)) {}
          while (!Dinner.pickUpChopstick(id, rightChopstick, false)) {}
          Console.printf("Philosopher %s eats.%n", id.toString)
          Dinner.putDownChopstick(id, rightChopstick, false)
          Dinner.putDownChopstick(id, leftChopstick, true)
        }
        exit()
    }
  }
}

/**
 * Dinner of 5 philosophers, each eating 5 times.
 */
object Dinner extends App {
  // Map to print out side
  val side: Map[Boolean, String] = Map(true -> "Left", false -> "Right")
  
  // Array of Booleans representing chopsticks, true means they are on the table
  val chopsticks: Array[Boolean] = Array.fill(5)(true)
  
  // List of Philosopher actors, and their respective chopsticks
  val philosophers: List[Philosopher] = List(
    new Philosopher(1, 0, 1),
    new Philosopher(2, 1, 2),
    new Philosopher(3, 2, 3),
    new Philosopher(4, 3, 4),
    new Philosopher(5, 4, 0)
  )
  
  // Let the feast begin
  philosophers.foreach(_.start)
  Console.println("Dinner is starting!")
  philosophers.foreach(_ ! 5)
  while (philosophers.exists(_.getState != Actor.State.Terminated)) {}
  Console.println("Dinner is over!")
  
  /**
   * Synchronized method, attempting to pick up a given chopstick by a philosopher.
   * Returns true if the chopstick was available and picked up successfully.
   * In order to prevent deadlocks, left hand side chopsticks can only be picked up if there are at least 2 chopsticks on the table.
   * Right hand side chopsticks can be picked up as long as they are on the table (philosophers always pick up left chopstick first).
   * The synchronization is the JVM native implementation of the Monitor Object pattern. 
   * In this case the monitor of the Dinner object is used, ensuring that only one chopstick can be picked up at a time. 
   */
  def pickUpChopstick(philosopher: Int, chopstick: Int, isLeft: Boolean): Boolean = synchronized {
    val result = chopsticks(chopstick) && (!isLeft || chopsticks.count(c => c) > 1)
    if (result) {
      Console.printf("Philosopher %s picks up %s chopstick.%n", philosopher.toString, side(isLeft))
      chopsticks(chopstick) = false;
    }
    result
  }
  
  /**
   * Puts down the given chopstick by a philosopher.
   * No synchronization is needed.
   */
  def putDownChopstick(philosopher: Int, chopstick: Int, isLeft: Boolean) = {
    Console.printf("Philosopher %s puts down %s chopstick.%n", philosopher.toString, side(isLeft))
    chopsticks(chopstick) = true
  }
  
}


Lake Partner Program Python Preprocess Script

$
0
0

This python script reads the Tab Separated text file extracted from the Excel file provided by Lake Partner Program and create one text to be converted to feature class, one text for secchi depth data and one txt file for total phosphorus.

import math

class LakePartnerStation:
    def __init__(self, Lake, Township, STN, SiteID, SiteDescription, Latitude, Longitude):
        self.Lake = Lake
        self.Township = Township
        self.STN = STN
        self.SiteID = SiteID
        self.SiteDescription = SiteDescription
        self.Latitude = Latitude
        self.Longitude = Longitude
        self.secchiDepthDict = {}
        self.tpDict = []
    def convertLatLngToUTM(self, lat, lng):
        if (lat < 0.0001):
            return "0\t0\t0"
        pi = 3.14159265358979; #PI
        a = 6378137; #equatorial radius for WGS 84
        k0 = 0.9996; #scale factor
        e = 0.081819191; #eccentricity
        e_2 = 0.006694380015894481; #e'2
        A0 = 6367449.146;
        B0 = 16038.42955;
        C0 = 16.83261333;
        D0 = 0.021984404;
        E0 = 0.000312705;

        zone = 31 + math.floor(lng / 6);
        lat_r = lat * pi / 180.0;
        t1 = math.sin(lat_r); # SIN(LAT)
        t2 = e * t1 * e * t1;
        t3 = math.cos(lat_r); # COS(LAT)
        t4 = math.tan(lat_r); # TAN(LAT)
        nu = a / (math.sqrt(1 - t2));
        S = A0 * lat_r - B0 * math.sin(2 * lat_r) + C0 * math.sin(4 * lat_r) - D0 * math.sin(6 * lat_r) + E0 * math.sin(8 * lat_r);
        k1 = S * k0;
        k2 = nu * t1 * t3 * k0 / 2.0;
        k3 = ((nu * t1 * t2 * t2 * t2) / 24) * (5 - t4 * t4 + 9 * e_2 * t3 * t3 + 4 * e_2 * e_2 * t3 * t3 * t3 * t3) * k0;
        k4 = nu * t3 * k0;
        k5 = t3 * t3 * t3 * (nu / 6) * (1 - t4 * t4 + e_2 * t3 * t3) * k0;

        #var lng_r = lng*pi/180.0;
        lng_zone_cm = 6 * zone - 183;
        d1 = (lng - lng_zone_cm) * pi / 180.0;
        d2 = d1 * d1;
        d3 = d2 * d1;
        d4 = d3 * d1;

        x = 500000 + (k4 * d1 + k5 * d3);
        rawy = (k1 + k2 * d2 + k3 * d4);
        y = rawy;
        if (y < 0):              y = y + 10000000;         return str(int(zone)) + "\t" + str(x)  + "\t" + str(y);     def strWithUTM(self):         id = self.STN * 10000 + self.SiteID                 return str(id) + "\t" + self.Lake + "\t" + self.Township + "\t" + str(self.STN) + "\t" + str(self.SiteID) + "\t" + self.SiteDescription + "\t" + str(self.Latitude) + "\t" +  str(self.Longitude)  + "\t" +  str(len(self.secchiDepthDict))  + "\t" +  str(len(self.tpDict))   + "\t" +  self.convertLatLngToUTM(self.Latitude, self.Longitude)     def __str__(self):         id = self.STN * 10000 + self.SiteID         if len(self.secchiDepthDict) > 0:
            self.getSecchiDepthString()
        if len(self.tpDict) > 0:
            self.getTPString()
        return str(id) + "\t" + self.Lake + "\t" + self.Township + "\t" + str(self.STN) + "\t" + str(self.SiteID) + "\t" + self.SiteDescription + "\t" + str(self.Latitude) + "\t" +  str(self.Longitude)  + "\t" +  str(len(self.secchiDepthDict))  + "\t" +  str(len(self.tpDict))   + "\t" + 'http://www.downloads.ene.gov.on.ca/files/mapping/LakePartner/TP/TP_EN_' + str(id) + '.html'    + "\t" +  'http://www.downloads.ene.gov.on.ca/files/mapping/LakePartner/TP/TP_FR_' + str(id) + '.html'    + "\t" +  'http://www.downloads.ene.gov.on.ca/files/mapping/LakePartner/SECCHI/SECCHI_EN_' + str(id) + '.html'    + "\t" +  'http://www.downloads.ene.gov.on.ca/files/mapping/LakePartner/SECCHI/SECCHI_FR_' + str(id) + '.html'
        #return self.getTPString()
    def getSecchiDepthTable(self):
        id = self.STN * 10000 + self.SiteID
        result = ""
        for key, value in self.secchiDepthDict.items():
            result = result + str(self.STN) + "\t" + str(self.SiteID) + "\t" + key + "\t" + value + "\t" + str(id) + "\n"
        return result

    def getSecchiDepthString(self):
        id = self.STN * 10000 + self.SiteID
        result = ""
        for key in sorted(self.secchiDepthDict.iterkeys()):
            value = self.secchiDepthDict[key]
            result = result + "{year:" + key + ", value: " + value + "},"
        #for key, value in self.secchiDepthDict.items():
        #    result = result + "{year:" + key + ", value: " + value + "},"
        result = "var dataArray = [" + result[:-1] + "];"
        for lang in ["EN", "FR"]:
            text_file = open("template_" + lang + "_SECCHI.htm", "r")
            template = text_file.read()
            text_file.close()
            #template = template.replace("${ID}", str(id))
            template = template.replace('<script type="text/javascript" src="secchi_${ID}.js"></script>', '<script type="text/javascript">// <![CDATA[
\n\t\t' + result + '\n\t
// ]]></script>')
 template = template.replace("${LAKENAME}", self.Lake)
 template = template.replace("${STN}", str(self.STN))
 template = template.replace("${SITEID}", str(self.SiteID))
 template = template.replace("${SITEDESC}", self.SiteDescription)
 handle1 = open("SECCHI/SECCHI_" + lang + "_" + str(id) + ".html",'w+')
 handle1.write(template)
 handle1.close();

 def addSecchiDepth (self, Year, SecchiDepth):
 if self.secchiDepthDict.has_key(Year):
 raise ValueError('The year %s has duplicated secchi depth %s and %s in station %s.' % (Year, SecchiDepth, self.secchiDepthDict[Year], str(self.STN) + " - " + str(self.SiteID)))
 self.secchiDepthDict[Year] = SecchiDepth
 def convertDate(self, inputDate):
 #27-Jun-11
 items = inputDate.split("-")
 if (int(items[2]) > 50):
 print "Error\n"
 year = "20" + items[2]
 day = items[0]
 monthList = {"Jan": "01", "Feb": "02", "Mar": "03", "Apr": "04", "May": "05", "Jun": "06", "Jul": "07", "Aug": "08", "Sep": "09", "Oct": "10", "Nov": "11", "Dec": "12"};
 month = monthList[items[1]]
 return year + "-" + month + "-" + day
 def getTPString(self):
 id = self.STN * 10000 + self.SiteID
 result = ""
 for value in self.tpDict:
 items = value.split("\t")
 result = result + "{date:'" + self.convertDate(items[0]) + "', tp1: " + items[1] + ", tp2: " + items[2] + "},"
 result = "var dataArray = [" + result[:-1] + "];"
 for lang in ["EN", "FR"]:
 text_file = open("template_" + lang + "_TP.htm", "r")
 template = text_file.read()
 text_file.close()
 #template = template.replace("${ID}", str(id))
 template = template.replace('<script type="text/javascript" src="tp_${ID}.js"></script>', '<script type="text/javascript">// <![CDATA[
\n\t\t' + result + '\n\t
// ]]></script>')
 template = template.replace("${LAKENAME}", self.Lake)
 template = template.replace("${STN}", str(self.STN))
 template = template.replace("${SITEID}", str(self.SiteID))
 template = template.replace("${SITEDESC}", self.SiteDescription)
 handle1 = open("TP/TP_" + lang + "_" + str(id) + ".html",'w+')
 handle1.write(template)
 handle1.close();
 def addTP (self, date, tpValues):
 #if self.tpDict.has_key(date):
 #raise ValueError('The year %s has duplicated secchi depth %s and %s in station %s.' % (date, tpValues, self.tpDict[date], str(self.STN) + " - " + str(self.SiteID)))
 # print str(self.STN) + " - " + str(self.SiteID) + " - " + date
 #self.tpDict[date] = tpValues
 self.tpDict.append(date + "\t" + tpValues)
 def getTPTable(self):
 id = self.STN * 10000 + self.SiteID
 result = ""
 for value in self.tpDict:
 result = result + str(self.STN) + "\t" + str(self.SiteID) + "\t" + value + "\t" + str(id) + "\n"
 return result
class LakePartner:
 def __init__(self, secchiDepthFile, tpFile):
 self.LakePartnerStations = {}
 import fileinput
 i = 0
 for line in fileinput.input(secchiDepthFile):
 i = i + 1
 if i < 3: continue items = line.strip().split("\t") STN = int(items[2]) SiteID = int(items[3]) id = STN * 10000 + SiteID if self.LakePartnerStations.has_key(id): self.LakePartnerStations[id].addSecchiDepth(items[7], items[8]) else: Lake = items[0] Township = items[1] SiteDescription = items[4] Latitude = self.parseDegree(items[5]) Longitude = -self.parseDegree(items[6]) if Longitude > -70 or id == 47140002:
 Latitude = 0
 Longitude = 0
 station = LakePartnerStation(Lake, Township, STN, SiteID, SiteDescription, Latitude, Longitude)
 #if id == 71680001:
 # print station.strWithUTM()
 station.addSecchiDepth(items[7], items[8])
 self.LakePartnerStations[id] = station
 i = 0
 for line in fileinput.input(tpFile):
 i = i + 1
 if i < 9: continue #print line items = line.strip().split("\t") STN = int(items[2]) SiteID = int(items[3]) id = STN * 10000 + SiteID if self.LakePartnerStations.has_key(id): self.LakePartnerStations[id].addTP(items[7], items[8] + "\t" + items[9]) else: Lake = items[0] Township = items[1] SiteDescription = items[4] Latitude = self.parseDegree(items[5]) Longitude = -self.parseDegree(items[6]) if Longitude > -70:
 Latitude = 0
 Longitude = 0
 station = LakePartnerStation(Lake, Township, STN, SiteID, SiteDescription, Latitude, Longitude)
 station.addTP(items[7], items[8] + "\t" + items[9])
 self.LakePartnerStations[id] = station
 #print items
 def parseDegree(self, ddmmss):
 if len(ddmmss.strip()) == 0:
 return 0
 d = int(ddmmss[:2])
 m = int(ddmmss[2:4])
 s = int(ddmmss[4:])
 return d + m/60.0 + s/3600.0
 def strWithUTM(self):
 result = "ID\tLAKENAME\tTOWNSHIP\tSTN\tSITEID\tSITEDESC\tLATITUDE\tLONGITUDE\tSE_COUNT\tPH_COUNT\tZONE\tEASTING\tNORTHING\n"
 for key, value in self.LakePartnerStations.items():
 result = result + value.strWithUTM() + "\n"
 return result

 def __str__(self):
 result = "ID\tLAKENAME\tTOWNSHIP\tSTN\tSITEID\tSITEDESC\tLATITUDE\tLONGITUDE\tSE_COUNT\tPH_COUNT\tTP_URL_EN\tTP_URL_FR\tSE_URL_EN\tSE_URL_FR\n"
 for key, value in self.LakePartnerStations.items():
 result = result + str(value) + "\n"
 return result
 def getTable(self):
 handle1 = open("secchiDepth1.txt",'w+')
 result = "STN\tSITEID\tYEAR_\tSECCI\tID\n"
 for key, value in self.LakePartnerStations.items():
 result = result + value.getSecchiDepthTable()
 handle1.write(result)
 handle1.close();
 handle1 = open("TP1.txt",'w+')
 result = "STN\tSITEID\tDATE_\tTP1\tTP2\tID\n"
 for key, value in self.LakePartnerStations.items():
 result = result + value.getTPTable()
 handle1.write(result)
 handle1.close();

 return result

if __name__ == "__main__":
 stations = LakePartner('SecchiDepth.txt', 'TP.txt')
 handle1 = open("1.txt",'w+')
 handle1.write(str(stations))
 handle1.close();
 stations.getTable();
 #os.system("1.py")

template_EN_SECCHI.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<TITLE>Water Transparency (Secchi Depth in meters)</TITLE>
		
    <!--PRIMARY-->
    <meta name="dc.title" content="" />
    <meta property="og:title" content="" />

    <meta name="dc.description" content="" />
    <meta name="description" content="" />
    <meta name="dcterms.audience" content="" />
    <meta name="dc.identifier" scheme="URI" content="" />
    <meta name="dc.date.created" scheme="W3CDTF" content="" />
    <meta name="dc.date.issued" scheme="W3CDTF" content="" />
    <meta name="dc.date.modified" scheme="W3CDTF" content="" />
    <!--PRIMARY-->
    
    <!--CONTROLLED-->

    <meta name="dc.subject" scheme="gccore" content="" />
    <meta name="Keywords" content="" />
    <meta name="dc.type" scheme="oncatype" content="" />
    <!--CONTROLLED-->
    
    <!--FACEBOOK-->
    <meta property="og:type" content="article" />
    <meta property="og:url" content="" />
    <meta property="og:image" content="" />
    <meta property="og:site_name" content="" />

    <meta property="og:description" content="" />
    <!--FACEBOOK-->	
	
	<!--SECONDARY-->
    <meta name="dc.format" scheme="IMT" content="text/html" />
    <meta name="dc.creator" content="Government of Ontario, Ministry of the Environment" />
    <meta name="dc.publisher" content="Government of Ontario, Ministry of the Environment" />
    <meta name="dc.contributor" content="Government of Ontario, Ministry of the Environment" />
    <meta name="dc.language" scheme="ISO639-2" content="Eng" />
    <meta name="dc.coverage.jurisdiction" content="Province of Ontario" />

    <meta name="dc.coverage.spatial" content="Ontario, Canada" />
    <meta name="dc.rights.intellectualProperty" content="Copyright: Queen's Printer for Ontario, 2010" />
    <meta name="go.contact.content" content="" />
    <meta name="go.contact.technical" content="" />
    <!--SECONDARY-->
	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/new.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/master.css" type="text/css" media="screen" />
	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/changeme.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/print.css" type="text/css" media="print" />

	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/mobile.css" type="text/css" media="handheld" />
	<link rel="icon" type="image/png" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/trillium4.ico" />
	
	<script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministryscripts/scripts/scripts.js"></script>
	<style type="text/css">
      .js #smenu3 {display:none;}
      .js #smenu4 {display:none;}
      .js #smenu5 {display:none;}
      .js #smenu6 {display:none;}
      .js #smenu7 {display:none;}
    </style>
    
    <script type="text/javascript">
      document.getElementsByTagName('html')[0].className = 'js';
    </script>
	<meta content="MSHTML 6.00.2900.3698" name="GENERATOR" />
	<style type="text/css">
		.lakepartner { width:700px; margin-right:-3px; border-spacing:1px; border-collapse:separate !important; border:1px #000000 solid; }	
		.lakepartner th { padding:2px; font-size:11px; border:1px #000000 solid; vertical-align:middle; text-align:left; }	  
		.lakepartner td { padding:2px; font-size:11px; border:1px #000000 solid; text-align:center; }
	</style>
	
	<style type="text/css">table.lakepartner { border-collapse: collapse; border-color: #000; }
		table.lakepartner th { background-color: #666; color: #FFF; padding: 3px; }
		table.lakepartner td { padding: 3px; }</style>
	<script type="text/javascript" src="http://www.google.com/jsapi"></script>
	<script type="text/javascript" src="secchi_${ID}.js"></script>	
	<script type="text/javascript">
			google.load("visualization", "1", {packages:["corechart"]});
			google.setOnLoadCallback(drawChart);
			
			function drawChart() {
				var data = new google.visualization.DataTable();
				data.addColumn('string', 'Year');
				data.addColumn('number', 'Secchi Depth (m)');
				data.addRows(dataArray.length+1);
				
				for (var i=0; i<dataArray.length+1; i++){
					if(i == 0){
						var year = "" + (dataArray[0].year - 1)
						data.setValue(0, 0, year);
						data.setValue(0, 1, 0);	
					}else{
						data.setValue(i, 0, "" + dataArray[i-1].year );
						data.setValue(i, 1, dataArray[i-1].value);	
					}					
				}
				var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));     
				chart.draw(data, {width: 700, height: 480, colors:['#d4bfff'],     
							hAxis: {title: 'Year', titleColor:'black'}, vAxis: {title: 'Secchi Depth (m)', minValue: 0.0}
							});
			}
			window.onload = function (){
				var str = "	<table class='lakepartner' border='1'><tr><th><center>Year</center></th><th><center>Secchi Depth (meters)</center></th></tr><tr><td>";
				strArray = [];
				for (var i=0; i<dataArray.length; i++){
					strArray.push(dataArray[i].year +  "</td><td><center>" + dataArray[i].value);
				}
				document.getElementById("data_table").innerHTML =  str + strArray.join("</center></td></tr><tr><td>") + "</center></td></tr></table>";			
			}
		</script>	
</head>
<body id="home">
<div id="wrapper">
  <div id="header"> 
  
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_header.js"></script>
  
</div>
  <a name="top" id="top"></a>
  
  <div id="right_column">
<h1>${LAKENAME} (STN ${STN}, Site ID ${SITEID})</h1>
<strong>${SITEDESC}</strong>
<p>The Lake Partner Program is a province-wide, volunteer-based, water-quality monitoring program. Volunteers collect total phosphorus samples and make monthly water clarity observations on their lakes. This information will allow the early detection of changes in the nutrient status and/or the water clarity of the lake due to the impacts of shoreline development, climate change and other stresses.</p><p>Approximately 800 active volunteers monitor total phosphorus at 728 locations in the lakes across Ontario.</p><p>Increases in phosphorus can decrease water clarity by stimulating algal growth. However, the amount of phosphorus in the lake is not the only factor controlling light penetration, as the amount of dissolved organic carbon (DOC) or non-biological turbidity also plays an important role. Water clarity can also be altered by invading species such as zebra mussels. It is always best, therefore, to use total phosphorus to evaluate the nutrient status of the lake. Nonetheless, water clarity readings are useful for tracking changes in the lake that might be occurring that would not be noticed by monitoring TP concentration alone, e.g. zebra mussel invasions.</p><p><a href="JavaScript:window.print();">Print this page</a></p>      <center><h3>Water Transparency (Secchi Depth in meters)</h3></center><center><div id="chart_div"></div><br>
	<br><h3>Water Transparency (Secchi Depth in meters)</h3>
<div id="data_table"></div>
</center>
		<br><br>If you have some suggestions or find some errors, please send an Email to <a href='mailto:lakepartner@ontario.ca?subject=Portal Error Submission'>lakepartner@ontario.ca</a>.
		</div>
<div id="left_column">

 
 	<div class="leftnav">
      <div class="photocap nav_top mycolour">&nbsp;</div>
      <div class="mycolour"><h2 class="header"><a style="display:block;" href="javascript:void(0)" onclick="showHide('smenu1');return false;">Provincial Groundwater Monitoring Network<img src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/arrow_down.gif" width="9" height="9" alt="" title="Open the explore menu" id="smenu1_arrow" /></a></h2></div>
      <ul class="menu clear" id="smenu1" style="display:block;">
	       <li><a href="http://www.ene.gov.on.ca/environment/en/local/lake_partner_program/index.htm">Return to Lake Partner Program</a></li>
	       <li><a href="../LakePartner_Accessible_en.htm">Accessibile Version</a></li>
      </ul>  
    </div>

    
    <div id="second_nav"></div>
	
	<script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_secondary.js"></script>
  
  </div>
  <div id="footer">
    
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_footer.js"></script>
  </div>
</div>
</body>
</html>


template_FR_SECCHI.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//FR" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<TITLE>Transparence de l'eau (profondeur en mètres d’après le disque Secchi)</TITLE>
	
    <!--PRIMARY-->
    <meta name="dc.title" content=" />
    <meta property="og:title" content=" />
    <meta name="dc.description" content=" />
    <meta name="description" content=" />
    <meta name="dcterms.audience" content=" />
    <meta name="dc.identifier" scheme="URI" content=" />
    <meta name="dc.date.created" scheme="W3CDTF" content=" />
    <meta name="dc.date.issued" scheme="W3CDTF" content=" />
    <meta name="dc.date.modified" scheme="W3CDTF" content=" />
    <!--PRIMARY-->
    
    <!--CONTROLLED-->
    <meta name="dc.subject" scheme="gccore" content=" />
    <meta name="Keywords" content=" />
    <meta name="dc.type" scheme="oncatype" content=" />
    <!--CONTROLLED-->
    
    <!--FACEBOOK-->
    <meta property="og:type" content="article" />
    <meta property="og:url" content=" />
    <meta property="og:image" content=" />
    <meta property="og:site_name" content=" />
    <meta property="og:description" content=" />
    <!--FACEBOOK-->	
	
	<!--SECONDARY-->
    <meta name="dc.format" scheme="IMT" content="text/html" />

    <meta name="dc.creator" content="Gouvernement de l'Ontario, Ministere de l'Environnement" />
    <meta name="dc.publisher" content="Gouvernement de l'Ontario, Ministere de l'Environnement" />
    <meta name="dc.contributor" content="Gouvernement de l'Ontario, Ministere de l'Environnement" />
    <meta name="dc.language" scheme="ISO639-2" content="fre" />
    <meta name="dc.coverage.jurisdiction" content="Province d'Ontario" />
    <meta name="dc.coverage.spatial" content="Ontario, Canada" />
    <meta name="dc.rights.intellectualProperty" content="Renseignements sur les droits d'auteur Imprimeur de la Reine pour l'Ontario, 2009 - 2010" />
    <meta name="go.contact.content" content="nmu.moe@ontario.ca" />
    <meta name="go.contact.technical" content="webmaster.moe@ontario.ca" />

    <!--SECONDARY-->
	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/new.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/master.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/changeme.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/print.css" type="text/css" media="print" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/mobile.css" type="text/css" media="handheld" />
    
    <link rel="icon" type="image/png" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/trillium4.ico" />
    
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministryscripts/scripts/scripts.js"></script>

	<style type="text/css">
      .js #smenu3 {display:none;}
      .js #smenu4 {display:none;}
      .js #smenu5 {display:none;}
      .js #smenu6 {display:none;}
      .js #smenu7 {display:none;}
    </style>
    
    <script type="text/javascript">
      document.getElementsByTagName('html')[0].className = 'js';
    </script>
	<meta content="MSHTML 6.00.2900.3698" name="GENERATOR" />
	<style type="text/css">
		.lakepartner { width:700px; margin-right:-3px; border-spacing:1px; border-collapse:separate !important; border:1px #000000 solid; }	
		.lakepartner th { padding:2px; font-size:11px; border:1px #000000 solid; vertical-align:middle; text-align:left; }	  
		.lakepartner td { padding:2px; font-size:11px; border:1px #000000 solid; text-align:center; }
	</style>
	
	<style type="text/css">table.lakepartner { border-collapse: collapse; border-color: #000; }
		table.lakepartner th { background-color: #666; color: #FFF; padding: 3px; }
		table.lakepartner td { padding: 3px; }</style>
	<script type="text/javascript" src="http://www.google.com/jsapi"></script>
	<script type="text/javascript" src="secchi_${ID}.js"></script>	
	<script type="text/javascript">
			google.load("visualization", "1", {packages:["corechart"]});
			google.setOnLoadCallback(drawChart);
			
			function drawChart() {
				var data = new google.visualization.DataTable();
				data.addColumn('string', 'Année');
				data.addColumn('number', 'Mesure du disque Secchi (m)');
				data.addRows(dataArray.length+1);
				
				for (var i=0; i<dataArray.length+1; i++){
					if(i == 0){
						var year = "" + (dataArray[0].year - 1)
						data.setValue(0, 0, year);
						data.setValue(0, 1, 0);	
					}else{
						data.setValue(i, 0, "" + dataArray[i-1].year );
						data.setValue(i, 1, dataArray[i-1].value);	
					}					
				}
				var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));     
				chart.draw(data, {width: 700, height: 480, colors:['#d4bfff'],     
							hAxis: {title: 'Année', titleColor:'black'}, vAxis: {title: 'Mesure du disque Secchi (m)', minValue: 0.0}
							});
			}
			window.onload = function (){
				var str = "	<table class='lakepartner' border='1'><tr><th><center>Année</center></th><th><center>Mesure du disque Secchi (m)</center></th></tr><tr><td>";
				strArray = [];
				for (var i=0; i<dataArray.length; i++){
					strArray.push(dataArray[i].year +  "</td><td><center>" + dataArray[i].value);
				}
				document.getElementById("data_table").innerHTML =  str + strArray.join("</center></td></tr><tr><td>") + "</center></td></tr></table>";			
			}
		</script>	
</head>
<body id="home">
<div id="wrapper">
  <div id="header"> 
  
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_header_fr.js"></script>
    
  </div>

  <a name="top" id="top"></a>
 
<div id="right_column">
<h1>${LAKENAME} (STN ${STN}, N&deg; du lieu ${SITEID})</h1>
<strong>${SITEDESC}</strong>
<p>Le Partenariat pour la protection des lacs ontariens est un programme de surveillance de la qualité de l’eau qui fait appel à des bénévoles de toute la province. Les bénévoles recueillent des échantillons d’eau d’un lac pour mesurer sa teneur en phosphore total et notent chaque mois des données sur la transparence de l’eau. Ces données permettent de noter rapidement les changements dans l'équilibre nutritif ou la transparence de l'eau du lac, qu'ils soient liés à l'aménagement des berges, au changement climatique ou à d’autres sources de perturbation.</p><p>Quelque 800 bénévoles évaluent la teneur en phosphore total de l’eau des lacs de l’Ontario dans 728 lieux.</p><p>Une teneur élevée en phosphore peut faire baisser la transparence de l’eau, car le phosphore stimule la croissance des algues. Cependant, la quantité de phosphore n’est pas le seul facteur qui altère la pénétration de la lumière dans le lac, car la quantité de carbone organique dissous (COD) ou de turbidité non biologique peuvent aussi être en cause. La transparence de l’eau peut aussi être altérée par des espèces envahissantes, comme les moules zébrées. Par conséquent, il est toujours préférable d’évaluer l’équilibre nutritif d’un lac en mesurant la teneur en phosphore total de l’eau. Néanmoins, il est utile de mesurer la transparence de l’eau pour noter les changements qui ne pourraient pas être décelés par la seule mesure de la teneur en phosphore total, comme une invasion de moules zébrées.</p><p><a href="JavaScript:window.print();">Imprimer cette page</a></p>      <center><h3>Transparence de l'eau (profondeur en mètres d’après le disque Secchi)</h3></center><center><div id="chart_div"></div><br>	<br><h3>Transparence de l'eau (profondeur en mètres d’après le disque Secchi)</h3>
<div id="data_table"></div>
</center>
		<br><br>Si vous avez des suggestions ou trouvez des erreurs, envoyez un courriel à <a href='mailto:lakepartner@ontario.ca?subject=Erreur de Portail'>lakepartner@ontario.ca</a>.
		</div>

  <div id="left_column">
 
 	<div class="leftnav">
      <div class="photocap nav_top mycolour">&nbsp;</div>
      <div class="mycolour"><h2 class="header"><a style="display:block;" href="javascript:void(0)" onclick="showHide('smenu1');return false;">Partenariat pour la protection des lacs ontariens<img src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/arrow_down.gif" width="9" height="9" alt="" title="Open the explore menu" id="smenu1_arrow" /></a></h2></div>
      <ul class="menu clear" id="smenu1" style="display:block;">
        <li><a href="http://www.ene.gov.on.ca/environment/fr/local/lake_partner_program/index.htm">Retour à Partenariat pour la protection des lacs ontariens</a></li>
		<li><a href="../LakePartner_Accessible_fr.htm">Version accessible</a></li>
      </ul>  
    </div>
    
    <div id="second_nav"></div>
	
	<script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_secondary_fr.js"></script>
 
  </div>
  <div id="footer">

    
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_footer_fr.js"></script>
    
  </div>
</div>
</body>
</html>

template_EN_TP.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<TITLE>Average Total Phosphorus (TP) Concentration (&micro;g/L)</TITLE>
		
    <!--PRIMARY-->
    <meta name="dc.title" content="" />
    <meta property="og:title" content="" />

    <meta name="dc.description" content="" />
    <meta name="description" content="" />
    <meta name="dcterms.audience" content="" />
    <meta name="dc.identifier" scheme="URI" content="" />
    <meta name="dc.date.created" scheme="W3CDTF" content="" />
    <meta name="dc.date.issued" scheme="W3CDTF" content="" />
    <meta name="dc.date.modified" scheme="W3CDTF" content="" />
    <!--PRIMARY-->
    
    <!--CONTROLLED-->

    <meta name="dc.subject" scheme="gccore" content="" />
    <meta name="Keywords" content="" />
    <meta name="dc.type" scheme="oncatype" content="" />
    <!--CONTROLLED-->
    
    <!--FACEBOOK-->
    <meta property="og:type" content="article" />
    <meta property="og:url" content="" />
    <meta property="og:image" content="" />
    <meta property="og:site_name" content="" />

    <meta property="og:description" content="" />
    <!--FACEBOOK-->	
	
	<!--SECONDARY-->
    <meta name="dc.format" scheme="IMT" content="text/html" />
    <meta name="dc.creator" content="Government of Ontario, Ministry of the Environment" />
    <meta name="dc.publisher" content="Government of Ontario, Ministry of the Environment" />
    <meta name="dc.contributor" content="Government of Ontario, Ministry of the Environment" />
    <meta name="dc.language" scheme="ISO639-2" content="Eng" />
    <meta name="dc.coverage.jurisdiction" content="Province of Ontario" />

    <meta name="dc.coverage.spatial" content="Ontario, Canada" />
    <meta name="dc.rights.intellectualProperty" content="Copyright: Queen's Printer for Ontario, 2010" />
    <meta name="go.contact.content" content="" />
    <meta name="go.contact.technical" content="" />
    <!--SECONDARY-->
	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/new.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/master.css" type="text/css" media="screen" />
	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/changeme.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/print.css" type="text/css" media="print" />

	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/mobile.css" type="text/css" media="handheld" />
	<link rel="icon" type="image/png" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/trillium4.ico" />
	
	<script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministryscripts/scripts/scripts.js"></script>
	<style type="text/css">
      .js #smenu3 {display:none;}
      .js #smenu4 {display:none;}
      .js #smenu5 {display:none;}
      .js #smenu6 {display:none;}
      .js #smenu7 {display:none;}
    </style>
    
    <script type="text/javascript">
      document.getElementsByTagName('html')[0].className = 'js';
    </script>
	<meta content="MSHTML 6.00.2900.3698" name="GENERATOR" />
	<style type="text/css">
		.lakepartner { width:700px; margin-right:-3px; border-spacing:1px; border-collapse:separate !important; border:1px #000000 solid; }	
		.lakepartner th { padding:2px; font-size:11px; border:1px #000000 solid; vertical-align:middle; text-align:left; }	  
		.lakepartner td { padding:2px; font-size:11px; border:1px #000000 solid; text-align:center; }
	</style>
	
	<style type="text/css">table.lakepartner { border-collapse: collapse; border-color: #000; }
		table.lakepartner th { background-color: #666; color: #FFF; padding: 3px; }
		table.lakepartner td { padding: 3px; }</style>
	<script type="text/javascript" src="http://www.google.com/jsapi"></script>
	<script type="text/javascript" src="tp_${ID}.js"></script>	
	<script type="text/javascript">
			google.load("visualization", "1", {packages:["corechart"]});
			google.setOnLoadCallback(drawChart);
			function greekSymbol(str) {return String.fromCharCode(str.charCodeAt(0) + (913 - 65));}
			function getAverage(tp1, tp2){
				var value = 0;
				if((typeof(tp1) != "undefined") && (typeof(tp2) != "undefined")){
					value = 0.5*(tp1 + tp2);
				}else{
					if((typeof(tp1) != "undefined")){
						value = tp1;
					}
					if((typeof(tp2) != "undefined")){
						value = tp2;
					}					
				}
				return parseFloat(value.toFixed(2));
				//return value;				
			}
			function drawChart() {
				var data = new google.visualization.DataTable();
				data.addColumn('string', 'Date');
				data.addColumn('number', 'Average Concentration of Total Phosphorus (' + greekSymbol('l') +'g/L)');
				data.addRows(dataArray.length);				
				for (var i=0; i<dataArray.length; i++){
					data.setValue(i, 0, dataArray[i].date);
					data.setValue(i, 1, getAverage(dataArray[i].tp1, dataArray[i].tp2));	
				}
				var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));     
				chart.draw(data, {width: 700, height: 480, colors:['#d4bfff'],     
							hAxis: {title: 'Date', titleColor:'black'}, vAxis: {title: 'Average Concentration of Total Phosphorus (' + greekSymbol('l') +'g/L)', minValue: 0.0}
							});
			}
			window.onload = function (){
				var str = "<table class='lakepartner' border='1'><tr><th><center>Date</center></th><th><center>Sample 1 (&micro;g/L)</center></th><th><center>Sample 2 (&micro;g/L)</center></th><th><center>Average (&micro;g/L)</center></th></tr><tr><td>";
				strArray = [];
				for (var i=0; i<dataArray.length; i++){
					var v1 = "";
					if((typeof(dataArray[i].tp1) != "undefined")){
						v1 = "" + (dataArray[i].tp1);
					}
					var v2 = "";
					if((typeof(dataArray[i].tp2) != "undefined")){
						v2 = "" + (dataArray[i].tp2);
					}
					avgString = "";
					var avg = getAverage(dataArray[i].tp1, dataArray[i].tp2);
					if(avg > 0){
						avgString = "" + avg;
					}
					strArray.push(dataArray[i].date +  "</td><td><center>" + v1 +  "</td><td><center>" + v2 + "</td><td><center>" + avgString);
				}
				document.getElementById("data_table").innerHTML =  str + strArray.join("</center></td></tr><tr><td>") + "</center></td></tr></table>";			
			}
		</script>	
</head>
<body id="home">
<div id="wrapper">
  <div id="header"> 
  
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_header.js"></script>
  
</div>
  <a name="top" id="top"></a>
  
  <div id="right_column">
<h1>${LAKENAME} (STN ${STN}, Site ID ${SITEID})</h1>
<strong>${SITEDESC}</strong>
<p>The Lake Partner Program is a province-wide, volunteer-based, water-quality monitoring program. Volunteers collect total phosphorus samples and make monthly water clarity observations on their lakes. This information will allow the early detection of changes in the nutrient status and/or the water clarity of the lake due to the impacts of shoreline development, climate change and other stresses.</p><p>Approximately 800 active volunteers monitor Secchi depth and total phosphorus at 728 locations in the lakes across Ontario.</p><p>Total phosphorus concentration are ideally used to interpret nutrient status in Ontario lakes, since phosphorus is the element that controls the growth of algae in most Ontario lakes. Increases in phosphorus will decrease water clarity by stimulating algal growth. In extreme cases, algal blooms will affect the aesthetics of the lake and/or cause taste and odour problems in the water.</p><p>Many limnologists place lakes into three broad categories with respect to nutrient status. Lakes with less that 10 μg/L TP are considered oligotrophic. These are dilute, unproductive lakes that rarely experience nuisance algal blooms. Lakes with TP between 10 and 20 μg/L are termed mesotrophic and are in the middle with respect to trophic status. These lakes show a broad range of characteristics and can be clear and unproductive at the bottom end of the scale or susceptible to moderate algal blooms at concentration near 20 μg/L. Lakes over 20 μg/L are classed as eutrophic and may exhibit persistent, nuisance algal blooms.</p><p>Note: Tea stained lakes, with high dissolved organic carbon (DOC), are called dystrophic lakes and do not share the algal/TP relationships described above. Generally there can be more TP in a dystrophic lake without the occurrence of algal blooms. The chemistry of these lakes is quite complex.</p><p><a href="JavaScript:window.print();">Print this page</a></p>      <center><h3>Average Total Phosphorus (TP) Concentration (&micro;g/L)</h3></center><center><div id="chart_div"></div><br>
	<br><h3>Average Total Phosphorus (TP) Concentration (&micro;g/L)</h3>
	<div id="data_table"></div>
</center>
		<br><br>If you have some suggestions or find some errors, please send an Email to <a href='mailto:lakepartner@ontario.ca?subject=Portal Error Submission'>lakepartner@ontario.ca</a>.
		</div>
<div id="left_column">

 
 	<div class="leftnav">
      <div class="photocap nav_top mycolour">&nbsp;</div>
      <div class="mycolour"><h2 class="header"><a style="display:block;" href="javascript:void(0)" onclick="showHide('smenu1');return false;">Provincial Groundwater Monitoring Network<img src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/arrow_down.gif" width="9" height="9" alt="" title="Open the explore menu" id="smenu1_arrow" /></a></h2></div>
      <ul class="menu clear" id="smenu1" style="display:block;">
	       <li><a href="http://www.ene.gov.on.ca/environment/en/local/lake_partner_program/index.htm">Return to Lake Partner Program</a></li>
	       <li><a href="../LakePartner_Accessible_en.htm">Accessibile Version</a></li>
      </ul>  
    </div>

    
    <div id="second_nav"></div>
	
	<script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_secondary.js"></script>
  
  </div>
  <div id="footer">
    
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_footer.js"></script>
  </div>
</div>
</body>
</html>


template_FR_TP.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//FR" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<TITLE>Concentration moyennes de phosphore total (&micro;g/L)</TITLE>
	
    <!--PRIMARY-->
    <meta name="dc.title" content=" />
    <meta property="og:title" content=" />
    <meta name="dc.description" content=" />
    <meta name="description" content=" />
    <meta name="dcterms.audience" content=" />
    <meta name="dc.identifier" scheme="URI" content=" />
    <meta name="dc.date.created" scheme="W3CDTF" content=" />
    <meta name="dc.date.issued" scheme="W3CDTF" content=" />
    <meta name="dc.date.modified" scheme="W3CDTF" content=" />
    <!--PRIMARY-->
    
    <!--CONTROLLED-->
    <meta name="dc.subject" scheme="gccore" content=" />
    <meta name="Keywords" content=" />
    <meta name="dc.type" scheme="oncatype" content=" />
    <!--CONTROLLED-->
    
    <!--FACEBOOK-->
    <meta property="og:type" content="article" />
    <meta property="og:url" content=" />
    <meta property="og:image" content=" />
    <meta property="og:site_name" content=" />
    <meta property="og:description" content=" />
    <!--FACEBOOK-->	
	
	<!--SECONDARY-->
    <meta name="dc.format" scheme="IMT" content="text/html" />

    <meta name="dc.creator" content="Gouvernement de l'Ontario, Ministere de l'Environnement" />
    <meta name="dc.publisher" content="Gouvernement de l'Ontario, Ministere de l'Environnement" />
    <meta name="dc.contributor" content="Gouvernement de l'Ontario, Ministere de l'Environnement" />
    <meta name="dc.language" scheme="ISO639-2" content="fre" />
    <meta name="dc.coverage.jurisdiction" content="Province d'Ontario" />
    <meta name="dc.coverage.spatial" content="Ontario, Canada" />
    <meta name="dc.rights.intellectualProperty" content="Renseignements sur les droits d'auteur Imprimeur de la Reine pour l'Ontario, 2009 - 2010" />
    <meta name="go.contact.content" content="nmu.moe@ontario.ca" />
    <meta name="go.contact.technical" content="webmaster.moe@ontario.ca" />

    <!--SECONDARY-->
	<link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/new.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/master.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/changeme.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/print.css" type="text/css" media="print" />
    <link rel="stylesheet" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/css/mobile.css" type="text/css" media="handheld" />
    
    <link rel="icon" type="image/png" href="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/trillium4.ico" />
    
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministryscripts/scripts/scripts.js"></script>

	<style type="text/css">
      .js #smenu3 {display:none;}
      .js #smenu4 {display:none;}
      .js #smenu5 {display:none;}
      .js #smenu6 {display:none;}
      .js #smenu7 {display:none;}
    </style>
    
    <script type="text/javascript">
      document.getElementsByTagName('html')[0].className = 'js';
    </script>
	<meta content="MSHTML 6.00.2900.3698" name="GENERATOR" />
	<style type="text/css">
		.lakepartner { width:700px; margin-right:-3px; border-spacing:1px; border-collapse:separate !important; border:1px #000000 solid; }	
		.lakepartner th { padding:2px; font-size:11px; border:1px #000000 solid; vertical-align:middle; text-align:left; }	  
		.lakepartner td { padding:2px; font-size:11px; border:1px #000000 solid; text-align:center; }
	</style>
	
	<style type="text/css">table.lakepartner { border-collapse: collapse; border-color: #000; }
		table.lakepartner th { background-color: #666; color: #FFF; padding: 3px; }
		table.lakepartner td { padding: 3px; }</style>
	<script type="text/javascript" src="http://www.google.com/jsapi"></script>
	<script type="text/javascript" src="tp_${ID}.js"></script>	
	<script type="text/javascript">
			google.load("visualization", "1", {packages:["corechart"]});
			google.setOnLoadCallback(drawChart);
			function greekSymbol(str) {return String.fromCharCode(str.charCodeAt(0) + (913 - 65));}
			function getAverage(tp1, tp2){
				var value = 0;
				if((typeof(tp1) != "undefined") && (typeof(tp2) != "undefined")){
					value = 0.5*(tp1 + tp2);
				}else{
					if((typeof(tp1) != "undefined")){
						value = tp1;
					}
					if((typeof(tp2) != "undefined")){
						value = tp2;
					}					
				}
				return parseFloat(value.toFixed(2));
				//return value;				
			}
			function drawChart() {
				var data = new google.visualization.DataTable();
				data.addColumn('string', 'Date');
				data.addColumn('number', 'Concentration moyennes de phosphore total (' + greekSymbol('l') +'g/L)');
				data.addRows(dataArray.length);				
				for (var i=0; i<dataArray.length; i++){
					data.setValue(i, 0, dataArray[i].date);
					data.setValue(i, 1, getAverage(dataArray[i].tp1, dataArray[i].tp2));	
				}
				var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));     
				chart.draw(data, {width: 700, height: 480, colors:['#d4bfff'],     
							hAxis: {title: 'Date', titleColor:'black'}, vAxis: {title: 'Concentration moyennes de phosphore total  (' + greekSymbol('l') +'g/L)', minValue: 0.0}
							});
			}
			window.onload = function (){
				var str = "<table class='lakepartner' border='1'><tr><th><center>Date</center></th><th><center>Échantillon 1 (&micro;g/L)</center></th><th><center>Échantillon 2 (&micro;g/L)</center></th><th><center>Moyenne (&micro;g/L)</center></th></tr><tr><td>";
				strArray = [];
				for (var i=0; i<dataArray.length; i++){
					var v1 = "";
					if((typeof(dataArray[i].tp1) != "undefined")){
						v1 = "" + (dataArray[i].tp1);
					}
					var v2 = "";
					if((typeof(dataArray[i].tp2) != "undefined")){
						v2 = "" + (dataArray[i].tp2);
					}
					avgString = "";
					var avg = getAverage(dataArray[i].tp1, dataArray[i].tp2);
					if(avg > 0){
						avgString = "" + avg;
					}
					strArray.push(dataArray[i].date +  "</td><td><center>" + v1 +  "</td><td><center>" + v2 + "</td><td><center>" + avgString);
				}
				document.getElementById("data_table").innerHTML =  str + strArray.join("</center></td></tr><tr><td>") + "</center></td></tr></table>";			
			}
		</script>	
</head>
<body id="home">
<div id="wrapper">
  <div id="header"> 
  
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_header_fr.js"></script>
    
  </div>

  <a name="top" id="top"></a>
 
<div id="right_column">
<h1>${LAKENAME} (STN ${STN}, N&deg; du lieu ${SITEID})</h1>
<strong>${SITEDESC}</strong>
<p>Le Partenariat pour la protection des lacs ontariens est un programme de surveillance de la qualité de l’eau qui fait appel à des bénévoles de toute la province. Les bénévoles recueillent des échantillons d’eau d’un lac pour mesurer sa teneur en phosphore total et notent chaque mois des données sur la transparence de l’eau. Ces données permettent de noter rapidement les changements dans l’équilibre nutritif ou la transparence de l’eau du lac, qu’ils soient liés à l’aménagement des berges, au changement climatique ou à d’autres sources de perturbation.</p><p>Quelque 800 bénévoles mesurent la transparence de l’eau avec un disque Secchi et évaluent la teneur en phosphore total de l’eau des lacs de l’Ontario dans 728 lieux.</p><p>Les mesures de la teneur en phosphore total servent à évaluer l’équilibre nutritif des lacs de l’Ontario, car le phosphore est la substance qui favorise la croissance des algues dans la plupart des lacs de l’Ontario. Plus la teneur en phosphore est élevée, plus il y a d’algues et donc plus l’eau est trouble. Dans les cas extrêmes, la prolifération d’algues dégrade l’aspect physique du lac, altère le goût de l’eau ou entraîne des odeurs.</p><p>Les limnologues classent généralement les lacs en trois catégories d’équilibre nutritif. D’abord, les lacs oligotrophes contiennent moins de 10 μg/L de phosphore total. Dilués et improductifs, ils sont rarement envahis par les algues. Ensuite, les lacs mésotrophes contiennent entre 10 et 20 μg/L de phosphore total. Situés au milieu de l’échelle trophique, ces lacs ont des caractéristiques variées. Ils peuvent être transparents et improductifs ou présenter une quantité modérée d’algues avec des concentration de près de 20 μg/L. Enfin, les lacs eutrophes contiennent plus de 20 μg/L de phosphore total et présentent des algues en abondance.</p><p>À noter : Les lacs dystrophes, de teinte brune, contiennent beaucoup de carbone organique dissous (COD). Le phosphore total dans ces lacs n’augmente pas la quantité d’algues comme dans les lacs décrits ci-dessus. Généralement, ces lacs peuvent avoir une teneur élevée en phosphore total sans prolifération d’algues. Leur composition chimique est assez complexe.
</p>

<p><a href="JavaScript:window.print();">Imprimer cette page</a></p>      <center><h3>Concentration moyennes de phosphore total (&micro;g/L)</h3></center><center><div id="chart_div"></div><br>	<br><h3>Concentration moyennes de phosphore total (&micro;g/L)</h3>
<div id="data_table"></div>
</center>
		<br><br>Si vous avez des suggestions ou trouvez des erreurs, envoyez un courriel à <a href='mailto:lakepartner@ontario.ca?subject=Erreur de Portail'>lakepartner@ontario.ca</a>.
		</div>

  <div id="left_column">
 
 	<div class="leftnav">
      <div class="photocap nav_top mycolour">&nbsp;</div>
      <div class="mycolour"><h2 class="header"><a style="display:block;" href="javascript:void(0)" onclick="showHide('smenu1');return false;">Partenariat pour la protection des lacs ontariens<img src="http://www.ene.gov.on.ca/stdprodconsume/fragments/ministrystylesheets/images/arrow_down.gif" width="9" height="9" alt="" title="Open the explore menu" id="smenu1_arrow" /></a></h2></div>
      <ul class="menu clear" id="smenu1" style="display:block;">
        <li><a href="http://www.ene.gov.on.ca/environment/fr/local/lake_partner_program/index.htm">Retour à Partenariat pour la protection des lacs ontariens</a></li>
		<li><a href="../LakePartner_Accessible_fr.htm">Version accessible</a></li>
      </ul>  
    </div>
    
    <div id="second_nav"></div>
	
	<script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_secondary_fr.js"></script>
 
  </div>
  <div id="footer">

    
    <script type="text/javascript" src="http://www.ene.gov.on.ca/stdprodconsume/groups/lr/@enetemplates/documents/developerfile/moe_footer_fr.js"></script>
    
  </div>
</div>
</body>
</html>



Learn to Program: Crafting Quality Code

$
0
0
# Do not import any modules. If you do, the tester may reject your submission.

# Constants for the contents of the maze.

# The visual representation of a wall.
WALL = '#'

# The visual representation of a hallway.
HALL = '.'

# The visual representation of a brussels sprout.
SPROUT = '@'

# Constants for the directions. Use these to make Rats move.

# The left direction.
LEFT = -1

# The right direction.
RIGHT = 1

# No change in direction.
NO_CHANGE = 0

# The up direction.
UP = -1

# The down direction.
DOWN = 1

# The letters for rat_1 and rat_2 in the maze.
RAT_1_CHAR = 'J'
RAT_2_CHAR = 'P'


class Rat:
    """ A rat caught in a maze. """

    # Write your Rat methods here.
    def __init__(self, symbol, row, col):
    """(Rat, str, int, int) -> NoneType"""
        self.symbol = symbol
        self.row = row
        self.col = col
        self.num_sprouts_eaten = 0
    def set_location(self, row, col):
    """(Rat, int, int) -> NoneType"""
        self.row = row
        self.col = col
    def eat_sprout(self):
    """(Rat) -> NoneType"""
        self.num_sprouts_eaten = self.num_sprouts_eaten + 1
    def __str__(self):
    """(Rat) -> str"""
         return self.symbol + ' at ('+ self.row +', '+ self.col +') ate ' + self.num_sprouts_eaten + ' sprouts.'
class Maze:
    """ A 2D maze. """
    def __init__(self, maze, rat_1, rat_2):
    """(Maze, list of list of str, Rat, Rat) -> NoneType"""
        self.maze = maze
        self.rat_1 = rat_1
        self.rat_2 = rat_2
        self.num_sprouts_left = 0
        for i in range(maze):
             for j in range(len(maze[i])):
                 if (maze[i][j] == SPROUT):
                     self.num_sprouts_left = self.num_sprouts_left + 1

    def is_wall(self, row, col):
    """(Maze, int, int) -> bool"""
        return maze[row][col] == WALL
    def get_character(self, row, col):
    """(Maze, int, int) -> str"""
        return maze[row][col]
    def move(self, rat, vDir, hDir):
    """(Maze, Rat, int, int) -> bool"""
        row = rat.row + vDir
        col = rat.col + hDir
        if (maze[row][col] == WALL):
            return False
        else:
            if (maze[row][col] == SPROUT):
                rat.eat_sprout()
                maze[row][col] = HALL
                self.num_sprouts_left = self.num_sprouts_left - 1
            rat.set_location(row, col)
            return True
    def __str__(self):
    """(Maze) -> str"""          
         maze[rat_1.row][rat_1.col] == rat_1.symbol
         maze[rat_2.row][rat_2.col] == rat_2.symbol
         result = str(maze) + str(rat_1) + str(rat_2)
         maze[rat_1.row][rat_1.col] == HALL
         maze[rat_2.row][rat_2.col] == HALL
         return result
    # Write your Maze methods here.

The Hardware/Software Interface Lab 1

$
0
0

Lab 1: Instructions


When you’re ready to submit your solution, go to the assignments list.


Lab 1: Manipulating Bits Using C

Overview

The purpose of this assignment is to become more familiar with data at the bit-level representation. You’ll do this by solving a series of programming “puzzles”. Many of these puzzles may seem artificial, but in fact bit manipulations are very useful in cryptography, data encoding, implementing file formats (e.g., MP3), etc. By working your way through these problems, you will get very familiar with bit representations and hopefully will have some fun. You will also be doing some very basic pointer manipulations and arithmetic. Again, the purpose is to get you familiar with data representations and pointers.

Instructions

Perform an update to your course-materials directory on the by running the update-course command from a terminal window. On the script’s success, you should find the provided code for lab1 in your course-materials directory. As a convenience, here is an archive of the course-materials directory as of this lab assignment: lab1.tar.gz.

The lab1 folder contains a number of tools, described later, a bits.c file, and a pointer.c file. Both files contain skeletons for the programming puzzles, along with a comment block that describes exactly what the function must do and what restrictions there are on its implementation. Your assignment is to complete each function skeleton using:

  • only straightline code (i.e., no loops or conditionals);
  • a limited number of C arithmetic and logical operators; and
  • no constants larger than 8 bits (i.e., 0 – 255 inclusive).

The intent of the restrictions is to require you to think about the data as bits – because of the restrictions, your solutions won’t be the most efficient way to accomplish the function’s goal, but the process of working out the solution should make the notion of data as bits completely clear.

Similarly, you will start working with basic pointers and use them to compute the size of different data items in memory and to modify the contents of an array

The Bit Puzzles

This section describes the puzzles that you will be solving in bits.c. More complete (and definitive, should there be any inconsistencies) documentation is found in the bits.c file itself.

Bit Manipulations

The table below describes a set of functions that manipulate and test sets of bits. The Rating column gives the difficulty rating (the number of points) for each puzzle and the Description column states the desired output for each puzzle along with the constraints. See the comments in bits.c for more details on the desired behavior of the functions. You may also refer to the test functions in tests.c. These are used as reference functions to express the correct behavior of your functions, although they don’t satisfy the coding rules for your functions.

Rating Function Name Description
1 bitAnd x & y using only ~ and |
1 bitXor x ^ y using only ~ and &
1 thirdBits return word with every third bit (starting from the least significant bit) set to 1
2 getByte Extract byte n from word x
3 logicalShift shift x to the right by n, using a logical shift
4 bang Compute !x without using !
Extra Credit:
3 conditional x ? y : z

Two’s Complement Arithmetic

The following table describes a set of functions that make use of the two’s complement representation of integers. Again, refer to the comments in bits.c and the reference versions in tests.c for more information.

Rating Function Name Description
2 fitsBits returns 1 if x can be represented as an n-bit, two’s complement integer
2 sign return 1 if positive, 0 if zero, and -1 if negative
3 addOK Determine if x+y can be computed without overflow
Extra Credit:
4 isPower2 returns 1 if x is a power of 2, and 0 otherwise

Checking Your Work

We have included two tools to help you check the correctness of your work.

dlc is a modified version of an ANSI C compiler from the MIT CILK group that you can use to check for compliance with the coding rules for each puzzle. The typical usage is:

$ ./dlc bits.c

The program runs silently unless it detects a problem, such as an illegal operator, too many operators, or non-straightline code in the integer puzzles. Running with the -e switch:

$ ./dlc -e bits.c

causes dlc to print counts of the number of operators used by each function. Type ./dlc -help for a list of command line options.

btest is a program that checks the functional correctness of the code in bits.c. To build and use it, type the following two commands:

$ make
$ ./btest

Notice that you must rebuild btest each time you modify your bits.c file. (You rebuild it by typing make.) You’ll find it helpful to work through the functions one at a time, testing each one as you go. You can use the -f flag to instruct btest to test only a single function:

$ ./btest -f bitXor

You can feed it specific function arguments using the option flags -1-2, and -3:

$ ./btest -f bitXor -1 7 -2 0xf

Check the file README for documentation on running the btest program.

Advice

Start early on bits.c, if you get stuck on one problem move on. You may find you suddenly realize the solution the next day. Puzzle over the problems yourself, it is much more rewarding to find the solution yourself than stumble upon someone else’s solution. If you do not quite meet the operator limit don’t worry there will be partial credit, but often times working with a suboptimal solution will allow you to see how to improve it.

Do not include the <stdio.h> header file in your bits.c file, as it confuses dlc and results in some non-intuitive error messages. You will still be able to use printf in your bits.c file for debugging without including the <stdio.h> header, although gcc will print a warning that you can ignore.

You should be able to use the debugger on your code. For example:

$ make
gcc -O -Wall -m32 -g -lm -o btest bits.c btest.c decl.c tests.c
gcc -O -Wall -m32 -g -o fshow fshow.c
gcc -O -Wall -m32 -g -o ishow ishow.c
$ gdb ./btest
GNU gdb (GDB) Fedora (7.1-34.fc13)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Reading symbols from /homes/iws/dvhc/cse351/lab1/src/btest...done.
(gdb) b bitXor
Breakpoint 1 at 0x8048717: file bits.c, line 144.
(gdb) r
Starting program: /homes/iws/dvhc/cse351/lab1/src/btest
ScoreRatingErrorsFunction

Breakpoint 1, bitXor (x=-2147483648, y=-2147483648) at bits.c:144
144}
(gdb) p x
$1 = -2147483648
(gdb) p/x x
$2 = 0x80000000
(gdb) q
A debugging session is active.

Inferior 1 [process 12728] will be killed.

Quit anyway? (y or n) y

The dlc program enforces a stricter form of C declarations than is the case for C++ or that is enforced by gcc. In particular, in a block (what you enclose in curly braces) all your variable declarations must appear before any statement that is not a declaration. For example, dlc will complain about the following code:

int foo(int x)
{
    int a = x;
    a *= 3;     /* Statement that is not a declaration */
    int b = a;  /* ERROR: Declaration not allowed here */
}

Instead, you must declare all your variables first, like this:

int foo(int x)
{
    int a = x;
    int b;
    a *= 3;
    b = a;
}

Using Pointers

This section describes the four functions you will be completing in pointer.c that is also in the lab1 folder you downloaded. Refer to the file pointer.c itself for more complete details.

Pointer Arithmetic

The first three functions in pointer.c ask you to compute the size (in bytes) of various data elements (ints, doubles, and pointers). You will accomplish this by noting that arrays of these data elements allocate contiguous space in memory so that one element follows the next. You are permitted to use casts for these functions.

Manipulating Data Using Pointers

The fourth function in pointer.c asks you to change the value of an element of an array using only the starting address of the array. You will add the appropriate value to the pointer to create a new pointer to the data element to be modified.

The next two functions deal with boundings checking of pointers and the final function deals with more bit manipulation. You

Checking your work

For pointer.c, we have included a simple test harness: ptest.c. You can test your solutions like this:

$ make ptest
$ ./ptest

This test harness only checks if your solutions return the expected result, not if they meet the specific criteria of each problem. We will review your solutions to ensure they meet the restrictions of the assignment.

Submitting Your Work

You will be able to submit your assignment with the submit-hw script that is bundled with the lab1 course-materials update. Using the script should be straight-forward, but it does expect you to not move/rename any files from the ”course-materials” directory. Open a terminal and type the following commands:

  submit-hw lab1.bits
  submit-hw lab1.pointer

This will submit both bits.c and pointer.c (one file per command). However, you may just want to submit all parts for Lab1 together. You may use the following command to do so. It will save you the trouble of calling both commands, but it will still count as a submission for each part.

  submit-hw lab1

After calling the submit-hw script, you will be prompted for your Coursera username and then your submission password. Your submission password is NOT the same as your regular Coursera account password!!!! You may locate your submission password at the top of the assignments list page.

After providing your credentials, the submit-hw script will run some basic checks on your code. For bits.c, it will run the driver.pl script and warn you if you get below a score of 41 (full-credit without the extra-credit). For pointer.c, it will simply check to see if ptest reports any failures to the tests.

Once confirming that you wish to submit, with a working Internet connection, the script should submit your code properly. You can go to the assignments list page to double-check that it has been submitted and check your score as well as any feedback the auto-grader gives you. You may also download your submission code from this page, if you wish.

// Rating: 1
int bitAnd(int, int);
int test_bitAnd(int, int);
int bitXor(int, int);
int test_bitXor(int, int);
int thirdBits();
int test_thirdBits();
// Rating: 2
int fitsBits(int, int);
int test_fitsBits(int, int);
int sign(int);
int test_sign(int);
int getByte(int, int);
int test_getByte(int, int);
// Rating: 3
int logicalShift(int, int);
int test_logicalShift(int, int);
int addOK(int, int);
int test_addOK(int, int);
// Rating: 4
int bang(int);
int test_bang(int);
// Extra Credit: Rating: 3
int conditional(int, int, int);
int test_conditional(int, int, int);
// Extra Credit: Rating: 4
int isPower2(int);
int test_isPower2(int);

/*
 * CSE 351 HW1 (Data Lab )
 *
 * *
 * bits.c - Source file with your solutions to the Lab.
 * This is the file you will hand in to your instructor.
 *
 * WARNING: Do not include the header; it confuses the dlc
 * compiler. You can still use printf for debugging without including
 * , although you might get a compiler warning. In general,
 * it's not good practice to ignore compiler warnings, but in this
 * case it's OK.
 */

#if 0
/*
 * Instructions to Students:
 *
 * STEP 1: Read the following instructions carefully.
 */

You will provide your solution to this homework by
editing the collection of functions in this source file.

INTEGER CODING RULES:

 Replace the "return" statement in each function with one
 or more lines of C code that implements the function. Your code
 must conform to the following style:

 int Funct(arg1, arg2, ...) {
 /* brief description of how your implementation works */
 int var1 = Expr1;
 ...
 int varM = ExprM;

 varJ = ExprJ;
 ...
 varN = ExprN;
 return ExprR;
 }

 Each "Expr" is an expression using ONLY the following:
 1. Integer constants 0 through 255 (0xFF), inclusive. You are
 not allowed to use big constants such as 0xffffffff.
 2. Function arguments and local variables (no global variables).
 3. Unary integer operations ! ~
 4. Binary integer operations & ^ | + << >>

 Some of the problems restrict the set of allowed operators even further.
 Each "Expr" may consist of multiple operators. You are not restricted to
 one operator per line.

 You are expressly forbidden to:
 1. Use any control constructs such as if, do, while, for, switch, etc.
 2. Define or use any macros.
 3. Define any additional functions in this file.
 4. Call any functions.
 5. Use any other operations, such as &&, ||, -, or ?:
 6. Use any form of casting.
 7. Use any data type other than int. This implies that you
 cannot use arrays, structs, or unions.

 You may assume that your machine:
 1. Uses 2s complement, 32-bit representations of integers.
 2. Performs right shifts arithmetically.
 3. Has unpredictable behavior when shifting an integer by more
 than the word size.

EXAMPLES OF ACCEPTABLE CODING STYLE:
 /*
 * pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
 */
 int pow2plus1(int x) {
 /* exploit ability of shifts to compute powers of 2 */
 return (1 << x) + 1;
 }

 /*
 * pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
 */
 int pow2plus4(int x) {
 /* exploit ability of shifts to compute powers of 2 */
 int result = (1 << x);
 result += 4;
 return result;
 }

NOTES:
 1. Use the dlc (data lab checker) compiler (described in the handout) to
 check the legality of your solutions.
 2. Each function has a maximum number of operators (! ~ & ^ | + << >>)
 that you are allowed to use for your implementation of the function.
 The max operator count is checked by dlc. Note that '=' is not
 counted; you may use as many of these as you want without penalty.
 3. Use the btest test harness to check your functions for correctness.
 4. The maximum number of ops for each function is given in the
 header comment for each function. If there are any inconsistencies
 between the maximum ops in the writeup and in this file, consider
 this file the authoritative source.

/*
 * STEP 2: Modify the following functions according the coding rules.
 *
 * IMPORTANT. TO AVOID GRADING SURPRISES:
 * Use the dlc compiler to check that your solutions conform
 * to the coding rules.
 */

#endif
// Rating: 1
/*
 * bitAnd - x&y using only ~ and |
 * Example: bitAnd(6, 5) = 4
 * Legal ops: ~ |
 * Max ops: 8
 * Rating: 1
 */
int bitAnd(int x, int y) {
 return ~(~x | ~y);
}
/*
 * bitXor - x^y using only ~ and &
 * Example: bitXor(4, 5) = 1
 * Legal ops: ~ &
 * Max ops: 14
 * Rating: 1
 */
int bitXor(int x, int y) {
 return ~(~x & ~y);
}
/*
 * thirdBits - return word with every third bit (starting from the LSB) set to 1
 * and the rest set to 0
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 8
 * Rating: 1
 */
int thirdBits(void) {
 return 2;
}
// Rating: 2
/*
 * fitsBits - return 1 if x can be represented as an
 * n-bit, two's complement integer.
 * 1 <= n <= 32
 * Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 15
 * Rating: 2
 */
int fitsBits(int x, int n) {
 return 2;
}
/*
 * sign - return 1 if positive, 0 if zero, and -1 if negative
 * Examples: sign(130) = 1
 * sign(-23) = -1
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 10
 * Rating: 2
 */
int sign(int x) {
 return 2;
}
/*
 * getByte - Extract byte n from word x
 * Bytes numbered from 0 (LSB) to 3 (MSB)
 * Examples: getByte(0x12345678,1) = 0x56
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 6
 * Rating: 2
 */
int getByte(int x, int n) {
 return 2;
}
// Rating: 3
/*
 * logicalShift - shift x to the right by n, using a logical shift
 * Can assume that 0 <= n <= 31
 * Examples: logicalShift(0x87654321,4) = 0x08765432
 * Legal ops: ~ & ^ | + << >>
 * Max ops: 20
 * Rating: 3
 */
int logicalShift(int x, int n) {
 return 2;
}
/*
 * addOK - Determine if can compute x+y without overflow
 * Example: addOK(0x80000000,0x80000000) = 0,
 * addOK(0x80000000,0x70000000) = 1,
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 20
 * Rating: 3
 */
int addOK(int x, int y) {
 return 2;
}
// Rating: 4
/*
 * bang - Compute !x without using !
 * Examples: bang(3) = 0, bang(0) = 1
 * Legal ops: ~ & ^ | + << >>
 * Max ops: 12
 * Rating: 4
 */
int bang(int x) {
 return 2;
}
// Extra Credit: Rating: 3
/*
 * conditional - same as x ? y : z
 * Example: conditional(2,4,5) = 4
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 16
 * Rating: 3
 */
int conditional(int x, int y, int z) {
 return 2;
}
// Extra Credit: Rating: 4
/*
 * isPower2 - returns 1 if x is a power of 2, and 0 otherwise
 * Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
 * Note that no negative number is a power of 2.
 * Legal ops: ! ~ & ^ | + << >>
 * Max ops: 20
 * Rating: 4
 */
int isPower2(int x) {
 return 2;
}
/*
 * CSE 351 HW1 (Data Lab - Pointers)
 *
 * <Please put your name and userid here>
 *
 * pointer.c - Source file with your solutions to the Lab.
 *          This is the file you will hand in to your instructor.
 *
 * WARNING: Do not include the <stdio.h> header; it confuses the dlc
 * compiler. You can still use printf for debugging without including
 * <stdio.h>, the following function declaration should prevent a
 * compiler warning. In general, it's not good practice to ignore
 * compiler warnings, but in this case it's OK.
 */
int printf(const char *, ...);

#if 0
/*
 * Instructions to Students:
 *
 * STEP 1: Read the following instructions carefully.
 */

You will provide your solution to this homework by
editing the collection of functions in this source file.

INTEGER CODING RULES:

  Replace the "return" statement in each function with one
  or more lines of C code that implements the function. Your code
  must conform to the following style:

  int Funct(arg1, arg2, ...) {
      /* brief description of how your implementation works */
      int var1 = Expr1;
      ...
      int varM = ExprM;

      varJ = ExprJ;
      ...
      varN = ExprN;
      return ExprR;
  }

  Each "Expr" is an expression using ONLY the following:
  1. Integer constants 0 through 255 (0xFF), inclusive. You are
      not allowed to use big constants such as 0xffffffff.
  2. Function arguments and local variables (no global variables).
  3. For 1-4, only Unary integer operations *, & and Binary integer
      operations - + * are allowed. For the last three, you may also
      use shifts (<<, >>), ~, ==, and ^.

  Some of the problems restrict the set of allowed operators even further.
  Each "Expr" may consist of multiple operators. You are not restricted to
  one operator per line.

  You are expressly forbidden to:
  1. Use any control constructs such as if, do, while, for, switch, etc.
  2. Define or use any macros.
  3. Define any additional functions in this file.
  4. Call any functions.
  5. Use any other operations, such as &&, ||, ?: or sizeof.
  6. Use any data type other than those already in the declarations provided.

  You may assume that your machine:
  1. Uses 2s complement, 32-bit representations of integers.
  2. Performs right shifts arithmetically.
  3. Has unpredictable behavior when shifting an integer by more
     than the word size.

/*
 * STEP 2: Modify the following functions according the coding rules.
 *
 * Test the code below in your own 'main' program.
 *
 */

#endif

/*
 * Return the size of an integer in bytes.
 */
int intSize() {
  int intArray[10];
  int * intPtr1;
  int * intPtr2;
  // TODO: Write code to compute size of an integer.

  return 2;
}

/*
 * Return the size of a double in bytes.
 */
int doubleSize() {
  double doubArray[10];
  double * doubPtr1;
  double * doubPtr2;
  // TODO: Write code to compute size of a double.

  return 2;
}

/*
 * Return the size of a pointer in bytes.
 */
int pointerSize() {
  double * ptrArray[10];
  double ** ptrPtr1;
  double ** ptrPtr2;
  // TODO: Write code to compute size of a pointer.

  return 2;
}

/*
 * Modify intArray[5] to be the value 351 using only &intArray and
 * pointer arithmetic.
 */
int changeValue() {
  int intArray[10];
  int * intPtr1 = intArray;
  int * intPtr2;
  // TODO: Write code to change value of intArray[5] to 351 using only
  //       intPtr1 and the + operator.

  return intArray[5];
}


/*
 * Return 1 if ptr1 and ptr2 are within the *same* 64-byte aligned
 * block (or word) of memory. Return zero otherwise.
 *
 * Operators / and % and loops are NOT allowed.
 */
int withinSameBlock(int * ptr1, int * ptr2) {
  // TODO
  return 2;
}

/*
 * Return 1 if ptr points to an element within the specified intArray,
 * 0 otherwise.
 */
int withinArray(int * intArray, int size, int * ptr) {
  // TODO
  return 2;
}
/*
 * Return x with the n bits that begin at position p inverted (i.e.,
 * turn 0 into 1 and vice versa) and the rest left unchanged. Consider
 * the indices of x to begin with the low-order bit numbered as 0.
 */
int invert(int x, int p, int n) {
  // TODO
  return 2;
}

Burrows-Wheeler Transform Discussion and Implementation

$
0
0

After playing with: Huffman coding, LZSSarithmetic coding, and run length encoding (RLE), you’d figure that I’d have enough. I thought so too. I briefly diverted my attention from compression with a venture into C++ implementations of my bit libraries, but compression curiosities came back to haunt me. I had long known about bzip2 and its better compression ratios than gzip. I even knew that the “b” is for “block”, but I never really understood how it worked. Where do blocks come into play and how does that let me improve on my compression ratios?

It turns out that the blocks are constructs of the Burrows-Wheeler block-sorting transform (BWT). This page discusses the Burrows-Wheeler transform and the related Move-To-Front coding (MTF). I have also provided links to my implementation of BWT and MTF.

As with my compression implementations, my intent is to publish an easy to follow ANSI C implementation of the Burrows-Wheeler transform. Anyone familiar with ANSI C and BWT should be able to follow and learn from my implementation. There’s a lot of room for improvement of speed, memory usage, and block size optimizations, but this project is about learning and sharing, not perfection.

If you just want my source code, click here for information on downloading it.

The rest of this page discusses BWT, Move-To-Front coding and the results of my efforts so far.


Algorithm Overview

The Burrows-Wheeler transform (BWT) is not actually a compression algorithm. In fact BWT requires that a small amount of additional information be stored with the transformed data so that the transformation may be reversed. This makes the transformed data larger than its original form.

BWT is useful because it converts the data into a format that is generally more compressible by run length encoders and statistical encoders with order greater than 0. By additionally applying move-to-front coding, the data will be in a format which is generally more compressible by even zero order statistical encoders such as traditional implementations of Huffman coding or arithmetic coding.

Transform

The Burrows-Wheeler transform is applied on blocks of input data (symbols). It is usually the case that larger blocks result in greater compressibility of the transformed data at the expense of time and system resources.

One of the effects of BWT is to produce blocks of data with more and longer runs (strings of identical symbols) than those found in the original data. The increasing the number of runs and their lengths tends to improve a the compressibility of data.

The first step of BWT is to read in a block of N symbols C0 … CN-1.

Example:
Read in the following block: this is a test.

N = 15
C0 = ‘t’
C1 = ‘h’

C13 = ‘t’
C14 = ‘.’

The next step is to think of the block as a cyclic buffer. N strings (rotations) S0 … SN-1 may be constructed such that:
S0 = C0, …, CN-1
S1 = C1, …, CN-1, C0
S2 = C2, …, CN-1, C0, C1

SN-1 = CN-1, C0, …, CN-2

Example:
“this is a test.” yields the following rotations:

S0  = "this is a test."
S1  = "his is a test.t"
S2  = "is is a test.th"
S3  = "s is a test.thi"
S4  = " is a test.this"
S5  = "is a test.this "
S6  = "s a test.this i"
S7  = " a test.this is"
S8  = "a test.this is "
S9  = " test.this is a"
S10 = "test.this is a "
S11 = "est.this is a t"
S12 = "st.this is a te"
S13 = "t.this is a tes"
S14 = ".this is a test"

The third step of BWT is to lexicographically sort S0 … SN-1.

Example:
“this is a test.” yields the following sorted rotations:

S7  = " a test.this is"
S4  = " is a test.this"
S9  = " test.this is a"
S14 = ".this is a test"
S8  = "a test.this is "
S11 = "est.this is a t"
S1  = "his is a test.t"
S5  = "is a test.this "
S2  = "is is a test.th"
S6  = "s a test.this i"
S3  = "s is a test.thi"
S12 = "st.this is a te"
S13 = "t.this is a tes"
S10 = "test.this is a "
S0  = "this is a test."

The final step in the transform is to output a string, L, consisting of the last character in each of the rotations in their sorted order along with I, the sorted row containing S0.

Example:
“this is a test.” yields the following output:

L = "ssat tt hiies .", I = 14

The input went from a block of 0 runs to a block of 3 runs of length 2 (not bad for 15 symbols). This transformation works on data blocks where there are symbols that are frequently preceded by the same symbol. In my example ‘ ‘ is twice preceded by ‘s’.

Believe it or not the string of last characters (L) along with the row S0 appears in after sorting (I) is enough information to reconstruct the original block (S0).

Reverse Transform

Reversing BWT is a little more complicated than the initial transform. The reversal process starts with a string L composed of last characters of sorted rotations (S0 … SN-1) and I, the position of the contribution S0 made to L. The reversal process must yield S0, the original block.

The approach to reversing the transform wasn’t the least bit obvious to me. If it’s obvious to you, feel free to skip this section.

It turns out there are a few ways to reverse the transform. The method discussed here is the one that I ended up implementing.

If L is composed of the symbols V0 … VN-1, the transformed string may be parsed to determine the following pieces of additional information:

  1. The number of symbols in the substring V0 … Vi-1 that are identical to Vi.
  2. For each unique symbol, Vi, in L, the number of symbols that are lexicographically less than that symbol.

Example:
L = "ssat tt hiies ." produces the following:

TABLE 1. Number of Preceding Symbols Matching Symbol in Current Position.
Position Symbol Number
Matching
Position Symbol Number
Matching
0 ‘s’ 0 8 ‘h’ 0
1 ‘s’ 1 9 ‘i’ 0
2 ‘a’ 0 10 ‘i’ 1
3 ‘t’ 0 11 ‘e’ 0
4 ‘ ‘ 0 12 ‘s’ 2
5 ‘t’ 1 13 ‘ ‘ 2
6 ‘t’ 2 14 ‘.’ 0
7 ‘ ‘ 1

TABLE 2. Number of Symbols Lexicographically Less Than Current Symbol
Symbol Number Less Than
‘ ‘ 0
‘.’ 3
‘a’ 4
‘e’ 5
‘h’ 6
‘i’ 7
‘s’ 9
‘t’ 12

Now we have:

  1. L, the string of last characters of rotations.
  2. I, the position of the contribution that S0 made to L.
  3. The number of times the symbol Vi appears in the substring V0 … Vi-1.
  4. The number of times a symbol lexicographically less than a unique symbol appears in L.

Amazingly this is all we need to reconstruct S0.

Remember our string S0 = C0 … CN-1. So CN-1 is the contribution from S0, and it’s in position I. (From #2)

Now that we’ve found the last character in S0, CN-1, we’ll try to reconstruct the rest of S0 backwards. (Trust me, there’s a technique that will let us do that.)

That means we need to find the symbol CN-2. CN-2 is the contribution from SN-1. so where is contribution from SN-1 in L?

It just so happens that SN-1 is the string that starts with CN-1 and we just found CN-1. So we know how SN-1 starts, which can help us find out where it is in the sort order.

The contributions from strings starting with symbols less than CN-1 will occur earlier in L than the contribution from SN-1L may also contain contributions from strings starting with symbols equal to CN-1. Some of these strings occur before SN-1 and others after.

From #3, we know the number of symbols identical to CN-1 that occur in L before CN-1. So we also know the number of strings starting with identical symbols that made contributions before SN-1.

From #4, we know how many symbols there are that are less than CN-1. So we also know the number of strings starting with lesser symbols that made contributions before SN-1.

No other strings may contribute to L before SN-1, therefore the contribution from SN-1 occurs in the position obtained by summing the values from #3 and #4. As stated earlier the contribution from SN-1 is CN-2.

Use the same technique to find CN-3, CN-4, …, C0.

Example:
Using tables 1 and 2 reverse BWT where L = "ssat tt hiies ." and I = 14.

We start with:
S0 = ???????????????

We’re given that C14 is V14 = ‘.’.
S0 = ??????????????.

Table 1 tells us that there are 0 other ‘.’ before V14 and Table 2 tells us that there are 3 characters < ‘.’, so C14 must be V0 + 3 = V3 = ‘t’.
S0 = ?????????????t.

Table 1 tells us that there are 0 other ‘t’ before V3 and Table 2 tells us that there are 12 characters < ‘t’, so C13 must be V0 + 12 = V12 = ‘s’.
S0 = ????????????st.

Table 1 tells us that there are 2 other ‘s’ before V12 and Table 2 tells us that there are 9 characters < ‘s’, so C12 must be V9 + 2 = V11 = ‘e’.
S0 = ???????????est.

Table 1 tells us that there are 0 other ‘e’ before V11 and Table 2 tells us that there are 5 characters < ‘e’, so C11 must be V0 + 5 = V5 = ‘t’.
S0 = ??????????test.

Table 1 tells us that there is 1 other ‘t’ before V5 and Table 2 tells us that there are 12 characters < ‘t’, so C10 must be V1 + 12 = V13 = ‘ ‘.
S0 = ????????? test.

Table 1 tells us that there is 2 other ‘ ‘ before V13 and Table 2 tells us that there are 0 characters < ‘ ‘, so C9 must be V2 + 0 = V2 = ‘a’.
S0 = ????????a test.

The rest is left as an exercise to the student. (I always loved that statement)

So What Do I Do with BWT?

Now that you understand BWT, you can publish web pages about it. Okay, that’s not what you’re looking for.

As I stated earlier BWT tends to transform blocks of symbols into blocks with more runs. This makes BWT useful for improving compression of run length encoders. The method for compression would be:

  1. Apply Burrows-Wheeler Transform on data to be encoded.
  2. Apply run length encoding on data to be encoded.

The method for decompression would be:

  1. Remove run length encoding on from the encoded data.
  2. Apply the reverse Burrows-Wheeler Transform on the encoded data.

Typically compression performed by run length encoders are far from optimal. Even after BWT, run length encoders don’t perform as well as statistical encoders. BWT doesn’t do anything to change the frequency distribution of symbols, so BWT alone won’t do anything to make data more compressible by order zero statistical algorithms. That’s where Move-To-Front Coding comes into play.

Move-To-Front Coding

Move-To-Front (MTF) coding is a technique that encodes streams of symbols based on an adapting code. Imagine that symbols are encoded by their position in a list of every symbol in the alphabet. Initially the list is in a lexicographical (or some predetermined) order. Once a symbol in a stream is encoded, that symbol is moved from it’s current position to the front of the list and its former predecessors are moved one position back.

Example:
Given an alphabet of ‘ ‘,’.',’a',’e',’h',’i',’s',’t’ encode “ssat tt hiies .”:

Renaming Symbols Symbol List Encoded Symbols
ssat tt hiies . ‘ ‘,’.',’a',’e',’h',’i',’s',’t’
sat tt hiies . ‘s’,’ ‘,’.',’a',’e',’h',’i',’t’ 6
at tt hiies . ‘s’,’ ‘,’.',’a',’e',’h',’i',’t’ 6,0
t tt hiies . ‘a’,'s’,’ ‘,’.',’e',’h',’i',’t’ 6,0,3
 tt hiies . ‘t’,'a’,'s’,’ ‘,’.',’e',’h',’i’ 6,0,3,7
tt hiies . ‘ ‘,’t',’a',’s',’.',’e',’h',’i’ 6,0,3,7,3
t hiies . ‘t’,’ ‘,’a',’s',’.',’e',’h',’i’ 6,0,3,7,3,1
hiies . ‘t’,’ ‘,’a',’s',’.',’e',’h',’i’ 6,0,3,7,3,1,0
hiies . ‘ ‘,’t',’a',’s',’.',’e',’h',’i’ 6,0,3,7,3,1,0,1
iies . ‘h’,’ ‘,’t',’a',’s',’.',’e',’i’ 6,0,3,7,3,1,0,1,6
ies . ‘i’,'h’,’ ‘,’t',’a',’s',’.',’e’ 6,0,3,7,3,1,0,1,6,7
es . ‘i’,'h’,’ ‘,’t',’a',’s',’.',’e’ 6,0,3,7,3,1,0,1,6,7,0
s . ‘e’,'i’,'h’,’ ‘,’t',’a',’s',’.’ 6,0,3,7,3,1,0,1,6,7,0,7
 . ‘s’,'e’,'i’,'h’,’ ‘,’t',’a',’.’ 6,0,3,7,3,1,0,1,6,7,0,7,6
. ‘ ‘,’s',’e',’i',’h',’t',’a',’.’ 6,0,3,7,3,1,0,1,6,7,0,7,6,4
‘.’,’ ‘,’s',’e',’i',’h',’t',’a’ 6,0,3,7,3,1,0,1,6,7,0,7,6,4,7

Notice that with MTF coding, the second and successive characters in any run are converted to 0 (“ss” became 6,0, “tt” became 1,0, and “ii” became 7,0). This works well with BWT, since it produces blocks with a lot of runs. You should also notice that there is nothing about MTF coding that requires prior use of BWT.

Move-To-Front Decoding

Unlike the reverse BWT, Move-To-Front (MTF) decoding was fairly obvious to me. It’s very much like the encoding process, but a little less time intensive. This time the position of a symbol in the list of every symbol in the alphabet is used to decode a symbol. Like the encode process, the list starts out in a lexicographical (or some predetermined) order. The encoded data indicates the position of the decoded symbol. After decoding the symbol, move it to the front of the list.

Example:
Given an alphabet of ‘ ‘,’.',’a',’e',’h',’i',’s',’t’ decode decode 6,0,3,7,3,1,0,1,6,7,0,7,6,4,7:

Renaming Symbols Symbol List Decoded Symbols
6,0,3,7,3,1,0,1,6,7,0,7,6,4,7 ‘ ‘,’.',’a',’e',’h',’i',’s',’t’
0,3,7,3,1,0,1,6,7,0,7,6,4,7 ‘s’,’ ‘,’.',’a',’e',’h',’i',’t’ s
3,7,3,1,0,1,6,7,0,7,6,4,7 ‘s’,’ ‘,’.',’a',’e',’h',’i',’t’ ss
7,3,1,0,1,6,7,0,7,6,4,7 ‘a’,'s’,’ ‘,’.',’e',’h',’i',’t’ ssa
3,1,0,1,6,7,0,7,6,4,7 ‘t’,'a’,'s’,’ ‘,’.',’e',’h',’i’ ssat
1,0,1,6,7,0,7,6,4,7 ‘ ‘,’t',’a',’s',’.',’e',’h',’i’ ssat_
0,1,6,7,0,7,6,4,7 ‘t’,’ ‘,’a',’s',’.',’e',’h',’i’ ssat t
1,6,7,0,7,6,4,7 ‘t’,’ ‘,’a',’s',’.',’e',’h',’i’ ssat tt
6,7,0,7,6,4,7 ‘ ‘,’t',’a',’s',’.',’e',’h',’i’ ssat tt_
7,0,7,6,4,7 ‘h’,’ ‘,’t',’a',’s',’.',’e',’i’ ssat tt h
7,0,7,6,4,7 ‘h’,’ ‘,’t',’a',’s',’.',’e',’i’ ssat tt h
0,7,6,4,7 ‘i’,'h’,’ ‘,’t',’a',’s',’.',’e’ ssat tt hi
7,6,4,7 ‘i’,'h’,’ ‘,’t',’a',’s',’.',’e’ ssat tt hii
6,4,7 ‘e’,'i’,'h’,’ ‘,’t',’a',’s',’.’ ssat tt hiie
4,7 ‘s’,'e’,'i’,'h’,’ ‘,’t',’a',’.’ ssat tt hiies
7 ‘ ‘,’s',’e',’i',’h',’t',’a',’.’ ssat tt hiies_
‘.’,’ ‘,’s',’e',’i',’h',’t',’a’ ssat tt hiies .

So What Do I Do with MTF?

Now that you understand MTF, you can publish web pages about it too. Okay, it was a bad joke the first time.

As I stated earlier MTF tends to increase the frequency of low value symbols within a block. This makes MTF useful for improving compression of statistical encoders such as Huffman coding orarithmetic coding.

The method for compression would be:

  1. Apply Burrows-Wheeler Transform on data to be encoded.
  2. Apply Move-To-Front encoding on data to be encoded.
  3. Apply statistical encoding on data to be encoded.

The method for decompression would be:

  1. Remove statistical from the encoded data.
  2. Remove Move-To-Front encoding from the encoded data.
  3. Apply the reverse Burrows-Wheeler Transform on the encoded data.

Implementation

I was extremely uncreative here. My implementation comes directly from “A Block-sorting Lossless Data Compression Algorithm” by Michael Burrows and David Wheeler. The source code includes comments which reference sections of their paper. My hope is that anybody reading their paper will be able to follow along with my source. This section addresses issues that were either discussed by Burrows and Wheeler or were required to implement their transform on real data.

Block Size

BWT is a block sorting algorithm, but the transform isn’t dependent upon the size of the block. BWT can be used on blocks of any size. When I was debugging my code I used 16 byte blocks, they are currently 4096 bytes. I chose 4096 bytes because it can be handled by most modern computers. The larger the block, the more opportunity you have for runs and repeated patterns. Burrows and Wheeler demonstrate improved compression ratios all the way to 103 megabyte blocks for one benchmark file.

The obvious downsides to large blocks are that blocks must be stored somewhere, so you need enough memory to hold the block and it’s rotations. An N byte block will have N rotations. The rotations are also sorted, and sorting is not a linear operation; larger blocks will also take more time.

End Of Block

In the ideal world any encoded data will be evenly divisible by whatever block size the transform happens to be using. Unfortunately, I don’t live in that world. More often than not, the last block is a partial block. There are a few ways to deal with this that I can think of:

  • Prefix the encoded data stream with a number of bytes encoded
  • Encode an End-of-Block symbol into each block
  • Prefix each block with a block size
  • Use EOF to indicate end of last block

When I started playing with BWT I thought that I might want to dynamically adjust the block size, so I prefixed each block with its size. It also allowed for some error checking. If the file ended before I read all the data in a block something bad happened. The dynamic block size adjustment never came into being, so the code I’m releasing actually takes the more compact approach of using the EOF as an indicator of a partial block.

In order to handle a partial block at the end of a file, I made one minor change to the BWT algorithm. Burrows and Wheeler output the last characters of the sorted rotations (L), followed by the index of the contribution of the unrotated block (I). If L is written before I, an attempt to read all the characters of a full size block will result in reading some or all of I before the EOF is reached. L can always be adjusted by removing the data that belongs to I, but there’s an easier approach. My implementation writes I then L. If we hit an EOF and L is a partial block we don’t need to do any magic to get I; we already have it.

Block Rotations

Burrows and Wheeler discuss a conceptual N × N matrix containing rotations of N long blocks, but they leave implementation of the concept to the implementer. I’m pretty sure they don’t expect anybody to use an actual N × N matrix.

Since rotations are just strings starting at index i in the block and wrapping around until, index (i – 1) mod N, I just refer to my rotations by their starting indices. My matrix of rotations is just an array of induces into the unrotated block.

Sorting of Rotations

In order to keep things simple, I use the qsort() function to sort rotations. The efficiency of qsort() really depends upon your compiler. You’d think it was just a text book quick sort, but it isn’t always. I think gcc uses a merge sort.

If you want to play with different sort functions, my sort library includes implementations of common sort algorithms which are plug-in replacements for qsort().

It turns out that the sorting of rotations is one of the most time consuming steps in the encode process. Optimizing the sorting process seems to be a pretty hot topic, with several published papers. Burrows and Wheeler suggest optimizing the process by using a radix sort to sort all rotations by their first two characters. Then using quick sort is use to sort within the groups of rotations that match at their first two characters. Versions 0.4 and later of my software introduce this optimization.

It should be pointed out that using a radix sort to sort rotations by their first two characters prior using quick sort isn’t always more optimal than using quicksort alone. Suppose an entire block is just one repeated character. All rotations in that block start with the same two characters, so a radix sort of such a block will not reduce the amount of comparisons performed by quick sort.

MTF Encode/Decode

My implementation of MTF encode/decode uses brute force. Apparently there are efficient implementations of MTF that are well known. Not by me, but I didn’t go looking for them either. One possible area to look for optimization is in the search for a symbol’s code during the encode process. I do a sequential search. It will find the code for a symbol in a run on the first try. The average search time for other symbols will be on the order of half the alphabet length. Other searches might have better average cases.

Another potential from optimization is the Move-To-Front operation itself. My code is stored in an array, and I move each character over one at a time. Linked lists will make the move faster, but then you can’t use the array index as the code.

Portability

All the source code that I have provided is written in strict ANSI C. I would expect it to build correctly on any machine with an ANSI C compiler. I have tested the code compiled with gcc on Linux andmingw on Windows 98/XP.

My implementation defines a value BLOCK_SIZE as 4096. This value may easily be changed. Increasing BLOCK_SIZE generally improves the compressibility of transformed data at the expense of memory and computation time. If BLOCK_SIZE is made larger than INT_MAX the preprocessor will issue and error which may be corrected by changing several ints to longs. If BLOCK_SIZE is made larger than the maximum size_t, I would expect calls to fread() and fwrite() to produce errors. Whether the errors are compile-time or run-time is probably dependent on the compiler.


Further Information

Michael Burrows and David Wheeler document their algorithm in “A Block-sorting Lossless Data Compression Algorithm”. I highly recommend that anybody interested in studying their algorithm make a point of reading this document.

Further information about BWT and other block-sorting algorithms may be found at http://www.datacompression.info/BWT.shtml. The site includes links to discussions of the algorithm, studies, libraries, and tools using BWT.

 

http://michael.dipperstein.com/bwt/

 


Algorithms, Part II Assignment 4

$
0
0

COS 226 Programming Assignment

Burrows-Wheeler Data Compression Algorithm

Implement the Burrows-Wheeler data compression algorithm. This revolutionary algorithm outcompresses gzip and PKZIP, is relatively easy to implement, and is not protected by any patents. It forms the basis of the Unix compression utililty bzip2.

The Burrows-Wheeler compression algorithm consists of three algorithmic components, which are applied in succession:

 

  1. Burrows-Wheeler transform. Given a typical English text file, transform it into a text file in which sequences of the same character occur near each other many times. 
  2. Move-to-front encoding. Given a text file in which sequences of the same character occur near each other many times, convert it into a text file in which certain characters appear more frequently than others. 
  3. Huffman compression. Given a text file in which certain characters appear more frequently than others, compress it by encoding freqently occuring characters with short codewords and rare ones with long codewords.

The final step is the one that compresses the message: it is particularly effective because the first two steps result in a text file in which certain characters appear much more frequently than others. To expand a message, apply the inverse operations in reverse order: first apply the Huffman expansion, then the move-to-front decoding, and finally the inverse Burrows-Wheeler transform. Your task is to implement Burrows-Wheeler and move-to-front components efficiently.

Binary input and binary output. To enable that your programs work with binary data, you will use the libraries BinaryStdIn.java and BinaryStdOut.java described in Algorithms, 4th edition. To display the binary output when debugging, you can useHexDump.java, which takes a command-line argument N, reads bytes from standard input and writes them to standard output in hexadecimal, N per line.

% more abra.txt
ABRACADABRA!

% java HexDump 16 < abra.txt
41 42 52 41 43 41 44 41 42 52 41 21
96 bits

Note that 'A' is 41 (hex) in ASCII.

Huffman encoding and decoding. Huffman.java (Program 5.10 in Algorithms, 4th edition) implements the classic Huffman compression and expansion algorithms.

% java Huffman - < abra.txt | java HexDump 16
50 4a 22 43 43 54 a8 40 00 00 01 8f 96 8f 94
120 bits
% java Huffman - < abra.txt | java Huffman +
ABRACADABRA!

You will not write any code for this step.

Move-to-front encoding and decoding. The main idea of move-to-front encoding is to maintain an ordered sequence of all of the characters in the alphabet, and repeatedly read in a character from the input message, print out the position in which that character appears, and move that character to the front of the sequence. As a simple example, if the initial ordering over a 6-character alphabet is A B C D E F, and we want to encode the input CAAABCCCACCF, then we would update the move-to-front sequences as follows:

move-to-front    in   out
-------------    ---  ---
 A B C D E F      C    2 
 C A B D E F      A    1
 A C B D E F      A    0
 A C B D E F      A    0
 A C B D E F      B    2
 B A C D E F      C    2
 C B A D E F      C    0
 C B A D E F      C    0
 C B A D E F      A    2
 A C B D E F      C    1
 C A B D E F      C    0
 C A B D E F      F    5
 F C A B D E

If the same character occurs next to each other many times in the input, then many of the output values will be small integers, such as 0, 1, and 2. The extremely high frequency of certain characters makes an ideal scenario for Huffman coding.

 

  • Move-to-front encoding. Your task is to maintain an ordered sequence of the 256 extended ASCII characters. Initialize the sequence by making the ith character in the sequence equal to the ith extended ASCII character. Now, read in each 8-bit character c from standard input one at a time, output the 8-bit index in the sequence where c appears, and move c to the front.
    % java MoveToFront - < abra.txt | java HexDump 16
    41 42 52 02 44 01 45 01 04 04 02 26
    96 bits

     

  • Move-to-front decoding. Initialize an ordered sequence of 256 characters, where extended ASCII character i appears ith in the sequence. Now, read in each 8-bit character i (but treat it as an integer between 0 and 255) from standard input one at a time, write the ith character in the sequence, and move that character to the front. Check that the decoder recovers any encoded message.
    % java MoveToFront - < abra.txt | java MoveToFront +
    ABRACADABRA!

Name your program MoveToFront.java and organize it using the following API:

public class MoveToFront {
    // apply move-to-front encoding, reading from standard input and writing to standard output
    public static void encode()

    // apply move-to-front decoding, reading from standard input and writing to standard output
    public static void decode()

    // if args[0] is '-', apply move-to-front encoding
    // if args[0] is '+', apply move-to-front decoding
    public static void main(String[] args)
}

The running time of move-to-front encoding and decoding should be proportional to R N in the worst case and proportional to N in practice on inputs that arise when compressing typical English text, where N is the number of characters in the input and R is the alphabet size.

Circular suffix array. To efficiently implement the key component in the Burrows-Wheeler transform, you will use a fundamental data structure known as the circular suffix array, which describes the abstraction of a sorted array of the N circular suffixes of a string of length N. As an example, consider the string “ABRACADABRA!” of length 12. The table below shows its 12 circular suffixes and the result of sorting them.

 i       Original Suffixes           Sorted Suffixes         index[i]
--    -----------------------     -----------------------    --------
 0    A B R A C A D A B R A !     ! A B R A C A D A B R A    11
 1    B R A C A D A B R A ! A     A ! A B R A C A D A B R    10
 2    R A C A D A B R A ! A B     A B R A ! A B R A C A D    7
 3    A C A D A B R A ! A B R     A B R A C A D A B R A !    0
 4    C A D A B R A ! A B R A     A C A D A B R A ! A B R    3
 5    A D A B R A ! A B R A C     A D A B R A ! A B R A C    5
 6    D A B R A ! A B R A C A     B R A ! A B R A C A D A    8
 7    A B R A ! A B R A C A D     B R A C A D A B R A ! A    1
 8    B R A ! A B R A C A D A     C A D A B R A ! A B R A    4
 9    R A ! A B R A C A D A B     D A B R A ! A B R A C A    6
10    A ! A B R A C A D A B R     R A ! A B R A C A D A B    9
11    ! A B R A C A D A B R A     R A C A D A B R A ! A B    2

We define index[i] to be the index of the original suffix that appears ith in the sorted array. For example, index[11] = 2 means that the 2nd original suffix appears 11th in the sorted order (i.e., last alphabetically).

Your job is to implement the following circular suffix array API, which provides the client access to the index[] values:

public class CircularSuffixArray {
    public CircularSuffixArray(String s)  // circular suffix array of s
    public int length()                   // length of s
    public int index(int i)               // returns index of ith sorted suffix
}

Your data type must use linear space; the methods length() and index() must take constant time. Prior to Java 7, Update 6, the array of circular suffixes could be constructed in linear space using the substring() method. It now takes quadratic space—do not explicitly generate the N suffixes. Instead, precompute and store the index[] array, which requires only linear space.

Burrows-Wheeler transform. The goal of the Burrows-Wheeler transform is not to compress a message, but rather to transform it into a form that is more amenable to compression. The transform rearranges the characters in the input so that there are lots of clusters with repeated characters, but in such a way that it is still possible to recover the original input. It relies on the following intuition: if you see the letters hen in English text, then most of the time the letter preceding it is t or w. If you could somehow group all such preceding letters together (mostly t‘s and some w‘s), then you would have an easy opportunity for data compression.

 

  • Burrows-Wheeler encoding. The Burrows-Wheeler transform of a string s of length N is defined as follows: Consider the result of sorting the N circular suffixes of s. The Burrows-Wheeler transform is the last column in the sorted suffixes array t[], preceded by the row number first in which the original string ends up. Continuing with the “ABRACADABRA!” example above, we highlight the two components of the Burrows-Wheeler transform in the table below.
     i     Original Suffixes          Sorted Suffixes       t    index[i]
    --    -----------------------     -----------------------    --------
     0    A B R A C A D A B R A !     ! A B R A C A D A B R A    11
     1    B R A C A D A B R A ! A     A ! A B R A C A D A B R    10
     2    R A C A D A B R A ! A B     A B R A ! A B R A C A D    7
    *3    A C A D A B R A ! A B R     A B R A C A D A B R A !   *0
     4    C A D A B R A ! A B R A     A C A D A B R A ! A B R    3
     5    A D A B R A ! A B R A C     A D A B R A ! A B R A C    5
     6    D A B R A ! A B R A C A     B R A ! A B R A C A D A    8
     7    A B R A ! A B R A C A D     B R A C A D A B R A ! A    1
     8    B R A ! A B R A C A D A     C A D A B R A ! A B R A    4
     9    R A ! A B R A C A D A B     D A B R A ! A B R A C A    6
    10    A ! A B R A C A D A B R     R A ! A B R A C A D A B    9
    11    ! A B R A C A D A B R A     R A C A D A B R A ! A B    2

    Since the original string ABRACADABRA! ends up in row 3, we have first = 3. Thus, the Burrows-Wheeler transform is

    3
    ARD!RCAAAABB

    Notice how there are 4 consecutive As and 2 consecutive Bs—these clusters make the message easier to compress.

    % java BurrowsWheeler - < abra.txt | java HexDump 16
    00 00 00 03 41 52 44 21 52 43 41 41 41 41 42 42
    128 bits

    Also, note that the integer 3 is represented using 4 bytes (00 00 00 03). The character 'A' is represented by hex 41, the character 'R' by 52, and so forth. 

  • Burrows-Wheeler decoder. Now, we describe how to invert the Burrows-Wheeler transform and recover the original input string. If the jth original suffix (original string, shifted j characters to the left) is the ith row in the sorted order, we define next[i]to be the row in the sorted order where the (j + 1)st original suffix appears. For example, if first is the row in which the original input string appears, then next[first] is the row in the sorted order where the 1st original suffix (the original string left-shifted by 1) appears; next[next[first]] is the row in the sorted order where the 2nd original suffix appears; next[next[next[first]]] is the row where the 3rd original suffix appears; and so forth. 
    • Decoding the message given t[], first, and the next[] array. The input to the Burrows-Wheeler decoder is the last column t[] of the sorted suffixes along with first. From t[], we can deduce the first column of the sorted suffixes because it consists of precisely the same characters, but in sorted order.
       i      Sorted Suffixes     t      next
      --    -----------------------      ----
       0    ! ? ? ? ? ? ? ? ? ? ? A        3
       1    A ? ? ? ? ? ? ? ? ? ? R        0
       2    A ? ? ? ? ? ? ? ? ? ? D        6
      *3    A ? ? ? ? ? ? ? ? ? ? !        7
       4    A ? ? ? ? ? ? ? ? ? ? R        8
       5    A ? ? ? ? ? ? ? ? ? ? C        9
       6    B ? ? ? ? ? ? ? ? ? ? A       10
       7    B ? ? ? ? ? ? ? ? ? ? A       11
       8    C ? ? ? ? ? ? ? ? ? ? A        5
       9    D ? ? ? ? ? ? ? ? ? ? A        2
      10    R ? ? ? ? ? ? ? ? ? ? B        1
      11    R ? ? ? ? ? ? ? ? ? ? B        4

      Now, given the next[] array and first, we can reconstruct the original input string because the first character of the ith original suffix is the ith character in the input string. In the example above, since first = 3, we know that the original input string appears in row 3; thus, the original input string starts with 'A' (and ends with '!'). Since next[first] = 7, the next original suffix appears in row 7; thus, the next character in the original input string is 'B'. Since next[next[first]] =11, the next original suffix appears in row 11; thus, the next character in the original input string is 'R'

    • Construction the next[] array from t[] and first. Amazingly, the information contained in the Burrows-Wheeler transform suffices to reconstruct the next[] array, and, hence, the original message! Here’s how. It is easy to deduce a next[]value for a character that appears exactly once in the input string. For example, consider the suffix that starts with 'C'. By inspecting the first column, it appears 8th in the sorted order. The next original suffix after this one will have the character 'C'as its last character. By inspecting the last column, the next original appears 5th in the sorted order. Thus, next[8] = 5. Similarly, 'D' and '!' each occur only once, so we can deduce that next[9] = 2 and next[0] = 3.
       i      Sorted Suffixes     t      next
      --    -----------------------      ----
       0    ! ? ? ? ? ? ? ? ? ? ? A        3
       1    A ? ? ? ? ? ? ? ? ? ? R
       2    A ? ? ? ? ? ? ? ? ? ? D
      *3    A ? ? ? ? ? ? ? ? ? ? !
       4    A ? ? ? ? ? ? ? ? ? ? R 
       5    A ? ? ? ? ? ? ? ? ? ? C
       6    B ? ? ? ? ? ? ? ? ? ? A
       7    B ? ? ? ? ? ? ? ? ? ? A
       8    C ? ? ? ? ? ? ? ? ? ? A        5
       9    D ? ? ? ? ? ? ? ? ? ? A        2
      10    R ? ? ? ? ? ? ? ? ? ? B
      11    R ? ? ? ? ? ? ? ? ? ? B

      However, since 'R' appears twice, it may seem ambiguous whether next[10] = 1 and next[11] = 4, or whether next[10] = 4 and next[11] = 1. Here’s the key rule that resolves the apparent ambiguity:

      If sorted row i and j both start with the same character and i < j, then next[i] < next[j].

      This rule implies next[10] = 1 and next[11] = 4. Why is this rule valid? The rows are sorted so row 10 is lexicographically less than row 11. Thus the ten unknown characters in row 10 must be less than the ten unknown characters in row 11 (since both start with 'R'). We also know that between the two rows that end with 'R', row 1 is less than row 4. But, the ten unknown characters in row 10 and 11 are precisely the first ten characters in rows 1 and 4. Thus, next[10] = 1 andnext[11] = 4 or this would contradict the fact that the suffixes are sorted.

    Check that the decoder recovers any encoded message.

    % java BurrowsWheeler - < abra.txt | java BurrowsWheeler +
    ABRACADABRA!

Name your program BurrowsWheeler.java and organize it using the following API:

public class BurrowsWheeler {
    // apply Burrows-Wheeler encoding, reading from standard input and writing to standard output
    public static void encode()

    // apply Burrows-Wheeler decoding, reading from standard input and writing to standard output
    public static void decode()

    // if args[0] is '-', apply Burrows-Wheeler encoding
    // if args[0] is '+', apply Burrows-Wheeler decoding
    public static void main(String[] args)
}

The running time of your Burrows-Wheeler encoder should be proportional to N + R in the worst case, excluding the time to construct the circular suffix array. The running time of your Burrows-Wheeler decoder should be proportional to N + R in the worst case.

Analysis (optional). Once you have MoveToFront.java and BurrowsWheeler.java working, compress some of these text files; then, test it on some binary files. Calculate the compression ratio achieved for each file and report the time to compress and expand each file. (Here, compression and expansion consists of applying BurrowsWheelerMoveToFront, and Huffman in succession.) Finally, determine the order of growth of the running time of each of your encoders and decoders, both in the worst case and on typical Englist text inputs.

Deliverables. Submit MoveToFront.javaBurrowsWheeler.java, and CircularSuffixArray.java along with any other helper files needed to run your program (excluding those in stdlib.jar and algs4.jar).

This assignment was developed by Kevin Wayne.
Copyright © 2004.
 
 

public class MoveToFront {    
    public static void encode() {
        byte[] mtf = new byte[256];
        for (int i = 0; i < mtf.length; i++) {
            mtf[i] = (byte) i;
        }        
        while (!BinaryStdIn.isEmpty()) {
            byte value = BinaryStdIn.readByte();
            int index = 0;
            byte temp = mtf[0];
            if (value != temp) {
                mtf[0] = value;
                while (value != temp) {
                    index++;
                    index = index % 256;
                    final byte temp2 = temp;
                    temp = mtf[index];
                    mtf[index] = temp2;
                }
            }
            BinaryStdOut.write((byte) index);
        }
        BinaryStdIn.close();
        BinaryStdOut.close();
    }
    
    public static void decode() {
        byte[] mtf = new byte[256];
        for (int i = 0; i < mtf.length; i++) {
            mtf[i] = (byte) i;
        }
        while (!BinaryStdIn.isEmpty()) {
            int index = BinaryStdIn.readByte();
            if (index < 0) {
                index = index + 256;
            }
            byte value = mtf[index];
            System.arraycopy(mtf, 0, mtf, 1, index);
            mtf[0] = value;
            BinaryStdOut.write(value);
        }
        BinaryStdOut.close();
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        if      (args[0].equals("-")) encode();
        else if (args[0].equals("+")) decode();
        else throw new IllegalArgumentException("Illegal command line argument");        
    }
}

public class CircularSuffixArray {
    private int [] index;
    
    public CircularSuffixArray(String s) {
        char[] input = s.toCharArray();
        int size = input.length;
        index = new int[size];
        for (int i = 0; i < size; i++) {
            index[i] = i;
        }
        sort(0, size, input, 0);
    }
    
    private void sort(int lo, int hi, char [] input, int shift) {
        int size = input.length;
        if (hi == lo + 1) return;
        if (hi == lo + 2) {
            int start1 = (index[lo] + shift) % size;
            int start2 = (index[lo + 1] + shift) % size;
            while (input[start1] == input[start2]) {
                start1 = (start1 + 1) % size;
                start2 = (start2 + 1) % size;
            }
            if (input[start1] > input[start2]) {
                int temp = index[lo];
                index[lo] = index[lo + 1];
                index[lo + 1] = temp;                
            }
            return;
        }
        int [] counter = new int[256];

        for (int i = lo; i < hi; i++) {
            counter[input[(index[i] + shift) % size]]++;
        }
        int [] offsetTable = new int[256];
        offsetTable[0] = 0;
        for (int i = 1; i < 256; i++) {
            offsetTable[i] = offsetTable[i - 1] + counter[i - 1];
        }
        
        int [] index1 = new int[hi - lo];
        for (int i = lo; i < hi; i++) {
            char c = input[(index[i] + shift) % size];
            index1[offsetTable[c]] = index[i]; 
            offsetTable[c]++;
        }
        for (int i = lo; i < hi; i++) {
            index[i] = index1[i - lo];
        }
        for (char r = 0; r < 255; r++) {
            if (counter[r] > 1) {
                sort(offsetTable[r] - counter[r] + lo, offsetTable[r + 1] - counter[r + 1] + lo, input, shift + 1);
            }
        }
    }
        
    public int length() {
        return index.length;
    }
    
    public int index(int i) {
        if (i >= index.length) {
            throw new IllegalArgumentException("Illegal command line argument");
        }
        return index[i];
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        String s = BinaryStdIn.readString();
        CircularSuffixArray c = new CircularSuffixArray(s);
        for (int i = 0; i < c.length(); i++) {
            System.out.println(c.index(i));
        }
    }

}

import java.util.Arrays;

public class BurrowsWheeler {
    public static void encode() {
        String s = BinaryStdIn.readString();
        CircularSuffixArray c = new CircularSuffixArray(s);
        int size = c.length();
        int first = -1;
        char[] lastCol = new char[size];        
        for (int i = 0; i < size; i++) {
            if (c.index(i) == 0) {
                first = i;
                lastCol[i] = s.charAt(size - 1);
            } else {            
                lastCol[i] = s.charAt(c.index(i) - 1);
            }
        }
        BinaryStdOut.write(first);        
        for (int i = 0; i < size; i++) {
            BinaryStdOut.write(lastCol[i]); 
        }                
        BinaryStdOut.close();
    }
    
    public static void decode() {
        int first = BinaryStdIn.readInt();
        String s = BinaryStdIn.readString();
        char[] lastColumn = s.toCharArray();
        int size = lastColumn.length;
        int[] next = new int[size];
        char [] firstColumn = new char[size];        
        for (int i = 0; i < size; i++) {
            firstColumn[i] = lastColumn[i];
        }        
        Arrays.sort(firstColumn);
        int index = 0;
        for (int i = 0; i < size; i++) {
            char c = firstColumn[i];
            while (lastColumn[index] != c) {
                index = (index + 1) % size;                
            }
            next[i] = index;
            if (i == size - 1) 
                break;
            if (firstColumn[i + 1] == c) {
                index = (index + 1) % size;
            } else {
                index = 0;
            }
        }
        for (int i = 0; i < size; i++) {
            BinaryStdOut.write(firstColumn[first]);
            first = next[first];
        }
        BinaryStdOut.close();
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        if      (args[0].equals("-")) encode();
        else if (args[0].equals("+")) decode();
        else throw new IllegalArgumentException("Illegal command line argument");        
    }
}


Computational Photography Programming Assignment 4 – Video Textures

$
0
0

part0

import numpy as np
import cv2

def video_volume(image_list):
  '''Create a video volume from the image list.

  Input:
    image_list - a list of frames. Each element of the list contains a numpy
    array of a colored image. You may assume that each frame has the same shape,
    (rows, cols, 3).

  Output:
    output - a single 4d numpy array. This array should have dimensions
    (time, rows, cols, 3) and dtype np.uint8.
  '''
  output = None
  # Insert your code here ------------------------------------------------------
  (rows, cols, color) = image_list[0].shape
  output = np.zeros((len(image_list), rows, cols, color), dtype = np.uint8)
  for i in range(len(image_list)):
    output[i,:,:,:] = image_list[i]
  # ----------------------------------------------------------------------------
  return output

def ssd(video_volume):
  '''Compute the sum of squared distances for each pair of frames in video volume.
  Input:
    video_volume - as returned by your video_volume function.

  Output:
    output - a square 2d numpy array of dtype float. output[i,j] should contain 
    the dsum of square differences between frames i and j.
  '''
  output = None
  # Insert your code here ------------------------------------------------------
  (frames, rows, cols, color) = video_volume.shape
  output = np.zeros((frames, frames), dtype = np.float)
  for i in range(frames):
    image_i = video_volume[i,:,:,:]
    for j in range(frames):
      image_j = video_volume[j,:,:,:]
      total = 0.0
      diff_image = image_i - image_j
      for k1 in range(rows):
        for k2 in range(cols):
          for k3 in range(3):
            total = total + diff_image[k1,k2,k3] * diff_image[k1,k2,k3]
      output[i, j] = total
  # ----------------------------------------------------------------------------
  return output

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''
  image_list1 = [np.array([[[ 0,  0,  0],
                            [ 0,  0,  0]]], dtype = np.uint8),
                 np.array([[[ 1,  1,  1],
                            [ 1,  1,  1]]], dtype = np.uint8),
                 np.array([[[ 2,  2,  2],
                            [ 2,  2,  2]]], dtype = np.uint8),
                 np.array([[[ 3,  3,  3],
                            [ 3,  3,  3]]], dtype = np.uint8)] 

  video_volume1 = np.array([[[[ 0,  0,  0],
                              [ 0,  0,  0]]],
                            [[[ 1,  1,  1],
                              [ 1,  1,  1]]],
                            [[[ 2,  2,  2],
                              [ 2,  2,  2]]],
                            [[[ 3,  3,  3],
                              [ 3,  3,  3]]]], dtype = np.uint8) 

  image_list2 =[np.array([[[2, 2, 2],
                           [2, 2, 2],
                           [2, 2, 2],
                           [2, 2, 2]],
                          [[2, 2, 2],
                           [2, 2, 2],
                           [2, 2, 2],
                           [2, 2, 2]]], dtype = np.uint8),
                np.array([[[1, 1, 1],
                           [1, 1, 1],
                           [1, 1, 1],
                           [1, 1, 1]],
                          [[1, 1, 1],
                           [1, 1, 1],
                           [1, 1, 1],
                           [1, 1, 1]]], dtype = np.uint8),
                np.array([[[0, 0, 0],
                           [0, 0, 0],
                           [0, 0, 0],
                           [0, 0, 0]],
                          [[0, 0, 0],
                           [0, 0, 0],
                           [0, 0, 0],
                           [0, 0, 0]]], dtype = np.uint8)] 

  video_volume2 = np.array([[[[2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2]],
                             [[2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2]]],
                            [[[1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1]],
                             [[1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1]]],
                            [[[0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0]],
                             [[0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0]]]], dtype = np.uint8)

  diff1 = np.array([[  0.,   6.,  24.,  54.],
                    [  6.,   0.,   6.,  24.],
                    [ 24.,   6.,   0.,   6.],
                    [ 54.,  24.,   6.,   0.]], dtype = np.float) 

  diff2 = np.array([[  0.,  24.,  96.],
                    [ 24.,   0.,  24.],
                    [ 96.,  24.,   0.]], dtype = np.float) 

  if __name__ == "__main__":
    print 'Evaluating video_volume.'
  for img_list, true_out in zip((image_list1, image_list2), (video_volume1, video_volume2)):
    if __name__ == "__main__":
      print "input:\n{}\n".format(img_list)

    usr_out = video_volume(img_list)

    if not type(usr_out) == type(true_out):
      if __name__ == "__main__":
        print "Error- video_volume has type {}. Expected type is {}.".format(
            type(usr_out), type(true_out))
      return False

    if not usr_out.shape == true_out.shape:
      if __name__ == "__main__":
        print "Error- video_volume has shape {}. Expected shape is {}.".format(
            usr_out.shape, true_out.shape)
      return False

    if not usr_out.dtype == true_out.dtype:
      if __name__ == "__main__":
        print "Error- video_volume has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, true_out.dtype)
      return False

    if not np.all(usr_out == true_out):
      if __name__ == "__main__":
        print "Error- video_volume has value:\n{}\nExpected value:\n{}".format(
            usr_out, true_out)
      return False

  if __name__ == "__main__":
    print "video_volume passed."
    print "evaluating ssd"

  for vid_volume, true_out in zip((video_volume1, video_volume2), (diff1, diff2)):
    if __name__ == "__main__":
      print "input:\n{}\n".format(vid_volume)

    usr_out = ssd(vid_volume)

    if not type(usr_out) == type(true_out):
      if __name__ == "__main__":
        print "Error- ssd has type {}. Expected type is {}.".format(
            type(usr_out), type(true_out))
      return False

    if not usr_out.shape == true_out.shape:
      if __name__ == "__main__":
        print "Error- ssd has shape {}. Expected shape is {}.".format(
            usr_out.shape, true_out.shape)
      return False

    if not usr_out.dtype == true_out.dtype:
      if __name__ == "__main__":
        print "Error- ssd has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, true_out.dtype)
      return False

    if not np.all(np.abs(usr_out - true_out) < 1.):
      if __name__ == "__main__":
        print "Error- ssd has value:\n{}\nExpected value:\n{}".format(
            usr_out, true_out)
      return False

  if __name__ == "__main__":
    print "All unit tests successful."
  return True

if __name__ == "__main__":
  print "Performing unit tests.(ssd will be accepted if the output is within 1 of the expected output.)"
  np.set_printoptions(precision=1)

  test()

part1

import numpy as np
import cv2
import scipy.signal

def binomial_filter_5():
  ''' Create a binomial filter of length 4.
  '''
  return np.array([ 0.0625,  0.25  ,  0.375 ,  0.25  ,  0.0625], dtype=float)

def diff2(diff1):
  '''Compute the transition costs between frames, taking dynamics into account.
  
  Input:
  diff1 - a difference matrix as produced by your ssd function.

  Output:
  output - a new difference matrix that takes preceding and following frames into 
           account. The cost of transitioning from i to j should weight the 
           surrounding frames according to the binomial filter provided to you 
           above. So, the difference between i and j has weight 0.375, the frames
           immediately following weight 0.25, etc...

           The output difference matrix should have the same dtype as the input,
           but be 4 rows and columns smaller, corresponding to only the frames
           that have valid dynamics.

  Hint: there is a very efficient way to do this with 2d convolution. Think about
        the coordinates you are using as you consider the preceding and following
        frame pairings.
  '''
  output = None
  # Insert your code here ------------------------------------------------------
  w_1d = binomial_filter_5()
  (w_size) = w_1d.shape
  (rows, cols) = diff1.shape
  output = np.zeros((rows - 4, cols - 4), dtype = np.float)
  for i in range(2, rows - 2, 1):
    for j in range(2, cols - 2, 1):
      total = 0.0;
      for k in range(-2, 3, 1):
          total = total + diff1[i + k, j + k]*w_1d[k + 2]
      output[i - 2, j - 2] = total
  #kernel = np.outer(w_1d, w_1d)
  #output = scipy.signal.convolve2d(diff1, kernel, 'valid')
  # ----------------------------------------------------------------------------
  return output

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''
  d1 = np.zeros((9,9), dtype = float) 
  d1[4,4] = 1

  d2 = np.eye(5, dtype = float)

  out1 = np.array([[ 0.0625,  0.    ,  0.    ,  0.    ,  0.    ],
                   [ 0.    ,  0.25  ,  0.    ,  0.    ,  0.    ],
                   [ 0.    ,  0.    ,  0.375 ,  0.    ,  0.    ],
                   [ 0.    ,  0.    ,  0.    ,  0.25  ,  0.    ],
                   [ 0.    ,  0.    ,  0.    ,  0.    ,  0.0625]], dtype = float)

  out2 = np.array([[1.]], dtype = float)

  if __name__ == "__main__":
    print 'Evaluating diff2.'
  for d, true_out in zip((d1, d2), (out1, out2)):
    if __name__ == "__main__":
      print "input:\n{}\n".format(d)

    usr_out = diff2(d) 

    if not type(usr_out) == type(true_out):
      if __name__ == "__main__":
        print "Error- diff2 output has type {}. Expected type is {}.".format(
            type(usr_out), type(true_out))
      return False

    if not usr_out.shape == true_out.shape:
      if __name__ == "__main__":
        print "Error- diff2 output has shape {}. Expected shape is {}.".format(
            usr_out.shape, true_out.shape)
      return False

    if not usr_out.dtype == true_out.dtype:
      if __name__ == "__main__":
        print "Error- diff2 output has dtype {}. Expected dtype is {}.".format(
            usr_out.dtype, true_out.dtype)
      return False

    if not np.all(np.abs(usr_out - true_out) < 0.05):
      if __name__ == "__main__":
        print "Error- diff2 output has value:\n{}\nExpected value:\n{}".format(
            usr_out, true_out)
      return False

  if __name__ == "__main__":
    print "diff2 passed."

  if __name__ == "__main__":
    print "All unit tests successful."
  return True

if __name__ == "__main__":
  print "Performing unit tests. (Your output will be accepted if it is within .05 of the true output)"
  np.set_printoptions(precision=1)

  test()

part2

import numpy as np
import cv2
import sys
import scipy.signal

def find_biggest_loop(diff2, alpha):
  '''Given the difference matrix, find the longest and smoothest loop that we can.
  
  Inputs:
  diff2 - a square 2d numpy array of dtype float. Each cell contains the cost
          of transitioning from frame i to frame j in the input video.

  alpha - a parameter for how heavily you should weigh the size of the loop
          relative to the transition cost of the loop. Larger alphas favor
          longer loops.

  Outputs:
  s - the beginning frame of the longest loop.
  f - the final frame of the longest loop.

  s, f will the indices in the diff2 matrix that give the maximum score
  according to the following metric:

  alpha*(f-s) - diff2[f,s]
  '''
  s = None
  f = None
  # Insert your code here ------------------------------------------------------
  (rows, cols) = diff2.shape
  maxValue = -10000
  for ss in range(rows):
    for ff in range(cols):
      val = alpha*(ff-ss) - diff2[ff,ss]
      if val > maxValue:
        maxValue = val
        s = ss
        f = ff
  # ----------------------------------------------------------------------------
  return s, f

def synthesize_loop(video_volume, s, f):
  '''Pull out the given loop from video.
  
  Input:
  video_volume - a (t, row, col, 3) array, as created by your video_volume function.
  i - the index of the starting frame.
  j - the index of the ending frame.

  Output:
  output - a list of arrays of size (row, col, 3) and dtype np.uint8, similar to
  the original input the video_volume function in part0.
  '''
  output = [] 
  # Insert your code here ------------------------------------------------------
  for i in range(s, f + 1, 1):
    output.append(video_volume[i, :, :, :])
  # ----------------------------------------------------------------------------
  return output

def test():
  '''This script will perform a unit test on your function, and provide useful
  output.
  '''
  d1 = np.ones((5,5), dtype = float)
  a1 = 1
  out1 = (0,4)

  d2 = np.array([[ 0.,  1.,  1.,  5.],
                 [ 1.,  0.,  3.,  4.],
                 [ 1.,  3.,  0.,  5.],
                 [ 5.,  4.,  5.,  0.]])
  a2 = 1 
  out2 = (0,2)

  d3 = np.array([[ 0.,  1.,  4.],
                 [ 1.,  0.,  1.],
                 [ 4.,  1.,  0.]])   
  a3 = 2
  out3 = (0,1)

  if __name__ == "__main__":
    print 'Evaluating find_biggest_loop'
  for d, a, true_out in zip((d1, d2, d3), (a1, a2, a3), (out1, out2, out3)):
    if __name__ == "__main__":
      print "input:\n{}\n".format(d)
      print "alpha = {}".format(a)

    usr_out = find_biggest_loop(d, a)

    if not usr_out == true_out:
      if __name__ == "__main__":
        print "Error- find_biggest_loop is {}. Expected output is {}.".format(
            usr_out, true_out)
      return False

  if __name__ == "__main__":
    print "find_biggest_loop passed."
    print "testing synthesize_loop."

  video_volume1 = np.array([[[[ 0,  0,  0],
                              [ 0,  0,  0]]],
                            [[[ 1,  1,  1],
                              [ 1,  1,  1]]],
                            [[[ 2,  2,  2],
                              [ 2,  2,  2]]],
                            [[[ 3,  3,  3],
                              [ 3,  3,  3]]]], dtype = np.uint8) 

  video_volume2 = np.array([[[[2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2]],
                             [[2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2],
                              [2, 2, 2]]],
                            [[[1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1]],
                             [[1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1],
                              [1, 1, 1]]],
                            [[[0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0]],
                             [[0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0],
                              [0, 0, 0]]]], dtype = np.uint8)

  frames1 = (2,3)
  frames2 = (1,1)


  out1 = [np.array([[[ 2,  2,  2],
                     [ 2,  2,  2]]], dtype = np.uint8),
          np.array([[[ 3,  3,  3],
                     [ 3,  3,  3]]], dtype = np.uint8)]

  out2 = [np.array([[[1, 1, 1],
                     [1, 1, 1],
                     [1, 1, 1],
                     [1, 1, 1]],
                    [[1, 1, 1],
                     [1, 1, 1],
                     [1, 1, 1],
                     [1, 1, 1]]], dtype = np.uint8)]

  for video_volume, frames, true_out in zip((video_volume1, video_volume2), 
      (frames1, frames2), (out1, out2)):
    if __name__ == "__main__":
      print "input:\n{}\n".format(video_volume)
      print "input frames:\n{}\n".format(frames)

    usr_out = synthesize_loop(video_volume, frames[0], frames[1])

    if not type(usr_out) == type(true_out):
      if __name__ == "__main__":
        print "Error- synthesize_loop has type {}. Expected type is {}.".format(
            type(usr_out), type(true_out))
      return False

    if not len(usr_out) == len(true_out):
      if __name__ == "__main__":
        print "Error - synthesize_loop has len {}. Expected len is {}.".format(
            len(usr_out), len(true_out))
        return False

    for usr_img, true_img in zip(usr_out, true_out):
      if not type(usr_img) == type(true_img):
        if __name__ == "__main__":
          print "Error- synthesize_loop has type {}. Expected type is {}.".format(
              type(usr_img), type(true_img))
        return False

      if not usr_img.shape == true_img.shape:
        if __name__ == "__main__":
          print "Error- synthesize_loop has shape {}. Expected shape is {}.".format(
              usr_img.shape, true_img.shape)
        return False

      if not usr_img.dtype == true_img.dtype:
        if __name__ == "__main__":
          print "Error- synthesize_loop has dtype {}. Expected dtype is {}.".format(
              usr_img.dtype, true_img.dtype)
        return False

      if not np.all(usr_img == true_img):
        if __name__ == "__main__":
          print "Error- synthesize_loop has value:\n{}\nExpected value:\n{}".format(
              usr_img, true_img)
        return False

  if __name__ == "__main__":
    print "synthesize_loop passed."

  if __name__ == "__main__":
    print "All unit tests successful."
  return True

if __name__ == "__main__":
  print "Performing unit tests."

  test()

MOE Interactive Maps Unsolved issues

$
0
0

1. Wells Record Data’s French translation “Puit enregistrer des données” is not correct.

2. m.a.s.l in PGMN water level is English. French translation is required.

3. PGMN Chemistry data has a long text.


OPS Dental and Medical insurance

$
0
0

http://www.opseu.org/ops/benefits/

Plan Name:
Dental OPSEU – ER
Plan Provider:
Great West Life Assurance Co.
Coverage:
Employee Only
Group Number:
330021
Customer Service: Ext:

Plan Name:
Vision/Hearing OPSEU – ER
Plan Provider:
Manulife Financial
Coverage:
Employee Only
Group Number:
15900



Algorithms, Part II Interview Questions

$
0
0

Interview Questions: Undirected Graphs

Question 1

Nonrecursive depth-first search. Implement depth-first search in an undirected graph without using recursion.
Your Answer Score Explanation
Total 0.00 / 0.00
Question ExplanationHint: use an explicit stack.

Question 2

Diameter and center of a tree. Given a connected graph with no cycles
  • Diameter: design a linear-time algorithm to find the longest simple path in the graph.
  • Center: design a linear-time algorithm to find a vertex such that its maximum distance from any other vertex is minimized.
Your Answer Score Explanation
Total 0.00 / 0.00
Question ExplanationHint (diameter): to compute the diameter, pick a vertex s; run BFS from s; then run BFS again from the vertex that is furthest from s.
Hint (center): consider vertices on the longest path.

Question 3

Eulierian cycle. An Eulierian cycle in a graph is a cycle (not necessarily simple) that uses every edge in the graph exactly one.
  • Show that a graph has an Eulerian cycle if and only if it is both connected and every vertex has even degree.
  • Design a linear-time algorithm to determine whether a graph has an Eulerian cycle, and if so, find one.
Your Answer Score Explanation
Total 0.00 / 0.00
Question ExplanationHint: use depth-first search and piece together the cycles you discover.

 Interview Questions: Directed Graphs

Question 1

Shortest directed cycle. Given a digraph G, design an efficient algorithm to find a directed cycle with the minimum number of edges (or report that the graph is acyclic). The running time of your algorithm should be at most proportional to V(E+V) and use space proportional to E+V, where V is the number of vertices and E is the number of edges.
Your Answer Score Explanation
Total 0.00 / 0.00
Question Explanation

Hint: run BFS from each vertex.

Question 2

Hamiltonian path in a DAG. Given a directed acyclic graph, design a linear-time algorithm to determine whether it has a Hamiltonian path (a simple path that visits every vertex), and if so, find one.
Your Answer Score Explanation
Total 0.00 / 0.00
Question Explanation

Hint: topological sort.

Question 3

Reachable vertex. 
  • DAG: Design a linear-time algorithm to determine whether a DAG has a vertex that is reachable from every other vertex, and if so, find one. 
  • Digraph: Design a linear-time algorithm to determine whether a digraph has a vertex that is reachable from every other vertex, and if so, find one.
Your Answer Score Explanation
Total 0.00 / 0.00
Question Explanation

Hint (DAG): compute the outdegree of each vertex.
Hint (digraph): compute the strong components and look at the kernel DAG (the digraph that results when you contract each strong component to a single vertex).

Interview Questions: Minimum Spanning Trees

Question 1

Bottleneck minimum spanning tree. Given a connected edge-weighted graph, design an efficient algorithm to find a minimum bottleneck spanning tree. The bottleneck capacity of a spanning tree is the weights of its largest edge. A minimum bottleneck spanning tree is a spanning tree of minimum bottleneck capacity.
Your Answer Score Explanation
Total 0.00 / 0.00
Question Explanation

Hint: prove that an MST is a minimum bottleneck spanning tree.
Extra challenge: Compute a minimum bottleneck spanning tree in linear time in the worst case. Assume that you can compute the median of n keys in linear time in the worst case.

Question 2

Is an edge in a MST. Given an edge-weighted graph G and an edge e, design a linear-time algorithm to determine whether e appears in some MST of G.
Note: Since your algorithm must take linear time in the worst case, you cannot afford to compute the MST itself.
Your Answer Score Explanation
Total 0.00 / 0.00
Question Explanation

Hint: consider the subgraph G′ of G containing only those edges whose weight is strictly less than that of e.

Question 3

Minimum-weight feedback edge set. A feedback edge set of a graph is a subset of edges that contains at least one edge from every cycle in the graph. If the edges of a feedback edge set are removed, the resulting graph is acyclic. Given an edge-weighted graph, design an efficient algorithm to find a feedback edge set of minimum weight. Assume the edge weights are positive.
Your Answer Score Explanation
Total 0.00 / 0.00
Question Explanation

Hint: complement of an MST.


Algorithms, Part II Linear Programming Exercise

$
0
0

Feedback — Linear Programming

You submitted this quiz on Wed 1 May 2013 1:51 PM PDT -0700. You got a score of 2.80 out of 3.00. You can attempt again, if you’d like.

To specify an array or sequence of values in an answer, you must separate the values by a single space character (with no punctuation and with no leading or trailing whitespace). For example, if the question asks for the first ten powers of two (starting at 1), the only accepted answer is:

1 2 4 8 16 32 64 128 256 512

If you wish to discuss a particular question and answer in the forums, please post the entire question and answer, including the seed (which is used by the course staff to uniquely identify the question) and the explanation (which contains the correct answer).

Question 1

(seed = 735654)
Which of the following constraints can be modeled using linear programming?
Your Answer Score Explanation
x1 - 2x2 - 3x3 - 4x4 <= 10.
0.20
x1 - 2x2 - 3x3 - 4x4 <= -10.
0.20
x1, x2, x3, x4 are either 0 or 1
0.20
x1, x2, x3, x4 are unconstrained
0.00
x1 + 1/2 x2 + 1/3 x3 + 1/4 x4 <= 10.
0.20
Total 0.80 / 1.00
Question Explanation

Question 2

(seed = 42623)
Consider the following linear programming simplex tableaux with 3 equations and 8 variables:

    maximize Z
     - 10/3 x0  +    2 x1  +    1 x2                                   +  1/4 x6  -  3/5 x7    -  Z    = -210
    ---------------------------------------------------------------------------------------------------------
     -    1 x0  -  5/2 x1  - 10/3 x2             +    1 x4             +  7/5 x6  +  9/5 x7            =    6
     +  9/2 x0  -   10 x1  -  4/3 x2                        +    1 x5  +    8 x6  +    4 x7            =   54
     -    1 x0  +    1 x1  -    1 x2  +    1 x3                        -   10 x6  +    3 x7            =   54
            x0  ,      x1  ,      x2  ,      x3  ,      x4  ,      x5  ,      x6  ,      x7           >=    0


Which variable could be the next to *enter* the basis? Check all that apply.
Your Answer Score Explanation
x0
0.12
x1
0.12
x2
0.12
x3
0.12
x4
0.12
x5
0.12
x6
0.12
x7
0.12
Total 1.00 / 1.00
Question Explanation

The basis is { x4, x5, x3 }.
The nonbasic variables are { x0, x1, x2, x6, x7 }.
The entering variables are those nonbasic variables with a positive objective function coefficient.

Question 3

(seed = 522611)
Consider the following linear programming simplex tableaux with 5 equations and 9 variables:

    maximize Z
                           -  3/4 x2  +  9/5 x3             -  9/5 x5             -  3/2 x7               -  Z    = -246
    --------------------------------------------------------------------------------------------------------------------
                           -  7/5 x2  -  1/4 x3             -    3 x5             +    2 x7  +    1 x8            =   42
                           +  1/5 x2  +    2 x3  +    1 x4  -  9/5 x5             -  2/5 x7                       =   18
     +    1 x0             -  1/3 x2  +  9/4 x3             +  2/5 x5             +   10 x7                       =    6
                +    1 x1  -    1 x2  -  4/5 x3             -  7/3 x5             +    6 x7                       =   30
                           +    5 x2  +    4 x3             +  7/2 x5  +    1 x6  -  5/2 x7                       =   30
            x0  ,      x1  ,      x2  ,      x3  ,      x4  ,      x5  ,      x6  ,      x7  ,      x8           >=    0


Suppose that variable x3 is the variable chosen to enter the basis.
Which variable could be the next to *leave* the basis? Check all that apply.
Your Answer Score Explanation
x0
0.11
x1
0.11
x2
0.11
x3
0.11
x4
0.11
x5
0.11
x6
0.11
x7
0.11
x8
0.11
Total 1.00 / 1.00
Question Explanation

The basis is { x8, x4, x0, x1, x6 }.
The nonbasic variables are { x2, x3, x5, x7 }.
The entering variable is x3.
The min ratio test determines the leaving variable: min ratio = { *, 9, 8/3, *, 15/2 } = 8/3.
The minimum occurs in row 2, which corresponds to basic variable x0.
The leaving variables is x0.

Pattern-Oriented Software Architectures for Concurrent and Networked Software Echo Server

$
0
0

ATTN: As with all peer-assessments, you will receive the average of your 4 scores.  For the programming assignments, you will receive the maximum score out of the ones you submit (so if you get 30/30 for Java and 20/30 for C++, you will get 30/30 for Programming Assignment 2).

The purpose of this assignment is to deepen your understanding of the Wrapper Facade pattern, the Reactor pattern and the (Acceptor role of the) Acceptor-Connector pattern in the context of Java Netty. In particular, you will write a platform-independent reactive server program that accepts a connection from a client and echos back what the client sent. In brackets below are some hints about what kinds of Netty classes you might want to look up to do these (see the Netty Javadocs and examples for more background).

In addition to the Netty NIO Socket wrappers, the component that you should use for this assignment are the ServerBootstrap and ServerSocketChannelFactory. The other hints are simply for your convenience.

The reactive server program should do the following activities:
  • Create an EchoServerHandler that inherits from SimpleChannelUpstreamHandler and implement its messageReceived() hook method so that it echos back back the client’s input either (a) a “chunk” at a time or (b) a “line” at a time (i.e., until the symbols “\n”, “\r”, or “\r\n” are read), rather than a character at a time.   You can additionally override methods such as channelOpen for example to show logging information.
  • Create a ChannelPipelineFactory which sets up a pipeline for processing the inbound messages.
  • Configure the ServerSocketChannelFactory that inherits from ServerChannelFactory, and binds the ServerBootstrap class to an appropriate InetSocketAddress.
  • Configure the ServerBootstrap class with appropriate thread pools to run the events. Configure the bootstrap object with a PipelineFactory.
  • When a client connection request arrives, the ServerChannelFactory and ChannelPipeline work together to pass events to the EchoServerHandler.
  • Note that implementing SimpleChannelUpstreamHandler takes care of the connection acceptance.
  • For this assignment, you can simply exit the server process (using Ctrl+C) when you’re done, which will close down all the open sockets.

Make sure your solution clearly indicates which classes play which roles in the Wrapper Facade, Reactor, and/or Acceptor-Connector patterns.

Please implement this server program in Java using the the Netty library–which you can download from http://netty.io/ (we recommend you use Netty 3.6.x) along with  documentation at http://docs.jboss.org/netty/3.2/guide/–and put the server code in a single file.  A second file may optionally be included for a simple console client (clearly named) if you write one during your solution development as a test program and wish to include it for the convenience of evaluators, but it is not required and will not be assessed as part of this exercise, just used as a test driver for your server.  You can also use a telnet client (such as putty) as a test driver for your server.

An evaluator should be able to compile it with a command such as “javac -cp netty.jar Program.java”  and execute it with ‘java -cp .:netty.jar Program port_number’ (and ’java -cp .;netty.jar Program port_number’ for Windows) and your program should successfully run! Note that the netty’s distribution jar (which can be downloaded here http://netty.io/downloads.html ) is provided by the evaluator.Rubric30 possible points
  •  5 points – code is well-structured and design makes sense
  • 15 points – Wrapper Facade, Reactor, and Acceptor-Connector patterns are used correctly (and the classes in the solution are clearly mapped to the appropriate roles in the patterns)
  • 5 points – code demonstrates the appropriate level of readability for others to understand the intent and execution of the program
  • 5 points – code compiles and runs smoothly

NOTE: Name your file something like “Program.txt” instead of “Program.java” so that the uploader will accept your code!

javac -cp netty-3.6.5.Final.jar;junit-4.8.2.jar *.java
java -cp .;netty-3.6.5.Final.jar EchoServer

java -cp .;netty-3.6.5.Final.jar EchoClient

java -cp .;netty-3.6.5.Final.jar;junit-4.8.2.jar EchoServiceTester localhost 8080

 

//package posacns;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import junit.framework.JUnit4TestAdapter;
import junit.textui.TestRunner;

import org.junit.Test;

public class EchoServiceTester {

    public static final String ERROR_BYTES = "Server sent wrong bytes after service reaction time. Try to increase the service reaction time if the response came truncated.";

    private static int portNumber = 2048;
    private static String hostName = "127.0.0.1";
    private static int serverReactionTime = 100;
    private static String EOL = System.getProperty("line.separator");

    public static void main(String[] args) {

        System.out.println("Stand alone textui JUnit test.");
        System.out.println();
        System.out.println("-------------------------------------------------------------------------------");
        System.out.println();
        System.out.println("Usage: [portNumber [hostName [serverReactionTime]]]");
        System.out.println();
        System.out.println("Arguments:");
        System.out.println();
        System.out.println("    portNumber           The server port.");
        System.out.println("    hostName             Server host name.");
        System.out.println("    serverReactionTime   The time in milliseconds that this test will wait");
        System.out.println("                         for the server to reply.");
        System.out.println();
        System.out.println("Default values are:");
        System.out.println();
        System.out.println("    portNumber           = " + portNumber);
        System.out.println("    hostName             = " + hostName);
        System.out.println("    serverReactionTime   = " + serverReactionTime);
        System.out.println();
        System.out.println("-------------------------------------------------------------------------------");
        System.out.println();

        if (args.length >= 1) {
            try {
                portNumber = Integer.parseInt(args[0]);
            } catch (NumberFormatException e) {
                System.err.println(String.format("Invalid argument: %s. Should be integer.", args[0]));
                System.exit(1);
            }
        }

        if (args.length >= 2) {
            hostName = args[1];
        }

        if (args.length == 3) {
            try {
                serverReactionTime = Integer.parseInt(args[2]);
            } catch (NumberFormatException e) {
                System.err.println(String.format("Invalid argument: %s. Should be integer.", args[2]));
                System.exit(2);
            }
        }

        System.out.println("Using these parameters:");
        System.out.println();
        System.out.println("    portNumber           = " + portNumber);
        System.out.println("    hostName             = " + hostName);
        System.out.println("    serverReactionTime   = " + serverReactionTime);
        System.out.println();
        System.out.println("-------------------------------------------------------------------------------");
        System.out.println();

        TestRunner.run(new JUnit4TestAdapter(EchoServiceTester.class));

    }

    @Test
    public void connectionToServer() throws UnknownHostException, IOException {

        /*
         * Description
         */

        System.out.println("Checking if it is possible to connect to the server...");

        /*
         * Test
         */

        Socket socket = new Socket(hostName, portNumber);
        assertTrue("Could not create a socket to the server.", socket.isConnected());
        socket.close();
        assertTrue("Successfully created a socket to the server, but failed to close this socket.", socket.isClosed());

    }

    @Test
    public void echoFromServer() throws UnknownHostException, IOException, InterruptedException {

        /*
         * Description
         */

        System.out.println("Checking if the server echoes a short message...");

        /*
         * Test
         */

        Socket socket = new Socket(hostName, portNumber);
        byte[] bytes = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + EOL).getBytes();
        socket.getOutputStream().write(bytes);
        // Waits for the server to respond
        Thread.sleep(serverReactionTime);
        int available = socket.getInputStream().available();
        byte[] actual = new byte[available];
        socket.getInputStream().read(actual);
        socket.close();

        assertArrayEquals(ERROR_BYTES, bytes, actual);

    }

    @Test
    public void randomLongEchoFromServer() throws UnknownHostException, IOException, InterruptedException {

        /*
         * Test parameter
         */
        int messageSize = 1024;

        /*
         * Description
         */

        System.out.println("Checking if the server echoes a long random message...");

        /*
         * Test
         */

        byte[] bytes0 = new byte[messageSize];
        for (int i = 0; i < messageSize; i++) {
            bytes0[i] = (byte)(32 + Math.random() * (126 - 32));
        }

        byte[] bytes = (new String(bytes0) + EOL).getBytes();

        Socket socket = new Socket(hostName, portNumber);
        socket.getOutputStream().write(bytes);
        // Waits for the server to respond
        Thread.sleep(serverReactionTime);
        int available = socket.getInputStream().available();
        byte[] actual = new byte[available];
        socket.getInputStream().read(actual);
        socket.close();

        assertArrayEquals(ERROR_BYTES, bytes, actual);

    }

    @Test
    public void multipleEchoesFromServer() throws UnknownHostException, IOException, InterruptedException {

        /*
         * Test parameter
         */

        int messages = 300;

        /*
         * Description
         */

        System.out.println("Checking if the server echoes several messages from the same client...");

        /*
         * Test
         */

        Socket socket = new Socket(hostName, portNumber);

        for (int i = 0; i < messages; i++) {

            byte[] bytes = ("Message" + i + EOL).getBytes();
            socket.getOutputStream().write(bytes);
            // Waits for the server to respond
            Thread.sleep(serverReactionTime);
            int available = socket.getInputStream().available();
            byte[] actual = new byte[available];
            socket.getInputStream().read(actual);
            assertArrayEquals(ERROR_BYTES, bytes, actual);

            System.out.print(".");

        }

        System.out.println();

        socket.close();

    }

    @Test
    public void concurrentClients() throws UnknownHostException, IOException, InterruptedException {

        /*
         * Test parameter
         */

        int numConcurrentClients = 40;

        /*
         * Description
         */

        System.out.println("Checking if the server echoes several messages from several clients simultaneously connected (although the server is NOT required to pass this test)...");

        /*
         * Test
         */

        ArrayList sockets = new ArrayList(numConcurrentClients);

        for (int i = 0; i < numConcurrentClients; i++) {
            sockets.add(new Socket(hostName, portNumber));
        }

        // Random strings
        ArrayList testData = new ArrayList();
        testData.add("Rio");
        testData.add("Tokyo");
        testData.add("NYC");
        testData.add("Madrid");
        testData.add("Cairo");

        for (String testDatum : testData) {
            for (Socket socket : sockets) {
                byte[] bytes = (testDatum + EOL).getBytes();
                socket.getOutputStream().write(bytes);
                // Waits for the server to respond
                Thread.sleep(serverReactionTime);
                int available = socket.getInputStream().available();
                byte[] actual = new byte[available];
                socket.getInputStream().read(actual);

                assertArrayEquals(ERROR_BYTES, bytes, actual);

                System.out.print(".");
            }
        }

        System.out.println();

       for (Socket socket : sockets) {
            socket.close();
        }
    }

}

/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
//package org.jboss.netty.example.echo;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

/**
 * Echoes back any received data from a client.
 */
public class EchoServer {

    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public void run() {
        // Configure the server.
        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));

        // Set up the pipeline factory.
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(new EchoServerHandler());
            }
        });

        // Bind and start to accept incoming connections.
        bootstrap.bind(new InetSocketAddress(port));
    }

    public static void main(String[] args) throws Exception {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 8080;
        }
        new EchoServer(port).run();
    }
}

/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
//package org.jboss.netty.example.echo;

import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;

/**
 * Handler implementation for the echo server.
 */
public class EchoServerHandler extends SimpleChannelUpstreamHandler {

    private static final Logger logger = Logger.getLogger(
            EchoServerHandler.class.getName());
	private static final int CHUNK_SIZE = 50;
    private final AtomicLong transferredBytes = new AtomicLong();

	private byte[] state = new byte[CHUNK_SIZE];
	private int stateSize = 0;

    public long getTransferredBytes() {
        return transferredBytes.get();
    }

    @Override
    public void messageReceived(
            ChannelHandlerContext ctx, MessageEvent e) {
        // Send back the received message to the remote peer.
		ChannelBuffer cb = (ChannelBuffer) e.getMessage();
		byte[] input = cb.array();
        //transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
		for (int i = 0; i < input.length; i++)
			System.out.println(input[i]);
		System.out.println("");
		for (int i = 0; i < input.length; i++) {
			if (stateSize == CHUNK_SIZE - 1) { //It is full.
				e.getChannel().write(ChannelBuffers.wrappedBuffer(state));
				stateSize = 0;
			} else if (input[i] == 10 || input[i] == 13) {
				byte[] output = new byte[stateSize + 1];
				for (int j = 0; j < stateSize; j++) {
					output[j] = state[j];
				}
				output[stateSize] = input[i];
				e.getChannel().write(ChannelBuffers.wrappedBuffer(output));
				stateSize = 0;
			} else {
				state[stateSize] = input[i];
				stateSize++;
			}
		}
        //e.getChannel().write(e.getMessage());
		//e.getChannel().write(ChannelBuffers.wrappedBuffer(input));
    }

    @Override
    public void exceptionCaught(
            ChannelHandlerContext ctx, ExceptionEvent e) {
        // Close the connection when an exception is raised.
        logger.log(
                Level.WARNING,
                "Unexpected exception from downstream.",
                e.getCause());
        e.getChannel().close();
    }
}

/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
//p/ackage org.jboss.netty.example.echo;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

/**
 * Sends one message when a connection is open and echoes back any received
 * data to the server.  Simply put, the echo client initiates the ping-pong
 * traffic between the echo client and server by sending the first message to
 * the server.
 */
public class EchoClient {

    private final String host;
    private final int port;
    private final int firstMessageSize;

    public EchoClient(String host, int port, int firstMessageSize) {
        this.host = host;
        this.port = port;
        this.firstMessageSize = firstMessageSize;
    }

    public void run() {
        // Configure the client.
        ClientBootstrap bootstrap = new ClientBootstrap(
                new NioClientSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));

        // Set up the pipeline factory.
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(
                        new EchoClientHandler(firstMessageSize));
            }
        });

        // Start the connection attempt.
        ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));

        // Wait until the connection is closed or the connection attempt fails.
        future.getChannel().getCloseFuture().awaitUninterruptibly();

        // Shut down thread pools to exit.
        bootstrap.releaseExternalResources();
    }

    public static void main(String[] args) throws Exception {
        // Print usage if no argument is specified.
        if (args.length < 2 || args.length > 3) {
            System.err.println(
                    "Usage: " + EchoClient.class.getSimpleName() +
                    "   []");
            return;
        }

        // Parse options.
        final String host = args[0];
        final int port = Integer.parseInt(args[1]);
        final int firstMessageSize;
        if (args.length == 3) {
            firstMessageSize = Integer.parseInt(args[2]);
        } else {
            firstMessageSize = 256;
        }

        new EchoClient(host, port, firstMessageSize).run();
    }
}

/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
//package org.jboss.netty.example.echo;

import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;

/**
 * Handler implementation for the echo client.  It initiates the ping-pong
 * traffic between the echo client and server by sending the first message to
 * the server.
 */
public class EchoClientHandler extends SimpleChannelUpstreamHandler {

    private static final Logger logger = Logger.getLogger(
            EchoClientHandler.class.getName());

    private final ChannelBuffer firstMessage;
    private final AtomicLong transferredBytes = new AtomicLong();

    /**
     * Creates a client-side handler.
     */
    public EchoClientHandler(int firstMessageSize) {
        if (firstMessageSize <= 0) {
            throw new IllegalArgumentException(
                    "firstMessageSize: " + firstMessageSize);
        }
        firstMessage = ChannelBuffers.buffer(firstMessageSize);
        for (int i = 0; i < firstMessage.capacity(); i ++) {
            firstMessage.writeByte((byte) i);
        }
		//firstMessage.writeByte('\n');
		//System.out.println(firstMessage);
    }

    public long getTransferredBytes() {
        return transferredBytes.get();
    }

    @Override
    public void channelConnected(
            ChannelHandlerContext ctx, ChannelStateEvent e) {
        // Send the first message.  Server will not send anything here
        // because the firstMessage's capacity is 0.
        e.getChannel().write(firstMessage);
    }

    @Override
    public void messageReceived(
            ChannelHandlerContext ctx, MessageEvent e) {
        // Send back the received message to the remote peer.
        //transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
       // e.getChannel().write(e.getMessage());
		ChannelBuffer cb = (ChannelBuffer) e.getMessage();
		byte[] input = cb.array();
        //transferredBytes.addAndGet(((ChannelBuffer) e.getMessage()).readableBytes());
		for (int i = 0; i < input.length; i++)
			System.out.println(input[i]);
		System.out.println("");
        //e.getChannel().write(e.getMessage());
		e.getChannel().write(ChannelBuffers.wrappedBuffer(input));
    }

    @Override
    public void exceptionCaught(
            ChannelHandlerContext ctx, ExceptionEvent e) {
        // Close the connection when an exception is raised.
        logger.log(
                Level.WARNING,
                "Unexpected exception from downstream.",
                e.getCause());
        e.getChannel().close();
    }
}



Scala-based high performance geoprocessing library GeoTrellis

$
0
0

Scala-based high performance geoprocessing library GeoTrellis adds vector support in new version 0.8

Tue, 2013/03/26 – 17:11 — Anonymous

The GeoTrellis team is very excited to announce the availability of GeoTrellis 0.8 (codename “Atlantis”), which is a major new release that is a huge step forward towards our goal of a general purpose, high performance geoprocessing library and runtime designed to perform and scale for the web.

As you delve into GeoTrellis 0.8 in more depth, here are some new features you may want to explore:

For more information, see the Azavea Labs blog here: http://www.azavea.com/blogs/labs/2013/03/geotrellis-0-8-has-arrived/


The ArcGIS Runtime SDK for Qt 10.2 beta is now available!

$
0
0

The ArcGIS Runtime SDK for Qt 10.2 beta is now available!

  •  2 23 405

Esri is pleased to announce the beta release of the ArcGIS Runtime SDK for Qt.

ArcGIS Runtime SDK for Qt is designed to help C++ developers use the Digia Qt framework to create highly functional GIS applications that use local services, yet the applications can have a small footprint. Local services allow for disconnected work in the field; an ArcGIS Server connection is not required.

 

Developers can build and deploy ArcGIS applications with this new SDK on both Windows and Linux platforms, 32- and 64-bit. This first release of the beta is available on Linux, with Windows to follow shortly, so stay tuned to the beta program for updates!

The ArcGIS Runtime SDK for Qt enables you to:

  • Create focused applications with small memory and disk-space footprints. You select the capabilities you want, from simple map view/navigation to geoprocessing.
  • Build touch-screen applications for platforms such as tablets and in-vehicle mounted devices.
  • Display web maps that have been authored on www.ArcGIS.com or your own on-premise ArcGIS portals.
  • Mashup data from your local device with map services from ArcGIS Online and/or your own on-premise ArcGIS Server to create unique maps.
  • Display information about features in a map using popups
  • Execute sophisticated geoprocessing tasks and display their results.
  • Perform geometric operations and compute spatial relationships between features.
  • Perform 2D visualization and analysis and 3D analysis
  • Let users interactively add graphics and markup to a map
  • Search for features or attributes in your GIS data and display the results
  • …more…

We invite you to browse the online documentation and participate in the forums!

To get started with the beta today, simply download the ArcGIS Runtime SDK for Qt from the community beta page. All you need is an Esri Global ID.

A summary from the related ArcGIS Runtime announcements at the Development Summit this week:

Esri is releasing this week 3 new runtimes SDKs:

  • ArcGIS Runtime SDK for OS X.
  • ArcGIS Runtime SDK for Windows Store apps.
  • ArcGIS Runtime SDK for Qt.

To join the 6 existing runtimes available:

  • ArcGIS Runtime SDK for iOS
  • ArcGIS Runtime SDK for WPF
  • ArcGIS Runtime SDK for Windows Phone
  • ArcGIS Runtime SDK for Windows Mobile
  • ArcGIS Runtime SDK for Java
  • ArcGIS Runtime SDK for Android

With the 3 new releases, developers have the choice of 9 native runtime platforms for writing mapping applications. Developers have options to target their native platforms and languages (C#, Objective-C, Java and C++)

Note these 3 SDKs are in Beta. If you happen to encounter any bugs or issues of any kind, we encourage you to use the Community Beta to submit these. Your participation and feedback are greatly appreciated!

Don’t forget to follow us on Twitter: @ArcGIS_Runtime

This entry was posted in App DevelopersDeveloper and tagged . Bookmark the permalink.

Viewing all 764 articles
Browse latest View live