Simulate normalizing arguments - python

If you pass string like this to your python as program argument
my.py name1=abc name2='def' name3="ghi klm"
then sys.args will return list like this
['name1=abc', 'name2=def', 'name3=ghi klm']
thus all quotes are considered and removed. Which function in python can take string of arguments and return such normalized list?
Update
Input string -> 'name1=abc name2=\'def\' name3="ghi klm"'
Output list -> ['name1=abc', 'name2=def', 'name3=ghi klm']

To split arguments in the same way as the shell, you can use shlex.split():
>>> shlex.split("name1=abc name2='def' name3=\"ghi klm\"")
['name1=abc', 'name2=def', 'name3=ghi klm']

Which function in python can take string of arguments and return such normalized list?
There may be one, but the work is actually done by your operating system. The Python interpreter just propagates the list it gets from the OS as sys.args.

Related

Convert function arguments to str

I wrote a function and call it as below:
from lib import base_frequency
base_frequency("AB610939-AB610950.gb", "genbank")
#This calls the function that uses a BioPython code.
How could I pass the function arguments as below?
base_frequency(AB610939-AB610950.gb, genbank)
Note that quotes are missing. Should I do this? Is there a recommended nomenclature in Python when function argument is sting?
I thought this required me to convert filename and record format to a string inside the function. That is:
AB610939-AB610950.gb to "AB610939-AB610950.gb"
genbank to "genbank"
I have tried str(AB610939-AB610950.gb) inside the function but it did not do the job.
There is no way to do this without quotes, or else Python will interpret it as an expression. Take the first argument for example,
AB610939-AB610950.gb
Python will read this as a subtraction operation between two variables, AB610939 and the gb property of AB610950, not a sequence of characters. The only way to stop this is to surround it in quotation marks to make it string literal.
Is there a recommended nomenclature in Python when function argument is string?
Yes.
Enclose a string literal "within quotes".
Here is a pair of valid examples of doing that:
base_frequency("AB610939-AB610950.gb", "genbank")
That produces a pair of str values,
pushes them onto the stack,
and calls the base_frequency function.
If e.g. the 2nd arg was an unquoted genbank,
that would mean something entirely different.
It would mean "please look up the value of
the variable named genbank and pass its
value to the function."
If you ask for a variable that does not exist,
the result will be a NameError.

Returning more than one output in C extensions?

Python allows to return more than one result using commas as separating value.
When developing a CPython extension written in C language, is it possible to obtain the same result? How?
I'm developing a CPython extension that replaces an existing Python code to do some tests on performance and I will prefer to have the same interface to not change the existing code base.
I'm using Python 3.6.
Yes, you can create a tuple with PyTuple_New, populate it and return it. The callee will be able to unpack the result as usual.
Python returns multiple values by using containers. A single object is returned that is unpacked. Comma separated means tuple; in square brackets, on the other hand, a list is created. See How does Python return multiple values from a function for more on this.
If you'd like an example of how one might do this in C you can take a look at the implementation of str.partition or array.buffer_info (or any tuple returning built-in method).

How do I get/record the index of the option in the arg list during argparse

I would like to get/record the indexes into the sys.argv list as the options are parsed
I am trying to wrap another program with a python script.
And in the wrapper script I am trying to parse the options that matter to the script
and remove them from the argv list, so that I can pass the remainder of the arguments to the program being wrapped.
To do this, I am using parser.parse_known_args() so that I don't have to track every argument the program may support. just the ones that matter to the wrapper.
Now if the parsing recorded the indexes of arguments that need to be removed
I could remove them after parsing and pass the remaining args to the wrapped program.
How do I record this information during parsing?
Not all arguments that is meaningful to the wrapper should be removed. So I need to be selective
parse.parse_known_args returns 2 values, the namespace containing arguments that it knows about, and a list of the strings that it could not handle. I think that rest list is what you want to pass on to the other program.
In other words:
[args1, rest] = parser1.parse_known_args() # or (sys.argv[1:])
args = parser2.parse_args(rest)
If you can't give parser2 an explicit list of arguments (e.g. it is coded as parse_args()), then you need to do to do something like:
sys.argv[1:] = rest
I looked again at the internals of argparse, _parse_known_args. It iterates through the argument strings a couple of times. The loop that consumes strings uses a while start_index<max_index:. start_index is incremented by varying amounts depending on the nargs of each argument. It does, in effect, point to the first string used for a particular argument (e.g. the -f flag). But its value is not given to the action function (which you can customize). Nor is it recorded anywhere. Strings that it can't handle are added to an extras list. This is the 2nd value that parse_known_args returns.
I am not familiar with parser.parse_known_args(). I am using Python 2.7 and there is no such function. What you could do though is save the original sys.argv in say arg_list and do
indices = [arg_list.index(a) for a in selected_arguments]
This will return a list of indices (the positions) of the selected arguments

Python subprocess module: How can I pass comma separated input into Popen?

I have a list of strings and a command I'd like to run with Popen. The command takes the strings as input arguments.
How can I easily add the entire list...
list=['asdf','qwer','zxcv',...]
...as comma separated input shown below:
Popen(['cmd','asdf','qwer','zxcv',...])
I won't be able to do this because it won't convert list to str implicitly:
Popen(['cmd',list])
Nor this, because it simply won't allow for spaces within a string:
Popen(['cmd',' '.join(list)])
Is there an alternative?
I do not want to use the 'shell=True' option.
You can do the following to create a new list from two (or more) separate lists.
['cmd'] + list
This creates a new list for you with the contents of both. As you mentioned, the syntax looks and does exactly as you expect, which is adding two lists together.
Note: I would also like to warn that you shouldn't use list as a variable name. Since this means you are shadowing the built-in list type. Which could cause unforeseen problems later.

What is the Python 3 equivalent of find ()?

I'm working on the MIT open courseware for python but have having a hard time with the following example:
To get started, we are going to use some built-in Python functions. To use these functions, include the statement
from string import *
at the beginning of your file. This will allow you to use Python string functions. In particular, if you want to find the starting point of the first match of a keyword string key in a target string target you could use thefind function.
Try running on some examples, such as find("atgacatgcacaagtatgcat","atgc")
Note how it returns the index of the first instance of the key in the target. Also note that if no instance of the key exists in the target, e.g, find("atgacatgcacaagtatgcat","ggcc") it returns the value -1.
The course in python 2.4 (or so) but I'm trying to do the assignments in Py3.. learning the differences along the way.
Use the .find() method of a string, rather than string.find(). (This also works, and is probably preferable, in python 2).
Isn't it still just find? From the documentation:
str.find(sub[, start[, end]])
Return the lowest index in the string
where substring sub is found, such
that sub is contained in the slice
s[start:end]. Optional arguments start
and end are interpreted as in slice
notation. Return -1 if sub is not
found.
str = "Python"
In Python2:
string.find(str,"y")
In Python3:
str.find("y")
For Python2 and Python3:
if 'atgc' in 'atgacatgcacaagtatgcat':
#do something
name = "ALIEN" # complete String
letter = 'E' # substring
#string.find(substring[start:end])
name.find(letter[:])
Output : 3

Categories

Resources