1

I am working on a machine learning modelling problem where an object is created to store training and validation data, but the validation set if optional and if not included when creating the object the default value is None.

If we find out later on though the user wants to add a validation pandas dataframe we were hoping to let them supply the name of the dataframe with input(). With a function defined right in the notebook we're running we can then do an eval(<input>) to turn the string into the object we need. If we define the object outside of our notebook though it seems like the scope doesn't include that variable.

I realize this probably isn't the best way to do this, so what is a more pythonic way to let a user supply a dataframe by name after an object as already been instantiated? We can pass the objects fine as arguments to functions. Is there a way to pass an object like that but with input() or some other user-friendly way to prompt the user?

snakecharmerb
  • 28,223
  • 10
  • 51
  • 86
maccam912
  • 534
  • 6
  • 18
  • 2
    Create a `dict` and keep a mapping ? – han solo Mar 22 '19 at 15:30
  • The sort of thing you're talking about sounds doable. But I think we need more to go on here. Can you post your code and ask a specific question about it? @hansolo may have the right idea. You could pass an empty dict instead of None so that you always have an object to work with. But it's pretty hard to know what your problem really is without seeing what you're doing in code. – CryptoFool Mar 22 '19 at 15:41
  • @Steve pretty sure they meant that you should use a dict to maintain a mapping from strings to dataframe instead of hackily relying on eval. None is just as much an object as a dict. Everything is an object in Python. In any case though, this question does require clarification. It is unclear exactly what isn't working for the OP, e.g. what does "we define the object outside of our notebook though it seems like the scope doesn't include that variable" even mean? – juanpa.arrivillaga Mar 22 '19 at 16:38

1 Answers1

1

It maybe possible to use locals() or globals() as a dict for grabbing an initialized variable by it's name.

the_variable = {'key_one': 'val_one'}

selected_input = input("Please input a variable name")
selected_var = locals()[selected_input]

print("selected_var continence -> {0}".format(selected_var))

Should output, well assuming the_variable was passed to input()

selected_var continence -> {'key_one': 'val_one'}

This is an adaptation of an answer to Calling a function of a module by using it's name a string, but seems to work in this instance too.


Update

I can't remember where I picked up the following perversion (I did look about though), and I'm not suggesting it's use in production. But...

questionable_response = lambda message: input("{message}: ".format(message = message))

this_response = json.loads(questionable_response("Input some JSON please"))
# <- '{"Bill": {"person": true}, "Ted": {"person": "Who is asking?"}}'

... does allow for object like inputting.

And getting data from an inputted json string could look like...

this_response['Bill']
# -> {u'person': True}

this_response['Ted'].get('person')
# -> u'Who is asking?'

... however, you'll likely see some issues with using above with other scripted components.

For the Unicode conversion there's some pre-posted answers on the subject. And checking help(json.loads) exposes that there's toggles for parse_ing floats, ints, and constants.

Even with that it may not be worth it, because there's still some oddities you'll run into if trying to implement this funkiness.

Just to list a few;

  • conjunctions are a no go; let's say ya get a clever Clara who inputs something like '{"Clara": {"person": "I'll not be labelled!"}}'. That would cause an error unless ' was escaped, eg. \'

  • the above is also quote fragile; perhaps someone at the keyboard hasn't had enough to drink and tries "{'Jain': {'person': True}}". That would first barf on quotes, then heave from True not being true

So like I prefaced at the start of this update, I'll not recommend this in production; could waist a lot of time chasing edge-cases. I only share it because maybe you've not found any other option for getting from input to something that can be interrogated like an object.

S0AndS0
  • 746
  • 1
  • 6
  • 18