Holding until next value change

Steve D'Aprano steve+python at pearwood.info
Sat Aug 20 02:07:48 EDT 2016


On Sat, 20 Aug 2016 02:53 pm, Arshpreet Singh wrote:

> I am writing a function as main_call() which is continuously producing
> values. (+ve or -ve) I want to print on screen only for first +ve value
> and hold until -ve value comes around. here is my code:
> 
> 
> def main_call():
>     while True:
>         yield strategy()
>  
> for value in main_call():
>     if(value>0):
>         print '+ve'
>     elif(value>0):
>         print '-ve'
>     else:
>         pass
> 
> Do I need to use threads or processes?

Only if you want a major headache.


Your code doesn't do what you want it to do. It prints "+ve" every time it
sees a positive value, not just the first time.

One solution to this is to think of a state machine: your machine starts off
in the state:

(1) Ignore negative values, print the first positive value you see, 
    then change to the next state.

The second state is:

(2) Ignore positive values, print the first negative value you see,
    then change to the next state.

The third state is unspecified. You don't know say what it is, so I'm going
to guess that you change to a third state:

(3) Don't ignore anything, print every value you see.


So here are our three machines:

def ignore_negative(x):
    if x < 0:
        return False
    else:
        print("+ve")
        return True

def ignore_positive(x):
    if x > 0:
        return False
    else:
        print("-ve")
        return True

def ignore_nothing(x):
    if x > 0:
        print("+ve")
    else:
        print("-ve")
    return False


Here is a table that specifies the changes in state:

TABLE = { # current state: next state
    ignore_negative: ignore_positive,
    ignore_positive: ignore_nothing,
    }


And some code to drive it:


state = ignore_negative  # DON'T call the function yet
for value in main_call():
    print(value)  # for testing
    if state(value):
        print("changing state")
        state = TABLE[state]




Another solution is to look at the itertools module, which has two
functions "dropwhile" and "takeuntil" that might help.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list