Python - Classes - Self Not Defined - python

Below I'm attempting to make a simple Keygen as a first project. Somewhere I'm getting the error the Self has not been defined.
I'm guessing it's probably something easy
import random
class KeyGenerator():
def __init__(self):
length = 0
counter = 0
key = []
Letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
def KeyGen4(self):
while self.counter != self.length:
a = random.choice(self.Letters)
print a #test
r = (random.randint(0,1))
print r #test
if r == True:
a = a.upper()
else:
pass
self.key.append(a)
self.counter += 1
s = ''
self.key = s.join(key)
print self.key
return self.key
def start(self):
selection = raw_input('[K]eygen4, [C]ustom length Keygen or [N]umbers? >')
if selection == 'K' or 'k':
length = 4
keyGen4(self)
elif selection == 'N' or 'n':
KeyGenN(self)
elif selection == 'C' or 'c':
length = int(raw_input("Key Length: "))
#KeyGen4(self) # Change later after creating method with more options
start(self)

Your indention is wrong, but I assume this is only a copy-pasting issue.
That start(self) at the bottom doesn't make sense,
and indeed self is not defined there. You should create an instance of the class, and then call its start method:
KeyGenerator().start()
# or
key_gen = KeyGenerator()
key_gen.start()

You have two problems:
you miss indentation on every class-function
you must create an object of the class before you can call any of its functions
Your class should look like this
import random
class KeyGenerator():
def __init__(self):
length = 0
counter = 0
key = []
Letters = ['a','b','c','d','e']
def KeyGen4(self):
while self.counter != self.length:
a = random.choice(self.Letters)
print a #test
r = (random.randint(0,1))
print r #test
if r == True:
a = a.upper()
else:
pass
self.key.append(a)
self.counter += 1
s = ''
self.key = s.join(key)
print self.key
return self.key
def start(self):
selection = raw_input('[K]eygen4, [C]ustom length Keygen or [N]umbers? >')
if selection == 'K' or 'k':
length = 4
self.keyGen4()
elif selection == 'N' or 'n':
self.KeyGenN()
elif selection == 'C' or 'c':
length = int(raw_input("Key Length: "))
#KeyGen4(self) # Change later after creating method with more options
#now make an instance of your class
my_key_gen = KeyGenerator()
my_key_gen.start()
Please note that when calling class functions inside the class, you need to use self.FUNCNAME. All class functions should take "self" as argument. If that is their only argument then you simply call them with self.func(). If they take arguments you still ommit the self, as self.func(arg1, arg2)

Related

class self acts like integer

I didn't understand why. And It will raise an error 'int' object has no attribute 'v', but I want to access the self.v. When I print only self it will print some numbers. I couldn't understand what was going on. Here is my code.
class Candidate:
def __init__(self,val,pscore,nscore):
self.v = val
self.p = pscore
self.n = nscore
def __str__(self):
return f"{self.v} ({self.p},{self.n})"
def check_plus_pos(self, guessval):
count = 0
b = self.v
a = str(b)
guessval = str(guessval)
for i in range(0,len(a)):
if a[i] == guessval[i]:
count += 1
return count
def check_neg_pos(self, guessval):
count = 0
b = self.v
a = str(b)
guessval = str(guessval)
for i in range(0,len(a)):
for j in range(0,len(guessval)):
if a[i] == guessval[j] and a[i] != guessval[i]:
count += 1
return count
def consistent(self, guess):
if Candidate.check_plus_pos(self,guess.v) == guess.p and Candidate.check_neg_pos(self,guess.v) == guess.n:
return True
else:
return False
The problem occurs at b == self.v I wanted to assign the self.v value to a variable.
To be honest it's pretty hard to understand what that code/class is supposed to do, imho it needs some serious refactoring.
My guess is you should:
instantiate your class somewhere
use the method as an instance method, so invoke it with self and not the class name
do NOT pass self explicitly at all
do NOT use abbreviations which are not commonly known
do NOT use single letter variables a means literally nothing
use docstrings for non-trivial functions (or as a rule of thumb to most of functions/methods)
use type hints, which will help you catch this kind of errors automatically (if you configure your IDE that is)
get rid of the assignment to b at all, it's not reused and doesn't seem do anything. This will do the same a = str(self.v)
... # all the class related code above
def check_neg_pos(self, guessval):
count = 0
a = str(self.v)
guessval = str(guessval)
for i in range(0,len(a)):
for j in range(0,len(guessval)):
if a[i] == guessval[j] and a[i] != guessval[i]:
count += 1
return count
def is_consistent(self, guess: Candidate)->bool:
return bool(self.check_plus_pos(guess.v) == guess.p and self.check_neg_pos(guess.v) == guess.n)
# Example usage
candidate_1 = Candidate(1,2,3)
candidate_2 = Candidate(4,5,6)
candidates_consistent = candidate_1.is_consistent(guess=candidate_2)
print(candidates_consistent)

Why is this code running twice? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am writing a Neural Net program to play connect four in python, and training it using existing minimax algorithms. I have written some basic code to establish communication between two algorithms. Following lines should result in one game between the two programs :-
game = ConnectFour()
game.start_new()
However, the game is played twice. ("IA is the winner" is printed twice.)
I added some debug print lines. There's a lot of code, but I cannot figure out the point where the problem is. So I am posting all of it. I suspect import statements, but do not know what is the problem exactly.
ConnectFourAIb.py:
from minimax2b import ConnectFour
def get_AI_move(grid):
i = 0
while grid[0][i]!=' ':
i += 1
return i
game = ConnectFour()
game.start_new()
minimax2b.py:
import os
import random
import time
from abc import ABCMeta, abstractmethod
CONNECT_FOUR_GRID_WIDTH = 7
CONNECT_FOUR_GRID_HEIGHT = 6
CONNECT_FOUR_COLORS = ["x","o"]
class ConnectFour(object):
_GRID_WIDTH = CONNECT_FOUR_GRID_WIDTH
_GRID_HEIGHT = CONNECT_FOUR_GRID_HEIGHT
_grid = None
_round = None
_finished = False
_winner = None
_current_player = None
_players = [None, None]
_COLORS = CONNECT_FOUR_COLORS
def __init__(self):
print("__init__")
self._round = 1
self._finished = False
self._winner = None
self._players[0] = _HumanPlayer(self._COLORS[0])
self._players[1] = _ComputerPlayer(self._COLORS[1])
for i in xrange(2):
print('%s play with %s ' % (self._players[i]._type, self._COLORS[i]))
self._current_player = self._players[random.randint(0, 1)]
self._grid = []
for i in xrange(self._GRID_HEIGHT):
self._grid.append([])
for j in xrange(self._GRID_WIDTH):
self._grid[i].append(' ')
def start(self):
print("start")
while not self._finished:
self._next_move()
def start_new(self):
print("start_new")
self._round = 1
self._finished = False
self._winner = None
self._current_player = self._players[random.randint(0, 1)]
self._grid = []
for i in xrange(self._GRID_HEIGHT):
self._grid.append([])
for j in xrange(self._GRID_WIDTH):
self._grid[i].append(' ')
self.start()
def _switch_player(self):
print("_switch_player")
if self._current_player == self._players[0]:
self._current_player = self._players[1]
else:
self._current_player = self._players[0]
def _next_move(self):
print("_next_move")
column = self._current_player.get_move(self._grid)
for i in xrange(self._GRID_HEIGHT - 1, -1, -1):
if self._grid[i][column] == ' ':
self._grid[i][column] = self._current_player._color
self._check_status()
if self._finished:
self._print_state()
return 1
self._switch_player()
self._round += 1
return 1
print("This column is full. Please choose an other column")
return
def _check_status(self):
print("_check_status")
if self._is_full():
self._finished = True
elif self._is_connect_four():
self._finished = True
self._winner = self._current_player
def _is_full(self):
print("_is_full")
return self._round > self._GRID_WIDTH * self._GRID_HEIGHT
def _is_connect_four(self):
print("_is_connect_four")
for i in xrange(self._GRID_HEIGHT - 1, -1, -1):
for j in xrange(self._GRID_WIDTH):
if self._grid[i][j] != ' ':
# check for vertical connect four
if self._find_vertical_four(i, j):
return True
return False
def _find_vertical_four(self, row, col):
print("_find_vertical_four")
consecutive_count = 0
if row + 3 < self._GRID_HEIGHT:
for i in xrange(4):
if self._grid[row][col] == self._grid[row + i][col]:
consecutive_count += 1
else:
break
if consecutive_count == 4:
if self._players[0]._color == self._grid[row][col]:
self._winner = self._players[0]
else:
self._winner = self._players[1]
return True
return False
def _print_state(self):
print("_print_state")
if self._finished:
print("Game Over!")
if self._winner != None:
print(str(self._winner._type) + " is the winner!")
else:
print("Game is a draw")
class _Player(object):
__metaclass__ = ABCMeta
_type = None
_color = None
def __init__(self, color):
self._color = color
#abstractmethod
def get_move(self, grid):
pass
class _HumanPlayer(_Player):
def __init__(self, color):
super(_HumanPlayer, self).__init__(color)
self._type = "Human"
def get_move(self, grid):
from ConnectFourAIb import get_AI_move
return get_AI_move(grid)
class _ComputerPlayer(_Player):
_DIFFICULTY = 5
def __init__(self, color,_DIFFICULTY=5):
super(_ComputerPlayer, self).__init__(color)
self._DIFFICULTY = _DIFFICULTY
self._type = "IA"
def get_move(self, grid):
return 4
There's still too much code to go all the way through, but at least one thing is suspicious. You start the game with a module-level call to ConnectFour in ConnectFourAIb.py. But your _HumanPlayer.get_move method imports ConnectFourAIb again; this will re-trigger the two lines at the end of that file.
To fix this, use the if __name__ == '__main__' trick:
if __name__ == '__main__':
game = ConnectFour()
game.start_new()
This ensures that those lines are only called when the file is run from the command line, not when it is imported.
(As an aside, please drop all those leading underscores. They don't add anything and just make your code harder to read.)

My code can't find the file

I have written a program that has to execute a file and draw it in turtle.
But when I try to call a fdl filename it cant find it.
import turtle
#I start out making the basic turtle commands
def lt (turtle, n):
turtle.lt(n)
def fd (turtle, n):
turtle.fd(n)
def bk (turtle, n):
turtle.bk(n)
def rt (turtle, n):
turtle.rt(n)
#Then i create a class that makes it possible to create a set of rules
class Rule(object):
#Here the rule based on a description string is initialized like ("F -> F L F L")
def __init__(self,repr):
#This is where the left and right part of the rule in "F -> F L F L" comes in
self.left, self.right = [a.strip() for a in repr.split("->")]
if self.left is None or self.right is None:
print("Invalid rule description!")
#Now i use the same princip like i did in task6. the Apply function
def apply_rule_on_elements(self,element):
return [self._apply_rule_for_element (element) for element in elements]
#This is a helper function that only works on one element at a time
def _apply_rule_for_element (self,element):
if element == self.left:
return self.right.split()
return element
#Here is a very simple helper function, handy in some cases
#This allows one to perform assignment multiple values og grouping
def split_command(command, *args):
return command, args
#Now i make a command class that wraps the execution of a given command
class Command(object):
def __init__(self,command):
#the name and number of arguments for the given command
self.name,self.args = split_command(*command.split())
def execute(self,turtle,length):
if self.name == "lt":
lt(turtle,int(self.args[0]))
elif self.name == "scale":
length[0] = length[0]*float(self.args[0])
elif self.name == "fd":
fd(turtle,length[0])
elif self.name == "bk":
bk(turtle,length[0])
elif self.name == "rt":
rt(turtle,int(self.args[0]))
elif self.name == "nop":
pass
#Here i write the main Fractal class
class Fractal(object):
def __init__(self):
#Initial and current state
self.state = []
#Rules associated with the current fractal
self.rules = []
#Commands associated with the current fractal
self.commands = {}
#since values are immutable and passed by value, I use an array (passed by reference value)
#to allow the modification of the variable
self.length = [0]
#The current depth
self.depth = 0
#Executes the command associated w/ the current states stored in the fractal
def execute_commands(self,turtle,states):
for state in states:
self.commands[state].execute(turtle,self.length)
#Flattens a list
def _flatten(self,l):
flattened_list = []
for element in l:
flattened_list.extend(element)
return flattened_list
#Here i compute the fractal, which does that actual iteration work
#It returns the state of the fractal after the computation
def compute(self):
current_depth = self.depth
current_state = self.state
while self.depth !=0:
current_state=self.compute_next_state(current_state)
self.depth-=1
return current_state
def _compute_next_state(self,state):
for rule in self.rules:
state = rule.apply_rule_on_elements(state)
return self._flatten(state)
#This parses the fdl file, creates a fractal and set it up with the values
#read in the fdl file
def read_fdl(filename):
import os
f = Fractal()
if os.path.exists(filename):
lines = open(filename).readlines()
for line in lines:
if not len(line.strip())==0:
name,arguments = split_command(*line.strip().split())
if name == "start":
f.state = arguments
elif name == "rule":
f.rules.append(Rule("".join(arguments)))
elif name =="length":
f.length = [int(arguments[0])]
elif name == "depth":
f.depth = int(arguments[0])
elif name == "cmd":
f.commands[arguments[0]] = Command("".join (arguments[1:]))
else:
print("File does not exist")
#no check is made, to see if we have a fractal that was completely initialized
return f
import sys
import turtle
if len(sys.argv)>1:
f=read_fdl(sys.argv[1])
f.execute_commands(turtle,f.compute())
read_fdl("sierpinski")
The message I get is "File does not exist", but it does.
No, it doesn't exist - at least not in the current directory and without an extension.
Try adding the right directory and extension to the name "sierpinski"
Given that this is an fdl (fractal definition language) file, try:
read_fdl("sierpinski.fdl")

Python function which needs to return a Class, returns None

So guys I have this class. It's a Treasure generator of static classes which return a Spell class, Weapon class, mana or health potion value.
The problem is, when I return the Value it returns None, but if I replace it with print, instead of return, then in prints it with no problems exactly as it in str function. How can I return the type, so it doesn't show me None ?
from random import randint
from weapon_class import Weapon
from spell_class import Spell
class Treasure:
#staticmethod
def generate_random_index(limit):
rand_index = randint(0, int(limit))
return rand_index
#staticmethod
def return_generated_treasure(max_mana, max_health):
# generate num from 0-3
rand_gen_num = Treasure.generate_random_index(3)
options = {
0: Treasure.generate_spell,
1: Treasure.generate_weapon,
2: Treasure.generate_mana_pot,
3: Treasure.generate_health_pot
}
# give arguments for mana and health potion functions only (for now)
if rand_gen_num == 2:
options[rand_gen_num](max_mana)
elif rand_gen_num == 3:
options[rand_gen_num](max_health)
else:
# call other functions, which doesn't need arguments,
# like generate spell and weapon
options[rand_gen_num]()
#staticmethod
def generate_spell():
with open('spell_names.txt', 'r') as f:
database_spell_names = f.read().replace('\n', '').split(',')
lst_len = len(database_spell_names) - 1
# generate number in range 0 - <spell names length>
rand_gen_num = Treasure.generate_random_index(lst_len)
spell_name = database_spell_names[rand_gen_num]
spell_mana_cost = randint(5, 35)
spell_damage = randint(5, 40)
cast_range = randint(1, 3)
# return spell
return Spell(spell_name, spell_damage, spell_mana_cost, cast_range)
#staticmethod
def generate_weapon():
with open('weapon_names.txt', 'r') as f:
database_weapon_names = f.read().replace('\n', '').split(',')
lst_len = len(database_weapon_names) - 1
rand_gen_num = Treasure.generate_random_index(lst_len)
weapon_name = database_weapon_names[rand_gen_num]
weapon_damage = randint(5, 40)
# return weapon
return Weapon(weapon_name, weapon_damage)
#staticmethod
def generate_mana_pot(max_mana):
max_possible_mana_limit = max_mana * 1/2
mana_portion = randint(0, int(max_possible_mana_limit))
return mana_portion
#staticmethod
def generate_health_pot(max_health):
max_possible_health_limit = max_health * 1/3
health_portion = randint(0, int(max_possible_health_limit))
return health_portion
def main():
award = Treasure.return_generated_treasure(100, 100)
print (award)
if __name__ == '__main__':
main()
return_generated_treasure doesn't return anything - there's no return keyword there.
You need to make outputs of other functions global. As they are returned within the function, their returns become local, and are then not propagated through the class or further returned.

Calling a method from the same class

I'm writing a class for a simple game of 4 in a row, but I'm running into a problem calling a method in the same class. Here's the whole class for the sake of completeness:
class Grid:
grid = None
# creates a new empty 10 x 10 grid
def reset():
Grid.grid = [[0] * 10 for i in range(10)]
# places an X or O
def place(player,x,y):
Grid.grid[x][y] = player
# returns the element in the grid
def getAt(x,y):
return Grid.grid[x][y]
# checks for wins in a certain direction
def checkLine(player,v,count,x,y):
x = x+v[0]
y = y+v[1]
if x < 0 or x > 9:
return
if y < 0 or y > 9:
return
if Grid.grid[x][y] == p:
count = count+1
if count == 4:
return True
checkLine(player,v,count,x,y)
return False
# returns the number of the player that won
def check():
i = 'i'
for x in range(0,10):
for y in range(0,10):
if Grid.grid[x][y] > 0:
p = Grid.grid[x][y]
f = checkLine(p,0,array(i,[1,0]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[0,1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[1,1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,0]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[0,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[1,-1]),x,y)
if f:
return p
f = checkLine(p,0,array(i,[-1,1]),x,y)
if f:
return p
return 0
reset = staticmethod(reset)
place = staticmethod(place)
getAt = staticmethod(getAt)
check = staticmethod(check)
checkLine = staticmethod(checkLine)
I'm trying to call checkLine() from check(), but I get the error "NameError: global name 'checkLine' is not defined". When I call Grid.checkLine() instead, I get "TypeError: 'module' object is not callable"
How do I call checkLine()?
EDIT:
#beer_monk
class Grid(object):
grid = None
# creates a new empty 10 x 10 grid
def reset(self):
Grid.grid = [[0] * 10 for i in range(10)]
# places an X or O
def place(self,player,x,y):
Grid.grid[x][y] = player
# returns the element in the grid
def getAt(self,x,y):
return Grid.grid[x][y]
# checks for wins in a certain direction
def checkLine(self,player,v,count,x,y):
x = x+v[0]
y = y+v[1]
if x < 0 or x > 9:
return
if y < 0 or y > 9:
return
if Grid.grid[x][y] == p:
count = count+1
if count == 4:
return True
checkLine(self,player,v,count,x,y)
return False
# returns the number of the player that won
def check(self):
i = 'i'
for x in range(0,10):
for y in range(0,10):
if Grid.grid[x][y] > 0:
p = Grid.grid[x][y]
for vx in range(-1,2):
for vy in range(-1,2):
f = self.checkLine(p,0,array(i,[vx,vy]),x,y)
if f:
return p
return 0
reset = staticmethod(reset)
place = staticmethod(place)
getAt = staticmethod(getAt)
check = staticmethod(check)
checkLine = staticmethod(checkLine)
Get rid of the class. Use plain functions and module level variable for grid.
The class is not helping you in any way.
PS. If you really want to call checkline from within the class, you'd call Grid.checkline. For example:
class Foo:
#staticmethod
def test():
print('Hi')
#staticmethod
def test2():
Foo.test()
Foo.test2()
prints
Hi
Syntax:
class_Name.function_Name(self)
Example:
Turn.checkHoriz(self)
A reworked example (hopefully showing a better use of classes!)
import itertools
try:
rng = xrange # Python 2.x
except NameError:
rng = range # Python 3.x
class Turn(object):
def __init__(self, players):
self.players = itertools.cycle(players)
self.next()
def __call__(self):
return self.now
def next(self):
self.now = self.players.next()
class Grid(object):
EMPTY = ' '
WIDTH = 10
HEIGHT = 10
WINLENGTH = 4
def __init__(self, debug=False):
self.debug = debug
self.grid = [Grid.EMPTY*Grid.WIDTH for i in rng(Grid.HEIGHT)]
self.player = Turn(['X','O'])
def set(self, x, y):
if self.grid[y][x]==Grid.EMPTY:
t = self.grid[y]
self.grid[y] = t[:x] + self.player() + t[x+1:]
self.player.next()
else:
raise ValueError('({0},{1}) is already taken'.format(x,y))
def get(self, x, y):
return self.grid[y][x]
def __str__(self):
corner = '+'
hor = '='
ver = '|'
res = [corner + hor*Grid.WIDTH + corner]
for row in self.grid[::-1]:
res.append(ver + row + ver)
res.append(corner + hor*Grid.WIDTH + corner)
return '\n'.join(res)
def _check(self, s):
if self.debug: print("Check '{0}'".format(s))
# Exercise left to you!
# See if a winning string exists in s
# If so, return winning player char; else False
return False
def _checkVert(self):
if self.debug: print("Check verticals")
for x in rng(Grid.WIDTH):
winner = self._check([self.get(x,y) for y in rng(Grid.HEIGHT)])
if winner:
return winner
return False
def _checkHoriz(self):
if self.debug: print("Check horizontals")
for y in rng(Grid.HEIGHT):
winner = self._check([self.get(x,y) for x in rng(Grid.WIDTH)])
if winner:
return winner
return False
def _checkUpdiag(self):
if self.debug: print("Check up-diagonals")
for y in rng(Grid.HEIGHT-Grid.WINLENGTH+1):
winner = self._check([self.get(d,y+d) for d in rng(min(Grid.HEIGHT-y, Grid.WIDTH))])
if winner:
return winner
for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
if winner:
return winner
return False
def _checkDowndiag(self):
if self.debug: print("Check down-diagonals")
for y in rng(Grid.WINLENGTH-1, Grid.HEIGHT):
winner = self._check([self.get(d,y-d) for d in rng(min(y+1, Grid.WIDTH))])
if winner:
return winner
for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
if winner:
return winner
return False
def isWin(self):
"Return winning player or False"
return self._checkVert() or self._checkHoriz() or self._checkUpdiag() or self._checkDowndiag()
def test():
g = Grid()
for o in rng(Grid.WIDTH-1):
g.set(0,o)
g.set(Grid.WIDTH-1-o,0)
g.set(Grid.WIDTH-1,Grid.HEIGHT-1-o)
g.set(o,Grid.HEIGHT-1)
print(g)
return g
g = test()
print g.isWin()
Unlike java or c++, in python all class methods must accept the class instance as the first variable. In pretty much every single python code ive seen, the object is referred to as self. For example:
def reset(self):
self.grid = [[0] * 10 for i in range(10)]
See http://docs.python.org/tutorial/classes.html
Note that in other languages, the translation is made automatically
There are multiple problems in your class definition. You have not defined array which you are using in your code. Also in the checkLine call you are sending a int, and in its definition you are trying to subscript it. Leaving those aside, I hope you realize that you are using staticmethods for all your class methods here. In that case, whenever you are caling your methods within your class, you still need to call them via your class's class object. So, within your class, when you are calling checkLine, call it is as Grid.checkLine That should resolve your NameError problem.
Also, it looks like there is some problem with your module imports. You might have imported a Module by name Grid and you have having a class called Grid here too. That Python is thinking that you are calling your imported modules Grid method,which is not callable. (I think,there is not a full-picture available here to see why the TypeError is resulting)
The best way to resolve the problem, use Classes as they are best used, namely create objects and call methods on those objects. Also use proper namespaces. And for all these you may start with some good introductory material, like Python tutorial.
Instead of operating on an object, you are actually modifying the class itself. Python lets you do that, but it's not really what classes are for. So you run into a couple problems
-You will never be able to make multiple Grids this way
the Grid can't refer back to itself and e.g. call checkLine
After your grid definition, try instantiating your grid and calling methods on it like this
aGrid = Grid()
...
aGrid.checkLine()
To do that you, you first need to modify all of the method definitions to take "self" as your first variable and in check, call self.checkLine()
def check(self):
...
self.checkLine()
...
Also, your repeated checking cries out for a FOR loop. You don't need to write out the cases.
Java programmer as well here, here is how I got it to call an internal method:
class Foo:
variable = 0
def test(self):
self.variable = 'Hi'
print(self.variable)
def test2(self):
Foo.test(self)
tmp = Foo()
tmp.test2()

Categories