3
\$\begingroup\$

This is a Python discord.py bot I am working on. It shows the prices, 24-hour volume, 1h percent change, 24h percent change, 7d percent change and much more of the cryptos. I'm still working on adding the same stuff as I have for Ethereum as I do for the other cryptos, but it's a work in progress.

If you have any questions, issues, or feedback with the bot, do let me know!

import random
import asyncio
import requests
from discord import Game
from discord.ext.commands import Bot
import aiohttp
BOT_PREFIX = ("?", "!")
TOKEN = "insert your token here"

client = Bot(command_prefix=BOT_PREFIX)



@client.command(pass_context=True)
async def bitcoin(ctx):
    url = 'https://api.coindesk.com/v1/bpi/currentprice/BTC.json'
    response = requests.get(url)
    value = response.json()['bpi']['USD']['rate']
    await client.send_message(ctx.message.channel, "Bitcoin price is: $" + value)
@client.command()
async def eth():
    url = 'https://api.coinmarketcap.com/v1/ticker/ethereum/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    rank = response.json()[0]["rank"]
    supply = response.json()[0]["total_supply"]
    change1 = response.json()[0]["percent_change_1h"]
    change24 = response.json()[0]["percent_change_24h"]
    change72 = response.json()[0]["percent_change_7d"]
    vol24 = response.json()[0]["24h_volume_usd"]
    sym = response.json()[0]["symbol"]
    await client.say("Ethereum price is: $" + value)
    await client.say("Ethereums rank is: " + rank)
    await client.say("Ethereums total supply is: " + supply)
    await client.say("Ethereums percent change in the past hour is: " +change1)
    await client.say("Ethereums percent change in the past 24 hours is:" + change24)
    await client.say("Ethereums percent change in the past 7 days is: " + change72)
    await client.say("Ethereums 24 hour volume is: " + vol24)
    await client.say("Ethereums symbol is: " + sym)
@client.command()
async def ripple():
    url = 'https://api.coinmarketcap.com/v1/ticker/ripple/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    rank = response.json()[0]["rank"]
    supply = response.json()[0]["total_supply"]
    change1 = response.json()[0]["percent_change_1h"]
    change24 = response.json()[0]["percent_change_24h"]
    change72 = response.json()[0]["percent_change_7d"]
    vol24 = response.json()[0]["24h_volume_usd"]
    sym = response.json()[0]["symbol"]
    await client.say("Ripples price is: $" + value)
    await client.say("Ripples rank is: " + rank)
    await client.say("Ripples total supply is: " + supply)
    await client.say("Ripples percent change in the past hour is: " +change1)
    await client.say("Ripples percent change in the past 24 hours is:" + change24)
    await client.say("Ripples percent change in the past 7 days is:" + change72)
    await client.say("Ripples 24 hour volume is:" + vol24)
    await client.say("Ripples symbol is: " + sym)
@client.command()
async def litecoin():
    url = 'https://api.coinmarketcap.com/v1/ticker/litecoin/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("Litecoin price is: $" + value)
@client.command()
async def neo():
    url = 'https://api.coinmarketcap.com/v1/ticker/neo/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("NEO price is: $" + value)
@client.command()
async def eos():
    url = 'https://api.coinmarketcap.com/v1/ticker/eos/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("EOS price is: $" + value)
@client.command()
async def dash():
    url = 'https://api.coinmarketcap.com/v1/ticker/dash/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("DASH price is: $" + value)
@client.command()
async def zcash():
    url = 'https://api.coinmarketcap.com/v1/ticker/zcash/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("Zcash price is: $" + value)
@client.command()
async def metal():
    url = 'https://api.coinmarketcap.com/v1/ticker/metal/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("METAL coin price is: $" + value)
@client.command()
async def trump():
    url = 'https://api.coinmarketcap.com/v1/ticker/trumpcoin/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("Trump Coin price is: $" + value)
@client.command()
async def gas():
    url = 'https://api.coinmarketcap.com/v1/ticker/gas/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("GAS coin price is: $" + value)
@client.command()
async def gts():
    url = 'https://api.coinmarketcap.com/v1/ticker/game/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("GTS coin price is: $" + value)
@client.command()
async def salus():
    url = 'https://api.coinmarketcap.com/v1/ticker/salus/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("Salus coin price is: $" + value)

##########################
















client.run(TOKEN)
\$\endgroup\$
4
\$\begingroup\$

You could certainly make it much more object oriented. Also, all of your functions in the beginning rely on a specific URL, you could either A) create a class that has no methods but the instance variables are the various URL's, or B) create another .py file that solely consists of your URL paths and import that file. If you go this route I'd recommend all capitals for the name of the variables to signify they're constants. You could name your other file URL and then inside of URL.py create a variable like eth_url and then inside this main py file you would import URL and then access it like this:

URL.eth_url

You've started to create functions for specific currencies (ethereum, ripple, etc.) You need to generalize your functions. Notice that the URL for the website you're pulling from follows a pattern, 'https://api.coinmarketcap.com/v1/ticker/ripple/'

Where the last part of the URL is the name of the coin. You could create a dictionary of coin names and their equivalent name on the website (for the most part they'd be 1:1 but there might be some common names that have a slightly different URL). Then once you've got this dictionary, change your functions from ripple or eth to:

@client.command()
async def get_coin_info(coin):
\$\endgroup\$
3
\$\begingroup\$

Try DRY:

One basic tenet of good software practice is Don't Repeat Yourself (aka: DRY). You have a very long run of functions which are all almost identical. They look like:

@client.command()
async def dash():
    url = 'https://api.coinmarketcap.com/v1/ticker/dash/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("DASH price is: $" + value)
@client.command()
async def zcash():
    url = 'https://api.coinmarketcap.com/v1/ticker/zcash/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("Zcash price is: $" + value)
@client.command()
async def metal():
    url = 'https://api.coinmarketcap.com/v1/ticker/metal/'
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("METAL coin price is: $" + value)

They could be refactored to look something like:

@client.command()
def dash():
    run_command('DASH', 'https://api.coinmarketcap.com/v1/ticker/dash/')


@client.command()
def zcash():
    run_command('Zcash', 'https://api.coinmarketcap.com/v1/ticker/zcash/')


@client.command()
async def metal():
    run_command('METAL', 'https://api.coinmarketcap.com/v1/ticker/salus/')


async def run_command(name, url):
    response = requests.get(url)
    value = response.json()[0]["price_usd"]
    await client.say("{} coin price is: ${}".format(name, value))

This has the advantage of making the differences, between the almost the same functions, much more explicit.

String formatting:

In addition, I think eth() and ripple() could be similarly consolidated through the use of format strings to look something like:

@client.command()
def ripple():
    url = 'https://api.coinmarketcap.com/v1/ticker/ripple/'
    messages = (
        "Ripples price is: ${price_usd}",
        "Ripples rank is: {rank}",
        "Ripples total supply is: {total_supply}",
        "Ripples percent change in the past hour is: {percent_change_1h}",
        "Ripples percent change in the past 24 hours is:{percent_change_24h}",
        "Ripples percent change in the past 7 days is:{percent_change_7d}",
        "Ripples 24 hour volume is:{24h_volume_usd}",
        "Ripples symbol is: {symbol}",
    )
    say_details(url, messages)

async def say_details(url, messages):
    response = requests.get(url).json()[0]
    for msg in messages:
        await client.say(msg.format(**response))

Pep8

You should consider formatting your code in accordance with pep8. This is important when sharing code, as the consistent style makes it much easier for other programmers to read your code. There are various tools available to assist in making the code pep8 compliant. I use the PyCharm IDE which will show pep8 violations right in the editor.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.