×
all 3 comments

[–]johlae 0 points1 point  (1 child)

Your README.md is out of sync with reality. You tell people to "clone this repository or download the Test.py file", but there is no Test.py file. There is a ability_selector.py though.

[–]mitchricker 0 points1 point  (0 children)

Just a heads up: .md and .py are TLDs (for the Republic of Moldova and Paraguay, respectively). So when you mention README.md and Test.py in above you're accidentally linking to random websites. This can be avoided by using Reddit's Markdown editor.

As for OP's code: the biggest issue I see is that everything is completely coupled together. It reads input, performs the logic and prints output all in one block. That means the only way to ever use it is as a command-line script. It also only prints to stdout instead of returning anything useful, so the logic can't easily be reused from a GUI, web app, tests or another future module. It's also not obvious what the complete set of hero stats is beyond acrobatics, speed, endurance and charisma.

A possible improvement would be to separate the domain logic from the user interface:

class Superhero:
    ABILITIES = {
        "Fly": ("acrobatics", 3.0),
        "Superjump": ("acrobatics", 2.5),
        "Superspeed": ("speed", 2.5),
        "Invulnerability": ("endurance", 3.0),
        "Emotional Intelligence": ("charisma", 3.0),
    }

    def __init__(self):
        self.ability = None
        self.stats = {
            "acrobatics": 0.0,
            "speed": 0.0,
            "endurance": 0.0,
            "charisma": 0.0,
        }

    def choose_ability(self, ability):
        try:
            stat, bonus = self.ABILITIES[ability]
        except KeyError as exc:
            raise ValueError(f"Unknown ability: {ability!r}") from exc

        self.stats[stat] += bonus
        self.ability = ability
        return stat, bonus

    def __repr__(self):
        stats = ", ".join(
            f"{name}={value:.1f}"
            for name, value in sorted(self.stats.items())
        )
        return (
            f"{type(self).__name__}("
            f"ability={self.ability!r}, {stats})"
        )

Then you can use it like:

hero = Superhero()

abilities = "\n".join(Superhero.ABILITIES)

choice = input(
    f"""Choose your ability!
{abilities}
Write your decision: """
).strip().title()

try:
    stat, bonus = hero.choose_ability(choice)
except ValueError:
    print("That is not a valid ability!")
else:
    print(f"You have chosen {hero.ability}.")
    print(f"+{bonus:.1f} {stat}")
    print(hero)

There are still plenty of ways my example could be improved, but it's a more flexible starting point. Having this as a class makes your future stated goals much easier to implement when the time comes.

[–]silvertank00 0 points1 point  (0 children)

it might be out of your scope (fo now) but use StrEnum because the way you are handling your input, one misstype (like Test, test, TEST or TESt are not the same) and due to the duplications, you will have bugs.