Subject:

May Listings Changes

From:

DBlake@cmp.com

Date:

Thu, 17 Feb 2005 11:25:47 -0700

To:

JErickson@ddj.com









Four articles had changes this month:

Rolf, bedn(MBED), eby, and Grim



ROLF

Listing One

void Nqueens (int Board[], int Trial[], int Size, int Row)

{

   if (Row == Size)

      Process(Board, Size);

   else

      for (int Col = 0; Col < Size; Col++)

      {

         Board[Row] = Col;

         if ( Valid (Board, Size, Row) )

            Nqueens (Board, Trial, Size, Row+1);

      }

}

Listing Two

int Valid (int Board[], int Size, int Row)

{

   for (int Idx = 0; Idx < Row; Idx++)

      if (  Board[Idx] == Board[Row] ||

            abs(Board[Row]-Board[Idx]) == (Row-Idx) )

         return 0;    // boolean false

   return 1;          // boolean true

}

Listing Three

int Valid (int Board[], int Size, int Row,

           int Col[], int Diag[], int AntiD[] )

{

   int Idx;        /* Index into Diag[] / AntiD[] */

   int Chk;        /* Occupied flag               */



   Chk = Col[Board[Row]];

/* Diagonal:  Row-Col == constant */

   Idx = Row - Board[Row] + Size-1;

   Chk = Chk || Diag[Idx];

/* AntiDiagonal:  Row+Col == constant */

   Idx = Row + Board[Row];

   Chk = Chk || AntiD[Idx];

   return !Chk;    /* Valid if NOT any occupied  */

}



Listing Four

void Nqueens (int Board[],int Size, int Row)

{

   int Idx, Lim, Vtemp;



/* Check for a partial board. */

   if (Row < Size-1)

   {

      if (Valid (Board, Size, Row)

         Nqueens (Board, Trial, Size, Row+1);

      for (Idx = Row+1; Idx < Size; Idx++)

      {

         Vtemp = Board[Idx];

         Board[Idx] = Board[Row];

         Board[Row] = Vtemp;

         if (Valid (Board, Size, Row))

            Nqueens (Board, Trial, Size, Row+1);

         }

      }

/*    Regenerate original vector from Row to Size-1:  */

      Vtemp = Board[Row];

      for (Idx = Row+1; Idx < Size; Idx++)

         Board[Idx-1] = Board[Idx];

      Board[Idx-1] = Vtemp;

   }

/* This is a complete board.  Final validity check    */

   else if ( Valid (Board, Size, Row) )

      Process(Board, Size);

}

Listing Five

/* Check the symmetries.  Return 0 if this is not the 1st     */

/* solution in the set of equivalent solutions; otherwise     */

/* return the number of equivalent solutions.                 */

int SymmetryOps(

    int Board[],     /* The fully-populated board             */

    int Trial[],     /* Used for symmetry checks              */

                     /* Holds its own scratch space too!      */

    int Size)        /* Number of cells in a row/column       */

{  int  Idx;         /* Loop variable; intncmp result         */

   int  Nequiv;      /* Number equivalent boards              */

   int *Scratch=&Trial[Size];   /* Scratch space              */



/* Copy; Trial will be subjected to the transformations       */

   for (Idx = 0; Idx < Size; Idx++)

      Trial[Idx] = Board[Idx];



/* 90 degrees --- clockwise (4th parameter of Rotate is FALSE)*/

   Rotate (Trial, Scratch, Size, false);

   Idx = intncmp (Board, Trial, Size);

   if (Idx > 0) return 0;

   if ( Idx == 0 )  /* No change on 90 degree rotation        */

      Nequiv = 1;

   else                                       /*  180 degrees */

   {  Rotate (Trial, Scratch, Size, false);

      Idx = intncmp (Board, Trial, Size);

      if (Idx > 0) return 0;

      if ( Idx == 0 ) /* No change on 180 degree rotation     */

         Nequiv = 2;

      else                                    /* 270 degrees  */

      {  Rotate (Trial, Scratch, Size, false);

         Idx = intncmp (Board, Trial, Size);

         if (Idx > 0) return 0;

         Nequiv = 4;

      }

   }

/* Copy the board into Trial for rotational checks */

   for (Idx = 0; Idx < Size; Idx++)

      Trial[Idx] = Board[Idx];

/* Reflect -- vertical mirror */

   Vmirror (Trial, Size);

   Idx = intncmp (Board, Trial, Size);

   if (Idx > 0) return 0;

   if ( Nequiv > 1 )    // I.e., no four-fold rotational symmetry

   {

/* -90 degrees --- equiv. to diagonal mirror */

      Rotate (Trial, Scratch, Size, true);

      Idx = intncmp (Board, Trial, Size);

      if (Idx > 0) return 0;

      if ( Nequiv > 2 ) // I.e., no two-fold rotational symmetry

      {

/* -180 degrees --- equiv. to horizontal mirror */

         Rotate (Trial, Scratch, Size, true);

         Idx = intncmp (Board, Trial, Size);

         if (Idx > 0) return 0;

/* -270 degrees --- equiv. to anti-diagonal mirror */

         Rotate (Trial, Scratch, Size, true);

         Idx = intncmp (Board, Trial, Size);

         if (Idx > 0) return 0;

      }

   }

/* WE HAVE A GOOD ONE! */

   return Nequiv * 2;  /* Double to handle the mirror images */

}

Listing Six

public class Board

{  private int nSoln = 0,    // Total solutions for this board

               nUniq = 0;    // Unique solutions, rejecting ones

                             // equivalent based on rotations.

   private int size,         // Board size AND number of queens

               limit,        // First row mid-point

               nextCol = 0;  // Next position to be computed



   public Board (int size)

   {  this.size = size;

      limit = (size+1) / 2;  // Mirror images done automatically

   }



// Accumulate partial results and assign the next problem.

// Synchronized because this is the critical section ---

// only one thread allowed in at a time.

   public synchronized int nextJob ( int nS, int nU)

   {  nSoln += nS;

      nUniq += nU;

   // If all columns have been assigned, return the exit flag

      return nextCol < limit ? nextCol++ : -1;

   }

}

// Return the saved information on total solutions

   public int total(){  return nSoln;  }



// Return the saved information on unique solutions

   public int unique(){  return nUniq;  }

}

Listing Seven

public WorkEngine(int size, int nMore, Board info)

{  this.size = size;

   this.info = info;

   board     = new int[size];

   trial     = new int[size];

   scratch   = new int[size];

   diagChk   = new boolean[2*size-1];

   antiChk   = new boolean[2*size-1];

   if ( nMore > 0 )

      try

      {  child = new WorkEngine( size, nMore-1, info );

         child.start();

      }

      catch ( Exception e )

      {  System.out.println(e);  }

   else

      child = null;

}

Listing Eight

public void run()

{  int  nextCol;

   long start = System.currentTimeMillis();



   while ( true )    // Will break out on -1 for column posn.

   {  int row, col;



   // On the first call, nTotal and nUnique hold zeroes.

      nextCol = info.nextJob(nTotal, nUnique);

      if ( nextCol < 0 )

         break;

   // Empty out counts from the last board processed

      nTotal = nUnique = 0;

   // Generate the initial permutation vector, given nextCol

      board[0] = nextCol;

      for ( row = 1, col = 0; row < size; row++, col++ )

         board[row] = col == nextCol ? ++col : col;

   // Empty out the diagChk and antiChk vectors

      for ( row = 0; row < 2*size-1; row++ )

         diagChk[row] = antiChk[row] = false;

   // Mark as inuse the diagonal and antidiagonal

      diagChk[size-1-nextCol] = antiChk[nextCol] = true;

   // Now compute from row 1 on down.

      nQueens (1);

   }

   if ( child != null )

      try

      {  child.join();  }

      catch ( Exception e )

      {  System.out.println(e);  }

}





DDJ



BEDN (MBED)

Listing One

try {

//Instantiate ClassLoader, passing the location (directory) of the class to

//load and the parent class loader

ClassLoader loader = new MacroClassLoader(classLocation,

                                          this.getClass().getClassLoader());



//Load the class with the custom ClassLoader;

// we can now instantiate new using the newInstance() method

Class klass = loader.loadClass(classToLoad);



//Instantiate a new instance of the loaded class - this is equivalent to the

//"new" keyword

Runnable loadedClass = (Runnable)klass.newInstance();



//Check to make sure that our custom ClassLoader succeeded

// in loading the class, and not the System class loader

if(this.getClass().getClassLoader() == loadedClass.getClass().getClassLoader())

{

  //If we get here, then the class instance loadedClass was

  //loaded by the System class loader, not by our custom class loader!!!

  printErrorMsg(classToLoad,

                new String("Class was not loaded by the proper class loader"));

  return;

}

} catch (ClassCastException e){

  printErrorMsg(classToLoad,

                new String("Class must implement java.lang.Runnable"));

  return;

} catch (ClassNotFoundException e){

  printErrorMsg(classToLoad,

                new String("Class could not be located at " + classLocation));

  return;

} catch (IllegalAccessException e){

  printErrorMsg(classToLoad,

                new String("ClassLoader threw an IllegalAccessException"))

  return;

} catch (InstantiationException e){

  printErrorMsg(classToLoad,

                new String("ClassLoader threw an InstantiationException"));

  return;

} catch (MalformedURLException e) {

  printErrorMsg(classToLoad,

                new String("ClassLoader threw a MalformedURLException"));

  return;

}

Listing Two

public class MacroClassLoader extends java.net.URLClassLoader {



  public MacroClassLoader(String classLocation, ClassLoader parent)

    throws MalformedURLException {

//Create a new URL[] array with one entry, a URL expressing the

//location of the String classLocation which is an input parameter to this

//method. We will assume that the class location is on the local filesystem,

//and will prepend the file:// (Unix) or file:/// (Windows) URL identifier as

//well as replacing any Windows-style forward slashes with URL-style

//backslashes

    super(new URL[] {

          new URL("file:" + ((classLocation.charAt(0) == '/') ? "//" : "///" )

                   + classLocation.replace('\\', '/') + "/")}, parent);

  }

}

Listing Three

public class TestRunnableProjRename implements java.lang.Runnable {

// (non-Javadoc) * @see java.lang.Runnable#run()



  public void run() {

    IWorkspace workspace = null;

    IWorkspaceRoot workspaceRoot = null;

    IProject [] projects = null;



    System.out.println("In TestRunnableProjRename...");



    workspace = ResourcesPlugin.getWorkspace();

    workspaceRoot = workspace.getRoot();

    projects = workspaceRoot.getProjects();



    //Iterate over all of the projects in the current workspace

    for(int i=0; i < projects.length; i++){



      //Closed projects should be ignored...

      if(!projects[i].isOpen())

        continue;



      //Rename all projects in workspace to $(PROJNAME)_Modified

      try {

        IProjectDescription description = projects[i].getDescription();

        System.out.println("\tAttempting to change project "

                           + description.getName());

        description.setLocation(description.getLocation());

        description.setName(description.getName().concat("_Modified"));



           //Actually perform the rename

        IResource resource = (IResource)projects[i];

        resource.move(description, true, false, null);

      } catch (Exception e) {

        e.printStackTrace();

      }

    }

  }

}



DDJ



EBY

Listing One

(a)

import atexit



def goodbye():

    print "Goodbye, world!"



atexit.register(goodbye)



(b)

import atexit



@atexit.register

def goodbye():

    print "Goodbye, world!"

Listing Two

(a)

class Something(object):

    def someMethod(cls,foo,bar):

        print "I'm a class method"

    someMethod = classmethod(someMethod)



(b)

class Something(object):

    @classmethod

    def someMethod(cls,foo,bar):

        print "I'm a class method"

Listing Three

(a)

def mydecorator(func):

    print "decorating", func

    return func

print "before definition"

@mydecorator



def some_function():

    print "I'm never called, so you'll never see this message"

print "after definition"



(b)

before definition

decorating <function some_function at 0x00A933C0>

after definition

Listing Four

def stupid_decorator(func):

    return "Hello, world!"

@stupid_decorator

def does_nothing():

    print "I'm never called, so you'll never see this message"

print does_nothing

Listing Five

class traced:

    def __init__(self,func):

        self.func = func



    def __call__(__self,*__args,**__kw):

        print "entering", __self.func

        try:

            return __self.func(*__args,**__kw)

        finally:

            print "exiting", __self.func

@traced

def hello():

    print "Hello, world!"

hello()

Listing Six

class SomeClass(object):

    @classmethod

    @traced

    def someMethod(cls):

        print "Called with class", cls

Something.someMethod()

Listing Seven

def traced(func):

    def wrapper(*__args,**__kw):

        print "entering", func

        try:

            return func(*__args,**__kw)

        finally:

            print "exiting", func

    return wrapper

Listing Eight

def require(expr):

    def decorator(func):

        def wrapper(*__args,**__kw):

            assert eval(expr),"Precondition failed"

            return func(*__args,**__kw)

        return wrapper

    return decorator

@require("len(__args)==1")

def test(*args):

    print args[0]

test("Hello world!")

Listing Nine

def author(author_name):

    def decorator(func):

        func.author_name = author_name

        return func

    return decorator



@author("Lemony Snicket")

def sequenceOf(unfortunate_events):

    pass

print sequenceOf.author_name    # prints "Lemony Snicket"

Listing Ten

def require(expr):

    def decorator(func):

        def wrapper(*__args,**__kw):

            assert eval(expr),"Precondition failed"

            return func(*__args,**__kw)

        wrapper.__name__ = func.__name__

        wrapper.__dict__ = func.__dict__

        wrapper.__doc__ = func.__doc__

        return wrapper

    return decorator

Listing Eleven

def synchronized(func):

    def wrapper(self,*__args,**__kw):

        try:

            rlock = self._sync_lock

        except AttributeError:

            from threading import RLock

            rlock = self.__dict__.setdefault('_sync_lock',RLock())

        rlock.acquire()

        try:

            return func(self,*__args,**__kw)

        finally:

            rlock.release()

    wrapper.__name__ = func.__name__

    wrapper.__dict__ = func.__dict__

    wrapper.__doc__ = func.__doc__

    return wrapper

class SomeClass:

    """Example usage"""

    @synchronized

    def doSomething(self,someParam):

        """This method can only be entered

           by one thread at a time"""



DDJ



GRIM

Listing One

class IndentListView : ListView

{

   public int InsertIndented(ListViewItem lvi, int indentLevel);

   protected int InsertItem(ListViewItem lvi, int indentLevel, int id);

   protected void SetItemText(int itemIndex, int subItemIndex, string text);

   class LVIData{};

   private ArrayList operations = null;

   protected override void OnHandleCreated(EventArgs e);

}

Listing Two

[DllImport("user32")]

static extern int SendMessage(IntPtr hWnd, int msg,

   int wParam, ref LVITEM lParam);

[StructLayout(LayoutKind.Sequential)]

struct LVITEM

{

   public const int LVIF_TEXT   = 0x0001;

   public const int LVIF_IMAGE  = 0x0002;

   public const int LVIF_PARAM  = 0x0004;

   public const int LVIF_INDENT = 0x0010;

   public const int LVM_INSERTITEM = 0x1007;

   public const int LVM_SETITEMTEXT = 0x102d;



   public uint mask;

   public int iItem;

   public int iSubItem;

   public uint state;

   public uint stateMask;

   public string pszText;

   public int cchTextMax;

   public int iImage;

   public IntPtr lParam;

   public int iIndent;

   public int iGroupId;

   public uint cColumns;

   public uint puColumns;

}

Listing Three

protected int InsertItem(ListViewItem lvi, int indentLevel, int id)

{

   int dispIdx = GetCount() + 1;

   LVITEM lvitem = new LVITEM();

   lvitem.mask = LVITEM.LVIF_TEXT | LVITEM.LVIF_PARAM

      | LVITEM.LVIF_IMAGE | LVITEM.LVIF_INDENT;

   lvitem.iItem = dispIdx;

   lvitem.pszText = lvi.Text;

   lvitem.iImage = lvi.ImageIndex;

   lvitem.iIndent = indentLevel;

   lvitem.lParam = (IntPtr)id;



   AddToItemsTable(lvi, id);

   dispIdx = SendMessage(this.Handle, LVITEM.LVM_INSERTITEM, 0, ref lvitem);

   UpdateItem(lvi, id, dispIdx);



   for (int idx = 0; (idx < lvi.SubItems.Count); ++idx)

   {

      SetItemText(id, idx, lvi.SubItems[idx].Text);

   }

   return lvi.Index;

}

protected void SetItemText(int itemIndex, int subItemIndex, string text)

{

   LVITEM lvitem = new LVITEM();

   lvitem.mask = LVITEM.LVIF_TEXT;

   lvitem.iItem = itemIndex;

   lvitem.iSubItem = subItemIndex;

   lvitem.pszText = text;

   SendMessage(this.Handle, LVITEM.LVM_SETITEMTEXT, itemIndex, ref lvitem);

}

private int GenerateNextID()

{

   Type type = typeof(ListView);

   MethodInfo mi = type.GetMethod("GenerateUniqueID",

      BindingFlags.NonPublic | BindingFlags.Instance);

   return (int)mi.Invoke(this, null);

}

private void AddToItemsTable(ListViewItem lvi, int id)

{

   Type type = typeof(ListView);

   FieldInfo fi = type.GetField("listItemsTable",

      BindingFlags.NonPublic | BindingFlags.Instance);

   Hashtable listItemsTable = (Hashtable)fi.GetValue(this);

   listItemsTable.Add(id, lvi);

   fi = type.GetField("itemCount",

      BindingFlags.NonPublic | BindingFlags.Instance);

   int count = (int)fi.GetValue(this);

   fi.SetValue(this, ++count);

}

private void UpdateItem(ListViewItem lvi, int id, int dispIdx)

{

   Type type = typeof(ListViewItem);

   MethodInfo mi = type.GetMethod("Host",

      BindingFlags.NonPublic | BindingFlags.Instance);

   object[] args = new object[]{this, id, dispIdx};

   mi.Invoke(lvi, args);

}

Listing Four

class LVIData

{

   public ListViewItem lvi;

   public int IndexLevel;

   public int ID;

}

public int InsertIndented(ListViewItem lvi, int indentLevel)

{

   if (this.Handle == IntPtr.Zero)

   {

      if (operations == null)

         operations = new ArrayList();

      LVIData data = new LVIData();

      data.lvi = lvi;

      data.IndexLevel = indentLevel;

      data.ID = GenerateNextID();

      operations.Add(data);

      return data.ID;

   }

   return InsertItem(lvi, indentLevel, GenerateNextID());

}

protected override void OnHandleCreated(EventArgs e)

{

   if (operations != null)

   {

      for (int idx = 0; idx < operations.Count; ++idx)

      {

         LVIData data = operations[idx] as LVIData;

         InsertItem(data.lvi, data.IndexLevel, data.ID);

      }

      operations = null;

   }

   base.OnHandleCreated(e);

}

Listing Five

public class MainForm : Form

{

   private IndentListView lv;

   public MainForm()

   {

      this.lv = new IndentListView();

      this.lv.Dock = DockStyle.Fill;

      this.lv.View = View.Details;

      ImageList il = new ImageList();

      Icon ic = LoadIconFromResources("first_icon");

      il.Images.Add(ic);

      lv.SmallImageList = il;



      ColumnHeader header;

      header = new ColumnHeader();

      this.lv.Columns.Add(header);

      header.Text = "Data";

      header.Width = 200;

      this.Controls.Add(this.lv);



      ListViewItem lvi = new ListViewItem("one", 0);

      lv.InsertIndented(lvi, 0);

      lvi = new ListViewItem("two", 0);

      lv.InsertIndented(lvi, 1);

      lvi = new ListViewItem("three", 0);

      lv.InsertIndented(lvi, 0);

   }

   static void Main()

   {

      Application.Run(new MainForm());

   }

}

Listing Six

class MainForm : Form

{

   MainForm()

   {

      this.Closed += new EventHandler(ClosedForm);

   }

   void ClosedForm(object sender, EventArgs e)

   {

      Application.ExitThread();

   }

   static void Main()

   {

      MainForm form = new MainForm();

      form.Visible = true;

      Application.Run();

   }

}





DDJ







__________________________________________________________________________________________



Any views or opinions are solely those of the author and do not necessarily

represent those of CMP Media LLC, 600 Community Drive, Manhasset, NY 11030.



The information transmitted is intended only for the person or entity to which

it is addressed and may contain confidential and/or privileged material.  If you

are not the intended recipient of this message please do not read, copy, use or

disclose this communication and notify the sender immediately.  It should be

noted that any review, retransmission, dissemination or other use of, or taking

action or reliance upon, this information by persons or entities other than the

intended recipient is prohibited.

__________________________________________________________________________________________





