[gnome-games] gnome-sudoku: Style cleanup in sudoku.py



commit 39827c18eb125402e2631e9d63e1cc2fc491c3aa
Author: Zhang Sen <zh jesse gmail com>
Date:   Tue May 12 20:11:20 2009 +0800

    gnome-sudoku: Style cleanup in sudoku.py
    
    Nothing but adding spaces and newlines. Part of bug 578903.
---
 gnome-sudoku/src/lib/sudoku.py |  433 +++++++++++++++++++++-------------------
 1 files changed, 228 insertions(+), 205 deletions(-)

diff --git a/gnome-sudoku/src/lib/sudoku.py b/gnome-sudoku/src/lib/sudoku.py
index 8974811..7a83de5 100644
--- a/gnome-sudoku/src/lib/sudoku.py
+++ b/gnome-sudoku/src/lib/sudoku.py
@@ -10,11 +10,12 @@ TYPE_ROW = 0
 TYPE_COLUMN = 1
 TYPE_BOX = 2
 
-digit_set = range(1,GROUP_SIZE+1)
+digit_set = range(1, GROUP_SIZE + 1)
 sets = [digit_set] * 9
 
 def is_set (row):
-    if len(row)==len(set(row)): return True
+    if len(row) == len(set(row)):
+        return True
 
 def is_sudoku (rows):
     # check rows
@@ -23,20 +24,22 @@ def is_sudoku (rows):
             return False
     for i in range(len(rows[0])):
         rw = [r[i] for r in rows]
-        if not is_set(rw): return False
+        if not is_set(rw):
+            return False
     # check boxes
     width = int(math.sqrt(len(rows)))
     # there should be 3x3 boxes, or 4x4 if we got funky, etc.
     # boxes will be indices
-    box_coordinates = [[n*width,
-                        (n+1)*width] for n in range(width)]
+    box_coordinates = [[n * width,
+                        (n + 1) * width] for n in range(width)]
     for x in box_coordinates:
         for y in box_coordinates:
             box = []
             for xrow in [rows[ri] for ri in range(*y)]:
                 for i in range(*x):
                     box.append(xrow[i])
-            if not is_set(box): return False
+            if not is_set(box):
+                return False
     return True
 
 class UnsolvablePuzzle (TypeError):
@@ -46,7 +49,7 @@ class UnsolvablePuzzle (TypeError):
 class ConflictError (ValueError):
 
     def __init__ (self, conflict_type, coordinates, value):
-        self.args = conflict_type,coordinates,value
+        self.args = conflict_type, coordinates, value
         self.type = conflict_type
         self.coordinates = coordinates
         self.x = coordinates[0]
@@ -57,94 +60,97 @@ class AlreadySetError (ValueError):
     pass
 
 class SudokuGrid:
-    def __init__ (self, grid=False, verbose=False, group_size=9):
+    def __init__ (self, grid = False, verbose = False, group_size = 9):
         self.grid = []
         self.cols = []
         self.rows = []
         self.boxes = []
         self.group_size = int(group_size)
-        self.verbose=False
-        self.gen_set = set(range(1,self.group_size+1))
+        self.verbose = False
+        self.gen_set = set(range(1, self.group_size + 1))
         for n in range(self.group_size):
             self.cols.append(set())
             self.rows.append(set())
             self.boxes.append(set())
-            self.grid.append([0]*self.group_size)
+            self.grid.append([0] * self.group_size)
         self.box_by_coords = {}
         self.box_coords = {}
         self.calculate_box_coords() # sets box_coords and box_by_coords
         self.row_coords = {}
-        for n,row in enumerate([[(x,y) for x in range(self.group_size)] for y in range(self.group_size)]):
-            self.row_coords[n]=row
+        for n, row in enumerate([[(x, y) for x in range(self.group_size)] for y in range(self.group_size)]):
+            self.row_coords[n] = row
         self.col_coords = {}
-        for n,col in enumerate([[(x,y) for y in range(self.group_size)] for x in range(self.group_size)]):
-            self.col_coords[n]=col
+        for n, col in enumerate([[(x, y) for y in range(self.group_size)] for x in range(self.group_size)]):
+            self.col_coords[n] = col
         if grid:
-            if type(grid)==str:
-                g=re.split("\s+",grid)
+            if type(grid) == str:
+                g = re.split("\s+", grid)
                 side = int(math.sqrt(len(g)))
                 grid = []
                 for row in range(side):
-                    start = row*int(side)
-                    grid.append([int(i) for i in g[start:start+side]])
+                    start = row * int(side)
+                    grid.append([int(i) for i in g[start:start + side]])
             self.populate_from_grid(grid)
-        self.verbose=verbose
+        self.verbose = verbose
 
     def calculate_box_coords (self):
         width = int(math.sqrt(self.group_size))
-        box_coordinates = [[n*width,
-                            (n+1)*width] for n in range(width)]
+        box_coordinates = [[n * width,
+                            (n + 1) * width] for n in range(width)]
         box_num = 0
         for xx in box_coordinates:
             for yy in box_coordinates:
-                self.box_coords[box_num]=[]
+                self.box_coords[box_num] = []
                 for x in range(*xx):
                     for y in range(*yy):
-                        self.box_by_coords[(x,y)]=box_num
-                        self.box_coords[box_num].append((x,y))
+                        self.box_by_coords[(x, y)] = box_num
+                        self.box_coords[box_num].append((x, y))
                 box_num += 1
 
-    def add (self, x, y, val, force=False):
-        if not val: pass
-        if self._get_(x,y):
+    def add (self, x, y, val, force = False):
+        if not val:
+            pass
+        if self._get_(x, y):
             if force:
                 try:
-                    self.remove(x,y)
+                    self.remove(x, y)
                 except:
-                    print 'Strange: problem with add(',x,y,val,force,')'
+                    print 'Strange: problem with add(', x, y, val, force, ')'
                     import traceback
                     traceback.print_exc()
             else:
                 #FIXME:  This is called when the fill button
                 #is clicked multiple times, which causes this exception:
                 #raise AlreadySetError
-                return;
+                return
         if val in self.rows[y]:
-            raise ConflictError(TYPE_ROW,(x,y),val)
+            raise ConflictError(TYPE_ROW, (x, y), val)
         if val in self.cols[x]:
-            raise ConflictError(TYPE_COLUMN,(x,y),val)
-        box=self.box_by_coords[(x,y)]
+            raise ConflictError(TYPE_COLUMN, (x, y), val)
+        box = self.box_by_coords[(x, y)]
         if val in self.boxes[box]:
-            raise ConflictError(TYPE_BOX,(x,y),val)
+            raise ConflictError(TYPE_BOX, (x, y), val)
         # do the actual adding
         self.rows[y].add(val)
         self.cols[x].add(val)
         self.boxes[box].add(val)
-        self._set_(x,y,val)
+        self._set_(x, y, val)
 
     def remove (self, x, y):
-        val = self._get_(x,y)
+        val = self._get_(x, y)
         self.rows[y].remove(val)
         self.cols[x].remove(val)
-        self.boxes[self.box_by_coords[(x,y)]].remove(val)
-        self._set_(x,y,0)
+        self.boxes[self.box_by_coords[(x, y)]].remove(val)
+        self._set_(x, y, 0)
 
-    def _get_ (self, x, y): return self.grid[y][x]
+    def _get_ (self, x, y):
+        return self.grid[y][x]
 
-    def _set_ (self, x, y, val): self.grid[y][x]=val
+    def _set_ (self, x, y, val):
+        self.grid[y][x] = val
 
     def possible_values (self, x, y):
-        return self.gen_set - self.rows[y] - self.cols[x] - self.boxes[self.box_by_coords[(x,y)]]
+        return self.gen_set - self.rows[y] - self.cols[x] - self.boxes[self.box_by_coords[(x, y)]]
 
     def pretty_print (self):
         print 'SUDOKU'
@@ -155,10 +161,10 @@ class SudokuGrid:
         print
 
     def populate_from_grid (self, grid):
-        for y,row in enumerate(grid):
-            for x,cell in enumerate(row):
+        for y, row in enumerate(grid):
+            for x, cell in enumerate(row):
                 if cell:
-                    self.add(x,y,cell)
+                    self.add(x, y, cell)
 
     def __repr__ (self):
         s = "<Grid\n       "
@@ -172,31 +178,31 @@ class SudokuGrid:
         possibilities = {}
         for x in range(self.group_size):
             for y in range(self.group_size):
-                if not self._get_(x,y):
-                    possibilities[(x,y)]=self.possible_values(x,y)
+                if not self._get_(x, y):
+                    possibilities[(x, y)] = self.possible_values(x, y)
         return possibilities
 
-    def find_conflicts (self, x, y, val, conflict_type=None):
+    def find_conflicts (self, x, y, val, conflict_type = None):
         '''Find all squares that conflict with value val at position x,y.
 
         If conflict_type is specified, we only find conflicts of given
         type (ROW, COLUMN OR BOX).
         '''
-        if conflict_type==TYPE_ROW:
+        if conflict_type == TYPE_ROW:
             coords = self.row_coords[y]
-        elif conflict_type==TYPE_COLUMN:
+        elif conflict_type == TYPE_COLUMN:
             coords = self.col_coords[x]
-        elif conflict_type==TYPE_BOX:
-            coords = self.box_coords[self.box_by_coords[(x,y)]]
+        elif conflict_type == TYPE_BOX:
+            coords = self.box_coords[self.box_by_coords[(x, y)]]
         else:
             coords = (self.row_coords[y]
                       + self.col_coords[x]
-                      + self.box_coords[self.box_by_coords[(x,y)]]
+                      + self.box_coords[self.box_by_coords[(x, y)]]
                       )
         conflicting_coordinates = []
-        for x,y in coords:
-            if self._get_(x,y)==val:
-                conflicting_coordinates.append((x,y))
+        for x, y in coords:
+            if self._get_(x, y) == val:
+                conflicting_coordinates.append((x, y))
         return conflicting_coordinates
 
     def to_string (self):
@@ -214,9 +220,9 @@ def is_valid_puzzle (p):
     corrupted puzzles).
     """
     try:
-        p = p.replace(' ','')
-        assert(len(p.replace(' ',''))==81)
-        [int(c) for c in p.replace(' ','')]
+        p = p.replace(' ', '')
+        assert(len(p.replace(' ', '')) == 81)
+        [int(c) for c in p.replace(' ', '')]
     except:
         #import traceback; traceback.print_exc()
         return False
@@ -225,15 +231,17 @@ def is_valid_puzzle (p):
 
 def sudoku_grid_from_string (s):
     """Given an 81 character string, return a grid."""
-    s=s.replace(' ','')
-    assert(len(s)<=GROUP_SIZE**2)
+    s = s.replace(' ', '')
+    assert(len(s)<=GROUP_SIZE ** 2)
     grid = []
     i = 0
     for x in range(GROUP_SIZE):
         row = []
         for y in range(GROUP_SIZE):
-            if len(s) <= i: n = 0
-            else: n = s[i]
+            if len(s) <= i:
+                n = 0
+            else:
+                n = s[i]
             try:
                 n = int(n)
             except:
@@ -249,44 +257,45 @@ def sudoku_grid_from_string (s):
 
 class SudokuSolver (SudokuGrid):
     """A SudokuGrid that can solve itself."""
-    def __init__ (self, grid=False, verbose=False,group_size=9):
+    def __init__ (self, grid = False, verbose = False, group_size = 9):
         self.current_guess = None
-        self.initialized=False
-        SudokuGrid.__init__(self,grid,verbose=verbose,group_size=group_size)
+        self.initialized = False
+        SudokuGrid.__init__(self, grid, verbose = verbose, group_size = group_size)
         self.virgin = SudokuGrid(grid)
         self.guesses = GuessList()
         self.breadcrumbs = BreadcrumbTrail()
         self.backtraces = 0
-        self.initialized=True
+        self.initialized = True
         self.solved = False
         self.trail = []
 
     def auto_fill_for_xy (self, x, y):
         """Fill the square x,y if possible."""
-        possible = self.gen_set - self.rows[y] - self.cols[x] - self.boxes[self.box_by_coords[(x,y)]]
+        possible = self.gen_set - self.rows[y] - self.cols[x] - self.boxes[self.box_by_coords[(x, y)]]
         changed = []
-        if len(possible)==1:
+        if len(possible) == 1:
             val = possible.pop()
-            self.add(x,y,val)
-            return ((x,y),val)
-        if len(possible)==0:
+            self.add(x, y, val)
+            return ((x, y), val)
+        if len(possible) == 0:
             return -1
         # check our column...
-        for coord_set,filled_set in [(self.col_coords[x],self.cols[x]),
-                                     (self.row_coords[y],self.rows[y]),
-                                     (self.box_coords[self.box_by_coords[(x,y)]],
-                                      self.boxes[self.box_by_coords[(x,y)]])
+        for coord_set, filled_set in [(self.col_coords[x], self.cols[x]),
+                                     (self.row_coords[y], self.rows[y]),
+                                     (self.box_coords[self.box_by_coords[(x, y)]],
+                                      self.boxes[self.box_by_coords[(x, y)]])
                                      ]:
             needed_set = self.gen_set - filled_set
             for coord in coord_set:
-                if self._get_(*coord): continue
-                elif (x,y)!=coord:
+                if self._get_(*coord):
+                    continue
+                elif (x, y) != coord:
                     needed_set = needed_set - self.possible_values(*coord)
-            if needed_set and len(needed_set)==1:
+            if needed_set and len(needed_set) == 1:
                 val = needed_set.pop()
                 if val in possible:
-                    self.add(x,y,val)
-                    return ((x,y),val)
+                    self.add(x, y, val)
+                    return ((x, y), val)
                 else:
                     return -1
             if len(needed_set)>1:
@@ -294,8 +303,10 @@ class SudokuSolver (SudokuGrid):
 
     def auto_fill (self):
         changed = []
-        try: changed = self.fill_must_fills()
-        except UnsolvablePuzzle: return changed
+        try:
+            changed = self.fill_must_fills()
+        except UnsolvablePuzzle:
+            return changed
         try:
             changed.extend(self.fill_deterministically())
         finally:
@@ -303,11 +314,11 @@ class SudokuSolver (SudokuGrid):
 
     def fill_must_fills (self):
         changed = []
-        for label,coord_dic,filled_dic in [('Column',self.col_coords,self.cols),
-                                           ('Row',self.row_coords,self.rows),
-                                           ('Box',self.box_coords,self.boxes)]:
-            for n,coord_set in coord_dic.items():
-                needs = dict([(n,False) for n in range(1,self.group_size+1)])
+        for label, coord_dic, filled_dic in [('Column', self.col_coords, self.cols),
+                                           ('Row', self.row_coords, self.rows),
+                                           ('Box', self.box_coords, self.boxes)]:
+            for n, coord_set in coord_dic.items():
+                needs = dict([(n, False) for n in range(1, self.group_size + 1)])
                 for coord in coord_set:
                     val = self._get_(*coord)
                     if val:
@@ -319,48 +330,56 @@ class SudokuSolver (SudokuGrid):
                         for v in self.possible_values(*coord):
                             # if we don't yet have a possible number, plug ourselves in
                             if needs.has_key(v):
-                                if not needs[v]: needs[v]=coord
-                                else: del needs[v]
-                for n,coords in needs.items():
+                                if not needs[v]:
+                                    needs[v] = coord
+                                else:
+                                    del needs[v]
+                for n, coords in needs.items():
                     if not coords:
-                        raise UnsolvablePuzzle('Missing a %s in %s'%(n,label))
+                        raise UnsolvablePuzzle('Missing a %s in %s' % (n, label))
                     else:
                         try:
-                            self.add(coords[0],coords[1],n)
-                            changed.append((coords,n))
+                            self.add(coords[0], coords[1], n)
+                            changed.append((coords, n))
                         except AlreadySetError:
                             raise UnsolvablePuzzle(
-                                "%s,%s must be two values at once!"%(coords)
+                                "%s,%s must be two values at once!" % (coords)
                                 )
         return changed
 
     def fill_deterministically (self):
         poss = self.calculate_open_squares().items()
-        one_choice=filter(lambda x: len(x[1])==1,poss)
+        one_choice = filter(lambda x: len(x[1]) == 1, poss)
         retval = []
-        for coords,choices in one_choice:
-            if self.verbose: print 'Deterministically adding ',coords,choices
+        for coords, choices in one_choice:
+            if self.verbose:
+                print 'Deterministically adding ', coords, choices
             val = choices.pop()
-            self.add(coords[0],coords[1],val)
-            retval.append([(coords[0],coords[1]),val])
-        if self.verbose: print 'deterministically returning ',retval
+            self.add(coords[0], coords[1], val)
+            retval.append([(coords[0], coords[1]), val])
+        if self.verbose:
+            print 'deterministically returning ', retval
         return retval
 
     def solve (self):
         self.auto_fill()
-        while not self.guess_least_open_square(): 1
-        if self.verbose: print 'Solved!\n', self
+        while not self.guess_least_open_square():
+            pass
+        if self.verbose:
+            print 'Solved!\n', self
         self.solved = True
 
     def solution_finder (self):
         self.auto_fill()
-        while not self.guess_least_open_square(): 1
-        self.solved=True
+        while not self.guess_least_open_square():
+            pass
+        self.solved = True
         yield tuple([tuple(r) for r in self.grid[0:]])
         while self.breadcrumbs:
             self.unwrap_guess(self.breadcrumbs[-1])
             try:
-                while not self.guess_least_open_square(): 1
+                while not self.guess_least_open_square():
+                    pass
             except UnsolvablePuzzle:
                 break
             else:
@@ -370,19 +389,22 @@ class SudokuSolver (SudokuGrid):
     def has_unique_solution (self):
         sf = self.solution_finder()
         sf.next()
-        if sf.next(): return False
-        else: return True
+        if sf.next():
+            return False
+        else:
+            return True
 
     def guess_least_open_square (self):
         # get open squares and check them
         poss = self.calculate_open_squares().items()
         # if there are no open squares, we're done!
         if not poss:
-            if self.verbose: print 'Solved!'
+            if self.verbose:
+                print 'Solved!'
             return True
         # otherwise, find the possibility with the least possibilities
-        poss.sort(lambda a,b: len(a[1])>len(b[1]) and 1 or len(a[1])<len(b[1]) and -1 or \
-                  a[0]>b[0] and 1 or a[1]<b[1] and -1 or 0)
+        poss.sort(lambda a, b: len(a[1]) > len(b[1]) and 1 or len(a[1]) < len(b[1]) and -1 or \
+                  a[0] > b[0] and 1 or a[1] < b[1] and -1 or 0)
         least = poss[0]
         # remove anything we've already guessed
         possible_values = least[1] - self.guesses.guesses_for_coord(*least[0])
@@ -394,22 +416,22 @@ class SudokuSolver (SudokuGrid):
             else:
                 raise UnsolvablePuzzle("Unsolvable %s.\n \
                 Out of guesses for %s. Already guessed\n \
-                %s (other guesses are %s)"%(self,
+                %s (other guesses are %s)" % (self,
                                             least[0],
                                             self.guesses.guesses_for_coord(*least[0]),
                                             self.guesses))
         guess = random.choice(list(possible_values))
         # Create guess object
-        guess_obj = Guess(least[0][0],least[0][1],guess)
+        guess_obj = Guess(least[0][0], least[0][1], guess)
         if self.breadcrumbs:
             self.breadcrumbs[-1].children.append(guess_obj)
         self.current_guess = None #reset (we're tracked via guess.child)
-        self.add(least[0][0],least[0][1],guess)
+        self.add(least[0][0], least[0][1], guess)
         self.current_guess = guess_obj # (All deterministic additions
                                        # get added to our
                                        # consequences)
         self.guesses.append(guess_obj)
-        self.trail.append(('+',guess_obj))
+        self.trail.append(('+', guess_obj))
         self.breadcrumbs.append(guess_obj)
         try:
             filled = self.auto_fill()
@@ -423,47 +445,38 @@ class SudokuSolver (SudokuGrid):
             return self.guess_least_open_square()
 
     def unwrap_guess (self, guess):
-        self.trail.append(('-',guess))
-        if self._get_(guess.x,guess.y): self.remove(guess.x,guess.y)
+        self.trail.append(('-', guess))
+        if self._get_(guess.x, guess.y):
+            self.remove(guess.x, guess.y)
         for consequence in guess.consequences.keys():
-            if self._get_(*consequence): self.remove(*consequence)
+            if self._get_(*consequence):
+                self.remove(*consequence)
         for child in guess.children:
             self.unwrap_guess(child)
-            if child in self.guesses: self.guesses.remove(child)
-        if guess in self.breadcrumbs: self.breadcrumbs.remove(guess)
-
-    def print_possibilities (self):
-        poss = self.calculate_open_squares()
-        poss_list = poss.items()
-        poss_list.sort(lambda a,b: len(a[1])>len(b[1]) and 1 or len(a[1])<len(b[1]) and -1 or 0)
-        most_poss = len(poss_list[-1][1])
-        for y in range(len(self.cols)):
-            for x in range(len(self.rows)):
-                if self.grid[y][x]: val = self.grid[y][x]
-                else:
-                    val="".join([str(s) for s in poss[(x,y)]])
-                print self.pad(val,most_poss+2),
-            for n in range(most_poss + 2): print
+            if child in self.guesses:
+                self.guesses.remove(child)
+        if guess in self.breadcrumbs:
+            self.breadcrumbs.remove(guess)
 
     def pad (self, n, pad_to):
         n = str(n)
         padding = int(pad_to) - len(n)
         second_half = padding / 2
         first_half = second_half + padding % 2
-        return " "*first_half + n + " "*second_half
+        return " " * first_half + n + " " * second_half
 
-    def add (self, x,y,val,*args,**kwargs):
+    def add (self, x, y, val, *args, **kwargs):
         if self.current_guess:
-            self.current_guess.add_consequence(x,y,val)
-        SudokuGrid.add(self,x,y,val,*args,**kwargs)
+            self.current_guess.add_consequence(x, y, val)
+        SudokuGrid.add(self, x, y, val, *args, **kwargs)
 
 
 class InteractiveSudoku (SudokuSolver):
     """A subclass of SudokuSolver that provides some convenience
     functions for helping along a human.who is in the midst of
     solving."""
-    def __init__ (self, grid=False, verbose=False, group_size=9):
-        SudokuSolver.__init__(self,grid,verbose,group_size)
+    def __init__ (self, grid = False, verbose = False, group_size = 9):
+        SudokuSolver.__init__(self, grid, verbose, group_size)
 
     def to_string (self):
         return self.virgin.to_string() + '\n' + SudokuSolver.to_string(self)
@@ -472,12 +485,12 @@ class InteractiveSudoku (SudokuSolver):
         """Return a list of impossibilities implied by the users actions."""
         row_cells = self.row_coords[y]
         col_cells = self.col_coords[x]
-        box = self.box_by_coords[(x,y)]
+        box = self.box_by_coords[(x, y)]
         box_cells = self.box_coords[box]
-        for coord_set in [row_cells,col_cells,box_cells]:
+        for coord_set in [row_cells, col_cells, box_cells]:
             broken = []
             # just work on the open squares
-            coord_set = filter(lambda coords: not self._get_(*coords),coord_set)
+            coord_set = filter(lambda coords: not self._get_(*coords), coord_set)
             for coords in coord_set:
                 if not self.possible_values(*coords):
                     broken.append(coords)
@@ -485,15 +498,15 @@ class InteractiveSudoku (SudokuSolver):
 
     def check_for_completeness (self):
         for r in self.rows:
-            if len(r)!=self.group_size:
+            if len(r) != self.group_size:
                 return False
         for c in self.cols:
-            if len(c)!=self.group_size:
+            if len(c) != self.group_size:
                 return False
         return True
 
     def is_changed (self):
-        return (self.grid!=self.virgin.grid)
+        return (self.grid != self.virgin.grid)
 
 class DifficultyRating:
 
@@ -502,17 +515,17 @@ class DifficultyRating:
     medium = _('Medium')
     easy = _('Easy')
 
-    very_hard_range = (0.75,10)
-    hard_range = (0.6,0.75)
-    medium_range = (0.45,0.6)
-    easy_range = (-10,0.45)
+    very_hard_range = (0.75, 10)
+    hard_range = (0.6, 0.75)
+    medium_range = (0.45, 0.6)
+    easy_range = (-10, 0.45)
 
     categories = {'very hard':very_hard_range,
                   'hard':hard_range,
                   'medium':medium_range,
                   'easy':easy_range}
 
-    ordered_categories = ['easy','medium','hard','very hard']
+    ordered_categories = ['easy', 'medium', 'hard', 'very hard']
     label_by_cat = {'easy':easy,
                     'medium':medium,
                     'hard':hard,
@@ -538,9 +551,9 @@ class DifficultyRating:
         else:
             self.instant_elimination_fillable = 0.0
 
-        self.proportion_instant_elimination_fillable = self.instant_elimination_fillable/self.squares_filled
+        self.proportion_instant_elimination_fillable = self.instant_elimination_fillable / self.squares_filled
         # some more numbers that may be crazy...
-        self.proportion_instant_fill_fillable = self.instant_fill_fillable/self.squares_filled
+        self.proportion_instant_fill_fillable = self.instant_fill_fillable / self.squares_filled
         self.elimination_ease = add_with_diminishing_importance(
             self.count_values(self.elimination_fillables)
             )
@@ -550,51 +563,60 @@ class DifficultyRating:
         self.value = self.calculate()
 
     def count_values (self, dct):
-        kk=dct.keys()
+        kk = dct.keys()
         kk.sort()
         return [len(dct[k]) for k in kk]
 
     def calculate (self):
-        return 1 - float(self.fillable_ease)/self.squares_filled \
-                 - float(self.elimination_ease)/self.squares_filled \
-                 + len(self.guesses)/self.squares_filled \
-                 + self.backtraces/self.squares_filled
+        return 1 - float(self.fillable_ease) / self.squares_filled \
+                 - float(self.elimination_ease) / self.squares_filled \
+                 + len(self.guesses) / self.squares_filled \
+                 + self.backtraces / self.squares_filled
 
-    def __repr__ (self): return '<DifficultyRating %s>'%self.value
+    def __repr__ (self):
+        return '<DifficultyRating %s>' % self.value
 
     def pretty_print (self):
-        for name,stat in [('Number of moves instantly fillable by elimination',
+        for name, stat in [('Number of moves instantly fillable by elimination',
                            self.instant_elimination_fillable),
                           ('Percentage of moves instantly fillable by elimination',
-                           self.proportion_instant_elimination_fillable*100),
+                           self.proportion_instant_elimination_fillable * 100),
                           ('Number of moves instantly fillable by filling',
                            self.instant_fill_fillable),
                           ('Percentage of moves instantly fillable by filling',
-                           self.proportion_instant_fill_fillable*100),
+                           self.proportion_instant_fill_fillable * 100),
                           ('Number of guesses made',
                            len(self.guesses)),
                           ('Number of backtraces', self.backtraces),
-                          ('Ease by filling',self.fillable_ease),
-                          ('Ease by elimination',self.elimination_ease),
-                          ('Calculated difficulty',self.value)
+                          ('Ease by filling', self.fillable_ease),
+                          ('Ease by elimination', self.elimination_ease),
+                          ('Calculated difficulty', self.value)
                           ]:
-            print name,': ',stat
+            print name, ': ', stat
 
     def value_string (self):
-        if self.value > self.very_hard_range[0]: return _(self.very_hard)
-        elif self.value > self.hard_range[0]: return _(self.hard)
-        elif self.value > self.medium_range[0]: return _(self.medium)
-        else: return _(self.easy)
+        if self.value > self.very_hard_range[0]:
+            return _(self.very_hard)
+        elif self.value > self.hard_range[0]:
+            return _(self.hard)
+        elif self.value > self.medium_range[0]:
+            return _(self.medium)
+        else:
+            return _(self.easy)
 
     def value_category (self):
         """Get category string, without i18n or capitalization
 
         For use in categorizing category.
         """
-        if self.value > self.very_hard_range[0]: return 'very hard'
-        elif self.value > self.hard_range[0]: return 'hard'
-        elif self.value > self.medium_range[0]: return 'medium'
-        else: return 'easy'
+        if self.value > self.very_hard_range[0]:
+            return 'very hard'
+        elif self.value > self.hard_range[0]:
+            return 'hard'
+        elif self.value > self.medium_range[0]:
+            return 'medium'
+        else:
+            return 'easy'
 
 def get_difficulty_category_name (diff_float):
     return DifficultyRating.label_by_cat.get(
@@ -603,14 +625,14 @@ def get_difficulty_category_name (diff_float):
         )
 
 def get_difficulty_category (diff_float):
-    for category,range in DifficultyRating.categories.items():
+    for category, range in DifficultyRating.categories.items():
         if range[0] <= diff_float < range[1]:
             return category
 
 class SudokuRater (SudokuSolver):
 
-    def __init__ (self, grid=False, verbose=False, group_size=9):
-        self.initialized=False
+    def __init__ (self, grid = False, verbose = False, group_size = 9):
+        self.initialized = False
         self.guessing = False
         self.fake_add = False
         self.fake_additions = []
@@ -618,21 +640,21 @@ class SudokuRater (SudokuSolver):
         self.fill_must_fillables = {}
         self.elimination_fillables = {}
         self.tier = 0
-        SudokuSolver.__init__(self,grid,verbose,group_size)
+        SudokuSolver.__init__(self, grid, verbose, group_size)
 
-    def add (self,*args,**kwargs):
+    def add (self, *args, **kwargs):
         if not self.fake_add:
             if self.initialized and not self.guessing:
                 self.scan_fillables()
                 for delayed_args in self.add_me_queue:
-                    coords = (delayed_args[0],delayed_args[1])
+                    coords = (delayed_args[0], delayed_args[1])
                     if not self._get_(*coords):
-                        SudokuSolver.add(self,*delayed_args)
-                if not self._get_(args[0],args[1]):
-                    SudokuSolver.add(self,*args)
+                        SudokuSolver.add(self, *delayed_args)
+                if not self._get_(args[0], args[1]):
+                    SudokuSolver.add(self, *args)
                 self.tier += 1
             else:
-                SudokuSolver.add(self,*args,**kwargs)
+                SudokuSolver.add(self, *args, **kwargs)
         else:
             self.fake_additions.append(args)
 
@@ -645,15 +667,15 @@ class SudokuRater (SudokuSolver):
             self.fill_must_fills()
         except:
             pass
-        self.fill_must_fillables[self.tier]=set(self.fake_additions[:])-self.filled
+        self.fill_must_fillables[self.tier] = set(self.fake_additions[:]) - self.filled
         self.add_me_queue = self.fake_additions[:]
         self.fake_additions = []
         try:
             self.fill_deterministically()
         except:
             pass
-        self.elimination_fillables[self.tier] = set(self.fake_additions[:])-self.filled
-        self.filled = self.filled|self.fill_must_fillables[self.tier]|self.elimination_fillables[self.tier]
+        self.elimination_fillables[self.tier] = set(self.fake_additions[:]) - self.filled
+        self.filled = self.filled | self.fill_must_fillables[self.tier] | self.elimination_fillables[self.tier]
         self.add_me_queue.extend(self.fake_additions[:])
         self.fake_add = False
 
@@ -662,13 +684,14 @@ class SudokuRater (SudokuSolver):
         return SudokuSolver.guess_least_open_square(self)
 
     def difficulty (self):
-        if not self.solved: self.solve()
+        if not self.solved:
+            self.solve()
         self.clues = 0
         # Add up the number of our initial clues through some nifty mapping calls
-        map(lambda r: map(lambda i: setattr(self,'clues',self.clues.__add__(i and 1 or 0)),
+        map(lambda r: map(lambda i: setattr(self, 'clues', self.clues.__add__(i and 1 or 0)),
                           r),
             self.virgin.grid)
-        self.numbers_added = self.group_size**2 - self.clues
+        self.numbers_added = self.group_size ** 2 - self.clues
         rating = DifficultyRating(self.fill_must_fillables,
                                   self.elimination_fillables,
                                   self.guesses,
@@ -678,12 +701,12 @@ class SudokuRater (SudokuSolver):
 
 
 class GuessList (list):
-    def __init__ (self,*guesses):
-        list.__init__(self,*guesses)
+    def __init__ (self, *guesses):
+        list.__init__(self, *guesses)
 
 
-    def guesses_for_coord (self,x,y):
-        return set([guess.val for guess in filter(lambda guess: guess.x==x and guess.y==y,self)])
+    def guesses_for_coord (self, x, y):
+        return set([guess.val for guess in filter(lambda guess: guess.x == x and guess.y == y, self)])
 
     def remove_children (self, guess):
         removed = []
@@ -696,10 +719,10 @@ class GuessList (list):
     def remove_guesses_for_coord (self, x, y):
         nuking = False
         nuked = []
-        for i in range(len(self)-1):
-            g = self[i-len(nuked)]
-            if g.x==x and g.y == y:
-                nuking=True
+        for i in range(len(self) - 1):
+            g = self[i - len(nuked)]
+            if g.x == x and g.y == y:
+                nuking = True
             if nuking:
                 self.remove(g)
                 nuked += [g]
@@ -708,10 +731,10 @@ class GuessList (list):
 class BreadcrumbTrail (GuessList):
     def append (self, guess):
         # Raise an error if we add something to ourselves twice
-        if self.guesses_for_coord(guess.x,guess.y):
-            raise ValueError("We already have crumbs on %s,%s"%(guess.x,guess.y))
+        if self.guesses_for_coord(guess.x, guess.y):
+            raise ValueError("We already have crumbs on %s, %s" % (guess.x, guess.y))
         else:
-            list.append(self,guess)
+            list.append(self, guess)
 
 class Guess:
     def __init__ (self, x, y, val):
@@ -722,20 +745,20 @@ class Guess:
         self.consequences = {}
 
     def add_consequence (self, x, y, val):
-        self.consequences[(x,y)]=val
+        self.consequences[(x, y)] = val
 
     def __repr__ (self):
-        s =  "<Guess (%s,%s)=%s"%(self.x,self.y,self.val)
+        s =  "<Guess (%s, %s)=%s" % (self.x, self.y, self.val)
         if self.consequences:
             s +=   " implies: "
-            s += ", ".join(["%s->%s"%(k,v) for k,v in self.consequences.items()])
+            s += ", ".join(["%s->%s" % (k, v) for k, v in self.consequences.items()])
         s += ">"
         return s
 
 
-def add_with_diminishing_importance (lst, diminish_by=lambda x: x+1):
+def add_with_diminishing_importance (lst, diminish_by = lambda x: x + 1):
     sum = 0
-    for i,n in enumerate(lst):
+    for i, n in enumerate(lst):
         sum += float(n) / diminish_by(i)
     return sum
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]