Convert function arguments to str - python

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.

Related

How can I use user input to choose a parameter name and an attribute name?

I'm using a library called unit-convert. The interface looks like this:
# Bytes to terabytes
>>> UnitConvert(b=19849347813875).tb
Suppose I have strings taken from user input (omitting the input code) like so:
input_value_unit = 'b'
output_value_unit = 'tb'
How can I substitute these into the call?
I tried using UnitConvert(input_value_unit=user_input_value).output_value_unit, but this doesn't use the string values.
Code like function(x=1) doesn't care if there's a variable named x naming a string; the x literally means x, not the x variable. Similarly for attributes: x.y doesn't care if there is a y variable naming a string; it will just get the y attribute of x.
However, we can use strings to specify both of these things "dynamically".
To replace the b in the example, we need to use a string as a keyword argument name. We can do this by making a dictionary for the keyword arguments, and then using ** to pass them. With a literal string, that looks like: UnitConvert(**{'b': ...}).
To replace the tb, we need to use a string as an attribute name. We can do this by using the built-in getattr to look up an attribute name dynamically. With a literal string, that looks like: getattr(UnitConvert(...), 'tb').
These transformations let us use a literal string instead of an identifier name.
Putting it together:
# suppose we have read these from user input:
input_value_unit = 'b'
output_value_unit = 'tb'
input_amount = 19849347813875
# then we use them with the library:
getattr(UnitConvert(**{input_value_unit: input_amount}), output_value_unit)
Edit again - perhaps I still misunderstand. You're using an existing module that you downloaded?
Now that your code has been pared back to look nothing like the original, my first answer no longer applies. I'll leave it below the underline because you should still be aware.
Usually in your situation the second unit would be passed as a second parameter to the function. Then the function can do the appropriate conversion.
UnitConvert(user_input_value, output_value_unit)
There's an alternative that looks a little closer to what you had in mind. If your function returns a dictionary with all the possible conversions, you can select the one you need.
UnitConvert(user_input_value)[output_value_unit]
The old irrelevant answer. Your statement:
if user_input_convert == ["kilometres", "miles", "nanometres", "metres"]:
is comparing a single string to a list of strings. They will never be equal. What you probably want is:
if user_input_convert in ["kilometres", "miles", "nanometres", "metres"]:
That checks to see if your string is equal to one of the strings in the list.

Is it possible to use format() function with a string in format's place?

I'm using a format() in python and I want to use a variable pokablelio so that the person could choose how many numbers to output after the dot. When I try to put the variable alone after the comma it outputs: ValueError: Invalid format specifier. I tried replacing some characters or making the whole string in a parentheses but that didn't work.
Right now I'm wondering: Can I even use a variable as a string to put it in format's place?
(note: The machine should have a "'.10f'" string in the variable)
Error and the code
It is possible to use variables as part of the format specifier, just include them inside additional curly braces:
>>> n_places = 10
>>> f'{1.23:.{n_places}f}'
'1.2300000000'

function argument as an input for f-string to change variables

def cleaning(input):
name = str(input)
read_file = pd.read_csv('#f"{name}".csv')
print(read_file)
cleaning(InputKeyword)
My function must take an input keyword, and this will change the "name" to "#input" word.
I was trying with f-strigs, but it doesn't work. Any ideas or referrals where can I find the solution?
Thanks in advance:)
read_file = pd.read_csv('#f"{name}".csv')
That's not actually an f-string, it's a normal string that has an f, some quotes, and some braces inside it. An f-string must be prefixed with (surprisingly enough) an f :-)
I suggest you try something like:
read_file = pd.read_csv(f"#{name}.csv")
If the name string holds xyzzy, this will try to process the file #xyzzy.csv.
Additionally, it's a very bad idea to use built-in functions as variable names. The input function is one such example. The following (complete) snippet solves both those issues:
# Assumes file_base is a string, see below.
def cleaning(file_base):
read_file = pd.read_csv(f"#{file_base}.csv")
print(read_file)
cleaning("someString")
Note that you can put arbitrary expressions inside f-strings, not just variable names. Hence there's no need to create name as a separate (named) object, you could just insert str(file_base) inside the braces.
However, for your particular case, I don't think the use of str(file_base} is necessary since it appears from tour comments that file_base is already a string, and I believe the formatting for a string without a format_spec is just the string itself(a).
This is why I have f"#{file_base}.csv" in the code above without a str() around the file_base variable.
(a) For objects in general, an {object} snippet inside an f-string will call the object's __format__() method, passing in the format_spec used. Hence f"{something:314159} would use the object method call something.__format__("314159") to format the object into a string.

How to take bytes as input without any manipulation in it in python?

I am taking a byte as input
b'\xe2I4\xdd\r\xe5\xfcy^4\xd5'
but it gets converted into string.
so when i am to trying to convert this string to byte it is again manipulating it and giving me output as:
b"b'\\xe2I4\\xdd\\r\\xe5\\xfcy^4\\xd5'"
My desired output is that when i provide b'\xe2I4\xdd\r\xe5\xfcy^4\xd5' it convert it into byte as it is without manipulating it or adding any character or symbol.
Any resource or reference will be helpful.
Thanks In Advance
The BAD idea
You could pass the value of input() to eval() function. The function eval() directly evaluates a string as if it were directly executed in Python. Although it might feel like a best feature at first but due to the same reason it is pretty much unsafe to use it within any production-level application, since, the user can execute any code using that which might cause a lot of problems.
Better alternative
You can use a safer alternative to eval() which is ast.literal_eval(). This function evaluates a given string as Python literals (like string, numbers, bytes object, etc.). In case if a string does not contain any literal (like function calls, object creation, assignment, etc.), this function throws an error. Enough about that let's see how you could get this working.
import ast
user_input = input()
eval_expr = ast.literal_eval(user_input)
If you want to check if the input is a bytes literal, you could use the isinstance function to check and then perform required action.
# Optional: Handle if `eval_expr` is not a `bytes` literal
if not isinstance(eval_expr, bytes):
...
So, all you need to do is import the module ast first. Then take the user's input. Thereafter pass this input string to ast.literal_eval() function to evaluate the string.

Simulate normalizing arguments

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.

Categories

Resources