python 'bool' object is not callable' - python

I have seen a few other similar questions, unfortunately none quite solved my issue. my codes are pretty extensive so not going to paste everything here. my python script is running an excel and a macro within. its does all the fine but when it comes to saving the file down I get the error. I have shown snippets of my codes below. any idea what seems to be happening? it sporadically works well and randomly stops working.
import win32com.client
import time
from datetime import datetime
def openWorkbook(xlapp, xlfile,upDateLink,openReadOnly,wbVisible):
try:
xlwb = xlapp.Workbooks(xlfile,upDateLink,openReadOnly,wbVisible) # the 2nd is for updatelink, 3rd is for OpenReadOnly
except Exception as e:
try:
print('run function')
xlapp.Workbooks.Open('C:\\blp\\API\\Office Tools\\BloombergUI.xla')
xlapp.RegisterXLL('C:/blp/API/Office Tools/bofaddin.dll')
xlwb = xlapp.Workbooks.Open(xlfile,upDateLink,openReadOnly) # the 2nd is for updatelink, 3rd is for OpenReadOnly
xlapp.Visible = wbVisible
except Exception as e:
print(e)
xlwb = None
return(xlwb)
wb1 = openWorkbook(xlapp, filepath,False,True,wbVisible)
filepathSaveStress = "C:\\Users\\abc\\Downloads\\Projects\\Stress" + extractDate2 + ".xlsm"
print('run CalculateValues')
xlapp.Application.run("CalculateValues")
xlapp.DisplayAlerts = False
if stresstype == 'Stress':
wb1.SaveAs(filepathSaveStress)
else:
wb1.SaveAs(filepathSavePostStress)
not sure why it errors out at wb1.SaveAs(filepathSaveStress)
in term or error all I get is this
'bool' object is not callable

Related

How to define multiple error handling statements?

I would like to read a set of csv files from URL as dataframes. These files contain a date in their name like YYYYMMDD.csv in their names. I need to iterate over a set of predefined dates and read the corresponding file into a Python.
Sometimes the file does not exist and an error as follows is thrown:
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found
What I would do in this situation is to add one day to the date like turning 2020-05-01 to 2020-05-02 and in case of throwing the aforementioned error I would add 2 days to the date or at most 3 days until there is a url available without an error.
I would like to know how I can write it in a program maybe with nested try - except where if adding 1 day to the date leads to a URL without error the subsequent steps are not executed.
As I don't have the data I will use the following URL as an example:
import pandas as pd
import requests
url = 'http://winterolympicsmedals.com/medals.csv'
s = requests.get(url).content
c = pd.read_csv(s)
Here the file being read is medals.csv. If you try madels.csv or modals.csv you will get the error I am talking about. So I need to know how I can control the errors in 3 steps by replacing the file name until I get the desired dataframe like first we try madels.csv resulting in an error, then models.csv also resulting in an error and after that medals.csv which result in the desired output.
My problem is that sometimes the modification I made to the file also fails in except so I need to know how I can accommodate a second modification.
No need to do any nested try-except blocks, all you need is one try-except and a for loop.
First, function that tries to read a file (returns content of the file, or None if the file is not found):
def read_file(fp):
try:
with open(fp, 'r') as f:
text = f.read()
return text
except Exception as e:
print(e)
return None
Then, function that tries to find a file from a predefined date (example input would be '20220514'). The functions tries to read content of the file with the given date, or dates up to 3 days after it:
from datetime import datetime, timedelta
def read_from_predefined_date(date):
date_format = '%Y%m%d'
date = datetime.strptime(date, date_format)
result = None
for i in range(4):
date_to_read = date + timedelta(days=i)
date_as_string = date_to_read.strftime(date_format)
fp = f'data/{date_as_string}.csv'
result = read_file(fp)
if result:
break
return result
To test, e.g. create a data/20220515.csv and run following code:
d = '20220514'
result = read_from_predefined_date(d)
here's a simple function that given that URL will do exactly what you ask. Be aware that a slight change in the input url can lead to a few errors so make sure the date format is exactly what you mentioned. In any case:
Notes: URL Parsing
import pandas as pd
import datetime as dt
def url_next_day(url):
# if the full url is passed I suggest you would use urllib parse but
# urllib parse but here's a workaround
filename = url.rstrip("/").split("/")[-1]
date=dt.datetime.strptime(filename.strip(".csv"),"%Y%m%d").date()
date_plus_one_day= date + dt.timedelta(days=1)
new_file_name= dt.datetime.strftime(date_plus_one_day,"%Y%m%d")+".csv"
url_next_day=url.replace(filename,new_file_name)
return url_next_day
for url in list_of_urls:
try:
s = requests.get(url).content
c = pd.read_csv(s)
except Exception as e:
print(f"Invalid URL: {url}. The error: {e}. Trying the days after...")
for _ in range(3): #because you want at most 3 days after
try:
url=url_next_day(url)
s = requests.get(url).content
c = pd.read_csv(s)
break
except Exception:
pass
else:
print("No file available in the days after. Moving on")
Happy Coding!
OK, I have enough changes I want to recommend on top of #Daniel Gonçalves's initial solution that I'm going to post them as a second answer.
1- The loop trying additional days needs to break when it got a hit, so it doesn't keep going.
2- That loop needs an else: block to handle the complete failure case.
3- It is best practice to catch only the exception you mean to catch and know how to handle. Here a urllib.error.HTTPError means a failure to fetch the page, but an other exception would mean something else is wrong with the program, and it would be best not to catch that, so you would notice it and fix your program when that happens.
The result:
for url in list_of_urls:
try:
s = requests.get(url).content
c = pd.read_csv(s)
except urllib.error.HTTPError as e:
print(f"Invalid URL: {url}. The error: {e}. Trying the days after...")
for _ in range(3): #because you want at most 3 days after
try:
url = url_next_day(url)
s = requests.get(url).content
c = pd.read_csv(s)
break
except urllib.error.HTTPError:
print(f"Also failed to fetch {url}...")
else:
# this block is only executed if the loop never breaks
print("No file available in the days after. Moving on.")
c = None # or an empty data frame, or whatever won't crash the rest of your code

Exception handling with Yahoo-finance

I am trying to scrape data using yfinance and have met a road block when trying to retrieve a ticker with no data, the error is - 7086.KL: No data found for this date range, symbol may be delisted.
How do I try catch this error? I've tried try catching it as seen in the code below but it still prints that error.
The code:
tickerdata = yf.Ticker("7086.KL")
try:
history = tickerdata.history(start="2019-06-01", end="2020-05-01")
except ValueError as ve:
print("Error")
Any advise on how to solve this?
I just had a look at the source code. It looks like they are indeed just printing the message. But they are also adding the error to a dictionary in the shared.py file. You can use this to check for errors:
from yfinance import shared
ticker = <ticker as string>
tickerdata = yf.Ticker(ticker)
history = tickerdata.history(start="2019-06-01", end="2020-05-01")
error_message = shared._ERRORS[ticker]

Is there anything wrong with my python code in line 56?

screen shot
hi, I am trying to run this python code for twitter scraping. as it is shown in the screenshot, it gives me a syntax error that I can't figure out. here is the whole code:
print ('Filtering the public timeline for track="%s"' % (q,))
twitter_stream = twitter.TwitterStream(auth=twitter_api.auth)
stream = twitter_stream.statuses.filter(track=q)
for tweet in stream:
try:
if tweet['truncated']:
tweet_text = tweet['extended_tweet']['full_text']
else:
tweet_text = tweet['text']
# write the values to file
csvwriter.writerow([
tweet['created_at'],
getVal(tweet['user']['screen_name']),
getVal(tweet_text),
getVal(tweet['user']['location']),
tweet['user']['statuses_count'],
tweet['user']['followers_count'],
tweet['user']['friends_count'],
tweet['user']['created_at']
])
# print something to the screen, mostly so we can see what is going on...
print (tweet['user']['screen_name'].encode('utf-8'), tweet['text'].encode('utf-8'))
except Exception, err:
print err
pass
I can only assume you are running this using Python 3 and not 2.
This question explains that the format you've used for the except statement would be wrong in that case.
The TL;DR of that post is:
switch the comma to as: except Exception as err:

python UnboundLocalError referenced before assignment

I see that this seems to be a common error, but I'm not seeing the answer for my case.
UnboundLocalError: local variable 'tfstate_dict' referenced before assignment
#!/usr/bin/env python
import json
def main():
get_sfleet_id()
def get_sfleet_id():
try:
f=open("terraform_remote.tfstate", "r")
contents =f.read()
tfstate_dict = json.load(contents)
except:
print("error loading %s" % f)
print(contents)
print(tfstate_dict)
if __name__ == '__main__': main()
As I wrote in my comment, tfstate_dict does not come in to existence until you exit your try block. But that's not to say that it applies to all the preceding code; it simply applies to tfstate_dict because it happens to be the very last line.
This is easily testable with the following:
try:
a = int(2)
b = int(3)
c = int('hi')
except:
print(locals())
print()
print(locals().get('a'))
You should see that 'a' and 'b' are both defined and can be accessed (depending on how you're running this code, there could a lot of stuff in locals() too). So, the existence of 'a' and 'b' gives you no assurance that 'c' exists.
There's two issues with your current exception handling:
There's probably too much going on in your try block to be handled the way you currently do. This code will fail if the file cannot be located, but you wouldn't necessarily know that was happening. And if your code originally failed only on tfstate_dict = json.load(contents) you're now scratching your head why you're getting a NameError on print(contents) all of a sudden.
You don't want to be catching these issues with blanket except. At a minimum you'll want to use except Exception as e:, which allows you to print e too.
Here's a hypothetical situation where you handle the file not existing, and you also give a shot at parsing JSON.
import json
from json.decoder import JSONDecodeError
try:
with open('something.json') as infile:
try:
#data = json.load(infile) # This is what you'd really use
data = json.loads("{hi: 2}") # But let's make it fail
except JSONDecodeError:
print("Not valid JSON, try something else")
data = infile.read()
except FileNotFoundError:
print("Can't find file")
data = ''

Python try except block does not recognize error type

My scrpt has the following line:
libro_dia = xlrd.open_workbook(file_contents = libro_dia)
When libro_dia is not valid, it raises the following error:
XLRDError: Unsupported format, or corrupt file: Expected BOF record; found '<!DOCTYP'
I whant to handle this error, so I write:
try:
libro_dia = xlrd.open_workbook(file_contents = libro_dia)
except XLRDError:
no_termina = False
But it raises the following error:
NameError: name 'XLRDError' is not defined
What's going on?
You don't have XLRDError imported. I'm not familiar with xlrd, but something like:
from xlrd import XLRDError
might work. Alternatively, qualify your Error when handling it:
try:
libro_dia = xlrd.open_workbook(file_contents = libro_dia)
except xlrd.XLRDError: #<-- Qualified error here
no_termina = False
The above is assuming you have the following import:
import xlrd
In response to your comment:
There are several ways to use imports in python. If you import by using import xlrd, then you will have to qualify every object in that module as xlrd.SomeObject. An alternative way is by using the form from xlrd import *, which would allow you to reference the XLRD error without its' module namespace. This is lazy and a bad idea though, as it can lead to namespace clashes. If you would like to reference the error without qualifying it, the correct way to do it would be from xlrd import XLRDError, which would allow you to say except XLRDError. Read more about Python Modules
XLRDError is a custom exception and must be imported to your namespace just like any other object.
Edit: As Burhan Khalid has noted, you could just modify the except block to except xlrd.XLRDError if you already have import xlrd in your module.
Try using
xlrd.XLRDError as e and e.message should contain the error string
Sample:
try:
workbook = xlrd.open_workbook(sys.argv[1])
except xlrd.XLRDError as e:
print e.message
sys.exit(-1)

Categories