How to fix "not defined", but it is defined? - python

I am coding something with python and I made a main class. I am working with tkinter.
In my class
class Main(tk.Tk):
I have multiple variables. There are two variables, which I defined. Underneath that, there is another variable, that runs the other two variables, I wrote above. But then it says, that those are not defined, but it is. The Error message: name 'bruteforceABC' is not defined
class Main(tk.Tk):
def bruteforceABC():
for length in range(1, 3): # only do lengths of 1 + 2
to_attempt = product(chars, repeat=length)
for attempt in to_attempt:
print(''.join(attempt))
def clear1():
list = window.grid_slaves()
for n in list:
n.destroy()
def clearforce():
bruteforceABC()
clear1()
I don't know, why it says, it is not defined. Because I've defined it. What can I do, that I don't get this error?
Thank you, for your help!

You have defined these functions as class methods but are calling them as generic ones. You should use self.method() to call them.
class Main(tk.Tk):
#staticmethod
def bruteforceABC():
for length in range(1, 3): # only do lengths of 1 + 2
to_attempt = product(chars, repeat=length)
for attempt in to_attempt:
print(''.join(attempt))
#staticmethod
def clear1():
list = window.grid_slaves()
for n in list:
n.destroy()
def clearforce(self):
self.bruteforceABC()
self.clear1()
Like this

Related

Problem finding array entry based on object attribute

i have been having problems with a function useing an object as an input, but not knowing the position of the object, so i have made a stripped down version of the code to exemplyfi
sett = []
class Test:
def __init__(self, name, number):
self.name = name
self.num = num
#staticmethod
def howmany(who):
print(who.number)
sett.append(Test('dog', 2))
sett.append(Test('cat', 5))
sett.append(Test('fish', 7))
Test.howmany(sett.index(Test.name == 'dog'))
if it worked at intended this would output '2' as that is the number of the object with name 'dog'.
pleas help thanks
Your code has a mix up between num and number. Besides that necessary fix, the index method returns ... an index, not a member of sett. Moreover, Test.name is wrong: Test is your class object, not an instance. You could use the next function to get a matching item.
As a side note: you can just create the list of three items in one go. There is no reason to call append repeatedly:
class Test:
def __init__(self, name, number):
self.name = name
self.number = number # fix
#staticmethod
def howmany(who):
print(who.number)
sett = [Test('dog', 2), Test('cat', 5), Test('fish', 7)]
Test.howmany(next(test for test in sett if test.name == 'dog'))
Another note: it is not clear to me why you want to define howmany as a static method and not as an instance method, unless you would foresee that who could be None, but that logic is currently missing.

What is causing an AttributeError with my Python code when I compile it?

I am attempting to write code that allows me to pass in a number that increases or decreases in my Square class. When compiling the code I am given this error:
AttributeError: 'Square' object has no attribute 'change_size'.
Entered code:
class Square():
def __init__(self,s1):
self.s1=s1
def calculate_perimeter(self):
return self.s1*4
def change_size(self,new_size):
self.s1+=new_size
a_square= Square(100)
Interaction:
>>> print(a_square.s1)
100
>>> a_square.change_size(200)
Does the code you posted above have identical indentation to your actual code? If so, the issue is likely caused by the fact that in Python, indentation does actually matter. That is:
class Square():
def init(self, s1):
self.s1 = s1
.
.
.
is not the same as
class Square():
def init(self, s1):
self.s1 = s1
.
.
.
You can see a longer explanation, and more examples, in the PEP8 style guide.
Please change the Indentation,
class Square():
def __init__(self,s1):
self.s1=s1
def calculate_perimeter(self):
return self.s1*4
def change_size(self,new_size):
self.s1+=new_size
return self.s1
a_square= Square(100)
Result:
a_square.s1
100
a_square.change_size(100)
200
Please let me know if you have any questions, i would be very happy to help you.
Few things:
1) use the code formatting blocks to help your make your code more readable
2) remove the += when changing size of the attribute because an augmented assignment operator will add the value to the existing value
3) establish the attribute s1 before you use it in the class
Try something like:
class Square():
s1 = 0
def init(self,s1):
self.s1=s1
def calculate_perimeter(self):
return self.s1*4
def change_size(self,new_size):
self.s1 = new_size
a_square = Square()
print(a_square.calculate_perimeter())
a_square.change_size(5)
print(a_square.calculate_perimeter())

Managing classes in Python programming

UPDATE
Tells me that TypeError: __init__() missing 1 required positional argument: 'storlek'
My class
class Hanterare:
def __init__(self, storlek):
self.storlek =storlek
My functions
def fråga_storlek():
try:
Hanterare().storlek =int(input('Choose size'))
except ValueError:
print("Wrong try again!!")
fråga_storlek()
And I want to use the value, the user has chosen and call them into my other functions for example:
def getNewBoard():
board = []
for i in range(fråga_storlek()):
board.append([' '] * fråga_storlek())
Unless I'm missing a notation, Q is a terrible name. Variable and method names should be in lowercase, and describe the purpose of the variable. board_width would be a much better name.
Having a method with the same name as a class member is confusing. Since you're asking for the board size, I'd rename the method to something like ask_board_size.
After taking the above into consideration, the problem solves itself:
class BoardHandler(self, board_size):
self.board_size = board_size
def ask_board_size(self):
try:
self.board_size = int(input("Choose size please"))
except ValueError:
print("Wrong try again!")
ask_board_size()
And is that constructor a new notation? It should probably use __init__:
class BoardHandler:
def __init__(self, board_size):
self.board_size = board_size
...
No, to create a field in a class, you should declare it in a function called __init__(self). Like so:
class BoardHandler:
def __init__(self, Q):
self.Q = Q
You can also take input upon creation instead of having it as a parameter, like so:
class BoardHandler:
def __init__(self):
self.Q = int(input("What size would you prefer?"))
You don't want to use:
class BoardHandler:
self.Q = 5 #some number
unless you want the board size to be the same across all BoardHandlers.
Then you can access it in other methods of the class by just using self.Q.
To use it outside the class, here's how:
b_size = int(input("What size?"))
bh = BoardHandler(b_size)
print("The board size is: " + str(bh.Q))

AttributeError: 'list' object has no attribute 'assignmentScores'

I don't understand the meaning of this problem or how to fix it!
I keep getting the problem AttributeError: 'list' object has no attribute 'assignmentScores'
What does this mean? and how do I fix this issue?
My code is:
class Student:
studentName = ""
studentCourse = ""
averageMark = 0
grade = "none"
assignmentScores = [1, 2, 3, 4]
def __init__(self, n, c, a, g,m):
self.studentName = n
self.studentCourse = c
self.averageMark = a
self.grade = g
self.assignmentScores = m
def getName(self):
return self.studentName
def getCourse(self):
return self.studentCourse
def getAverage(self):
return self.averageMark
def getGrade(self):
return self.grade
def getMarks(self):
return self.assignmentScores
def setAverage(self):
mark = self.averageMark
return mark
def setGrade(self):
grade = self.grade
return grade
def setMarks(self):
marks = self.setMarks()
return marks
def addMark(self):
score = list.append(self, self.assignmentScores)
def calculateAverage(self):
if len(self.assignmentScores) > 0:
average = sum(self) / float(len(self.assignmentScores))
return average
else:
return 0
def determineGrade(self):
return 0
print(calculateAverage(assignmentScores))
First, please use 4 spaces for all indentation, it helps a lot. PEP 8 is your friend and will keep everyone friendly and helpful.
As for your problem, after running the code myself and looking at the traceback, it looks like you assigned the self.assignmentScores list to self itself, so when you type self.assignmentScores you are looking up an attribute of self, which is now a list instead of an instance of the class.
This mistake comes from the way you called the method:
calculateAverage(assignmentScores)
This method only requires one argument, which is supposed to be an instance of the class Student, but not only are you calling the method directly from the class instead of from an instance, you are using the assignmentScores list as an argument for the method. This makes it so that the method calculateAverage() replaces self with self.assignmentScores so when you try to check if the list is empty the code is reading it as self.assignmentScore.assignmentScore instead of the intended way.
The way you have the class defined at the moment strongly encourages you to call the method like this.
billy = Student("","",0,"none",[1,2,3,4])
print(billy.calculateAverage())
There is another error standing in your way after you solve this problem, but a good look at the traceback and a careful reading of the relevant code will lead you to the solution. Right now all you need is a better understanding of classes and calling methods work.

Get the return value from a function in a class in Python

I am trying to simply get the value out of my class using a simple function with a return value, I'm sure its a trivial error, but im pretty new to python
I have a simply class set up like this:
class score():
#initialize the score info
def __init__(self):
self.score = 0
self.num_enemies = 5
self.num_lives = 3
# Score Info
def setScore(num):
self.score = num
# Enemy Info
def getEnemies():
return self.num_enemies
# Lives Info
def getLives():
return self.getLives
etc.....
Than I create an instance of the class as such:
scoreObj = score()
for enemies in range(0, scoreObj.getEnemies):
enemy_sprite.add(enemy())
I get the error saying that an integer is expected, but it got an instancemethod
What is the correct way to get this information?
Thanks!
scoreObj.getEnemies is a reference to the method. If you want to call it you need parentheses: scoreObj.getEnemies().
You should think about why you are using a method for this instead of just reading self.num_enemies directly. There is no need for trivial getter/setter methods like this in Python.
The first parameter for a member function in python is a reference back to the Object.
Traditionally you call it "self", but no matter what you call the first parameter, it refers back to the "self" object:
Anytime I get weird errors about the type of a parameter in python, I check to see if I forgot the self param. Been bit by this bug a few times.
class score():
#initialize the score info
def __init__(self):
self.score = 0
self.num_enemies = 5
self.num_lives = 3
# Score Info
def setScore(self, num):
self.score = num
# Enemy Info
def getEnemies(self):
return self.num_enemies
# Lives Info
def getLives(foo): #foo is still the same object as self!!
return foo.num_lives
#Works but don't do this because it is confusing
This code works:
class score():
def __init__(self):
self.score = 0
self.num_enemies = 5
self.num_lives = 3
def setScore(self, num):
self.score = num
def getEnemies(self):
return self.num_enemies
def getLives(self):
return self.getLives
scoreObj = score()
for enemy_num in range(0, scoreObj.getEnemies()):
print enemy_num
# I don't know what enemy_sprite is, but
# I commented it out and just print the enemy_num result.
# enemy_sprite.add(enemy())
Lesson Learned:
Class functions must always take one parameter, self.
That's because when you call a function within the class, you always call it with the class name as the calling object, such as:
scoreObj = score()
scoreObj.getEnemies()
Where x is the class object, which will be passed to getEnemies() as the root object, meaning the first parameter sent to the class.
Secondly, when calling functions within a class (or at all), always end with () since that's the definition of calling something in Python.
Then, ask yourself, "Why am I not fetching 'scoreObj.num_lives' just like so instead? Am I saving processing power?" Do as you choose, but it would go faster if you get the values directly from the class object, unless you want to calculate stuff at the same time. Then your logic makes perfect sense!
You made a simple mistake:
scoreObj.getEnemies()
getEnemies is a function, so call it like any other function scoreObj.getEnemies()

Categories

Resources