dylanmensaert
dylanmensaert

Reputation: 1739

Python | returning a variable

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

Answers (3)

David Heffernan
David Heffernan

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

Jean
Jean

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

arknave
arknave

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

Related Questions