Python Forum
'namespace' shorthand for function arguments?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
'namespace' shorthand for function arguments?
#1
(using 3.9)
I tried to search for this subject but couldn't find the right wording (typical problem).
I have a function I am passing an object with attributes ('hand'). Hand has four attributes and I end up with dozens of references to those attributes by hand.this and hand.that.
What seems 'pythonic' would be a way to 'namespace' the argument for lack of a better word so I can just use 'this' and 'that'. For now I copied the four arguments into local variables, did all my work with those, then copied them back to the argument object. Here is my code with my klunky fix:
def updatevalue(hand):
    cards=hand.cards
    aceslow=hand.aceslow
    aceshigh=hand.aceshigh
    value=sum(cards)+(aceshigh*10) #for every aceshigh add 10
    while (value > 21) and (aceshigh > 0):  #lower aces until hand is <= 21 or no more aces
        aceshigh -= 1
        value -= 10
        aceslow += 1
        print(f'Current hand: {value}, aces high: {aceshigh}, aces low: {aceslow}')
    while aceshigh !=0 and value < 21:   #optional downgrades of remaining aces
        reply=input('Downgrade a remaining Ace?')
        if reply not in ('y','Y','n','N'):
            reply = 'y'
            print('Hunh? Try again, y or n.')
            continue
        elif reply.capitalize() =='Y':
            aceshigh -= 1
            value -= 10
            aceslow += 1
            continue
        else:
            break
    print('---------------------------------')
    print(f'Final hand: {value}, aces high: {aceshigh}, aces low: {aceslow}')
    hand.value = value
    hand.cards = cards
    hand.aceslow = aceslow
    hand.aceshigh = aceshigh
    return value
Reply
#2
What, exactly, is wrong with having to write hand.value, for example?

It's a shame that you mutate hand instead of creating a new one, though (immutability is a really good idea - look up Rich Hickey's talk titled "The Value of Values" for a good explanation).
Reply
#3
Usually it is not a problem to use a qualified name such as hand.aceshigh instead of just aceshigh and the trick used in your function indicates that the function should probably be rewritten some other way, for example by cutting it in smaller functions. For example you could do this
def user_approves(msg):
    while True:
        reply = input(msg).lower()
        if reply in ('y', 'n'):
            return reply == 'y'
        else:
            print('Hunh? Try again, y or n')

def updatevalue(hand):
    value = sum(hand.cards) + hand.aceshigh * 10
    while (
        (hand.aceshigh > 0) and
        ((value > 21) or user_approves('Downgrade a remaining Ace?'))):
        hand.aceshigh -= 1
        hand.aceslow += 1
        value -= 10
    print('---------------------------------')
    print(f'Final hand: {value}, aces high: '
          f'{hand.aceshigh}, aces low: {hand.aceslow}')
    return value
Notice that this code is shorter and better because we separated the interaction with the user from the main loop. More progress can be made because usually functions that don't print anything are more useful and reusable than functions that print something, but for this program it may be sufficient.

Just a comment about ndc85430's answer: note that Rich Hickey is the inventor of the Clojure language, a functional programming language related to Lisp. Functional programmers often convey a whole ideology of how programming really should be in the best of the worlds, but I don't think it is a good idea to suscribe blindly to these advices, especially if you are a procedural language's programmer. Immutability has many advantages but mutability has many advantages too. We all use mutable instances every day, so don't remake the world when you are just writing a game of cards!
Reply
#4
I understand the concern. By using lots of attributes in an object that was passed in as an argument your updatevalue method becomes strongly tied to the design of the cards class. This is not good for long term maintenance and it limits the usefulness of the function.

I don't think your problem is with using attributes of a class. I think updatevalue is poorly designed. A key tenet of software design is that each function has a well defined purpose. What is the purpose of updatevalue? Can you describe it in one or two short sentences?
Reply
#5
In addition, updatevalue may well be a method of hand class
Gribouillis likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
(Aug-10-2021, 08:18 PM)deanhystad Wrote: I understand the concern. By using lots of attributes in an object that was passed in as an argument your updatevalue method becomes strongly tied to the design of the cards class. This is not good for long term maintenance and it limits the usefulness of the function.

I don't think your problem is with using attributes of a class. I think updatevalue is poorly designed. A key tenet of software design is that each function has a well defined purpose. What is the purpose of updatevalue? Can you describe it in one or two short sentences?

The decision tree for blackjack isn't very uniform and I realized at one point I needed a final value for a hand that could not be resolved based on the cards alone, but also required the user to make choices (in this case about downgrading Aces) and work later routines based on the final value alone.

I'm not a very good strategic thinker so doing a lot of up front planning for something even as simple as blackjack is an exercise in constantly learning where to draw the lines between what does where, AFTER I start programming.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  calling external function with arguments Wimpy_Wellington 7 1,453 Jul-05-2023, 06:33 PM
Last Post: deanhystad
  If with For statement shorthand? kaega2 5 1,108 Sep-06-2022, 08:12 PM
Last Post: Gribouillis
  Checking the number of arguments a function takes Chirumer 3 2,166 Jul-06-2021, 04:56 PM
Last Post: Chirumer
  Possible to dynamically pass arguments to a function? grimm1111 2 2,201 Feb-21-2021, 05:57 AM
Last Post: deanhystad
  [PyKML] Loop through all Placemarks; Remove namespace Winfried 2 3,448 Aug-28-2020, 09:24 AM
Last Post: Winfried
  How to pass multiple arguments into function Mekala 4 2,465 Jul-11-2020, 07:03 AM
Last Post: Mekala
  How to give a name to function arguments in C-API? WonszZeczny 0 1,351 Jun-22-2020, 10:20 AM
Last Post: WonszZeczny
  cant understand the logic behind shorthand form of operator pradeep_sn 2 1,759 May-20-2020, 06:53 PM
Last Post: buran
  Function Recognises Variable Without Arguments Or Global Variable Calling. OJGeorge4 1 2,254 Apr-06-2020, 09:14 AM
Last Post: bowlofred
  Pass Arguments to Function phillyfa 2 2,031 Mar-27-2020, 12:05 PM
Last Post: phillyfa

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020