Я пишу бота Discord с помощью discord.py и пытаюсь реализовать систему для покупки акций на python 3.6, поскольку python3 .7 + имеет asyncio.run(func())
.
import discord
import asyncio
import os
import random
import time
import math
client = discord.Client()
# contains coin information including balance, stock price, number of stocks, etc
with open('coins.conf', 'r') as f:
for line in f.readlines():
exec(line)
def save_all():
with open('coins.conf', 'w') as f:
f.write('coins = '+repr(coins))
random.seed(os.urandom(32))
searchusers = []
bank_cooldown = {}
bans['global'] = False
@client.event
async def on_ready():
'''Notification on ready.'''
print('Logged in! Bot running.')
await client.change_presence(activity=discord.Game(name='/help'))
@client.event
async def on_member_join(user):
'''Direct message the rules on member join.'''
await user.create_dm()
await user.dm_channel.send(f'Hi **{user.name}**, welcome to the server! Be sure to read the rules to stay out of trouble. Have a great time!')
def getcoins(uid):
'''Get the amount of coins, if nonexistent set to 0.'''
try:
return coins[uid][0]
except Exception:
coins[uid] = [0, time.time()+1, time.time()+1, 0, 320, time.time()+600, 0]
return 0
def mention_to_uid(mention):
'''Extract the UID from a mention (exclude first two char and last char)'''
uid = mention[2:-1]
if uid[0] == '!':
uid = uid[1:]
return uid
def setcoins(uid, value):
'''Set the amount of coins someone has.'''
try:
coins[uid][0] = value
except Exception:
coins[uid] = [value, time.time()+1, time.time()+1, 0, 320, time.time()+600, 0]
@client.event
async def on_message(message):
'''Main bot code running on message.'''
#############################
# some initialization stuff #
#############################
if message.content.startswith('/'):
user = message.author.id
name = message.author.display_name
text = message.content[1:].strip()
command = text.split(' ')[0]
subcommand = text.split(' ')[1:]
######################
# other bot commands #
######################
if command == 'stocks':
if len(subcommand) < 2:
await message.channel.send('Missing arguments! `/stocks [buy | sell] <amount>` or `/stocks help [info | price]`')
elif subcommand[0] == 'help':
if subcommand[1] == 'info':
msg = 'Invest in bot stocks! Use `/stocks help price` to find the current price per share.'
msg += '\nEvery 7-15 minutes, the stock price will change. It will decrease or increase by a little bit.'
msg += '\nStocks will more than likely output profit, but it is very random.'
msg += '\nEvery share bought increases the price by 1 and every share sold decreases the price by 1.'
await message.channel.send(msg)
elif subcommand[1] in ('price', 'amount', 'cost'):
await message.channel.send(f"The current stock price is **{getcoins('stock')}**. Get them while you can!")
elif subcommand[0] == 'buy':
amount = int(subcommand[1])
if amount < 0:
await message.channel.send('lol dummy. Positive number dude.')
else:
cost = (amount * getcoins('stock')) + (amount**2 - amount)//2 # price including increases
if getcoins(user) < cost:
await message.channel.send(f"You don't have enough coins to buy that many shares! Try `/balance`.\n[Debug] {cost}")
else:
coins[user][6] += amount # coins[user][6] => number of stocks user has
setcoins(user, getcoins(user)-cost)
setcoins('stock', getcoins('stock')+amount)
await message.channel.send(f'You bought {amount} shares for {cost} coins.')
elif subcommand[0] == 'sell':
amount = int(subcommand[1])
if amount < 0:
await message.channel.send('lol dummy. Positive number dude.')
else:
sell = (amount * getcoins('stock')) - (amount**2 - amount)//2 # price including decreases
if coins[user][6] < amount:
await message.channel.send(f"You don't have enough shares!")
else:
coins[user][6] -= amount
setcoins(user, getcoins(user)+sell)
setcoins('stock', getcoins('stock')-amount)
await message.channel.send(f'You sold {amount} shares for {sell} coins.')
else:
await message.channel.send('Invalid arguments! `/stocks [buy | sell] <amount>` or `/stocks help [info | price]`')
######################
# other bot commands #
######################
##################################
# this stuff is the main problem #
##################################
async def main():
'''Bot code.'''
await client.start('Nj*********************************************************')
while True:
await asyncio.sleep(random.randint(420,900))
## I'm certain anything below this doesn't run ##
change = random.choice([ *1*[-50], *4*[-8], *5*[-7], *6*[-6], *7*[-5], *8*[-4], *9*[-3], *10*[-2], *10*[-1],
*10*[0], *10*[1], *10*[2], *10*[3], *9*[4], *8*[5], *7*[6], *6*[7], *5*[8], *4*[9], *3*[10], *2*[12], *1*[15]
])
setcoins('stock', getcoins('stock')+change)
if getcoins('stock') < 15:
setcoins('stock', 15)
setcoins('jackpot', getcoins('jackpot')+random.randint(10, 20))
asyncio.get_event_loop().run_until_complete(main())
Выполняется только половина функции.
Строка await client.start()
не должна быть блокирующим вызовом и в любом случае ожидается. Даже после ожидания 20 минут (максимум 15 минут) вторая часть строки l oop - change = random.choice
и все, что ниже, не запускается.
Я думаю, проблема в вызове client.start
блокирует, но из документации (https://discordpy.readthedocs.io/en/latest/api.html#discord .Client.start )
await start(*args, **kwargs)
Эта функция является сопрограммой. Сокращенная сопрограмма для login () + connect ().
Вызывает ошибку TypeError - был получен неожиданный аргумент ключевого слова. команда start - это сопрограмма.
Я попытался уменьшить время asyncio.sleep
до 10 секунд и даже полностью удалить его. Цена акций и сумма джекпота билетов, которые предполагается изменить, не меняются.