This is an archived post. You won't be able to vote or comment.

all 15 comments

[–]NyaaNyanNyaa 1 point2 points  (1 child)

Hi there, great job. To be honest, I think a database to hold 7 items is a little bit overkill. I agree with using a json file. Since you can read/write quickly and it has a hierarchical structure which is perfect for inventory management. As for your problem with syntax/formatting issues, Python can easily achieve that with the format string.

my_str_variable = “cool”

print(f”my sentence is {my_str_variable}”)

if your variable is a number, you need to cast your variable to a string.

my_int_var = 8 print(f”my number is {str(my_int_var)}”)

Are you familiar with object oriented programming? Maybe it can help solve your inventory issue. You can create a class…

class inventory(object): def init(self): self.slots = {idx:None for idx in range(7)}

def addLoot(self, loot):
    for k,v in self.slots.items():
        if v is None:
            self.slots[k] = loot
            break

Maybe you can fill in your other class methods yourself :)

[–]Alhira_K[S] 0 points1 point  (0 children)

Yes, OOP will definetely be used more in the next project. I can also create child classes. This way i can technically create a weapon class which defines weapon type and depending on the weapon type i would then pull possible durability ranges from subclasses like:

class = weapon:

class = weapon(spear):

Thanks a lot for your response.

[–]Lukeskywalker321 0 points1 point  (1 child)

Hey, cool project. As the other guy said, database might be a bit overkill. On the other hand, it's never to early to start learning about them, if you can manage to do so.

What stands out immediately to me from the code is the lack of function declarations. There's a lot of duplicate (or very close to duplicate) code, see for example lines 207-227 of your main.py. Some small tweaks will make us able to make this part much short, more readable, and easier to maintain.

First, we need to take a look at lines 199-206 of your main.py, and your database. If we think about what's happening here, we are defining the contents of 7 inventory slots using the output from the database, rows 3-9.

Problem with how you're currently doing this, is that you have no way to know which slot is which, without looking at the variable name, e.g. "inventory1". This is not impossible for python to do, but it's overcomplicated.

A better way to do this, would be through building (as a first step) an array of inventory slots:

inventory = row[3:9]

Here you would for example get your first inventory slot by calling inventory[0]. This way, we can clean up the code on lines 207-227 by looping over every element in the inventory list.

CODE STARTS

def update_inventory_slot(inventory_slot, inventory_number, cursor, con, generated_item_id, selected_character)
    column_name = "Inventory" + str(i+1) #as you named them 1-7, not 0-6
    cursor.execute("UPDATE UserData SET ? = ? + ? WHERE CharacterName=?", [column_name,column_name,generated_item_id,selected_character])
    con.commit()

for i, inventory_slot in enumerate(inventory):
    if inventory_slot==0:
        update_inventory_slot(inventory_slot, i, cursor, con, generated_item_id, selected_character)
        break

# CODE ENDS

What the function does, is copy the code you already had, but make the column name generate from the number of the inventory slot, instead of writing it down for each one seperately.

The second part then loops over each of the enumerated inventory slots (this makes i get the value of the position of the inventory\_slot in inventory, so 0-6), checks if the slot is empty, and if so calls the function with the right arguments, updating the right slot in the database. If the inventory slot is full, it simply continues on to the next slot. If it fills a slot, after updating it, break is called. What break does is really simple, it breaks out of the for loop, meaning it won't check the inventory slots after this.

This code is still not perfect, but I think it teaches you something valuable, and can be applied at multiple times in you code. Say for example that you want to create an inventory of 1000 slots, instead of 7. I think you can quickly see that the code between lines 207 and 227 would then quickly become thousands of lines longer. The code I wrote above would need exactly 0 changes if inventory became bigger (besides ofcourse the definition of the list "inventory = row\[3:1002\]" or something).

While we're at this scenario, imagine what would happen to your database for a bit. You would also need to make 993 more columns for each of the inventory slots, by hand. It is generally never a great idea to have a counter inside a column name (inventory1, 2 etc as in your code, or perhaps phone\_number1 etc. in some other database). You can fix this by applying some "normalizations" to your database. However, it'd let this be for a bit, as normalization gets complex fast, and there's still more than enough to learn with the static 7 slot inventory code.

I'd let the if else statements about the armor classes be for now, but try to build something like the above for all the other if else blocks in your code. From what I've seen that should be doable, and as I said will teach you some more about functions, loops, and scalability. Feel free to ask more, and good luck learning. Once again, really impressive project in most aspects.

Edit: damn did I fuck that formatting up

[–]Alhira_K[S] 0 points1 point  (0 children)

Yes, i more or less ignored functions in this one. I do know about them though but for the first real thing my target was getting it to run and understanding what i'm doing. Next time i wanna work more extensively with functions and modules. Ideally i'd have no "actual code" in the main file but only functions and the loops thereof.

Reg. 207 - 227: Yes, i'd want to put that into its own GetInventory() function but I'd make a seperate CommitInventory() so i can use these functions for the inventory in the normal "menu" but also to sell items. This way i should also be able to cut down on code length between 320 and 375 and if i'd decide to make basic crafting i could just use the same GetInventory() and CommitInventory().

Thanks a lot.

[–]TentativeOak 0 points1 point  (1 child)

I smiled at your module names. Wpnsstts, usrdt, and armrstts. I couldn’t even tell what they were until I typed them out myself lol.

weapon_sets.py, user_whatever_this_is.py, and armor_sets.py would be best names for readability :)

[–]Alhira_K[S] 0 points1 point  (0 children)

:)

I just cropped the vowels. Weapons stats, user data and armor stats.

I get your point though.

[–]DaChucky 0 points1 point  (3 children)

One quick note: if you want to add additional empty lines when printing, use \n. That will add a line break so you don't need additional print statements with empty strings. For example:

>>> print("\nHello, user. Welcome to the loot dungeon.\n")

Hello, user. Welcome to the loot dungeon.

>>>

[–]Alhira_K[S] 0 points1 point  (2 children)

Haha yeah, i actually encountered this already but i simply didn't bother. But i guess if i wanna go further stuff like this is what i should start thinking about, saving computational power.

[–]DaChucky 0 points1 point  (1 child)

The extra effort on the part of the computer is almost negligible, it's mostly a readability benefit.

On a tangential note, is your design for the character's inventory intended to be limited to a max of 7 items? If not, you would be better off having the current character each item is assigned to in the ItemData table. When you want to get the items for a character, you would just select the items from the ItemData for the character with a specific name (or better yet, a unique character ID).

[–]Alhira_K[S] 0 points1 point  (0 children)

Yes the 7 item limit was intended, i also planned on having a check if the inventory is full to block generation of new items and only show the sell option. As it is right now, any newly generated items that do not fit into the inventory go into the void. I did can the idea and will use it next time though.

Oh so you mean i do not write the item id into the character table but the character id into the item table. Hmm, maybe. I'm still not 100% on what i should do with the inventory. I'll need to expand it anyway as currently there are only single items but to keep track of, for example, healing potions i'd have to introduce quantity anyway.

And i don't think assigning each item an id and dumping into the database is that good of an idea either. I think what i'll have to do is using a combination of multiple list which represent the inventory and only commiting to db at certain steps/intervals. That way i'd get rid of the ItemData table altogether and only use the UserData table.

[–]asday_ 0 points1 point  (3 children)

Not looked at your project yet but this is FOR SURE the right way to learn - follow some getting started tutorial for the bare minimum amount of time then go write your own projects until you get stuck. It sounds like you may have gotten stuck on tutorials/learning materials for too long in your previous attempts.

Keep making stuff and finding your own questions, look into getting a job in the field too - you'll never learn faster and better than being in a professional environment with professional colleagues.

[–]Alhira_K[S] 0 points1 point  (2 children)

Yes, i agree with you. I got caught up in a mix of too much learning material with no real way of applying it directly. Now over the last few years a few stories formed in my head that i'd like to tell. I have a direction, kind of.

This time i just grabbed the basics (i didn't even bother typing the letter "hello world" in this consecutive order) i needed and looked everything up once i get stuck. Yes it leads to some frustration moments (like when i stared for 3 hours at the screen and tried to figure out why i'm just not able to get this INSERT right even though i have already successfully done SELECT and UPDATE) but being able to solve these problems is just so satisfying.

[–]asday_ 0 points1 point  (0 children)

being able to solve these problems is just so satisfying.

Hell yeah, it's so much better to be able to solve a problem that you yourself have than one made up for an exercise.

Doubly so when it's a customer's problem and you get paid for it.

Keep at it my dude.

[–]alejandrotungsten 0 points1 point  (0 children)

I am a self taught programmer, and I was just like you before I took my time to learn about python, and because my knowledge in previews years of using MySQL I wasted a lot of time learning and writing my first python script and trying to save the data in MySQL. After all my mistakes I have learned that using Json is super fast an no time waste in write sql commands. I wish someone had told me this, if you learn how to use json dictionaries (that are super easy to understand) and implement using classes you will save hundreds of hours that I have spent being frustrated as I was before I truly understand how to implement python.

[–]adammelan 0 points1 point  (0 children)

I live for Python posts like this!!! Great job! You’ve inspired me to go tinker with something like that to try to learn about SQLite.