Using the same method name for two different method headers - python

I'm experiencing a little issue, while working with Python/Django. I have a class, called 'Plantao', and a method 'get_ultima_posicao', which, I wanted to behave in the following way:
If called by the class, like Plantao.get_ultima_posicao, it should expect two parameters, one mandatory and one optional. And when called by a class object, like p.get_ultima_posicao (p being an instance of Plantao) the only parameter it should expect would be self.
Is there a way of doing that?
I know there's a way of doing something like polymorphism, using (self, *args) in the method header, but since one of my methods should be static, using #staticmethod, it doesn't have self as a parameter.
EDIT
In [4]: Plantao.get_ultima_posicao(empresa = 1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/*************************************/<ipython console> in <module>()
TypeError: unbound method get_ultima_posicao() must be called with Plantao instance as first argument (got nothing instead)
In [5]: planta.get_ultima_posicao()
Out[5]: 0
Where planta.empresa = 1. I wanted that to work, and both executions returning the same values
I wanted the methods definitions to be something like:
def get_ultima_posicao(self):
AND
#staticmethod
def get_ultima_posicao(empresa, data = datetime.date.today()):
EDIT
Ok, here's my model for the Plantao class:
usuario = models.ForeignKey(Usuario, null=True, blank=True) # user
empresa = models.ForeignKey(Empresa, null=True, blank=True) # department
posicao = models.IntegerField(default=0) # position in queue
data = models.DateField(null=True, blank=True) # date added in queue
So, I may know which deparment I want to get an user from, so why would I need to retrieve one Plantao object just to search for it? At the same time, if I already retrieved it, why would I need to get the deparment again, if it's already in Plantao object? That's why I want to do that.
EDIT
In hope it may help finding a solution I'm adding the functions codes here:
#staticmethod
def get_ultima_posicao(empresa, data = datetime.date.today()):
if empresa is None:
return 'Empresa invalida'
ultima = Plantao.get_ultimo_fila(empresa = empresa)
plantao = Plantao.objects.filter(data=data, empresa=empresa).order_by('posicao')
usuario = None
for i in plantao:
ultima += 1
i.posicao = ultima
i.save()
if i.usuario.atendimento_pendente() == False and i.usuario.cliente_aguardando() == False and i.usuario.esta_online() == True:
return i.usuario
return "Nenhum usuario disponivel na escala"
def get_ultima_posicao(self):
if self.empresa is None:
return 'Empresa invalida'
ultima = Plantao.get_ultimo_fila(empresa = self.empresa)
plantao = Plantao.objects.filter(data=self.data, empresa=self.empresa).order_by('posicao')
usuario = None
for i in plantao:
ultima += 1
i.posicao = ultima
i.save()
if i.usuario.atendimento_pendente() == False and i.usuario.cliente_aguardando() == False and i.usuario.esta_online() == True:
return i.usuario
return "Nenhum usuario disponivel na escala"

Related

count the sales of a worker

I am trying to count the sales made by a worker but I get the following error when using the code mentioned below:
TypeError: object of type 'bool' has no len()
class Movement_type (models.Model):
_name = 'project_rc.movement_type'
_rec_name = 'movement_type'
type_movement = fields.Selection ([('purchase', 'Purchase'), ('sale', 'Sale'), ('merma', 'Merma')], string = "Movement type", required = True)
class Worker (models.Model):
_name = 'project_rc.worker'
_rec_name = 'name'
sales_counter = fields.Integer (string = "Sales made", compute = "get_sales_realized", store = True)
#api.depends('move_type_ids')
def get_sales_realized (self):
for rec in self:
rec.count_sale = len (rec.move_type_ids.mov_type == 'sale')
I'm not familiar with whatever framework you are using, but if you look at the error you are getting you can see that it is correct.
On line 3, you write rec.move_type_ids.mov_type == 'sale'. It doesn't matter what rec.move_type_ids.mov_type is, when you compare it to something with ==, the answer will either be True or False. It doesn't make sense to take the length of a boolean (t/f).
From the context, I'm guessing that rec.move_type_ids is a list of objects and you want to figure out how many of them have a mov_type property equal to 'sale'. If that's the case, then you could easily do that with a for loop:
sales = []
for thing in rec.move_type_ids:
if thing.type == 'sale':
sales.append(thing)
rec.count_sale = len(sales)
If you want to get a little fancier, you can do that with a filter function:
rec.count_sale = len(filter(lambda x: x.mov_type == 'sale', rec.move_type_ids))

Python ERROR: TypeError: ... missing 1 required positional argument:

class Estudante:
def __init__(self,nome,numero_estudante):
self.nome=nome
self.numero_estudante=numero_estudante
self.cadeiras = []
def enrol (self, curso_decorrer):
self.cadeiras.append(curso_decorrer)
curso_decorrer.add_estudante(self)
class Departamento:
def __init__(self,nome, codigo_departamento, local):
self.nome=nome
self.codigo_departamento = codigo_departamento
self.local= local
self.cursos = []
def add_curso(self,descricao,codigo_curso, creditos,departamento):
self.cursos[codigo_curso] = Curso(self,descricao,codigo_curso, creditos,departamento)
return self.cursos[codigo_curso]
class Curso:
def __init__(self,descricao,codigo_curso, creditos,departamento):
self.descricao = descricao
self.codigo_curso= codigo_curso
self.creditos=creditos
self.departamento=departamento
self.departamento.add_curso(self)
self.decorridos =[]
def adicionar_ano(self,ano):
self.decorridos.append(Cursodecorrer(self,ano))
return self.decorridos[-1]
class Cursodecorrer:
def __init__(self,curso,ano):
self.curso = curso
self.ano = ano
self.estudantes =[]
def adicionar_estudante(self,estudante):
self.estudantes.append(estudante)
Engenharia=Departamento("Departamento de Engenharia","001","Azurém")
Matemática=Departamento("Departamento de Matemática","002","Braga")
MIEBIOM=Departamento.add_curso("Engenharia Biomédica",'001-1',"55","Engenharia")
MIEBIOL=Departamento.add_curso("Engenharia Biológica",'001-2',"55","Engenharia")
MAT=Departamento.add_curso("Matemática",'002-1',"30")
MIEBIOM_2017=Curso.adicionar_ano("2017")
A74000=Estudante("Pedro Miguel","74000")
Code error: MIEBIOM=Departamento.add_curso("Engenharia
Biomédica",'001-1',"55","Engenharia")**
TypeError: add_curso() missing 1 required positional argument: 'departamento'
I tried everything, anyone knows what's wrong?
Calling a method directly on a class you should only do with class methods. You should first create an instance of Departamento on which you can call the instance method add_curso.
Here's an example of such a code where you first create a Departamento and then add a curso to it, which I guess is what you want to do:
dep = Departamento("name", "codigo dep", "local")
dep.add_curso("Engenharia Biomédica",'001-1',"55","Engenharia")
You can see it is an instance method because the first argument in the method definition is self (this is a convention).
More about class methods vs instance methods: Difference between Class and Instance methods
Your add_curso function requires 5 values
def add_curso(self,descricao,codigo_curso, creditos,departamento):
But you are passing only 4 values when you are calling it in this line:
MIEBIOM=Departamento.add_curso("Engenharia Biomédica",'001-1',"55","Engenharia")
So Python interprets it like this:
self = "Engenharia Biomedica"
descricao = "001-1"
codigo_curso = "55"
creditos = "Engenharia"
departamento = !!Missing Value!!
Hope this helps.

Correct approach to Django Many to Many save

Given the models
class Book(models.Model):
title = models.CharField(max_length=200)
price = models.FloatField()
inventory_quantity = models.IntegerField()
def movement(type, qty):
# ...
if type == 'sell':
self.inventory_quantity -= qty
if type == 'donation':
self.inventory_quantity += qty
# ...
class Operation(models.Model):
operation_type_choices = (
('sell', 'Sell'),
('donation', 'Donation'),
)
book = models.ManyToManyField(Book, through = 'BookOperation')
operation_type = models.CharField(max_length=50, choices=operation_type_choices)
def save(self, *args, **kwargs):
super(Operation, self).save(*args,**kwargs)
bok_op = BookOperation()
bok = Book()
op = Operation()
bok.movement(op.operation_type, bok_op.quantity)
class BookOperation(models.Model):
book = models.ForeignKey(Book)
operation = models.ForeignKey(Operation)
quantity = models.IntegerField()
On the OPERATION model, i overrode the save() function to change the Book quantity by executing the movement() function on Book's model(at least that was the intention).
The logic that determines if the inventory_quantity should add or subtract is in this function, is that the right way to do it?
Also, I know my code is extremely wrong on terms of how Python deals with objects, when I save an operation on admin panel I get movment() takes exactly 2 arguments (3 given), why? It seems that i'm passing only op.operation_type, bok_op.quantity
Thanks for the help
I'm not exactly clear on why you're overriding save, but you should make the super call last there, since it's what does the actual saving of the instance data.
Re "takes exactly 2 arguments (3 given)", the definition of the movement method in the Book class should take self as its first argument. All Python method calls automatically are passed the instance itself as the first method parameter.
See the Python docs for more: "the method function is declared with an explicit first argument representing the object, which is provided implicitly by the call..."
(Also, you don't show us where liv is defined so we can't be sure what it is -- from reading your code it seems it should be self instead.)

Django - Functions in models and views don't return correct Boolean value

I am creating a django app/website and am in trouble with some Boolean results I don't understand.
In my models, I have a Article class with 2 functions :
class Article(models.Model):
#some vars
basetime = models.IntegerField()
duration = models.IntegerField()
has_begun = models.BooleanField()
def remainingTime(self):
if(self.basetime + self.duration) - time.time() >= 0:
return ((self.basetime + self.duration) - time.time())
else:
return -1
def stillAvailable(self):
if self.remainingTime() >= 0:
return True
return False
And in my views I have a function check :
def check(request,i):
try:
article = Article.objects.get(pk=i)
except Article.DoesNotExist:
return ccm(request)
if (article.stillAvailable):
return test(request,article.remainingTime)
else:
return quid(request)
When a page calls check, my browser displays the test page, and the argument article.remainingTime is -1. (wich is the correct value for what I want to do).
My problem is : if article.remainingTime = -1, then article.stillAvailable should return False, and so the check function should return quid(request).
I don't see the reason why django/python interpreter evaluates article.stillAvailable True.
If anyone can help, that'd be very appreciated :P
You are using
if (article.stillAvailable):
As a attribute, rather than calling it as a method. As the attribute exists, it's interpreted as non false. You just need to add the brackets to call the method.

Create a Python User() class that both creates new users and modifies existing users

I'm trying to figure out the best way to create a class that can modify and create new users all in one. This is what I'm thinking:
class User(object):
def __init__(self,user_id):
if user_id == -1
self.new_user = True
else:
self.new_user = False
#fetch all records from db about user_id
self._populateUser()
def commit(self):
if self.new_user:
#Do INSERTs
else:
#Do UPDATEs
def delete(self):
if self.new_user == False:
return False
#Delete user code here
def _populate(self):
#Query self.user_id from database and
#set all instance variables, e.g.
#self.name = row['name']
def getFullName(self):
return self.name
#Create a new user
>>u = User()
>>u.name = 'Jason Martinez'
>>u.password = 'linebreak'
>>u.commit()
>>print u.getFullName()
>>Jason Martinez
#Update existing user
>>u = User(43)
>>u.name = 'New Name Here'
>>u.commit()
>>print u.getFullName()
>>New Name Here
Is this a logical and clean way to do this? Is there a better way?
Thanks.
You can do this with metaclasses. Consider this :
class MetaCity:
def __call__(cls,name):
“”“
If it’s in the database, retrieve it and return it
If it’s not there, create it and return it
““”
theCity = database.get(name) # your custom code to get the object from the db goes here
if not theCity:
# create a new one
theCity = type.__call__(cls,name)
return theCity
class City():
__metaclass__ = MetaCity
name = Field(Unicode(64))
Now you can do things like :
paris = City(name=u"Paris") # this will create the Paris City in the database and return it.
paris_again = City(name=u"Paris") # this will retrieve Paris from the database and return it.
from : http://yassinechaouche.thecoderblogs.com/2009/11/21/using-beaker-as-a-second-level-query-cache-for-sqlalchemy-in-pylons/
Off the top of my head, I would suggest the following:
1: Use a default argument None instead of -1 for user_id in the constructor:
def __init__(self, user_id=None):
if user_id is None:
...
2: Skip the getFullName method - that's just your Java talking. Instead use a normal attribute access - you can convert it into a property later if you need to.
What you are trying to achieve is called Active Record pattern. I suggest learning existing systems providing this sort of things such as Elixir.
Small change to your initializer:
def __init__(self, user_id=None):
if user_id is None:

Categories

Resources