Python Forum
partial functions before knowing the values
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
partial functions before knowing the values
#1
Hello python experts!

I'm working on a function ("salary_or_name_builder" in the example) that routes my input parameters to multiple functions.
Ideally, (for decoupling purposes) that function lets another function decide the scenario and use that scenario to simply execute the function.
The issue is that my two functions salary_func & age_func take a different number of arguments.
I know I can modify salary_func so that it gets a third parameter that it doesn't use, but that sounds sloppy.
Does anyone have a tip to handle this "gracefully"?

from typing import Union


def salary_func(base_salary: int, yearly_bonus: int) -> None:
    print(f"you're expected to make {12*base_salary + yearly_bonus} / year")


def age_func(year:int, month:int, day:int) -> None:
    print(f"you were born on {day}-{month}-{year}")


def determine_scenario(param: Union[int, None]) -> str:
    if param is None:
        return salary_func
    else:
        return age_func


def salary_or_name_builder(param1: int, param2: int, param3: Union[int, None] = None) -> None:
    call = determine_scenario(param3)
    call(param1, param2, param3)


salary_or_name_builder(2000, 1, 1)  # works OK!
salary_or_name_builder(2800, 10000)  # salary_func() takes 2 positional arguments but 3 were given
My best effort so far was modifying my salary_or_name_builder with functools.partial like this

from functools import partial
...
def salary_or_name_builder(param1: int, param2: int, param3: Union[int, None] = None) -> None:
    call = determine_scenario(param3)
    if getattr(call, '__name__', repr(callable)) == "age_func":
        call = partial(call, day=param3)

    call(param1, param2)
But that kind of beats the purpose of the abstraction (since it needs to know all the possible inputs).
Is this the most graceful solution?
I was also thinking of using *args & **kwargs, but I find that syntax bad for readibility. I know what my functions need and I don't want to "mask" that Smile

Thanks for any suggestion!
Mikis
Reply
#2
Woops - Duplicate post
Reply
#3
(Dec-22-2023, 03:25 PM)mikisDeWitte Wrote: I was also thinking of using *args & **kwargs, but I find that syntax bad for readibility.
using *args and **kwargs is perfectly fine. Actually for me it's hard to see any benefit from this dispatch function salary_or_name_builder you try to create for some "abstraction".
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
#4
(Dec-22-2023, 05:46 PM)buran Wrote:
(Dec-22-2023, 03:25 PM)mikisDeWitte Wrote: I was also thinking of using *args & **kwargs, but I find that syntax bad for readibility.
using *args and **kwargs is perfectly fine. Actually for me it's hard to see any benefit from this dispatch function salary_or_name_builder you try to create for some "abstraction".

perhaps it's taste, but with args & kwargs the first 10 lines of each function would be to get the arguments from the args & kwargs.
I find it less readible because if I compare these two, I much prefer the first one
def func1(a: int, b:int, c:str) -> None:
    ...


def func2(*args, **kwargs) -> None:
    a: int = kwargs.get("a")
    b: int = kwargs.get("b")
    c: int = kwargs.get("c")
    ...
I do need to decide somewhere somehow which route my data needs to take. Is this dispatching function too far fetched?
My reason for building it is mostly to have a central place for logging the chosen scenario and also to extend the options in a flexible way.
Perhaps I'm just overthinking it after watching a lot of arjancodes design patterns on youtube Huh
Reply
#5
According to PEP 484 shouldn’t this be the intended way:

def spam(*args: int):
    # do_something
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Move Files based on partial Match mohamedsalih12 2 832 Sep-20-2023, 07:38 PM
Last Post: snippsat
  Partial KEY search in dict klatlap 6 1,287 Mar-28-2023, 07:24 AM
Last Post: buran
  remove partial duplicates from csv ledgreve 0 794 Dec-12-2022, 04:21 PM
Last Post: ledgreve
  Webhook, post_data, GPIO partial changes DigitalID 2 997 Nov-10-2022, 09:50 PM
Last Post: deanhystad
  Optimal way to search partial correspondence in a large dict genny92c 0 1,005 Apr-22-2022, 10:20 AM
Last Post: genny92c
  Partial Matching Rows In Pandas DataFrame Query eddywinch82 1 2,383 Jul-08-2021, 06:32 PM
Last Post: eddywinch82
  Partial key lookup in dictionary GaryNR 1 3,459 Jul-16-2020, 06:55 PM
Last Post: Gribouillis
  find file not knowing the extension Leon79 6 3,119 Jul-07-2020, 04:44 PM
Last Post: Leon79
  Partial using Tkinter function chesschaser 10 6,824 Jul-03-2020, 03:57 PM
Last Post: chesschaser
  Partial Word Search Kristenl2784 2 2,132 Jun-29-2020, 08:26 PM
Last Post: Kristenl2784

Forum Jump:

User Panel Messages

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