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))
Related
I'm in doubt with this program of mine with inheritance, I don't know if I understand the concept wrong or the code is wrong (maybe both), but I really need some help.
The other functions are working, the only problem is when I try to access the Saving class function by the Account (Subclass).
class Savings:
def __init__(self):
self.money = 0
self.statement = []
def apply(self, value):
self.money += value
self.statement.append(("Apply", f"${value}"))
class Accounts(Savings):
def __init__(self, client: Client, bank: Bank):
super().__init__()
#other variables
def change_money(self):
print("3 - Apply in Savings")
choose = int(input("Choose: "))
elif choose == 3:
value = float(input("Value to apply: $").replace(",", "."))
super().apply(value)
print(super().money)
else:
pass
And when I try to access the money variable, it says
super().money
AttributeError: 'super' object has no attribute 'money'
I made a test using only Accounts as Object and the money variable changed,
Input:
a = Accounts()
a.change_money()
a.money
Output
3 - Apply in Savings
Choose: 3
Value to apply: $100
100.0
but Accounts and Savings are different classes and I need to access it and change from the Subclass
Please, can anyone help me ?
You can use self.apply(value) instead:
class Savings:
def __init__(self):
self.money = 0
self.statement = []
def apply(self, value):
self.money += value
self.statement.append(("Apply", f"${value}"))
class Accounts(Savings):
def change_money(self):
value = float(input("Value to apply: $"))
self.apply(value)
print(self.money)
a = Accounts()
a.change_money() # input, say, 10
print(a.statement) # [('Apply', '$10.0')]
Your object a inherits the method apply attached to itself, so a can call its own method by self.apply.
You don’t need to call super as it is a pre defined function and is part of the savings accounts class. Just call self.apply(value)
I am trying to add new objects to a class(emne) but the new instances of the class needs to be created using user input. So i need a way to be able to chose the name for the object and set some of the values of the objects with user input.
I have already tried to create a function that passes the value of the user input into a x = emner(x) to create it but it only returns:
AttributeError: 'str' object has no attribute 'fagKode'
so i think my issue is that the value of the input is created as a string so that it is not understood as a way to create the function
emne=[]
class Emne:
def __init__(self,fagKode):
self.fagKode = fagKode
self.karakter = ""
emne.append(self)
def leggTilEmne():
nyttEmne = input("test:")
nyttEmne=Emne(nyttEmne)
expected result is that the code creates a new instance of the class.
If by choosing a name you mean your fagKode attribute, what you need is:
fagKode = input('Enter code: ')
Emne(fagKode)
You're adding the instances of Enme to the list in the constructor, so you don't need to save them to a variable.
Alternatively, you can handle that in the function:
emne=[]
class Emne:
def __init__(self,fagKode):
self.fagKode = fagKode
self.karakter = ""
def leggTilEmne():
nyttEmne = input("test:")
enme.append(Emne(nyttEmne))
I'm not sure what exactly you are asking, since you haven't responded to the comments. So,
emne=[]
class Emne:
def __init__(self,fagKode):
self.fagKode = fagKode
self.karakter = ""
emne.append(self)
def leggTilEmne(self, value): # <--- is this what you want
self.nyttEmne= Emne(value)
This is an example of when to use a class method. __init__ should not be appending to a global variable, though. Either 1) have the class method append to a class attribute, or 2) have it return the object and let the caller maintain a global list.
emne = []
class Emne:
emne = []
def __init__(self, fag_kode):
self.fag_kode = fag_kode
self.karakter = ""
#classmethod
def legg_til_emne_1(cls):
nytt_emne = input("test:")
cls.emne.append(cls(nytt_emne))
#classmethod
def legg_til_emne_2(cls):
nyttEmne = input("test:")
return cls(nyttEmne)
Emne.legg_til_emne_1() # Add to Emne.emne
e = Emne.legg_til_emne_2()
emne.append(e)
I am creating a class to make some calculations. The class would have 3 arguments to get started. I have done like this in a simplified representation:
class TheCalcs:
def __init__(self, pk_from_db, cat_score_list, final_score):
self.pk_from_db = pk_from_db
self.cat_score_list = cat_score_list
self.final_score = final_score
def calculate_cat_score(self):
#Do some calcs with the data of the pk_from_db and return that!
a_list_of_scores = [] # create a list of scores
return a_list_of_scores
def final_score(self): # The argument for this function would be the return of the calculate_cat_score function!
# Again do some calcs and return the final score
the_final_score = int()
return the_final_score
def score_grade(self): # the argument this this function again the return but now from the final_score function
# Do some cals and return the grade
the_grade = ("a string", "an integer")
return the_grade
When I call the class I would have to present the arguments --> However as you can see I just do now the value of the first argument. The second and the third being calculated throughout the class. When I call the class just with one argument I will of course have an error of failing arguments. Anyone has an idea on that?
If those values are calculated, simply don't make them arguments. You could instead call those calculation methods to compute the values:
class TheCalcs:
def __init__(self, pk_from_db):
self.pk_from_db = pk_from_db
self.cat_score_list = self.calculate_cat_score()
self.final_score = self.calculate_final_score()
# ...
or postpone calculations until you need them.
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()
I am writing a program to add to and update an address book. Here is my code:
EDITED
import sys
import os
list = []
class bookEntry(dict):
total = 0
def __init__(self):
bookEntry.total += 1
self.d = {}
def __del__(self):
bookEntry.total -= 1
list.remove(self)
class Person(bookEntry):
def __init__(self, n):
self.n = n
print '%s has been created' % (self.n)
def __del__(self):
print '%s has been deleted' % (self.n)
def addnewperson(self, n, e = '', ph = '', note = ''):
self.d['name'] = n
self.d['email'] = e
self.d['phone'] = ph
self.d['note'] = note
list.append()
def updateperson(self):
key = raw_input('What else would you like to add to this person?')
val = raw_input('Please add a value for %s' % (key))
self.d[key] = val
def startup():
aor = raw_input('Hello! Would you like to add an entry or retrieve one?')
if aor == 'add':
info = raw_input('Would you like to add a person or a company?')
if info == 'person':
n = raw_input('Please enter this persons name:')
e = raw_input('Please enter this persons email address:')
ph = raw_input('Please enter this persons phone number:')
note = raw_input('Please add any notes if applicable:')
X = Person(n)
X.addnewperson(n, e, ph, note)
startup()
When I run this code I get the following error:
in addnewperson
self.d['name'] = n
AttributeError: 'Person' object has no attribute 'd'
I have two questions:
UPDATED QUESTIONS
1. why isnt the d object being inherited from bookentry()?
I know this question/code is lengthy but I do not know where to go from here. Any help would be greatly appreciated.
The addnewperson shoud have 'self' as first argument; actually, the name doesn't matter ('self' is just a convention), but the first argument represent the object itself. In your case, it's interpreting n as the "self" and the other 3 as regular arguments.
____del____ must not take arguments besides 'self'.
Edit: BTW I spotted a few other problems in your example, that maybe you're not aware of:
1) d in bookentry is a class member, not an instance member. It's shared by all bookentry's instances. To create an instance member, use:
class bookentry(dict):
def __init__(self,n):
self.d = {}
# rest of your constructor
2) you're trying to access d directly (as you would do in Java, C++ etc), but Python doesn't support that. You must have a 'self' parameter in your methods, and access instance variables through it:
class person(bookentry):
def foo(self,bar):
self.d[bar] = ...
person().foo(bar)
Update: for the last problem, the solution is to call the super constructor (which must be done explicitly in Python):
class Person(bookEntry):
def __init__(self, n):
super(Person, self).__init__()
self.n = n
print '%s has been created' % (self.n)
A brief explanation: for people with background in OO languages without multiple inheritance, it feels natural to expect the super type constructor to be called implicitly, automatically choosing the most suitable one if no one is mentioned explicitly. However, things get messy when a class can inherit from two or more at the same time, for this reason Python requires the programmer to make the choices himself: which superclass constructor to call first? Or at all?
The behavior of constructors (and destructors) can vary wildly from language to language. If you have further questions about the life cycle of Python objects, a good place to start would be here, here and here.
why isnt the d object being inherited from bookentry()?
That's because __init__ of the bookEntry is not called in the __init__ of the Person:
super(Person, self).__init__()
BTW, why inherit from dict if its functionality is not used? It's better to remove it and inherit from object instead (also class names are usually CamelCased):
class BookEntry(object):