python - while loop structure - python

I need help to construct a working while loop.
my code goes like this
class Bot():
def __init__(self):
self.woke = False
while self.woke == False:
self.wake_word() # --> when it predicts wake word self.woke changes to True
while self.woke == True:
self.voice_recognition() # --> takes audio turns it to a spoke.txt file
break
self.chat() # --> reads the spoke.txt and finds a response
self.respond() # --> speaks the responds using pyttsx3
the code works perfectly but only for one time..it does what I want it to do but for once and then the script stops.
I need to run it until I give the command to stop it using
sys.exit(0) # in a function
meaning when it responses it starts listening again (self.voice_recognition() function) and again does the chat() and finds a respond().

Not exactly sure what you are looking for, but try this -
class Bot():
def __init__(self):
self.woke = False
while self.woke == False:
self.wake_word() # --> when it predicts wake word self.woke changes to True
while self.woke == True:
self.voice_recognition() # --> takes audio turns it to a spoke.txt file
self.woke=False
break
self.chat() # --> reads the spoke.txt and finds a response
self.respond() # --> speaks the responds using pyttsx3

I had a problem with the way I'm capturing audio.. (I had to close the stream).
what happened was that each time the voice_recognition() was called the stream was already open so the data didn't change and that causes an infinite loop inside the function which caused it to not work how it was supposed to
the final code the was correctly working is this
self.wake_word()
while True:
self.voice_recognition()
self.chat()
self.respond()
really simple and straight forward, the problem was with it the function not the while loop structure.
Thanks for anyone who took the time and tried to answer I'm sure your answers / comments were correct as this wasn't about the while loop structure yet a simple unrecognized missing code.

Related

Tkinter text updates take too long to load

i've got a working piece of code here, but when the if flag == True: statement completes, the playsound activates, but it takes roughly 3 seconds longer for the detectionLabel text to update. Can someone take a look at the code below and help recommend a way that I can help speed up the text updating process? Thanks!
def loop(addressField,url):
detectionLabel['text']="Scanning..."
flag = False
address = addressField.get()
def loopOver(flag):
print("loop")
flag,response = searchLoop(address,url,flag)
if flag == True:
print("Detected")
playsound.playsound('success.mp3')
detectionLabel['text']=f"DETECTED:\n{response}"
else:
detectionWindow.after(5000,lambda: loopOver(flag))
loopOver(flag)

Continuing function after else

thanks in advance for the help!
I'm building a simple program; the idea is for it to periodically check whether a variable has changed and, if it has, do something and, if not, check again. Use case: show a graph derived from the user's current URL in their browser; if the URL is unchanged, do nothing, if it changes, redraw the graph.
I'm running into an issue; I want my function to keep running while the condition is met, and if the condition is not met do something else, but then keep running.
Here's my while function code; my IDE and reading are telling me that "continue" is not permitted here: is there another way that I can keep my function active? Conversely, please do let me know if this is a foolish way to achieve what I'm trying to do!
while new_value != previous_value:
#wait
#do something
#put contents of new_value into previous_value
#update new_value from external source (e.g. URL from browser, which may or not be have changed)
else:
#wait
#do nothing
#put contents of new_value into previous_value
#update new_value from external source
continue
that's an alright start. The while loop will stop if the values are identical which is often. Inside the while loop you can add an if statement for the desired result. While True keeps going until stopped.
while True:
#wait for a couple of seconds
if new_value != previous_value:
#do something
#put contents of new_value into previous_value
#update new_value from external source
I would try something like this:
while True:
#wait some seconds if you need
if(new_value != previous_value):
#do something
else:
#update new_value from external source
I would use a while loop to keep your program running, and then use an if/else statement within the loop. Then just use break statement to stop running the loop.
while True:
if new_value != previous_value:
# Run your code
else:
# Run your code
# When I want the loop to end
break
The issue here is that the 'else' statement, when used like this, is being executed once your loop is already broken. As such there is nothing to 'continue' and your IDE is flagging a syntax error.
This is a somewhat obscure Python construct, but it (and the reasoning behind it) are well explained here at 15m53s.
What you're probably meaning to do is this:
while True:
if new_value != previous_value:
# Do one thing
else:
# Do a different thing
# You will need to specify an end condition,
# or it will continue looping indefinitely.
if exit_conditon_met:
break

Is it possible to programmatically check for a new connection using PySerial?

I found this post which asks a similar question. However, the answers were not what I expected to find so I'm going to try asking it a little differently.
Let's assume a function searching_for_connection will run indefinitely in a while True loop. It that function, we'll loop and preform a check to see if a new connection has been made with /dev/ttyAMA0. If that connection exists, exit the loop, finish searching_for_connection, and begin some other processes. Is this possible to do and how would I go about doing that?
My current approach is sending a carriage return and checking for a response. My problem is that this method has been pretty spotty and hasn't yielded consistent results for me. Sometimes this method works and sometimes it will just stop working
def serial_device_connected(serial_device: "serial.Serial") -> bool:
try:
serial_device.write(b"\r")
return bool(serial_device.readlines())
except serial.SerialException
return False
I suggest having a delay to allow time for the device to respond.
import time
def serial_device_connected(serial_device: "serial.Serial") -> bool:
try:
serial_device.write(b"\r")
time.sleep(0.01)
return bool(serial_device.readlines())
except serial.SerialException
return False

How do I set up this threaded socket read properly?

UPDATE: I found the source of the program hanging. In my pdthread it calls mysocket1.sendall(mydata). It doesn't seem to be able to get past this. Does anyone know why this might be an issue?
I have the following code:
mysocket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysocket1.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
mysocket1.connect(('127.0.0.1', 10001))
while mysocket1:
try:
msg = mysocket1.recv(4092)
msg = pickle.loads(msg)
print(msg)
for pd in pd_objects:
if msg[0] == pd.cam_ip and str(msg[1]) == 'ON' and pd.pd_active == False:
pd.pd_active = True
pdthread = Thread(target=get_pd_data(pd.cam_ip))
pdthread.daemon = True
pdthread.start()
print("testing1")
elif msg[0] == pd.cam_ip and msg[1] == 'OFF':
pd.pd_active = False
print("testing else")
print("testing2")
except:
traceback.print_exc(file=sys.stdout)
break
print("reached end")
I have another python program connected on the other end. This connects and runs perfectly the first time I press a button to activate it. I have my data sending over in the pdthread and all works swell. It's what happens afterwards that's the problem. Future button presses are NOT picked up by this side. The data is being sent over the socket just fine from the other end, it's just not being received here.
I've put in some prints for testing and I found a few interesting things that I cannot explain which is why I'm asking here:
The print("testing1") is never printed. Ever. Not even after the first successful click. Which makes me think that pdthread.start() is behaving like pdthread.join()... which confuses me.
The print("testing else") is never printed. This is expected given my testing but I wanted to rule it out.
Here's the weirdest one. I have two items in my pd_objects list. When I click the button that sends the pd.cam_ip of the first item, print("testing2") does not print, but it DOES print if I click the one for the second item in the list.
Can anyone help explain this bizarre behaviour?
EDIT: the final print is also never printed

how to check if any program is running in windows using python

I would like to use win32 in python to create 2 functions... 1. A function that checks if a certain application is running. 2. A function that checks if an application is installed...
I have tried the following to check if something is running;
def IsRunning(ProgramName):
if win32ui.FindWindow(None, ProgramName):
print("its running")
return True
else:
print("its not running!")
but the findwindow always throws an error if the program is not running before my program ever gets to the else statement and I do not know how to bypass that....
I needed to pass it like this;
def IsRunning(WindowName):
try:
if win32ui.FindWindow(None, WindowName):
print("its running")
return True
except win32ui.error:
print("its not running!")
return False
You need to put the window title exactly for it to pass the test and return True...
The next thing I want to write is a similar function that uses regular expressions to find any part of a title name...
Brilliant!!! Happy now :)
The only thing with this, is that if the Applications creator decides to change the title of the main window of the program you are trying to test for, it will no longer work... I was hoping for a much more robust way of doing it... i.e. through some kind of unique process code!
in any case this will do for the time being, but if anyone has a more definitive answer please let me know...

Categories