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\$ Commented Apr 29, 2019 at 0:56
  • \$\begingroup\$ See the updated code for documentation. ts3conn is a ts3.query.TS3ServerConnection object. \$\endgroup\$ Commented Apr 29, 2019 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\$ Commented Apr 29, 2019 at 3:31

2 Answers 2

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\$ Commented Apr 29, 2019 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\$ Commented Apr 29, 2019 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\$ Commented Apr 29, 2019 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\$ Commented Apr 29, 2019 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\$ Commented Apr 29, 2019 at 10:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.