Python TypeError ('<=' не поддерживается между экземплярами 'str' и 'int')

import random
elements = {
    "normal": {"strong_against": ["None"], "weak_against": ["None"]},
    "fire": {"strong_against": ["earth", "ice"], "weak_against": ["water", "ice"]},
    "water": {"strong_against": ["fire", "poison"], "weak_against": ["earth", "electric"]},
    "earth": {"strong_against": ["water", "poison"], "weak_against": ["fire", "nature"]},
    "holy": {"strong_against": ["dark"], "weak_against": ["dark"]},
    "dark": {"strong_against": ["holy"], "weak_against": ["holy"]},
    "ice": {"strong_against": ["fire"], "weak_against": ["fire"]},
    "electric": {"strong_against": ["water"], "weak_against": ["earth"]},
    "poison": {"strong_against": ["nature"], "weak_against": ["earth", "water"]},
    "nature": {"strong_against": ["earth"], "weak_against": ["poison", "fire"]}
}
class armor:
    def __init__(self, name, defence, element=None):
        self.name = name
        self.defence = defence
        self.element = element
class weapon:
    def __init__(self, name, damage, element=None):
        self.name = name
        self.damage = damage
        self.element = element
class restore_spell:
    def __init__(self, name, restore_power,cost):
        self.name = name
        self.restore_power = restore_power
        self.cost = cost
class attack_spell:
    def __init__(self, name, attack_spell_power, cost, element=None):
        self.name = name
        self.attack_spell_power = attack_spell_power
        self.cost = cost
        self.element = element
class  status_effects:
    pass
class Person:
    def __init__(self,name,armor=None,weapon=None,attack_spell=None,restore_spell=None,debuff=None,buff=None,max_health = 100,health=None,max_mp=48,mp=None,strength=18,defe=12,dex=10,magic=20,magic_defe=12,luck=16,evasion=2,exp=0,lvl=1,skill_points=0,attack_accuracy=100,max_lvl=100, base_d=0, base_d_m=0):
        self.name = name
        self.max_health = max_health
        self.health = health if health is not None else max_health
        self.weapon = weapon
        self.attack_spell = attack_spell
        self.restore_spell = restore_spell
        self.buff = buff
        self.debuff = debuff
        self.max_mp = max_mp
        self.mp = mp if mp is not None else max_mp
        self.strength = strength
        self.defe = defe
        self.armor = armor
        self.dex = dex
        self.magic = magic
        self.magic_defe = magic_defe
        self.luck = luck
        self.evasion = evasion
        self.exp = exp
        self.lvl = lvl
        self.skill_points = skill_points
        self.attack_accuracy = attack_accuracy
        self.evasion = evasion
        self.max_lvl = max_lvl
        self.base_d_m = base_d_m
    def see_stats(self):
        print("max health: ", self.max_health,"/ health: ", self.health)
        print("max mp: ", self.max_mp,"/ mp: ", self.mp)
        print("strength: ", self.strength)
        print("defense: ", self.defe)
        print("magic defense: ", self.magic_defe)
        print("dexterity: ", self.dex )
        print("luck: ", self.luck)
        print("exp: ", self.exp)
        print("lvl: ", self.lvl)
    def see_gear(self):
        print("weapon: ", self.weapon.name if self.weapon else "None")
        print("armor: ", self.armor.name if self.armor else "None")
    def restore_health(self):
            if self.health < self.max_health and self.restore_spell and self.mp >= self.restore_spell.cost:
                self.health = min(self.health + self.restore_spell.restore_power, self.max_health)
                self.mp -= self.restore_spell.cost
                print(f"{self.name} used {self.restore_spell.name} and restored health to {self.health}")
            else:
                print(f"{self.name} cannot use the restore spell.")
    def calculate_base_d(self):
            return (self.strength + (self.weapon.damage if self.weapon else 0)) * random.uniform(0.9375, 1.0625)
    def calculate_base_d_m(self):
            return (self.magic + (self.attack_spell.attack_spell_power if self.attack_spell else 0)) * random.uniform(0.9375, 1.0625)
    def attack(self):
        attack_type = input("What kind of attack do you want to do (magic/physical): ").lower()
        if attack_type == "magic" or "m":
            if self.attack_spell and self.mp >= self.attack_spell.cost:
                self.mp -= self.attack_spell.cost
                return self.calculate_base_d_m()
            else:
                print("Not enough MP to cast a spell or no spell equipped.")
                return 0
        elif attack_type == "physical" or "p":
            return self.calculate_base_d()
        else:
            print("Please enter a valid attack type.")
            return 0

    def exp_to_next_lvl(self):
            if 1 <= self.lvl <= 9:
                return self.lvl * 100
            elif 10 <= self.lvl <= 15:
                return self.lvl  * 200
            else:
                return self.lvl * 300
    def  gain_exp(self, exp):
            self.exp += exp
            while self.exp >= self.exp_to_next_lvl():
                self.level_up()
    def level_up(self):
            self.exp -= self.exp_to_next_lvl
            self.lvl += 1
            self.skill_points += 5
            if 0 <= self.lvl <= 10:
                self.max_health += 75
                self.mp += 10
            elif 11 <= self.lvl <= 50:
                self.max_health += 150
                self.mp += 15
            elif 51 <= self.lvl <= 99:
                self.max_health +=250
                self.mp += 25
            else:
                print("you are at max lvl")

            print(f"Congratulations! You've reached level {self.lvl}")
    def s_skill_p(self):
            if self.skill_points >0:
                x = input("which skill you want to incrase:\nstrength\ndefense\nmagic\nmagic_defense\ndexterity\nluck ").lower()
                if x == 'strength':
                    self.strength += 1
                    self.skill_points -= 1
                elif x == 'defense':
                    self.defe += 1
                    self.skill_points -= 1
                elif x == 'magic':
                    self.magic += 1
                    self.skill_points -= 1
                elif x == 'magic_defense':
                    self.magic_defe += 1
                    self.skill_points -= 1
                elif x == 'dexterity':
                    self.dex += 1
                    self.skill_points -= 1
                elif x == 'luck':
                    self.luck += 1
                    self.skill_points -= 1
                else:
                    print("Please enter a valid skill")
            else:
                print("you dont have skill points ")
    def is_dead(self):
        return self.health <= 0

class  Barbarian(Person):
    pass
class Wizard(Person):
    def __init__(self, name, max_health=None, health=None, max_mp=48, mp=None, magic=20, magic_defe=12, attack_spells=None):
        super().__init__(name, max_health, health, max_mp, mp, magic=magic, magic_defe=magic_defe)
        self.attack_spells = attack_spells if attack_spells is not None else []

class Monster(Person):
    def __init__(self, name, max_health=100, health=None, max_mp=48, mp=None, magic=20, magic_defe=12, element=None, attack_spells=None):
        super().__init__(name, max_health, health, max_mp, mp, magic, magic_defe, element, attack_spells)
        self.element = element
        self.attack_spells = attack_spells if attack_spells is not None else []

    def attack_m(self):
        if self.health > self.max_health * 0.5:
            return self.calculate_base_d()
        else:
            return self.calculate_base_d_m()
def battle(player, monster):
    while not player.is_dead() and not monster.is_dead():
        print(f"{player.name}'s turn:")
        player_turn = True

        while player_turn:
            action = input("What do you want to do? (attack/restore/stats/gear): ").lower()
            if action == "attack" or action == "a":
                damage = player.attack()
                if player.weapon and player.weapon.element or player.attack_spell and player.attack_spell.element:
                    attack_element = player.weapon.element if player.weapon else player.attack_spell.element
                    if monster.element and attack_element in elements[monster.element]['weak_against']:
                        damage *= 1.5
                    elif monster.element and attack_element in elements[monster.element]['strong_against']:
                        damage *= 0.5
                monster.health -= damage
                print(f"{player.name} attacks {monster.name} for {damage:.2f} damage!")

                if monster.is_dead():
                    player.gain_exp(monster.exp)
                    break
                player_turn = False
            elif action == "stats" or action == "s":
                player.see_stats()
            elif action == "gear" or action == "g":
                player.see_gear()
            elif action == "restore" or action == "r":
                player.restore_health()
                player_turn = False
            else:
                print("Please enter a valid action.")

        if monster.is_dead():
            break

        print(f"{monster.name}'s turn:")
        m_damage = monster.attack_m()
        player.health -= m_damage
        print(f"{monster.name} attacks {player.name} for {m_damage:.2f} damage!")

        if player.is_dead():
            break

cure = restore_spell("cure", 50, 10)
fireball = attack_spell("fireball", 30, 15, "fire")
thunder = attack_spell("thunder", 25, 12, "electric")

player_weapon = weapon("Sword", 10, "normal")
player = Person(name = "Hero", weapon=player_weapon, attack_spell=fireball, restore_spell=cure)

monster = Monster(name = "Goblin", element = "fire", max_health=250, health=250, max_mp=20, mp=20, magic=10, attack_spells=None)
monster.weapon = weapon("Claws", 5, "fire")

battle(player, monster)

Я пытаюсь сделать что-то вроде ролевой игры на питоне, чтобы хорошо понимать классы. из ниоткуда функция is_dead начинает вызывать эту ошибку ('<=' не поддерживается между экземплярами 'str' и 'int'). Как я могу улучшить свой код и решить проблему Ребята, помогите, пожалуйста, я новичок в Python.

Как я могу решить эту проблему

Добро пожаловать в Stack Overflow. Пожалуйста, включите полную ошибку трассировки, а также образец входных данных. Я заметил одну вещь: if attack_type == "magic" or "m": не делает того, что вы думаете.

ewokx 11.06.2024 01:54

Ваши дочерние классы, наследуемые от класса Person (Варвар, Волшебник, Монстр), проблематичны, особенно в методах инициализации. Когда вы вызываете конструктор super, вы передаете аргументы (например, max_health, health и т. д.) в качестве позиционных аргументов, но вы ожидаете, что они будут вести себя как аргументы ключевого слова. Результат: броня равна max_health, оружие становится здоровьем и т. д. В конечном итоге вы передаете строку в качестве позиционного аргумента для фактического здоровья или max_health, что в конечном итоге сломается в is_dead, когда вы попытаетесь сравнить строку с целым числом.

Paul M. 11.06.2024 02:26

Короче говоря, ваш класс Person' __init__ ожидает много позиционных аргументов, но вы не предоставляете ему достаточно аргументов/в правильном порядке в своих подклассах. Например, max_health — это восьмой позиционный аргумент __init__ вашего Person, поэтому вам нужно передать аргументы для всех остальных первых семи позиционных аргументов, прежде чем передавать max_health. Тот факт, что имя передаваемой вами переменной совпадает с именем параметра, не означает, что Python автоматически узнает, какой параметр вы намеревались назначить.

Paul M. 11.06.2024 02:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
3
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В сообщении об ошибке написано '<=' not supported between instances of 'str' and 'int'. Это означает, что вы использовали оператор <=, пытаясь сравнить строку и целое число. Ваша функция is_dead() имеет только одну строку, return self.health <= 0. Мы знаем, что 0 — целое число. Таким образом, в какой-то момент вы присваиваете строку атрибуту health человека.

Как уже упоминал Пол М., проблема заключается в вызове super() в вашем Monster классе.

super().__init__(name, max_health, health, max_mp, mp, magic, magic_defe, element, attack_spells)

Вам не хватает спецификаторов ключевых слов при вызове функции. Это должно выглядеть так:

super().__init__(name, max_health=max_health, health=health, max_mp=max_mp, mp=mp, magic=magic, magic_defe=magic_defe)

Python не проверяет имена переменных в области вызывающего объекта и не сопоставляет их с сигнатурой функции, вам необходимо указать имена. Опуская их, конструктор родительского класса получает аргументы по порядку. Это означает, что когда Monster инициализируется, ему присваиваются armor=max_health, weapon=health, attack_spell=max_mp и т. д.

Также вы передаете element и attack_spells в super(), но у Person нет этих атрибутов.

Та же проблема существует и для других подклассов Person.


И еще: для вашего elements я настоятельно рекомендую использовать strong_against: [] вместо strong_against: ["None"].

Посмотрите на эту строку кода:

super().__init__(name, max_health, health, max_mp, mp, magic, magic_defe, element, attack_spells)

И это:

def __init__(self, name, armor=None, weapon=None, attack_spell=None, restore_spell=None, debuff=None, buff=None,
             max_health=100, health=None, max_mp=48, mp=None, strength=18, defe=12, dex=10, magic=20, magic_defe=12,
             luck=16, evasion=2, exp=0, lvl=1, skill_points=0, attack_accuracy=100, max_lvl=100, base_d=0,
             base_d_m=0):

В функции init Person health является девятым параметром (не считая self). Однако когда вы передаете значение, это третий параметр. То же самое и с max_health; на самом деле он получает значение element. Таким образом, ваши значения путаются, и в результате health становится строкой. Убедитесь, что вы передаете значения в одном и том же порядке или используете аргументы ключевых слов. Я бы рекомендовал использовать аргументы ключевых слов, чтобы сделать его менее запутанным.

        super().__init__(name=name, max_health=max_health, health=health, max_mp=max_mp, mp=mp, magic=magic,
                         magic_defe=magic_defe)

Есть еще несколько вещей, на которые стоит обратить внимание. Все имена классов должны быть в PascalCase. Например: class armor должно быть class Armor. Также attack_type == 'magic' or 'm' — это ошибка. Поскольку 'm' не является пустой строкой, ее оценка True сделает все утверждение истинным, несмотря ни на что. Измените это на attack_type == 'magic' or attack_type == 'm'. Это касается и attack_type == 'physical' or 'p'.

другой синтаксис для проверки attack_type, который мне нравится использовать для CLI: attack_type in ('magic', 'm')

ryyyn 11.06.2024 03:32

Другие вопросы по теме

Множественное приведение UUID в операторе выбора SQL Alchemy
Множественное наследование Python генерирует «TypeError: получено несколько значений для аргумента ключевого слова»
Попытка отсортировать таблицу: TypeError: невозможно прочитать свойства неопределенного значения (чтение «textContent»)
Ошибка типа: Tasks.map не является функцией (стек MERN)
Невозможно открыть файл Rnw после обновления R до 4.4.0 - (TypeError): невозможно прочитать свойства неопределенного значения (чтение `count`)
Разработка API с помощью Oak от Deno: TypeError — request.body не является функцией
Ошибка Webpack 5 после успешной сборки! (Необнаруженная ошибка выполнения Inpage.js)
TypeError при попытке запустить версию Flutter Web для разработчиков
PyCharm предупреждает: «Ожидаемый тип 'int', получено 'float'» для случайного.randint, но код все равно иногда запускается
Необработанная ошибка времени выполнения TypeError: невозможно прочитать свойства null (чтение «по умолчанию») в моем next.js