Code:
# Random Choice
#client.command(aliases=["rand_c"])
async def random_choice(ctx, python_list):
await ctx.send(random.choice(python_list))
Weird error when I type a proper Python list (["Cats", "Dogs", "No pet"]):
discord.ext.commands.errors.UnexpectedQuoteError: Unexpected quote mark, '"', in non-quoted string
It works fine in regular Python, but why not in discord.py?
All of the inputs to your commands are initially treated as strings. You need to provide a converter function to tell the command what to do with that string:
from ast import literal_eval
#client.command(aliases=["rand_c"])
async def random_choice(ctx, *, python_list: literal_eval):
await ctx.send(str(python_list))
Related
I am trying to execute the command abs.__ doc__ inside the exec() function but for some reason it does not work.
function = input("Please enter the name of a function: ")
proper_string = str(function) + "." + "__doc__"
exec(proper_string)
Essentially, I am going through a series of exercises and one of them asks to provide a short description of the entered function using the __ doc__ attribute. I am trying with abs.__ doc__ but my command line comes empty. When I run python in the command line and type in abs.__ doc__ without anything else it works, but for some reason when I try to input it as a string into the exec() command I can't get any output. Any help would be greatly appreciated. (I have deliberately added spaces in this description concerning the attribute I am trying to use because I get bold type without any of the underscores showing.)
As a note, I do not think I have imported any libraries that could interfere, but these are the libraries that I have imported so far:
import sys
import datetime
from math import pi
My Python version is Python 3.10.4. My operating system is Windows 10.
abs.__doc__ is a string. You should use eval instead of exec to get the string.
Example:
function = input("Please enter the name of a function: ")
proper_string = str(function) + "." + "__doc__"
doc = eval(proper_string)
You can access it using globals():
def func():
"""Func"""
pass
mine = input("Please enter the name of a function: ")
print(globals()[mine].__doc__)
globals() return a dictionary that keeps track of all the module-level definitions. globals()[mine] is just trying to lookup for the name stored in mine; which is a function object if you assign mine to "func".
As for abs and int -- since these are builtins -- you can look it up directly using getattr(abs, "__doc__") or a more explicit: getattr(__builtins__, "abs").__doc__.
There are different ways to lookup for a python object corresponding to a given string; it's better not to use exec and eval unless really needed.
I have tried reading the docs, but I don't understand what is going on here and how to fix it. I am trying to map a mention to its proper Name#NNNN form, but alas, it is proving to be a fruitless endeavor for me.
import discord
from discord.ext import commands
from collections import defaultdict
client = commands.Bot(command_prefix=">")
#client.event
async def on_ready():
print('Ready!')
jobz = {}
'''PART 1 v v v'''
#client.event
if message.content.startswith('>jobsched'):
author = message.author
jobz[author].append(...)
await channel.send(jobz[author])
'''PART 2 v v v'''
if message.content.startswith('>when '):
channel = message.channel
worker = list(filter(None, message.content[6:].split(' ')))[0]
uname = message.mentions[0].mention
await channel.send(jobz[uname])
PART 1:
I run this first, the send works as expected as seen below:
>jobsched 'a'
>jobsched 'b'
As seen in the last line, this spits out ['1a', '2b']
PART 2:
Here is where I have my issue.
>when #Name
I expected this to spit out ['1a', '2b'] because I expected it to look up or translate the mentioned name, find its respective name and discriminator. I thought this should happen since, in the above piece, that is how the name gets written into the dictionary is i.e. Name#1234: ['1a','2b']
Printing out .keys() shows that the key has the name and discriminator i.e. Name#1234 in the 'jobz' dictionary.
However, I can't seem to get the mention to give me the Name and Discriminator. I have tried doing mentions[0].mention from what I have seen here on stackoverflow, but it doesn't result in a Member class for me, just a string, presumably just '#Name'. If I leave it alone, as shown in my 'worker' variable, it passes an empty list. It should pull the list because when I override it to jobz['Name#1234'] it gives me the list I expect.
Can anyone please help?
just cast the member object to string to get the name and discriminator as it says in the discord.py docs. To mention someone, put the internal representation like this: f'<#{member.id}>'. To stop problems like this, use client.command() it's way easier to put in parameters, and easier to access info. So, here would be the code:
#client.command()
async def when(ctx, member: discord.Member):
await ctx.send(jobz[str(member)])
Also, if your worker variable is returning None, you're not passing a parameter at all
mentions is a list of Member objects, so when you do mentions[0] you are referencing a Member. Thus, mentions[0].mention is the formatted mention string for the first-mentioned (element 0) Member.
You probably want mentions[0].name and mentions[0].discriminator
See: https://discordpy.readthedocs.io/en/latest/api.html#discord.Message.mentions
The trouble I'm having here is that the isalpha() function isn't doing what it's supposed to do, users are able to send messages that contain characters that are not alphabetical. I'm not sure why this occurs. I assumed that it was some kind of hosting issue (which from the looks of it wasn't) prior to assuming that there was a logical error in my code, but logically it makes sense to me which perhaps is wrong? I kinda also made the assumption that it had to do with the function not being asynchronous, I don't know I probably am reaching with that one.
import discord
from discord.ext import commands
import re
class Shiritori(commands.Cog):
""" Start a new word from the last letter of the one before. """
def __init__(self, client):
self.client = client
self.repeats = re.compile(r'(.)\1{2,}') # Matches spam like 'eeeeeee'
self.shiritori_channel = 578788555120312330 # Official
#commands.Cog.listener()
async def on_message(self, message):
try:
if message.channel.id == self.shiritori_channel:
previous_message = (await message.channel.history(limit=2).flatten())[1].content
repeats_mo = self.repeats.search(message.content)
if not repeats_mo and message.content.isalpha():
if previous_message[-1].lower() != message.content[0].lower():
await message.author.send(
f'Your message must start with the last letter of the latest message!')
await message.delete()
else:
await message.author.send("You can't do that here!")
await message.delete()
except discord.Forbidden:
await message.delete()
I guess you are expecting that any non-ascii English character is not alpha.
But
According to the doc,
str.isalpha() Return True if all characters in the string are
alphabetic and there is at least one character, False otherwise.
Alphabetic characters are those characters defined in the Unicode
character database as “Letter”, i.e., those with general category
property being one of “Lm”, “Lt”, “Lu”, “Ll”, or “Lo”. Note that this
is different from the “Alphabetic” property defined in the Unicode
Standard.
So for example à (french a) or любовь are also considered alpha
'à'.isalpha()
True
'любовь'.isalpha()
True
If you want the english letters, use isascii():
'à'.isascii()
False
I tried to use re.findall to look for some string to parse to information I want to pattern from a large html file. the information I need is 0000-01-02-03-04-asdasdad that sit in the string like https://xxx/yyy/0000-01-02-03-04-asdasdad/index.css
How can I do it?
def func(html: str):
import re
pattern = r'\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\w+'
s = fr'https://xxx/yyy/{pattern}/index.css'
return re.findall(s, html)
# error: TypeError: cannot use a string pattern on a bytes-like object
I have the following functions defined using Python type-hinting:
from typing import BinaryIO
def do_something(filename: str):
my_file = open(filename, "rb")
read_data(my_file)
def read_data(some_binary_readable_thing: BinaryIO):
pass
However my IDE (PyCharm 2017.2) gives me the following warning on the line I invoke read_file:
Expected type 'BinaryIO', got 'FileIO[bytes]' instead
What is the correct type for me to use here? PEP484 defines the BinaryIO as "a simple subtype of IO[bytes]". Does FileIO not conform to IO?
This looks like a bug in either Pycharm or typing module. From the typing.py module:
class BinaryIO(IO[bytes]):
"""Typed version of the return of open() in binary mode."""
...
Also the documentation specifies:
These represent the types of I/O streams such as returned by open().
So it should work as stated. For now, a workaround would be to explicitly use FileIO.
from io import FileIO
def do_something(filename: str):
my_file = open(filename, "rb")
read_data(my_file)
def read_data(some_binary_readable_thing: FileIO[bytes]):
pass