Reputation: 1739
I read and understand the whole article described in other question.
My problem is regarding this source code.
the author returns values in function assign:
def assign(values, s, d):
"""Eliminate all the other values (except d) from values[s] and propagate.
Return values, except return False if a contradiction is detected."""
other_values = values[s].replace(d, '')
if all(eliminate(values, s, d2) for d2 in other_values):
return values
else:
return False
But assign is never used to set existing variable values in calling function parse_grid(grid):
def parse_grid(grid):
values = dict((s, digits) for s in squares)
for s,d in grid_values(grid).items():
if d in digits and not assign(values, s, d):
return False ## (Fail if we can't assign d to square s.)
return values
So returning values seems rather unnecessary to me. Since he only uses assign() as a boolean, can't he just return true instead?
I understood that returning a value doesn't change anything about the original variable. Only if the variable is passed as parameter and changed there without getting rebound to another variable, only then does the 'original' variable change because it holds the same reference.
However the return values
in def parse_grid(grid
) should be a totally changed values then the one at the start of the function. When does this get assigned?
Question:
Where does values
in def parse_grid(grid
) get changed? Because this function returns values and this returned values should not be the same as the one set at start of this function. So where did it get changed and how?
It is called for example like this: display(parse_grid(grid2))
Upvotes: 0
Views: 6452
Reputation: 613003
Let us take a look at this function:
def parse_grid(grid):
values = dict((s, digits) for s in squares)
for s,d in grid_values(grid).items():
if d in digits and not assign(values, s, d):
return False ## (Fail if we can't assign d to square s.)
return values
Here the function returns a new dict
. It returns it so that the caller can do something with it. The function doesn't return True
because the caller wants to obtain and use that new dict
.
Upvotes: 2
Reputation: 7673
In the code you display, assign seems underused. You are right: it is only used to check the validity of the values (a no-contradiction test). So, as you say, returning true would do the trick.
But since assign can do more, why cripple it? It may be useful elsewhere in the code.
Edit: and it actually is. Looking at the linked code the function search
calls it and uses the return values.
Upvotes: 1
Reputation: 613
The assign function is called multiple times. For example, in the search function:
def search(values):
"Using depth-first search and propagation, try all possible values."
if values is False:
return False ## Failed earlier
if all(len(values[s]) == 1 for s in squares):
return values ## Solved!
## Chose the unfilled square s with the fewest possibilities
n,s = min((len(values[s]), s) for s in squares if len(values[s]) > 1)
return some(search(assign(values.copy(), s, d))
for d in values[s])
The return value of assign is passed into search to continue the depth-first-search.
Upvotes: 2