1

I have to work with a bunch of if statement in one code. They are all the same with slight changes. Is there any way how I can compromise all this code and make it more elegant and shorter ?

Code below:

if con_name == 'coh':
    coh = my_coherence(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean)
    coh_surro = my_coherence(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)
    return coh, coh_surro, freqs, freqs_surro

if con_name == 'imcoh':
    imcoh = my_imcoh(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean)
    imcoh_surro = my_imcoh(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)
    return imcoh, imcoh_surro, freqs, freqs_surro

if con_name == 'cohy':
    cohy = my_cohy(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean)
    cohy_surro = my_cohy(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)
    return cohy, cohy_surro, freqs, freqs_surro

if con_name == 'plv':
    plv = my_plv(n_freqs, Rxy, Rxy_mean)
    plv_surro = my_plv(n_freqs, Rxy_s, Rxy_s_mean)
    return plv, plv_surro, freqs, freqs_surro

if con_name == 'pli':
    pli = my_pli(n_freqs, Rxy, Rxy_mean)
    pli_surro = my_pli(n_freqs, Rxy_s, Rxy_s_mean)
    return pli, pli_surro, freqs, freqs_surro

if con_name == 'wpli':
    wpli = my_wpli(n_freqs, Rxy, Rxy_mean)
    wpli_surro = my_wpli(n_freqs, Rxy_s, Rxy_s_mean)
    return wpli, wpli_surro, freqs, freqs_surro

I am sorry if this is to easy, but I tried and tried and can't figure out a way.

3
  • 2
    FIrst of all you could use elif rather than just if Commented Jun 29, 2015 at 11:35
  • 2
    elif is useless since there is a return in all statements. Commented Jun 29, 2015 at 11:40
  • @Hacketo yep didn't see that Commented Jun 29, 2015 at 12:04

4 Answers 4

5

Without reflection

func, flag = {
    "coh": (my_coherence, True),
    "imcoh": (my_imcoh, True)
    "cohy": (my_cohy, True),
    "ply": (my_plv, False),
    "pli": (my_pli, False),
    "wpli": (my_wpli, False)
}[con_name]

args = (n_freqs, Rxy_mean, Rxx_mean, Ryy_mean) if flag else (n_freqs, Rxy, Rxy_mean)
surro_args = (n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean) if flag else (n_freqs, Rxy_s Rxy_s_mean)

val = func(*args)
surro = func(*surro_args)
return val, surro, freqs, freqs_surro

OR This is also possible

...
args = (Rxy_mean, Rxx_mean, Ryy_mean) if flag else (Rxy, Rxy_mean)
surro_args = (Rxy_s_mean, Rxx_s_mean, Ryy_s_mean) if flag else (Rxy_s Rxy_s_mean)

val = func(n_freqs, *args)
surro = func(n_freqs *surro_args)
...

Maybe there is a cool name for flag for classifying those functions. Use it instead.

Sign up to request clarification or add additional context in comments.

Comments

2

I would use a dictionary. Something like:

functions = {'coh':my_coherence,'imcoh':my_imcoh....}

Which would be called like this:

functions[con_name](n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)

Comments

1
r = {
    'coh':   lambda: (my_coherence(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean), my_coherence(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean), freqs, freqs_surro),
    'imcoh': lambda: (my_imcoh(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean), my_imcoh(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean), freqs, freqs_surro),
    'cohy':  lambda: (my_cohy(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean), my_cohy(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean), freqs, freqs_surro),
    'plv':   lambda: (my_plv(n_freqs, Rxy, Rxy_mean), my_plv(n_freqs, Rxy_s, Rxy_s_mean), freqs, freqs_surro),
    'pli':   lambda: (my_pli(n_freqs, Rxy, Rxy_mean), my_pli(n_freqs, Rxy_s, Rxy_s_mean), freqs, freqs_surro),
    'wpli':  lambda: (my_wpli(n_freqs, Rxy, Rxy_mean), my_wpli(n_freqs, Rxy_s, Rxy_s_mean), freqs, freqs_surro),
    }
return r[con_name]()

You can further avoid repetitions, for example last two items are repeated for each case:

r = {
    'coh':   lambda: (my_coherence(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean), my_coherence(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)),
    'imcoh': lambda: (my_imcoh(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean), my_imcoh(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)),
    'cohy':  lambda: (my_cohy(n_freqs, Rxy_mean, Rxx_mean, Ryy_mean), my_cohy(n_freqs, Rxy_s_mean, Rxx_s_mean, Ryy_s_mean)),
    'plv':   lambda: (my_plv(n_freqs, Rxy, Rxy_mean), my_plv(n_freqs, Rxy_s, Rxy_s_mean)),
    'pli':   lambda: (my_pli(n_freqs, Rxy, Rxy_mean), my_pli(n_freqs, Rxy_s, Rxy_s_mean)),
    'wpli':  lambda: (my_wpli(n_freqs, Rxy, Rxy_mean), my_wpli(n_freqs, Rxy_s, Rxy_s_mean)),
    }
return r[con_name]() + (freqs, freqs_surro)

2 Comments

I was about to write a similar answer, but I believe it's better to pass arguments to lambdas for them to be proper high-order functions, e.g. the call would look like r[con_name](...arguments for inner functions...)
@ mescalinum: Thanks. It's a nice approach. I corrected your tiny mistakes and it works fine.
0

You could use Reflection. I would create a method, which would be responsible for calling the given methods. I would pass the two method names in each case and the parameters. Based on the method param names you could call each time the right function and return what is needed. And in the code chunk you have shown I would call the method, passing the two method names and the parameters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.