I am very newbie to python and to optparse module in general. I have figured out how to add options in python script using optparse but having trouble linking the options with my variable names in python.
import sys
from optparse import OptionParser
def main ():
parser = OptionParser()
parser.add_option("-f", "--file", dest="in_filename",
help="Input fasta file", metavar="FILE")
parser.add_option("-o", "--out", dest="out_filename",
help="Output fasta file", metavar="FILE")
parser.add_option("-i", "--id", dest="id",
help="Id name to change", metavar="ID")
(options,args) = parser.parse_args()
with open(f, 'r') as fh_in:
with open(o, 'w') as fh_out:
id = i
result = {}
count = 1
for line in fh_in:
line = line.strip()
if line.startswith(">"):
line = line[1:]
result[line] = id + str(count)
count = count + 1
header = ">" + str(result[line])
fh_out.write(header)
fh_out.write("\n")
else:
fh_out.write(line)
fh_out.write("\n")
main()
When i run this i get this below traceback and error:
python header_change.py -f consensus_seq.txt -o consensus_seq_out.fa -i "my_test"
Traceback (most recent call last):
File "/Users/upendrakumardevisetty/Documents/git_repos/scripts/header_change.py", line 36, in <module>
main()
File "/Users/upendrakumardevisetty/Documents/git_repos/scripts/header_change.py", line 18, in main
with open(f, 'r') as fh_in:
NameError: global name 'f' is not defined
Can someone point to me what i am doing wrong.
You've got two problems here.
First, as the optparse tutorial shows, optparse doesn't create global variables, it creates attributes in the options namespace that it returns:
parse_args() returns two values:
options, an object containing values for all of your options—e.g. if --file takes a single string argument, then options.file will be the filename supplied by the user, or None if the user did not supply that option
args, the list of positional arguments leftover after parsing options
So, if the user typed -f, you're not going to have f, you're going to have options.f.
Second, f isn't the right name anyway. You explicitly specified a different destination, instead of the default:
parser.add_option("-f", "--file", dest="in_filename",
help="Input fasta file", metavar="FILE")
So it's going to do what you asked and store the file in in_filename.
And likewise for the other options. So, your code should start off like this:
with open(options.in_filename, 'r') as fh_in:
with open(options.out_filename, 'w') as fh_out:
Related
I currently have the following code which works to produce a PDF output. Is there a better way of writing up the content for the PDF, other than done here? This is a basic pdf, but am hoping to include multiple variables in later versions. I have inserted variable x, defined before the PDF content, into the latex pdf. Many thanks for any advice you can give.
PDF Output - image
import os
import subprocess
x = 7
content = \
r'''\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1cm,landscape]{geometry}
\title{Spreadsheet}
\author{}
\date{}
\begin{document}''' + \
r'This is document version: ' + str(x) +\
r'\end{document}'
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--course')
parser.add_argument('-t', '--title')
parser.add_argument('-n', '--name',)
parser.add_argument('-s', '--school', default='My U')
args = parser.parse_args()
with open('doc.tex','w') as f:
f.write(content%args.__dict__)
cmd = ['pdflatex', '-interaction', 'nonstopmode', 'doc.tex']
proc = subprocess.Popen(cmd)
proc.communicate()
retcode = proc.returncode
if not retcode == 0:
os.unlink('doc.pdf')
raise ValueError('Error {} executing command: {}'.format(retcode, ' '.join(cmd)))
os.unlink('doc.tex')
os.unlink('doc.log')```
As explained in this video, I think a better approach would be to export the variables from Python and save them into a .dat file using the following function.
def save_var_latex(key, value):
import csv
import os
dict_var = {}
file_path = os.path.join(os.getcwd(), "mydata.dat")
try:
with open(file_path, newline="") as file:
reader = csv.reader(file)
for row in reader:
dict_var[row[0]] = row[1]
except FileNotFoundError:
pass
dict_var[key] = value
with open(file_path, "w") as f:
for key in dict_var.keys():
f.write(f"{key},{dict_var[key]}\n")
Then you can call the above function and save all the variables into mydata.dat. For example, in Python, you could save a variable and call it document_version using the following line of code:
save_var_latex("document_version", 21)
In LaTeX (in the preamble of your main file), you just have to import the following packages:
% package to open file containing variables
\usepackage{datatool, filecontents}
\DTLsetseparator{,}% Set the separator between the columns.
% import data
\DTLloaddb[noheader, keys={thekey,thevalue}]{mydata}{../mydata.dat}
% Loads mydata.dat with column headers 'thekey' and 'thevalue'
\newcommand{\var}[1]{\DTLfetch{mydata}{thekey}{#1}{thevalue}}
Then in the body of your document just use the \var{} command to import the variable, as follows:
This is document version: \var{document_version}
I have created the Python script below which i would like to run and call another script from and then give the called script a variable in this case it would be an email address as "line" from a text file. What would be the easiest way to accomplish this please?
The problem now is that the script that is being called will not take the 'line' variable as an argument.
import bob
import os
# file handle fh fh = open('mailout.txt') while True:
# read line
line = fh.readline()
line = line.replace("\r", "").replace("\n", "")
command = 'python3 bob.py ' + line
os.system(command)
# check if line is not a empty value
if not line:
break fh.close()
As #Zach's comment, you can call it by giving line as argument. Otherwise, you can do it by using argparse. Assume that you have two functions inner.py and outer.py.
inner.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--sentence')
args = parser.parse_args()
print(args.sentence)
outer.py
import os
f = open('email.txt')
line = f.readline()
line = line.replace("\r", "").replace("\n", "")
line = "\""+line+"\""
command = 'python inner.py -s' + line
os.system(command)
Then calling python outer.py returns
Just a line to try
I am trying to write a python script that can be run from the command line with
python script.py --input file.txt
or
python script.py -i file.txt
script.py will take in the file file.txt and open/read.
This is what I have so far:
#!/usr/bin/python
import argparse
parser = argparse.ArgumentParser(description="I'm not sure what I should write here.")
parser.add_argument('-i','--input', help='Input file name',required=True)
args = parser.parse_args()
Now...How do I actually access the input file?
What I want is to write to an output file, e.g. python script.py --outputfile file.csv? I do not understand how to interact with writing the file. Sorry if this is too easy.
It is pretty simple!
#!/usr/bin/python
import argparse
parser = argparse.ArgumentParser(description="Something like -- File reader: reads file line by line.")
parser.add_argument('-i','--input', help='Input file name',required=True)
args = parser.parse_args()
with open(args.input) as fp:
for line in fp:
print line
If you want to write some content to the input file. Open the file in write mode and write to it whatever you want.
with open(args.input, 'w') as fp:
fp.write("Hello World!")
If you want a separate file to write, add an argument to your argparser in write mode and then write to it.
parser = argparse.ArgumentParser(description="Something like -- File reader/writer: reads/writes files line by line.")
parser.add_argument('-i','--input', help='Input file name',required=True)
parser.add_argument('-o','--output', help='Output file name',type=argparse.FileType('w'),required=True)
args = parser.parse_args()
with open(args.input) as fp:
for line in fp:
print line
with open(args.output) as fp:
fp.write("Hello World!")
You can access the string the user enter after -i with:
args.input
For example:
argp_test.py -i my_file_name.txt
Now:
print(args.input)
prints:
my_file_name.txt
Next step is to read the file content:
with open(args.input) as fobj:
for line in fobj:
# do something with this line
BTW, you got a syntax error in this line:
parser = argparse.ArgumentParser(description='I'm not sure what I should write here.')
It should look like this:
parser = argparse.ArgumentParser(description="I'm not sure what I should write here.")
When you use a ' in your string, you need to use " at the begging and end of your string. So use:
"I'm not"
instead of:
'I'm not'
I'm trying to give a TXT file with argparse and then to open it in a function.
Can you tell me why it say : error:unrecognized arguments : dataBase.txt
(ps: dataBase is the file I'm trying to open)
update(1)
my main :
if __name__ =='__main__':
parser=argparse.ArgumentParser()
parser.add_argument("file_name",type= argparse.FileType,help="name of file with network")
args=parser.parse_args()
z=args.file_name
names,network= loadNetwork()
a little part of my function:
def loadNetwork():
fileName=open('z', 'r')
name = fileName.readlines()
I think it's because file is not a valid type for argparse in Python3. The type argument takes a callable, and since file doesn't exist in Python3, it'll throw an error. Try using FileType instead.
parser = argparse.ArgumentParser()
parser.add_argument("file_name", type=argparse.FileType("r"), help="name of file with network")
Here's roughly, how I think your code should look:
def loadNetwork(afile):
name = afile.readlines()
return name
if __name__ =='__main__':
parser=argparse.ArgumentParser()
parser.add_argument("file",type= argparse.FileType('r'),
help="name of file with network")
# FileType opens the file you specified;
# so you don't need to open it
args = parser.parse_args()
names,network = loadNetwork(args.file)
args.file.close()
It's a good idea to pass values set by argparse to your functions as parameters, rather than setting global variables.
But if instead you would prefer to open and close the file yourself, I'd suggest:
def loadNetwork(filename):
with open(filename) as f:
name = f.readlines()
return name
if __name__ =='__main__':
parser=argparse.ArgumentParser()
parser.add_argument("filename", help="name of file with network")
args = parser.parse_args()
names,network = loadNetwork(args.filename)
the with statement opens and closes the file. A down side to this is that argparse isn't going to issue an error message if the filename isn't valid. But the with open will. Also this doesn't accept '-' as a filename (FileType takes that to mean sys.stdin).
I'm trying open a txt file and read it, but I'm getting a type error and I'm unsure why. If you you could please provide a reasoning along with the correct syntax, I'm trying to get a better grasp of what's going on underneath. Here's the code, it's pretty simple I think:
from sys import argv
script = argv
filename = argv
txt = open(filename)
print "Here's your file %r" %filename
print txt.read()
Muchas Gracias
argv is a list, not a string. You want
script = argv[0]
filename = argv[1]
Consider using argparse instead of handing sys.argv directly:
>>> import argparse
>>> parser = argparse.ArgumentParser(description="Print a file.")
>>> parser.add_argument("path", type=str, nargs=1, help="Path to the file to be printed.")
_StoreAction(option_strings=[], dest='path', nargs=1, const=None, default=None, type=<type 'str'>, choices=None, help='Path to the file to be printed.', metavar=None)
>>> args = parser.parse_args()
>>> print args
Namespace(path=[<...>])
It looks much more complicated, but it will make your command-line utility much more flexible, easier to expand, and it will ensure you get proper documentation on the command line.
First of all, argv is a list of arguments. Open doesn't take a list. That's why you're getting a type error.
Second, open (should) take 2 parameters, the filename and the mode (yes mode is optional, but get in the habit of putting it there. Replace with
import sys
script = sys.argv[0]
filename = sys.argv[1]
txt = open(filename, 'r')
print "Here's your file %r" %filename
print txt.read()
argv will be a list, while filename should be a string.
You should probably be using filename = argv[1]