#๐Ÿ”’ Seeking Code Review and Feedback

113 messages ยท Page 1 of 1 (latest)

inland dragon
#

https://paste.pythondiscord.com/VDFA

Newbie here seeking code review and feedback. Is my code good? bad? What can be improved? Any best practices I should be implementing

Gameplay loop:

  1. Input Player Name
  2. Input an action that will increment/decrement stats
  3. Enter store to buy items that will also increment/decrement stats
wintry locustBOT
#

@inland dragon

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.

inland dragon
#

@main siren you available?

main siren
#

you misspelled prestiege (=> prestige)

#

is this working fine now?

#

line 113 โ€“ under what conditions will that code be executed?

inland dragon
#

it's only used to get out of the visit_store() and back to Game.continue_game(cls)

inland dragon
main siren
#

can you answer my question though?

inland dragon
#

It prints 'Exiting the store' when I input q

#

Is this what you're asking?

main siren
#

sorry, I misread the code and jumped to the wrong conclusion; ignore me.

#

it's fine.

#

the Game class looks odd and shouldn't be there

#

this is not how classes are supposed to be used at all

inland dragon
#

I'm going to be honest though. Most of the time, I have no idea whether I'm linking things up correctly. Like when to use cls or self.

inland dragon
main siren
#

a class is supposed to be a structured template for an object

#

it represents some concept

#

let's talk about Items

#

what does an Items instance represent?

inland dragon
#

A new item like: Sword, Shield, Potion

main siren
#

so if you have three instances of Items, what do you call a bunch of them? Itemses?

#

you yourself used a singular form when describing one such thing

inland dragon
#

I don't get it. Aren't they all instances of class Items?

main siren
#

is a Sword an Items then?

inland dragon
#

Yeah

main siren
#

so if you have a Sword and a Shield, what do you call that collection? Itemses?

inland dragon
#

Items no?

main siren
#

much like you have str and int classes, they're not called strings or integers

#

the singular form reflects the fact that 1 or "abc" is a single integer or string

inland dragon
#

so the class Items should be renamed to Item?

main siren
#

yes, for starters

#

what's also odd to me is that there is a class method in Items that constructs all the items

#

isn't that something the game itself should be doing?

#

why does the Items class have to know about every possible item?

inland dragon
#

I figured that since its related to Items, I should just put it all in the same place.

And if more items were to be added in the future, it would have cluttered the Game class.

main siren
#

isn't the initial collection of items inherent to the logic of the game though?

#

that clutter always goes somewhere, and I don't think the Item class should care about that

#

like the others pointed out yesterday, this way of using classes as namespaces is highly unorthodox

#

for example you can't have two different games with different parameters this way

inland dragon
#

Sorry, I don't understand.

  • What's a namespace and why would it be an issue?
  • What would the best practice in this case? You mentioned earlier that Game class was odd and shouldn't be there
  • Why can't we have two different games this way? Since Game is an instance shouldn't it be able to support multiple games?
main siren
#

no, because they're both modifying the same Player and Items classes

#

so you can't have two truly separate Game instances this way

#

the normal way would be to have the Game instance instantiate a Player object and initialize the list of Items within that game

#

imagine what would happen if you were to play another game after the old one ended

inland dragon
#

Ok, so I should:

  1. Move initialize_items into Game, and
  2. Make Player an instance variable by adding a def __init__?
inland dragon
main siren
#

I mean, if you tried to run the game again without closing the interpreter

#

sure, if you closed the program entirely, it would reset back to defaults

#

but you asked for best practices

inland dragon
#

Ok, in that case, the same data would carry over to the new Player?

main siren
#

if you did not make an instance of it, yes

#

another thing is that it's a faux pas to wait for user input in __init__()

#

__init__() should never block for any reason

#

I think a Game.run() method would be reasonable

inland dragon
#

Ok, so in this case the Game __init__() should only have the name property? Everything else like create player and initalize items should go under a run() method?

main siren
#

what's the name property about?

inland dragon
#

Something like this? so new instance has a name.

class Game:
    def __init__(self, name):
        name = name
main siren
#

what are you using the name property for?

inland dragon
#

Nothing lol. Just thought it should have a name

main siren
#

don't add useless things to it

#

I think the Game.run() method should initialize the game and then have a loop where it asks for the player's action, and then executes those actions

#

the way you're doing it now, if I'm not mistaken, is that you call Game.continue_game() before returning from the previous call

#

this is bad because it's basically a recursive call, adding one stack frame for every new action

#

see what you can come up with when implementing game.run()

inland dragon
main siren
#

when you call a function, you should also return from that function in a timely manner

#

because the interpreter keeps track of these calls

#

if something goes wrong, you get a "traceback", right?

#

where you see the exception raised, and all the function calls in your current stack, starting from Game.__init__() (as things stand right now)

inland dragon
main siren
#

I think the game_ prefix is redundant

#

and also don't call game_run() in the initializer

#

call it on a Game instance you create in the main body of the script

main reef
#

Yeah, what we want seems to be some sort of while loop where the game repeatedly asks you for an action

main siren
#

like Game().run()

main reef
inland dragon
main siren
#

doesn't need a return statement necessarily, so long as you exit from the function instead of calling itself again

#

you must have seen a traceback when your program crashed

inland dragon
main siren
#

there's no point in having an empty __init__()

#

an __init__() method is not necessary for instantiating a class

#

that said...

#

you would probably want to initialize some member variables there

#

depending on the structure your Game class ends up with

#

if you ever add any parameters to your game, those would be saved in __init__ ()

inland dragon
main siren
#

if you're not calling the function from itself, or calling another one that calls the same function again

#

there are ways to programmatically check for this, but it's not normally done

inland dragon
main siren
#

well, maybe like "difficulty" or "starting money", etc.

inland dragon
main siren
#

line 134 in your paste

inland dragon
#

So if it was return Game.continue_game(cls), there would not be any traceback errors?

main siren
#

no, you're missing the point

#

if you're calling a Game.continue_game() which then causes another call to Game.continue_game() before returning from the previous call, you end up with a perpetually growing stack

#

this is why your game should have a top-level while loop for processing player actions

inland dragon
#

Ok, but how is it not returning from the previous call?

main siren
#

because it's unconditionally calling Game.continue_game() before it can do so

#

see line 66

inland dragon
#

I don't get it. I mean, I get what you're saying, but I don't see it from the code. If possible, please down dumb a few more levels lol.

Like continue_game(self), I go to store, then I purchase an item, then I hit 'q' and it goes back to continue_game(self)?

main siren
#

you are calling that function within the while loop

#

it doesn't go back to the same call of continue_game(), but it starts a new one!

#

and that is the problem

inland dragon
#

Hmm, but it is outside the while loop, no? It has the same indentation. As in after exiting the loop, it calls continue_game()

And, how would I make it go back to the same call?

#

Ok, I need to step out for a bit. Thanks for the help again @main siren !. Will refactor seek review again

main siren
#

line 66 is indented on the same level as the match

#

so it's inside the while loop

#

just make a top-level interaction loop, and don't call that method from any other method

wintry locustBOT
#
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.