How to except SyntaxError? - python

I would like to except the error the following code produces, but I don't know how.
from datetime import datetime
try:
date = datetime(2009, 12a, 31)
except:
print "error"
The code above is not printing "error". That's what I would like to be able to do.
edit: The reason I would like to check for syntax errors, is because 12a is a command line parameter.
Thanks.

command-line "parameters" are strings. if your code is:
datetime(2009, '12a', 31)
it won't produce SyntaxError. It raises TypeError.
All command-line parameters are needed to be cleaned up first, before use in your code. for example like this:
month = '12'
try:
month = int(month)
except ValueError:
print('bad argument for month')
raise
else:
if not 1<= month <= 12:
raise ValueError('month should be between 1 to 12')

You can't catch syntax errors because the source must be valid before it can be executed. I am not quite sure, why you can't simple fix the syntax error, but if the line with the datetime is generated automatically from user input (?) and you must be able to catch those errors, you might try:
try:
date = eval('datetime(2009, 12a, 31)')
except SyntaxError:
print 'error'
But that's still a horrible solution. Maybe you can tell us why you have to catch such syntax errors.

If you want to check command-line parameters, you could also use argparse or optparse, they will handle the syntax check for you.

Related

Python string indices must be integers

I'm reading a Dictionary from an API which has a field called 'price'.
I'm reading it fine for a while (so, the code works) until I get to a point I get the error message: string indices must be integers.
That breaks my code.
So, I would like to find a way to skip it (ignore it) when this happens, and continue with the code. And just print something out so I know something happened.
So, far I don't manage to see what number is causing this error.
If I test this by itself, it works fine.
fill = {'price': 0.00002781 }
price = fill['price'] # OUTPUT: string indices must be integers
print(price)
I've tried many things:
from decimal import Decimal
price = decimal(fill['price'])
also:
price = int(fill['price']) # but it's not really an int
and:
price = float(fill['price']) # but sometimes it's a very big float so I need decimal
It seems that what you get from the API is not exactly what you expect:
The variable fill is a string (at least at the time you get the error).
As strings can't have string indices (like dictionaries can) you get the TypeError exception.
To handle the exception and troubleshoot it, you can use try-except, like so:
try:
price = fill['price']
except TypeError as e:
print(f"fill: {fill}, exception: {str(e)}")
This way, when there is an issue, the fill value will be printed as well as the exception.
string indices must be integers tells you that the type of fill during runtime at some point is a str instead of Dict. I suggest that you add type checking or assertion to your program to make sure fill is of the expected type.
If you want to just ignore it you could use try and except blocks.
try:
price = fill['price']
except Exception as e:
print(f"Error reading the price. Error: {e}")

Is there a python equivalent to the Unix '$?' command?

I am using fastjsonschema for validating json records against its schema.
Some thing like this:
import fastjsonschema
validate = fastjsonschema.compile({'type': 'string'})
validate('hello')
If the json is valid, it returns the json string else return the error string. I just want to check if the json is valid or not. For this I can do a workaround of comparing output of the validate method and the json input.
But I want something cleaner. May be something like '$?' in unix or something better.
Could you suggest me?
From the documentation, there seem to be two different exceptions thrown in case of error:
JsonSchemaDefinitionException, when the definition is bad
JsonSchemaException, when the data is not matching the definition
In Python, you can simply wrap that with a try ... except block like this:
try:
validate = fastjsonschema.compile({'type': 'string'})
validate(1)
except (fastjsonschema.JsonSchemaException, fastjsonschema.JsonSchemaDefinitionException):
print("Uh oh ...")

Python try-except-except

Im gonna include the description of the task this code is supposed to do in case someone needs it to answer me.
#Write a function called "load_file" that accepts one
#parameter: a filename. The function should open the
#file and return the contents.#
#
# - If the contents of the file can be interpreted as
# an integer, return the contents as an integer.
# - Otherwise, if the contents of the file can be
# interpreted as a float, return the contents as a
# float.
# - Otherwise, return the contents of the file as a
# string.
#
#You may assume that the file has only one line.
#
#Hints:
#
# - Don't forget to close the file when you're done!
# - Remember, anything you read from a file is
# initially interpreted as a string.
#Write your function here!
def load_file(filename):
file=open(filename, "r")
try:
return int(file.readline())
except ValueError:
return float(file.readline())
except:
return str(file.readline())
finally:
file.close()
#Below are some lines of code that will test your function.
#You can change the value of the variable(s) to test your
#function with different inputs.
#
#If your function works correctly, this will originally
#print 123, followed by <class 'int'>.
contents = load_file("LoadFromFileInput.txt")
print(contents)
print(type(contents))
When the code is tested with a file which contains "123", then everything works fine. When the website loads in another file to test this code, following error occurs:
[Executed at: Sat Feb 2 7:02:54 PST 2019]
We found a few things wrong with your code. The first one is shown below, and the rest can be found in full_results.txt in the dropdown in the top left:
We tested your code with filename = "AutomatedTest-uwixoW.txt". We expected load_file to return the float -97.88285. However, it instead encountered the following error:
ValueError: could not convert string to float:
So Im guessing the error occurs inside the first except statement, but i don't understand why. If an error occurs when the value inside a file is being converted to float, shouldnt the code just go to the second except statement ? And in the second except it would be converted to string, which will work anyway ? I'm guessing i misunderstand something about how try-except(specified error)-except(no specified error) works.
Sorry for long post.
shouldnt the code just go to the second except statement ?
Nope: this "flat" try/except statement works only for the first try block. If an exception occurs there, the except branches catch this exception and straight away evaluate the appropriate block. If an exception occurs in this block, it's not caught by anything, because there's no try block there.
So, you'd have to do a whole lot of nested try/except statements:
try:
do_this()
except ValueError:
try:
do_that()
except ValueError:
do_this()
except:
do_that_one()
except:
# a whole bunch of try/except here as well
You may need to add an extra level of nesting.
This is terribly inefficient in terms of the amount of code you'll need to write. A better option might be:
data = file.readline()
for converter in (int, float, str):
try:
return converter(data)
except:
pass
Note that if you do converter(file.readline()), a new line will be read on each iteration (or, in your case, in any new try/except block), which may not be what you need.
No, only one of those except blocks -- the first one matching the exception -- will be executed. The behavior you are describing would correspond to
except ValueError:
try:
return float(file.readline())
except:
return str(file.readline())
def load_file(filename):
file=open(filename, "r")
try:
val = file.readline()
return int(val)
except ValueError:
try:
return float(val)
except:
return str(val)
finally:
file.close()

python3 exception invalid syntax error

I recently started learning python3, and I am trying to write an exception.
I have this line, which is a list of words.
I want to match the word create to the list, sometimes it's there sometimes its not. When it's not there I get this error:
Traceback (most recent call last):
File "sub_process.py", line 17, in <module>
if (line.index("create")):
ValueError: 'create' is not in list
and I am fine with that. This is expected. So I thought if I wrote an exception to it the script could just continue on and keep doing stuff. So I an exception below and all its suppose to do is nothing. Catch the error and continue on.
line = line.split()
if line.index("create"):
print("basd");
except ValueError:
print("123");
But everytime i try to compile this I get syntax error at "except" and I am not sure why. It looks perfectly normal compared against all the tutorials that I could find.
Rather than using index, you should just be using the in operator, which returns a simple boolean:
if "create" in line:
print("basd")
else:
print("123")
This will not raise an exception so there is no need for try/except.
if/except is not a valid construct. Use try/except:
line = line.split()
try:
if line.index('create'):
print('basd')
except ValueError:
print("123")
Alternatively, you could avoid the exception and the try/except altogether:
line = line.split()
if 'create' in line:
print('basd')
else:
print("123")
You need to add try before the if statement:
line = line.split()
try: # added 'try'
if line.index("create"):
print("basd");
except ValueError:
print("123");
Also note, you don't need the semicolons at the end of statements, and it is generally frowned upon when they are used in that way.
As an alterintave to #Rosemans solution, you can do that all on one line:
print('basd') if "create" in line else print("123")
#use try block..
line = line.split()
try:
if line.index("create"):
print("basd")
except ValueError:
print("123")

Python BeautifulSoup is unnecessarily slow

While this code works pretty fast:
for olay in soup("li", {"class":"textb"}):
tanim = olay("strong")
try:
print tanim[0]
except IndexError:
pass
Getting string property like this makes this code considerably slower:
for olay in soup("li", {"class":"textb"}):
tanim = olay("strong")
try:
print tanim[0].string
except IndexError:
pass
My question is, am I doing something that I shouldn't getting string property like that? Should I have used something else to get plain text version of an object?
Update:
This is also working pretty fast, so slowness is unique to string property I guess?
for olay in soup("li", {"class":"textb"}):
tanim = olay("strong")
try:
print tanim[0].text
except IndexError:
pass
If you just want to print the string representation of tanim[0]. You should just do: print str(tanim[0]). Also, do a dir(tanim[0]) to see if it has a property called string at all.
for olay in soup("li", {"class":"textb"}):
tanim = olay("strong")
try:
print str(tanim[0])
except IndexError:
pass
For everyone to provide a better answer, you could also post the target HTML or the URI and mention which bit you are trying to extract out of it.

Categories