How to Name Variables on the Fly

How to name variables on the fly?

Use assign:

assign(paste("orca", i, sep = ""), list_name[[i]])

How to create variable names on the fly

You cannot make C variables after the program has been compiled. In order to create named things at runtime you need a dynamic data structure like a dictionary.

That said, perhaps you don't actually need the variables named, in which case a dynamically allocated array is what you need. Since you cannot actually create variables at runtime, the naming issues becomes moot.

C# call variables by formatting their name on the fly

var variablename = "v" + i;
MethodInfo method = product.GetType().GetMethod(variablename);
object result = method.Invoke(product, new object[] {}); // pass in the parameters if you need to

You can use reflection for that purpose

How can I generate new variable names on the fly in a shell script?

You need to utilize Variable Indirection:

SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'

for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done

From the Bash man page, under 'Parameter Expansion':

"If the first character of parameter is an exclamation point (!), a
level of variable indirection is introduced. Bash uses the value of
the variable formed from the rest of parameter as the name of the
variable; this variable is then expanded and that value is used in the
rest of the substitution, rather than the value of parameter itself.
This is known as indirect expansion."

Create variables with specific type on the fly in Python

Well, without getting into the details of your nesting, you could attach a variable type to the name by using a tuple.

I've done this on 2 of your variable names : ('_idx_brg',str), ('stn','int')

Rather than using zip, you'll need to hook that back up to your nested tuples and you'll also need to add error handling in case the string value from the file doesn't fit the expected variable type.

import builtins
import pdb

def set_attr(tgt, names, values):

try:
for name, value in zip(names, values):
cls_ = None
if isinstance(name, str):
setattr(tgt, name, float(value))
elif isinstance(name, tuple):
name, cls_ = name
if callable(cls_):
setattr(tgt, name, cls_(value))
elif isinstance(cls_, str):
cls_ = globals().get(cls_) or getattr(builtins, cls_)
setattr(tgt, name, cls_(value))
else:
raise ValueError("variable types have to be a string or callable like `int`,`float`, etc")
except (ValueError,TypeError,AttributeError) as e:
print(f" somethings wrong:\n{dict(exception=e, name=name, cls_=cls_, value=value)}")
#raise

#pragma: no cover pylint: disable=unused-variable
except (Exception,) as e:
if 1:
pdb.set_trace()
raise

class Foo:
pass

variable_names = ('_idx_brg', 'stn', 'stn_rel', '_n_lines', '_brg_type')
values = (1.0, 1, 1.2, 1.3, 1.4, 1.5)

foo = Foo()

print("\n\nsetting for foo")
set_attr(foo, variable_names, values)

print("\n\nfoo:", vars(foo))

variable_names2 = (('_idx_brg',str), ('stn','int'), 'stn_rel', '_n_lines', ('_brg_type','xxx'))

bar = Foo()

print("\n\nsetting for bar:")
set_attr(bar, variable_names2, values)

print("\n\nbar:", vars(bar))

output:



setting for foo


foo: {'_idx_brg': 1.0, 'stn': 1.0, 'stn_rel': 1.2, '_n_lines': 1.3, '_brg_type': 1.4}


setting for bar:
somethings wrong:
{'exception': AttributeError("module 'builtins' has no attribute 'xxx'"), 'name': '_brg_type', 'cls_': 'xxx', 'value': 1.4}


bar: {'_idx_brg': '1.0', 'stn': 1, 'stn_rel': 1.2, '_n_lines': 1.3}
br>

You could even build your own classes.

class Myclass:
def __init__(self, value):
self.value = value

#part of your name/type tuples...
(('somevar', Myclass), ('_idx_brg',str)...)

edit re. yaml:

I am not testing this so you may have to adjust a bit, esp around the exact yaml to get a dict with a nested varnames dict in it.

---
varnames:
_idx_brg: str
stn : int
from yaml import safe_load as yload
with open("myconfig.yaml") as fi:
config = yload(li)

mapping = {}

#the yaml is all strings right now
# map it to actual types/classes
for name, type_ in config["varnames"].items():
cls_ = globals().get(type_) or getattr(builtins, type_)
mapping[name] = cls_

#using it
for name, value in zip(names, values):

#fall back to `float` if there is no special-case for this varname
cls_ = mapping.get(name, float)
setattr(tgt, name, cls_(value))

Now, this does rely on all instances of a given variable name having the same type no matter where in the data hierarchy, but that's just best practices.

The other thing is that, if I have one area that looks a bit fishy/brittle to me, it is your complex nesting with tuples of values and names that somehow need to be always in synch. Much more so than your basic requirement to load text data (whose format is not under your control) but then format it different ways. I'd work at getting your names to flow more naturally with the data, somehow. Maybe try to identify incoming data by record types and then assign a mapping class to it? Same thing as what you're doing, really, just not relying on complex nesting.

Or maybe, going from your remark about row, column, you could put all that into the yaml config file as well, load that into a mapping data structure and explicitly use indices rather than nested loops? Might make your code a lot simpler to reason about and adjust for data changes.

There are also interesting things in the Python data parsing space like Pydantic. Might or might not be helpful.

R: creating a variable on the fly

You can define variables on the fly with assign. For example, the following generates three variables v1 ... v3:

var_names <- paste("v", 1:3, sep="")
for (v in var_names) assign(v, runif(1))

The counterpart to assign is get, that is, if you want the values of the variables, use something like:

bb <- sapply(var_names, get)

Also note that both assign and get have an optional envir parameter, which enables you to keep those variables away from the rest of your code.

I am not sure, but I think it is possible that if there are many variables, assign/get is faster than a list, at least if you want to look up some values.



Related Topics



Leave a reply



Submit