[Tutor] Debug help
Jim
jf_byrnes at comcast.net
Wed Jul 22 17:39:43 EDT 2020
On 7/19/20 6:57 PM, Cameron Simpson wrote:
> On 19Jul2020 15:25, jim <jf_byrnes at comcast.net> wrote:
> [...]
>> Here is the part of the code that generates the error, the remainder of
>> the script just manipulates the spreadsheet.
>>
>> for stock in stocks:
>> # ~ count = 0
>> # ~ while count < total_num_of_stocks:
>> # ~ while count < 33:
>> while True:
>> # ~ count = count + 1
>> try:
>> # ~ print('Day = ' + day)
>> ticker = yf.Ticker(stock)
>> # ~ print('Ticker = ' + ticker)
>> hist = ticker.history(start=day)
>> # ~ print('History = ' + hist)
>> close_price = hist.loc[day]['Close']
>> # ~ print('Close = ' + close_price)
>> closing_prices.append(close_price)
>>
>> except:
>> print ('yfinance JSONDecodeError DAILY, retyring')
>> # ~ print ('ticker: ' + hist)
>> continue
>> break
>>
>> # Get stock values by multiplying the list elements by number of shares
>> # using zip()
>> value = [num_shares * stk for num_shares, stk in zip(shares,
>> closing_prices)]
>>
>> # Put date in cell then go down one row
>> S(cell_loc).string = day
>> S().dispatch('GoDown')
>>
>> # Fill column for MY100000 with stock values using the number of
>> stocks in MY100000
>> for stk in value[:total_num_MY100000]:
>> S().value = stk # Line 102
>> S().dispatch('GoDown')
>>
>> If I run the script with the print lines outside the except commented
>> out it will print the date in the spreadsheet, go down 1 cell and
>> throw the error and end. If I uncomment any of the print lines it
>> seems to go into a endless loop printing out the exception error msg.
>>
>> I wonder if anyone has an idea of how to figure out what Yahoo Finance
>> is doing to cause a problem and I am curious as to why uncommenting a
>> print seems to cause an endless loop.
>
> I'm unfamiliar with Yahoo Finance, but I want to comment on your
> debugging issues.
>
> Your code's control structure is like this:
>
> while True:
> try:
> [...]
> # ~ print('Close = ' + close_price)
> [...]
> except:
> print ('yfinance JSONDecodeError DAILY, retyring')
> # ~ print ('ticker: ' + hist)
> continue
>
> First up, consider what happens when anything goes wrong inside the
> try/except: you print something and continue, restarting the loop. If
> that thing happens on every pass, you get an infinite loop.
>
> See the commented out print(). Supposing close_price is not a string.
> The addition will raise a TypeError exception. And into the infinite
> loop you go.
>
> Better, for debugging statements, to perform as few operations as
> possible. because if something is wrong, any operation might itself fail
> because things as not as you expect. So consider:
>
> print('Close = ', close_price)
>
> Because print() converts all is arguments to strings, the form above
> does no addition and still produces a result.
>
> However, the biggest problem here is what we call a "bare except": an
> except which catches _any_ exception. That's handy for reporting on
> _everything_ which explodes, but otherwise a bad practice.
>
> The rule of thumb for catching excpetions is to _only_ catch what you
> expect and know how to handle _correctly_. Your code catches everything
> (again, great for reporting) but does not know what to do with it.
>
> Because you do not print the exception or where it came from, you learn
> nothing about the underlying issue. Consider this:
>
> while True:
> try:
> [...]
> # ~ print('Close = ' + close_price)
> [...]
> except Exception as e:
> print("unexpection exception:", e)
> print ('yfinance JSONDecodeError DAILY, retyring')
> # ~ print ('ticker: ' + hist)
> continue
>
> At least this will show you what is wrong. But better still is not to
> catch it at all. It is unexpected, so your print-and-continue action is
> probably inappropriate (because you do not know the context - _anything_
> might be wrong). As a scarey example, consider:
>
> while True:
> try:
> x = closed_price
> [...]
> # ~ print('Close = ' + close_price)
> [...]
> except Exception as e:
> print("unexpection exception:", e)
> print ('yfinance JSONDecodeError DAILY, retyring')
> # ~ print ('ticker: ' + hist)
> continue
>
> Here, "closed_price" is a misspelled variable name. Python will raise a
> NameError because it is an unknown name, and you won't have even printed
> out the exception, so you will be blind to a simple typo in the code.
>
> The usual pattern with try/except is to catch exactly what you can
> handle, and let other exceptions out. That does abort your programme,
> but you get the raw exception _and_ a nice stacktrace showing where it
> came from:
>
> while True:
> try:
> x = closed_price
> [...]
> # ~ print('Close = ' + close_price)
> [...]
> except HTTPError as e:
> print("HTTP networking error", e)
> time.sleep(1)
> continue
>
> Here we catch an expected failure (the network maybe went away, and the
> HTTP conencion did not work). We print that, and we sleep for 1 second
> to avoid a busy loop (spinning until the network works again). But this
> is an _expected_ exception with a well defined plan for accomodating it.
> So we catch it, report it, and continue.
>
> Now, you may only know how to handle a specific type of an exception.
> Then the pattern is only slightly more elaborate:
>
> while True:
> try:
> x = closed_price
> [...]
> # ~ print('Close = ' + close_price)
> [...]
> except HTTPError as e:
> # I'm just making up some kind of test on the exception here
> if e.errno == errno.EIO:
> print("HTTP networking error", e)
> time.sleep(1)
> continue
> raise
>
> Here, we know how to handle a specific type of HTTPError. Any others are
> just reraised, producing an error and a stack trace for you to examine.
>
Cameron,
I am finally able to get back to this discussion. Thanks for the great
explanation of try/except. I was always confused when people talked
about only catch what you expect and can handle. I googled python
exceptions and found a list of them. It makes more sense now.
The error that promoted my question was:
uno.RuntimeException: Couldn't convert Date
2020-07-17 134858.5
2020-07-17 134858.5
Name: Close, dtype: float64 to a UNO type; caught exception: <class
'AttributeError'>: 'Series' object has no attribute 'getTypes',
traceback follows
This comes from the module ooSheet, because it was given data in a form
it did not expect. Can try/except be used to catch exemptions from an
imported module? In this case I would want the program to stop, but I
imagine there could be a case where I would want it to continue.
Thanks, Jim
More information about the Tutor
mailing list