0

I'm trying to parse a lot of files to get some info in one table. Here is my script:

import pandas as pd
import numpy as np
M1 = pd.DataFrame(Test,columns=['Test'])

for sample in samples:
    with open("file/"+sample+".txt") as f:
        c=0
        tpm=[]
        for line in f:
            c+=1
#                if c==1:
#                    if line.split('/')[1].split('.')[0]!='abc':
#                        break
            if c>2 and line.startswith('gene'):
                try:
                    return tpm.append(int(line.rstrip().split('\t')[6])/int(line.rstrip().split('\t')[5])*1000)
                except ZeroDivisionError:
                    return 0

M1[Test]=tpm/np.sum(tpm)*1000000
M=M1
M=M.fillna(0)
M.index=M['Test']
M.to_csv('M.xls',index=False,sep='\t')'

Without lines containing try: and except ZeroDivisionError it works but I got a ZeroDivision error and results are not usable for the next line. So I wanted to add 0 when a 0 is encountered in *.txt file instead of doing division.

In this script I got a 'return' outside function syntax error

I tried many approaches such as add try before for line in f: or add except: pass but it didn't work.

vmicrobio
  • 331
  • 1
  • 2
  • 13
  • 3
    `SyntaxError: 'return' outside function` you can not catch a `SyntaxError`, you should not have a `return` statement outside a function – python_user Oct 22 '20 at 14:00
  • 2
    You can't catch *this* `SyntaxError`, since it is raised by the parser, not at runtime (for appropriate distinctions between parse/compile time and runtime). (For example, `exec` and `eval` can raise `SyntaxError`s at runtime, and those can be caught.) – chepner Oct 22 '20 at 14:07
  • What's unclear about that message? You have no functions, and has nothing to do with the try-except. Even if you did, a return there would stop your loop after the first occurrence, so that's not what you want, I'm guessing – OneCricketeer Oct 22 '20 at 14:11

3 Answers3

1

As I commented you can not catch a SyntaxError, you should not use the return statement outside a function. If your intention is to add a 0 when a ZeroDivisionError occurs you can change your code like so in the except part. This way you will add a 0 if you run into a ZeroDivisionError.

try:
    tpm.append(int(line.rstrip().split('\t')[6])/int(line.rstrip().split('\t')[5])*1000)
except ZeroDivisionError:
    tpm.append(0)

Edit : @chepner has pointed out that some SyntaxErrors can still be caught more info in this SO answer.

python_user
  • 5,375
  • 2
  • 13
  • 32
1

the real problem here, is that you are using a return command outside a function, the return must used only inside function definition

but your logique implementation is correct: the uses of Try/except is correct

however it's butter to store the value in varibales and check the second value if it's equal to Zero, and here you can remove the try/except block.

 try:
     a=tpm.append(int(line.rstrip().split('\t')[6])
     b=int(line.rstrip().split('\t')[5])*1000)
     if b==0:
        print(a/b)
     else:
        print(0)
except ZeroDivisionError:
     print(0)

but take in your count where the value not equal to zero , but it's too small: like 1/(10**9999999999999999999999999999999999999999999999999), here the value is not equal to zero , but it will take time to be evaluated, so it's butter to make the condition like that:

if round(x,10)==0:
HichamDz38
  • 94
  • 7
1

you are using return statement outside function definition.

You can either avoid return all-together and use assignment or some other logic, Or wrap the whole thing with def block and call it.

But the later doesn't make sense in your situation (b/c return will break the for loop). So re-arrange your code as the following.

[...]  
       
     try:
          tpm.append(int(line.rstrip().split('\t')[6])/int(line.rstrip().split('\t')[5])*1000)
     except ZeroDivisionError:
          pass
DevCl9
  • 298
  • 1
  • 9