As stated in the title, how? I'm really struggling with understanding the documentation as there are no examples of anything. How do I define something like a VoiceState, Member, VoiceChannel, etc...
Running on tutorials is fine until you have to start consulting the documentation for something specific, at which point it becomes really frustrating when you have no idea how to define objects or use certain commands...
A lot of this will come from experience, so don't be discouraged if it takes a while to get the hang of! I know that the docs can be a bit daunting, but I'll try to help as best I can by giving a couple of examples.
When making a discord bot, usually you're going to be getting information based off of arguments and ctx (context).
First I'll start off with some general examples, and then I'll move onto how to use these when working with d.py.
Parameters and args
When you create functions in python, you can define parameter types:
def my_func(a: int):
return a + 5
What this does is assume that the args passed into my_func will be integers, and therefore behave as ints too:
my_func(1)
Will return, as you might expect, 6.
However, when you try to pass in something like so:
my_func("1")
You'll get a TypeError which complains about concatenating str and int. Additionally, you can see the differences in an object when you list its attributes like so: dir(obj)
When applying this same concept to a command:
#bot.command()
async def cmd(ctx, member: discord.Member):
await ctx.send(f"Hello, {member.mention}!")
But when using commands, what it does is it's able to get a member based off of an attribute you enter, such as the member's ID or name. The member that it finds, then has all of the discord.Member object's attributes.
This means you'll be able to access things such as the member's roles, which return a list containing each role as a discord.Role object, which from there, you can get the role's attributes, and so on and so forth.
SIDE-NOTE:
Another way of getting objects in d.py is by using discord.utils. It takes in an iterable, e.g. a list, as the first argument, and then after that it takes keyword arguments, such as name, id, colour, or any attributes of an abc to return an object.
Example:
#bot.command()
async def getrole(ctx):
role = discord.utils.get(ctx.author.roles, name="Very Special Role!", mentionable=True)
await ctx.send(f"Look at you with your {role.mention} How classy!")
And that will iterate through each of the message sender's roles, looking for the name (case sensitive) Very Special Role! which is mentionable, and it will send the message using one of the role's attributes; mention.
Context
With commands, the first argument you're going to be passing in is Context, which by convention is denoted as ctx.
As shown in the link, it has a range of attributes, which revolve mostly around the command's origin, author, and all other details about it etc.
#bot.command()
async def hello(ctx):
await ctx.send(f"Hello, {ctx.author.name}!")
In the command there, I'm using the coroutine from context called send(), which is used for sending messages.
And in the context of the command, it'll be sending it to the same channel, which is how that works.
Also, an example of some commonly used superfluous code:
ctx.message.channel.send("some message")
ctx.message.author.send("some dm")
can be respectively turned into:
ctx.send("some message")
ctx.author.send("some dm")
But how do you know where you can send() a message to? Well that brings us onto the next part:
Abstract Base Classes
These are, what I'm assuming you were talking about when you were on about defining objects. They are the base templates for objects to inherit from - for example, TextChannel has inherited all of Messageable's attributes (except connectable, which is only inherited by discord.VoiceChannel.channel.
I'll use abc.Messageable as an example. In the link, it gives us examples of some Messageable objects, i.e. where you can send messages to, and these are objects such as TextChannels, Members etc.
Occasionally I see someone miss out an await or not know when to add them, or add them too often. You'll know when to add one, as the docs will state whether the function is a couroutine or not, for example:
That's how you know what you can do with each object - think of these as templates for the objects you get within discord, not something that you define!
If you need any further clarification or if you noticed any mistakes with my answer, please let me know.
References:
commands.Command() - decorator for commands
commands.Context
Coroutines
discord.Member
Member.roles
discord.Role
Context.send()
discord.TextChannel
discord.utils
discord.abc
Related
I've built a class to ask a user a question, based on a type.
class Question:
def __init__(self, subject):
self.subject = subject
self.question = f"Enter the {subject} to be created. You may end this by typing 'DONE':\n"
self.still_needed = True
def ask_question(self):
ans_list = []
running = True
while running:
var = input(f"Enter {self.subject}?\n")
if var.lower() == 'done':
running = False
else:
ans_list.append(var)
return ans_list
The idea is to have a question model, to create lists of items.
This seems to work well with the following code in main.
roles = Question(subject="role").ask_question()
This creates a list from the Queue Class and uses it's method ask question to generate the list. As far as I can tell the object is then destroyed, as it's not saved to a variable.
My question, being new to Python and OOP is, does this seem like a solid and non-confusing way, or should I refractor? If so, what does the community suggest?
MY OPINION
I guess it depends on you. For one, one of the main purposes of using a class is to create an instance with it later on. Classes are objects ,or "categories" as I like to call them, that you use when there are distinctive types of instances in your project.
Given your code snippet, I can't really suggest anything, I don't know the usage of self.question and self.still_needed. However, if I were to base my opinion on just this part: roles = Question(subject="role").ask_question(), then I'd definitely go with using a function instead. As you've said,
As far as I can tell the object is then destroyed, as it's not saved
to a variable.
ALTERNATIVE SOLUTION
Use decorators → the one with # symbol
In this case, #staticmethod is the way to go!
What are staticmethods? The staticmethod decorator is a way to create a function in a class. So instead of it becoming a method, it can be treated as a function (without self parameter). This also means that a static method bounds to the class rather than its object. Consequently, static methods do not depend on objects (hence, you don't need to create an object for you to use it). Example:
class SomeMathStuff():
#staticmethod
def AddSomeNumbers(iterable):
return sum(iterable)
result = SomeMathStuff.AddSomeNumbers([1, 2, 3])
# result = 6
As you can see, I did not need to create an object, instead I just needed to call its class to use it. Word of warning, most Python programmers argue that this is the un-Pythonic way, but I wouldn't worry too much about it. Hell, even I use these methods sometimes. In my defense, this is a good and efficient way to organize your project. With this, you can apply class methods globally and you can "categorize" them in certain classes you find suitable.
Anyway, this is all I have! I apologize if I misinformed you in any way.
ADDITIONAL INFROMATION ... in case I wasn't the best teacher
https://www.programiz.com/python-programming/methods/built-in/staticmethod
Difference between staticmethod and classmethod
https://softwareengineering.stackexchange.com/questions/171296/staticmethod-vs-module-level-function
I read the doc, been there, done that. Still no clue how to write a decorator I need in a way that makes common sense.
In brief: Got an interceptor that executes before the validation layer. That simply means that invalid data can get in the interceptor and break the app. To avoid that I would like to use a decorator on some methods, and to be more accurate on parameters of such methods.
public async getUserById(#IsIntNumber() userId: number): Promise<UserEntity>
{
// method logic
}
Here #IsIntNumber() is a custom decorator that validates the userId parameter.
As a matter of fact I'd like to have a little library of mine in the application holding a bunch a that kinds of validation decorators that I could apply to different parameters.
Is there some legal method to do this without shedding too much blood and too many tears?
I know it's a difficult question.
In the docs they sort of say:
The #required decorator adds a metadata entry that marks the parameter
as required. The #validate decorator then wraps the existing greet
method in a function that validates the arguments before invoking the
original method.
Meaning I've got to pack all my validation logic into that validate function or what? Really?
Does it mean that we don't have adequate parameter decorators in TS? Cos if I understand this right, these ones are absolutely, totally unusable.
Is there any reason the Origen::Parameters sets do not have a public method for retrieving all of the possible set ids? I do see a public method that works, though it isn't named like it is meant to be used publicly. Why is this not more visible?
[6] pry(#<PPEKit::Product>)> $dut.func._parameter_sets.ids
=> [:default,
:func_default,
:func_harvest_default,
EDIT
#Ginty, I tried your suggestion but it doesn't return the keys I am looking for. In the first sentence in the Parameter docs, the keys I am looking for are referred to 'parameter contexts'. The reason these would be useful would be to do something like this:
my_param_key = :my_param_key
if Origen.top_level.func.has_context? my_param_key
...
Specifically, I am creating parameter contexts from the information in my flow file and would like to verify that they exist before trying to access them. Essentially it is a handshake between my test flow and the test method parameters I am storing using unique (hopefully) parameter IDs/contexts.
thx
In your example, dut.func.params should return a hash-like object which contains all the parameter sets, so to get the IDs is just: dut.func.params.keys
EDIT
I see now that you want a collection containing the available contexts, but it doesn't seem like that is currently provided via an API.
I don't think there is any particular reason for that, probably hasn't been needed until now.
params.context returns the currently active context, I would recommend we add params.contexts and/or params.available_contexts to return an array of the available context names.
Origen now supports knowing the available parameter contexts.
This question is with reference to the Cymbol code from the book (~ page 143) :
int t = ctx.type().start.getType(); // in DefPhase.enterFunctionDecl()
Symbol.Type type = CheckSymbols.getType(t);
What does each component return: "ctx.type()", "start", "getType()" ? The book does not contain any explanation about these names.
I can "kind of" understand that "ctx.type()" refers to the "type" rule, and "getType()" returns the number associated with it. But what exactly does the "start" do?
Also, to generalize this question: what is the mechanism to get the value/structure returned by a rule - especially in the context of usage in a listener?
I can see that for an ID, it is:
String name = ctx.ID().getText();
And as in above, for an enumeration of keywords it is via "start.getType()". Any other special kinds of access that I should be aware of?
Lets disassemble problem step by step. Obviously, ctx is instance of CymbolParser.FunctionDeclContext. On page 98-99 you can see how grammar and ParseTree are implemented (at least the feeling - for real implementation please see th .g4 file).
Take a look at the figure of AST on page 99 - you can see that node FunctionDeclContext has a several children, one labeled type. Intuitively you see that it somehow correspond with function return-type. This is the node you retrieve when calling CymbolParser.FunctionDeclContext::type. The return type is probably sth like TypeContext.
Note that methods without 'get' at the beginning are usually children-getters - e.g. you can access the block by calling CymbolParser.FunctionDeclContext::block.
So you got the type context of the method you got passed. You can call either begin or end on any context to get first of last Token defining the context. Simply start gets you "the first word". In this case, the first Token is of course the function return-type itsef, e.g. int.
And the last call - Token::getType returns integral representation of Token.
You can find more information at API reference webpages - Context, Token. But the best way of understanding the behavior is reading through the generated ANTLR classes such as <GrammarName>Parser etc. And to be complete, I attach a link to the book.
What is the indented lines directly below try: called/reffered to? I have heard "the body of try:" and "the expression of try:". Please clarify. (See user - poke´s - answer)
What is try:, except:, while: etc. reffered to? Like True and False are reffered to as "statements". (See user - poke´s - answer)
Is there any reason to change function1 into function2. The only difference between them is ValueError. The functions are only supposed to force the user to input an integer. (See user - poke´s - answer)
function1
def get_integer(LIMIT_PROMPT):
while True:
try:
return int(input(LIMIT_PROMPT))
except:
pass
I have seen lots of except statement: and in the body/expression there is a piece of code that does something if an error occured in the body/expression of try:
I have used this particular function in two programs and have not run into any trouble.
function2
def get_integer(LIMIT_PROMPT):
while True:
try:
return int(input(LIMIT_PROMPT))
except ValueError:
pass
Like True and False are referred to as "statements"
True and False are both variables referring to singleton values of the bool type. As variables, they are atomic expressions.
try, except, while etc. are statements, or more accurately, compound statements because they contain a group of other statements. Usually you would refer to that group of statements as a block, as in other languages they are encapsulated within block creating tokens (e.g. { and }). In the Python specification, they are being referred to as suite.
The suites of each compound statement does not really have a special name, so I guess you could just call them “try suite”, “except suite” etc., or “try block” and “except block”.
Is there any reason to change this function into this (the only change is ValueError)
Usually, when you check for exceptions, you should be as specific as possible. If you know that what you do within the try block can throw an exception of type X, then catch/except exception X only.
Not specifying a type will make the except catch any exception including those you might not know of that they could be thrown there, so you would lose useful information there. There are a lot questions on SO that already handle that topic, so I’ll just lead you to a random one I just found. Exception management is language agnostic, so you can just apply what you read to Python.