What is this object? - python

I know this is a data object but I'm new to python and I don't understand what user_output is doing. Trying to understand all this.
def user_output(self,check): #data object
output = ""
#loop of all the info for __user_arr
for user in self.__user_arr:
if user.user_bot == str(check):
output += '''
<div class='about'>
<h1>{user.user_name}</h1>
<h2>My favorite band is: {user.user_band} </h2>
<div class='business'>
<p>Why I want the tickets:<br /> {user.user_business}</p>
</div>
</div>
'''
return output.format(**locals())
else: #this will spit an error if the user do not answer the last question correctly.
output = '''<div class='error'><h2>Turns out you are a robot. No tickets for you </h2></div>'''
return output

It will generate for each user a div block with some favorite bands etc. , provided that, the user flag user_bot is equal to check (as far as I can understand a kind of bot check). If the user is a bot (does not pass the check) the program will generate the Turns out you are a robot.. block.

This looks like a function, not an object. It checks whether your user is a robot. It does so by checking if your user (for every user) has their user_bot as the string you get as input, probably a string identifying robots. Then you write something I know nothing about to the output string, probably selling the ticket.
This function seems to do this only for the first user, though because it returns in the first if else clause.

user_output() seems to be a method in some class. It is using a "poor man's" tempting facility to output an HTML fragment.
It appears to use a loop, for user in self.__user_arr:, but this is a bit of a sham. It uses this construct to pick the first item out of self.__user_arr. Because it soon returns from the function under all conditions, it will never return to the head of the loop to check subsequent users (if any).
Also note that the double-understore prefix to self.__user_arr marks it as a private part of the implementation of the object. A deeply private part. A single underscore usually indicates "private." Double underscores don't have a super-precise definition, but "very private" or "very implementation dependent" would be my guess.
If the user_bot property of that first user is a string equal to the check value (as stringified), then the template is instantiated. It does this first by setting a string variable (output) which has embedded in tt the variable markers ({a_variable}) compatible with str's format method. Calling output.format(**locals()) does the string formatting operation using locals() (which is a lookup dictionary of all current variable assignments, a.k.a. a symbol table). The **locals() construction means "use this dict (or dict-like) object as though it were a set of keyword arguments." The effect is that substrings in output like {user.user_band} are directly interpolated into the output string. Then the filled-in string is returned.
If, instead, the user.user_bot == str(check) test fails, a simple error string is returned.
In either case, a string is returned, and the method exits.
The only other case worth considering is what if there are no users in the self.__user_arr collection? Then the loop would never run, and the method would return None implicitly.

Related

Disallow passing f-strings as argument

I am reporting data from some tests, and each test can have a 'summary' and a 'details' section. The 'summary' field for any particular test should be static, with any additional dynamic information going into the details field, as follows:
run_test()
if condition:
report_test_data(summary="condition met", details=f"{component} ended with {state}")
else:
report_test_data(summary="condition not met", details=f{component} ended with {state}")
However, this only applies to these calls to report_test_data, and there is nothing to stop another test from swapping these around, or putting all the data into the 'summary' field:
run_test()
if condition:
report_test_data(summary=f"{component} ended with {state} - condition met", details="")
else:
report_test_data(summary=f"{component} ended with {state} - condition not met", details="")
I am analyzing the test data based off the summary, so any particular ending state (e.g. condition = True) should have a static return string. I thought about making a class that manually defines every possible 'summary' string, but that quickly becomes untenable with more tests when a given test can have tens of possible ending states. The best option I can think of is if I could force the value passed into 'summary' to be a normal string. Is there any way to disallow passing f-strings into a particular function?
Note: I use pylint, so if there's an easy way to make it call these out, that would work as well.

How do I pass an object instead of a string via pythons' input() function?

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?
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.

Is it more efficient to use function args after branching (Python)?

I have a function that takes several arguments, one of which is a contact number. The data provided to the function is used to generate documents, and if one option is selected, that document is immediately returned inline, where the other option takes the contact number and generates an email. In the original version of this function, the contact number was immediately parsed at the start of the function, but I moved it into the else block as that is where the email is actually generated that uses that contact number and I saw no reason to create a new variable if it was not used half of the time. An example of this is below, and is built in Python using the Django framework:
def function(request, object, number=None):
obj = ObjectItem.objects.get(id=object)
# Originally number processed here
if request.method == 'POST':
if 'inline' in request.POST:
data = {
'object': obj,
}
return generate_document(data, inline=True)
else:
if number:
contact = '{}'.format(number)
else:
contact = obj.contact
data = {
'object': obj,
}
document = generate_document(data, inline=False)
return message(document, contact)
else:
return redirect()
While looking at my code, I realize that I could move the data dict creation outside of the processing for the inline vs no inline in the POST, but I do not know if moving the processing of the number argument into the else block in that processing actually saves any time or is the more standard way of doing things. I know that as Python is a scripting language, there is not any kind of optimizations that would be performed automatically like they would rearranging that kind of declaration in a compiled language, so I am looking for the most efficient way of doing this.
From a performance perspective, it makes no difference whether you create data above the if or in the if. Python will only hit the line once and the dict will only be created once. But you should move it above the if for design reasons.
First, don't repeat yourself - if you can reasonably implement a bit of code in one place, don't sprinkle it around your code. Suppose you decide a defaultdict is better later, you only have to change it in one place.
Second, placement implies intent. If you put it above your if you've made a statement that you plan to use that data structure everywhere. In your current code, readers will ask the same question you do... why wasn't that above the if? Its kinda trivial but the reading of the code shouldn't raise more questions.

using boolean in python from inputs

PhoneValue=0
if (condition== "new"):
PhoneValue=int(PhoneValue+10)
else:
PhoneValue=int(PhoneValue+9)
if GPS==bool(input("true")):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
if WiFi==eval(bool(input("true"))):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
if camera==eval(bool(input("true"))):
PhoneValue=int(PhoneValue+1)
else:
PhoneValue=int(PhoneValue)
global PhoneValue
This is my code. I am supposed to be able to input the condition, GPS, camera, and WiFi and the code evaluates the input and gives points for each condition. If the phone is new it gets ten points and if used it gets nine. For GPS, Camera, and WiFi it wants me to use boolean to either give it a point for true or no points for false. I am wondering how do I convert the input string into boolean in order to add it to phone value?
There's a lot wrong in this code. Firstly, the input() command is defined
input([prompt])
If the prompt argument is present, it is written to standard output without a trailing newline.
which means your call to input("true") prints "true" on the console and waits for a line of input. That's not what you were hoping for.
Your use of eval is bad. Almost every use of eval on user input is a problem. But you saved yourself here by accident: eval(bool(text)) is superfluous. The only thing that bool() can return True or False neither of which is dangerous to eval, but since you already had a boolean in hand, eval'ing it didn't do anything.
Converting the result of integer addition to an int() is useless, and your if / else clauses can be more clearly written as:
if input("Is there a GPS? "):
PhoneValue += 1
with no else clause needed. Unfortunately, this has almost no chance of getting correct input. If I type "True" the if block will trigger. It will also trigger if I write "no", "false", or "JosEduSol", those will be evaluated as True also. The declaration at the end
global PhoneValue
does absolutely nothing as the last line. In fact, you should probably just forget that global exists because most everybody uses it incorrectly.
There are more faults in the code, and you should really get assistance from a teacher or get a better learning resource.

Placing a Python variable inline

Forgive this rather basic Python question, but I literally have very little Python experience. I'm create a basic Python script for use with Kodi:
http://kodi.wiki/view/List_of_built-in_functions
Example code:
import kodi
variable = "The value to use in PlayMedia"
kodi.executebuiltin("PlayMedia(variable)")
kodi.executebuiltin("PlayerControl(RepeatAll)")
Rather than directly providing a string value for the function PlayMedia, I want to pass a variable as the value instead. The idea is another process may modify the variable value with sed so it can't be static.
Really simple, but can someone point me in the right direction?
It's simple case of string formatting.
template = "{}({})"
functionName = "function" # e.g. input from user
arg = "arg" # e.g. input from user
formatted = template.format(functionName, arg)
assert formatted == "function(arg)"
kodi.executebuiltin(formatted)
OK as far as I get your problem you need to define a variable whose value could be changed later, so the first part is easier, defining a variable in python is as simple as new_song = "tiffny_avlord_I_love_u", similarly you can define another string as new_video = "Bohemia_on_my_feet", the thing to keep in mind is that while defining variables as strings, you need to encapsulate all the string inside the double quotes "..." (However, single quotes also work fine)
Now the issue is how to update it's value , the easiest way is to take input from the user itself which can be done using raw_input() as :
new_song = raw_input("Please enter name of a valid song: ")
print "The new song is : "+new_song
Now whatever the user enters on the console would be stored in the variable new_song and you could use this variable and pass it to any function as
some_function(new_song)
Try executing this line and you will understand how it works.

Categories

Resources