I'm working on some basic Python code but I've got a problem I've never been able to solve.
Indeed, I would like to change the helptip of a function and I can totally do it.
First of all, here is my code (for example) :
def main(arg1,arg2,arg3):
#some blabla
return 1
The thing is, if I start calling this function (in IDLE for example), I have an helptip appearing which just get the same syntax as my function is defined : main(arg1,arg2,arg3).
I would prefer to have something like main(Responsible name, Responsible nickname, Responsible telephone), which represents way more better what each args are. I've already try some docstring implementation but I can only get the two lines together but not remove the first one with the arg1 ...
Can someone tell me if there is a way to get what I want ?
Two things:
If you want to have named arguments, that's fine; define your function with them: def main(name, nickname, phone):; and
For docstrings, the format isn't # (comment), it's """ (multiline string).
For example:
def myfunc(name, age, height):
"""Returns a growth-rate for the person based on age and height."""
return height / age
Now the "tooltip" reads:
(name, age, height)
Returns a growth-rate for the person based on age and height.
If you don't want any named arguments to be shown, you can use *args:
def myfunc(*args):
"""Takes three arguments: name, age and height, returns a growth rate."""
name, age, height = args
return height / age
Now the tooltip is:
(...)
Takes three arguments: name, age and height, returns a growth rate.
well, basically you can't do what you say you want. You need to change the prototype of your function to match what you want to see in the doc, even though that means using very long variable names in your code.
If you take the Zen of python (explicit is better than implicit), you need to choose carefully your variable names, so they are explicit and not too long. So in either cases, your name choice is bad, arg0,arg1,arg2 is awful because it means nothing, and Responsible name... is too long (and I won't even mention that it makes no sense including a space).
And then, it's part of the docstring to give a sentence for each argument to say what that argument is all about, typically:
def afunc(foo, bar):
"""This is a function
#param foo this is the first parameter
#param bar this is the second paramater
"""
pass
Related
I am new to vim and recently I learned that it is possible to select a function in c with vip, and I was wondering if there is a way to do it with functions in python
keep in mind that function can contain different indentation levels for example
def func():
pass
if 1 > 2:
pass
and that I can't use any plugins
vip is v, followed by ip:
v enters visual mode,
ip is a text object that expands the selection to cover the current "paragraph".
It could be used to visually select a function in any language with functions, maybe, if that function satisfies Vim's definition of "paragraph". But that is a big "if", so vip is as far from being a "select function" silver bullet as it can be.
See :help v and :help ip.
Now, the way text objects like ip work is that they essentially locate a known landmark in one direction (a blank line in the case of ip) and then look for a matching one in the other direction.
Given that (simplified) description, it would be relatively easy to imagine a custom pseudo-text object for a Ruby function:
def say_hello(name)
var = "Hello, " + name
return var
end
because its boundaries are clearly defined.
But Python functions:
def func():
pass
if 1 > 2:
pass
don't have well defined boundaries and there is not a single built-in text object that is able to cover such a case.
You will need third-party help for that:
https://github.com/jeetsukumaran/vim-pythonsense
https://github.com/bps/vim-textobj-python
probably others…
I'm creating a program with a class that has 3 input attributes. The program calls a function that creates many of these objects with their inputs being given based on some other criteria not important to this question.
As I further develop my program, I may want to add more and more attributes to the class. This means that I have to go and find all instances of the function I am using to create these objects, and change the input arguments.
For example, my program may have many of these:
create_character(blue, pizza, running)
where inputs correspond to character's favorite color, food, and activity. Later, I may want to add a fourth input, such as favorite movie, or possibly a fifth or sixth or ninety-ninth input.
Do professional programmers have any advice for structuring their code so that they don't have to go through and individually change each line that the create_character function is called so that it now has the new, correct number of inputs?
Find and replace seems fine, but this makes error possible, and also seems tedious. I'm anticipating calling this function at least 50 times.
I can think of a few options for how you could design your class to make easier to extend later new kinds of "favorite" things.
The first approach is to make most (or all) of the arguments optional. That is, you should specify a default value for each one (which might be None if there's not a real value that could apply as a default). This way, when you add an extra argument, the existing places that call the function without the new argument will still work, they'll just get the default value.
Another option would be to use a container (like a dictionary) to hold the values, rather than using a separate variable or argument for each one. For instance, in your example could represent the character's favorites using a dictionary like favorites = {'color': blue, 'food': pizza, 'activity': running} (assuming the those values are defined somewhere), and then you could pass the dictionary around instead of the separate items. If you use the get method of the dictionary, you can also make this type of design use default values (favorites.get('movie') will return None if you haven't updated the code that creates the dictionary to add a 'movie' key yet).
You can take advantage of argument/keyword argument unpacking to support dynamically-changing function parameters. And also factory function/classes that generate the function you need:
def create_character(required1, required2, *opt_args, **kwargs):
""" create_character must always be called with required1 and required2
but can receive *opt_args sequence that stores arbitrary number of
positional args. kwargs hold a dict of optional keyword args """
for i, pos_arg in enumerate(opt_args):
# pos_arg walks opt_args sequence
print "position: {}, value: {}".format(i+3, pos_arg)
for keyword, value in kwargs:
print "Keyword was: {}, Value was: {}".format(keyword, value)
pos_args = (1,2,3)
create_character('this is required','this is also required', *pos_args)
""" position: 3, value: 1
position: 4, value: 2
position: 5, value: 3 """
a_dict = {
'custom_arg1': 'custom_value1',
'custom_arg2': 'custom_value2',
'custom_arg3': 'custom_value3'
}
create_character('this is required','this is also required', **a_dict)
""" Keyword was: custom_arg2, value: custom_value2
Keyword was: custom_arg3, value: custom_value3
Keyword was: custom_arg1, value: custom_value1 """
I really like the list or dictionary input method, but it was still messy and allowed for the possibility of error. What I ended up doing was this:
I changed the class object to have no inputs. Favorites were first assigned with random, default, or unspecified options.
After the class object was created, I then edited the attributes of the object, as so:
self.favorite_movie = "unspecified"
self.favorite_activity = "unspecified"
new_character = (character())
new_character.favorite_movie = "Dr. Strangelove"
I think that the downside to this approach is that it should be slower than inputting the variables directly. The upside is that this is easy to change in the future. Perhaps when the program is finished, it will make more sense to then convert to #Blckknight 's method, and give the input as a list or dictionary.
This question already has answers here:
Expanding tuples into arguments
(5 answers)
Closed 5 months ago.
I need to pass the output of a function in Python as an argument to another function. The only catch is that the 1st function returns a tuple and the entire tuple needs to be passed to the second function.
For ex:
I have a library function:
def some_function(some_string, some_number):
# does something
return (text,id)
Now I want to pass text and id returned from the some_function as arguments to another function. The catch is that the function has other arguments as well. I also need need to retrieve many texts and ids that will be generated by different values of some_string and number.
Depending on the condition met, I want to call another function which will look something like this
if abcd:
other_function(name,phone,**some_function("abcd","123")**,age)
elif xyz:
other_function(name,phone,**some_function("xyz","911")**,age)
else:
other_function(name,phone,**some_function("aaaa","000")**,age)
So what should I replace some_function("abcd","123") with so that it expands the tuple and sends both the text and id as arguments?
The other_function is defined like this
def other_function(name, phone, text, id, age):
...
return
Will simply passing some_function("aaaa","000") as an argument work?
I am asking this because I wrote a simple code to test my hypothesis and it was giving me a blank output.
def f(id,string):
return ("123", "hello")
def a(name, age, id, words, phone):
print name + age + id + words + phone
def main():
a("piyush", "23", f("12", "abc"), "123")
You have two options*; either explicitly unpack the function result first:
id, words = f('12', 'abc')
a('piyush', '23', id, words, '123')
or use tuple unpacking within the call to a, and supply the last parameter by keyword:
a('piyush', '23', *f('12', 'abc'), phone='123')
If this syntax is unfamiliar, see What does ** (double star) and * (star) do for parameters?
Note that if you try to pass phone as a positional argument (rather than a keyword argument as above) after the unpacked results from f, i.e.
a('piyush', '23', *f('12', 'abc'), '123')
you will get SyntaxError: only named arguments may follow *expression. You can't have positional arguments after * unpacking, you must use the keywords for any additional arguments.
* Unless you either:
rearrange the order of the parameters, as Oz123 suggests; or
wait for Python 3.5's release, as noted by abarnert.
You could also change the order of arguments in the signature:
def a(name, age, id, words, phone):
name = name
age=age
id=id
words=words
phone=phone
print name+age+id+words+phone
a("piyush", "23", 123, *f("12","123"))
piyush23123123hello
This way you can unpack the returned values directly when calling the function.
Note, however, that this makes readability very poor and debugging harder.
Also if you don't want to use unpacking and change the you call your function you can change the code like this:
def a(name, age, id_words, phone):
name = name
age=age
id=id_words[0]
words=id_words[1]
phone=phone
print name+age+id+words+phone
a("piyush", "23", f("12","123"), "123")
piyush23123hello123
This has the advatage of keeping all the functions call the same as they were. Only the interal works of the function change, not the signature.
Assuming you live in the future, the right way to do this is to just unpack the tuple into the middle of the argument list, like this:
a('piyush', '23', *f('12', 'abc'), '123')
Unfortunately, you, the OP, probably don't live in the future, so this is largely only helpful for people who find this answer after September 2015 (or are willing to require a pre-release version of Python before that). This functionality was added as PEP 448, which doesn't go in until Python 3.5 (and, as of 13 April 2015, doesn't even have a patch in trunk yet—but if you really want to live dangerously, you can download the latest patch at #2292, apply it to a local fork of the repo, and build it yourself…).
So, for the time being, you have to fake it, e.g., as in jonrsharpe's answer.
I just started building a text based game yesterday as an exercise in learning Python (I'm using 3.3). I say "text based game," but I mean more of a MUD than a choose-your-own adventure. Anyway, I was really excited when I figured out how to handle inheritance and multiple inheritance using super() yesterday, but I found that the argument-passing really cluttered up the code, and required juggling lots of little loose variables. Also, creating save files seemed pretty nightmarish.
So, I thought, "What if certain class hierarchies just took one argument, a dictionary, and just passed the dictionary back?" To give you an example, here are two classes trimmed down to their init methods:
class Actor:
def __init__(self, in_dict,**kwds):
super().__init__(**kwds)
self._everything = in_dict
self._name = in_dict["name"]
self._size = in_dict["size"]
self._location = in_dict["location"]
self._triggers = in_dict["triggers"]
self._effects = in_dict["effects"]
self._goals = in_dict["goals"]
self._action_list = in_dict["action list"]
self._last_action = ''
self._current_action = '' # both ._last_action and ._current_action get updated by .update_action()
class Item(Actor):
def __init__(self,in_dict,**kwds)
super().__init__(in_dict,**kwds)
self._can_contain = in_dict("can contain") #boolean entry
self._inventory = in_dict("can contain") #either a list or dict entry
class Player(Actor):
def __init__(self, in_dict,**kwds):
super().__init__(in_dict,**kwds)
self._inventory = in_dict["inventory"] #entry should be a Container object
self._stats = in_dict["stats"]
Example dict that would be passed:
playerdict = {'name' : '', 'size' : '0', 'location' : '', 'triggers' : None, 'effects' : None, 'goals' : None, 'action list' = None, 'inventory' : Container(), 'stats' : None,}
(The None's get replaced by {} once the dictionary has been passed.)
So, in_dict gets passed to the previous class instead of a huge payload of **kwds.
I like this because:
It makes my code a lot neater and more manageable.
As long as the dicts have at least some entry for the key called, it doesn't break the code. Also, it doesn't matter if a given argument never gets used.
It seems like file IO just got a lot easier (dictionaries of player data stored as dicts, dictionaries of item data stored as dicts, etc.)
I get the point of **kwds (EDIT: apparently I didn't), and it hasn't seemed cumbersome when passing fewer arguments. This just appears to be a comfortable way of dealing with a need for a large number of attributes at the the creation of each instance.
That said, I'm still a major python noob. So, my question is this: Is there an underlying reason why passing the same dict repeatedly through super() to the base class would be a worse idea than just toughing it out with nasty (big and cluttered) **kwds passes? (e.g. issues with the interpreter that someone at my level would be ignorant of.)
EDIT:
Previously, creating a new Player might have looked like this, with an argument passed for each attribute.
bob = Player('bob', Location = 'here', ... etc.)
The number of arguments needed blew up, and I only included the attributes that really needed to be present to not break method calls from the Engine object.
This is the impression I'm getting from the answers and comments thus far:
There's nothing "wrong" with sending the same dictionary along, as long as nothing has the opportunity to modify its contents (Kirk Strauser) and the dictionary always has what it's supposed to have (goncalopp). The real answer is that the question was amiss, and using in_dict instead of **kwds is redundant.
Would this be correct? (Also, thanks for the great and varied feedback!)
I'm not sure I understand your question exactly, because I don't see how the code looked before you made the change to use in_dict. It sounds like you have been listing out dozens of keywords in the call to super (which is understandably not what you want), but this is not necessary. If your child class has a dict with all of this information, it can be turned into kwargs when you make the call with **in_dict. So:
class Actor:
def __init__(self, **kwds):
class Item(Actor):
def __init__(self, **kwds)
self._everything = kwds
super().__init__(**kwds)
I don't see a reason to add another dict for this, since you can just manipulate and pass the dict created for kwds anyway
Edit:
As for the question of the efficiency of using the ** expansion of the dict versus listing the arguments explicitly, I did a very unscientific timing test with this code:
import time
def some_func(**kwargs):
for k,v in kwargs.items():
pass
def main():
name = 'felix'
location = 'here'
user_type = 'player'
kwds = {'name': name,
'location': location,
'user_type': user_type}
start = time.time()
for i in range(10000000):
some_func(**kwds)
end = time.time()
print 'Time using expansion:\t{0}s'.format(start - end)
start = time.time()
for i in range(10000000):
some_func(name=name, location=location, user_type=user_type)
end = time.time()
print 'Time without expansion:\t{0}s'.format(start - end)
if __name__ == '__main__':
main()
Running this 10,000,000 times gives a slight (and probably statistically meaningless) advantage passing around a dict and using **.
Time using expansion: -7.9877269268s
Time without expansion: -8.06108212471s
If we print the IDs of the dict objects (kwds outside and kwargs inside the function), you will see that python creates a new dict for the function to use in either case, but in fact the function only gets one dict forever. After the initial definition of the function (where the kwargs dict is created) all subsequent calls are just updating the values of that dict belonging to the function, no matter how you call it. (See also this enlightening SO question about how mutable default parameters are handled in python, which is somewhat related)
So from a performance perspective, you can pick whichever makes sense to you. It should not meaningfully impact how python operates behind the scenes.
I've done that myself where in_dict was a dict with lots of keys, or a settings object, or some other "blob" of something with lots of interesting attributes. That's perfectly OK if it makes your code cleaner, particularly if you name it clearly like settings_object or config_dict or similar.
That shouldn't be the usual case, though. Normally it's better to explicitly pass a small set of individual variables. It makes the code much cleaner and easier to reason about. It's possible that a client could pass in_dict = None by accident and you wouldn't know until some method tried to access it. Suppose Actor.__init__ didn't peel apart in_dict but just stored it like self.settings = in_dict. Sometime later, Actor.method comes along and tries to access it, then boom! Dead process. If you're calling Actor.__init__(var1, var2, ...), then the caller will raise an exception much earlier and provide you with more context about what actually went wrong.
So yes, by all means: feel free to do that when it's appropriate. Just be aware that it's not appropriate very often, and the desire to do it might be a smell telling you to restructure your code.
This is not python specific, but the greatest problem I can see with passing arguments like this is that it breaks encapsulation. Any class may modify the arguments, and it's much more difficult to tell which arguments are expected in each class - making your code difficult to understand, and harder to debug.
Consider explicitly consuming the arguments in each class, and calling the super's __init__ on the remaining. You don't need to make them explicit:
class ClassA( object ):
def __init__(self, arg1, arg2=""):
pass
class ClassB( ClassA ):
def __init__(self, arg3, arg4="", *args, **kwargs):
ClassA.__init__(self, *args, **kwargs)
ClassB(3,4,1,2)
You can also leave the variables uninitialized and use methods to set them. You can then use different methods in the different classes, and all subclasses will have access to the superclass methods.
For my app, I need to print out a series of outputs and then accepts inputs from the user. What would be the best way of doing this?
Like:
print '1'
x = raw_input()
print '2'
y = raw_input()
Something like this, but it would go on for at least 10 times. My only concern with doing the above is that it would make up for poor code readability.
How should I do it? Should I create a function like this:
def printOut(string):
print string
Or is there a better way?
First one note: raw_input() takes an optional argument ... a prompt string.
Regarding the broader question, a simplistic approach would be to create a class which defines the elements of your form and provides the functions for their input, validation, and later manipulations or output.
With such a class instances can be created (instantiated), and collected, stored, etc.
Such an approach need not any more complicated than something like:
#!/usr/bin/python
# I use /usr/bin/env python; but making SO's syntax highlighter happy.
class generic_form:
def __init__(self, element_list):
self.form_elements = element_list
self.contents= dict()
def fill_it_in(self):
for prompt in self.form_elements:
self.contents[prompt] = raw_input(prompt)
def get(self, item):
return self.contents[item]
def print_it(self):
for each in self.form_elements:
print each, self.contents[each]
if __name__ == '__main__':
sample_fields = ("Given Name: ",
"Surname: ",
"Date of Birth: ",
"Notes: ")
example = generic_form(sample_fields)
print "Fill in my form:"
example.fill_it_in()
print
print "Please review your input:"
example.print_it()
# store(:%s, %s: %s" % (example.get('Surname: '), \
# example.get('Given Name: '), example.get('Notes: '))
The main code is only a dozen lines long to define a generic form class with input
and output functionality (and a simple get() method for further illustrative purposes).
The rest of this example simply creates an instance and shows how it could be used.
Because my generic_form class is generic, we have to supply a list of field names which are to be filled in. The names are used as both the names of the fields for later access (see the get() method for an example). Personally I wouldn't do it this way, I'd provide a list of short field names and prompts similar to Marcelo's example. However, I wanted this particular example to be a short as possible to get the main point across.
(The comment at the end would be a call to a hypothetical "store()" function to store this for posterity, by the way).
This is the most minimal approach. However, you'd rapidly find that it's far more useful to have a richer class with validation for each field, and separate classes which format and output instances of that in different ways, and different classes for input. "teletype" input (as provided by the Python raw_input() built-in function) is the crudest form (primarily useful for simplicity and for the ability to process files using shell redirection). One could also support input with the GNU readline support (already included as a standard library in Python), curses support (also included), and one could imagine writing some HTML wrapper and CGI code for handling web-based input.
Coupling "raw_input()" and "print" into our class would mean more work if we ever needed or wanted to support any forms of input or output other than "dumb terminal."
If we create a class which only concerns itself with the data to be collected, then it could provide an interface for any other input class to get the list of the prompts with references to "setter" functions (and perhaps a "required" or "optional" flag). Then any instance of any input class could request the list of desired/required inputs for any form ... present the prompts, call the "setter" methods (which return a boolean to indicate if the data supplied was valid), loop over bad inputs on "required" fields, offer to skip "optional" fields, and so on.
Notice that the logic for displaying prompts, accepting responses, relaying those back to the data object via their setter methods, and handling invalid inputs and be the same for many types of forms. All we need is a way for the form to provide the list of prompts and their corresponding validation functions (and we need to ensure that all these validation functions have the same semantics --- taking the same parameters and so on).
Here's an example of separating the input behavior from the storage and validation of the data fields:
#!/usr/bin/env python
class generic_form:
def __init__(self, element_list):
self.hints = list()
for each in element_list:
self.hints.append((each, each, self.store))
self.contents= dict()
def store(self, key, data):
'''Called by client instances
'''
self.contents[key] = data
return True
def get_hints(self):
return self.hints
def get(self, item):
return self.contents[item]
def form_input(form):
for each, key, fn in form.get_hints():
while True:
if fn(key,raw_input(each)):
break
else:
keep_trying = raw_input("Try again:")
if keep_trying.lower() in ['n', 'no', 'naw']:
break
if __name__ == '__main__':
sample_fields = ("Given Name: ",
"Surname: ",
"Date of Birth: ",
"etc: ")
example = generic_form(sample_fields)
print "Fill in my form:"
form_input(example)
print
print "Please review your input:"
for i, x, x in example.get_hints():
print example.get(i),
In this case the extra complication is not doing anything useful. Our generic_form performs no validation. However, this same input function could be used with any data/form class that provided the same interface. That interface, in this example, only requires a get_hints() method providing tuples of "prompt string", storage key, and storage function references, and a store() method which must return "True" or "False" and take arguments for the key and data to be stored.
The fact that our storage key is passed to our input "client" as an opaque item that must be passed back through its calls to our store() method is a bit subtle; but it allows us to use any single validation function for multiple form elements ... all names can be any string, all dates must pass some call to time.strftime() or some third party parser ... and so on.
The main point is that I can create better forms classes which implement data validation methods as appropriate to the data being gathered and stored. The input example will work for our original dumb forms, but it will work better with forms that return meaningful results from our calls to store() (A better interface between forms and input handling might supply "error" and "help" prompts as well as the simple short "input" prompt we show here. A more complex system might pass "datum" objects through the get_hints() methods. That would require that the forms class instantiate such objects and store a list of them instead of the tuples I'm showing here).
Another benefit is that I can also write other input functions (or classes which implement such functions) that can also use this same interface to any form. Thus I could write some HTML rendering and CGI processing which could use all of the forms that had developed with no changes to my data validation semantics.
(In this example I'm using the get_hints() method as hints for my crude output function as well as my inputs. I'm only doing this to keep the example simple. In practice I'd want to separate input hinting from output handling).
If you are reading in several fields, you might want to do something like this:
field_defs = [
('name', 'Name'),
('dob' , 'Date of Birth'),
('sex' , 'Gender'),
#...
]
# Figure out the widest description.
maxlen = max(len(descr) for (name, descr) in field_defs)
fields = {}
for (name, descr) in field_defs:
# Pad to the widest description.
print '%-*s:' % (maxlen, descr),
fields[name] = raw_input()
# You should access the fields directly from the fields variable.
# But if you really want to access the fields as local variables...
locals().update(fields)
print name, dob, sex
"10 times... poor code readability"
Not really. You'll have to provide something more complex than that.
20 lines of code is hardly a problem. You can easily write more than 20 lines of code trying to save yourself from simply writing 20 lines of code.
You should, also, read the description of raw_input. http://docs.python.org/library/functions.html#raw_input
It writes a prompt. Your four lines of code is really
x = raw_input( '1' )
y = raw_input( '2' )
You can't simplify this much more.