-1

I am creating a SuDuko Generator, and am trying to distribute my 1's to every single box. To do this, I have created a list with two items (acting a coordinates). After the function has run, it returns a list such as [a, 1]. I then want a quick way to assign a variable a1 to 1 (a1 would be the variable I would want if [a, 1] was returned and 1 because I'm trying to distribute my 1's). Is there a way to do this? If so how? Here is the source code:

import random
def func():
    rows1 = ['a', 'b', 'c']
    rows2 = ['d', 'e', 'f']
    rows3 = ['g', 'h', 'i']
    columns1 = [1, 2, 3]
    columns2 = [4, 5, 6]
    columns3 = [7, 8, 9]
    letter1 = random.choice(rows1)
    number1 = random.choice(columns1)
    random1 = [letter1, number1]
    rows1.remove(letter1)
    columns1.remove(number1)
    letter2 = random.choice(rows1)
    number2 = random.choice(columns2)
    random2 = [letter2, number2]
    rows1.remove(letter2)
    columns2.remove(number2)
    letter3 = random.choice(rows1)
    number3 = random.choice(columns3)
    random3 = [letter3, number3]
    columns3.remove(number3)
    letter4 = random.choice(rows2)
    random4 = [letter4, number4]
    rows2.remove(letter4)
    columns1.remove(number4)
    letter5 = random.choice(rows2)
    number5 = random.choice(columns2)
    random5 = [letter5, number5]
    rows2.remove(letter5)
    columns2.remove(number5)
    letter6 = random.choice(rows2)
    number6 = random.choice(columns3)
    random6 = [letter6, number6]
    columns3.remove(number6)
    letter7 = random.choice(rows3)
    number7 = random.choice(columns1)
    random7 = [letter7, number7]
    rows3.remove(letter7)
    letter8 = random.choice(rows3)
    number8 = random.choice(columns2)
    random8 = [letter8, number8]
    rows3.remove(letter8)
    letter9 = random.choice(rows3)
    number9 = random.choice(columns3)
    random9 = [letter9, number9]
    return  (random1, random2, random3)    #etc

Thanks in advance

  • 2
    What's your question? – Blender Feb 28 '13 at 20:46
  • 1
    How to assign `a1` to `1` or `c3` to `1`, depending on what the function returns, sorry if I didn't make that clear @Blender –  Feb 28 '13 at 20:51
  • 1
    So if the function returns `random1` as `[a, 1]`, I want a quick way to assign `a1` to `1` –  Feb 28 '13 at 20:55
  • 1
    You almost certainly don't want to do this. Just create a `dict` for your cells, then set `cells['a'][1]` instead of `a1`. See [this question](http://stackoverflow.com/questions/2320945/python-using-vars-to-assign-a-string-to-a-variable) and about a dozen others. – abarnert Feb 28 '13 at 21:00
  • @Lewis: You need to create some sort of data structure. I'd try making a `Sudoku` class and start giving it some useful methods. – Blender Feb 28 '13 at 21:01

1 Answers1

0

I then want a quick way to assign a variable a1 to 1 (a1 would be the variable I would want if [a, 1] was returned and 1 because I'm trying to distribute my 1's). Is there a way to do this?

Yes, there is a way to do this, but no, you do not want to. The right thing to do is this:

Instead of creating 81 different variables, create one data structure, which can be indexed.

The most obvious choice is a dict that uses (row, col) pairs as keys.

First, for a dict:

cells = {}
cells['a', '1'] = 1

The downside here is that the cells don't exist until you fill them in. You can pre-fill them like this:

cells = {(letter, digit): None for letter in 'abcdefghi' for digit in '123456789'}

Or you can use a defaultdict, or use the setdefault function in place of [].

You could also use some kind of explicit 2D object, like a list of lists, or a numpy.array, etc., but then you'll need some way to convert a letter and digit into a pair of array coordinates:

cells = [[None for _ in range(9)] for _ in range(9)]

def getcell(letter, digit):
    return cells[letter - ord('a')][int(digit) - 1]

def setcell(letter, digit, value):
    cells[letter - ord('a')][int(digit) - 1] = value

       

You may realize that this is starting to look complex enough that it might be worth wrapping up in a class. If so, you're right. Something like this:

class Board(object):
    def __init__(self):
        self.cells = [[None for _ in range(9)] for _ in range(9)]
    def map_coords(self, letter, digit):
        return letter - ord('a'), int(digit) - 1
    def getcell(self, letter, digit):
        row, col = self.map_coords(letter, digit)
        return self.cells[row][col]
    def setcell(self, letter, digit, value):
        row, col = self.map_coords(letter, digit)
        self.cells[row][col] = value

Now you can just do this:

board = Board()
board.setcell('a', '1') = 1
XORcist
  • 4,288
  • 24
  • 32
abarnert
  • 354,177
  • 51
  • 601
  • 671