Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
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.
Improve this question
So I created a set of libraries that makes it easier for me to track my LoL Stats over the course of the season, for that I have a class game:
class game:
def __init__(self,kills,deaths,assists,pos,champ,cs,tk,wl,length = time(0,20,0)):
self.k = kills
self.a = assists
self.d = deaths
self.l = length
self.p = pos
self.c = champ
self.cs = cs
self.tk = tk
self.wl = wl
and a class gl (GameList)
class gl:
def __init__(self):
self.ki = []
self.ass = []
self.de = []
self.ch = []
self.po = []
self.le = []
self.csc = []
self.tki = []
self.wil =[]
Now when I use the method self.add() in the gl class where g is an object of the class game:
def add(self,g):
self.ki.append(g.k)
self.ass.append(g.a)
self.de.append(g.d)
self.ch.append(g.c)
self.po.append(g.p)
l = g.l.traM()
self.le.append(l)
self.csc.append(g.cs)
self.tki.append(g.tk)
if game.wl == True:
self.wil.append("Win")
else:
self.wil.append("Loss")
I get the Error: AttributeError: 'tuple' object has no attribute 'k'
Now when I tried this earlier it worked fine and I have no Idea why it stopped working the only thing that change was that I installed matplotlib and used that to create a few methods involving piecharts.
I would be happy if someone could help me out and maybe provide a solution, since I am fairly new to python but programmed in Pascal before.
Since you're new to Python, if you haven't already met type() let me introduce you :-) The type() function will show you what something is. To troubleshoot your code try adding some print statements like this:
def add(self,g):
print('add() type(g)={}'.format(type(g)))
print('add() g={}'.format(g))
self.ki.append(g.k)
self.ass.append(g.a)
self.de.append(g.d)
Once you find out what kind of thing g is go ahead and edit your question and let us know. Like #Graipher says it is probably something different than you expect.
Once you get that working, from a design point of view it seems easier to keep a list of Game instances instead of a list of all the individual attributes.
class gl2:
def __init__(self):
self.games = [ ] # list to hold games
def __str__(self):
return 'gl2(#games={})'.format(len(self.games)))
def add(self, g):
self.games.add(g)
Adding __str__() methods can make it much easier to see what your classes are doing. You might want to add one to your game class, if nothing else just to make debugging easier:
class game:
def __str__(self):
return 'game(#kills={})'.format(len(self.k)))
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am trying to improve my object oriented programming skills. So I did this practice in python in which I try to create a cake object. However I have a doubt as to whether I am doing things correctly.
I need this class handle a list of ingredients.For this I created an empty list and a method that receives as a parameter an Ingredent object instance.
#Define a ingredient.
class Ingredient:
#Constructor of ingredient
def __init__(self, name,measure):
#Name of ingredient
self.name = name
#unit of measurement
self.measure = measure
class IngredientQuantity(Ingredient):
def __init__(self,name,measure,quantity):
'''
Here we are having access to methods and attributes from
the parent class. Now we can set attribute values and access to
methods.
'''
super().__init__(name,measure)
#Define quantity of ingredient.
self.quantity = quantity
#Define a list of ingredients.
class IngredentsList:
def __init__(self):
#Empty list that will be populated with ingredients.
self.listOfIngredients = []
#Add a new ingredient to list.
def addIngredent(self,ingredient):
print('adding ' + str(ingredient.quantity) + ' ' + ingredient.measure + ' of ' + ingredient.name + '...')
self.listOfIngredients.append(ingredient)
Here is how I pass parameters...
ilist = IngredentsList()
ilist.addIngredent(IngredientQuantity('ingredient','piece',1))
I'm not sure this is the best way to do it. Then I would like to hear an opinion.
I also have doubts about how to treat this class in a UML diagram. This class is not inherited from any other. How could I relate it?
Thanks in advance.
An ingredient is just a string. Doesn't need a class.
A measurement, on the otherhand includes a unit and a quantity (e.g. 2 TBSP). So, create a class for that
from dataclasses import dataclass
#dataclass
class Measurement:
unit: str
quantity: float
Then you want to store a list of ingredients with measurements, so you can use a list of tuples
recipe = [
('Apples', Measurement(None, 1.0))
('Cinnamon', Measurement('tbsp', 2.0))
]
If you really wanted to create other classes, you could, but the relationships as far as UML goes is composition and aggregation, not inheritance.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I made a class with some functions:
But when I instantiate the values the answer is bringing me 'alimentos', but that's wrong it should be 'portugues' .
I have two dictionaries and this class:
professores_x = {
'alimentos': [{"prof_id":"xx_alimento_1", "prof_disc":"alimentos"},
{"prof_id":"xx_alimento_2", "prof_disc":"alimentos"}],
'português': [{"prof_id":"xx_port_1", "prof_disc":"português"},
{"prof_id":"xx_port_2", "prof_disc":"português"}]}
courses_x = {'alimentos': [{"course_name":"padeiro_confeiteiro"},
{"course_name":"padeiro_confeiteiro"}]}
# trying refactoring
class Disciplinas_cursos_1:
"Define the disciplinas and professors"
def __init__(self,cursos_,professores_):
self.cursos_ = cursos_
self.professores_ = professores_
for self.p in self.cursos_.keys():
if self.p == 'alimentos': self.alimentos()
elif self.p == 'português': self.portugues()
def alimentos(self):
profiel_prof_disc = self.professores_[self.p][::]
prof_disc_al = self.p
discipl_alimentos = [self.p,[x['prof_id'] for x in profiel_prof_disc
if x['prof_disc'] == prof_disc_al]]
return discipl_alimentos
def portugues(self):
print("Now its portuguese turn")
profiel_prof_disc = self.professores_[self.p][::]
prof_disc_port = self.p
print(f"see I'm printing {prof_disc_port}. It's that the same of portuguese? If' not it's wrong")
discipl_port =[self.p,[x['prof_id'] for x in profiel_prof_disc if x['prof_disc'] ==prof_disc_port]]
print(f"see I'm printing {prof_disc_port} and {discipl_port}")
return discipl_port
# ok!! Now I do the instance:
disc_a = Disciplinas_cursos_1(courses_x, professores_x)
disc_a.alimentos()
Output
['alimentos', ['xx_alimento_1', 'xx_alimento_2']]
Nice, that is what I want but when I try the second function it's bring me 'alimentos'
but I need 'portugues' and not 'alimentos'.
disc_a.portugues()
Output
Now its portuguese turn
see I'm printing alimentos. It's that the same of portuguese? If' not it's wrong
see I'm printing alimentos and ['alimentos', ['xx_alimento_1', 'xx_alimento_2']]
Your issue is with self.p. In __init__, you're setting that value with your loop, and when you call self.alimentos() or self.portugues() in the body of the loop it will make sense since the self.p value will correspond to the method being called.
But if you call disc_a.portugues() from outside of __init__, you're going to get the last value self.p had after the loop, which may not match up at all with the method you're calling. That's why you're getting invalid output, it's using an inappropriate self.p key.
I don't have a firm understanding of what you're intending to do in your methods, so I don't really have a recommended fix. But in general, I'd suggest you think more carefully about which values you're passing to which parts of your code as attributes and as arguments. self.p should probably not exist as an attribute. Maybe it should be an argument to the methods? Maybe you need different attributes to sort your data into separate containers, rather than repeatedly looping over it all. You may need to redesign your class to have its data make more sense the way you need to use it.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to have a black box in python where
The input is a list A.
There is a random number C for the black box which is randomly selected the first time the black box is called and stays the same for the next times the black box is called.
Based on list A and number C, the output is a list B.
I was thinking of defining this black box as a function but the issue is that a function cannot keep the selected number C for next calls. Note that the input and output of the black box are as described above and we cannot have C also as output and use it for next calls. Any suggestion?
Make it a Class so C will persist.
class BlackBox():
def __init__(self):
self.C = rand.randint(100)
etc...
As a side note, using some pretty cool Python functionality...
You can make objects of this class callable by implementing __call__() for your new class.
#inside the BlackBox class
def __call__(self, A):
B = []
#do something to B with A and self.C
return B
You can then use this in your main code.
bb = BlackBox()
A = [1, 2, 3]
B = bb(A)
the issue is that a function cannot keep the selected number C for next calls.
This may be true in other languages, but not so in Python. Functions in Python are objects like any other, so you can store things on them. Here's a minimal example of doing so.
import random
def this_function_stores_a_value():
me = this_function_stores_a_value
if 'value' not in me.__dict__:
me.value = random.random()
return me.value
This doesn't directly solve your list problem, but it should point you in the right direction.
Side note: You can also store persistent data in optional arguments, like
def this_function_also_stores_a_value(value = random.random()):
...
I don't, however, recommend this approach because users can tamper with your values by passing an argument explicitly.
There are many ways to store persistent data for a function. They all have their uses, but in general, the ones that come first are useful more often than the ones that come later. (To keep things shorter, I'm solving a slightly simpler problem than the one you asked about, but it should be obvious how to adapt it.)
Instance attribute
class BlackBox:
def __init__(self):
self.C = rand.randint(100)
def check(self, guess):
return (guess - self.C) / abs(guess - self.C)
Now you can create one or more BlackBox() instances, and each one has its own random number.
Closure variable
def blackbox():
C = rand.random()
def check(guess):
return (guess - C) / abs(guess - C)
return check
Now, you can create one or more check functions, and each one has its own random number. (This is dual to the instance variable—that is, it has the same capabilities—but usually one or the other is more readable.)
Global variable
def makeblackbox():
global C
C = random.randint(100)
def check(guess):
return (guess - C) / abs(guess - C)
This way, there's only a single blackbox for the entire program. That's usually not as good a design, which is one of the reasons that "globals are bad". Plus, it's polluting the global namespace with a C variable that means nothing to anyone but the check function, which is another one of the reasons that "globals are bad".
Function attribute
def makeblackbox():
check.C = random.randint(100)
def check():
return (guess - check.C) / abs(guess - check.C)
This is equivalent to a global in that you can only ever have one black box, but at least the variable is hidden away on the check function instead of polluting the global namespace.
Class attribute
class BlackBox:
C = rand.randint(100)
#staticmethod
def check(guess):
return (guess - BlackBox.C) / abs(guess - BlackBox.C)
This is again equivalent to a global variable without polluting the global namespace. But it has a downside over the function attribute—you're creating a class that has no useful instances is often misleading.
Class attribute 2
class BlackBox:
C = rand.randint(100)
#classmethod
def check(cls, guess):
return (guess - cls.C) / abs(guess - cls.C)
This is different from the last three in that you can create new blackboxes by creating subclasses of BlackBox. But this is very rarely what you actually want to do. If you want multiple persistent values, you probably want instances.
Since you are asking in the comments.
This is probably not recommended way but it's easy and works so I'll add it here.
You can use global variable to achieve your goal.
import random
persistant_var = 0
def your_func():
global persistant_var
if persistant_var:
print('variable already set {}'.format(persistant_var))
else:
print('setting variable')
persistant_var = random.randint(1,10)
your_func()
your_func()
Output:
setting variable
variable already set 7
Hope this is clear.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have the following class:
class Gene(object):
"""
Represents transcripts.
Called gene for convenience, but the class actually represents different transcripts of genes.
"""
def _set_start_end(strand, start_position, end_position):
if strand == '-':
return end_position, start_position
else:
return start_position, end_position
def __init__(self, transcript_name, gene_name, chromosome, strand, start_position, end_position):
self.transcript_name = transcript_name
self.gene_name = gene_name
self.chromosome = chromosome
self.strand = strand
self.start_position, self.end_position = _get_start_end(strand, start_position, end_position)
When I try to instantiate this class with refgene = Gene("NM_016166", "PIAS1", "Chr15", "-" "68346571", "68480404"), Python keeps complaining that I have one argument too few:
Traceback (most recent call last):
refgene = Gene("NM_016166", "PIAS1", "Chr15", "-" "68346571", "68480404")
TypeError: __init__() takes exactly 7 arguments (6 given)
Why? I am surely not mean to send self to the constructor?
Ps. Python 2.7.8 :: Anaconda 2.0.0 (64-bit)
You missed a comma:
Gene("NM_016166", "PIAS1", "Chr15", "-" "68346571", "68480404"),
# ^
Making that one string as Python concatenates two strings separated only by whitespace:
>>> 'foo' 'bar'
'foobar'
Add in the comma:
Gene("NM_016166", "PIAS1", "Chr15", "-", "68346571", "68480404"),
Next problem is that your _set_start_end function is not going to work; you either need to make it a method, or move it out of the class. If it is a method, you need to add self in two places; one to call it and one to receive the bound instance:
self.start_position, self.end_position = self._get_start_end(strand, start_position, end_position)
and:
def _set_start_end(self, strand, start_position, end_position):
Yes, this question has been asked before. No, none of the answers I read could fix the problem I have.
I'm trying to create a little Bounce game. I've created the bricks like this:
def __init__(self,canvas):
self.canvas = canvas
self.brick1 = canvas.create_rectangle(0,0,50,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick2 = canvas.create_rectangle(50,0,100,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick3 = canvas.create_rectangle(100,0,150,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick4 = canvas.create_rectangle(150,0,200,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick5 = canvas.create_rectangle(200,0,250,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick6 = canvas.create_rectangle(250,0,300,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick7 = canvas.create_rectangle(300,0,350,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick8 = canvas.create_rectangle(350,0,400,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick9 = canvas.create_rectangle(400,0,450,20,fill=random_fill_colour(),outline=random_fill_colour())
self.brick10 = canvas.create_rectangle(450,0,500,20,fill=random_fill_colour(),outline=random_fill_colour())
self.bricksId = [self.brick1,self.brick2,self.brick3,self.brick4,self.brick5,self.brick6,self.brick7,self.brick8,self.brick9,self.brick10]
And I'm trying to reference the ID of bricksId[0] over here:
self.hit_brick(pos,self.bricks.bricksId[0])
Earlier, in the __init__, I define bricks as bricks, which is defined as Brick(canvas). However, the error states:
TypeError: 'Brick' object does not support indexing
In the answers to the other questions of this subject, I cannot find any that help me access bricks.bricksId[0].
In order for the Brick object to be indexable, you must implement the methods:
__getitem__
__setitem__
__delitem__
You don't need all of them, only the ones you use.
However, this seems like a case of self.bricks being a brick instead of a list of bricks. A list of bricks is indexable; however, a brick itself is not unless you implement the methods above.
Check this for reference.
In order to be able to call self.bricks.bricksId[number] when I needed:
def __getitem__(self,index):
return self.bricks.bricksId[index]
def __setitem__(self,index,value):
self.bricks.bricksId[index] = value