I Upgraded My Python Discord Bot (Week4)

Good Morning from my Robotics Lab! This is Shadow_8472 and today, the month of bot development continues. Be sure to catch the previous posts before reading this one. Let’s get started!

Iteration vs. Recursion

My first major milestone this week was coding a recursive dice tally function to replace the iterative one. Iteration and recursion are two approaches to solving the same types of problems.

The experience of iteration is the more native one to think in. Your program has a path to walk that loops back in on itself as needed. Its downside is that this path can grow beyond the comprehension of the programmer fairly quickly when using in loops within loops within loops if need be. From experience, I found myself guessing more often than not when I was finishing the iterative tally function, and even then I had to teach myself to indent debug text.

To get the idea of recursion, imagine having an army of clones. Each recursion clone has a tiny job, but half that job is working out what it’s supposed to do, and most of the time, that it’s subdividing the problem and summoning one or more clones to work on each one. Recursion has a higher learning curve, but it’s a lot simpler to maintain. I was able to identify and squash a bug involving my pip tally missing secondary pips within seconds to a minute as opposed to fixing the same bug in minutes to an hour and a lot print() statements.

Code Polishing

The more time I spend on this project, the more I discover or rediscover tidier ways to code. It’s not always a hundred lines crunched down into two or three, but it can still feel validating to get a whole chunk of debug code onto a single line I can easily comment out.

In terms of memorable condensations this week, I had two functions –cleanInput() and tokenizeInput() (the later of which underwent around an eighteen:three line reduction last week)– in my dice engine file used for turning raw input into a format my roller can understand. Upon closer inspection, they combined neatly. Later, I solved a bug introduced when adding support for counting dice sets against the total [subtraction] by re-arranging lines of code from tokenizeInput in before lines from cleanInput.

Another thing that’s been bothering me has been the inability to pass off the context from Discord messages to other functions. As far back as the first stint on this bot, I wanted a function so I wouldn’t have to repeat myself in-code when sending a copy of returned messages to the command line. I achieved this with a function that logs, then returns strings I pass it.

print(“Hello World!”)
await ctx.send(“Hello World!”)

becomes

await ctx.send(broadcast(“Hello World!”))

Furthermore, I also played around with the ‘or’ operator. As I began work on implementing more features, of a trio of lines used for grabbing a user’s server nickname – or baring one, a user’s global account name. The way Python works, I was able to use

(ctx.message.author.nick or ctx.message.author.name)

straight in my broadcast liner function.

My general philosophy for this project has been to come up with a creative approach instead of just patching problems as they pop up. The readability of code will go down sharply as efforts to limit the amount of guesswork patching are neglected. As it stands right now with the next section’s features unfinished, I’d say this should be something I can come back to in a few months and make sense of faster than recoding it from scratch.

The Pythonic Way

Change of plan: implementing a save system can wait. While researching save file systems, I happened across an article on askpython.com about so-called “pythonic coding” [1]. Conventions change over time. I’ve noticed this first hand over this project as my style has noticeably drifted as I’ve consulted resources from over the past decade. Looks like I’ll be going through my code again and bringing my code up to standard where I can.

My first task was converting to using fstrings (f-strings – I cannot find anyone saying for sure what the f stands for, but I will be thinking of it as “format” until someone corrects me) when putting variables into strings. It went pretty smoothly, though I did have to be careful about using single vs double quotes when dealing with string data, such as keys in a dictionary. I’m not going for total conversion. If a print statement contains just one string and one variable, I can separate them with a comma. Anything more, and it’s time for fstrings.

The enumerate() function for getting loop indexes was one I’ve read about before, but didn’t appreciate until now. Similar to fstrings, enumerate has its place – specifically anywhere I used pointer variables. Now that I look at my code, my most annoying use of pointers was in that ugly function I’ve already replaced. Nevertheless, I was able to combine a pointer and its supporting code into for-loop statements. Similarly, I employed range() in a while-loop being used for a similar indexing job.

The AskPython article also brought up naming conventions, but I’m putting a hard pass on that one for this project. Variable names are fragile, and only work if they’re all converted at once. I’m not up to that level of potential breakage right now.

Takeaway

Code takes a lot of work to maintain and ensure readability. Add a seemingly innocent feature or consolidate chunks of code that belonged together all along, and you’re liable for something breaking and going unnoticed. I’ve lost track of all the bugs I’ve squashed, but I try to commit it to Git whenever I have a stable version, documenting my progress since my last commit. I still haven’t looked into using its other features yet, but it’s good practice making improved quality commits, and I know that’s worth something, even if it doesn’t feel like it yet.

Final Question

Have you ever taken up [part of] a set of standards for projects, even mid-project?

I look forward hearing your answers on in the comments below or on my Discord server.

Work Cited

[1] pankaj, “Pythonic Way of Writing Code,” [Online]. Available: https://www.askpython.com/python/examples/pythonic-way-of-coding. [Accessed Sept. 19, 2022].

Leave a Reply