Hi everybody,

New adventure question: if you know how macros act in C, is there such a behavior in C?

Basically the most important feature I'm looking for is similar to this:

#define MY_C_MACRO(x)  {if (x>0) x++; else return}

Such a macro would cause the function where it is called to return without executing whatever code comes after this macro call. It's sort of like break for a loop.

Now, in Python, I have a lot of similar checks to do, I have an idea of how to implement a check function (for different variables) but I would like to go to the end of the current function where thechecks are called if one of them fails.

If this doesn't make sense, please tell me so I stop looking for a way. I tried even returning 'return' from the check function and trying exec(check_function) in the caller.

Thanks in advance for any advice,

-T

I do not recommend to continue to use this kind of style in Python.

Could you dig up some real use case with input data and sample output (preferably one function only), so we can suggest how you should adapt your style.

Anyway, in Python function is not separate from variable so any variable, which has suitable function value can be used instead of the function name. Return is not a function, and putting it hiding inside macro sounds for me calling for trouble.

Thanks for your reply. Here's a schematic of what I'm trying to do.

class test:
    def __init__(self):
        self.par1 = 3
        self.par2 = 10
        self.status = 'Pass'

    def run(self):
        self.par1 +=5
        self.check_par(self.par1, 8)  #will return Ok
     
        self.par2 -=6
        self.check_par(self.par2, 3)  #will return Not Ok, we should jump
                                                     #jump directly to return self.state

        self.par1 = 7
        self.check_par(self.par1, 7)  #would return Ok but we should never         
                                                    #get here
        return self.status


    def check_par(self, my_p, expected_p):
        if my_p == expected_p:    
             self.status = 'Pass'
       else:
             self.status = 'Fail'



c = test()
c.run()

Imagine a complex scripting mechanism with several such test classes and all the 'run' methods being run one after the other. The idea is that a failing test should be noted as such, but should also allow the following tests to be run, considering of course that the system has been properly restarted after each TC.

Any ideas for this?

Edited 6 Years Ago by tzushky: n/a

Ok, how about this my_run, I copied all action from your function by adding to init and doing loop with functions.

Actually I would prefer to give as return value True/False or 'Pass'/'' and then the self.status will not actually be needed to keep as variable. Maybe in some multitasking situation it could be needed?

class test:
    def __init__(self):
        self.par1 = 3
        self.par2 = 10
        self.check_list=((self.action1, self.par1, 8),
                        (self.action2,  self.par2, 3),
                        (self.action3,  self.par1, 7))
        
        self.status = 'Pass'

    def run(self):
        self.par1 +=5
        self.check_par(self.par1, 8)  #will return Ok
     
        self.par2 -=6
        self.check_par(self.par2, 3)  #will return Not Ok, we should jump
                                                     #jump directly to return self.state
        print "I am not printing" ## debug
        self.par1 = 7
        print self.check_par(self.par1, 7)  #would return Ok but we should neve
                                            #get here
        return self.status

    def check_par(self, my_p, expected_p):
        if my_p == expected_p:    
             self.status = 'Pass'
        else:
             self.status = 'Fail'

    def action1(self):
        self.par1 +=5

    def action2(self):
        self.par2 -=6

    def action3(self):
        print "I am not printing"  ## debug
        self.par1 = 7

    def my_run(self):
        for (action,variable,value) in self.check_list:
            action()
            self.check_par(variable,value)
            print "par1: %i, par2: %i" % (self.par1,self.par2) ## debug
            if self.status == 'Fail': return 'Fail'
        else: return 'Pass'
            
c = test()
##print c.run()
print c.my_run()

Output:

>>> 
par1: 8, par2: 10
Fail
>>>

Edited 6 Years Ago by pyTony: Comment on self.status

The variable was evaluated in init and thats why result was wrong.
It is indirect reference through string, so int() would not convert the variable to value. Thats why I was forced to use eval. (Could use my safer ev, from my 1/3=0 eliminator)

class test:
    def __init__(self):
        self.par1 = 3
        self.par2 = 10
        self.check_list=((self.action1, "self.par1", 8),
                        (self.action2,  "self.par2", 3),
                        (self.action3,  "self.par1", 7))       
        self.status = 'Pass'

    def run(self):
        self.par1 +=5
        self.check_par(self.par1, 8)  #will return Ok
     
        self.par2 -=6
        self.check_par(self.par2, 3)  #will return Not Ok, we should jump
                                                     #jump directly to return self.state
        print "I am not printing" ## debug
        self.par1 = 7
        print self.check_par(self.par1, 7)  #would return Ok but we should neve
                                            #get here
        return self.status

    def check_par(self, my_p, expected_p):
        print my_p,'vs',expected_p  ##debug
        if my_p == expected_p:    
             self.status = 'Pass'
        else:
             self.status = 'Fail'

    def action1(self):
        self.par1 +=5
        print 'Act1'

    def action2(self):
        self.par2 -=6
        print 'Act2'

    def action3(self):
        print "I am not printing"  ## debug
        self.par1 = 7

    def my_run(self):
        for (action,variable,value) in self.check_list:
            action()
            self.check_par(eval(variable),value)
            if self.status == 'Fail': break
        else: return 'Pass'
        print "par1: %i, par2: %i" % (self.par1,self.par2) ## debug
        print "Failed %s:%i" % (variable,value)
        return 'Fail'
            
c = test()
##print c.run()
print c.my_run()
Act1
8 vs 8
Act2
4 vs 3
par1: 8, par2: 4
Failed self.par2:3
Fail
>>>

Edited 6 Years Ago by pyTony: n/a

Hi,

sorry I hadn't answered, it's because I'm a little distracted with all the project.

I couldn't really go with that because the complexity of what I'm doing does not allow it. How ever I went with Exceptions, which work great and can be raised anytime by anyone. Different levels of exceptions for me (ony for printing ou some message, in case something worse or considered fatal occurred) are raised where checks are made or totally unexpected behavior happens.

I ddn't know much about exceptions, but now I do and they allow me to have the behavior I wanted from a macro that would contain 'return' and jump out of the current calling function.

Sorry again, and your idea is great anyway!

T

This article has been dead for over six months. Start a new discussion instead.