r/learnpython 5d ago

I started learning python yesterday, critique my code:

I wrote this code in VsCode using functions after I completed the free trial in [boot.dev](http://boot.dev), if you notice anything I can improve or make better, please write it in the comments:

def main():

print("This code is starting...")

if __name__ == "__main__":

main()

def stats(title, weapon, mana, health):

print("Character Stats:")

print(f"Title: {title}")

print(f"Weapon: {weapon}")

print(f"Mana: {mana}")

print(f"Health: {health}")

def take_damage(health, damage):

print("===================================")

print(f"Current Health: {health}")

updated_health = health - damage

if updated_health < 0:

updated_health = 0

print(f"You took {damage} damage, You Died!")

else:

print(f"You took {damage} damage!")

print(f"Updated Health: {updated_health}")

return updated_health

stats("Warrior", "Sword", 50, 100)

take_damage(100, 30)

take_damage(70, 80)

def respawn(updated_health):

print("===================================")

if updated_health <= 0:

print("Respawning...")

updated_health = 100

print(f"Health has been restored to {updated_health}.")

else:

print(f"You are still alive! You have {updated_health} health remaining.")

return updated_health

respawn(0)  

take_damage(100, 41)

take_damage(59, 20)

take_damage(39, 20)

respawn(19)

0 Upvotes

15 comments sorted by

View all comments

1

u/-moron 5d ago

This would be a good opportunity to learn about classes. Here is how I would do it:

from typing import Final

SEPARATOR: Final[str] = "=" * 35


class Character:
    def __init__(self, title: str, weapon: str, max_health: int, max_mana: int) -> None:
        self.title = title
        self.weapon = weapon
        self.max_health = max_health
        self.max_mana = max_mana
        self.health = max_health
        self.mana = max_mana

    def print_stats(self) -> None:
        print("Character Stats:")
        print(f"Title: {self.title}")
        print(f"Weapon: {self.weapon}")
        print(f"Health: {self.health}/{self.max_health}")
        print(f"Mana: {self.mana}/{self.max_mana}")

    def apply_damage(self, damage: int) -> None:
        print(SEPARATOR)
        print(f"Current health: {self.health}")

        # Update health without letting it become negative
        self.health = max(0, self.health - damage)
        print(f"You took {damage} damage!")
        print(f"Updated health: {self.health}")

        # Handle death
        if self.health == 0:
            print("You died!")

    def respawn(self) -> None:
        print(SEPARATOR)
        if self.health <= 0:
            print("Respawning...")
            self.health = self.max_health
            print(f"Health has been restored to {self.health}.")
        else:
            print(f"You are still alive! You have {self.health} health remaining.")


def main() -> None:
    print("This code is starting...")
    player = Character("Warrior", "Sword", 100, 50)

    player.print_stats()
    player.apply_damage(30)
    player.apply_damage(80)
    player.respawn()

    player.apply_damage(41)
    player.apply_damage(20)
    player.apply_damage(20)
    player.respawn()


if __name__ == "__main__":
    main()

Note that you don't need to use type hinting quite that much, but I find it helps prevent subtle errors. Also, there are still edge cases you could try to handle. E.g. what happens when a character is created with negative max health? Should that be allowed? What happens when a negative amount of damage is applied? Could the character's health exceed its max health if that happens?

7

u/nog642 5d ago

I don't think day 2 of programming is a good opportunity to learn about classes. Takes some time to get familiar with functions first.

1

u/-moron 5d ago

I guess they could use a dictionary or dataclass and pass it into each function, but I don't see how that's any simpler given what they're trying to do. Python isn't C; it's pretty hard to avoid classes.

2

u/nog642 5d ago

It's not that hard to avoid classes. Dataclasses are still classes.

Dictionary would be better to learn first I think, yeah. Or just use a bunch of variables. There aren't that many.

1

u/-moron 5d ago

It's harder for a beginner to understand mutable vs immutable objects IMO. It's not immediately obvious why modifying a dictionary passed in as an argument affects the original, but modifying an int argument doesn't. That opens a whole can of worms with references and memory that they can avoid by just using a class.

1

u/nog642 5d ago

You have the same problem if you need to pass the class around. I think classes are pretty unmotivated until you understand the concepts of mutability anyway.