Editing text file through command line argument in Python - python

I want to edit text file by passing integer number via command line argument in Python. However my code is not working, can some one point me where I am wrong.
import sys, argparse
def main(argv=None):
if argv is None:
argv=sys.argv[1:]
p = argparse.ArgumentParser(description="Editing omnetpp.ini")
p.add_argument('arg1', action='store', default= 1, type=int, help="number of clients")
args = p.parse_args(argv)
n = args.arg1
f = open('C:\\Users\Abcd\Desktop\Omnet\omnetpp.ini', 'a')
for i in range(n):
f.write('*.voipClient['+str(i)+'].udpApp['+str(i)+'].destAddresses = "voipGateway"\n')
f.write('*.voipGateway.udpApp['+str(i)+'].destAddresses = "voipClient['+str(i)+']"\n')
f.close()
If integer number 5 is passed via command line argument then it should add following lines in text file, which is not happening
Output
*.voipClient[0].udpApp[0].destAddresses = "voipGateway"
*.voipGateway.udpApp[0].destAddresses = "voipClient[0]"
*.voipClient[1].udpApp[1].destAddresses = "voipGateway"
*.voipGateway.udpApp[1].destAddresses = "voipClient[1]"
*.voipClient[2].udpApp[2].destAddresses = "voipGateway"
*.voipGateway.udpApp[2].destAddresses = "voipClient[2]"
*.voipClient[3].udpApp[3].destAddresses = "voipGateway"
*.voipGateway.udpApp[3].destAddresses = "voipClient[3]"
*.voipClient[4].udpApp[4].destAddresses = "voipGateway"
*.voipGateway.udpApp[4].destAddresses = "voipClient[4]"
I am following these steps:
Code is saved in test.py
From command line C:\Users\Abcd\Desktop>python test.py 5

Don't close the file in the loop, as soon as it is closed you cannot write to it anymore (in fact, an error should be thrown if you try to write to a closed file object).
Instead, close it after the loop.
Also, to put each sentence on a new line, end the string with the newline symbol \n (sort of pressing "ENTER").
f = open('C:\\Users\Abcd\Desktop\Omnet\omnetpp.ini', 'a')
for i in range(n):
f.write('*.voipClient['+str(i)+'].udpApp['+str(i)+'].destAddresses = "voipGateway"\n')
f.write('*.voipGateway.udpApp['+str(i)+'].destAddresses = "voipClient['+str(i)+']"\n')
f.close()
EDIT
By the way, as Rostyslav Dzinko said in the comments, the way you defined your code is not how you define a main function. In fact, try something like this (see also this SO question):
if __name__ == '__main__':
p = argparse.ArgumentParser(description="Editing omnetpp.ini")
p.add_argument('arg1', action='store', default= 1, type=int, help="number of clients")
args = p.parse_args()

Related

How to pass single String value from Python sub-process code to R Code

I am trying to run a R code from the Python using Subprocess library.
I need to run one .R file from the python and have pass one single String value(args = ["INV28338"]).
I am new in R and so not able to figure out exact data type conversion code in both R and Python.
Please someone help me, how to pass single string/scalar value from Python to R Function/Model ?
Later I will give the shape of 'Flask REST API' for this code.
Thank you so much in advance
Python code:-
import subprocess
command = 'Rscript'
path2script = 'classification_model_code.R'
args = ["INV28338"]
cmd = [command, path2script] + args
x = subprocess.check_output(cmd, universal_newlines=True)
print('The Output is:', x)
R code:-
myArgs <- commandArgs(trailingOnly = TRUE)
nums = as.numeric(myArgs)
invoice_in_scope<-nums
#Followed by more code
my script, test2.R
myArgs <- commandArgs(trailingOnly = TRUE)
nums = as.character(myArgs)
print(nums)
you need to have args as part of the list, so append it to cmd and it works ok:
import subprocess
command = 'Rscript'
path2script = './test2.R'
args = "INV28338"
cmd = [command, path2script]
cmd.append(args)
x = subprocess.check_output(cmd, universal_newlines=True)
print('The Output is:', x)

Command-line argument overwritten by default value when using subparser

I have a program with sub commands, but they all have common arguments (e.g. they all require input and output directories) which I included in the parent parser to avoid redundancies. However, I want each subcommand to have a different default value, but this causes the value provided in the command-line to be ignored.
MWE:
import argparse
top_parser = argparse.ArgumentParser()
top_parser.add_argument("--input-dir", type=str)
subparsers = top_parser.add_subparsers()
generate_parser = subparsers.add_parser("generate")
generate_parser.set_defaults(input_dir=".")
process_parser = subparsers.add_parser("process")
process_parser.set_defaults(input_dir="SOME_OTHER_DIR")
generate_args = top_parser.parse_args("--input-dir USE_THIS_DIR generate".split())
print("generate_args = ", generate_args)
process_args = top_parser.parse_args("--input-dir USE_THIS_DIR process".split())
print("process_args = ", process_args)
This gives:
generate_args = Namespace(input_dir='.')
process_args = Namespace(input_dir='SOME_OTHER_DIR')
but I want:
generate_args = Namespace(input_dir='USE_THIS_DIR')
process_args = Namespace(input_dir='USE_THIS_DIR')
I can circumvent this by separately adding the argument to each subparser, but I would like to avoid this redundancy if possible.
One workaround would be to check the value of input_dir after parsing, and substitute a subparser-specific default at that time.
import argparse
top_parser = argparse.ArgumentParser()
top_parser.add_argument("--input-dir", type=str)
subparsers = top_parser.add_subparsers()
generate_parser = subparsers.add_parser("generate")
generate_parser.set_defaults(alt_input_dir=".")
process_parser = subparsers.add_parser("process")
process_parser.set_defaults(alt_input_dir="SOME_OTHER_DIR")
args = top_parser.parse_args()
if args.input_dir is None:
args.input_dir = args.alt_input_dir
del args.alt_input_dir

Copy parameters into list

I am trying to copy parameters passed into a python script to a file. Here is the parameters.
["0013","1","1","\"john.dow#gmail.com\"","1","P123-ND 10Q","10Q H??C"]
I understand that there is a buffer problem and I am getting bad data into my parameters. However, I do not have control over what is being passed in. I am trying to copy, starting at the 5th parameter, the parameters into a file.
f = open(in_file_name, 'w')
for x in range(5, len(arg_list)):
f.write(arg_list[x] + '\n')
f.close()
The result of the file is below:
P123-ND 10Q
10Q H??C
Here is what it should be:
P123-ND
10Q
How can I not include the bad data? What is happening to the spaces between the valid information and the bad information?
As requested, here is the full program:
#!/bin/python
class Argument_Indices:
PRINTER_INDEX = 0
AREA_INDEX = 1
LABEL_INDEX = 2
EMAIL_INDEX = 3
RUN_TYPE_INDEX = 4
import argparse
import json
import os
from subprocess import call
import sys
from time import strftime
def _handle_args():
''' Setup and run argpars '''
parser = argparse.ArgumentParser(description='Set environment variables for and to call Program')
parser.add_argument('time_to_run', default='NOW', choices=['NOW', 'EOP'], help='when to run the report')
parser.add_argument('arguments', nargs='+', help='the remaining command line arguments')
return parser.parse_args()
def _proces_program(arg_list):
time_stamp = strftime("%d_%b_%Y_%H_%M_%S")
printer = arg_list[Argument_Indices.PRINTER_INDEX]
area = arg_list[Argument_Indices.AREA_INDEX]
label = arg_list[Argument_Indices.LABEL_INDEX]
in_file_name = "/tmp/program{0}.inp".format(time_stamp)
os.environ['INPUT_FILE'] = in_file_name
f = open(in_file_name, 'w')
for x in range(5, len(arg_list)):
f.write(arg_list[x])
f.close()
call(['./Program.bin', printer, area, label])
os.remove(in_file_name)
def main():
''' Main Function '''
arg_list = None
args = _handle_args()
if len(args.arguments) < 1:
print('Missing name of input file')
return -1
with open(args.arguments[0]) as input_file:
arg_list = json.load(input_file)
_process_program(arg_list)
return 0
if __name__ == '__main__':
if main() != 0:
print('Program run failed')
sys.exit()
For your exact case (where you're getting duplicated parameters received with some spaces in between) this would work:
received_param_list = ["0013","1","1","\"john.dow#gmail.com\"","1","P123-ND 10Q","10Q H??C"]
arg_list = [i.split(" ")[0] for i in received_param_list]
last_param = received_param_list[-1].split()[-1]
if last_param != arg_list[-1]:
arg_list.append(last_param)
for x in range(5, len(arg_list)):
print (arg_list[x])
Although there might be another simpler way

Python counting the unique occurences of a string in a file

I’m trying to count the unique IP addresses in a Apache log-file using python 3.3.1
The thing is I don’t think that it is counting everything correctly.
Here is my code:
import argparse
import os
import sys
from collections import Counter
#
# This function counts the unique IP adresses in the logfile
#
def print_unique_ip(logfile):
IPset = set()
for line in logfile:
head, sep, tail = line.partition(" ")
if(len(head) > 1):
IPset.update(head)
print(len(IPset))
return
#
# This is the main function of the program
#
def main():
parser = argparse.ArgumentParser(description="An appache log file processor")
parser.add_argument('-l', '--log-file', help='This is the log file to work on', required=True)
parser.add_argument('-n', help='Displays the number of unique IP adresses', action='store_true')
parser.add_argument('-t', help='Displays top T IP adresses', type=int)
parser.add_argument('-v', help='Displays the number of visits of a IP adress')
arguments = parser.parse_args()
if(os.path.isfile(arguments.log_file)):
logfile = open(arguments.log_file)
else:
print('The file <', arguments.log_file, '> does not exist')
sys.exit
if(arguments.n == True):
print_unique_ip(logfile)
if(arguments.t):
print_top_n_ip(arguments.t, logfile)
if(arguments.v):
number_of_ocurrences(arguments.v, logfile)
return
if __name__ == '__main__':
main()
I have left put everything else.
When I run it I get
$ python3 assig4.py -l apache_short.log -n
12
But I know that there are more than 12 unique IPs in the file
It doesn’t seem to be giving me the right result. What I am trying to do is to read the file line by line, then when I find an IP address I put it into a set as it only saves unique elements and then I print out the length of said set.
IPset.update(head)
Bug. This will not do what you're expecting. You want to add each IP to your set instead. Examples make it clearest:
>>> s1 = set()
>>> s2 = set()
>>> s1.add('11.22.33.44')
>>> s2.update('11.22.33.44')
>>> s1
set(['11.22.33.44'])
>>> s2
set(['1', '3', '2', '4', '.'])

Argparse File Output in Brackets and Single Quotes

Objective: To add a prefix or suffix to a string.
Problem: The output to the file is modified to include a [''] around the input. (ex: ['prefix']word, or word['suffix'])
Question: How do I remove the bracket and single quote around the input string?
Code:
parser.add_argument('-p', dest='prefix', metavar='[Prefix]', nargs=1, help="Add a user defined prefix")
parser.add_argument('-s', dest='suffix', metavar='[Suffix]', nargs=1, help="Add a user defined suffix")
#Adding a prefix to the string
elif args.prefix:
s = str(args.prefix)
print s
def addprefix(n):
p = s + n
args.outfile.write(p)
myline = args.infile.readline()
while myline:
addprefix(myline)
myline = args.infile.readline()
args.infile.close
#Adding a suffix to the string
elif args.suffix:
s = str(args.suffix)
def addsuf(n):
p = str(n.strip()+s+"\n")
args.outfile.write(p)
myline = args.infile.readline()
while myline:
addsuf(myline)
myline = args.infile.readline()
args.infile.close
Side Note: This is a snippet of code from the much larger program.
Thanks in advance.
I'm guessing the problem is nargs=1. This tells argparse that you want to make a list. Instead, remove the nargs=1 bit and put in action='store'. You may also want to specify a default.
parser.add_argument('-p', dest='prefix',
metavar='[Prefix]',action='store',default='',
help="Add a user defined prefix")

Categories

Resources