Python args kwargs

Discussion in 'Tech Discussion' started by Ai chan, Feb 8, 2019.

  1. Ai chan

    Ai chan Queen of Yuri, Devourer of Traps, Abused Witch

    Joined:
    Nov 7, 2015
    Messages:
    8,645
    Likes Received:
    17,968
    Reading List:
    Link
    Oh wow, outright calling me a liar huh? I don't know what kind of genius you think people are, but there are people who take much more to understand certain stuff that is not their vocation. For example, you are not a baker. You are given a recipe. Can you bake a cake to be just like the picture given?

    Similarly, if you give C++ For Dummies to your uncle who is a farmer, telling him he can google anything he doesn't understand, do you think he can be a passable programmer? Google is not everything, even googling doesn't give you the answers that are not factual in essence. It excel in giving facts, but it isn't good at correcting your mistakes for you. You need an actual teacher.

    Programming is a niche skill. It's not like riding a bike, which almost everyone can learn. Granted, there are kids who take a long time to learn how to ride a bike, but generally, unless you have a disability, anyone can ride them. People said that @WinByDying gave the best explanation, but I still couldn't understand it. It took @RyouDou 's explanation to supplement his explanation that I could get a hint of what it is. Google is not the answer, there's a reason why programming forums exist.

    Instead of forcing your superiority complex on others, why don't you help by pointing me the source that google give you. You said it's for my own good, right? What you're doing is only showing off your superiority. This question is not factual in nature, but instructional in nature.

    For the record, I am an author and a translator. I can do HTML and I passed simple C++ under Programming 1 back on college, but I am not someone who learn programming full time or even part time. I learn enough to make my own visual novel. Anything I don't know, I ask, because asking experts are a lot faster than browsing google and trying to make sense of different examples.
     
    Last edited: Feb 9, 2019
    Ruyue, orematcha and Nanashy like this.
  2. Nanashy

    Nanashy Scarybun of Horror

    Joined:
    Mar 13, 2016
    Messages:
    401
    Likes Received:
    540
    Reading List:
    Link
    While one can for sure learn the language by just googling, there is always a need of having someone to explain/teach the nuances. There are many examples in the internet, but rarely they state that the "args" and "kwargs" names can be something else as long as the stars are before them and such. I have seen many newbies continuing using those two names thinking that they are of the keywords presented by the language.
     
    Ai chan likes this.
  3. otokonoko

    otokonoko 【LGBTQ+ association】 【ohko is ohko!】

    Joined:
    Sep 18, 2017
    Messages:
    194
    Likes Received:
    440
    Reading List:
    Link
    I didn't read @WinByDying's link, but one reason why args and kwargs are useful are because it allows your code to be more reusable even when you add/change more features in the future.

    I'll give an example here.

    Pretend you work for a big weapons software company and a coworker from another overseas department in India (not yours) wrote this really fancy program that would be a headache to change yourself:

    Code:
    # Your coworker's code:
    def detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo):
        # pretend this function is really complicated and has 10000 lines of code
        # kaboom!
    
    Now, one day your boss comes to you and tells you he wants a function with a confirmation dialogue that wraps the nuclear_bomb function so that an idiot doesn't accidentally fire the bomb.

    So you go ahead and write a wrapper function called "are_you_sure_detonate_nuclear_bomb":

    Code:
    # Your coworker's code:
    def detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo):
        # pretend this function is really complicated and has 10000 lines of code
        # kaboom!
    
    # Your wrapper code:
    def are_you_sure_detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo):
        yesimsure = prompt("Are you sure you want to blow up the world?")
        if yesimsure:
             detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo)
    
    But this is annoying because you had to copy the entire argument list in your wrapper function.

    Also there's a possibility that if you're a stupid programmer, you might do something unnecessarily complicated and silly like this:

    Code:
    # Your coworker's code:
    def detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo):
        # pretend this function is really complicated and has 10000 lines of code
        # kaboom!
    
    # Your wrapper code:
    def are_you_sure_detonate_nuclear_bomb(Im, changing, the, arguments, names, because, I, can, make, sure, don't, typo):
        really = Im
        complicated = changing
        list = the
        of = names
        one = because
        hundred = I
        you = can
        yesimsure = prompt("Are you sure you want to blow up the world?")
        if yesimsure:
             detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo)
    
    This is bad because anybody else reading your code will be confused. Also, you might even get confused looking at your own code, and there's always the possibility you had an accidental typo or arranged the arguments in the wrong order.

    What makes it even worse is that one day, your coworker might change the original detonate bomb function they wrote without being aware that you wrote a wrapper function somewhere else:

    Code:
    # Your coworker's code:
    def detonate_nuclear_bomb(I, changed, my, mind, I, want, my, arguments, to, be, different):
        # pretend this function is really complicated and has 10000 lines of code
        # kaboom!
    
    # Your wrapper code:
    def are_you_sure_detonate_nuclear_bomb(Im, changing, the, arguments, names, because, I, can, make, sure, don't, typo):
        really = Im
        complicated = changing
        list = the
        of = names
        one = because
        hundred = I
        you = can
        yesimsure = prompt("Are you sure you want to blow up the world?")
        if yesimsure:
             detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo)
    
    Now the program broke! Oh no!!!!

    This is bad and all of a sudden your nuclear defense system crashes at the worst possible moment and you all die!

    ----------------

    There's a really simple way for you and your coworker to solve all of these problems: use args and kwargs!

    Code:
    # Your coworker's code:
    def detonate_nuclear_bomb(really, complicated, list, of, one, hundred, arguments, make, sure, you, don't, typo):
        # pretend this function is really complicated and has 10000 lines of code
        # kaboom!
    
    # Your wrapper code:
    def are_you_sure_detonate_nuclear_bomb(*args, **kwargs):
        yesimsure = prompt("Are you sure you want to blow up the world?")
        if yesimsure:
             detonate_nuclear_bomb(args, kwargs)
    
    Now you didn't need to write the entire argument list again and it just gets passed directly to the inside function. Yay, life is easier and less risk of mistakes.
     
    Last edited: Feb 12, 2019
    gangbuntu and Ai chan like this.
  4. WinByDying

    WinByDying I can count to four

    Joined:
    Jul 18, 2017
    Messages:
    621
    Likes Received:
    538
    Reading List:
    Link
    My link? I think you mean someone else, I didn't provide a link.
     
  5. gangbuntu

    gangbuntu Well-Known Member

    Joined:
    Jul 9, 2016
    Messages:
    153
    Likes Received:
    87
    Reading List:
    Link
    you did; it even said Link just under your name.

    joking aside,

    "googling is your friend", "programming is stackoverflow" can be a pit sometimes.
    the top search result / most voted answer doesn't always give the best (or even right) answer.
    heck, even microsoft's msdn sometimes give pit-level samples that code monkey would just imitate.

    some languages provide syntactic sugar and many "kites" (those following wherever the wind blows) would join the bandwagon without understanding the intent, purpose or nuance of the new feature.
    they just thought: it's new, it's sexy, i like. and they become zealot preachers.

    WinByDying started by explaining what those keywords mean
    otokonoko expands by explaining why those keywords matter
    at this point one can conclude that those keywords are not merely cryptic / exotic, but also useful.
    it would be great if someone can expand further on when the keywords do more harm instead.
    the right tool for the right job; using something because it is appropriate, not because "yes, we can"
     
    Ai chan likes this.
  6. Jeebus

    Jeebus Well-Known Member

    Joined:
    Jun 20, 2017
    Messages:
    628
    Likes Received:
    547
    Reading List:
    Link
    Dictionaries are formed from a key and a value pair. We can make a quick dictionary to describe a hydra to show how they work:
    hydra = {'heads': 9, 'legs': 4, 'tails': 1}

    If you wanted to access the number of heads a hydra has, you can just input: hydra['heads'] to get an output of 9.

    Dictionaries are unordered, and the keys are immutable. If the order of your arguments matters, don't use a dictionary. If you need the keys to be mutable, don't use a dictionary. Mutable vs. immutable is a conversation for another time.

    Searching keys in a dictionary is constant (O(1)) for an average case in terms of algorithmic efficiency up to a certain point. Afterward, it converges on O(log n). In any case, they're great to use if you need to iterate over a large dataset.

    As far as *args and **kwargs goes, *args is for a list or tuple of arguments while **kwargs is for dictionary key and value pairs.

    You don't actually need to use *args and **kwargs. You just need to use the * or ** to denote what you're trying to do. *poop is just as valid as *args. Similarly, **poop is functionally equivalent to **kwargs. Point being, you can put any variable name you want after the asterisk(s).

    There's a lot more to dictionaries and how to pass them as arguments, as well as functions and methods, but they fall outside the scope of the initial question.

    EDIT:
    As for OP's question:
    achievement.register(name, **kwargs) gives your code a lot more flexibility and extensibility for the future. Say you want to record specific details about the achievement other than name. For instance, the date the achievement was earned, the IP address the user had when they earned the achievement, or anything else you can imagine. If you decide you want to add some other data about the achievement later on, using **kwargs allows you to add that item without changing your arguments everywhere you call achievement.register. You'd only need to add an extra key/value pair for the corresponding addition when passing it to your function.

    This post ended up being a lot longer than I'd intended. Hope that clarified some things.
     
    Last edited: Feb 14, 2019
  7. WinByDying

    WinByDying I can count to four

    Joined:
    Jul 18, 2017
    Messages:
    621
    Likes Received:
    538
    Reading List:
    Link
    Wait, am I blind or am I missing something? There's no hyperlink in my previous post. The only Link is the one to my non-public Reading List beneath my profile pic and name, but that's irrelevant.

    I actually said something incorrect before, though not in the Python explanation. Args and kwargs are not taken from C. I was thinking of argc/argv, but those are for a variable amount of command line arguments to main. There are a few similarities, but a lot of differences. There's no real equivalent to args kwargs in C/C++ for arbitrary functions, and you can only call a main once, at the very beginning.
     
  8. Otwentyfirst

    Otwentyfirst Well-Known Member

    Joined:
    Oct 21, 2017
    Messages:
    239
    Likes Received:
    227
    Reading List:
    Link
    here or anywhere else is just adding to the repository of answers. plus there's the hope that someone else's way of explaining will make more sense.