1

As a way of practicing python I'm trying to write a little program that creates sudoku puzzles. I've found multiple questions similar to my issue but none seem to exactly relate.

#!usr/bin/python3
from random import randint


class Puzzle :
    def __init__(self, **puzzle): 
        puzzle = [[0 for x in range(9)]for y in range(9)]

    def createEasy(self):
        count = 0
        while(count < 32):
            i = randint(0,8)
            j = randint(8,9)
            k = randint(1,9)
            if (self.puzzle[i][j] != 0):
                self.puzzle[i][j] = k
                count += 1

    def createMedium(self):
        count = 0
        while(count < 30):
            i = randint(0,8)
            j = randint(8,9)
            k = randint(1,9)
            if (self.puzzle[i][j] != 0):
                self.puzzle[i][j] = k
                count += 1
    def createHard(self):
        count = 0
        while(count < 26):
            i = randint(0,8)
            j = randint(8,9)
            k = randint(1,9)
            if (self.puzzle[i][j] != 0):
                self.puzzle[i][j] = k
                count += 1


    def main():
        print("Welcome to sudoku!!!")
        answer = input( "what level of difficultly do you want today?")
        if (answer == "easy"):
            self.createEasy()
            for x in Puzzle.puzzle:
                for y in x:
                    print(y)
                print('\n')

Puzzle.main()

Most answers I found either had to do with functions not being defined in the right order or not putting "self" in the parameter list of all the functions. One answer even said to get rid of "self" parameter in the init function but that didn't help either. I also found this answer though I don't think it relates either. NameError: name 'self' is not defined The only thing I can think of is that I need to declare the list called puzzle elsewhere since it's suppose to be a class variable but from python code I've I don't think that's true not to I'm not sure since it's 2d and writing puzzle = [][] is wrong.

Sorry here's the whole output with error.

Welcome to sudoku!!!
what level of difficultly do you want today?easy
Traceback (most recent call last):
  File "sudoku_maker.py", line 49, in <module>
    Puzzle.main()
  File "sudoku_maker.py", line 43, in main
    self.createEasy(self)
NameError: name 'self' is not defined
codehelp4
  • 132
  • 1
  • 2
  • 15

3 Answers3

1

The error disappears if you make the following changes:

  1. Add self as a parameter of the main() function.
  2. Create an instance of the class: p = Puzzle() and call p.main() then.
  3. Write self.puzzle in the __init__ function instead of just puzzle.

(Then there are different errors though not related to this one)

lawful_neutral
  • 633
  • 8
  • 29
1

First of all, in __init__ method when you declare puzzle attribute, you forgot the self, so it is not declared:

def __init__(self, **puzzle): 
    self.puzzle = [[0 for x in range(9)] for y in range(9)]

You also forgot de self when declaring the main function. And, inside of this one you got an error too, when you call Puzzle.puzzle, it should be with the self instance:

def main(self):
    print("Welcome to sudoku!!!")
    answer = input( "what level of difficultly do you want today? ")
    if (answer == "easy"):
        self.createEasy()
        for x in self.puzzle:
            for y in x:
                print(y)
            print('\n')

And finally, when you call the function. You need to create the instance of Puzzle first, but you are using Puzzle.main, so your not initializing the object, so the self instance will not exist.

You have to do it like this:

Puzzle().main()

However, there's another error when using randint(a, b), because this function generate a random int between a and b, but including the limits, so when you call it in createEasy, the 9 should not be in the limits.

  • Thanks for the info. I'm surprised I never saw it written that way between all the other questions I saw on here. – codehelp4 Aug 14 '17 at 02:38
1

It seems like you want main() to be a class method or a static method rather than an instance method. Class methods are methods that are not bound to an object but to a class. In that case, you need to define it clearly.

https://docs.python.org/3.5/library/functions.html#classmethod https://docs.python.org/3.5/library/functions.html#staticmethod

This answer clearly explains the difference between class methods and static methods. What is the difference between @staticmethod and @classmethod in Python?

One more way of solving your problem is :

  1. Make main() as an instance method by passing self as an argument.

    main(self)
    
  2. Create an object of Puzzle.

    puzzle = Puzzle()
    
  3. Call the object's main method.

    puzzle.main()
    
Will_of_fire
  • 1,089
  • 4
  • 12
  • 24
  • I ended up doing this although I think I was trying to avoid creating an object of the class by calling the class name directly and although you can by writing Puzzle().main() I decided to just create an object despite the fact that I understand why there're parenthesis after the word Puzzle. – codehelp4 Aug 14 '17 at 02:37