Python Translator Hole Example

Moved from PythonTranslator

In Perl:

 package hole;

use strict; use Exporter; use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = (); @EXPORT_OK = qw( &new ); %EXPORT_TAGS = ( DEFAULT => [qw ( &new )] );

# # new - hole constructor # peg ) By convention, contains a fill color # black implies there is a peg in the hole and # white impleis there is no peg in the hole. # # index) holes must be indexed 0 through 14 # # links) is a ref to an array of adjacent holes. # This isn't typical passed to the new constructor. # It is easier to call setLinks ( see below ) # sub new { my ($pkg, $peg, $index, $level, $links ) = @_; my $obj = bless { peg => $peg, holeIndex => $index, level => $level, links => $links # ref to array of holes }, $pkg; return $obj; }

# # takes a ref to an array of adjacent holes # and sets this hole's links attribute # sub setLinks { my $obj = shift; my $links = shift; $obj->{'links'} = $links; }

# # takes a fill color of the peg. # black => has peg # white => does not have peg # sub setPeg { my $obj = shift; my $peg = shift; $obj->{'peg'} = $peg; }

# # returns the links attribute # sub getLinks { my $obj = shift; return $obj->{'links'}; }

# # returns the peg attribute # sub getPeg { my $obj = shift; return $obj->{'peg'}; }

# # jumpingOver determines if another peg from the hole # having index of $jumperIndex is allowed to jump the # peg in this hole. # sub jumpingOver { my $obj = shift; my $jumperIndex = shift;

# # You have no peg to jump with # if ( $obj->{'peg'} eq 'white' ) { return -1; }

# # You can't jump yourself # if ( $jumperIndex == $obj->{'holeIndex'} ) { return -1; }

# # find jumper in links array # my $jumper = $obj->getHoleWithIndex ( $jumperIndex ); if ( $jumper ) { if ( !$jumper->hasPeg() ) { return -1; } my $objIndex = $obj->{'holeIndex'}; my $jumperLevel = $jumper->{'level'}; my $objLevel = $obj->{'level'}; my $levelDiff = abs($objLevel - $jumperLevel); my $targetIndex = 2 * $objIndex + $levelDiff - $jumperIndex; my $targetHole = $obj->getHoleWithIndex( $targetIndex ); if ( $targetHole ) { # # we can jump to hole with index of $targetIndex # return $targetIndex if $targetHole->{'peg'} eq 'white'; # # we can jump because there is a peg is blocking # return -1; } else { # # no hole # return -1; } } else { # # The jumper is not adjacent to this hole # return -1; } # # we should NOT get here. # return -1; }

# # If peg is black then there is a peg there # sub hasPeg { my $obj = shift; return ( $obj->{'peg'} eq 'black' ); }

# # return the hole that has index, i # sub getHoleWithIndex { my $obj = shift; my $i = shift;

foreach my $link ( @{$obj->{'links'}} ) { if ( $link->{'holeIndex'} == $i ) { return $link; } } return undef; }

1;


Direct Python Translation:

 class Hole:

# # _init_ - hole constructor # peg ) By convention, contains a fill color # black implies there is a peg in the hole and # white impleis there is no peg in the hole. # #index) holes must be indexed 0 through 14 # #links) is a ref to an array of adjacent holes. # This isn't typical passed to the new constructor. # It is easier to call setLinks ( see below ) # def __init__ ( self, peg, index, level, links ): self.peg= peg self.holeIndex= index self.level= level self.links= links # ref to array of holes

# # takes a ref to an array of adjacent holes # and sets this hole's links attribute # def setLinks ( self, links ): self.links = links

# # takes a fill color of the peg. # black => has peg # white => does not have peg # def setPeg ( self, peg ): self.peg = peg

# # returns the links attribute # def getLinks (self): return self.links

# # returns the peg attribute # def getPeg (self): return self.peg

# # jumpingOver determines if another peg from the hole # having index of jumperIndex is allowed to jump the # peg in this hole. # def jumpingOver ( self, jumperIndex ): # # You have no peg to jump with # if self.peg == 'white': return -1

# # You can't jump yourself # if jumperIndex == self.holeIndex: return -1

# # find jumper in links array # jumper = self.getHoleWithIndex ( jumperIndex ) if jumper: # # you have to use a peg to jump # if not jumper.hasPeg(): return -1 objIndex = self.holeIndex jumperLevel = jumper.level objLevel = self.level levelDiff = abs(objLevel - jumperLevel) targetIndex = 2 * objIndex + levelDiff - jumperIndex targetHole = self.getHoleWithIndex( targetIndex ) if targetHole: # # we can jump to hole with index of targetIndex # if targetHole.peg == 'white': return targetIndex # # we can't jump because there is a # peg is blocking # return -1 else: # # no hole # return -1 else: # # The jumper is not adjacent to this hole # return -1 # # we should NOT get here. # return -1

# # If peg is black then there is a peg there # def hasPeg (self): return self.peg == 'black'

# # return the hole that has index, i # def getHoleWithIndex (self, i): for link in self.links: if link.holeIndex == i: return link return NULL

# # print out the hole object # def dump (self): print "Hole:\n\tpeg => [" + self.peg + "]" for l in self.links: print "\tlink => [" + l.peg + "]" print "\tlevel => [" + str(self.level) + "]"


Be aware that the preious translation is _really_ not idiomatic:

A more idiomatic version would be:

 class Hole(object):
    def __init__(self, has_peg, index, level, links):
        '''
        _init_ - hole constructor
            has_peg  ) Flag set to True if hole contains a peg or False if not
            index) holes must be indexed 0 through 14
            links) is a ref to an array of adjacent holes.        
                   This isn't typical passed to the new constructor.
                   It is easier to just set the links directly
        '''
        self.has_peg = has_peg
        assert 0 <= index <= 14
        self.index  = index
        self.level  = level
        self.links  = links # ref to array of holes

def jumping_over(self, jumper_index): ''' Determines if another peg from the hole having index of jumper_index is allowed to jump the peg in this hole. ''' try: assert self.has_peg # Must have a peg to jump assert jumper_index != self.index # You can't jump yourself

# find jumper in adjacent links array jumper = self.get_hole_with_index(jumper_index)

assert jumper # There must be a hole to jump from assert jumper.has_peg # it must contain a peg

# find target in adjacent links array level_diff = abs(self.level - jumper.level) target_index = 2 * self.index - jumper.index + level_diff target_hole = self.get_hole_with_index(target_index)

assert target_hole # There must be a hole to jump to assert not target_hole.has_peg # it mustn't contain a peg except AssertionError?: return -1 # retained for compatibility

return target_index # All tests passed

def get_hole_with_index(self, i): ''' Returns the hole that has index equal to i ''' for link in self.links: if link.holeIndex == i: return link return None

def __str__(self): ''' Allows "print <hole>" ''' out = ["Hole %s:"%self.index, "\thas_peg => [%s]"%self.has_peg]

out.extend(["\tlink => [%s]"%l.peg for l in self.links]) out.append("\tlevel => [%s]"% self.level) return "\n".join(out)


Of course this still isn't fully idiomatic - links should be a dictionary, with its keys as each hole's index. This makes lookup trivial (though even this version still doesn't feel fully idiomatic ;-):

 class Hole(object):
    def __init__(self, has_peg, index, level, links):
        '''
        Constructor for hole instances
            has_peg: Flag set to True if hole contains a peg or False if not
            index: holes must be indexed 0 through 14
            links: This is a property, allowing self._links to be accessed as:
                self.links                 # call self._get_links()
                self.links = [h1, h2, h3]  # call self._set_links([h1, h2, h3])
            _links: This is a dictionary (associative array/mapping) with
                key equal to hole.index, and value equal to a ref to the hole.
        '''
        self.has_peg = has_peg
        assert 0 <= index <= 14
        self.index  = index
        self.level  = level
        self._links = {}
        self.links  = links

def _set_links(self, links): ''' Accessor function for links property() ''' for link in links: self._links[link.index] = link

def _get_links(self): ''' Accessor function for links property() ''' return self._links

links = property(_get_links, _set_links)

def jumping_over(self, jumper_index): ''' Determines if another peg from the hole having index of jumper_index is allowed to jump the peg in this hole. ''' try: assert self.has_peg # Must have a peg to jump assert jumper_index != self.index # Can't jump yourself

# find jumper in links dict. Raises KeyError? if not found jumper = self.links[jumper_index] assert jumper.has_peg # hole must contain a peg

level_diff = abs(self.level - jumper.level) target_index = 2 * self.index - jumper.index + level_diff

# find target in links dict. Raises KeyError? if not found target_hole = self.links[target_index] assert not target_hole.has_peg # hole mustn't contain a peg

except (AssertionError?, KeyError?): return -1 # retained for compatibility

return target_index # All tests passed

def __str__(self): ''' Allows "print <hole>" ''' out = ["Hole %s:"%self.index, "\thas_peg => [%s]"%self.has_peg]

out.extend(["\tlink => [%s]"%l.peg for l in self.links.values()]) out.append("\tlevel => [%s]"% self.level) return "\n".join(out)


CategoryComparisons


EditText of this page (last edited June 27, 2004) or FindPage with title or text search