Using dict like C switch - python-2.7

class checkevent:
def __init__(self,fromuser):
self.fromuser = fromuser
def openid_check(self):# use sqlalchemy
exist_user = User.query.filter_by(openid = self.fromuser).first()
if exist_user is None:
text = u'请绑定后在使用'
return text
def grade(self):
openid_check()
exist_user = User.query.filter_by(openid = self.fromuser).first()
geturp = urp(exist_user.username, exist_user.password_urp) #the function
return geturp #return the grades as text
def key_check(self,x): # use dict like switch
{'grade': self.grade
}
contents = checkevent('ozvT4jlLObJWzz2JQ9EFsWSkdM9U').key_check('grade')
print contents
It's always return None,I want to get a value
and it's the right way to use dict?

There's no return statement in key_check, so naturally it doesn't return anything. You're basically missing the last bit of the implementation: once you look up the appropriate function by name, you need to call that function and return the result.
def key_check(self, key): # "x" is a meaningless name; use something meaningful
lookup = {
'grade': self.grade
}
func = lookup[key] # Look up the correct method
return func() # Call that method and return its result
Technically you could in-line all that into one statement if you really wanted to, but unless performance is at a premium I wouldn't recommend it as the readability suffers.

Related

How to execute a function when a variable's value is changed?

In Odoo 10, I want to change the value of a variable when the forecasted quantity of a product is changed. I tried using the #api.onchange decorator, but it doesn't work. The forecasted quantity change, but the variable keeps the same value. I have this:
class MyProduct(models.Model):
_inherit = 'product.product'
was_changed = fields.Boolean(default = False)
#api.onchange('virtual_available')
def qtychanged(self):
self.was_changed = True
_logger.info('Product_Qty_Cahnged: %s',str(self.virtual_available))
In this code, if the forecasted quantity of a product would change, the variable was_changed should be set to True, but nothing happens.
After that, I tried to overwrite the write method for my custom class, like this:
class MyProduct(models.Model):
_inherit = 'product.product'
was_changed = fields.Boolean(default=False)
#api.multi
def write(self, values):
if values['virtual_available']:
values['was_changed'] = True
# THE FOLLOWING LINES WERE IN THE ORIGINAL WRITE METHOD
res = super(MyProduct, self).write(values)
if 'standard_price' in values:
self._set_standard_price(values['standard_price'])
return res
But still, I have the same result. I can't seem to get that flag to change. So, any ideas?
Try this:
class MyProduct(models.Model):
_inherit = 'product.product'
was_changed = fields.Boolean(default = False)
#api.onchange('virtual_available')
def qtychanged(self):
self.write({'was_changed': True})
_logger.info('Product_Qty_Cahnged: %s',str(self.virtual_available))

Union Find algorithm in Python

I am trying to implement Union Find algorithm in python and I don't understand what's wrong with my code as everything seems to be in the right place.
Please help in this regard. Below is my code
class UnionFind:
def __init__(self,v):
self.parent = [-1 for i in range(v)]
self.lis=[]
def addEdge(self,i,j):
self.lis.append([i,j])
def findParent(self,i):
if self.parent[i] == -1:
return i
else :
self.findParent(self.parent[i])
def union(self,i,j):
self.parent[i]=j
def printResult(self):
print self.lis
def isBool(self):
for lisIter in self.lis:
x=self.findParent(lisIter[0])
y=self.findParent(lisIter[1])
if(x==y):
return True
self.union(x,y)
return False
uf = UnionFind(3)
uf.addEdge(0,1)
uf.addEdge(1,2)
uf.addEdge(2,0)
if uf.isBool():
print "The graph is cyclic"
else:
print "The graph is not cyclic"
Finally I got that little logic which I missed in the my code. I need to add the return statement in the else block of findParent method or else the returned value will be discarded and a none value will get returned. Uff!
def findParent(self,i):
if self.parent[i] == -1:
return i
else :
return self.findParent(self.parent[i])

Compressing series of if-else statement in Groovy

I have a series of if-else statements in Groovy:
String invoke = params?.target
AuxService aux = new AuxService()
def output
if(invoke?.equalsIgnoreCase("major")) {
output = aux.major()
}
else if(invoke?.equalsIgnoreCase("minor")) {
output = aux.minor()
}
else if(invoke?.equalsIgnoreCase("repository")) {
output = aux.repository()
}
...
else if(invoke?.equalsIgnoreCase("temp")) {
output = aux.temp()
}
else {
output = aux.propagate()
}
The ellipsis contains yet another 14 sets of if-else statements, a total of 19. You see, depending on the value of invoke the method that will be called from AuxService. Now I'm thinking the following to reduce the lines:
String invoke = params?.target()
AuxService aux = new AuxService()
def output = aux?."$invoke"() ?: aux.propagate()
But I think the third line might not work, it looks very unconventional. And just a hunch, I think that line is prone to error. Is this a valid code or are there any more optimal approach to compress these lines?
Just test String invoke before using it. Note that aux won't be null, so no need to use safe navigation (?.).
class AuxService {
def major() { 'major invoked' }
def minor() { 'minor invoked' }
def propagate() { 'propagate invoked' }
}
def callService(invoke) {
def aux = new AuxService()
return invoke != null ? aux.invokeMethod(invoke, null) : aux.propagate()
}
assert callService('major') == 'major invoked'
assert callService(null) == 'propagate invoked'
Note this is will fail if the input doesn't contain a valid method in class AuxService.
Firstly, your code is avlid in Groovy. Though, if equalsIgnoreCase is required, your reduced code will not work. The same for if params is null, since then invoke would be null. But I think your basic idea is right. So what I would do is making a map (final static somewhere) with the methods in uppercase as String key and the real method in correct casing as String value. Then you can use that to ensure correctness for different cases. Null handling I would solve separate:
def methodsMap = ["MAJOR":"major",/* more mappings here */]
String invoke = params?.target()
AuxService aux = new AuxService()
def methodName = methodsMap[invoke?.toUpperCase()]
def output = methodName ? aux."$methodName"() : aux.propagate()
An slightly different approach would be to use Closure values in the map. I personally find that a bit overkill, but it allows you to do more than just the plain invocation
def methodsMap = ["MAJOR":{it.major()},/* more mappings here */]
String invoke = params?.target()
AuxService aux = new AuxService()
def stub = methodsMap[invoke?.toUpperCase()]
def output = stub==null ? stub(aux) : aux.propagate()
I thought about using the Map#withDefault, but since that will create a new entry I decided not to. It could potentially cause memory problems. In Java8 you can use Map#getOrDefault:
String invoke = params?.target()
AuxService aux = new AuxService()
def methodName = methodsMap.getOrDefault(invoke?.toUpperCase(), "propagate")
def output = aux."$methodName"()
The Elvis operator is used to shorten the equivalent Java ternary operator expression.
For example,
def nationality = (user.nationality!=null) ? user.nationality : "undefined"
can be shortened using the Elvis operator to
def nationality = user.nationality ?: "undefined"
Note that the Elvis operator evaluates the expression to the left of the "?" symbol. If the result is non-null, it returns the result immediately, else it evaluates the expression on the right of the ":" symbol and returns the result.
What this means is that you cannot use the Elvis operator to perform some extra logic on the right side of the "?" symbol if the condition evaluates to true. So, the ternary expression
user.nationality ? reportCitizen(user) : reportAlien(user)
cannot be (directly)expressed using the Elvis operator.
Coming back to the original question, the Elvis operator cannot be (directly) applied to checking if a method exists on an object and invoking it if present. So,
def output = aux?."$invoke"() ?: aux.propagate()
will not work as expected, because the Elvis operator will try to evaluate "aux?."$invoke"()" first. If "invoke" refers to a method that does not exist, you will get a MissingMethodException.
One way I can think of to work around this is -
class AuxService {
def major() { println 'major invoked' }
def minor() { println 'minor invoked' }
def propagate() { println 'propagate invoked' }
}
def auxService = new AuxService()
def allowedMethods = ["major", "minor", "propagate"]
def method = null
allowedMethods.contains(method?.toLowerCase()) ? auxService."${method?.toLowerCase()}"() : auxService.propagate() // Prints "propagate invoked"
method = "MaJoR"
allowedMethods.contains(method?.toLowerCase()) ? auxService."${method?.toLowerCase()}"() : auxService.propagate() // Prints "major invoked"
method = "undefined"
allowedMethods.contains(method?.toLowerCase()) ? auxService."${method?.toLowerCase()}"() : auxService.propagate() // Prints "propagate invoked"
In a nutshell, store the list of invoke-able methods in a list and check to see if we're trying to invoke a method from this list. If not, invoke the default method.

How can I get a list from model for the template

in the models.py, I have a model which has a list attribute:
Class Controller(models.Model):
def controller(self):
result = []
#...do some works here...
result = xxx
Now I want to use the "result" attribute in the template, in views.py I have:
def results(request):
cmodel = Controller()
cmodel.controller()
firstList = get_list_or_404(Controller, 'I am not sure how to write this filter')
return render_to_response('blablabla/')
I am not sure how to write the filter, since the samples are giving something like "pk=1", but I don't have any primary keys or ids for the 'result' object. Can anyone help me? Thank you.
Your controller function should return result:
Class Controller(models.Model):
def controller(self):
result = []
#...do some works here...
result = xxx
return result # <----------
And then you can get it as:
c = Controller()
result_list = c.controller()
Is that what you want?

Overload get_FIELD_display() function

Is there a way to overload Django's get_FIELD_display() function properly? When I call the function from inside itself, the result is a recursion. But I can't call it using super() either, as it's not a parent class' method but a method created by the metaclass...
The goal is to have a common interface for getting a displayable version of a CHOICE field (which is given by get_FIELD_display), but with the possibility to customize it in some specific cases.
Example:
# This does not work because it results in recursion
def get_opposition_state_display(self):
"""Overloading of default function."""
value = self.get_opposition_state_display()
if self.opposition_state == 4:
return '%s %s' % (value, self.opposition_date.strftime('%d.%m.%Y'))
return value
updated
field = self._meta.get_field('opposition_state')
value = self._get_FIELD_display(field)
To override get_FOO_display you need something like this:
field_name = models.PositiveSmallIntegerField('Field', choices=some_choices)
def _get_FIELD_display(self, field):
f_name = field.name
if f_name == 'field_name':
return 'what_you_need'
return super(YourModelName, self)._get_FIELD_display(field=field)