#development

1 messages · Page 757 of 1

sterile minnow
#

I'll ask my other devs for this Webhook stuff

sinful lotus
#

stop trying to help if you dont know what you are answerting

sterile minnow
#

In wbhooks i'm out

quartz kindle
#

Shards should be able to fetch channels from each other no?

late hill
#

Discord webhooks are incredibly easy to use

#

If you google

#

You'll find answers

sterile minnow
#

I'll try it

#

thx for helping me 😄

late hill
#

Depending on his sharding method, the channel might not be there

sinful lotus
#

they cant

late hill
#

It could also be that his code in there is executed before the ready event?

sinful lotus
#

unless you broadcastEval or make a custom function for it

late hill
#

Which would also cause that I guess

#

His code should be aware that it could be undefined

#

And handle that properly

sterile minnow
#

i'll try the Webhook thingy

quartz kindle
#

Can you do client.channels.fetch(id) tho?

#

Fetching a channel from the api should bypass shards

#

Or client.fetchChannel in stable or whatever

sterile minnow
#

Without the shards i've the same error

#

nah f*ck it i'll use webhooks

earnest phoenix
quartz kindle
#

Literally what it says?

sinful lotus
#

if you want extra memory

#

you can

#

just fetch it

summer torrent
#

Disable "Requires Oauth2 code grant" @earnest phoenix

earnest phoenix
#

Its disabled alr @summer torrent

sterile minnow
#

@earnest phoenix the URL to redirect is invalid

earnest phoenix
#

@summer torrent that is not what the issue is

#

weird

warm marsh
#

Would using a listener for commands be bad?

#

Something like

// IN loader:
<MyClass>.on("ping", function(message, args)
{
  message.channel.send("Pong!");
});

// IN message listener:
<MyClass>.emit("ping", message, args);
quartz kindle
#

Not bad just possibly needless overhead

#

I've done something similar

warm marsh
#

Alright, So what would be the absolute best way of doing commands?

summer torrent
#

use the command handler

warm marsh
#

Very vague.

#

A command handler could be a magnitude of different things.

sudden geyser
#

aka make a list of commands e.g. files and load them all at start, so you can manage them like that

warm marsh
#

But that's just for managing them that's probably not the best performance.

quartz kindle
#

If you want absolute best performance, code your commands inside the message event

#

Will save you a couple nanoseconds

#

And yes, a command handler can literally be a million different things, do whatever you feel like

#

I've done shit like parse commands in the raw event and use them like this client.on("/ping", message => {})

#

And also shit like client.on("message", message => require("commandsfile")(message))

#

Be creative

earnest phoenix
#

How can we make bot 7/24

sudden geyser
#

you mean keep it online?

earnest phoenix
#

Yes

grizzled raven
#

host

sudden geyser
#

hosting, look at pinned messages

dark swift
#

hey does anyone know why I am getting this error?

#

it downloads and then it says I have not installed ffmpeg

quartz kindle
#

pastebin or similar please

dark swift
#

I am using it in a cog btw

modest maple
#

ffmpeg/avconv what would appear it cant find ether of these

dark swift
#

hmm i installed it and put it in my path though

#

or environment variables

#

how do I fix it?

quartz kindle
#

Did you restart your terminal/ssh/system after adding to path?

dark swift
#

yes

quartz kindle
#

Are you on windows or linux?

#

Are you using visual studio?

dark swift
#

pycharm

#

windows

#

i'll try restarting again

#

ok I am back

#

new error

quartz kindle
#

Well, it seems ffmpeg is working now

#

That just looks like a code problem

dark swift
#

yeah that's good

#

definitely my code haha

#

'name' might be referenced before assignment

quartz kindle
#

The error says you're calling play on a none type

#

So it seems your voice variable is not getting a voice channel correctly

#

but I'm not a python guy

dark swift
#

ah okay

#

thank you.

unique nimbus
#

@dark swift that was taken from GitHub or a YouTube video I recognize the code

dark swift
#

yeah, I don't understand how to use the ffmpeg and youtube dl so I watched a video, when i said my code I meant like the code I am using

#

not trying to take credit for it

opaque eagle
vital lark
#

I don't recommend assigning objects

opaque eagle
#

oh

#

could that be why?

vital lark
#

could be

opaque eagle
#

It worked fine until I made some recent changes... I was trying to go from a regular client class that I'd pass into everything to a singleton

#

i suspect that it might mess up eris's client, but im not sure

vital lark
#

honestly I don't see an issue

#

with passing the Eris client

opaque eagle
#

me neither, but i just wanted to try this out

#

When I do it this way, I don't have to import the client class into lots of the other files

#

(its a TS project so i need to import it in every command and event file due to typings)

#
class SomeCommand extends Command {
   constructor(client: Client) {
      super(client, { name: "blah" });
   }
}```
vital lark
#

yea I know it's a TS project

opaque eagle
#

if i made it into a singleton i wouldn't need to import the Client class in all the files where i don't need to access it, which would be a majority of the filess

#

im starting to suspect that it's not an eris error... i did this: ts import { Client } from "eris"; class MySingletonClient { private client: Client; constructor() { this.client = new Client(process.env.TOKEN); Object.assign(this, this.client); } }

#

and it still gave the same error

proper inlet
#

Hi! I use client.fetchUser(id).tag to get a user tag to show it in my bot economy top. But i get 'undefined'. What is my mistake? (discord.js)

function getNicks(obj){
  let fr = '';
  for (var i = 0; i < 20; i++) {
  let user = client.fetchUser(obj[i].id); // undefined
  fr+=user.tag+"\n";
  }
  return fr;
}

When I use eval 'undefined' too. (I evaled 'client.fetchUser(SOME ID)')

slender thistle
#

I thought fetchUser returns a Promise

proper inlet
#

And how I can get user tag? (I am new in js)

vital lark
#

you gotta use async await my dude

#

fetchUser is a promise man!

proper inlet
#

Thx

opaque eagle
#

Ok... i've tried manually assigning all the properties from settings, that didn't solve it

#

I tried to make a new bot using a singleton... just the client class and logging in, and it worked fine... so the problem is somewhere in my code

vital lark
#

I would make it into a getter

#

i.e: this.settings = {};

glacial mango
#

How do I find a member in a server if their username is Jasper, and the search field is jasper, JaSpEr etc

opaque eagle
#

JS?

glacial mango
#

Yes

opaque eagle
#

.toLowerCase() both the username and the input and see if they're equal

glacial mango
#

Hm yes but

#

How do I get the username of all the members in the server?

opaque eagle
#

Collection.find()

#

takes a function

#

<Guild>.members.find(member => /* check if usernames are equal */)

topaz fjord
#

Doesn't the max call stack size error occur when you make too many function calls

opaque eagle
#

yeah

#

common if u do recursive stuff

#

i do have a recursive function on there

#

this.walk()

#

but i have a stop thing

quartz kindle
#

It's an infinite loop somewhere

opaque eagle
#

and it didn't error before all this singleton stuff

#

yeah

quartz kindle
#

Add the code back piece by piece until it breaks

opaque eagle
#

lmao ok

quartz kindle
#

You said it worked with only the client instance

#

Start with that

opaque eagle
#

alright

#

Keep in mind that the imports and functions are still there but they're not called in the constructor

quartz kindle
#

Which block did you add before it broke?

opaque eagle
#

Lines 21-27

quartz kindle
#

What is new require?

#

What class is that require returning?

lofty hamlet
#

Hi, i go to shard my bopt but i have some problems, the first is the number of guilds andd members

#
        bot.shard.fetchClientValues('guilds.size')
            .then(results => {
                return results.reduce((prev, guildCount) => prev + guildCount, 0)
            })
            .catch(console.error);
    }

    function getMembers() {
        bot.shard.broadcastEval('this.guilds.reduce((prev, guild) => prev + guild.memberCount, 0)')
            .then(results => {
                return results.reduce((prev, memberCount) => prev + memberCount, 0)
            })
            .catch(console.error);
    }```
opaque eagle
#

imma console.log and check

lofty hamlet
#

Why getGuilds() is undefined ?

topaz fjord
#

Impossible to know if you don't give us the error

quartz kindle
#

Wrong way to use async await

lofty hamlet
#

Me ?

opaque eagle
#

All the events are being loaded multiple timess

#

it loads all the events, then loads all of them again, and again, and again

lofty hamlet
#

getMembers() for example return undefined for me

quartz kindle
#

Doe the class you are requiring create a new instance of the singleton?

opaque eagle
#

some of them do, yeah

#

wait not a new instance

#

they just run ManateeClient.getInstance()

sudden geyser
#

neb, return the value from the function

quartz kindle
#

@lofty hamlet e function returns immediately, it doesnt wait for the .then()

lofty hamlet
#

?

quartz kindle
#

You need to use an async function and use await instead

lofty hamlet
#

Oh ok so if i want return the number of guild of my bot i do this ?

sudden geyser
#

I think functions will still handle the .then iirc

opaque eagle
#
import { ManateeClient, Event } from "./wherever";
export default class extends Event {
   exec() {
      ManateeClient.getInstance().user.id
   }
}```
#

They do stuff like that ^

#

And getInstance() is in the gist from earlier

vital lark
#

could be from your recursive "walk" function doing something

opaque eagle
#

its not called yet

#

i was re-adding the code piece by piece, and so far, walk() hasn't been called

#

ok i can confirm that the client class is being initialized multiple times

#
console.log(readdirSync(events));
for (const file of readdirSync(events)) {
   if (!file.endsWith(".js")) continue;
   const event = new (require(path.join(events, file)).default)(file.split(".")[0]);
   this.on(event.name, (...args: any[]) => event.exec(...args));
}```
#

i ran that (notice how the console.log is outside the for loop)

#

and i got the same array of filenames logged several times

#

so the constructor is being called several times

#

But the constructor is being initialized only once? (2 results show up but one is TS and the other is compiled JS)

#

...

sterile minnow
sudden geyser
#

well, are you still creating multiple instances of mantee

prime cliff
#

Instances of mantee? 6_ThonkHmmm

quartz kindle
#

@opaque eagle I think you have a cyclic dependency

#

The command loader calls getInstance and getInstance calls another command loader because the instance didn't finish initializing, so the actual instance never gets created

opaque eagle
#

ohhh

#

how could I go about fixing it?

quartz kindle
#

Pass the unfinished instance onto the loader as an argument

#

And use the unfinished instance instead of calling getInstance

#

Or move the loader out of the constructor

#

And call it manually

opaque eagle
#
function loadEvents(): any[] {
   const events = path.join(process.cwd(), "dist", "Internals", "Events");
   return readdirSync(events).reduce((arr: any[], file: string) => {
      if (file.endsWith(".js")) {
         const event = new (require(path.join(events, file)).default)(file.split(".")[0]);
         arr.push(event);
      }
      return arr;
   }, []);
}

export class ManateeClient extends Client {

   private constructor() {
      super(settings.token);

      for (const event of loadEvents()) {
         this.on(event.name, (...args) => event.exec(...args));
      }

   }

}```
#

i did that ^

#

still same error

#

(moved the loader out of the function)

lofty hamlet
#

I, i want get the values of all guilds of my bot in shard

#

How i can make this ?

modest maple
#
  1. what lib
  2. what 'values'
lofty hamlet
#

The number of guilds

#

With varibiable than i can use

#

In discord.js

#

@modest maple

#

No thx it's good

#

But i have another question

#

I have 3 shards

#

Sorry for ping fail

#

But i have system of webhooks with server

boreal yarrow
#
const dbl = new DBL('DBLTOKEN/APİ', client);
client.on('ready', () => {
    setInterval(() => {
        dbl.postStats(client.guilds.size);
    }, 280000);
});```
lofty hamlet
#

But the port is already use

boreal yarrow
#

im using these

lofty hamlet
#

No my bot is shard it's another system

opaque eagle
#

can someone from before help

vital lark
#

@boreal yarrow if client is in the DBL constructor, it'll autopost

#

so you don't have to post stats since it'll do it by itself

quartz kindle
#

@lofty hamlet you cannot use the same port multiple times, you have to put your dbl webhook in your shardmanager

#

Or only in one shard

lofty hamlet
#

Yeah i know

#

@quartz kindle what i do put in my shard ?

#

Shardmanager*

#

All of bot.on ?

#

My logs is broken with shard

quartz kindle
#

It's easier to put in only one shard

#

You can do something like js If(client.shard.id === 0) { let dbl = new DBL(...) dbl.webhook.on(...) }

#

I don't remember the exact code, but check the docs

lofty hamlet
#

Yeah i know

#

I speak bout my logs

#

When one command is write a logs in channel is send

#

But now, does'nt work with sharding

quartz kindle
#

Different shards have different channels

lofty hamlet
#

And my vote system

#

Is broken

#

Wtf

quartz kindle
#

So you have to either fetch the channel or do broadcastEval

lofty hamlet
#

@quartz kindle what ?

#

Ok i have understand my vote and my logs work on one shard

quartz kindle
#

client.fetchChannel in djs stable

#

Or broadcastEval

lofty hamlet
#

For ?

quartz kindle
#

@steady carbon you need to put your bots ip address I n top.gg edit page

#

I g2g

steady carbon
#

hmm

#

okay

#

let me see

lofty hamlet
#
    const dmlogs = bot.channels.get("526172579141124110")
    const logs = bot.channels.get("493050003657457664")

    if (message.channel.type === "dm") {
        if (message.length > 500) return
        if (message.author.id == "471749111125770250") return
        let embed = new Discord.RichEmbed()
            .setTimestamp()
            .setTitle("Un message privé a été envoyé au Bot")
            .addField(`Envoyé par :`, `${message.author.username}#${message.author.discriminator}`)
            .setColor(config.embed)
            .setThumbnail(message.author.displayAvatarURL)
            .addField(`Contient : `, message.content)
        dmlogs.send(embed)
        return
    }

    if (db.get(`guildPrefix_${message.guild.id}`) == null) {
        db.set(`guildPrefix_${message.guild.id}`, "?")
    }

    const args = message.content.slice(db.get(`guildPrefix_${message.guild.id}`).length).trim().split(/ +/g)
    const command = args.shift().toLowerCase()

    if (message.author.bot) return
    if (message.isMentioned(bot.user)) {
        message.channel.send('Mon prefix sur ce serveur est : ' + db.get(`guildPrefix_${message.guild.id}`))
    }
    if (message.content.indexOf(db.get(`guildPrefix_${message.guild.id}`)) !== 0) return
    try {
        let embed = new Discord.RichEmbed()
            .setTitle('Akimitsu')
            .addField(`Utilisateur :`, `${message.author.username}#${message.author.discriminator}\n${message.author.id}`)
            .addField(`Contenant de la commande :`, `${message.content}`)
            .addField(`Nom du Discord :`, `${message.guild.name}\n${message.guild.id}`)
            .setThumbnail(message.author.displayAvatarURL)
            .setTimestamp()
            .setColor(config.embed)
        logs.send(embed)
        let commandFile = require(`./commands/${command}.js`)
        commandFile.run(bot, message, args, config)
    } catch (e) {}
})```
#

System of logs

#

And with sharding he work just in one shard

#

@quartz kindle

#

And also my ststem of guildCreate

#

Wtf

#

He work just on the shard was launch

outer niche
#
  File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 31, in <module>
    start(fakepyfile,mainpyfile)
  File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 30, in start
    exec(open(mainpyfile).read(),  __main__.__dict__)
  File "<string>", line 20, in <module>
AttributeError: 'Command' object has no attribute 'command'

[Program finished]```


```@bot.command(pass_context=True)
async def echo(ctx, arg):
    await ctx.send(arg)```
I do not get what is wrong with it I have you written the command several times
slender thistle
#

Are you sure it's that command

outer niche
#

Yes

steady carbon
#
Webhook running at http://0.0.0.0:5000/dblwebhook```
slender thistle
#

Send the rest of your code, culan

steady carbon
#

do you know why isnt calling? :/

modest maple
#

the address is already in use on that port

#

what

lofty hamlet
#

How i can make vote system with sharding ?

#

But my vote system does'nt work with sharding

opaque eagle
#

how i do it is when the webhook hits my api it'll just update a boolean in my db

#

and the bot gets it from the db

outer niche
#
  File "C:\Users\Culann\Desktop\echo\echo.py", line 232, in <module>
    async def bottles(ctx, amount: typing.Optional[int] = 99, *, liquid="beer"):
NameError: name 'typing' is not defined```
vital lark
#

hm

#

did you import typing

outer niche
#

how can i fix this

#

fug i froget to

earnest phoenix
#

hello i am currently working on a sql system for your website and have a question how can i do that if you find the matching UID and AID in the SQL table then edit the EID but if you can't find it then make the board

modest maple
#

@earnest phoenix Just try Fetchall from the row using the UID or AID at the locator, if the length of Fetchall == 0 you know it doesnt exist, you can then make / add what ever from there

#

@outer niche please send the rest of your code otherwise its like playing guess the shape

outer niche
#

Oof sorry

earnest phoenix
#
if (isset($_POST['btn-eplistsave-add'])) {
        $uid = $_GET['uid'];
        $aid = $_GET['aid'];
        $eid = $_POST['eid'];

        if (empty($aid)) {
            $error = true;
        }

        if (!$error) {
            $eidq = mysqli_query($con, "INSERT INTO animelist (uid,aid,eid) VALUES ('$uid','$aid','$eid')");
            header("Location: ../../../view.php?aid=$aid");
        } else {
            header("Location: ../../../view.php?aid=$aid&denied");
        }
    } else {
        header("Location: ../../../view.php?aid=$aid&hiba");
    } ```
modest maple
#

@earnest phoenix idk what im supposed todo with this

earnest phoenix
#

create it only if you cannot find the specified UDI and AID

#

but if you find a UID and AID, edit the EID

split dune
#

use num_rows

#

but first try find specified variable, then use num_rows to check

#
if($getmember->num_rows == 1) {
/* ur code */
}``` smth like that
#

and you can do:

            $error = true;
            header("Location: ../../../view.php?aid=$aid&denied");
        }``` instead creating another else
magic lion
#

def SheetsMain():
SAMPLE_SPREADSHEET_ID = '129gwuo7c2STrgnNs82KDIN3FcxKccRafOk4ykO_imak'
SAMPLE_RANGE_NAME = 'File List!A4:155'

global ReturningList

SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly']
creds = None

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
        creds = pickle.load(token)

if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(
            r'C:\Users\ChillFish8\Documents\The_Innkeeper_Database\Spreadsheet/credentials.json', SCOPES)
        creds = flow.run_local_server(port=0)
    # Save the credentials for the next run
    with open('token.pickle', 'wb') as token:
        pickle.dump(creds, token)
#

Is that to log in?

modest maple
#

what

#

no

#

thats for using google spreadsheets

#

xD

magic lion
#

OOF

#

How do I log in???

modest maple
#

learn the basics first

#

like

#

you dont know what pip is

#

thats like the thing u need before u can even do anything in python

magic lion
#

Not true

modest maple
#

yes true

#

xD

magic lion
#

You can print without using pip

modest maple
#

you cannot say you know python unless you know how to use external modules

magic lion
#

Okie sorry

modest maple
#

you cant even use discord without installing an external module anyway

#

learn the basics

magic lion
#

WHY WON'T YOU HELP ME???

modest maple
#

i am

#

IM TELLING YOU LEARN THE BASICS

#

legit

#

if you learnt the basic things in python

#

you could run a discord bot

mossy vine
#

you cannot say you know python unless you know how to use external modules

magic lion
#

You're not telling me anything about coding

restive furnace
#

Google -> Learn python, then Google -> Discord.py Docs

modest maple
#

the thing is

#

i can just say learn the basics here, because.

#

thats what you need

#

to even install d.pu

quartz kindle
#

@earnest phoenix careful with SQL injections

#

Use prepared statements instead

split dune
#

just use mysql_real_espace function

#

to protect sql injections

quartz kindle
#

You mean mysql_real_escape_string?

split dune
#

ye that

#

xd

quartz kindle
#

Nvm it's not that one

#

That one is deprecated

split dune
#

mysqli_real_escape_string

quartz kindle
#

But mysqli has a replacement

split dune
#

php7 has only supported mysqli_* so xd

quartz kindle
#

Well SO says

Prepared statements only. Because nowhere escaping is the same thing. In fact, escaping has absolutely nothing to do with whatever injections, and shouldn't be used for protection.

While prepared statements offer the 100% security when applicable.

split dune
#

tbh ye, but i tested it and it works perfectly to block sql injections

#

for me

#

¯_(ツ)_/¯

quartz kindle
#

Yeah it makes sense that it works

#

But it's like using the wrong tool for the job lul

#

Hammering a nail with a machete

split dune
#

yep

balmy crest
#

anyone know a bot that can moderate, join and leave logs, and leveling roles?

modest maple
#

this isnt the area for it

balmy crest
#

o sorry

modest maple
#

and go to top.gg and go tot moderation tag

balmy crest
#

ok

modest maple
#

like there are thousands with it

balmy crest
#

ok rt

#

ty

lusty dew
#

What should I use when coding in C++?

mossy vine
#

literally any code editor/ide

lusty dew
#

Okay

mossy vine
#

codeblocks and visual studio are popular options

lusty dew
#

But don't you need a compiler

mossy vine
#

yes

lusty dew
#

What compiler should you sue

mossy vine
#

most ides will include the compiler iirc

lusty dew
#

use*

#

I don't feel like wasting a shit ton of space on Visual Studio so I installed vsc instead

mossy vine
#

if you are on linux, g++

lusty dew
#

I am on Windows

mossy vine
#

i know there is something for windows too

#

lemme search

lusty dew
#

Ok

vast holly
#

guys

#

what is best hosting place

#

for the best ping

#

?

#

Europe ?

#

or france

#

or ..

#

?

lusty dew
#

Okay so I installed g++ for windows

#

but it says its not a recognized term

mossy vine
#

@lusty dew did you add the binaries to PATH

lusty dew
#
or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ g++ version
+ ~~~
    + CategoryInfo          : ObjectNotFound: (g++:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException```
mossy vine
#

@vast holly check pins

lusty dew
#

Yea I am pretty sure

vast holly
#

ok but what is the best

#

.. ?

#

ping country

mossy vine
#

run the executable from directly where it is

vast holly
#

because i want to make vps

#

for my bot

mossy vine
#

@vast holly discord has servers in many places, so it depends on guilds

vast holly
#

ok what is the best

#

?

lusty dew
#

@mossy vine huh

mossy vine
#

there is no "best"

#

choose whatever you want

#

50-150 ping doesnt matter, and you wont get anything higher than that

earnest phoenix
#

it generally doesn't matter

#

you would ideally want a vps nearest to the api servers

#

which is NYC i think

#

but again it doesn't matter because of internal latency and the latency of the server region

#

Im new to this, once I export my bot, if i add new content to it, would I need to replace all the files or only a certain few?

mossy vine
#

im getting 124 ping on a vps hosted in somewhere east europe

earnest phoenix
#

in what language @earnest phoenix

#

Javascript

#

yeah cyber that's normal

mossy vine
#

i know, ping is usually 50-150 unless api is shitting itself

earnest phoenix
#

hypers, if you are debugging and running the program directly with node, just edit the files you need to edit and restart the process, if the app is published you will need to republish it again after editing

#

alright ty

lusty dew
#

Yea g++ still isn't working

mossy vine
#

yeah i dont think i can help you, i dont use windows, sorry

lusty dew
#

... okay

#

can anyone help me with g++ compiler from MinGW

#

it isn't recognizing g++ command

empty owl
#

how do you do a random pic command that provides new and fresh pics without nsfw

#

and since ur not a big bot you dont have weeb.sh

lusty dew
#

Depends

#

Where are you getting the pics from

empty owl
#

exactly

lusty dew
#

If you are getting the pics from reddit you wanna randomize the pics you get

empty owl
#

if I had an array i would need to refresh it a couple of times a day or it will get old

#

i can do that

lusty dew
#

no

empty owl
#

but with random puppy

lusty dew
#

you can use Math.random()

empty owl
#

yEs

#

I know

lusty dew
#

so you wouldn't have to refresh your array 😂

empty owl
#

Wgat

lusty dew
#

if I had an array i would need to refresh it a couple of times a day or it will get old

#

You wouldn't

empty owl
#

ok just randomize the same array

#

bruh

lusty dew
#

I mean

#

Yes?

empty owl
#

so

#

oh here its a dog

lusty dew
#

If you want new pictures to be displayed

empty owl
#

oh here another dog

#

oh here a dog

lusty dew
#

add more to the array

empty owl
#

but i dotn want to do that

#

thats the point

lusty dew
#

🤔

empty owl
#

ok lets talk memes

#

memes get old

lusty dew
#

Then where will the pics come from

empty owl
#

thats the point of the quest

#

iomn

lusty dew
#

🤔

#

Easiest would be to use reddit

empty owl
#

yea

lusty dew
#

Reddit has an offical API or you can use something like random-puppy

#

but even then

empty owl
#

cant guarantee not nsfw

lusty dew
#

you will wanna use an array of subreddits and randomize it

#

Yea you can

empty owl
#

noo u cant

lusty dew
#

Yes?

empty owl
#

how

lusty dew
#

Reddit has an nsfw filter

empty owl
#

it does?

lusty dew
#

it filters out nsfw subreddits

#

default is sfw subreddits

empty owl
#

oh

lusty dew
#

but you can implement a filter to return nsfw subreddits

#

Here is how I would do it using random puppy

empty owl
#

yea just put a ranodm array

#

then imput it with random puppy

#

right

#

etc

lusty dew
#
let subreddits = [
//array of subreddits
]

let sub = subreddits[Math.floor(Math.random() * subreddits.length)]

randomPuppy(sub) // blah blah blah
empty owl
#

yea

#

👍

lusty dew
#

Yep

#

What are the bennefits of making your client a class instead of doing client = commands.Bot()

summer torrent
#

I want to get position of role on role list. but .position gives me an incorrect position

#

example : 1st role on role list, seems to be lowest

lusty dew
#

Are you trying to get the highest role or what?

earnest phoenix
#

well yes

summer torrent
#

(I am using master)

lusty dew
#

Doesn't it go in order of when it was added

earnest phoenix
#

the higher the position the lower the role is in the list

lusty dew
#

or am I wrong

earnest phoenix
#

it follows a ranking system

#

a position of 1 is going to be the highest

#

wait no

lusty dew
#

Ah mk

#

I thought it went in order of when it was added

#

Highest being the lowest in the list cause it was added first

earnest phoenix
#

yeah actually i think it is, a role with a position of 1 is going to be the highest role

lusty dew
#

Yea

earnest phoenix
#

date of creation wouldn't matter here

#

because the roles can be reordered

lusty dew
#

Well yes

#

Idk

#

and don't really care ima go back to my work

empty owl
#

try it and seeee tm

lusty dew
#

🤔

#

Why waste my time on something that’s possibly not good when I can get feedback from other people that help me make a decision on what’s good or not

modest maple
#

Idk why you need a asyncio SQL lite

#

As the queries r async anyway and are quick enough to probably be faster than an asyncio version of the lib

#

We don't need . thanks

west raptor
#

-dotpost @earnest phoenix

gilded plankBOT
#

@earnest phoenix

Please do not post dots to clear your messages/get attention. It adds absolutely nothing to the conversation and just causes spam If you need to get attention, then say hello everyone. If you need to clear your messages, then press the Esc key. If you do not follow these instructions you will be muted.

west raptor
#

also this is development

empty owl
#

what the heck does esc

#

does

lusty dew
#

Mk

#

I am curious how classes work in python

modest maple
#

you just put

#

Class

#

Nane

#

Stuff

#

About it

lusty dew
#

I am trying to call a class method in another file but I get this

        self.create_engine('sqlite:///:memory', echo=True)
        print("Successfully created an engine")```
modest maple
#

XD

lusty dew
#

oof

#

wrong thing

#
  File "star.py", line 29, in <module>
    StarDatabase.create_eg()
TypeError: create_eg() missing 1 required positional argument: 'self'
#

xd

#

I get that

#

but I don't get what self would even be

modest maple
#

You're trying to make a class?

lusty dew
#

Yea

modest maple
#

By making a function

lusty dew
#

No

modest maple
#

See the issue

lusty dew
#
class StarDatabase():
    async def create_eg(self):
        self.create_engine('sqlite:///:memory', echo=True)
        print("Successfully created an engine")
modest maple
#

You're calling self

#

Before assign it

#

Self just means

#

The class object gets that thing

#

you need to assign it like a var

#

E.g

#

Self.stuff = xyz

lusty dew
#

Why is it a required thing

modest maple
#

And then your class will have the property .stuff

#

Cuz that's how you make objects?

lusty dew
#

Also I kinda see similarities with js

modest maple
#

Doing self.zyx just is trying to call a property that don't exist

#

Unless u assign it

lusty dew
#

👀

#

Okay

#

so when I tried defining it

#

it moved it to an __init__ function inside the class

modest maple
#

Yh

lusty dew
#

I am assuming

#

you define stuff in there

modest maple
#

Yh

lusty dew
#

then use it inside the other funcs

modest maple
#

Yh

lusty dew
#

so like

#
class StarDatabase():
    def __init__(self):
        self.engine = create_engine('sqlite:///:memory', echo=True)

    async def create_eg(self):
        self.engine
        print("Successfully created an engine")
#

?

#

or

modest maple
#

If you have the create engine in the init function that's where it is creating the db

lusty dew
#

Hm

modest maple
#

So calling self.engine in the async function is pointless

lusty dew
#

so would i just define self.engine then in the create_eg func give it a value?

modest maple
#

Yh

lusty dew
#
class StarDatabase():
    def __init__(self):
        self.engine

    async def create_eg(self):
        self.engine = create_engine('sqlite:///:memory', echo=True)
        print("Successfully created an engine")
modest maple
#

Maybe?

#

I'm not sure wether it will like the self.engine by itself being undefined

#

You might just need to play around with it

#

Cuz you might not actually need the _ init_ function if youre only doin that

lusty dew
#

It tells me to move it to an __init__ func

ruby talon
#

PyCharm?

lusty dew
#

Yea

ruby talon
#

Ah yeah.
I read youe thingy.
I wouldn't use the self if you're only going to use it for what it is rn.
If you wanna use it further in other functions ect sure.
If not I would ignore the PyCharm notification.

#

For what it is rn I wouldn't even put it in a class tbh.

#

🤷‍♂️

slim heart
#

when i try to add a reaction with a unicode character i get this TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters (node-fetch)

amber fractal
#

@slim heart can you show some code?

sudden geyser
#

maybe encode it?

slim heart
#

oh yeah that worked

#

i forgot i could encode unicode

amber fractal
slim heart
#

tanku

sudden geyser
#

np

minor kelp
#
@bot.command()
async def owner(ctx):
    e = discord.Embed(title="Test", colour=0xFF0000)
    msg = await ctx.send(embed=e)
    em = discord.Embed(title="Test was edited", colour=0xFF0000)
    await ctx.message.edit(embed=em)

How would i make the ctx.message.edit edit the bots message variable msg?

earnest phoenix
#

ctx.msg.edit?

#

Good night

minor kelp
#

than k

#

@earnest phoenix didnt work

#

"Context has no attribute msg"

slender thistle
#

A Message instance is returned from <Messageable>.send

#

you call .edit on that returned instance

#

So msg.edit

lusty dew
#

What would be the best way to make a database in python? make it in a seperate file or?

slender thistle
#

What do you mean "in a separate file"?

lusty dew
#

Like

#

would I do all my database stuff in my main file

#

or do it in a seperate file

slender thistle
#

Working with the db?

lusty dew
#

What?

slender thistle
#

Are you talking about interacting with your database in your bot's main file or using one db file for everything?

lusty dew
#

I am making a database for my bot

#

I am talking about doing all the db stuff in a seperate file is it wise

#

Like creating the tables and such

earnest phoenix
#

you aren't planning on using actual text/json files as a database are you

lusty dew
#

No

#

I am using sqlite3

earnest phoenix
#

ah

lusty dew
#

But I haven't ever used it in python so I am not sure how I should go about doing this

slender thistle
#

I'd say it depends

lusty dew
#

I plan on making my own functions to help handle the db

slender thistle
#

Attach a connection to your bot variable and then work with it anywhere where it's necessary

lusty dew
#

How would I do that

slender thistle
#

Attach the sqlite connection to bot?

lusty dew
#

to the variable yes

slender thistle
#

bot.x = sqlite.connect(...)

lusty dew
#

Okay

lusty dew
#

Should the text be highlighted like that?

#

or is it just a pycharm thing

#

Ima assume it’s a pycharm thing

stable horizon
#

its a pycharm thing

lusty dew
#

Ah okay

#

Btw

#

How would I make it so I don’t have to create the table in the on_ready event

#

Like

#

How can I explain this

#

I wanna make a func that creates all the tables when called

#

And call that func in the on_ready event

#

I’d assume I’d make the function in a different file then import the function into the main file and call it that way right?

slender thistle
#

It doesn't have to be in a separate file

stable horizon
#

youre using sqlite yea?

lusty dew
#

Ik

#

But I want it to be

#

Yes sqlite3

stable horizon
#

also, you need an async lib

slender thistle
#

aiosqlite?

stable horizon
#

no

lusty dew
#

No

#

The built in sqlite3 lib

stable horizon
#

you cant use the built in one

lusty dew
#

Wdym

#

Why can’t I

stable horizon
#

its blocking

lusty dew
#

Bruh

#

What else am I supposed to use

#

Smh

stable horizon
#

i literally linked you soemthing

lusty dew
#

Why can’t shit just be simple

#

Smh

stable horizon
#

welcome to programming

lusty dew
#

Lmfao

stable horizon
#

tis a pain in the ass to do anything other than 1+1

lusty dew
#

Python is a pain in the ass period

slender thistle
#

pow(e,0) smug

stable horizon
#

easier than js ¯_(ツ)_/¯

slender thistle
#

Any language is pain in the ass at this point

lusty dew
#

D.js lib is easier then d.py

slender thistle
#

That's preferences

#

X is easier for someone than Y but for someone else Y is easier than X

lusty dew
#

At least you can use sqlite3 without it causing problems

#

xd

stable horizon
#

literally any non-async lib will cause problems

slender thistle
#

You can use sqlite if you are 100000% sure it won't hang your entire bot because it stopped somewhere for too long

stable horizon
#

or an async lib

lusty dew
#

What the hell is the difference between what I am doing and what they are doing

#

🤔

#

They are using sqlite3

stable horizon
#

yeah but its being wrapped so it doesnt block your bot

lusty dew
#

So what am I supposed to do with it

stable horizon
#

make a file, chuck that code inside it, import the file, and use it

lusty dew
#

🤔

stable horizon
#

the usage is p much the same, you just have to await everything

slender thistle
#

Flashbacks to me being yelled at for not using f-strings in d.py server
Now it's sync vs async here

lusty dew
#

Flashbacks to being disrespected in d,py server
Still happens

stable horizon
#

just dont ask questions when vex is around and youll be fine

#

also dont ask stupid questions

lusty dew
#

🤔

#

Might as well not ask questions at all

slender thistle
#

Tbh I'm grateful for that since f-strings are 10/10

lusty dew
#

Any question can be considered stupid depending on who you are asking

stable horizon
lusty dew
#

Again

#

any question can be considered dumb depending on who you ask

slender thistle
#

It's usually the ones that need common sense to be applied

lusty dew
#

Hm

#

Well

#

I guess I will just do what you said

slender thistle
#

Questions that would need a look at from a more experienced Python coder for more efficiency etc is not that dumb objectively

lusty dew
#

Time to do something people tell you not to do xd

stable horizon
lusty dew
#

Wtf

slender thistle
#

Couldn't you just for-loop that 🤣

stable horizon
#

yea

lusty dew
#

Yea

stable horizon
#

but i did it a long time ago

#

and im too lazy to fix

slender thistle
#

👌

lusty dew
#

Didn’t they have an example on loading cogs

stable horizon
#

dude i did everything the way you werent supposed to

lusty dew
#

Xd

#

Want me to fix that for you?

#

I have nothing else to do

stable horizon
lusty dew
#

I see nothing wrong there

stable horizon
#

overrode _inject and _eject

lusty dew
slender thistle
#

Sounds interesting

lusty dew
#

Does anyone wanna collab on a py bot

#

I may not know Jack shit about python but hey it’ll be a fun ride 😉

#

Nah I’m kidding

#

Hmmm

#

Odd

#

@stable horizon Didn't you say that everything is the same you just gotta await it

stable horizon
#

including connect

#

you havent awaited connect

lusty dew
#

I have

stable horizon
#

you havent awaited something

lusty dew
#

Everything is awaited

stable horizon
#

'_ContextManagerMixin'
that is a wrapper for something that has yet to be awaited

lusty dew
#

Idk then

stable horizon
#

whats your code?

lusty dew
#

I’ve awaited everything

#
from custommods import asqlite


async def create_tables():
    db = await asqlite.connect('pystar.sqlite')
    cursor = await db.cursor()
    await cursor.execute('''CREATE TABLE IF NOT EXISTS users(
            user_id TEXT,
            warns INT,
            mutes INT,
            reports INT,
            bans INT,
            joined_at DATE)''')

stable horizon
#

hm

lusty dew
#

I got it working

#

I made a typo in one of the awaits

#

Every time you wanna query the db you gotta reconnect to it?

stable horizon
#

no?

#

you should be assigning it to a botvar

lusty dew
#

Wdym

stable horizon
#

bot.db = await connect to db

lusty dew
#

Hm

#

I was just going to do

#
from custommods import asqlite


async def create_tables():
    db = await asqlite.connect('pystar.sqlite')
    cursor = await db.cursor()
    await cursor.execute('''CREATE TABLE IF NOT EXISTS users(
            user_id TEXT,
            warns INT,
            mutes INT,
            reports INT,
            bans INT,
            joined_at DATE)''')


async def find_one():
    db = await asqlite.connect('pystar.sqlite')

#

make my own functions

stable horizon
#

efficiency says dont, but you do you

lusty dew
#

Wdym efficiency

#

How is this not efficent

stable horizon
#

youre connecting every time you want to use the db

#

ineffecient.

lusty dew
#

Oh wait yea

#

But wait

#

won't I still be connecting everytime I use the db by attaching it to the client

#

if I call that variable I am still connecting to it am I not

stable horizon
#

no

#

youll stay connected

lusty dew
#

Okay

#

so if I connect it using my client

#

can i then make my own functions?

stable horizon
#

sure

#

just make them use bot.db or whatever you call it

lusty dew
#

okay

#

is there any specific way I have to do it

#

or can any file I make have access to client.db

stable horizon
#

could pass client as an argument

lusty dew
#

How so?

stable horizon
#

to your function...

lusty dew
#

Oh

#

I thought you meant to something else

#

lol

#

Wait do you mean define client.db in the main file or inside the file where I make the functions @stable horizon

stable horizon
#

main file

lusty dew
#

Hm

#

How will I do that if i have to await it

#

Oh wait

#

nvm

#

oof

#

Okay nevermind my way didn't work

#
class StarClient(commands.Bot):
    async def on_ready(self):
        await create_tables()
        print('Logged on as {0}!'.format(self.user))

    async def on_message(self, message):
        await self.process_commands(message)


client = StarClient(command_prefix="p$")
client.db = await asqlite.connect('pystar.sqlite')

since my client is setup like that

#

I don't see how I could make client.db async

stable horizon
#

do it in on_ready

lusty dew
#

How

#

Wouldn't that be using client before client is defined?

verbal tide
#

How do I create a node for a music bot through lavalink?

lusty dew
#

@stable horizon

stable horizon
#

no?

lusty dew
#

How so

stable horizon
#

on_ready is run when the cache is filled. your client is defined when you do client()

lusty dew
#

Ah mk

#

AttributeError: '_ContextManagerMixin' object has no attribute 'execute'

stable horizon
#

check your awaits again

lusty dew
#

Everything is awaited

#

I promise you

stable horizon
#

you said that last time pepoS

lusty dew
#

This time I am 100% sure

stable horizon
#

the error says otherwise tho

lusty dew
stable horizon
#

could.... try awaiting it twice? thats a terrible solution but...

restive furnace
#

@Dough#2688 just download lavalink cli and start it thats your new node

stable horizon
#

they gone

restive furnace
#

i dont think so i just think uncached

lusty dew
#

or if they are using js

stable horizon
#

no theyre gone

restive furnace
#

kk

lusty dew
#

Is that customized discord?

#

Wee wooo

stable horizon
#

wait fuck. i dont know what youre talking about.

lusty dew
#

LMAO

stable horizon
#

its not better discord

lusty dew
#

I don't really care tbh

#

I used to use better discord

#

but then I stopped

#

It got annoying

#

Wtf is this package

stable horizon
#

js it would seem

lusty dew
#

Yea I know

#

I was trying to make something similar

stable horizon
#

i will not be subjecting myself to the torture of looking at js

lusty dew
#

but in python

stable horizon
#

kthnx for coming to my ted talk

lusty dew
#

xd

#

ima assume

#

it is for randomizing an array

stable horizon
#

uh

#

random.shuffle is a thing

lusty dew
#

Lol

#

Yea

#

I know

#

Oh wait

#

I see what this is

#

I am stupid

#

xd

#

I am trying to recreate a js package in python

#

called random puppy

#

for the hell of it

stable horizon
lusty dew
#

Well one

#

It does something I want to do in my python bot

lusty dew
#
await cursor.execute('''SELECT (?) FROM ? WHERE ?''', table, values, cond)
#

Just checking myself isn't this a valid sql query?

quartz kindle
#

depends on the sql library you're using

#

but from most libraries i've seen, it should be 'QUERY' not '''QUERY'''

#

also check with that library if that is the correct way of using prepared statements

#

most of them dont let you use prepared statements for table names

lusty dew
#

I am using python sqlite3 package

quartz kindle
#

and your variables are switched

lusty dew
#

pretty sure pythons built in sqlite3 package allows me to use prepared statements like that

#

and it is '''QUERY'''

quartz kindle
#

c.execute('SELECT * FROM stocks WHERE symbol=?', t)

lusty dew
#

Okay

#

It doesn't really matter how many single quotes you use

quartz kindle
#
# This is the qmark style:
cur.execute("insert into people values (?, ?)", (who, age))

# And this is the named style:
cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})

print cur.fetchone()```
#

this should be the correct way

lusty dew
#

Okay

#

so I am doing it wrong>

#

?*

quartz kindle
#

yes, it should be cursor.execute('SELECT * FROM tablename WHERE field = ?''', (condition))

lusty dew
#

Okay

#

But

#

that means I would have to set a specifc table name

quartz kindle
#

yes, table names cannot be parameterized

#

only hardcoded

lusty dew
#
async def find_one(client, table, cond):
    cursor = await client.db.cursor()
    await cursor.execute('''SELECT * FROM ? WHERE ?''', (table, cond))
#

which isn't what I want

quartz kindle
#

i mean, you can try, but from the js sqlite libraries ive used it doesnt work

#

you would have to hardcode the table name

lusty dew
#

Hm

#

I am pretty sure they don't

#

I have used js libraries and parameterized tablenames

#

and it worked

#

better-sqlite3 being one of

#

em*

#

Maybe not all of em do?

quartz kindle
#

No, you can't do that, with SQLite or with most other SQL products. Parameter binding is for binding parameters, not replacing any old bit of the query that you fancy

lusty dew
#

What\

#

how does that have any context here

quartz kindle
#

you cannot pass table names as parameters in an sql query

#

but i mean, go ahead and try it

#

maybe it works in your library

restive furnace
#

@quartz kindle on python """text""" are multiline like on js `text
text2`

quartz kindle
#

ah ok

lusty dew
#
    await cursor.execute('''SELECT * FROM ? WHERE ?''', (table, cond))
  File "C:\Users\SecretUsername\Desktop\PyStar\custommods\asqlite.py", line 122, in execute
    return await self._post(self._cursor.execute, sql, parameters)
  File "C:\Users\SecretUsername\Desktop\PyStar\custommods\asqlite.py", line 31, in _call_entry
    result = entry.func(*entry.args, **entry.kwargs)
sqlite3.OperationalError: near "?": syntax error
#

Hm

#

Idk if that is the FROM ? or the WHERE ?

modest maple
#

It's both

#

You need to tell SQL where to select values from and where to locate said values

lusty dew
#
await find_one(client, 'users', 'user_id=479603748382179329')
modest maple
#

E.g SELECT * FROM {TABLE} would everything in the table

lusty dew
#

Yes

#

I know

#

But I am doing what you should do at least I am pretty sure I am

#
await find_one(client, 'users', 'user_id=479603748382179329')
#

2nd param table 3rd cond

modest maple
#

You haven't got the ? In ()

lusty dew
#

which one

#

the WHERE?

modest maple
#

Both

lusty dew
#

Okay

#

Same error

modest maple
#

Yes ik I just checked my db

lusty dew
#

Ok

modest maple
#

If it's SQL lite it needs

#

Select * from {table name} where {column name}=?

#

Atleast that's what's working on my system

lusty dew
#

and I am assuming it would be (?=?)

#

or (?) = (?)

#

Neither works

#

Sigh

modest maple
#

just try """SELECT * FROM ? WHERE ?=?""", (x, y, z,)

lusty dew
#

Nope

#

Tim was right

#

you can't paramertize tablenames

#

I specified the tablename in the sql query and it worked

modest maple
#

ah

lusty dew
#

Which sucks

#

Smh

quartz kindle
#

you can do string concatenation instead

#

but you need to manually sanitize it

modest maple
#

hmm

quartz kindle
#

if the table name is user defined

modest maple
#

i might need to rethink a system myself

lusty dew
#

I am to tired for this

#

it is 2am

modest maple
#

sleep bruh

lusty dew
#

Python is exausting

modest maple
#

SQL is exausting

quartz kindle
#

idk how to concatenate in python, but theorically "SELECT * FROM " + tablename + " WHERE " + condition + " = ?"

#

but you need to validate/sanitize those variables

lusty dew
#

Hm

modest maple
#

no string formatting for us 🙃

lusty dew
#

you could just use f strings cant you

quartz kindle
#

yeah

lusty dew
#

👀

modest maple
#

no

#

bad

#

not with SQL you dont

quartz kindle
#

you cant use f string? why not?

#

isnt f string the same as ` in js?

#

string templating

modest maple
#

theyre regarded as being the worst possible thing to use with SQL and python

#

as theyre the easiest todo with a SQL injection attack

lusty dew
#

How else would you do it

modest maple
#

like time say i suppose

#

tim* sadi*

#

said*

#

fuck my english today man

lusty dew
#

okay

quartz kindle
#

yes, but there is no difference between f string and string concatenation security wise

#

or there is?

lusty dew
#

I don't see how there is

#

basically the same thing as concatenation

late hill
#

throwback to when someone found an sql injection in my bot, but my bot doesn't use sql dab

lusty dew
#

just cleaner

modest maple
#

you should still be able to use "?", (x,)

quartz kindle
#

wesley wat

late hill
#

just some troll

#

lol

quartz kindle
#

lmao

lusty dew
#

Anyways

#

how could I sanitize it

#

Wdym by that

modest maple
#

but basically F strings and .format are liable to SQL injection attacks but ? method doesnt

#

idk why

quartz kindle
#

the easiest way to do it is to run it against a list of your valid tables

#

like if(variable exists in list of tables) continue

#

make it only run the query if the table name is an actual table name that exists

lusty dew
#

@modest maple Again what is the difference between concatenation and f strings, like tim said

#

how does it make it more vulnerable

modest maple
#

i honestly cant tell you

lusty dew
#

using f strings

quartz kindle
#

@modest maple f stirngs and format have nothing to do with the ? method

#

the ? method is sqlite parameterization, everyone should use it always

#

but parameterization cant be used with table names

modest maple
#

you can use ? in python as another method of string formatting

quartz kindle
#

the rest of the sql query is made by strings and string manipulation

#

? in sql is not string formatting

#

or does it have other uses in non-sql python ?

modest maple
#

it has non-sql uses

quartz kindle
#

oh

lusty dew
#
if table == list of table names:
  //do query
else: 
  return
modest maple
#

it does the same job as f strings and .format

#

but for some reason

#

isnt liable to sql attacks

quartz kindle
#

can you show an example?

modest maple
#

i honestly have no idea why

quartz kindle
#

of using ? for strings

modest maple
#

hmm idk

#

i use f strings for everything execept sql cuz theyre just easier

#

i might be mistaken actually it might be an sql only thing

lusty dew
#

@quartz kindle

if table == list of table names:
  //do query
else: 
  return
#

Mean like that?

modest maple
#

you need in not ==

lusty dew
#

Ah shit

#

my bad

modest maple
#

dw

#

its a common mistake tbh

lusty dew
#

wait

quartz kindle
#

i found this

lusty dew
#

nvm

#

oof

quartz kindle
#

python is a mess lmao

modest maple
#

yh

#

like

#

their are many

#

many ways

#

of formatting a string