Search code examples
pythonfilecommand-linecoordinatesargv

reads a stream of (x, y) pairs from the command line and writes the modified pairs (x, f(y)) to a file


Here is the problem:

Read streams of (x, y) pairs from the command line. Modify the datatrans1.py script such that it reads a stream of (x, y) pairs from the command line and writes the modified pairs (x, f(y)) to a file. The usage of the new script, here called datatrans1b.py, should be like this:

this is the input to the command line:
python datatrans1b.py tmp.out 1.1 3 2.6 8.3 7 -0.1675

resulting in an output file tmp.out:

  • 1.1 1.20983e+01
  • 2.6 9.78918e+00
  • 7 0.00000e+00

Hint: Run through the sys.argv array in a for loop and use the range function with appropriate start index and increment Below is the datatrans1.py original script:

```
import sys, math

try:
   infilename = sys.argv[1]
   outfilename = sys.argv[2]
except:
   print("Usage:", sys.argv[0], "infile outfile")
   sys.exit(1)

ifile = open(infilename, 'r')  # open file for reading
ofile = open(outfilename, 'w')  # open file for writing


def myfunc(y):
   if y >= 0.0:
       return y ** 5 * math.exp(-y)
   else:
       return 0.0

```

read ifile line by line and write out transformed values:

```

for line in ifile:
   pair = line.split()
   x = float(pair[0])
   y = float(pair[1])
   fy = myfunc(y)  # transform y value
   ofile.write('hello' '%g  %12.5e\n' % (x, fy))
ifile.close()
ofile.close()

```

any clues on how to modify the above code to properly run the command line argument and generate the tmp.out file with the coordinate pairs would be really helpful


Solution

  • This should solve the problem:

    import sys, math
    
    try:
       outfilename = sys.argv[1]
    except:
       print("Usage:", sys.argv[0], "outfile pairs")
       sys.exit(1)
    
    ofile = open(outfilename, 'w')  # open file for writing
    
    def myfunc(y):
       if y >= 0.0:
           return y ** 5 * math.exp(-y)
       else:
           return 0.0
    
    # Loop through y values, using slices to start at position 3
    # and get every second value
    for i, y in enumerate(sys.argv[3::2]):
    
        # The corresponding x value is the one before the selected y value
        x = sys.argv[2:][i*2]
    
        # Call myfunc with y, converting y from string to float.
        fy = myfunc(float(y))
    
        # Write output using f-strings
        ofile.write(f'({x}, {fy})\n')