1

I am working on translating some code from Matlab into Python. Currently I am working on this:

switch SIGNATURES_TYPE
    case 1
        rand('seed',5);
        load('USGS_1995_Library')
        wavlen=datalib(:,1);    % Wavelengths in microns
        [L n_materiais]=size(datalib);
        # select randomly
        sel_mat = 4+randperm(n_materiais-4);
        sel_mat = sel_mat(1:p);
        M = datalib(:,sel_mat);
        # print selected endmembers
        clear datalib wavelen names aux st;
    case 2
        error('type not available')
    case 3
        M = rand(L,p);
    case 4
        M = randn(L,p);
    case 5
        L=p;
        M = diag(linspace(1,(1/(COND_NUMBER)^(1/DECAY)),p).^DECAY);
    case 6
        L=p;
        M = diag(linspace(1,(1/(COND_NUMBER)^(1/DECAY)),p).^DECAY);
        A = randn(p);
        [U,D,V] = svd(A);
        M = U*M*V';
        clear A U D V;
    otherwise
        error('wrong signatute type')
end

Previously I had worked on a similar Switch/Case code:

for i=1:2:(length(varargin)-1)
    switch upper(varargin{i})
        case 'MM_ITERS'
            MMiters = varargin{i+1};
        case 'SPHERIZE'
            spherize = varargin{i+1};

The latter I was able to translate to this:

for i in range(1, 2, length(*args)-1):
        if (arg[i].upper() == "MM_ITERS"):
            MMiters = arg(i+1)
        elif (arg[i].upper() == "SPHERIZE"):
            spherize = arg(i+1)

However for the former I am wondering how I can create similar if statements. For example, for the first case can my code be something like:

if SIGNATURES_TYPE == 0:
    ** finish function

I wanted to know if something like this works or if it would be better to perhaps separate out statements into separate functions and then call them?

Thanks for the help and input!

3
  • 1
    The direct translation is just if SIGNATURES_TYPE == 1:, elif SIGNATURES_TYPE == 2:, etc. Is there a reason that's not good enough? Commented Jul 26, 2018 at 19:41
  • 1
    You can also use a dictionary to kinda emulate switch case functionality, if you don't like if/elif/else Commented Jul 26, 2018 at 20:04
  • No, my intuition was that the direct translation was just like that, but for some reason it slipped my mind that that should be how I code it. Thank you for clarifying! Commented Jul 26, 2018 at 20:19

1 Answer 1

2

The if/else construct would work. Another way to do this is to use a dict where the keys are the signature types and the values are functions that return M. This has the advantage of not having to clear anything. So it would look something like this:

def case1(p):
    # calculate L and M
    return L, M

def case6(p):
    # calculate M
    return p, M

try:
    L, M = {1: case1(p),
            3: (L, np.random.rand(L, p)),
            4: (L, np.random.randn(L,p)),
            5: (p, np.diag(np.linspace(1,(1/(COND_NUMBER)**(1/DECAY)),p)**DECAY),
            6: case6(p)}[SIGNATURES_TYPE]
except KeyError:
    raise ValueError('Wrong signatute type: {}'.format(SIGNATURES_TYPE))

As for your previous example, the MATLAB code is a workaround for the lack of default argument handling. Python has default argument handling, so you don't need the if/else or loop at all. You can just do something like:

def myfunc(arg1, arg2, arg3, MM_ITERS=MM_ITERS_default, SPHERIZE=SPHERIZE_default):

where arg1, arg2, and arg3 are the required arguments (the number doesn't matter, there could even be zero). MM_ITERS_default and SPHERIZE_default are the values you want the corresponding variables to hold when the user doesn't define them. You can even collect the arguments directly into a dict, using:

def myfunc(arg1, arg2, arg3, **kwargs):

Then you can access, say MM_ITERS, just using something like:

if MM_ITERS in kwargs:
    MM_ITERS = kwargs[MM_ITERS]`

Or

MM_ITERS = kwargs.get(MM_ITERS, MM_ITERS_default)

But generally it is easier to just use the default argument handling I showed earlier.

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

2 Comments

Thank you for help! This was very clear. I am new to both Matlab and Python and could not understand the need to use command line arguments in the Matlab code. Just to clarify, If I were to set the default value of a variable in the function definition, when the method is actually called with a different value, that value will be used by the method?
@A.Torres: Yes. So say you call myfunc(val1, val2, val3), then the MM_ITERS variable would have MM_ITERS_default and SPHERIZE would have SPHERIZE_default. On the other hand if you called myfunc(val1, val2, val3, val4), then MM_ITERS would have val4 while SPHERIZE would have SPHERIZE_default. And myfunc(val1, val2, val3, val4, val5), has val4 for MM_ITERS and val5 for SPHERIZE. You could also do, for example, myfunc(val1, val2, val3, SPHERIZE=val5), in which case MM_ITERS variable would have MM_ITERS_default and SPHERIZE would have val5.

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.