0

Hi guys;
I'm new in python and thread ,i start learning by create a simple code but i find some defficult this code below have some function and thread also Queue function to share data between thread this is a part of my code:

def PutChar(Ch):     #ask user to put the correct char

    b=raw_input("Enter "+Ch+" char ")
    while (b != Ch):
         b=raw_input("Enter "+Ch+" char ")
    return b     

def sleep_time():#sleep time function
n=11
time.sleep(5)
for i in range(1,n):
    time.sleep(1)
    if(i==5):
        print"\ntime almost finish rest",str(i),"second"
        print"Enter f char "

if(q.get(False)=='f'):
    print(q.get())
else:
    pass    

print"\ntime finish wait more than",str(i),"second"

    print"\ntime finish",i

def PutFchar(in_q):   #function for putting the F char
        k=PutChar('f')
        putEchar()
        in_q.put(k)

def PutEchar():#function for putting the E char
    PutChar('e')
    print("cycle correct")  

and i have this code in main() function:

q=Queue.Queue()
t2=threading.Thread(target=sleep_time)
t1=threading.Thread(target=PutFchar, args=(q,))

t1.start()
t2.start()

t1.join()
t2.join()
print"Program finish"

i have two questions:

First: why when i use the queue function the code block ? i mean in this code i use thread for running the PutFchar() and sleep_time() functions in parallel but when i add the queue function for share data between threads functions the PutFchar work but the sleep_time function block
i have this screenshot for more understand:

Second: i call the PutEchar() in the PutFchar() function but the console show me an error so what i can do for calling function in thread function ?
this is the also another screenshot:

Finally i search for an easy way to input some words or number without blocking the code for exemple if you put a word after 10 second of waiting the console quit and program finish but if i put the time sleep and the input function i need to wait first the time sleep or the user to put some thing in console but in my way i need the time work when the user put something in console so i use thread but i find the queue also a block function
I hope find some help and thanks :)

Edited by sekmani

Attachments Capture3.PNG 41.28 KB Capture4.PNG 84.65 KB
2
Contributors
10
Replies
111
Views
4 Months
Discussion Span
Last Post by sekmani
Featured Replies
  • This is a long post and there are many questions. Let's first start with a simple code that waits for console input with a timeout. A correct way to do it is by using `select.select()`. from select import select import sys def main(): timeout = 5 print('Please type something: ', … Read More

  • The print part may be a problem if you are using python 2 instead of python 3. If this is the case, my advice is to always write from __future__ import (absolute_import, division, print_function, unicode_literals) at the very top of every new python 2 program. Among other benefits, the print … Read More

  • No, no, you don't have to play with the select function's arguments. These must be lists of python files, or linux file descriptors. To make things simpler, I wrapped the call to select in a function `my_raw_input()` that you can use. It works like `raw_input()`, but it accepts a timeout … Read More

  • It's hard to believe, can you post the same screenshot, but with the code window this time? Or perhaps the console is a part of the Geany editor ? IDE's such as Geany may redefine sys.stdin. Did you try the code in a true terminal? Read More

  • If you have a working solution, it's OK, although I don't see the difference with my solution... Read More

1

This is a long post and there are many questions. Let's first start with a simple code that waits for console input with a timeout. A correct way to do it is by using select.select().

from select import select
import sys

def main():
    timeout = 5
    print('Please type something: ', end = '')
    sys.stdout.flush()
    rlist, wlist, xlist = select([sys.stdin],[],[], timeout)
    if rlist:
        data = sys.stdin.readline()
        print('you entered', data)
    else:
        print('\nSorry, {} seconds timeout expired!'.format(timeout))

if __name__ == '__main__':
    main()

I'll try to understand your code and see how you can add threads in this. Two remarks first

  • It is not usually a good idea to mix calls to time.sleep() with threads. There are other ways to wait, such as queue input and output, the threads join() method, or Lock and Conditions objects etc
  • For your second error, you wrote putEchar() instead of PutEchar()

Edit: actually, I'm not sure the select.select method works in Windows OS. If you're in windows, tell me if it works.

Edited by Gribouillis

0

yes it working thanks i'm using raspberry pi the only problem in

print('Please type something: ', end = '')

always show me an error but if i remove

,end = ' ')

the program run ,i'm using Geany i don't know if the problem in the IDE Geany or the syntax of the code

finally thanks friend for the help and please if you can give me more explain about this line

rlist, wlist, xlist = select([sys.stdin],[],[], timeout)

why you put "wlist" and "xlist" and you just use the "rlist" in the code

2

The print part may be a problem if you are using python 2 instead of python 3. If this is the case, my advice is to always write

from __future__ import (absolute_import, division,
                        print_function, unicode_literals)

at the very top of every new python 2 program. Among other benefits, the print statement is replaced by a print function with python 3 behavior.
It would be even better to switch to python 3. Python 2 support ends in 2020!

If you don't want all this, you can simply write

print 'Please type something: ',

(notice the comma at the end of the statement)

The select.select() function is an old unix function that comes directly from the C language. It is a part of the Posix standard. It is the traditional linux way for programs to wait until an input/output file descriptor is available. You should start with this function's documentation to understand the arguments.

Edited by Gribouillis

0

I understand thanks in this moment i'm working with python 2 in raspberry i'm using now in my code the select and sys library but i find a problem how i can put a condition in the if statement ,you put in the exemple (if rlist) but in my case i need a condition i put in my code (if rlist=='F') but doesn't work and other question in the select function you put(select([sys.stdin]) if i like to put a message what i can put ???? In my code i write this (select([sys.stdin.writeline("enter a char")]) but this not working you have an idea and thanks

2

No, no, you don't have to play with the select function's arguments. These must be lists of python files, or linux file descriptors. To make things simpler, I wrapped the call to select in a function my_raw_input() that you can use. It works like raw_input(), but it accepts a timeout argument

from __future__ import (absolute_import, division,
                        print_function, unicode_literals)

from select import select
import sys

class TimeoutError(RuntimeError):
    pass

def my_raw_input(prompt='', timeout=-1):
    if timeout < 0:
        return raw_input(prompt).decode(sys.stdin.encoding)
    print(prompt, end = '')
    sys.stdout.flush()
    rlist, wlist, xlist = select([sys.stdin],[],[], timeout)
    if rlist:
        return sys.stdin.readline().decode(sys.stdin.encoding).strip('\n')
    else:
        raise TimeoutError

def main():
    try:
        char = my_raw_input('Enter a char: ', timeout=5)
    except TimeoutError:
        print("\nSorry, too late")
        return
    print('You entered', char)

if __name__ == '__main__':
    main()

You can see in the main() function how to use the my_raw_input() function. Note that it works like raw_input, which means that you need to hit the enter key after your input.

Edit: I changed the code so that my_raw_input() returns a unicode string. This is especially useful if you commonly write
non english words, such as french words with accents.

Edited by Gribouillis

Votes + Comments
Timeouts are nice.
0

thanks for the help friend but when i execute the program he give me this result:

you entered None

he don't ask me to put a char, directly give me the None result
you can see here the screenshot :

Edited by sekmani

Attachments Capture.PNG 177.06 KB
1

It's hard to believe, can you post the same screenshot, but with the code window this time? Or perhaps the console is a part of the Geany editor ? IDE's such as Geany may redefine sys.stdin. Did you try the code in a true terminal?

Edited by Gribouillis

0

I try in the terminal and in geany i don't try in python editor i will try but i find a good and a nice solution here is :

from __future__ import print_function
from select import select
import sys

timeout = 5
print('Please type something: ', end =       '')
sys.stdout.flush()
inputready, _, _ = select([sys.stdin],[],[], timeout)
if inputready:
    k = sys.stdin.readline()
    if k.strip()=="f":
        print("You printed 'f'")
    else:
        print("Not 'f'")
else:
        print('\nSorry, {} seconds timeout     expired!'.format(timeout))
1

If you have a working solution, it's OK, although I don't see the difference with my solution...

Edited by Gribouillis

0

No of course this is your solution all your work just i add a condition and thank you so much i add a variable
(K) And i put in this variable the sys.stdin.readline() contains but in the first time i found a problem because the sys.stdin.readline() print the result with (\n) so that's why i add strip() finally in genaral thanks

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.