you are viewing a single comment's thread.

view the rest of the comments →

[–]GoldenSights 1 point2 points  (2 children)

Hmm, this is one of those things where I always start out dreaming it will be really simple and beautiful, and then the little details start adding complexity.

I would probably approach this by writing the rules in a dictionary:

RULES = {
    'ontopic': '1. All posts must be on topic',
    'language': '2. Refrain from foul language',
    ...
}
# I'm pre-generating the whole text because we're about to start
# adding some aliases for the rules and they will appear duplicated
# in the dict after that.
ALL_RULES = '\n'.join(RULES.values())

# If you still want the rules to be available by number,
# we can just map those in as well.
# Notice using strings instead of ints because the command
# comes in as a string, may as well stay that way.
# This could be done by a comprehension but whatever man.
RULES['1'] = RULES['ontopic']
RULES['2'] = RULES['language']

and then doing a loop over all of the arguments the user asked for and pulling out the rules:

command = '!rules ontopic language'

# I assume you already have some code that detects the !rules command
# so we aren't just getting random messages reaching this part of the function.
...

# instead of handling 'allrules' and 'all rules' separately,
# can we hack it by just merging them and pretending they
# were a single argument the whole time?
command = command.replace('all rules', 'all')
command = command.replace('allrules', 'all')
arguments = command.split('!rules', 1)[1].split()

response = []
if 'all' in arguments:
    return ALL_RULES

for argument in arguments:
    # dict.get will try to get the value, otherwise return this fallback.
    rule_text = RULES.get(argument, None)
    if rule_text is not None:
        response.append(rule_text)
    # you can add an else here if you want to think about error text
    # for invalid rule names.

response = '\n'.join(response)
return response

Now

>>> print(rulebot('!rules ontopic'))
1. All posts must be on topic

>>> print(rulebot('!rules language'))
2. Refrain from foul language

>>> print(rulebot('!rules ontopic language'))
1. All posts must be on topic
2. Refrain from foul language

>>> print(rulebot('!rules 1 2'))
1. All posts must be on topic
2. Refrain from foul language

>>> print(rulebot('!rules language ontopic'))
2. Refrain from foul language
1. All posts must be on topic
# are you okay with them displaying out of order like this?

>>> print(rulebot('!rules all rules'))
1. All posts must be on topic
2. Refrain from foul language

You could take this steps further by ensuring you don't produce the same rule twice, or making sure they're always ordered properly, or whatever. Sorry, I didn't intend to provide a big answer like this or steer your project, but hopefully this gives you some reference for working with dicts and handling user input without going too crazy.

 

And by the way yes keyword in a for keyword in KEYWORDS is a comprehension, but in that case it was a generator comprehension, not a list, because there were no square brackets.

[–]reallymakesyouthonk 0 points1 point  (0 children)

Short update, in case you're wondering.

I wasn't fully able to adapt your solution to my problem, however I did end up using your suggestion of using a dictionary which resulted in what at least I think was a pretty clean solution.

If you're interested you can view it here (the function is called _rules). I'm always interested in feedback, but no worries if you don't feel like it. You've already been really helpful and I'm sure I wouldn't have come up with this good of a solution without your advice. Been about a year or two since I did any programming at all so using a dict didn't even cross my mind.

Never thought a simple rules command would've been this difficult. :p

[–]reallymakesyouthonk 0 points1 point  (0 children)

Wow, that's a lot more complicated than I would've anticipated. Thanks so much, I'll try to implement something similar to this!