5
\$\begingroup\$

I am currently working on a Discord bot as a way to learn and practice Python. I have been trying to learn object-oriented programming, and apply the "don't repeat yourself" principle.

The code below connects/disconnects from a local database (using XAMPP) with the "mysql.connector" package, and registers a user in the database using their Discord ID. In my example below, I define a class called MySQL, and define three methods (connect(), disconnect() and query_users()) that I found myself using in almost every command/method.

In my register command/method, I call all three methods (connect(), disconnect() and query_users()). Is this the correct way to access those methods and their variables in my register command? My code works great, but the more I read on OOP, the less confident I become, and the more I question myself. Any tips or confirmation would be greatly appreciated.

Thank you all for your help.

"""The following packages/modules are required:""" import json import mysql.connector from discord.ext import commands as viking with open('config/database.json') as config: database = json.load(config) class MySQL: def __init__(self, viking): self.viking = viking def connect(self): self.connection = mysql.connector.connect(**database) self.cursor = self.connection.cursor(buffered=True) def disconnect(self): self.cursor.close() self.connection.close() def query_users(self): self.cursor.execute("SELECT discord_id FROM users") self.existing_users = ', '.join([str(users[0]) for users in self.cursor]) @viking.command(pass_context=True) async def register(self, ctx): """*register Viking will register your Discord ID in the Viking database.""" self.connect() self.query_users() discord_id = str(ctx.message.author.id) if discord_id in self.existing_users: await self.viking.say('You are already a registered member in the Viking database.') else: self.cursor.execute("INSERT INTO users (discord_id) VALUES (%s)", (discord_id,)) self.connection.commit() await self.viking.say('You are now registered in the Viking database.') self.disconnect() 
\$\endgroup\$

    1 Answer 1

    2
    \$\begingroup\$

    Is this the correct way to access those methods and their variables in my register command?

    Yes. Looks good to me.

    I can't say I'm fond of your docstrings. But your code is perfectly clear.

    You are focused on MySQL / MariaDB. I tend to access mysql through sqlalchemy, just in case in future I'll want to use sqlite or postgresql or another.

    The code starting if discord_id in ... is a bit odd, perhaps it could go into a function? It is a usual expectation that calling code could import your module (define your class) more than once without odd side effects.

    \$\endgroup\$
    5
    • \$\begingroup\$Hi J H. Thank you for your time and feedback. In regards to the docstrings, what would be the best approach? As for creating a function, I'm currently looking into it. My problem is that I rely on a user entering a command on Discord, so, in order to get their Discord ID, I need to use the ctx parameter. I do use if discord_id in self.existing_users: a couple times elsewhere in my project, but to accomplish different tasks.\$\endgroup\$CommentedAug 26, 2017 at 2:58
    • \$\begingroup\$Hi, Brayden. I'm going to take them as two separate items. (1) docstrings: I see a module level docstring that should probably just be a comment as it seems to offer pretty local advice for the next few lines, rather than describe the whole module: # The following packages/modules are required. And in register(), I can see your heart was in the right place, but honestly, it's not super helpful to some poor soul wondering how best to call register(). I'm no expert, so I'm afraid I can't offer expert advice on what callers need to know. I'm just saying I didn't find it very illuminating.\$\endgroup\$
      – J_H
      CommentedAug 26, 2017 at 4:17
    • \$\begingroup\$(2) I'm looking at if discord_id in self.existing_users:. I think there was maybe a formatting detail that you recently tidied up. When I was originally looking at it, I think my criticism was that if discord_id in self.existing_users: and the rest of it was at indent level zero. I am generally opposed to having such code run at import time -- I'd much rather see it protected by a clause like if __name__ == '__main__':. But I think I see you have indented it four spaces in a recent edit, so it looks good to me at this point.\$\endgroup\$
      – J_H
      CommentedAug 26, 2017 at 4:23
    • \$\begingroup\$You're totally right. I've been getting too comfortable, and writing poor docstrings and documentation. I plan on taking a closer look at the PEP8 style guide when I'm happy with the functionality. I'll certainly work on that. My apologies. I made a small formatting error during my initial post. It was supposed to be indented. Anyways, thank you for your help and wisdom. I appreciate it a lot.\$\endgroup\$CommentedAug 26, 2017 at 4:44
    • \$\begingroup\$Cool! Glad I could be helpful.\$\endgroup\$
      – J_H
      CommentedAug 26, 2017 at 4:58

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.