#development

1 messages · Page 218 of 1

quartz kindle
#

or use an utf parser

#

you mean add a bot to top.gg? you go to the website and add it there

untold vortex
#

but bot is declined

#

idk why how can i see the reason?

quartz kindle
#

then read the reason for why it was declined

#

you should receive a dm informing you of the reason

untold vortex
quartz kindle
#

and search for your bot'd id

untold vortex
#

k

quartz kindle
untold vortex
#

hmm yea but it have both

#

shapes - ai
code - cmds

#

i am only using shapes for ai

#

rest it have cmds

#

prefix cmds

quartz kindle
#

then make sure to remove anything that says its from shapes

quartz kindle
#

and removing anything that makes it look like its a copy of shapes

untold vortex
#

k

#

i will try to no look like shape

quartz kindle
#

like for example, often people copy other bot's code

#

and forget to change basic stuff like help command

untold vortex
#

nah thats my code only

#

i only made that

quartz kindle
#

and when you run the help command, you see the help command for a bot with a different name

#

that happens a lot

untold vortex
#

means me and 3 frineds

#

ok

#

leme tey again

quartz kindle
#

you can also dm the person who reviewed your bot and ask them

urban delta
#

when i asked review in the wrong place, the person reviewed me with a troll review

#

like, it saying that i begged for review

#

and only talked about math command

#

that i already fixed

bitter granite
quartz kindle
bitter granite
quartz kindle
urban delta
#

ou tu ta só me zoando?

quartz kindle
solemn latch
bitter granite
solemn latch
#

it cant be modified

#

yeah

quartz kindle
quartz kindle
solemn latch
#

its like botghost iirc

#

you give your token

quartz kindle
#

oh

solemn latch
quartz kindle
#

i mean, then you should explicitly say that when denying

bitter granite
quartz kindle
#

then its not really correct to say "unmodified clone" as the reason for denial

#

it will only confuse people

#

just say "we dont allow bots created with shapes"

bitter granite
#

that would lead to more issue

quartz kindle
#

but thats literally what it is, just in other words, no?

solemn latch
#

technically speaking, it could be modified. They just would have to add their own bot too

#

Its just 99.99% of shapes devs wouldnt know thats a possibility

bitter granite
quartz kindle
#

because when you talk about "unmodified clone" you give people the idea that they just didnt change it enough, so they will keep trying not realizing that it will never be enough

#

essentially lying to them in a way

bitter granite
quartz kindle
#

wat

solemn latch
#

Honestly, I dont disagree. I just doubt itll be possible for us to make every bot reviewer add their own custom button for declining shapes bots.

#

We've never really forced that

quartz kindle
#

bot reviewers cant write a reason for denial manually? they just click a premade answer button?

#

lmao

solemn latch
#

they can, but we're all lazy 😄

quartz kindle
#

lmao

#

i mean

#

thats fine

bitter granite
solemn latch
quartz kindle
#

but like, if i were applying and got denied for that, i would be left stratching my head

solemn latch
#

We do inform people who submit bots they can reach out to us iirc

#

But I do agree with your thoughts

quartz kindle
#

could at least add something like "we require bots to be unique therefore we cannot allow bots made with platforms where creating something unique is not possible"

green kestrel
#

has everyone heard about discords new monetization policy

quartz kindle
#

"unfortunately shapes inc does not provide suficient tools to create a bot with a unique identity"

untold vortex
#

hey guys do anyone have working lavalink?

solemn latch
quartz kindle
#

"considerable amount of customization" = yeah i just add my own command names and its good enough :)

bitter granite
untold vortex
#

cause all are offline lavalink

#

and idk how to make a lavalink

bitter granite
untold vortex
#

ty

quartz kindle
#

people offer hosted instances free of charge like that?

bitter granite
#

yes

quartz kindle
#

dafuq

#

isnt lavalink resource intensive?

bitter granite
#

it is

quartz kindle
#

all the downloading and transcoding

bitter granite
#

and it used too much

quartz kindle
#

and people use these to play music on their bots

#

then wonder why their bots are bad

bitter granite
quartz kindle
#

lmao

#

thats even worse

bitter granite
#

ngl

#

thats how i know

#

that site

untold vortex
bitter granite
#

not all of them is up

untold vortex
#

ohh ok

untold vortex
#

i hope its online

pearl trail
#

just make sure you're not using the latest lavalink wrapper, I doubt those nodes are at the latest version, which only allow http requests instead via websocket

#

maybe it exists, just try one by one

untold vortex
#

its wrong

#

i made it

#

its js

#

and the clone is py

sharp geyser
#

Dm @shell tundra

untold vortex
bitter granite
urban delta
#

okay so, i can't open my traceback, how do i print my traceback here?

class Macro:
    async def exemac(self, args, database, guild_id, author_id, bot, starter):
        macrocache["command"] = args
        macrocache["database"] = database
        macrocache["guild_id"] = guild_id
        macrocache["author_id"] = author_id
        macrocache["bot"] = bot
        macrocache["start with ->"] = starter

        try:
            print(f"{args = }")
            try:
                args = await conversor(args)
                grammar_compilation = macro_grammar.parse(args)
            except (lark.UnexpectedCharacters, lark.LarkError) as error:
                indicator = error.get_context(args)
                print(error.__traceback__)
                raise InvalidCharacter(indicator)

            cmd = await Compiler(macrocache).transform(grammar_compilation)

            # await macrocache["database"].clear_cache(id=macrocache["author_id"])

            return cmd
        except Exception as e:
            print(e)
            return (e,)


#################
###   CACHE   ###
#################
macrocache = dict()
sharp geyser
urban delta
#

i tried but didn't worked

sharp geyser
#

import traceback

#

then traceback.print_tb(error.__traceback__)

#

all __traceback__ is irrc just the memory address of where it is on the heap

urban delta
# sharp geyser import traceback

okay so i got this:

  File "C:\Users\User\RP-Utilities\rp_utilities\macros.py", line 1973, in exemac
    grammar_compilation = macro_grammar.parse(args)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\rp-utilities-2cgrnvKo-py3.11\Lib\site-packages\lark\lark.py", line 658, in parse
    return self.parser.parse(text, start=start, on_error=on_error)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\rp-utilities-2cgrnvKo-py3.11\Lib\site-packages\lark\parser_frontends.py", line 104, in parse
    return self.parser.parse(stream, chosen_start, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\rp-utilities-2cgrnvKo-py3.11\Lib\site-packages\lark\parsers\earley.py", line 279, in parse
    to_scan = self._parse(lexer, columns, to_scan, start_symbol)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\rp-utilities-2cgrnvKo-py3.11\Lib\site-packages\lark\parsers\xearley.py", line 152, 
in _parse
    to_scan = scan(i, to_scan)
              ^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\rp-utilities-2cgrnvKo-py3.11\Lib\site-packages\lark\parsers\xearley.py", line 125, 
in scan
    raise UnexpectedCharacters(stream, i, text_line, text_column, {item.expect.name for item in to_scan},
!echo [{ k-a }{ ***k***-zu }{ k-ra }{ k-ka }]
This character is not compatible with compiler or you mistyped something
#

didn't understood what it means

#

like, was that the "-"?

#

or...?

#

this wasn't suppose to happen

sharp geyser
#

Thats the full stacktrace

#

idk anything about python though so I can't help

#

I only knew how to view the stacktrace

#

:^)

past field
#

what are all factors to having a game that can handle 50+ players?

#

it works fine for up to like 45 players

#

after that, i get an invalid webhook token error

quartz kindle
quartz kindle
#

if the error that lark generated is not enough, you need to print the contents of args before it goes into macro_grammar.parse() and try to guess what the problem is, or you need to look inside the lark source code for clues

quartz kindle
#

invalid token doesnt seem like an error caused by too many players, sounds more like a logic issue somewhere

urban delta
#

this is what is being compiled:

quartz kindle
#

otherwise make sure the program is not starved somewhere

past field
#

i’ll post it here.. and if anyone wouldn’t mind having a look it’ll be very helpful!

urban delta
#

this is my grammar

#

and i included everything from the grammar to it

#

i have no idea why that error

#

in my grammar there is k-a

#

k-zu

#

and so on

quartz kindle
#

i cant really help with lark unfortunately

#

other than that have you though of looking into using code ranges for characters instead of defining char by char?

raven parcel
#

If anyone knows how to keep my bot active, please help me.

deft wolf
#

Like... host it somewhere?

raven parcel
#

somehow keep it active

deft wolf
#

Yes, you need to rent some hosting (preferably a VPS) and have it active there

past field
past field
# pine willow ai code? o.o

most of it yes lol, i’m still learning and studying the methods and logics it creates + the documentations helps me learn how to approach things

quartz kindle
past field
#

i know it’s frowned upon and makes me illegitimate but it helps me learn

past field
quartz kindle
untold vortex
#

hey do anyone know how to make a code which sends message whenever boost the server

urban delta
#

e para japoneses

#

qual é o primeiro e qual é o ultimo?

quartz kindle
#

google is yur frend

quartz kindle
#

but i can guess why it is failing with too many players

#

how long does a game take more or less?

#

interaction tokens are valid for 15 minutes, if the game takes longer than 15 minutes, your token will become invalid

#

so what you can do is to use normal messages instead of followup messages

past field
#

the games usually only take about 5 minutes or less

past field
#

is the token valid upon command invocation? or only when the startgame function is called?

quartz kindle
#

from there on, all followup messages use the same token

past field
quartz kindle
#

button clicks are not part of the oringinal interaction, each click has its own interaction token

past field
quartz kindle
past field
pine willow
#

Do you plan to make your bot public at some point?

past field
pine willow
#

Alr

past field
#

but if i can make this game successfully then i may make another bot specifically for this game

quartz kindle
#

try it yourself, create a new game in your second server while there is a game running on the first server

sharp geyser
surreal sage
#

my biggest flex: i paid for voicemeeter

sharp geyser
#

yknow what, I've heard a lot about ruby

#

What's the appeal of it

frosty gale
#

ruby on rails

sharp geyser
#

no idea what that is tbh

civic scroll
surreal sage
#

valid sanae_yes

eternal osprey
#

I learned about various flooding attacks today and I was like fuck it let me try, I used a ping packet with a maximum fragment offset, being 65528 bytes long, together with the data gram header it equaled 65548. I thought that it was fixed in an ipv4 update so I tried it on my own vps. Turns out it still was able to buffer overflow lol.

quartz kindle
#

duh

sharp geyser
#

listen here you little shi

sharp geyser
#

emphasis on the kind of

quartz kindle
#

working on something for a client, ngl this looks cool

sharp geyser
#

I am making a bot

#

but its not a serious bot

#

what should I make it in

#

I could do js, C++, rust, C#, lua or any other language that has a maintained discord library

quartz kindle
#

LOLCODE

#

brainfuck

#

jsfuck

sharp geyser
#

oh god

#

I

#

dislike you

#

WTF IS LOLCODE

#
HAI 1.2
  CAN HAS STDIO?
  VISIBLE "HAI WORLD!!!1!"
KTHXBYE
quartz kindle
#

thats like one of the most famous ones

#

its pretty old

sharp geyser
#

can you even do any http calls with it

quartz kindle
#
HAI 1.3
  CAN HAS SOCKS?

  I HAS A local
  local R I IZ SOCKS'Z BIND YR "ANY" AN YR 12345 MKAY

  BTW get an IP address
  I HAS A addr ITZ I IZ SOCKS'Z RESOLV YR "google.com" MKAY

  BTW connect to a remote port
  I HAS A remote
  remote R I IZ SOCKS'Z KONN YR local AN YR addr AN YR 80 MKAY

  BTW send some stuff
  I IZ SOCKS'Z PUT YR local AN YR remote AN YR "GET http://www.google.com/:)" MKAY

  BTW should be "HTTP/1.0 200 OK\n"
  I HAS A data
  data R I IZ SOCKS'Z GET YR local AN YR remote AN YR 16 MKAY
  VISIBLE data

  BTW cleanup or else program will be blocked waiting for port
  I IZ SOCKS'Z CLOSE YR local MKAY
KTHXBYE
sharp geyser
#

tim

#

Don't make me make a discord library

#

for this fucking esoteric language

#

😭

quartz kindle
#

i dont need to

#

you're gonna make yourself do it

#

:^)

sharp geyser
#

no

#

I honestly do not want to learn the syntax for this

#

like wtf is this

#

I'd quite literally have to make my own websocket implementation

quartz kindle
sharp geyser
#

wtf is SOCKS

quartz kindle
#

lolcode built in sockets library

sharp geyser
#

😔

#

Ima just head out

#

I'd have to basically learn a whole LANGUAGE before I can learn that programming language

quartz kindle
#

lolcode is basically a wrapper for C

#

you write C programs with it

#

but with its stupid syntax

#

you can import any C lib

sharp geyser
#

its quite literally a C program written using an actual language as reference

quartz kindle
#

although the compiler/interpreter has been abandoned for 10 years

#

lmao

sharp geyser
#

rip

#

honestly

#

might use java

#

that way all that boilerplate will increase my lines of code

#

making me look like a pro programmer

quartz kindle
#

lmao

past field
#

thank you @quartz kindle !!

#

that game handled 66 people no issues

#

no webhook errors

quartz kindle
#

np

past field
quartz kindle
past field
quartz kindle
#

modals are unique per user

#

there is no such thing as multiple users accessing the same modal

past field
#

ah

#

hm

past field
quartz kindle
sharp geyser
#
using NCalc;

class Util
{
    public static Dictionary<string, string> TempertureFormulas = new Dictionary<string, string> {
        { "CToF", "(C * 9/5) + 32" },
        { "CToK", "C + 273.15" },
        { "FToC", "(F - 32) * 5/9" },
        { "FToK", "(F-32) * 5/9 + 273.15" },
        { "KToC", "K - 273.15" },
        { "KToF", "(K - 273.15) * 9/5 + 32" }
    };

    public static double Evaulate(string expression)
    {
        Expression express = new Expression(expression);
        var result = express.Evaluate();
        return Convert.ToDouble(result);
    }
}

@scenic kelp how do you like my C# code

#

💀

scenic kelp
#

that certainly is C# code

sharp geyser
#

oh also

#
switch (conversion)
        {
            case "F":
                {
                    if (Util.TempertureFormulas.TryGetValue("CToF", out string formula))
                    {
                        await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"Celsius To Fahrenheit: {Util.Evaulate(formula.Replace("C", value))}"));
                    }
                    break;
                }
            case "K":
                {
                    if (Util.TempertureFormulas.TryGetValue("CToK", out string formula))
                    {
                        await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"Celsius To Kelvin: {Util.Evaulate(formula.Replace("C", value))}"));
                    }
                    break;
                }
        }
#

Well fuck you discord for formatting it tht way

#

Thats better

scenic kelp
#

kinda unnecessary to use a switch

sharp geyser
#

fair

#

I honestly have 0 clue what I am doing

#

This is my first time using C# in like 2 years

#

Anything else you recommend doing here other than not using a switch statement?

#

I feel like this is going to get repetitive, as I will be doing not only temps but also units of measurements

scenic kelp
#

i'd just use an if

sharp geyser
#

👍

#

Ah nvm

#

its just telling me its a version compatibility issue I think

scenic kelp
#

yeah it's not got net8.0 listed as compatible probably

#

should still work

sharp geyser
#

ye

#

kind of annoying it spams the console with it

#

but whatever

#

also is it okay to do Dictionary.TryGetValue(key, out string? value)

#

or should I not put the ?

scenic kelp
#

it's not necessary unless it's a Dictionary<string?>

#

i think

sharp geyser
#

ic

scenic kelp
#

actually you might need it

sharp geyser
#

Just wondering cause it sends a warning that I am converting a non-null type

scenic kelp
#

yeah if it's got a warning you can do that

#

or you can do out string! value

#

to tell it to fuck off

sharp geyser
#

yea I tried that as well

#

but it can't be used inside of the TryGetValue method it seems

scenic kelp
#

cause technically you can still access value even if the TryGet returns false

sharp geyser
#

so ig ? it is

sharp geyser
#

yea

#

It tells me it can't be used inside this context

scenic kelp
#

wack

#

ig stick with string? then

sharp geyser
#

alrighty thanks 👍

scenic kelp
#

that's actually kinda annoying

sharp geyser
#

I wonder why it doesn't allow it

scenic kelp
#

it makes sense because it's technically not a type thing it's an actual operator

#
string balls = "";
if (dict.TryGetValue("balls", out balls!)) {
    balls.ToArray();
}
``` so you could do that
#

but it takes an expression as an input not a type like ? does

#
if (dict.TryGetValue("balls", out string? balls)) {
    balls!.ToArray();
}
#

that's your other alternative

#
if (dict.TryGetValue("balls", out string? balls)) {
    if (balls is null) throw new NullReferenceException();
    balls.ToArray();
}
``` or the "good boy" way of doing it
sharp geyser
#

Welp

lyric mountain
#

You're legally obliged to add bananas and bald eagles units

#

And football fields

sharp geyser
#

no

#

please

#

no

#

Also

#

How the fuck do I convert that long ass decimal to just 26.85

#

Floor will just cut off the decimal

#

Actually is it even important to use decimals in temps?

#

Ima just floor it

sharp geyser
#

nvm

#

it wasn't the proper type

#

💀

lyric mountain
sharp geyser
#

it has a special overload that lets me specify the decimal places to display

lyric mountain
#

Well, yeah

north turtle
#

I'm implementing a music playing function.
However, it is very unstable to run as a single process.
If an error occurs while playing music on one server,
All servers that were playing music also stop playing.
Is there any way to solve this?

#

I've heard the word sharding, but I'm not sure if it's right to use it in this case.

#

Additionally, I am currently creating and running one child process per server, but it feels like a huge waste of resources.

pearl trail
#

lavalink? ytdl?

north turtle
#

ytdl and got
got is used for soundcloud, url like https://domain.com/file.mp3, message attachment

surreal sage
#

i copied the code for some component from hexta ui

#

and holy shit there are so many type errors

#

there was an entire interface under the imports that was unused

#

fucked function definition orders.. no useCallback hooks

#

etc

#

and Array.forEach

#

wow

#

this is 2024

#

who even uses .forEach anymore

#

aaaaaaaaaaaaa

#

dies inside

quartz kindle
surreal sage
quartz kindle
#

dafuq is that

frosty gale
quartz kindle
#

i cant take react seriously

#

the syntax is just so weird

eternal osprey
#

i want tio learn react this summer i think

tribal axle
#

how can i get the total votes ?

frosty gale
#

you can either learn angular or svelte

eternal osprey
frosty gale
#

react is a curse

neon leaf
#

Can confirm as react dev

#

If U need jsx / tsx use solidjs

lyric mountain
#

honestly, flutter aint that bad as a react replacement

neon leaf
#

Depends on use case

lyric mountain
#

front end

neon leaf
#

Well yes but like

#

What kind of app you are building can decide what you can't use

civic scroll
#

framer-motion my beloved

neon leaf
#

Well I'm too deep in now

#

So I can't get away

civic scroll
surreal sage
#

missing the | null though

neon leaf
surreal sage
#

whats that

neon leaf
#

Wakatime

surreal sage
#

damn

#

too bad i hadnt installed it earlier

civic scroll
surreal sage
civic scroll
surreal sage
civic scroll
surreal sage
#

useRef<T>(defaultValue)
MutableRef<T | typeof defaultValue>

civic scroll
#

damn

surreal sage
#

smthn like that ig

civic scroll
#
export type Nullable<T> = T | null;
surreal sage
#

`ts Troll

civic scroll
#

i'm on phone

surreal sage
#

im on chair

civic scroll
#

hi on chaie

neon leaf
#

I'm on bus chair

sharp geyser
#

hello peepers, I have a question on how I should handle evaluations.

I have multiple maps with different formulas. I have to query the maps for the formula I am wanting to use and then call an Evaluate method to evaluate the math expression.

As it stands now, I think it is messy with how I am doing it, as I don't want to make multiple evaluate methods to handle roughly the same code as all i'd be doing is changing the depth of the decimal place depending on what formula is being evaluated.

My first idea was to just have a depth field and a key field in the evaluate method, and just query the dictionary based on the depth and key but I am not sure.

    public static string Evaluate(string key, string expression, int depth = 2)
    {
        if (depth == 2)
        {
            // Grab from the TempertureFormulas dict using the `key`
            Expression express = new Expression(expression);
            var result = express.Evaluate();

            return Convert.ToDouble(result).ToString("F2");
        }
        else if (depth == 4)
        {
            // Grab from the UnitFormulas dict using the `key`
            return Convert.ToDouble("1234").ToString("F4");
        }

        return "NaN";
    }
#

This seems extreamly messy, as once I start multiple different points of conversions besides Units of Measurements & Tempertures it will get rather weird to handle, as not every conversion makes sense to have say 2 decimal places, or 4 decimal places.

#

This is C# btw

past field
#

I can't seem to get modal form submissions to go through for anyone, I don't get any errors in console logs or from the bot itself, the modal form just says "Something went wrong. Try again." bot doesn't shut down or anything https://pastes.dev/tiwwaUhueS

deft wolf
#

Personally, I would use awaitModalSubmit() because I doubt that the modal will be treated in the same way as buttons, e.g. (createMessageComponentCollector())

past field
#

ahh that makes sense! thank you

#
const filter = (interaction) => interaction.customId === 'modal';
interaction.awaitModalSubmit({ filter, time: 15_000 })
  .then(interaction => console.log(`${interaction.customId} was submitted!`))
  .catch(console.error);
lyric mountain
sharp geyser
#

That doesn't seem to have anything to do with what I am asking

lyric mountain
#

u want to have automatic precision no?

sharp geyser
#

Not really (kind of)

lyric mountain
#

then I read it wrong, lemme reread it

sharp geyser
#

I can just summarize it

#

Essentially I want to find a way to easily evaluate based off any expression. I have maps of formulas for different types of conversions. E.g Formulas for temp conversion, and also units of measurements. Problem is, each different formula requires different decimal precision (so ig you are right I am looking for automatic precision) but I also I am finding myself writing lengthy if statements to make sure I am evaluating the appropriate formula, which is not ideal.

lyric mountain
#

oh, well, can't u just have a dict of precision <-> classes?

sharp geyser
#

How do you mean?

lyric mountain
#
{
  1: Class1,
  2: Class2,
  3: Class3,
}
#

for precision 1, use Class1

#

for 2, use Class2

#

and so on

sharp geyser
lyric mountain
#

then just dict[depth].SomeInterfaceMethod(expression)

sharp geyser
#

Well, automatic precision is probably better than doing it that way ngl

#

My issue is, I have multiple dicts of different formulas

#
    public static Dictionary<string, string> TempertureFormulas = new Dictionary<string, string> {
        { "CF", "(C * 9/5) + 32" },
        { "CK", "C + 273.15" },
        { "FC", "(F - 32) * 5/9" },
        { "FK", "(F-32) * 5/9 + 273.15" },
        { "KC", "K - 273.15" },
        { "KF", "(K - 273.15) * 9/5 + 32" }
    };

    public static Dictionary<string, double> UnitFormulas = new Dictionary<string, double> {
        { "FM", 1 } // Feet to Meters
    };

I have yet to fully write out the UnitFormulas dict, but the gist is, I will end up having to query each dict and then grab the formula, replace the placeholder and evaluate it

#

Which can get messy

#

For example,
/feet can convert feet to numerous amounts of measurements, Centimeters, Meters, Kilometers, Miles, etc etc

#

I'd have a big chain of if/else if statements

#

That seems not ideal

lyric mountain
#
var dicts = {
  2: TempertureFormulas,
  4: UnitFormulas,
}

...
dicts[depth][key]
sharp geyser
#

That could work yes

#

I was using TryGetValue simply because its the "safer" method

lyric mountain
#

well, yeah use it

#

as [key] will throw a NPE if [depth] returns null

sharp geyser
#

I'd have to chain the TryGetValue then

#

💀

lyric mountain
#

nope

sharp geyser
#

wym nope

lyric mountain
#

tryget the depth

sharp geyser
#

Ah wait

#

yea

lyric mountain
#

then check if key returns null

#

btw, it'd be easier for u if u used a yaml file for it

sharp geyser
#

I guess C# doesn't have an any type

lyric mountain
#

it does

#

object

sharp geyser
#

oh right

lyric mountain
#

or dynamic

#

or was it auto?

#

yep, dynamic

sharp geyser
#

Guess I can't use dynamic here

#

It can't convert the Dictionary Types to string, dynamic

lyric mountain
sharp geyser
#

nope

lyric mountain
#

well, then use object

sharp geyser
#

Same thing

lyric mountain
#

then smth is wrong

sharp geyser
#

@scenic kelp C# person, explain :D

lyric mountain
#

I've used maps with dynamics and objects before

sharp geyser
#
The best overloaded Add method 'Dictionary<int, Dictionary<string, dynamic>>.Add(int, Dictionary<string, dynamic>)' for the collection initializer has some invalid argumentsCS1950
Argument 2: cannot convert from 'System.Collections.Generic.Dictionary<string, string>' to 'System.Collections.Generic.Dictionary<string, dynamic>'
#

I guess its due to mainly this

lyric mountain
#

no error

#

aside from the hint there to use var

sharp geyser
#

I don't understand the use of var tbh

lyric mountain
#

oh wait, how are u applying it?

lyric mountain
sharp geyser
lyric mountain
#

well, yes u cant do that

sharp geyser
#

oh wait

#

string -> int

#

my bad

lyric mountain
#

lmao

sharp geyser
#

actually nvm

#

read the wrong dictionary type

lyric mountain
#

set the top ones to dynamic too

#

or set the dict-dict to int string

sharp geyser
#

so dynamic is just like "Idk the type rn, figure it out at runtime" ?

lyric mountain
#

yes

#

literal any

sharp geyser
#

gotcha

lyric mountain
#

btw I do recommend setting up a yaml structure like I mentioned before

#

it'll be easier for u and reduce boilerplate

sharp geyser
#

I will eventually

#

Right now I jsut want a proof of concept

#

😭

#

I also dk how to read yaml files in c#

lyric mountain
#

can also use whatever format u prefer

#

yaml is just pretty fit for the task

sharp geyser
#

ic

#

I wonder

sharp geyser
#

I mean, I can use NCalc, but I am only wondering because I am noticing I am basically repeating other expressions inside an expression

#

like to convert K to F, I have to first convert K to C, then C to F

#
tempeture:
  CF: "(C * 9/5) + 32"
  CK: "C + 273.15"
  FC: "(F - 32) * 5/9"
  FK: "(F-32) * 5/9 + 273.15"
  KC: "K - 273.15"
  KF: "(K - 273.15) * 9/5 + 32"

KF -> KC * CF

#

Idk if thats something I should care about

#

but readability wise maybe?

#

I don't know Hmm

lyric mountain
#

CK is wrong btw

#

KC too, they're inverted

lyric mountain
sharp geyser
#

1 Celsius = 274.15

#

so that math is correct

#

2 C = 2 + 273.15 = 275.15

sharp geyser
#

I'd need to grab the other formulas and pass in the appropriate values

#

I'd like to figure out how to make my own parser

eternal osprey
#

Who wants to beta test my AI training power usage and efficiency metrics zoomeyes

#

Spent a whoppin 2 weeks on that bitch

sharp geyser
#

Sure

#

tell me what I need to do

eternal osprey
#

now evaluation does not only rely on accuracy etc, but power consumptation too. Lets get AI environment friendly lads

eternal osprey
sharp geyser
#

I still haven't been able to touch the ai model you made for me

#

💀

#

Got super busy with family, and then another project grabbed my eye

eternal osprey
#

hahahah crazyyy

#

disprespecting my work like that

sharp geyser
#

Sorry man 😔

scenic kelp
sharp geyser
#

Im not anymore

#

decided it was stupid

sharp geyser
#

AI is just wayyyy over my head

#

Idek how to read the code you wrote

scenic kelp
#

also you just can't use dynamic as type arguments

#

because dynamic doesn't have a specific size

#

generics are a compile time mechanism and dynamic is a runtime one

eternal osprey
sharp geyser
eternal osprey
#

You are still using the neural network i sent you right?

#

Yeah we are

sharp geyser
#

Yup

eternal osprey
#

You can actually make it better using GloVe or whatever it's called but the download process was hella slow so i gave up.

sharp geyser
#

I played around with it a bit but got busy

eternal osprey
#

Yeah, you can change the hyperparameters as well, but iirc i applied gridsearch on it to find the "most optimal" tuning.

scenic kelp
#

also you should realistically never be using dynamic in actual C# code

#

the only time dynamic should ever be used is interfacing with other .NET languages that are dynamically typed

sharp geyser
#

👍

#

so dynamic is unsized?

scenic kelp
#

yes

#

because it's not an actual type

sharp geyser
#

so its quite literally just a placeholder

#

and it takes on the type depending on whats passed to it

#

but at compile time thats not good right?

scenic kelp
#

generics are static placeholders, i.e. compile time ones, whereas dynamic is a runtime one

#

it defers type checks to the run time

quartz kindle
#

dynamic = js

scenic kelp
#

actually dynamic dictionaries seem to work fine huh

#

still, don't do that

sharp geyser
scenic kelp
#

there's technically a couple of types in C# that don't inherit from System.Object

#

i'm sure those would fuck it up

#

if you're really doing scuffed things, just use object

sharp geyser
#

well

#

now im trying to figure out how to make a math parser

scenic kelp
#

math parsers are pretty simple

sharp geyser
#

yuh

#

to you maybe

#

to me its a foreign concept

#

Never made a parser before

scenic kelp
#

no they are like objectively the easiest type of parser to make

#

you could technically get away without tokenizing first but a good first goal would be to make a tokenizer

sharp geyser
#
tempeture:
  CF: "(C * 9/5) + 32"
  CK: "C + 273.15"
  FC: "(F - 32) * 5/9"
  FK: "FC + 273.15"
  KC: "K - 273.15"
  KF: "KC * CF"

My only goal is to support nested formulas such as KF

scenic kelp
#

something that converts like
2 + 3 * (4 / 2)
into

Number(2) Operator(+) Number(3) Operator(*) LParen(() Number(4) Operator(/) Number(2) LParen()) EOF()
#

then you write parser rules using those tokens which is a lot easier than having to deal with raw characters

#

your parser takes the token stream and makes a tree

#

then to evaluate your expression you visit every node in the tree and evaluate that

#

number nodes evaluate to their value, operator nodes operate to value of lnode op value of rnode

sharp geyser
#

uhm

#

Sureeeeee

scenic kelp
#

your goal is to make an expression into a tree

#

that's it

sharp geyser
#

uhm

#

well

#

how do I even start

#

Like I said

#

I've never done even a basic parser

scenic kelp
#

that expression has a tree like that

sharp geyser
#

so idek where to start

scenic kelp
#

group your objects into tokens and think in terms of a grammar

#

operators like +, -, *, / operate on two values

sharp geyser
#

Right theory I understand, but programming no.

scenic kelp
#

so they're binary operators, we can define them in a grammar as
expression binary_op expression

sharp geyser
#

I guess first step is just taking in an expression

scenic kelp
#

tokenizing!!!!

#

let me continue

sharp geyser
#

Then looping over that expression, breaking it up, and tokenizing it

scenic kelp
#

you want to tokenize first

#

anyways your expressions will basically be either a binary operator expression, a number, or another formula

#

so start with that, your tokenizer should be pretty simple

#

you just loop over your input and output tokens for numbers, operators, and formulas

sharp geyser
#

C# has enums right

scenic kelp
#

yes, i normally use static strings though

sharp geyser
#

oh?

#

Why that over enums

scenic kelp
#

better for interop and printing etc

sharp geyser
#

I've always seen people use Enums

scenic kelp
#

it's a personal preference but you incur a quite significant performance cost when you stringify enum values into their names etc

sharp geyser
#

How exactly would static strings work

scenic kelp
#

which doesn't matter in the end but also you incur a huge portability cost

#

just a static class

#
class Token {
    public string TokenType { get; init; }
    ...
    static string TOKEN_PLUS = "Plus";
    static string TOKEN_MINUS = "Minus";
}
``` or just build it into the token class
#

you're technically losing some type safety

#

but i've never had it be an issue

sharp geyser
#

get; init;?

#

I know what get is

#

it sets it as a getter

#

but what is init?

scenic kelp
#

init is a setter that only lets it get set once in the constructor

sharp geyser
#

I see

#

also there is private gets and sets right?

#

or am I misremembering

scenic kelp
#

yes

#
class Token {
    public string TokenType { get; private set; }
    ...
    static string TOKEN_PLUS = "Plus";
    static string TOKEN_MINUS = "Minus";
}
sharp geyser
#

and that means it can only be set inside the class Token right?

scenic kelp
#

yep

sharp geyser
#

or can it also be done in inherited classes

scenic kelp
#

not with private

quartz kindle
#

just make a huge nested switch case

#

job done

sharp geyser
#

For some reason tim

#

I dont trust that

scenic kelp
#

now technically that is probably the most performant way of writing a lexer

#

but yknow

quartz kindle
#

i mean

#

its a small thing

scenic kelp
#

state machines are not exactly super readable

quartz kindle
#

literally maximuim 3 depth

scenic kelp
#

yeah

quartz kindle
#

max number of symbols is like 4

#

thats what i did

scenic kelp
#

don't do that, performance will be more than acceptable with a basic lexer

sharp geyser
#

Right parm

scenic kelp
#

typically i build pretty 'stupid' state machines but with a switch in the main parser method

#

then call other methods for processing things like strings and numbers

sharp geyser
#

do you know any articles I can read to do this

#

or should I literally just go with the flow

scenic kelp
#

i forget what resources i've used

#

but honestly go with the flow

sharp geyser
#

😔

scenic kelp
#

if you have any questions or get stuck i'm here

sharp geyser
#

Alright

#

to break it down in ways I understand

scenic kelp
#

until my lens adapter gets here then i'm going and taking photos but

quartz kindle
#

i just made a bunch of switch cases to handle every possible string combination

#

this is what my data looks like, its not much different from what you have

scenic kelp
#

oh god

sharp geyser
#
  1. Tokenizing - Grabbing the expression, breaking it down using some kind of split method and then tokenizing the individual components
  2. Parsing it and evaluating it?
scenic kelp
#

parsing and evaluating are technically separate steps

#

easier that way, you could technically combine them but

#

the pipeline is quite flexible depending on what you're writing

#

but otherwise yes, your tokenizer takes a complex stream of characters and abstracts it into tokens

#

which makes your parser MUCH simpler because it can operate on much more well-defined inputs

sharp geyser
#

Honestly dk how I'd do this without the use of enums

scenic kelp
#

what did you want enums for

#

token types?

sharp geyser
#

Ye

#

actually nvm

#

Im dumb

scenic kelp
#

you can use enums i was just saying i personally prefer strings in most cases

sharp geyser
#

ignore me

scenic kelp
#

if you wanted to be really cool and awesome you could also use derived classes from a Token base but

#

that's too much work for my shitty lexers

#

your token class basically just needs to store the character content and the type

sharp geyser
#
class Token
{
    public string TokenType { get; init; };
    static string TOKEN_PLUS = "Plus";
    static string TOKEN_MINUS = "Minus";
    static string TOKEN_DIVIDE = "Divide";
    static string TOKEN_MULT = "Mult";
    static string TOKEN_LPAREN = "LParen";
    static string TOKEN_RPAREN = "RParen";
}

Then I can have a Tokenizer class that has a dictionary of tokens, and then that would have a method that takes in a expression, breaks it down into components, and associates a token with that component and adds it to the dictionary right?

scenic kelp
#

uhhhhh

#

i would not use dictionaries for that at all

sharp geyser
#

ic

scenic kelp
#

it could probably work but

#

normally the easiest thing to do is just have a tokenizer class with a method that takes in a string and returns a List<Token>

sharp geyser
#

I see

scenic kelp
#

you're basically writing a state machine

sharp geyser
#

no idea what that is

#

also, apparently you cant use ; after that TokenType field

scenic kelp
#

oh yeah did i do that

#

no semis after properties

#

you don't need them

sharp geyser
#

really?

scenic kelp
#

no i didn't do that

#

ok good

eternal osprey
#

using c/c++ as oop should be a crime

scenic kelp
#

i would have looked very uncredible

#

C++ was literally designed to be object oriented wdym

sharp geyser
#

then why do ; after TOKEN_PLUS

eternal osprey
#

nah java on top

scenic kelp
#

you need that

sharp geyser
#

but its a property

scenic kelp
#

buddy 😭

#

no token_plus is a field

sharp geyser
scenic kelp
#

ok so

sharp geyser
#

whats the difference between TokenType and the rest?

scenic kelp
#

if there's no { get; set; } bullshit going on

#

it's a field

#

otherwise it's a property

sharp geyser
#

What is the difference between a property and a field then

scenic kelp
#

properties are just a really convenient shorthand for getter and setter methods

eternal osprey
#

Aaron is always internally fighting for his life when learning new things 😭

sharp geyser
#

cuz I always used the both interchangeably

scenic kelp
#

so we're not doing the java thing of having fucking ugly code

sharp geyser
scenic kelp
#
String thing;

String getThing() {
    return thing;
}

void setThing(String thing) {
    this.thing = thing;
}
eternal osprey
#

i am not clowning you btw, or calling you out. Just something i found funny to see hahah

scenic kelp
#
string thing {get; set;}
eternal osprey
#

me myself, i am also always on the verge of suicide when learning new concepts

scenic kelp
#

which is cleaner

sharp geyser
#

It takes me a sec for my brain to click what is being said to me.

scenic kelp
#

let's not talk about the full form for C# properties because it's just as bad

#
string _thing;
string Thing
{
   get { return _thing; }
   set { _thing = value; }
}
#

basically that's what the { get; set; } does for you automatically!

sharp geyser
#

icic

scenic kelp
#

now the motivation behind using properties is iffy but basically a) you get better access control and b) you can do validation in the setters

#

a) is very valid, literally never done b)

#

oh and because they're methods they're part of the public interface of your class so that's your c)

sharp geyser
#

Also

#

Should I be using static methods for my tokenizer?

scenic kelp
#

i would say no because you can keep the input and output as instance variables

#

it's a design decision basically

sharp geyser
#

TokenType I assume would be one of the TOKEN_PLUS type stuff right?

#

So a Token would have TokenType and Value right?

scenic kelp
#

yes

sharp geyser
#

So I would have to do something like

#

Also, wait

#

since the static fields are private how do I create the token?

scenic kelp
#

oh right yeah they need to be public

sharp geyser
#

Oh bout to say

scenic kelp
#

i noticed that before but i forgot to correct myself oopsies!!

sharp geyser
#

Was I doing something wrong

#

😭

scenic kelp
#

i'm so not used to the new list initializer syntax it feels so weird to me

sharp geyser
#

How should I determine the token type?

#

Side note, this is kind of making me want to make my own language

#

💀

scenic kelp
#

see that's what i'm saying

#

anyways for that you can basically instantly feed your operators into a token

#

you've only got numbers and formulas now right, so if the first character is a number it must be a number

#

you can blindly trust that or you can do a sanity check and check the other characters in the string to make sure

sharp geyser
#

Right, but how do I determine that its a number, or its a +, -, /, *

scenic kelp
#

well you have the string

#

also actually you might be better off looping over the characters rather than using split

#

think of the case where you have like --2 (we don't have unary operators yet but)

#

it should be tokenized as Minus(-) Minus(-) Number(2)

sharp geyser
#

Right

#

But my main concern is, yes I have the string, but how exactly do I determine its a minus

#

or its a plus

#
class Token
{
    public required string TokenType { get; init; }
    public required string Value { get; init; }
    public static string TOKEN_PLUS = "Plus";
    public static string TOKEN_MINUS = "Minus";
    public static string TOKEN_DIVIDE = "Divide";
    public static string TOKEN_MULT = "Mult";
    public static string TOKEN_LPAREN = "LParen";
    public static string TOKEN_RPAREN = "RParen";
    public static string TOKEN_NUMBER = "Number";
}

because the prop names aren't exactly easy to determine as such

#

How would I go from
"2 + 2" -> Number(2) Plus(+) Number(2)

scenic kelp
#

you check in your method

sharp geyser
#

right

#

how

scenic kelp
#

with a switch or an if

sharp geyser
#

oh wait

#

duh

#

😭

scenic kelp
sharp geyser
#

idek what it does

#

it just is something vscode did itself

scenic kelp
#

when you initialize a class with

Token t = new Token { TokenType = Token.TOKEN_PLUS }
``` it would give you an error
#

because you're missing Value

sharp geyser
#

gotcha

#

so its an extra type safety

#

because else it'd be seen as nullable right?

scenic kelp
#

null safety yeah

#

because nullability was shoved into the language only a couple of years ago

sharp geyser
#

Ok

#

so I have a general idea on what to do now

#
switch (components[i]) // or would it be the typeof? idk {
  case "+": {
    // create the plus token
  }
}
#

idek how i'd handle numbers

#

if I was to go based on typeof, i'd need a nested switch right?

#

well no

scenic kelp
#

typically in that case when i read a number i'd create a different method in the tokenizer class that's PURELY for reading that number

sharp geyser
#

nvm

sharp geyser
#

Splitting it off and making it more readable comes later

scenic kelp
#

then you'd just use a different loop

sharp geyser
#

lest I confuse myself

scenic kelp
#

are you still using a for loop with the split actually

sharp geyser
#

as of rn yes

scenic kelp
#

hm

#

depending on how much you care about error resilience

sharp geyser
#

error resilience?

scenic kelp
#

you could just see the first character is a number and go "yeah that means this is a number"

#

but obviously 123NUMBER is not a number

sharp geyser
#

I'd like to go the route that makes the most sense

#

and is in line with "proper" procedures

scenic kelp
#

imma keep it real with you i have no idea what is proper

#

i just have my own bones for it

sharp geyser
#

ok

#

How would you do it then

scenic kelp
#

i think it's easier to loop over the characters without splitting them because then you can handle cases like ++

#

and then it also makes it easier to, when you read a number, call a different method specifically for handling reading a number

sharp geyser
#

gotcha

#

what's the easiest way to loop over a string?

scenic kelp
#

it has its own while loop and only consumes the parts so 123NUMBER would get parsed as Number(123) Identifier(NUMBER)

#

i always use a while loop and manually advance it

sharp geyser
#

just

for (int i = 0; i < string.Length; i++ ) {}
```?
scenic kelp
sharp geyser
#

I see

#

never really touched while loops tbh

#

idek how they really work

scenic kelp
#

it's a bit more error prone because you have to remember to advance them but

#

for loops are just sugar over while loops

#
for (int i = 0; i < s.Length; i++)
{ ... }
``` is just sugar for
```cs
int i = 0;
while (i < s.Length) 
{
...
i++;
}
sharp geyser
#

I see

#

so what do you mean manually advancing it?

scenic kelp
#

like for example with plus

#
...
case '+':
    tokens.Append(new Token { Value = input[i++], TokenType = Token.TOKEN_PLUS);
    break;
#

notice how i use i++

#

(in reality i should be a class property and not a local variable so you can advance from the other methods but)

sharp geyser
#

Wdym class property

#

You can do that?

scenic kelp
#

like it should be on the class

#

not a local variable

sharp geyser
#

I didn't know you could do that

#

How exactly does that work in the case of starting where you left off in other methods?

#

For example, I have a method for parsing a number, I call it parse that number, and then now I return back to the main method and parse the plus

scenic kelp
#
class Token {
   int pos;
}```
sharp geyser
#

how do I now to start after the number

sharp geyser
#

oh I see

scenic kelp
#

your number method takes care of that

#

you can do something like,

  1. store the starting position
  2. iterate until the next character is no longer a number
  3. get the substring and create a new token
  4. advance the position to the end point
  5. return the token back to the call point in the main method
sharp geyser
#

Alright

#

let me see if I can get this to work

sharp geyser
#

but I have another question ram_heh

scenic kelp
#

😡🤬🤬🤬😡🤬🤬🤬😡🤬🤬🤬🤬

sharp geyser
#

sorry ;c

scenic kelp
#

my reaction to being pinged on discord

sharp geyser
#

sorry

scenic kelp
#

anyways ask away!!!

sharp geyser
#

I am working on parsing numbers first, since that seems the hardest.

I made a prop called startingPos on the Tokenizer class to keep track of the position to start at. Now, when calling the TokenizeNumber method I made which handles tokenizing the number, I need to take in the expression used, and then loop over it at that startingPos and once I reach something that isn't a number, update that startingPos and exit the function returning the new Token correct?

scenic kelp
#

nah you'd want to keep it in the method since you only care where it starts in the method

#

like in your method you just keep track of int start = pos

sharp geyser
#

but you said every method needs to know where to start next

scenic kelp
#

yeah, that's what the pos is for on your class

#

that way, when you're done in the number method pos is advanced past the number token

sharp geyser
#

I am confused

#

Is that not what I am doing?

#
class Tokenizer
{

    int startingPos = 0;
    public List<Token> Tokenize(string expression)
    {
        List<Token> tokens = [];

        while (startingPos < expression.Length)
        {
            char currentItem = expression[startingPos];

            if (Char.IsDigit(currentItem))
            {
                tokens.Append(TokenizeNumber(expression));
            }

            switch (currentItem)
            {
                case '+':
                    {
                        tokens.Append(new Token
                        {
                            TokenType = Token.TOKEN_PLUS,
                            Value = currentItem,
                            Position = startingPos
                        });
                        break;
                    }
            }
        }

        return tokens;
    }

    Token TokenizeNumber(string expression)
    {

    }
}
scenic kelp
#
blah blah 23 + 2
          ^
``` that's the position when you go into the function
#
blah blah 23 + 2
            ^
``` that's the position when you exit it
#

so that the next loop of your main function, it reads the whitespace after

sharp geyser
#

I think I may be doing it entirely wrong then

#

cause that above is how I am currently calling my TokenizeNumber method

#

and how I plan on treating it

scenic kelp
#

you can rename startingPos to pos

#

the startingPos in your tokenize is just a temporary measure so you know where to take the substring from

sharp geyser
#

so have int pos = 0 at the class level, and then inside the Tokenize method have int startingPos = pos?

scenic kelp
#

yeah

#

then you're literally only using it when you make the token so you can take the substring

sharp geyser
#

so even in the Tokenize method I am updating pos right not startingPos?

scenic kelp
#

yep

sharp geyser
scenic kelp
#

pos is basically where the current token you're reading is

#

it's the cursor in your text editor

sharp geyser
#

right but how would that work

scenic kelp
#

think of it like that

sharp geyser
#

int startingPos = pos sets the current value of pos

#

so updating pos doesn't update startingPos does it?

scenic kelp
#

no

#

you don't want it to

sharp geyser
#

oh?

scenic kelp
#

then you take a substring from startingPos to pos

#

think of it as a text editor analogy

#

you've got a math expression open in notepad

#

and you're really stupid or something and can only read the one character your cursor is at

#

when you see a number, you go ahead and start highlighting it

#

we're "highlighting" it by recording the position at which it starts, and we already know the position where it ends because we know the next character isn't a number at pos

#

bad analogy but whatever

#

i thought it was better when i started it

sharp geyser
#

I get it

#

so should I still be passing in the entire expression or should I pass in only from the starting position to the end of the expression to the TokenizeNumber method?

scenic kelp
#

you don't pass anything into your tokenize method

#

because all the data it needs is on the class

sharp geyser
#

What

scenic kelp
#

the input string, and the current position

sharp geyser
#

How exactly are you envisioning this

scenic kelp
#

(which you should make the input string a class field btw)

sharp geyser
#

because what I am doing is passing in the expression to the Tokenize method

scenic kelp
#

true

#

you should probably move that to the constructor

#

it would only really make sense to pass it directly to the tokenize method if it were static

sharp geyser
#

gotcha

#

so basically public string Expression {get; init;}

scenic kelp
#

yeah

sharp geyser
#

and when I am calling the TokenizeNumber method, I make a substring inside it of the current position and the end of the expression and loop over that?

scenic kelp
#

the end of the number specifically

sharp geyser
scenic kelp
#

because your goal is to find where the number ends

#

that's what that method does

#

it knows where it starts, because it got called

sharp geyser
#

How do I know the end of the number without looping over it first

scenic kelp
#

you do loop over it

#

which is why we store the start point

sharp geyser
#

right...I guess I am not explaining what I am saying properly

scenic kelp
#

that method has its own little loop

sharp geyser
#

yea

scenic kelp
#
start point = current position
while current position is number:
    current position++
number = input.substring(start point, current position)
return the token
``` there's the pseudocode probably with 2 different off-by-one errors
sharp geyser
#

right

#
    Token TokenizeNumber()
    {
        int startingPos = pos;

        while (Char.IsDigit(Expression[startingPos]))
        {
            pos++;
        }

        string number = Expression.Substring(startingPos, pos);

        return new Token
        {
            TokenType = Token.TOKEN_NUMBER,
            Value = number,
            Position = pos
        };
    }

This seems a little off

#

but this is what my brain came up with

#

My biggest concern is the while loop won't actually go beyond the startingPos will it?

#

so it'd just read one character and then move on to making the substring

scenic kelp
#

use pos instead of starting pos in the loop

sharp geyser
#
Token TokenizeNumber()
    {
        int startingPos = pos;

        while (pos < Expression.Length && Char.IsDigit(Expression[pos]))
        {
            pos++;
        }

        string number = Expression.Substring(startingPos, pos - startingPos);

        return new Token
        {
            TokenType = Token.TOKEN_NUMBER,
            Value = number,
            Position = pos
        };
    }
sharp geyser
#

so that instead?

scenic kelp
#

in the first

sharp geyser
#

huh

#

ah

#

nvm I understand what you mean

#

I was testing my current implementation and logging the results of Tokenize and it seems to hang and not finish as it never outputs the list of tokens

#

am I blind and missing something?

#

yea

#

I've caused some problems

#

It's just spamming the TokenizeNumber method

#

I see, its never moving past the 2

#

huh, how is the starting position 1

#

I solved it

#

in the Tokenize method I have no need to make a startingPos variable

#

I can just directly use pos

scenic kelp
#

yeah you don't need a startpos for tokenize

#

because that's the main one, you only need it for when you're doing things like you did in the number one

#

technically think of the main one as stupid, it doesn't really know how to parse anything other than your simple one-character tokens

#

it calls on other people to do that for you

#

your other methods

#

anyways my lens adapter got here im going to shoto photos bye

sharp geyser
#

Love to see the photos

frosty gale
#

i swear ubuntu is turning into windows but for linux when it comes to privacy and foss

#

thanks canonical

#

think im just going to stick with pure debian in that case