#πŸ”’ I started Python back in April, I've done my best to make this as minimal and simple as possible.

109 messages Β· Page 1 of 1 (latest)

old iris
#

How did I do? The entire purpose of this is to simplify my life as a reverse engineer working and testing different DLLs, all this does is make it so I can move the newly compiled DLL to the directory, and also allows me to also test the DLL by launching the game right then and there.
https://paste.pythondiscord.com/MBAA

dull sandBOT
#

@old iris

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

old iris
#

(Reposted as it was shut and nobody responded)

merry socket
#

on first glance it looks fine

#

curious why you decided to alias Path as P and send2trash as recycle

#

i would split launch_program() into launch_client() and launch_server() as the logic is technically entirely separate

#

the type in def delete_old_dll(type): doesn't really describe much (and actually overwrites a builtin). i would rename it to something like move_after_deletion and replace if type == 1: with if move_after_deletion:

#

ClientStr and ServerStr don't look like they're used anywhere

#

shutil.copy(NewDLL, ServerPath / OldDLLName) can be replaced with shutil.copy(NewDLL, OldDLL) since they refer to the same path anyways

old iris
old iris
old iris
merry socket
old iris
#

since

def launch_program(num):
    if num == 1:
        subprocess.Popen(str(ServerLaunchBat), shell=True, cwd=ServerLaunchBat.parent)
    elif num == 2:
        subprocess.Popen(str(ClientLaunchBat), shell=True, cwd=ClientLaunchBat.parent)

is the same

#

Just different variables

merry socket
#
def launch_server():
    subprocess.Popen(str(ServerLaunchBat), shell=True, cwd=ServerLaunchBat.parent)

def launch_client():
    subprocess.Popen(str(ClientLaunchBat), shell=True, cwd=ClientLaunchBat.parent)
old iris
#

Yeah I'm saying why make them into two functions

#

Also just realized a way to make it even more optimized and smaller

#

gonna do that rq

merry socket
#

in my mind i think of those two of doing different things so i'd split them into different functions

misty thorn
old iris
hearty niche
#

with python you can use r'' to not need to do all the inverted slashes if you prefer

#

something = Path(r'C:\Program Files\whatever')

#

renaming Path to P is kind of an anti-move; just makes it less clear and doesn't really help anything

#
# cleaner (another style choice)
VCProjectPath = Path.home() / Path(r"Downloads\RVLATESTFORREAL\Prod\VPS Game Modes\x64\Release")
#

unused variables looks like

#
ServerStr = str(ServerLaunchBat)
ClientStr = str(ClientLaunchBat)
old iris
hearty niche
#
# don't use the var name "type"
def delete_old_dll(type):
#

if you must use type, use _type, but rather to use dll_type or so

old iris
#

or youre comparing them

hearty niche
#

not comparing, combining like you are

#

Path(r'C:') / Path(r'Program Files\Something')

#

don't need to do the / 'string' / 'other string' stuff

#

don't use random numbers for types like this

#

be explicit what those mean

#

for example

#
command=lambda: launch_program('Server')
#

first it makes your code more clear, then you realize you can do loops easier, and so on

old iris
hearty niche
#

you combining them:

old iris
#

But you said

VCProjectPath = Path.home() / Path(r"Downloads\RVLATESTFORREAL\Prod\VPS Game Modes\x64\Release")
#

Why would we go Path.home then do the direct path instead of just

hearty niche
#

just doing the exact same thing as you but not using multiple strings

#
VCProjectPath = P.home() / "Downloads" / "RVLATESTFORREAL" / "Prod" / "VPS Game Modes" / "x64" / "Release"
old iris
#

hm

hearty niche
#

you can combine all those strings

old iris
#

Yeah my point being is you stated Path twice

#

I only stated path once

hearty niche
#
VCProjectPath = P.home() / Path(r"Downloads\RVLATESTFORREAL....")
#

it is the same but smaller

old iris
#

And my question is wouldnt you just put one path, without the P.home()

hearty niche
#

I would yes

old iris
#

VCProjectPath = Path(r"Downloads\RVLATESTFORREAL....")

#

So thats what my confusion was

hearty niche
#

don't you want to start from home

old iris
#

Oh πŸ’€

hearty niche
#

doing it that way starts from current working directory

old iris
#

Sorry yeah my brains going insane rn I guess

#

I didn't realize that and now it clicked in

#

If I were to do that I would just put the whole path then, the drive letter and everything

#

But yeah Path.home() does the same thing, just looks weird to me

hearty niche
#

instead of using var name to store key information, use dictionary

#

LaunchBat['Client'] =

old iris
# hearty niche

Before you said that I did indeed fix it and changed it to this

BatList = {
    1: P("D:/Rumbleverse Launcher Preset/Server Patch/Rumbleverse/StartServer.bat"),
    2: P.home() / "Desktop" / "Desktopped" / "dl" / "rubbleverse" / "ARCHIVEDRumbleverse" / "Rumbleverse" / "OpenAndInject.bat"
}
def launch_program(num):
        subprocess.Popen(str(BatList[num]), shell=True, cwd=BatList[num].parent)

And I can go ahead and clean those paths up

hearty niche
#

then when you use proper 'type' instead of 0 and 1, you don't need to duplicate the Popens

old iris
#

yeah I just did that lol

#

perfect timing

hearty niche
#

You well on your way!

old iris
#

Thanks

#

I actually thought of it before you showed up but I appreciate the help

hearty niche
#

as you can see it's all just little nitpicky stuff and style choices etc for the most part πŸ™‚

#

soon you should/could start to move more to classes, as it cleans a lot of this stuff up

old iris
#

Yeah I was working on classes in the past

#

I'm simultaneously slowly learning C++ at the same time lol
I just went back into Python today after like a month

old iris
old iris
potent plank
old iris
potent plank
old iris
#

Yeah I ended up reverting to it lol

potent plank
#

a quick snippet -

from pathlib import Path

def move_file(old_loc: Path, new_loc: Path):
    if not old_loc.exists():
        log.insert(tk.END, f'Failed to find the new File in {old_file}\n')
        return
        
    try:
        shutil.copy(old_loc, new_loc)
        log.insert(tk.END, f'Successfully transferred the new File.\n')
    except Exception as e:
        log.insert(tk.END, f'{e}\n')

move_file(NewDLL, ServerPath / OldDLLName)
#

I tried making it a bit more reusable, by using arguments instead of global variables.

old iris
#

My go to is dumbed down explanations so if thats correct or not it would help me understand lol

#

Oh I see so its more simplified as well, its actually kinda the opposite

potent plank
old iris
#

So if not then we return

#

if so we continue

#

so the if so we don't have to type its just there already

#

This is the changes I've currently made

def delete_old_dll(replace):
    clear_button.invoke()
    if not OldDLL.exists():
        if replace:
            log.insert(tk.END, f'Failed to delete, DLL already gone.\n')
            return
        log.insert(tk.END, f'Failed to delete, DLL already gone.\nMoving new DLL...\n')
        move_new_dll()
    try:
        recycle(OldDLL)
        if replace:
            log.insert(tk.END, f'Successfully removed old DLL.\n')
            return
        log.insert(tk.END, f'Successfully removed old DLL.\nMoving new DLL...\n')
        move_new_dll()
    except Exception as e:
        log.insert(tk.END, f'{e}\n')
        return
potent plank
#

btw, if you're going to pass tk.End every time you call log - you might as well wrap it with a short function.
like

log_end = lambda *args, **kwargs: log.insert(tk.End, *args, **kwargs)
``` or
```py
def log_end(*args, **kwargs):
   log.insert(tk
End, *args, **kwargs)
old iris
#

I mean I get it, but the code I don't.

dull sandBOT
#
The `*args` and `**kwargs` parameters

These special parameters allow functions to take arbitrary amounts of positional and keyword arguments. The names args and kwargs are purely convention, and could be named any other valid variable name. The special functionality comes from the single and double asterisks (*). If both are used in a function signature, *args must appear before **kwargs.

Single asterisk
*args will ingest an arbitrary amount of positional arguments, and store it in a tuple. If there are parameters after *args in the parameter list with no default value, they will become required keyword arguments by default.

Double asterisk
**kwargs will ingest an arbitrary amount of keyword arguments, and store it in a dictionary. There can be no additional parameters after **kwargs in the parameter list.

Use cases

  • Decorators (see /tag decorators)
  • Inheritance (overriding methods)
  • Future proofing (in the case of the first two bullet points, if the parameters change, your code won't break)
  • Flexibility (writing functions that behave like dict() or print())

See /tag positional-keyword for information about positional and keyword arguments

old iris
#

@potent plank Thanks for all the help, I've been working on super optimizing it

#

I'll send the final result in a few and I would like to see what you think

#

I followed your advice

dull sandBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.