1
\$\begingroup\$

I am using a library that specifically needs me to provide arguments as strings one by one. However, different combinations are possible. Right now I am using a bunch of elif:

def get_all_users(times=False, groups=False, ips=False):
    """Get a list of all users online"""
    if times and groups and ips:
        return ts3conn.exec_("clientlist", "times", "groups", "ips")
    elif times and groups:
        return ts3conn.exec_("clientlist", "times", "groups")
    elif times and ips:
        return ts3conn.exec_("clientlist", "times", "ips")
    elif groups and ips:
        return ts3conn.exec_("clientlist", "groups", "ips")
    elif times:
        return ts3conn.exec_("clientlist", "times")
    elif groups:
        return ts3conn.exec_("clientlist", "groups")
    elif ips:
        return ts3conn.exec_("clientlist", "ip")
    else:
        return ts3conn.exec_("clientlist")

But I am wondering if this could be improved.

NOTE: I tried if I could use tuples but it won't work:

stuff = (times, groups, ips)
return ts3conn.exec_("clientlist", stuff)
>>> TypeError: can only concatenate str (not "tuple") to str

Update:
Library is at: https://github.com/benediktschmitt/py-ts3/blob/v2/ts3/query_builder.py

The code raises error on function compile:

for option in options:
    res += " -" + option
\$\endgroup\$
3
  • \$\begingroup\$ To be clear, could you point us to the documentation for the ts3conn object, whatever it is? \$\endgroup\$ Apr 29 '19 at 0:56
  • \$\begingroup\$ See the updated code for documentation. ts3conn is a ts3.query.TS3ServerConnection object. \$\endgroup\$
    – Saelyth
    Apr 29 '19 at 0:59
  • 1
    \$\begingroup\$ You want ts3conn.exec_('clientlist', *stuff) (tuple splatting). But this is off topic for CR, as this isn't about improving working code. Rather, your attempt to use tuples yields an error, which is a question that is on topic for StackOverflow. \$\endgroup\$ Apr 29 '19 at 3:31
2
\$\begingroup\$

You could use itertools.compress in combination with the tuple

def get_all_users(times=False, groups=False, ips=False):
    """Get a list of all users online"""
    arguments = ("clientlist", "times", "groups", "ips")
    selectors = (True, times, groups, ips)

    return ts3conn.exec_(*itertools.compress(arguments , selectors))

or in python 3.6+, using the retained insertion order of dicts (earlier versions can use an collections.ordereddict

def get_all_users(times=False, groups=False, ips=False):
    """Get a list of all users online"""
    arguments = {
        "clientlist": True,
        "times": times,
        "groups" : groups, 
        "ips": ips,
    }
    return ts3conn.exec_(*(key for key, value in arguments.items() if value))
\$\endgroup\$
3
  • \$\begingroup\$ is there any reason to use orderdeddict post-3.7? \$\endgroup\$
    – Alec
    Apr 29 '19 at 14:56
  • \$\begingroup\$ the important part is the ordering of the dict. In Cpython, this is guarantued from python 3.7:Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.. This might not be the case for PyPy or CPython 4.0 \$\endgroup\$ Apr 29 '19 at 14:58
  • \$\begingroup\$ at least current versions of pypy have iteration order=insertion order, and unless someone finds a faster type of dict, pypy won't change. \$\endgroup\$ Apr 29 '19 at 17:45
1
\$\begingroup\$

In Order to unpack a tuple you can use the * operator, then you just need to generate a tuple of selected options and expand it:

def get_all_users(times=False, groups=False, ips=False):
    """Get a list of all users online"""

    argument_list = ['clientlist']
    if times: 
        argument_list.append('times')
    if groups: 
        argument_list.append('groups')
    if ips: 
        argument_list.append('ips')
    arguments = tuple(argument_list)

    return ts3conn.exec_(*arguments)

From your question I guess you already have the tuple of arguments, this would make the entire process considerably easier.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ You don't actually need to convert to a tuple; lists are unpackable in the same way. i.e. return ts3conn.exec_(*argument_list) would work too. \$\endgroup\$ Apr 29 '19 at 10:34
  • \$\begingroup\$ @HoboProber I am aware of that however I thoght I convert the list to a tuple as this is more in line with what OP asked, but good remark. \$\endgroup\$
    – Lucas
    Apr 29 '19 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.