Python - Running Command Based on Result of If Statement - python

I am fairly new to Python and coming from a JavaScript background where I am familiar with capturing the output of a command (success, error) and chaining that result to indicate my application's next command. Is there an approach to do something similar in Python?
For example, I am using the gspread package to interact with a Google Sheet. I am running the command gc.open(*Name*) that searches for a Google Sheet when provided a string (*Name*), but if this does not return a value or if it returns an error as it currently does, SpreadsheetNotFound:, then I would create a sheet with gc.create(*Name) criteria. I was playing around with try/exception, but felt like I was approaching it incorrectly.
This is what I'm hoping to achieve:
if (API Call Finds the Sheet):
Set regression_output = sheet
else:
Set regression_output = creation of sheet with specified name
Current Code:
open_regression_output_sheet = gc.open(file_name)
for value in open_regression_output_sheet:
try:
regression_output = print("Test")
except:
regression_output = print("Error")
Error:
SpreadsheetNotFound:

How about a logic breakdown as such:
try:
open_regression_output_sheet = gc.open(file_name)
except:
print 'SpreadsheetNotFound raised, creating new spreadsheet'
open_regression_output_sheet = gc.create('A new spreadsheet')

You're on the right track with try/except, but pay careful attention to where the traceback says the exception was raised. I'm guessing it was actually the
open_regression_output_sheet = gc.open(file_name) line that raised the exception.
If that's the case, you need to wrap that line in a try/except like
try:
open_regression_output_sheet = gc.open(file_name)
except SpreadsheetNotFound:
# handle the exception or whatever
else:
for value in open_regression_output_sheet:
...

Related

Python - do something and continue when process finished with exit code 1

I have created a text file content reader - I have created several functions but I can't handle all cases - if some case is not defined, the program returns the message "Process finished with exit code 1" - Is it possible to get around this? If there is a problem - the Process finished with exit code 1 message - then I would like to save the name of the file and continue reading the rest of the files - at the moment it works so that if there is an error the program just stops working - but I want it to save the name of the file with the error and continue working. How to add such a condition to existing functions?
Please give me some advice
Example of such an error:
import pandas as pd
list=['a',2,3,4]
df = pd.DataFrame(list)
df[0] = df[0].astype(int)
print (df)
Can't convert a character into an int so an error occurs.
This is only an example of a possible error, but the name of the file where the error occurs should be saved and the loop should continue.
As you haven't included any code, I assume that the error was created by a block of code. In that case, you can enclose it within a try block and add an 'except` block to save the file's name in a file.
for example,
try :
# to read your files
except: # an exception occurred
# save the file name in a log
continue
try to share your code for better help.
EDIT 1 : Added an explanation for using plain except.
As documented, SystemExit does not inherit from Exception. You would have to use except BaseException.
However, this is for a reason:
This exception inherits from BaseException instead of StandardError or
Exception so that it is not accidentally caught by code that catches
Exception.
It is unusual to want to handle "real" exceptions in the same way you want to handle SystemExit. You might be better off catching SystemExit explicitly with except SystemExit.

How can you return good data from inside a function if the function breaks?

I am gathering data from a web api (using python) and I am using a loop to go through thousands of calls to the api. The function was running fine but my computer went to sleep and the internet connection was lost. I am storing the data as a list of dictionarys while calling the api. My question is this: When the function failed, since my list was inside the function I can't even get the several hundred successful calls it made before it failed. How can I add error handling or some other method so that if it fails at some point, say after 500 calls, I can still get 499 pieces of data?
If I had run the code without putting it into a function, my list would still be viable up to the point the code broke, but I felt like putting it into a function was "more correct"
#this is how the function is set up in pseudo-code:
def api_call(x):
my_info = []
for i in x:
dictionary = {}
url=f'http://www.api.com/{x}'
dictionary['data'] = json['data']
my_info.append(dictionary)
return my_info
another_variable = api_call(x)
Just wrap it in a try/except/finally block. The finally is always executed before leaving the try statement. Explanation of what the finally block does is here.
def api_call(x):
my_info = []
try:
for i in x:
dictionary = {}
url=f'http://www.api.com/{x}'
dictionary['data'] = json['data']
my_info.append(dictionary)
except Exception as e:
print('Oopsie') # Can log the error here if you need to
finally:
return my_info
another_variable = api_call(x)

Python as Hive UDF - Clean Exit on Exception

I'm trying to do a clean exit from the program whenever my python as Hive UDF fails with an exception.
Here is an example:
SELECT TRANSFORM (id, name) USING
'D:\Python27\python.exe streaming.py' AS (id string,
name string, count integer) FROM hivesampletable;
#streaming.py
import sys
from datetime import datetime
try:
for line in sys.stdin.readlines():
fields = line.strip().split('\t')
fields.append(len(name))
print "\t".join(fields)
except:
#I want program to break/clean exit with out printing (writing back) to table
Ideas appreciated
The pass statement will let you ignore the error and return control flow to your program.
except Exception, e:
pass
#To see your exception
print str(e)
# Alternately, you could get details of your exception using
print sys.exc_info()
If you essentially want to "swallow" the exception, then I would recommend in the except block you explicitly call sys.exit(0), which will both exit the program and indicate (from a shell level) that the program is "OK".
e.g. You will end up with a a truly clean exit that even a shell, e.g. bash, will see as "success".
Note: If you want to exit without printing anything but allow a shell to know something went awry, pass a non-zero error code to exit.
Response to comment from OP:
Hmm, I wouldn't expect that, since you're explicitly swallowing the exception...
The next step would likely be to print out what the exception is, as was suggested in the other answer, and go from there, depending on what that exception is.
Another thing that may be contributing is I don't think your Python script matches your TRANSFORM statement, so that may be contributing to the issue.
Also, you are referencing name without that being initialized (that might be the exception here -- NameError: name 'name' is not defined).

Display message on crash in Python?

I am [relatively] new to python, and I'm making an application that calculates compound interest. I want users to be able to report their crashes, and to do this I need to write some code that executes when there is a problem and the program stops running. I just want to display some text and show the contents of some variables so the user can cut and paste them into an email.
Is this feasible?
Thanks!
If you know something that will throw an error, use a try except finally block.
try:
raise ANonSenseError()
except ANonSenseError:
# Log it
# Bring some dialog for users to report it.
finally:
# Well, this part is optional, but you can use it in case an exception isn't thrown
# It will always run
If you don't want to use the try except block, you could try and establish something that will have to execute if the program stops. You might not be able to find out what error it is, but you will have the flexibility of doing anything freely after the main section of your program crashes.
Also, a suggestion if you're using Tkinter: use Tkinter.Toplevel to raise a top level window.
Take a look at this question, which should give you some guidance about raising a new window when your main application crashes.
Sure take a look at how to use try/except here: https://docs.python.org/3.4/tutorial/errors.html
Example:
#!/usr/bin/env python3
import sys
def calculation():
return 1/0
if __name__ == "__main__":
try:
print(calculation())
except Exception as e:
print("Oops, something went wrong: {}".format(e), file=sys.stderr)
sys.exit(1)
Use the traceback module to handle you stacktrace. I use this under most of my exceptions
import traceback
import sys, os
try:
bla
except Exception as e:
top = traceback.extract_tb(sys.exc_info()[2])[-1]
print '{} : {} in {} at line {}'.format(type(e).__name__, str(e), os.path.basename(top[0]), str(top[1]))
Output:
NameError : name 'bla' is not defined in test.py at line 4

Recovering from ECONNRESET in Python/Mechanize

I've got a large bulk downloading application written in Python/Mechanize, aiming to download something like 20,000 files. Clearly, any downloader that big is occasionally going to run into some ECONNRESET errors. Now, I know how to handle each of these individually, but there's two problems with that:
I'd really rather not wrap every single outbound web call in a try/catch block.
Even if I were to do so, there's trouble with knowing how to handle the errors once the exception has thrown. If the code is just
data = browser.response().read()
then I know precisely how to deal with it, namely:
data = None
while (data == None):
try:
data = browser.response().read()
except IOError as e:
if e.args[1].args[0].errno != errno.ECONNRESET:
raise
data = None
but if it's just a random instance of
browser.follow_link(link)
then how do I know what Mechanize's internal state looks like if an ECONNRESET is thrown somewhere in here? For example, do I need to call browser.back() before I try the code again? What's the proper way to recover from that kind of error?
EDIT: The solution in the accepted answer certainly works, and in my case it turned out to be not so hard to implement. I'm still academically interested, however, in whether there's an error handling mechanism that could result in quicker error catching.
Perhaps place the try..except block higher up in the chain of command:
import collections
def download_file(url):
# Bundle together the bunch of browser calls necessary to download one file.
browser.follow_link(...)
...
response=browser.response()
data=response.read()
urls=collections.deque(urls)
while urls:
url=urls.popleft()
try:
download_file(url)
except IOError as err:
if err.args[1].args[0].errno != errno.ECONNRESET:
raise
else:
# if ECONNRESET error, add the url back to urls to try again later
urls.append(url)

Categories