How to call python function call subsequently - python

I have a python function which is working as expected when called first time.
as soon as i add another call it is errors out "IndexError: list index out of range"
import os
import re
import glob
LDIR="/data/reports/get-snapshots/labs"
PDIR="/data/reports/get-snapsnots/prod"
def get_latest_snap_files(path, *paths):
snap_path=os.path.join(path, *paths)
snap_file=sorted(glob.iglob(snap_path), key=os.path.getctime, reverse=True)
return snap_file[0]
def main():
l=get_latest_snap_files(LDIR, '*')
print(l)
p=get_latest_snap_files(PDIR, '*')
print(p)
main()
$python h.py
/data/reports/get-snapshots/labs/labs.snapshot.2019-05-25_184501-out.sorted.log
Traceback (most recent call last):
File "h.py", line 24, in <module>
main()
File "h.py", line 22, in main
p=get_latest_snap_files(PDIR, '*')
File "h.py", line 16, in get_latest_snap_files
print(snap_file[0])
IndexError: list index out of range

As per the #Chris_Rands's comment on your answer, snap_file is probably empty sometimes.
You should check that and return None when that happens.
import os
import re
import glob
LDIR="/data/reports/get-snapshots/labs"
PDIR="/data/reports/get-snapsnots/prod"
def get_latest_snap_files(path, *paths):
snap_path=os.path.join(path, *paths)
snap_file=sorted(glob.iglob(snap_path), key=os.path.getctime, reverse=True)
return None if len(snap_file) == 0 else snap_file[0]
def main():
l=get_latest_snap_files(LDIR, '*')
print(l)
p=get_latest_snap_files(PDIR, '*')
print(p)
main()

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

TypeError: 'float' object is not iterable when calling from a function

I want to use the reactome2py package to analyse pathways by adapting the Reference code. Unlike the reference code, which only read one file, my code intends to apply the reactome2py's analysis function for three files, mrna, cna, and meth.
Reference code:
https://colab.research.google.com/drive/1OufIYapCWirfLsudpg0fw1OxD7KTud2y?usp=sharing#scrollTo=e1q6oxLUKGGR
The portion of the code that's throwing the error:
for k, v in chain.from_iterable(cna_dict_items):
cna_dd[k].extend(v)
Full code:
import pandas as pd
import numpy as np
from sklearn.decomposition import PCA
from operator import methodcaller
from itertools import chain
from collections import defaultdict
from reactome2py import analysis
directory = "./gbm_tcga/"
def genepath(cna_row_dict):
cna_dd = defaultdict(list)
cna_dict_items = map(methodcaller("items"), cna_row_dict)
for k, v in chain.from_iterable(cna_dict_items):
cna_dd[k].extend(v)
cna_dict = dict(cna_dd)
return cna_dict
class DataProcessing:
def __init__(self, data):
self.df = pd.read_csv(data, sep="\t", header=0)
def data_dict(self):
df_dict = self.df.to_dict("records")
return df_dict
def main():
cna = DataProcessing(directory + "data_linear_cna.txt")
cna_dict = cna.data_dict()
gene_path = genepath(cna_dict)
main()
Traceback:
Traceback (most recent call last):
File "main.py", line 45, in <module>
main()
File "main.py", line 41, in main
gene_path = genepath(cna_dict)
File "main.py", line 19, in genepath
cna_dd[k].extend(v)
TypeError: 'float' object is not iterable

Python Curses addwstr() returned ERR when adding lines to screen

Suppose I am adding a large number of lines to a curses screen.
Minimal non-working example:
import curses
class MyApp(object):
def __init__(self, stdscreen):
self.screen = stdscreen
for i in range(0,100):
self.screen.addstr(str(i) + '\n')
self.screen.refresh()
self.screen.getch()
if __name__ == '__main__':
curses.wrapper(MyApp)
The above code returns:
Traceback (most recent call last):
File "test.py", line 17, in <module>
curses.wrapper(MyApp)
File "/usr/lib/python3.7/curses/__init__.py", line 94, in wrapper
return func(stdscr, *args, **kwds)
File "test.py", line 11, in __init__
self.screen.addstr(str(i) + '\n')
_curses.error: addwstr() returned ERR
Press ENTER to continue
1) What is this error?
2) If the error is because I am adding too many lines to the screen, how could I list those entries with curses? Perhaps with a scroll view of some sort?
It occurred to me that I could use try/except to determine the maximum number of lines that can be printed on the screen to avoid this error:
import curses
class MyApp(object):
def __init__(self, stdscreen):
self.screen = stdscreen
maximum = self.maxlines()
for i in range(maximum):
self.screen.addstr(str(i) + '\n')
self.screen.refresh()
self.screen.getch()
def maxlines(self):
n = 0
try:
for i in range(100):
self.screen.addstr(str(i) + '\n')
n += 1
except:
pass
self.screen.erase()
return n
if __name__ == '__main__':
curses.wrapper(MyApp)

AttributeError: 'numpy.ndarray' object has no attribute 'convert' and error of IndexError: list index out of range

Attribute errors may have posted earlier however in my situation when I found a solution, I got another error stating that my list index was out of range. I am beginner in Python working on breaking an image captcha. I have used the code provided from here - How to remove line from captcha completely
Based on that I added few lines to run it
lineRemoval.py
from PIL import Image,ImageFilter
from scipy.misc import toimage
from operator import itemgetter
from skimage import measure
import numpy as np
import copy
import heapq
import cv2
import matplotlib.pyplot as plt
from scipy.ndimage.filters import median_filter
#----------------------------------------------------------------
class preprocessing:
def pre_proc_image(self,img):
#img_removed_noise=self.apply_median_filter(img)
img_removed_noise=self.remove_noise(img)
p1,p2,LL=self.get_line_position(img_removed_noise)
img=self.remove_line(p1,p2,LL,img_removed_noise)
img=median_filter(np.asarray(img),1)
return img
def remove_noise(self,img):
img_gray=img.convert('L')
w,h=img_gray.size
max_color=np.asarray(img_gray).max()
pix_access_img=img_gray.load()
row_img=list(map(lambda x:255 if x in range(max_color-15,max_color+1) else 0,np.asarray(img_gray.getdata())))
img=np.reshape(row_img,[h,w])
return img
def apply_median_filter(self,img):
img_gray=img.convert('L')
img_gray=cv2.medianBlur(np.asarray(img_gray),3)
img_bw=(img_gray>np.mean(img_gray))*255
return img_bw
def eliminate_zeros(self,vector):
return [(dex,v) for (dex,v) in enumerate(vector) if v!=0 ]
def get_line_position(self,img):
sumx=img.sum(axis=0)
list_without_zeros=self.eliminate_zeros(sumx)
min1,min2=heapq.nsmallest(2,list_without_zeros,key=itemgetter(1))
l=[dex for [dex,val] in enumerate(sumx) if val==min1[1] or val==min2[1]]
mindex=[l[0],l[len(l)-1]]
cols=img[:,mindex[:]]
col1=cols[:,0]
col2=cols[:,1]
col1_without_0=self.eliminate_zeros(col1)
col2_without_0=self.eliminate_zeros(col2)
line_length=len(col1_without_0)
dex1=col1_without_0[round(len(col1_without_0)/2)][0]
dex2=col2_without_0[round(len(col2_without_0)/2)][0]
p1=[dex1,mindex[0]]
p2=[dex2,mindex[1]]
return p1,p2,line_length
def remove_line(self,p1,p2,LL,img):
m=(p2[0]-p1[0])/(p2[1]-p1[1]) if p2[1]!=p1[1] else np.inf
w,h=len(img),len(img[0])
x=list(range(h))
y=list(map(lambda z : int(np.round(p1[0]+m*(z-p1[1]))),x))
img_removed_line=list(img)
for dex in range(h):
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
rlist=[]
while i>=0:
f1=i
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
break
rlist.append(i)
i=i-1
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
while True:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
if np.abs(f2-f1) in [LL+1,LL,LL-1]:
rlist=list(set(rlist))
for k in rlist:
img_removed_line[k][j]=0
return img_removed_line
if __name__ == '__main__':
img = cv2.imread("captcha.png")
p = preprocessing()
imgNew = p.pre_proc_image(img)
cv2.imshow("Image", imgNew)
cv2.waitKey(0)
Initially when trying with the above code I was getting the error
Traceback (most recent call last):
File "lineRemoval.py", line 98, in <module>
imgNew = p.pre_proc_image(img)
File "lineRemoval.py", line 18, in pre_proc_image
img_removed_noise=self.remove_noise(img)
File "lineRemoval.py", line 25, in remove_noise
img_gray=img.convert('L')
AttributeError: 'numpy.ndarray' object has no attribute 'convert'
I searched and found the solution by changing my main function to this
if __name__ == '__main__':
image = cv2.imread("captcha.png")
img = Image.fromarray(image)
p = preprocessing()
imgNew = p.pre_proc_image(img)
cv2.imshow("Image", imgNew)
cv2.waitKey(0)
However after that my array is out of index
Traceback (most recent call last):
File "lineRemoval.py", line 98, in <module>
imgNew = p.pre_proc_image(img)
File "lineRemoval.py", line 20, in pre_proc_image
img=self.remove_line(p1,p2,LL,img_removed_noise)
File "lineRemoval.py", line 83, in remove_line
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
IndexError: list index out of range
Cannot identify where the error lies, does the while condition need to be changed or was the previous change causing it or is it something else.
Update
I have changed the condition for the while loop however similar comes for the initial while loop condition of i>=0
lineRemoval.py
while i>=0:
f1=i
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
break
rlist.append(i)
i=i-1
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
while i<len(img_removed_line)-1:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
Error that is shown
Traceback (most recent call last):
File "lineRemoval.py", line 98, in <module>
imgNew = p.pre_proc_image(img)
File "lineRemoval.py", line 20, in pre_proc_image
img=self.remove_line(p1,p2,LL,img_removed_noise)
File "lineRemoval.py", line 73, in remove_line
if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
IndexError: list index out of range
Replace your second while loop in the function removed line with this code:
while i<len(img_remmoved_line)-1:
f2=i
if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
break
rlist.append(i)
i=i+1
You are increasing i at each iteration which after sometime breaks the index limit of the list. This condition protects the iteration of the loop if the value of i is bigger then index limit of that list.

Why can't I run the example code of the Python package corpcrawl?

I installed corpcrawl but when I try to run this code from its documentation page:
from corpcrawl.crawler import CorpCrawl
from corpcrawl.backend import Backend
def main()
I get the following error
from corpcrawl.crawler import CorpCrawl
Traceback (most recent call last):
File "<ipython-input-40-a34fa6bf09cd>", line 1, in <module>
from corpcrawl.crawler import CorpCrawl
File "C:\ProgramData\Anaconda3\lib\site-packages\corpcrawl\crawler.py", line 1, in <module>
from parser import Parser
ImportError: cannot import name 'Parser'
def main()
File "<ipython-input-44-eaaf015e0d6b>", line 1
def main()
^
SyntaxError: invalid syntax
Why am I getting this error?
The code from corpcrawl's documentation page is broken:
Missing :
Wrong indentation
Illegal characters (such as “ instead of ")
Here is what it should look like (Python 2):
from corpcrawl.crawler import CorpCrawl
from corpcrawl.backend import Backend
class MyBackend(Backend):
def get_company(self, name):
pass
def add_company(self, comp):
print "Adding %s" % str(comp)
def main():
my_backend = MyBackend()
crawler = CorpCrawl(cache_path = '/an/absolute/path/to/some/dir', backend = my_backend)
c.crawl(years = [2011, 2012], quarters = [1, 2, 3, 4])

Categories

Resources