views:

54

answers:

3

i have implemented a function:

def postback(i,user,tval):
    """functie ce posteaza raspunsul bazei de date;stringul din mesaj tb sa fie mai mic de 140 de caractere"""
    result = {
        1:api.PostDirectMessage(user,'Trebuie sa-mi spui si marca pe care o cauti'),
        2:postmarket(user,tval),
        3:api.PostDirectMessage(user,'Imi pare rau, dar nu stiu unde poti gasi aceste tipuri de smantana: %s' % tval)}
    return result.get(i)

but it does not work as a case alternative(from c++) it executes all 3 cases no matter wha i try...i'm a begginer so there might be another error, so please help!p.s. please don't tell me that the if...else.. is the only alternative cause i know this can work

+2  A: 

If you absolutely must use a dict, use a dict of functions:

result = {
    1: lambda: api.PostDirectMessage(...),
    2: lambda: postmarket(...),
    ...
}
return result[i]()

The lambda keyword defines an anonymous inline function, and they only get called on the last line.

Matti Virkkunen
+1  A: 

The value expressions in the dict will be evaluated when this is compiled. If you want those things executed, you could wrap them in a lambda.

def postback(i,user,tval):
    result = {
        1: lambda: api.PostDirectMessage(user,'Trebuie sa-mi spui si marca pe care o cauti'),
        2: lambda: postmarket(user,tval),
        3: lambda: api.PostDirectMessage(user,'Imi pare rau, dar nu stiu unde poti gasi aceste tipuri de smantana: %s' % tval)}
    return result.get(i)
bstpierre
A: 

It executes all three cases because you define the result dict that way! You call all three functions and assign them to the keys 1, 2, 3.

What you should instead is something like this:

functions = {
    1: lambda: api.PostDirectMessage(user,'Trebuie sa-mi spui si marca pe care o cauti'),
    2: lambda: postmarket(user,tval),
    3: lambda: api.PostDirectMessage(user,'Imi pare rau, dar nu stiu unde poti gasi aceste tipuri de smantana: %s' % tval)}
func = functions.get(i)
if func:
    return func()
else:
    raise ValueError("Bad index: %d!" % i)

Here I define small wrapper functions and store those in the dict instead. You then pick the right function and call on this one function.

Martin Geisler
You could even refactor the function call to `return functions.get(i, lambda:raise ValueError("Bad index: %d!" % i))()` to avoid the following branch.
Rudi
Rudi: yeah, that would work too. I have a slight preference for the explicit if-statement, though.
Martin Geisler