How to catch and manage exceptions for GPS module? - python

I have a raspberry pi using a GPS module. To use the module, I am running a code such as this:
##Prints the latitude and longitude every second.
import time
import microstacknode.hardware.gps.l80gps
if __name__ == '__main__':
gps = microstacknode.hardware.gps.l80gps.L80GPS()
while True:
data = gps.get_gpgga()
List = [list(data.values())[x] for x in [7, 9, 12]]
string=str(List)
string = string[1:-1]
text_file = open("/home/pi/fyp/gps.txt","a")
text_file.write(string + "\n")
time.sleep(1)
However, every now and then it gives this error because it cannot find my location:
Traceback (most recent call last):
File "gps.py", line 8, in <module>
data = gps.get_gpgga()
File "/usr/lib/python3/dist-packages/microstacknode/hardware/gps/l80gps.py", line 119, in get_gpgga
pkt = self.get_nmea_pkt('GPGGA')
File "/usr/lib/python3/dist-packages/microstacknode/hardware/gps/l80gps.py", line 293, in get_nmea_pkt
"Timed out before valid '{}'.".format(pattern))
microstacknode.hardware.gps.l80gps.NMEAPacketNotFoundError: Timed out before valid 'GPGGA'.
It's alright to have that error. The trouble I have is that the program stops running if it occurs. Is there a way to catch that error and get the program to loop back and try again even if it encounters this error?
UPDATE
if I try Stefan_Reinhardt's method, I would get the following error instead:
Traceback (most recent call last):
File "gps.py", line 9, in <module>
data = gps.get_gpgga()
File "/usr/lib/python3/dist-packages/microstacknode/hardware/gps/l80gps.py", line 119, in get_gpgga
pkt = self.get_nmea_pkt('GPGGA')
File "/usr/lib/python3/dist-packages/microstacknode/hardware/gps/l80gps.py", line 293, in get_nmea_pkt
"Timed out before valid '{}'.".format(pattern))
microstacknode.hardware.gps.l80gps.NMEAPacketNotFoundError: Timed out before valid 'GPGGA'.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "gps.py", line 10, in <module>
except NMEAPacketNotFoundError:
NameError: name 'NMEAPacketNotFoundError' is not defined

I agree to the answer of Oisin,
but i'd suggest to put the try-except clause only arround the line where it could happen, and pass the rest of the while-loop with a continue statement so it would look like
##Prints the latitude and longitude every second.
import time
import microstacknode.hardware.gps.l80gps
if __name__ == '__main__':
gps = microstacknode.hardware.gps.l80gps.L80GPS()
while True:
try:
data = gps.get_gpgga()
except NMEAPacketNotFoundError:
continue
List = [list(data.values())[x] for x in [7, 9, 12]]
string=str(List)
string = string[1:-1]
text_file = open("/home/pi/fyp/gps.txt","a")
text_file.write(string + "\n")
time.sleep(1)

This should work but it could get stuck in an infinite recursion loop.
##Prints the latitude and longitude every second.
import time
import microstacknode.hardware.gps.l80gps
if __name__ == '__main__':
getPos()
def getPos():
try:
while True:
gps = microstacknode.hardware.gps.l80gps.L80GPS()
data = gps.get_gpgga()
List = [list(data.values())[x] for x in [7, 9, 12]]
string=str(List)
string = string[1:-1]
text_file = open("/home/pi/fyp/gps.txt","a")
text_file.write(string + "\n")
time.sleep(1)
except microstacknode.hardware.gps.l80gps.NMEAPacketNotFoundError:
getPos()

Related

How to print line number of error that is inside a function using except in Python?

I want to print an error's line number and error message in a nicely displayed way. The follow is my code, which uses linecache:
import linecache
def func():
if xx == 1:
print('ok')
try:
func()
except:
exc_type, exc_obj, tb = sys.exc_info()
f = tb.tb_frame
lineno = tb.tb_lineno
filename = f.f_code.co_filename
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, f.f_globals)
print_('ERROR - (LINE {} "{}"): {}'.format(lineno, line.strip(), exc_obj))
However, this only gives where the func() is called:
ERROR - (LINE 8 ""): name 'xx' is not defined
Is there a way to print the line number where the error actually occured, which should be Line 4? Or even better, can I print Line 8 and then trace back to line 4? For example, if I do not use try - except, the code:
def func():
if xx == 1:
print('ok')
func()
will give me the following error message, which is much better to locate the error:
File "<input>", line 5, in <module>
File "<input>", line 2, in func
NameError: name 'xx' is not defined. Did you mean: 'xxx'?
You can use traceback and sys modules to get advanced traceback output like you are wishing for.
Here is an example:
import traceback
import sys
def func():
zeroDivide = 1 / 0
try:
func()
except Exception:
print(traceback.format_exc()) # This line is for getting traceback.
print(sys.exc_info()[2]) # This line is getting for the error type.
Output will be:
Traceback (most recent call last):
File "b:\abc\1234\pppp\main.py", line 10, in <module>
func()
File "b:\abc\1234\pppp\main.py", line 7, in func
zeroDivide = 1 / 0
ZeroDivisionError: division by zero
You can use the traceback module to get the line number of the error,
import traceback
def function():
try:
# code
except:
tb_list = traceback.extract_tb(sys.exc_info()[2])
line_number = tb_list[-1][1]
print("An error occurred on line:", line_number)
You can use the traceback.extract_tb() function. This function returns a list of traceback objects, each of which contain information about the stack trace. The last element of this list, tb_list[-1], holds information about the line where the exception occurred. To access the line number, you can use the second element of this tuple, tb_list[-1][1]. This value can then be printed using the print() function.
To get the line number as an int you can get the traceback as a list from traceback.extract_tb(). Looking at the last item gives you the line where the exception was raised:
#soPrintLineOfError2
import sys
import traceback
def func():
if xx == 1:
print('ok')
try:
func()
except Exception as e:
tb = sys.exc_info()[2]
ss = traceback.extract_tb(tb)
ss1 = ss[-1]
print(ss1.line)
print(ss1.lineno)
Output:
if xx == 1:
6

Exception: Failed to process waveform

Error:
Traceback (most recent call last):
File "c:\Programming\New_assistant\speech_to_text.py", line 18, in <module>
if rec.AcceptWaveform(data):
File "C:\Users\david\AppData\Local\Programs\Python\Python310\lib\site-packages\vosk\__init__.py", line 84, in AcceptWaveform
raise Exception("Failed to process waveform")
Exception: Failed to process waveform
PS C:\Programming\New_assistant>
I get this error when I try to use AcceptWaveform regardless of the file (wav) or the rest of the code, but the error is removed only when using vosk-model-small-ru-0.22, and does not give errors on vosk-model-ru-0.22, but the processing time is too long.
Code:
from vosk import Model, KaldiRecognizer
import json
import wave
model = Model(r"File\vosk-model-small-ru-0.22")
wf = wave.open(r"File\record1.wav", "rb")
rec = KaldiRecognizer(model, 8000)
result = ''
last_n = False
while True:
data = wf.readframes(8000)
if len(data) == 0:
break
if rec.AcceptWaveform(data):
res = json.loads(rec.Result())
if res['text'] != '':
result += f" {res['text']}"
last_n = False
elif not last_n:
result += '\n'
last_n = True
res = json.loads(rec.FinalResult())
result += f" {res['text']}"
print(result)
Using the poke method, I found a solution and got an assumption about the error occurring, so if I'm wrong or you have a more complete solution, add it and I'll mark it.
If you copied the sample code using vosk, then most likely this is the version with the module vosk-model-ru-0.22 which works with the sampling rate 8000,but vosk-model-small-ru-0.22 works with 44100, so just change 8000 to 44100 (depending on the entry)

string index out of range? - python

im buliding a chat and i'm keep getting the next error:
Traceback (most recent call last):
File "C:/Users/ronen/Documents/CyberLink/tryccc.py", line 651, in <module>
main()
File "C:/Users/ronen/Documents/CyberLink/tryccc.py", line 630, in main
print_message(data_from_server, len(temp_message), username)
File "C:/Users/ronen/Documents/CyberLink/tryccc.py", line 265, in print_message
temp_l = data[0]
IndexError: string index out of range
i am trying to get the first char of the data string and convert it into int but i get this error
the problem is in the first line of the code
def print_message(d_temp, line_length, this_username):
temp_l = d_temp[0] #the problematic line
len_username = int(temp_l)
username_sender = d_temp[1:(len_username + 1)]
message_sent = d_temp[(len_username + 1): -4]
hour_time = d_temp[-4: -2]
min_time = d_temp[-2:]
printed_message = "\r" + hour_time + ":" + min_time + " " + username_sender + " : " + message_sent
print printed_message, # Prints this message on top of what perhaps this client started writing.
# if this client started typing message
complete_line_with_space(len(printed_message), line_length)
data- the data (string) from the server
line_length - the length of the temp massage
this_username - the client's username
thank you to all the helpers
empty d_temp will give this error.
This might be the reason:
>>> d_temp = ""
>>> d_temp[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
This happens because print_message is executed with an empty string as first parameter
print_message("",...)
This means the problem is somewhere else in your code.

Python NameError when var IS most definitely defined

def make_pdf(self):
self.get_filez()
self.get_client()
file_name = self.client_id+"_"+self.client_name+"_"+self.batch_num
style = libxslt.parseStylesheetDoc(self.xsl_file)
transformation = style.applyStylesheet(self.xml_file,None)
style.saveResultToFilename("tmp/"+file_name+".fo",transformation,0)
style.freeStylesheet()
self.xml_file.freeDoc()
transformation.freeDoc()
fop_cmd = "/usr/bin/xmlgraphics-fop"
#file_name = self.tpa+"_"+self.be+"_"+self.batch_num
cmd = [fop_cmd,"-fo","tmp/"+file_name+".fo","-pdf","tmp/"+file_name+".pdf"]
#fop_transform = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
#fop_log = "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
#fop_log = fop_log + time.strftime('%Y-%m-%d %R:%S')+"\n"
#fop_log = fop_log + file_name+".fo" + "\n"
#fop_log = fop_transform.communicate()[0]+"\n"
#f = open("/tmp/error_log","a")
#f.write(fop_log)
#f.close()
OK If I comment out the cmd variable declaration the code runs and makes an fo file correctly. With is uncommented like it is above, I get a NameError on file_name is not defined (which it is in the top). If I uncomment the second declaration of file_name right above the cmd declaratioin, it thows a NameError on self. '.' In the past when this sort of thing happens, it is a syntax error. I am missing it, please helpz!
When the second declaration of file_name is commented out:
Traceback (most recent call last):
File "make_pdfs.py", line 11, in ?
from MakePdfs import MakePdfs
File "/home/khouser/removed/removed/MakePdfs.py", line 16, in ?
class MakePdfs:
File "/home/khouser/removed/removed/MakePdfs.py", line 39, in MakePdfs
cmd = [fop_cmd,"-fo","tmp/"+file_name+".fo","-pdf","tmp/"+file_name+".pdf"]
NameError: name 'file_name' is not defined
When the second declaration of file_name is uncommented:
Traceback (most recent call last):
File "make_pdfs.py", line 11, in ?
from MakePdfs import MakePdfs
File "/home/khouser/removed/removed/MakePdfs.py", line 16, in ?
class MakePdfs:
File "/home/khouser/removed/removed/MakePdfs.py", line 38, in MakePdfs
file_name = self.tpa+"_"+self.be+"_"+self.batch_num
NameError: name 'self' is not defined
Mysterious NameErrors may arise from your file containing invisible control characters. On unix machines, you can spot these errors by looking at the output of
cat -A filename.py
Try to print file_name after each line, to see if somebody is removing the "file_name" variable from your namespace.
In addition, to be more pythonic (and efficient), use
file_name = "_".join((self.client_id, self.client_name, self.batch_num))
to concatenate strings.
If you're assigning file_name here:
file_name = self.client_id+"_"+self.client_name+"_"+self.batch_num
And you're getting a NameError reporting, that file_name is not defined, then try wrapping the operation in a try..except, to see what is going wrong:
try:
file_name = self.client_id+"_"+self.client_name+"_"+self.batch_num
except NameError as err:
print err, 'failed, here is some debug stuff:'
print "CLIENT ID =", self.client_id
print "CLIENT NAME =", self.client_name
print "BATCH NUM =", self.batch_num
If any of this is failing, this will set you on the course to finding out why and narrowing down the cause of it.

Python isn't catching KeyError properly

I've tried two different versions of the same function:
def position_of(self, table_name, column_name):
positions = self.heading_positions()
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
return position
-
def position_of(self, table_name, column_name):
positions = self.heading_positions()
try:
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
except KeyError:
raise RuntimeError('No heading found for {t}.{c} in import profile "{ip}"'.format(t=table_name, c=column_name, ip=self))
return position
With the first version, I get the following error, which is fine:
Traceback (most recent call last):
File "./import.py", line 15, in <module>
g.process()
File "/home/jason/projects/mcifdjango/mcif/models/generic_import.py", line 39, in process
row.process()
File "/home/jason/projects/mcifdjango/mcif/models/csv_row.py", line 18, in process
self.save()
File "/home/jason/projects/mcifdjango/mcif/models/csv_row.py", line 26, in save
self.output("Phone: " + self.value('customer', 'phone'));
File "/home/jason/projects/mcifdjango/mcif/models/csv_row.py", line 60, in value
print self.generic_import.import_profile.position_of(table_name, column_name)
File "/home/jason/projects/mcifdjango/mcif/models/import_profile.py", line 22, in position_of
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
KeyError: 'customer.phone'
But the second version - the one that has the more informative error description - fails silently. Why is this?
The second version of position_of works fine for me. I have turned it into a minimal complete program as follows:
class Test(object):
def heading_positions(self):
return {}
def position_of(self, table_name, column_name):
positions = self.heading_positions()
try:
position = positions['{t}.{c}'.format(t=table_name, c=column_name)]
except KeyError:
raise RuntimeError('No heading found for {t}.{c} in import profile "{ip}"'.format(t=table_name, c=column_name, ip=self))
return position
a = Test()
a.position_of('customer', 'phone')
When I run this (using Python 2.6.6 on MacOS X) I get the following error message as expected:
Traceback (most recent call last):
File "./a.py", line 17, in <module>
a.position_of('customer', 'phone')
File "./a.py", line 13, in position_of
raise RuntimeError('No heading found for {t}.{c} in import profile "{ip}"'.format(t=table_name, c=column_name, ip=self))
RuntimeError: No heading found for customer.phone in import profile "<__main__.Test object at 0x100426ad0>"
This shows that catching the KeyError and turning it into a RuntimeError works fine. Does this example work for you? As Sven already writes, a possible explanation would be if you catch RuntimeError but not KeyError somewhere in the call chain.

Categories

Resources