Creating loops to update a label in app jar - python-3.x

I'm trying to make a countdown timer in appJar and have a label that shows how much time is remaining until the end of the allotted amount of time. I've looked at the guides on appJar's website a fair amount and know of the two ways that they say you can create loops with their library. You can use .registerevent(function) or .after(delay_ms, function, *args). I've tried both of these ways and can't get either to work. I haven't managed to figure out how to get the .after function to work and every time I try to use the .registerevent function something doesn't work. My current issue is that I can get the function to run but it isn't actually working. That is, it says the block of code is running but the GUI ins't updating
Here are the specific lines of code in question
def introduction_bill(x):
global time_remaining, time_allotted
time_remaining = 120
time_allotted = 120
app.removeAllWidgets()
print("ran 'introduction_bill'")
app.addLabel('timer', 'Time remaining: 2:00')
app.addButtons(['start timer','update'], [start_timer, update_timer])
app.addButton('next introduction', next_introduction)
....
def update_timer():
global time_remaining, current_function
current_function = 'update timer'
time_remaining = end_time - t.time()
minutes = int(time_remaining // 60)
seconds = round(time_remaining % 60, 2)
app.setLabel('timer', 'Timer remaining: ' + str(minutes) + ':' + str(seconds))
print("ran 'update_timer'")
if time_remaining > -10:
app.registerEvent(update_timer)
def start_timer(x):
print("ran 'start_timer'")
global start_time, end_time
start_time = t.time()
end_time = start_time + time_allotted
update_timer()
And here is the code in its entirety
Keep in mind that I am still a beginner in coding so this code is both incomplete and very rough.

You can achieve what you want with both of the methods you mention.
With registerEvent() you should only call it once, it then takes care of scheduling your function. In your code, you are calling it repeatedly, which won't work.
With after() you have to take care of calling it again and again.
So, with your current code, you're better off using after():
In update_timer() try changing the call to app.registerEvent(update_timer) to be app.after(100, update_timer)
The timer should then update every 0.1 seconds.
However, if you click the Start Timer button again, you'll run into problems, so you might want to disable the button until the timer finishes.

Related

How to break out of loop when URL read is taking too long

Hi I have the following code to skip the particular URL if it is taking too long to read.
timeout = 30
loop begins below for different urlz {
timeout_start = time.time()
webpage = urlopen(urlz[i]).read()
if time.time() > timeout_start + timeout:
continue}
My question is; wont the program execute the line of code "webpage = urlopen(urlz[i]).read()" before moving down to check the if condition? In that case I think it wont detect if the page is taking too long (more than 30 seconds to read). I basically want to skip this URL and move on to the next one if the program is stuck for 30 seconds (i.e. we have run into a problem when reading this particular URL).
The urlopen() function has a timeout method inbuilt:
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
So in your code:
timeout = 30
loop begins below for different urlz {
try:
webpage = urlopen(urlz[i], timeout=timeout).read()
}

Python asyncio wait() with cumulative timeout

I am writing a job scheduler where I schedule M jobs across N co-routines (N < M). As soon as one job finishes, I add a new job so that it can start immediately and run in parallel with the other jobs. Additionally, I would like to ensure that no single job takes more than a certain fixed amount of time. Any jobs that take too long should be cancelled. I have something pretty close, like this:
def update_run_set(waiting, running, max_concurrency):
number_to_add = min(len(waiting), max_concurrency - len(running))
for i in range(0, number_to_add):
next_one = waiting.pop()
running.add(next_one)
async def _run_test_invocations_asynchronously(jobs:List[MyJob], max_concurrency:int, timeout_seconds:int):
running = set() # These tasks are actively being run
waiting = set() # These tasks have not yet started
waiting = {_run_job_coroutine(job) for job in jobs}
update_run_set(waiting, running, max_concurrency)
while len(running) > 0:
done, running = await asyncio.wait(running, timeout=timeout_seconds,
return_when=asyncio.FIRST_COMPLETED)
if not done:
timeout_count = len(running)
[r.cancel() for r in running] # Start cancelling the timed out jobs
done, running = await asyncio.wait(running) # Wait for cancellation to finish
assert(len(done) == timeout_count)
assert(len(running) == 0)
else:
for d in done:
job_return_code = await d
if len(waiting) > 0:
update_run_set(waiting, running, max_concurrency)
assert(len(running) > 0)
The problem here is that say my timeout is 5 seconds, and I'm scheduling 3 jobs across 4 cores. Job A takes 2 seconds, Job B takes 6 seconds and job C takes 7 seconds.
We have something like this:
t=0 t=1 t=2 t=3 t=4 t=5 t=6 t=7
-------|-------|-------|-------|-------|-------|-------|-------|
AAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
However, at t=2 the asyncio.await() call returns because A completed. It then loops back up to the top and runs again. At this point B has already been running for 2 seconds, but since it starts the countdown over, and only has 4 seconds remaining until it completes, B will appear to be successful. So after 4 seconds we return again, B is successful, then we start the loop over and now C completes.
How do I make it so that B and C both fail? I somehow need the time to be preserved across calls to asyncio.wait().
One idea that I had is to do my own bookkeeping of how much time each job is allowed to continue running, and pass the minimum of these into asyncio.wait(). Then when something times out, I can cancel only those jobs whose time remaining was equal to the value I passed in for timeout_seconds.
This requires a lot of manual bookkeeping on my part though, and I can't help but wonder about floating point problems which cause me to decide that it's not time to cancel a job even though it really is). So I can't help but think that there's something easier. Would appreciate any ideas.
You can wrap each job into a coroutine that checks its timeout, e.g. using asyncio.wait_for. Limiting the number of parallel invocations could be done in the same coroutine using an asyncio.Semaphore. With those two combined, you only need one call to wait() or even just gather(). For example (untested):
# Run the job, limiting concurrency and time. This code could likely
# be part of _run_job_coroutine, omitted from the question.
async def _run_job_with_limits(job, sem, timeout):
async with sem:
try:
await asyncio.wait_for(_run_job_coroutine(job), timeout)
except asyncio.TimeoutError:
# timed out and canceled, decide what you want to return
pass
async def _run_test_invocations_async(jobs, max_concurrency, timeout):
sem = asyncio.Semaphore(max_concurrency)
return await asyncio.gather(
*(_run_job_with_limits(job, sem, timeout) for job in jobs)
)

Why does my code stuck after speak function?

I try to create a Voice Assistant on python3
This is my function Speak (with pyttsx):
def speak(what):
print("Gosha: " + what)
speak_engine.say( what )
speak_engine.runAndWait()
speak_engine.stop()
in the main body it works fine, but in function execute_cmd, after Speak function my code stucks.
One part of execute_cmd:
def execute_cmd(cmd, voice):
global finished
finished = False
#import debug
if cmd == 'ctime':
now = datetime.datetime.now()
hours = str(now.hour)
minutes = str(now.minute)
if (now.minute < 10): minutes = '0' + minutes
speak("Now " + hours + ":" + minutes)
finished = True
finished will never True
This happens anywhere in the function
pls help me
(sorry for my eng, I'm from Russia)
UPD: I debugged my code and noticed, my code get stuck on speak_engine.runAndWait()
I know, many people have same problem, but their solutions didn't help me
I'm not sure I understand you problem. What exactly do you mean by your code getting "Stuck"? Since you said that your finished variable will never be False, I assume that the code runs through and doesn't get stuck. My best guess is that your code simply doesn't produce sound.
If that's the case, I could imagine it's due to the previous loop still being active. So maybe try adding the following to your speak() function:
ef speak(what):
print("Gosha: " + what)
try:
speak_engine.endLoop()
except Exception as e:
pass
speak_engine.say( what )
speak_engine.runAndWait()
speak_engine.stop()

Python - queuing one function

I've just started learning python, but I have problem with my code:
import pifacecad
# listener initialization
cad = pifacecad.PiFaceCAD()
listener = pifacecad.SwitchEventListener(chip=cad)
listener.register(4, pifacecad.IODIR_ON, blowMyMind)
listener.activate()
def blowMyMind(event):
print('some prints...')
time.sleep(4)
print('and the end.')
blowMyMind() will be fired as many times as listener it tells to. That is okay.
My goal is to deactivate listener UNTIL blowMyMind ends. Pifacecad suggest Barrier() to achieve that, at least I think that it was here for that reason(correct me if I'm wrong).
Now it's working as many times as I activate listener event, but It's not like pushing function 99 times at once, but queues it and runs one by one.
With Barriers I think it should look like this:
# Barrier
global end_barrier
end_barrier = Barrier(1)
# listener initialization
listener = pifacecad.SwitchEventListener(chip=cad)
listener.register(4, pifacecad.IODIR_ON, blowMyMind)
listener.activate()
def blowMyMind(event):
global end_barrier
test = end_barrier.wait()
print(test) # returns 0, which should not in about 5 seconds
print('some prints...')
time.sleep(4)
print('and the end.')
The funny part is when I change parties in Barrier initialization it is causing BrokenBarrierError at first listener event.
Actually I think that I completely misunderstood Barrier() I think the problem with it is that all listener events are in one thread instead of their own threads.
It's making me even more confused when I'm reading:
parties The number of threads required to pass the barrier.
from here: https://docs.python.org/3/library/threading.html
My conclusion: when initializing Barrier(X) it would be realeased when there will be X('or less', 'or more'?) number of threads. That sounds VERY stupid :D
I tried to make it that way with no luck:
# listener initialization
global busy
busy = 0
cad = pifacecad.PiFaceCAD()
listener = pifacecad.SwitchEventListener(chip=cad)
listener.register(4, pifacecad.IODIR_ON, blowMyMind)
listener.activate()
def blowMyMind(event):
global busy
if busy == 0:
busy = 1
print('some prints...')
time.sleep(4)
print('and the end.')
busy = 0
else:
return None

Trials Timer with Read and Write

I am creating a GUI in Matlab that will read and write data to a text file based on the trial duration. The user will enter the number of trials and trial duration and
then push the "start" button.
For example the user enters 5 trials at 10 seconds duration. While starting the 1st trial, I will need to read/write data continuously for 10 seconds, then stop and save the text file. This process will continue for the next 5 trials. Here is a brief code I tried to implement below.
How can I run both the timer for 10 seconds and simultaneously read/write data with that time limit?
Thanks in advance.
% Get Number of Trials
number_trials = str2double(get(handles.Number_Trials,'String'));
% Get Trial Duration
trial_duration = str2double(get(handles.Trial_Duration,'String'));
% Timer Counter
global timer_cnt
timer_cnt = 0;
global eye_data
eye_data = 0;
for i = 1:number_trials
% Set Current Trial Executing
set(handles.Current_Trial_Text,'String',num2str(i));
% Set Text File Specifications
data_fname = get(handles.Data_Filename_Edit_Text,'String');
file_fname = '.dat';
data_fname_txt = strcat(data_fname,file_fname);
% Timer Object
fprintf('%s\n','Timer Started');
% Pauses 10 Seconds
t = timer('TimerFcn','stat=false','StartDelay',10);
start(t);
stat = true;
while(stat == true)
disp('.');
pause(1)
end
fprintf('%s\n','Timer Ended');
delete(t);
end
In my experience, timers are usually used in the context of "wait this amount of time, then do foo" rather than how you're using it, which is "do foo until you've done it for this amount of time".
The humble tic/toc functions can do this for you.
t_start = tic;
while toc(t_start) < 10
% do data collection
end

Resources