-2

I have an input file which looks like

    ===========================
    __A= 2.3
    __b= 3.26
    ===========================
    __ctx= 4.2
    ===========================
    __itermax= 100
    __errmax= 1e-07

Using this inputfile a collection of outputs within a different code( not implemented in python) has been generated. I am now trying to write some Python scripts to read this input file as well as other generated outputs to perform postproccessing analysis. I thus would like to extract the value of each parameter(A, b, ctx, ...) by a python script. Please note that this input file is distinct from the setting file discussed here as I can not perform any modification on the structure of the input file.

I have tried

    import sys

    try:
        directory_name=sys.argv[1]
        print(directory_name)
    except:
        print('Please pass directory_name')

    input_file = directory_name +"input.txt"
    with open(input_file) as fin:
        for line in fin:
            exec(line)

The error that I am encountering after running the code is

    File "code.py", line 14, in <module>
         exec(line)
    File "<string>", line 1
    ===========================
    ^
    SyntaxError: invalid syntax

Any suggestion on improving this code, or with a different outputting method (e.g. as a dictionary), to obtain the values of the parameters is helpful.

Shasa
  • 173
  • 1
  • 10
  • 4
    Are you sure you want to execute arbitrary lines of code from an arbitrary file? I would simply convert it to JSON format then reading the file is as easy as `json.load(f)` or actually use a conf parsing module such as `ConfigParser`. I believe almost every approach will be better than this. – DeepSpace May 07 '18 at 09:21
  • Relevant https://stackoverflow.com/questions/5055042/whats-the-best-practice-using-a-settings-file-in-python – Chris_Rands May 07 '18 at 09:23
  • Please go read about how to write a config file in Python, at those links. – smci May 07 '18 at 09:36
  • You _really_ should **not** use `exec` for stuff like this. Do you have any control over the structure of that input file? If you can change it to a standard `.ini` file, or JSON, that would make this task a bit easier. – PM 2Ring May 07 '18 at 09:39
  • @DeepSpace That dupe target isn't relevant here if Shasa has no control over the structure of that input file. – PM 2Ring May 07 '18 at 09:45
  • Shasa, if the linked question isn't helpful, please edit your question to explain why the suggestions there don't help you, and your question will be reviewed for re-opening. – PM 2Ring May 07 '18 at 09:46
  • @DeepSpace I do not have the possibility of modifying the structure of the input file. – Shasa May 08 '18 at 06:07
  • @PM2Ring, I have modified the question abit as I have not chance to change the structure of the input file. – Shasa May 08 '18 at 06:08

5 Answers5

1

Do you wanna exec the string "==================" ?
This string is not a python code.
There is a lazy way, use try ... except ... to resolve this.

import sys

try:
    directory_name=sys.argv[1]
    print(directory_name)
except:
    print('Please pass directory_name')

input_file = directory_name +"input.txt"
with open(input_file) as fin:
    for line in fin:
        try:
            exec(line)
        except Exception as e:
            print(e)

Another way is you can remove all unuseful strings before you exec them.

Karl Doenitz
  • 2,220
  • 3
  • 20
  • 38
  • 1
    Based on suggestions I have decided not to use "exec". The input file is a bit unusual and I had no privilege to modify that. Thank you for your reply. – Shasa May 08 '18 at 06:46
0

Executing random lines of code from a file is risky, and a bit 'hacky'. If you really want to do it, the easiest way to fix your code is to just try each line:

import sys

try:
    directory_name=sys.argv[1]
    print(directory_name)
except:
    print('Please pass directory_name')

input_file = directory_name +"input.txt"
with open(input_file) as fin:
    for line in fin:
        try:
            exec(line)
        except:
            print("Line invalid: {}".format(line))
Alex
  • 2,270
  • 3
  • 33
  • 65
0

you first have to check "line" makes sens to be executed.

the problem is when line = "=========" you can use :

if line.startwith("===") continue

to skip it.

or

if line.startwith("__"): exec(line)

to avoid exectuting unknown stuff

p.deman
  • 584
  • 2
  • 10
  • 24
0

for extract thei value use re.search

import re
import sys

textfile = sys.argv[1]
f = open(textfile, 'r').readlines()
for l in f:
    extract = l.rstrip()
    try:
      f = re.search('__A= (.*)', extract)
      return True
    except:
      return False
    valueA = f.group(1)
    print valueA
Skiller Dz
  • 897
  • 10
  • 17
  • @Shasa if this also work , try to accept the answer who it work better , accept answers that will help other to know how to fix this probleme if they will have it – Skiller Dz May 08 '18 at 09:04
0

Try a simple regular expression:

import re

e = r'^__(.*?)=(.*?)$'

with open('data.txt') as f:
    print(dict(re.findall(e, f.read(), re.M)))

This will print:

{'A': ' 2.3', 'b': ' 3.26', 'ctx': ' 4.2', 'itermax': ' 100', 'errmax': ' 1e-07'}
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284