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

Time:01-23

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.

CodePudding user response:

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)

CodePudding user response:

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.

  • Related